When fa7226f (kvm tools: init network devices only when the virtio
driver is ready to go) was introduced, a tiny detail was overlooked:
- Initialization of the uip layer is now coming in very late (only
when the guest driver says it is ready).
- In parallel, the rx thread is created quite early (as soon as the
queues are allocated).
This cause the rx thread to call uip_rx, which calls uip_buf_get_used,
which starts to use buf_lock mutex/the buf_used_cond, which haven't
been initialized yet. Tears and devastation follow, not to mention a
certain lack of network connectivity for the unsuspecting guest.
The (not so pretty) fix is to split uip_init:
- uip_static_init: initialize the lists, mutexes and conditions,
called from virtio_net__init_one.
- uip_init: perform the dynamic memory allocations, called from
notify_status.
This allows the network to be safely initialized.
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Support mergable rx buffers for virtio-net. This helps reduce the amount
of memory the guest kernel has to allocate per rx vq.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
We want to make the size of the virtio net header opaque to
uip.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
We already have something to wrap pthread with mutex_[init,lock,unlock]
calls. This patch creates a new struct mutex abstraction and moves
everything to work with it.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Respect guest tcp window size and stop sending tcp segments to guest
if guest's receive window is closed.
This fixes the TCP hang I'm seeing where guest and host are transferring
big chuck of data.
This problem was not triggered when guest and external host
communicates, probably because guest to external host communication
walks through real network and is much slower than guest and host
communication. Thus, guest's receive window has little chance to be
closed.
v2: use pthread_cond_wait to wait
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch removes the manual/usermode dhcp client configuration and instead
uses the DHCP client built within the kernel.
Since this client is tightly integrated with NFS (if NFS config is set), we
will add a specific NFS root addr in our DHCP offer to point it to a non
existent address so that we won't hang trying to poke it for our root.
Acked-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
uip_tx_do_ipv4_udp_dhcp() is used to handle DHCP packages from guest.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch get domain name and nameserver information from host config
file /etc/resolv.conf.
Guest can obtain DNS information through DHCP.
Signed-off-by: Asias He <asias.hejun@gmail.com>
[ penberg@kernel.org: check fscanf() for errors ]
Signed-off-by: Pekka Enberg <penberg@kernel.org>
If DHCP DISCOVER or DHCP REQUEST is found, reply with DHCP OFFER or DHCP
ACK respectively.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch checks:
- sport and dport
- magic cookie
to detemine whether a UDP package is a DHCP package.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This helper cooks a ethernet package and virtio header for UDP.
This patch also makes uip_udp_socket_thread() shorter.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch implement rx interface for uip. uip_rx() can be called in
virtio_net_rx_thread().
It is a consumer of the ethernet used buffer. It sleeps until there is
used buffer avaiable and copy ethernet data into virtio iov buffers
which provided by virtio_net_rx_thread().
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch implement tx interface for uip. uip_tx() can be called in
virtio_net_tx_thread().
It dispatches ethernet frame to ARP or IP handling code.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- Implement uip_tx_do_ipv4_tcp() to send TCP package to remote host.
- Implement uip_tcp_socket_thread() to receive TCP package from
remote host.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Guest's initial sequence number can be found in the SYN package that
guest send to us to intialize a TCP session.
Remote server's initial sequence number is faked. RFC 793 specifies
that the ISN should be viewed as a 32-bit counter that increments
by one every 4 microseconds. For simplicity's sake, current
implementation in uip just returns a constant.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch adds too helpers uip_tcp_is_syn(), uip_tcp_is_fin() to check if SYN and
FIN bit is set.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
uip_tcp_payload() returns start address of TCP payload in a TCP package.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This patch adds three helpers uip_tcp_hdrlen(), uip_tcp_len(),
uip_tcp_payloadlen() to return TCP header length, TCP totoal
length, and tcp payload length.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
struct uip_tcp_socket is used to present every session
between guest and remote host.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- Implement uip_tx_do_ipv4_udp() to send UDP package to remote host.
- Implement uip_udp_socket_thread() to receive UDP package from
remote host.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
struct uip_udp_socket is used to present every "connection" between
guest and remote host.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- Introduce struct uip_icmp to present ICMP package
- Implement uip_csum_icmp() to calculate ICMP checksum
- Current ICMP implementation in uip does not really send ICMP package
to remote host in question, instead it just fake a ICMP reply to fool guest.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Other protocal, e.g. TCP, UDP, ICMP, can use uip_csum() to make
checsksum as well.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- Introduce struct uip_ip to present IP package
- Add a helper uip_ip_len() to return totoal length of a IP package
- Add a helper uip_ip_hdrlen() to return the IP header length
- Currently, uip does not support IP options
Drop IP package if IP header length is not 20 bytes which means it
contains IP options.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- Introduce struct uip_arp to present ARP package
- uip_tx_do_arp()
Clone incoming ARP ethernet frame, if ARP is requesting
host IP address, tell guest host MAC address.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
- uip_buf_get_free()
Get a free buffer from buffer pool, sleep if there is no free buffer.
- uip_buf_get_used()
Get a used buffer from buffer pool, sleep if there is no used buffer.
- uip_buf_set_free()
Set a buffer as free, so it can be reused by the buffer producer.
- uip_buf_set_used()
Set a buffer as used, uip rx code will inject the ethernet frame in
this buffer into guest.
- uip_buf_clone()
Get a free buffer, and clone data into it.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>