41 Commits
Author SHA1 Message Date
Alan 93454e8983 tools/kvm: fix assumption of no IP options 2015-07-15 01:57:26 +01:00
Marc Zyngier 5f3aaf2281 kvm tools: plug race between uip_init and virtio_net_rx_thread
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>
2015-06-01 16:39:54 +01:00
Sasha Levin 7668c3a677 kvm tools: virtio-net mergable rx buffers
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>
2015-06-01 16:39:54 +01:00
Sasha Levin 7200d3a15c kvm tools: use iovec functions in uip_rx
Simplifies the code a lot.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:54 +01:00
Sasha Levin 643f6c0857 kvm tools: pass virtio header size to uip_init
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>
2015-06-01 16:39:54 +01:00
Sasha Levin d3476f7d3b kvm tools: use mutex abstraction instead of pthread mutex
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>
2015-06-01 16:39:53 +01:00
Asias He 3909f9b57b kvm tools: Respect guest tcp window size
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>
2015-06-01 16:39:52 +01:00
Asias He 7b0155fed9 kvm tools: Use macro in uip_tx_do_ipv4()
Use marcro instead of magic number in uip_tx_do_ipv4()

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:48 +01:00
Asias He de6aae9ff9 kvm tools: Drop unused variable in struct uip_buf
'u32 payload' is not used, so drop it.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:48 +01:00
Sasha Levin 575a9e3f31 kvm tools: Use kernel dhcp for network autoconfiguration
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>
2015-06-01 16:39:47 +01:00
Asias He bcd315db17 kvm tools: Introduce uip_tx_do_ipv4_udp_dhcp()
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>
2015-06-01 16:39:46 +01:00
Asias He ab8d80a615 kvm tools: Fill all DHCP options
The following DHCP options are filled.

   - MSG_TYPE

   - SERVER_ID

   - LEASE_TIME

   - SUBMASK

   - ROUTER

   - DNS_SERVER

   - DOMAIN_NAME

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:46 +01:00
Asias He 32a44aaf03 kvm tools: Fill DHCP options with domain name and DNS server IP
Domain name and DNS server IP address are filled.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:46 +01:00
Asias He bdcc9e40df kvm tools: Get domain name and nameserver from host
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>
2015-06-01 16:39:46 +01:00
Asias He 8f5f2f958f kvm tools: Add helpers to tell the type of a DHCP message
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>
2015-06-01 16:39:46 +01:00
Asias He 0c4bfcac1c kvm tools: Add helper to tell if a UDP package is a DHCP package
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>
2015-06-01 16:39:46 +01:00
Asias He b4db808201 kvm tools: Introduce struct uip_dhcp
struct uip_dhcp is used to present DHCP package

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:46 +01:00
Asias He d9da915bb5 kvm tools: Introduce uip_udp_make_pkg()
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>
2015-06-01 16:39:46 +01:00
Asias He 60d2902cce kvm tools: Introduce uip_rx() for uip
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>
2015-06-01 16:39:45 +01:00
Asias He 0c84745800 kvm tools: Introduce uip_tx() for uip
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>
2015-06-01 16:39:45 +01:00
Asias He 91b10270c4 kvm tools: Introduce uip_init() for uip
- Initialize TCP/UDP socket list, ethernet buffer list.

- Allocate memory for ethernet buffer.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 3df5d5938a kvm tools: Add TCP support for uip
- 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>
2015-06-01 16:39:45 +01:00
Asias He 89fb0bf807 kvm tools: Implement uip_csum_tcp() to calculate TCP checksum
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 6bd80bd847 kvm tools: Add helper to allocate and get TCP initial sequence number
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>
2015-06-01 16:39:45 +01:00
Asias He c6d1f44cf8 kvm tools: Add helpers to test whether SYN or FIN bit is set.
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>
2015-06-01 16:39:45 +01:00
Asias He d5768d2dff kvm tools: Add helper to return start address of TCP payload
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>
2015-06-01 16:39:45 +01:00
Asias He 34be5efa92 kvm tools: Add helpers to return TCP {header, total, payload} length
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>
2015-06-01 16:39:45 +01:00
Asias He b821664b2e kvm tools: Introduce struct uip_tcp_socket
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>
2015-06-01 16:39:45 +01:00
Asias He f2fdf98480 kvm tools: Introduce struct uip_tcp to present TCP package.
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He dd7a270b55 kvm tools: Add UDP support for uip
- 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>
2015-06-01 16:39:45 +01:00
Asias He 07197967df kvm tools: Implement uip_csum_udp() to calculate UDP checksum
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 39b72fd01d kvm tools: Add helper to return ethernet header length
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 8df66da791 kvm tools: Add two helpers to return UDP {header, total} length
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 4768afc6f0 kvm tools: Introduce struct uip_udp_socket
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>
2015-06-01 16:39:45 +01:00
Asias He dfc0655327 kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header
This pseudo header is used for UDP checksum.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He cbd1f4ac66 kvm tools: Introduce struct uip_udp to present UDP package
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
2015-06-01 16:39:45 +01:00
Asias He 0134a2a7e3 kvm tools: Add ICMP support for uip
- 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>
2015-06-01 16:39:45 +01:00
Asias He d8db9f85af kvm tools: Implement IP checksum for uip
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>
2015-06-01 16:39:45 +01:00
Asias He 67ba1b25d6 kvm tools: Add IPV4 support for uip
- 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>
2015-06-01 16:39:45 +01:00
Asias He 9f74838ffd kvm tools: Add ARP support for uip
- 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>
2015-06-01 16:39:45 +01:00
Asias He 26570aaffb kvm tools: Introduce ethernet frame buffer system for uip
- 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>
2015-06-01 16:39:45 +01:00