All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/31] Implement user mode network for kvm tools
@ 2011-06-30  8:40 Asias He
  2011-06-30  8:40 ` [PATCH v2 01/31] kvm tools: Introduce ethernet frame buffer system for uip Asias He
                   ` (31 more replies)
  0 siblings, 32 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

This patch series implement user mode network for kvm tools.

This is a from-scratch, lightweight, 1K LOC, implementation of the {TCP,UDP}/IP
protocal stack in user mode. Usr mode network enables plain user without special
privileges to have network access in guest OS. Zero-configuration is needed
in host side. 

uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
e.g., HTTP, FTP, SSH, DNS.

--------------------------------
To use user mode network:
--------------------------------

1) Just add '-net user' option when you starts kvm tools.

2) Since DHCP is not implemented right now, guest needs to setup IP and DNS
   manually.

   # ifconfig eth0 192.168.33.15
   # route add default gw 192.168.33.1
   # echo "nameserver dns_ip" > /etc/resolv.conf

--------------------------------
Performance test:
--------------------------------
All tests are under a 100Mbps network system

TCP_STREAM
guest(using user mode network) -> remote server: 92.97 Mbps (CPU 10.29%)
host(where guest runs on) -> remote server:      93.68 Mbps (CPU 25.31%)

UDP_STREAM
guest(using user mode network) -> remote server: 94.5 Mbps (CPU 99.90%)
host(where guest runs on) -> remote server:      95.7 Mbps (CPU 25.51%)


Asias He (31):
  kvm tools: Introduce ethernet frame buffer system for uip
  kvm tools: Add ARP support for uip
  kvm tools: Add IPV4 support for uip
  kvm tools: Implement IP checksum for uip
  kvm tools: Add ICMP support for uip
  kvm tools: Introduce struct uip_udp to present UDP package
  kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header
  kvm tools: Introduce struct uip_udp_socket
  kvm tools: Add two helpers to return UDP {header, total} length
  kvm tools: Add helper to return ethernet header length
  kvm tools: Implement uip_csum_udp() to calculate UDP checksum
  kvm tools: Add UDP support for uip
  kvm tools: Introduce struct uip_tcp to present TCP package.
  kvm tools: Introduce struct uip_tcp_socket
  kvm tools: Add helpers to return TCP {header, total, payload} length
  kvm tools: Add helper to return start address of TCP payload
  kvm tools: Add helpers to test whether SYN or FIN bit is set.
  kvm tools: Add helper to allocate and get TCP initial sequence number
  kvm tools: Implement uip_csum_tcp() to calculate TCP checksum
  kvm tools: Add TCP support for uip
  kvm tools: Introduce uip_init() for uip
  kvm tools: Introduce uip_tx() for uip
  kvm tools: Introduce uip_rx() for uip
  kvm tools: Add MACRO for user and tap mode for virtio net
  kvm tools: Reanme net_device to net_dev
  kvm tools: Introduce -net {user, tap, none} options for virtio net
  kvm tools: Change default guest MAC address to 00:15:15:15:15:15
  kvm tools: Make virtio net work with user mode network
  kvm tools: Make default network mode to user mode
  kvm tools: Make default host ip address to 192.168.33.1
  kvm tools: Introduce struct net_dev_operations

 tools/kvm/Makefile                 |    8 +
 tools/kvm/include/kvm/uip.h        |  292 +++++++++++++++++++++++++++++++++
 tools/kvm/include/kvm/virtio-net.h |    4 +
 tools/kvm/kvm-run.c                |   40 +++--
 tools/kvm/uip/arp.c                |   30 ++++
 tools/kvm/uip/buf.c                |  114 +++++++++++++
 tools/kvm/uip/core.c               |  188 +++++++++++++++++++++
 tools/kvm/uip/csum.c               |   92 +++++++++++
 tools/kvm/uip/icmp.c               |   29 ++++
 tools/kvm/uip/ipv4.c               |   29 ++++
 tools/kvm/uip/tcp.c                |  317 ++++++++++++++++++++++++++++++++++++
 tools/kvm/uip/udp.c                |  221 +++++++++++++++++++++++++
 tools/kvm/virtio/net.c             |  146 ++++++++++++-----
 13 files changed, 1449 insertions(+), 61 deletions(-)
 create mode 100644 tools/kvm/include/kvm/uip.h
 create mode 100644 tools/kvm/uip/arp.c
 create mode 100644 tools/kvm/uip/buf.c
 create mode 100644 tools/kvm/uip/core.c
 create mode 100644 tools/kvm/uip/csum.c
 create mode 100644 tools/kvm/uip/icmp.c
 create mode 100644 tools/kvm/uip/ipv4.c
 create mode 100644 tools/kvm/uip/tcp.c
 create mode 100644 tools/kvm/uip/udp.c

-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v2 01/31] kvm tools: Introduce ethernet frame buffer system for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 02/31] kvm tools: Add ARP support " Asias He
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   69 ++++++++++++++++++++++++++
 tools/kvm/uip/buf.c         |  114 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/include/kvm/uip.h
 create mode 100644 tools/kvm/uip/buf.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index d368c22..91539de 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -45,6 +45,7 @@ OBJS	+= disk/qcow.o
 OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
 OBJS	+= irq.o
+OBJS	+= uip/buf.o
 OBJS	+= kvm-cmd.o
 OBJS	+= kvm-debug.o
 OBJS	+= kvm-help.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
new file mode 100644
index 0000000..32a5da3
--- /dev/null
+++ b/tools/kvm/include/kvm/uip.h
@@ -0,0 +1,69 @@
+#ifndef KVM__UIP_H
+#define KVM__UIP_H
+
+#include "linux/types.h"
+#include "kvm/mutex.h"
+
+#include <netinet/in.h>
+#include <sys/uio.h>
+
+#define UIP_BUF_STATUS_FREE	0
+#define UIP_BUF_STATUS_INUSE	1
+#define UIP_BUF_STATUS_USED	2
+
+struct uip_eth_addr {
+	u8 addr[6];
+};
+
+struct uip_eth {
+	struct uip_eth_addr dst;
+	struct uip_eth_addr src;
+	u16 type;
+} __attribute__((packed));
+
+struct uip_info {
+	struct list_head udp_socket_head;
+	struct list_head tcp_socket_head;
+	pthread_mutex_t udp_socket_lock;
+	pthread_mutex_t tcp_socket_lock;
+	struct uip_eth_addr guest_mac;
+	struct uip_eth_addr host_mac;
+	pthread_cond_t buf_free_cond;
+	pthread_cond_t buf_used_cond;
+	struct list_head buf_head;
+	pthread_mutex_t buf_lock;
+	pthread_t udp_thread;
+	int udp_epollfd;
+	int buf_free_nr;
+	int buf_used_nr;
+	u32 host_ip;
+	u32 buf_nr;
+};
+
+struct uip_buf {
+	struct list_head list;
+	struct uip_info *info;
+	u32 payload;
+	int vnet_len;
+	int eth_len;
+	int status;
+	char *vnet;
+	char *eth;
+	int id;
+};
+
+struct uip_tx_arg {
+	struct virtio_net_hdr *vnet;
+	struct uip_info *info;
+	struct uip_eth *eth;
+	int vnet_len;
+	int eth_len;
+};
+
+struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
+struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf);
+struct uip_buf *uip_buf_get_used(struct uip_info *info);
+struct uip_buf *uip_buf_get_free(struct uip_info *info);
+struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg);
+
+#endif /* KVM__UIP_H */
diff --git a/tools/kvm/uip/buf.c b/tools/kvm/uip/buf.c
new file mode 100644
index 0000000..5e564a9
--- /dev/null
+++ b/tools/kvm/uip/buf.c
@@ -0,0 +1,114 @@
+#include "kvm/uip.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+struct uip_buf *uip_buf_get_used(struct uip_info *info)
+{
+	struct uip_buf *buf;
+	bool found = false;
+
+	mutex_lock(&info->buf_lock);
+
+	while (!(info->buf_used_nr > 0))
+		pthread_cond_wait(&info->buf_used_cond, &info->buf_lock);
+
+	list_for_each_entry(buf, &info->buf_head, list) {
+		if (buf->status == UIP_BUF_STATUS_USED) {
+			/*
+			 * Set status to INUSE immediately to prevent
+			 * someone from using this buf until we free it
+			 */
+			buf->status = UIP_BUF_STATUS_INUSE;
+			info->buf_used_nr--;
+			found = true;
+			break;
+		}
+	}
+
+	mutex_unlock(&info->buf_lock);
+
+	return found ? buf : NULL;
+}
+
+struct uip_buf *uip_buf_get_free(struct uip_info *info)
+{
+	struct uip_buf *buf;
+	bool found = false;
+
+	mutex_lock(&info->buf_lock);
+
+	while (!(info->buf_free_nr > 0))
+		pthread_cond_wait(&info->buf_free_cond, &info->buf_lock);
+
+	list_for_each_entry(buf, &info->buf_head, list) {
+		if (buf->status == UIP_BUF_STATUS_FREE) {
+			/*
+			 * Set status to INUSE immediately to prevent
+			 * someone from using this buf until we free it
+			 */
+			buf->status = UIP_BUF_STATUS_INUSE;
+			info->buf_free_nr--;
+			found = true;
+			break;
+		}
+	}
+
+	mutex_unlock(&info->buf_lock);
+
+	return found ? buf : NULL;
+}
+
+struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf)
+{
+	mutex_lock(&info->buf_lock);
+
+	buf->status = UIP_BUF_STATUS_USED;
+	info->buf_used_nr++;
+	pthread_cond_signal(&info->buf_used_cond);
+
+	mutex_unlock(&info->buf_lock);
+
+	return buf;
+}
+
+struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf)
+{
+	mutex_lock(&info->buf_lock);
+
+	buf->status = UIP_BUF_STATUS_FREE;
+	info->buf_free_nr++;
+	pthread_cond_signal(&info->buf_free_cond);
+
+	mutex_unlock(&info->buf_lock);
+
+	return buf;
+}
+
+struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg)
+{
+	struct uip_buf *buf;
+	struct uip_eth *eth2;
+	struct uip_info *info;
+
+	info = arg->info;
+
+	/*
+	 * Get buffer from device to guest
+	 */
+	buf = uip_buf_get_free(info);
+
+	/*
+	 * Clone buffer
+	 */
+	memcpy(buf->vnet, arg->vnet, arg->vnet_len);
+	memcpy(buf->eth, arg->eth, arg->eth_len);
+	buf->vnet_len	= arg->vnet_len;
+	buf->eth_len	= arg->eth_len;
+
+	eth2		= (struct uip_eth *)buf->eth;
+	eth2->src	= info->host_mac;
+	eth2->dst	= arg->eth->src;
+
+	return buf;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 02/31] kvm tools: Add ARP support for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
  2011-06-30  8:40 ` [PATCH v2 01/31] kvm tools: Introduce ethernet frame buffer system for uip Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 03/31] kvm tools: Add IPV4 " Asias He
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   15 +++++++++++++++
 tools/kvm/uip/arp.c         |   30 ++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/arp.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 91539de..006218d 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -45,6 +45,7 @@ OBJS	+= disk/qcow.o
 OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
 OBJS	+= irq.o
+OBJS	+= uip/arp.o
 OBJS	+= uip/buf.o
 OBJS	+= kvm-cmd.o
 OBJS	+= kvm-debug.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 32a5da3..c5eb417 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -21,6 +21,19 @@ struct uip_eth {
 	u16 type;
 } __attribute__((packed));
 
+struct uip_arp {
+	struct uip_eth eth;
+	u16 hwtype;
+	u16 proto;
+	u8 hwlen;
+	u8 protolen;
+	u16 op;
+	struct uip_eth_addr smac;
+	u32 sip;
+	struct uip_eth_addr dmac;
+	u32 dip;
+} __attribute__((packed));
+
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
@@ -60,6 +73,8 @@ struct uip_tx_arg {
 	int eth_len;
 };
 
+int uip_tx_do_arp(struct uip_tx_arg *arg);
+
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
 struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf);
 struct uip_buf *uip_buf_get_used(struct uip_info *info);
diff --git a/tools/kvm/uip/arp.c b/tools/kvm/uip/arp.c
new file mode 100644
index 0000000..98423da
--- /dev/null
+++ b/tools/kvm/uip/arp.c
@@ -0,0 +1,30 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_arp(struct uip_tx_arg *arg)
+{
+	struct uip_arp *arp, *arp2;
+	struct uip_info *info;
+	struct uip_buf *buf;
+
+	info = arg->info;
+	buf = uip_buf_clone(arg);
+
+	arp	 = (struct uip_arp *)(arg->eth);
+	arp2	 = (struct uip_arp *)(buf->eth);
+
+	/*
+	 * ARP replay code: 2
+	 */
+	arp2->op   = htons(0x2);
+	arp2->dmac = arp->smac;
+	arp2->dip  = arp->sip;
+
+	if (arp->dip == htonl(info->host_ip)) {
+		arp2->smac = info->host_mac;
+		arp2->sip = htonl(info->host_ip);
+
+		uip_buf_set_used(info, buf);
+	}
+
+	return 0;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 03/31] kvm tools: Add IPV4 support for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
  2011-06-30  8:40 ` [PATCH v2 01/31] kvm tools: Introduce ethernet frame buffer system for uip Asias He
  2011-06-30  8:40 ` [PATCH v2 02/31] kvm tools: Add ARP support " Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 04/31] kvm tools: Implement IP checksum " Asias He
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   28 ++++++++++++++++++++++++++++
 tools/kvm/uip/ipv4.c        |   15 +++++++++++++++
 3 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/ipv4.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 006218d..7dc5bb2 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -46,6 +46,7 @@ OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
 OBJS	+= irq.o
 OBJS	+= uip/arp.o
+OBJS	+= uip/ipv4.o
 OBJS	+= uip/buf.o
 OBJS	+= kvm-cmd.o
 OBJS	+= kvm-debug.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index c5eb417..e48420d 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -34,6 +34,23 @@ struct uip_arp {
 	u32 dip;
 } __attribute__((packed));
 
+struct uip_ip {
+	struct uip_eth eth;
+	u8 vhl;
+	u8 tos;
+	/*
+	 * len = IP hdr +  IP payload
+	 */
+	u16 len;
+	u16 id;
+	u16 flgfrag;
+	u8 ttl;
+	u8 proto;
+	u16 csum;
+	u32 sip;
+	u32 dip;
+} __attribute__((packed));
+
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
@@ -73,6 +90,17 @@ struct uip_tx_arg {
 	int eth_len;
 };
 
+static inline u16 uip_ip_hdrlen(struct uip_ip *ip)
+{
+	return (ip->vhl & 0x0f) * 4;
+}
+
+static inline u16 uip_ip_len(struct uip_ip *ip)
+{
+	return htons(ip->len);
+}
+
+int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c
new file mode 100644
index 0000000..da53fec
--- /dev/null
+++ b/tools/kvm/uip/ipv4.c
@@ -0,0 +1,15 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_ipv4(struct uip_tx_arg *arg)
+{
+	struct uip_ip *ip;
+
+	ip = (struct uip_ip *)(arg->eth);
+
+	if (uip_ip_hdrlen(ip) != 20) {
+		pr_warning("IP header length is not 20 bytes");
+		return -1;
+	}
+
+	return 0;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 04/31] kvm tools: Implement IP checksum for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (2 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 03/31] kvm tools: Add IPV4 " Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 05/31] kvm tools: Add ICMP support " Asias He
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |    2 ++
 tools/kvm/uip/csum.c        |   25 +++++++++++++++++++++++++
 3 files changed, 28 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/csum.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 7dc5bb2..ece542c 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -48,6 +48,7 @@ OBJS	+= irq.o
 OBJS	+= uip/arp.o
 OBJS	+= uip/ipv4.o
 OBJS	+= uip/buf.o
+OBJS	+= uip/csum.o
 OBJS	+= kvm-cmd.o
 OBJS	+= kvm-debug.o
 OBJS	+= kvm-help.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index e48420d..00100e1 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -103,6 +103,8 @@ static inline u16 uip_ip_len(struct uip_ip *ip)
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
+u16 uip_csum_ip(struct uip_ip *ip);
+
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
 struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf);
 struct uip_buf *uip_buf_get_used(struct uip_info *info);
diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c
new file mode 100644
index 0000000..8023ddb
--- /dev/null
+++ b/tools/kvm/uip/csum.c
@@ -0,0 +1,25 @@
+#include "kvm/uip.h"
+
+static u16 uip_csum(u16 csum, u8 *addr, u16 count)
+{
+	long sum = csum;
+
+	while (count > 1) {
+		sum	+= *(u16 *)addr;
+		addr	+= 2;
+		count	-= 2;
+	}
+
+	if (count > 0)
+		sum += *(unsigned char *)addr;
+
+	while (sum>>16)
+		sum = (sum & 0xffff) + (sum >> 16);
+
+	return ~sum;
+}
+
+u16 uip_csum_ip(struct uip_ip *ip)
+{
+	return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip));
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 05/31] kvm tools: Add ICMP support for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (3 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 04/31] kvm tools: Implement IP checksum " Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 06/31] kvm tools: Introduce struct uip_udp to present UDP package Asias He
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   11 +++++++++++
 tools/kvm/uip/csum.c        |    8 ++++++++
 tools/kvm/uip/icmp.c        |   29 +++++++++++++++++++++++++++++
 tools/kvm/uip/ipv4.c        |    8 ++++++++
 5 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/icmp.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index ece542c..9ad09a4 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -46,6 +46,7 @@ OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
 OBJS	+= irq.o
 OBJS	+= uip/arp.o
+OBJS	+= uip/icmp.o
 OBJS	+= uip/ipv4.o
 OBJS	+= uip/buf.o
 OBJS	+= uip/csum.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 00100e1..b9fa932 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -51,6 +51,15 @@ struct uip_ip {
 	u32 dip;
 } __attribute__((packed));
 
+struct uip_icmp {
+	struct uip_ip ip;
+	u8 type;
+	u8 code;
+	u16 csum;
+	u16 id;
+	u16 seq;
+} __attribute__((packed));
+
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
@@ -100,9 +109,11 @@ static inline u16 uip_ip_len(struct uip_ip *ip)
 	return htons(ip->len);
 }
 
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
+u16 uip_csum_icmp(struct uip_icmp *icmp);
 u16 uip_csum_ip(struct uip_ip *ip);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c
index 8023ddb..c86bfdf 100644
--- a/tools/kvm/uip/csum.c
+++ b/tools/kvm/uip/csum.c
@@ -23,3 +23,11 @@ u16 uip_csum_ip(struct uip_ip *ip)
 {
 	return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip));
 }
+
+u16 uip_csum_icmp(struct uip_icmp *icmp)
+{
+	struct uip_ip *ip;
+
+	ip = &icmp->ip;
+	return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
+}
diff --git a/tools/kvm/uip/icmp.c b/tools/kvm/uip/icmp.c
new file mode 100644
index 0000000..233297c
--- /dev/null
+++ b/tools/kvm/uip/icmp.c
@@ -0,0 +1,29 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg)
+{
+	struct uip_ip *ip, *ip2;
+	struct uip_icmp *icmp2;
+	struct uip_buf *buf;
+
+	buf		= uip_buf_clone(arg);
+
+	icmp2		= (struct uip_icmp *)(buf->eth);
+	ip2		= (struct uip_ip *)(buf->eth);
+	ip		= (struct uip_ip *)(arg->eth);
+
+	ip2->sip	= ip->dip;
+	ip2->dip	= ip->sip;
+	ip2->csum	= 0;
+	/*
+	 * ICMP reply: 0
+	 */
+	icmp2->type	= 0;
+	icmp2->csum	= 0;
+	ip2->csum	= uip_csum_ip(ip2);
+	icmp2->csum	= uip_csum_icmp(icmp2);
+
+	uip_buf_set_used(arg->info, buf);
+
+	return 0;
+}
diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c
index da53fec..6175992 100644
--- a/tools/kvm/uip/ipv4.c
+++ b/tools/kvm/uip/ipv4.c
@@ -11,5 +11,13 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg)
 		return -1;
 	}
 
+	switch (ip->proto) {
+	case 0x01: /* ICMP */
+		uip_tx_do_ipv4_icmp(arg);
+		break;
+	default:
+		break;
+	}
+
 	return 0;
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 06/31] kvm tools: Introduce struct uip_udp to present UDP package
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (4 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 05/31] kvm tools: Add ICMP support " Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 07/31] kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header Asias He
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index b9fa932..e220403 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -60,6 +60,21 @@ struct uip_icmp {
 	u16 seq;
 } __attribute__((packed));
 
+struct uip_udp {
+	/*
+	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
+	 */
+	struct uip_ip ip;
+	u16 sport;
+	u16 dport;
+	/*
+	 * len = UDP hdr +  UDP payload
+	 */
+	u16 len;
+	u16 csum;
+	u8 payload[0];
+} __attribute__((packed));
+
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 07/31] kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (5 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 06/31] kvm tools: Introduce struct uip_udp to present UDP package Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 08/31] kvm tools: Introduce struct uip_udp_socket Asias He
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

This pseudo header is used for UDP checksum.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index e220403..35c7c23 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -75,6 +75,14 @@ struct uip_udp {
 	u8 payload[0];
 } __attribute__((packed));
 
+struct uip_pseudo_hdr {
+	u32 sip;
+	u32 dip;
+	u8 zero;
+	u8 proto;
+	u16 len;
+} __attribute__((packed));
+
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 08/31] kvm tools: Introduce struct uip_udp_socket
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (6 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 07/31] kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 09/31] kvm tools: Add two helpers to return UDP {header, total} length Asias He
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

struct uip_udp_socket is used to present every "connection" between
guest and remote host.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 35c7c23..473b9c7 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -114,6 +114,15 @@ struct uip_buf {
 	int id;
 };
 
+struct uip_udp_socket {
+	struct sockaddr_in addr;
+	struct list_head list;
+	pthread_mutex_t *lock;
+	u32 dport, sport;
+	u32 dip, sip;
+	int fd;
+};
+
 struct uip_tx_arg {
 	struct virtio_net_hdr *vnet;
 	struct uip_info *info;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 09/31] kvm tools: Add two helpers to return UDP {header, total} length
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (7 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 08/31] kvm tools: Introduce struct uip_udp_socket Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 10/31] kvm tools: Add helper to return ethernet header length Asias He
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 473b9c7..e79cc4b 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -141,6 +141,16 @@ static inline u16 uip_ip_len(struct uip_ip *ip)
 	return htons(ip->len);
 }
 
+static inline u16 uip_udp_hdrlen(struct uip_udp *udp)
+{
+	return 8;
+}
+
+static inline u16 uip_udp_len(struct uip_udp *udp)
+{
+	return ntohs(udp->len);
+}
+
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 10/31] kvm tools: Add helper to return ethernet header length
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (8 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 09/31] kvm tools: Add two helpers to return UDP {header, total} length Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:40 ` [PATCH v2 11/31] kvm tools: Implement uip_csum_udp() to calculate UDP checksum Asias He
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index e79cc4b..979e2b0 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -151,6 +151,11 @@ static inline u16 uip_udp_len(struct uip_udp *udp)
 	return ntohs(udp->len);
 }
 
+static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
+{
+	return sizeof(*eth);
+}
+
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 11/31] kvm tools: Implement uip_csum_udp() to calculate UDP checksum
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (9 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 10/31] kvm tools: Add helper to return ethernet header length Asias He
@ 2011-06-30  8:40 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 12/31] kvm tools: Add UDP support for uip Asias He
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:40 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    1 +
 tools/kvm/uip/csum.c        |   29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 979e2b0..e2ad66a 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -161,6 +161,7 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
 u16 uip_csum_icmp(struct uip_icmp *icmp);
+u16 uip_csum_udp(struct uip_udp *udp);
 u16 uip_csum_ip(struct uip_ip *ip);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c
index c86bfdf..a152a0f 100644
--- a/tools/kvm/uip/csum.c
+++ b/tools/kvm/uip/csum.c
@@ -31,3 +31,32 @@ u16 uip_csum_icmp(struct uip_icmp *icmp)
 	ip = &icmp->ip;
 	return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
 }
+
+u16 uip_csum_udp(struct uip_udp *udp)
+{
+	struct uip_pseudo_hdr hdr;
+	struct uip_ip *ip;
+	int udp_len;
+	u8 *pad;
+
+	ip	  = &udp->ip;
+
+	hdr.sip   = ip->sip;
+	hdr.dip	  = ip->dip;
+	hdr.zero  = 0;
+	hdr.proto = ip->proto;
+	hdr.len   = udp->len;
+
+	udp_len	  = uip_udp_len(udp);
+
+	if (udp_len % 2) {
+		pad = (u8 *)&udp->sport + udp_len;
+		*pad = 0;
+		memcpy((u8 *)&udp->sport + udp_len + 1, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&udp->sport, udp_len + 1 + sizeof(hdr));
+	} else {
+		memcpy((u8 *)&udp->sport + udp_len, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&udp->sport, udp_len + sizeof(hdr));
+	}
+
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 12/31] kvm tools: Add UDP support for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (10 preceding siblings ...)
  2011-06-30  8:40 ` [PATCH v2 11/31] kvm tools: Implement uip_csum_udp() to calculate UDP checksum Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-07-01 11:46   ` Ingo Molnar
  2011-06-30  8:41 ` [PATCH v2 13/31] kvm tools: Introduce struct uip_tcp to present TCP package Asias He
                   ` (19 subsequent siblings)
  31 siblings, 1 reply; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   15 +++
 tools/kvm/uip/ipv4.c        |    3 +
 tools/kvm/uip/udp.c         |  221 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/udp.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 9ad09a4..f92cfdb 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -48,6 +48,7 @@ OBJS	+= irq.o
 OBJS	+= uip/arp.o
 OBJS	+= uip/icmp.o
 OBJS	+= uip/ipv4.o
+OBJS	+= uip/udp.o
 OBJS	+= uip/buf.o
 OBJS	+= uip/csum.o
 OBJS	+= kvm-cmd.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index e2ad66a..ccc1698 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -11,6 +11,20 @@
 #define UIP_BUF_STATUS_INUSE	1
 #define UIP_BUF_STATUS_USED	2
 
+#define UIP_ETH_P_IP		0X0800
+
+#define UIP_IP_VER_4		0X40
+#define UIP_IP_HDR_LEN		0X05
+#define UIP_IP_TTL		0X40
+#define UIP_IP_P_UDP		0X11
+
+/*
+ * IP package maxium len == 64 KBytes
+ * IP header == 20 Bytes
+ * UDP header == 8 Bytes
+ */
+#define UIP_MAX_UDP_PAYLOAD	(64*1024 - 20 -  8 - 1)
+
 struct uip_eth_addr {
 	u8 addr[6];
 };
@@ -157,6 +171,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 }
 
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c
index 6175992..75058cd 100644
--- a/tools/kvm/uip/ipv4.c
+++ b/tools/kvm/uip/ipv4.c
@@ -15,6 +15,9 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg)
 	case 0x01: /* ICMP */
 		uip_tx_do_ipv4_icmp(arg);
 		break;
+	case 0x11: /* UDP */
+		uip_tx_do_ipv4_udp(arg);
+		break;
 	default:
 		break;
 	}
diff --git a/tools/kvm/uip/udp.c b/tools/kvm/uip/udp.c
new file mode 100644
index 0000000..5f9d7a4
--- /dev/null
+++ b/tools/kvm/uip/udp.c
@@ -0,0 +1,221 @@
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+
+#define UIP_UDP_MAX_EVENTS 1000
+
+static struct uip_udp_socket *uip_udp_socket_find(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	struct uip_udp_socket *sk;
+	pthread_mutex_t *sk_lock;
+	struct epoll_event ev;
+	int flags;
+	int ret;
+
+	sk_head = &arg->info->udp_socket_head;
+	sk_lock = &arg->info->udp_socket_lock;
+
+	/*
+	 * Find existing sk
+	 */
+	mutex_lock(sk_lock);
+	list_for_each_entry(sk, sk_head, list) {
+		if (sk->sip == sip && sk->dip == dip && sk->sport == sport && sk->dport == dport) {
+			mutex_unlock(sk_lock);
+			return sk;
+		}
+	}
+	mutex_unlock(sk_lock);
+
+	/*
+	 * Allocate new one
+	 */
+	sk = malloc(sizeof(*sk));
+	memset(sk, 0, sizeof(*sk));
+
+	sk->lock = sk_lock;
+
+	sk->fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sk->fd < 0)
+		goto out;
+
+	/*
+	 * Set non-blocking
+	 */
+	flags = fcntl(sk->fd, F_GETFL, 0);
+	flags |= O_NONBLOCK;
+	fcntl(sk->fd, F_SETFL, flags);
+
+	/*
+	 * Add sk->fd to epoll_wait
+	 */
+	ev.events	= EPOLLIN;
+	ev.data.fd	= sk->fd;
+	ev.data.ptr	= sk;
+	if (arg->info->udp_epollfd <= 0)
+		arg->info->udp_epollfd = epoll_create(UIP_UDP_MAX_EVENTS);
+	ret = epoll_ctl(arg->info->udp_epollfd, EPOLL_CTL_ADD, sk->fd, &ev);
+	if (ret == -1)
+		pr_warning("epoll_ctl error");
+
+	sk->addr.sin_family	 = AF_INET;
+	sk->addr.sin_addr.s_addr = dip;
+	sk->addr.sin_port	 = dport;
+
+	sk->sip			 = sip;
+	sk->dip			 = dip;
+	sk->sport		 = sport;
+	sk->dport		 = dport;
+
+	mutex_lock(sk_lock);
+	list_add_tail(&sk->list, sk_head);
+	mutex_unlock(sk_lock);
+
+	return sk;
+
+out:
+	free(sk);
+	return NULL;
+}
+
+static int uip_udp_socket_send(struct uip_udp_socket *sk, struct uip_udp *udp)
+{
+	int len;
+	int ret;
+
+	len = ntohs(udp->len) - uip_udp_hdrlen(udp);
+
+	ret = sendto(sk->fd, udp->payload, len, 0, (struct sockaddr *)&sk->addr, sizeof(sk->addr));
+	if (ret != len)
+		return -1;
+
+	return 0;
+}
+
+static void *uip_udp_socket_thread(void *p)
+{
+	struct epoll_event events[UIP_UDP_MAX_EVENTS];
+	struct uip_udp_socket *sk;
+	struct uip_info *info;
+	struct uip_eth *eth2;
+	struct uip_udp *udp2;
+	struct uip_buf *buf;
+	struct uip_ip *ip2;
+	u8 *payload;
+	int nfds;
+	int ret;
+	int i;
+
+	info = p;
+
+	do {
+		payload = malloc(UIP_MAX_UDP_PAYLOAD);
+	} while (!payload);
+
+	while (1) {
+		nfds = epoll_wait(info->udp_epollfd, events, UIP_UDP_MAX_EVENTS, -1);
+
+		if (nfds == -1)
+			continue;
+
+		for (i = 0; i < nfds; i++) {
+
+			sk = events[i].data.ptr;
+			ret = recvfrom(sk->fd, payload, UIP_MAX_UDP_PAYLOAD, 0, NULL, NULL);
+			if (ret < 0)
+				continue;
+
+			/*
+			 * Get free buffer to send data to guest
+			 */
+			buf		= uip_buf_get_free(info);
+
+			/*
+			 * Cook a ethernet frame
+			 */
+			udp2		= (struct uip_udp *)(buf->eth);
+			eth2		= (struct uip_eth *)buf->eth;
+			ip2		= (struct uip_ip *)(buf->eth);
+
+			eth2->src	= info->host_mac;
+			eth2->dst	= info->guest_mac;
+			eth2->type	= htons(UIP_ETH_P_IP);
+
+			ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
+			ip2->tos	= 0;
+			ip2->id		= 0;
+			ip2->flgfrag	= 0;
+			ip2->ttl	= UIP_IP_TTL;
+			ip2->proto	= UIP_IP_P_UDP;
+			ip2->csum	= 0;
+			ip2->sip	= sk->dip;
+			ip2->dip	= sk->sip;
+
+			udp2->sport	= sk->dport;
+			udp2->dport	= sk->sport;
+			udp2->len	= htons(ret + uip_udp_hdrlen(udp2));
+			udp2->csum	= 0;
+
+			memcpy(udp2->payload, payload, ret);
+
+			ip2->len	= udp2->len + htons(uip_ip_hdrlen(ip2));
+			ip2->csum	= uip_csum_ip(ip2);
+			udp2->csum	= uip_csum_udp(udp2);
+
+			/*
+			 * virtio_net_hdr
+			 */
+			buf->vnet_len	= sizeof(struct virtio_net_hdr);
+			memset(buf->vnet, 0, buf->vnet_len);
+
+			buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
+
+			/*
+			 * Send data received from socket to guest
+			 */
+			uip_buf_set_used(info, buf);
+		}
+	}
+
+	free(payload);
+	pthread_exit(NULL);
+	return NULL;
+}
+
+int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg)
+{
+	struct uip_udp_socket *sk;
+	struct uip_info *info;
+	struct uip_udp *udp;
+	struct uip_ip *ip;
+	int ret;
+
+	udp	= (struct uip_udp *)(arg->eth);
+	ip	= (struct uip_ip *)(arg->eth);
+	info	= arg->info;
+
+	/*
+	 * Find socket we have allocated before, otherwise allocate one
+	 */
+	sk = uip_udp_socket_find(arg, ip->sip, ip->dip, udp->sport, udp->dport);
+	if (!sk)
+		return -1;
+
+	/*
+	 * Send out UDP data to remote host
+	 */
+	ret = uip_udp_socket_send(sk, udp);
+	if (ret)
+		return -1;
+
+	if (!info->udp_thread)
+		pthread_create(&info->udp_thread, NULL, uip_udp_socket_thread, (void *)info);
+
+	return 0;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 13/31] kvm tools: Introduce struct uip_tcp to present TCP package.
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (11 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 12/31] kvm tools: Add UDP support for uip Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 14/31] kvm tools: Introduce struct uip_tcp_socket Asias He
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index ccc1698..1368694 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -89,6 +89,22 @@ struct uip_udp {
 	u8 payload[0];
 } __attribute__((packed));
 
+struct uip_tcp {
+	/*
+	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
+	 */
+	struct uip_ip ip;
+	u16 sport;
+	u16 dport;
+	u32 seq;
+	u32 ack;
+	u8  off;
+	u8  flg;
+	u16 win;
+	u16 csum;
+	u16 urgent;
+} __attribute__((packed));
+
 struct uip_pseudo_hdr {
 	u32 sip;
 	u32 dip;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 14/31] kvm tools: Introduce struct uip_tcp_socket
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (12 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 13/31] kvm tools: Introduce struct uip_tcp to present TCP package Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 15/31] kvm tools: Add helpers to return TCP {header, total, payload} length Asias He
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

struct uip_tcp_socket is used to present every session
between guest and remote host.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 1368694..a772fdf 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -153,6 +153,28 @@ struct uip_udp_socket {
 	int fd;
 };
 
+struct uip_tcp_socket {
+	struct sockaddr_in addr;
+	struct list_head list;
+	struct uip_info *info;
+	pthread_mutex_t *lock;
+	pthread_t thread;
+	u32 dport, sport;
+	u32 guest_acked;
+	/*
+	 * Initial Sequence Number
+	 */
+	u32 isn_server;
+	u32 isn_guest;
+	u32 ack_server;
+	u32 seq_server;
+	int write_done;
+	int read_done;
+	u32 dip, sip;
+	u8 *payload;
+	int fd;
+};
+
 struct uip_tx_arg {
 	struct virtio_net_hdr *vnet;
 	struct uip_info *info;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 15/31] kvm tools: Add helpers to return TCP {header, total, payload} length
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (13 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 14/31] kvm tools: Introduce struct uip_tcp_socket Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 16/31] kvm tools: Add helper to return start address of TCP payload Asias He
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/include/kvm/uip.h |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index a772fdf..2ac48d7 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -203,6 +203,25 @@ static inline u16 uip_udp_len(struct uip_udp *udp)
 	return ntohs(udp->len);
 }
 
+static inline u16 uip_tcp_hdrlen(struct uip_tcp *tcp)
+{
+	return (tcp->off >> 4) * 4;
+}
+
+static inline u16 uip_tcp_len(struct uip_tcp *tcp)
+{
+	struct uip_ip *ip;
+
+	ip = &tcp->ip;
+
+	return uip_ip_len(ip) - uip_ip_hdrlen(ip);
+}
+
+static inline u16 uip_tcp_payloadlen(struct uip_tcp *tcp)
+{
+	return uip_tcp_len(tcp) - uip_tcp_hdrlen(tcp);
+}
+
 static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 {
 	return sizeof(*eth);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 16/31] kvm tools: Add helper to return start address of TCP payload
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (14 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 15/31] kvm tools: Add helpers to return TCP {header, total, payload} length Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 17/31] kvm tools: Add helpers to test whether SYN or FIN bit is set Asias He
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

uip_tcp_payload() returns start address of TCP payload in a TCP package.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 2ac48d7..a3fd1b0 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -222,6 +222,11 @@ static inline u16 uip_tcp_payloadlen(struct uip_tcp *tcp)
 	return uip_tcp_len(tcp) - uip_tcp_hdrlen(tcp);
 }
 
+static inline u8 *uip_tcp_payload(struct uip_tcp *tcp)
+{
+	return (u8 *)&tcp->sport + uip_tcp_hdrlen(tcp);
+}
+
 static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 {
 	return sizeof(*eth);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 17/31] kvm tools: Add helpers to test whether SYN or FIN bit is set.
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (15 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 16/31] kvm tools: Add helper to return start address of TCP payload Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 18/31] kvm tools: Add helper to allocate and get TCP initial sequence number Asias He
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/include/kvm/uip.h |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index a3fd1b0..5585680 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -18,6 +18,13 @@
 #define UIP_IP_TTL		0X40
 #define UIP_IP_P_UDP		0X11
 
+#define UIP_TCP_FLAG_FIN	1
+#define UIP_TCP_FLAG_SYN	2
+#define UIP_TCP_FLAG_RST	4
+#define UIP_TCP_FLAG_PSH	8
+#define UIP_TCP_FLAG_ACK	16
+#define UIP_TCP_FLAG_URG	32
+
 /*
  * IP package maxium len == 64 KBytes
  * IP header == 20 Bytes
@@ -227,6 +234,16 @@ static inline u8 *uip_tcp_payload(struct uip_tcp *tcp)
 	return (u8 *)&tcp->sport + uip_tcp_hdrlen(tcp);
 }
 
+static inline bool uip_tcp_is_syn(struct uip_tcp *tcp)
+{
+	return (tcp->flg & UIP_TCP_FLAG_SYN) != 0;
+}
+
+static inline bool uip_tcp_is_fin(struct uip_tcp *tcp)
+{
+	return (tcp->flg & UIP_TCP_FLAG_FIN) != 0;
+}
+
 static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 {
 	return sizeof(*eth);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 18/31] kvm tools: Add helper to allocate and get TCP initial sequence number
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (16 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 17/31] kvm tools: Add helpers to test whether SYN or FIN bit is set Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 19/31] kvm tools: Implement uip_csum_tcp() to calculate TCP checksum Asias He
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/include/kvm/uip.h |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 5585680..46cec20 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -244,6 +244,19 @@ static inline bool uip_tcp_is_fin(struct uip_tcp *tcp)
 	return (tcp->flg & UIP_TCP_FLAG_FIN) != 0;
 }
 
+static inline u32 uip_tcp_isn(struct uip_tcp *tcp)
+{
+	return ntohl(tcp->seq);
+}
+
+static inline u32 uip_tcp_isn_alloc(void)
+{
+	/*
+	 * FIXME: should increase every 4ms
+	 */
+	return 10000000;
+}
+
 static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 {
 	return sizeof(*eth);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 19/31] kvm tools: Implement uip_csum_tcp() to calculate TCP checksum
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (17 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 18/31] kvm tools: Add helper to allocate and get TCP initial sequence number Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 20/31] kvm tools: Add TCP support for uip Asias He
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/uip.h |    3 +++
 tools/kvm/uip/csum.c        |   30 ++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 46cec20..37c87c6 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -28,8 +28,10 @@
 /*
  * IP package maxium len == 64 KBytes
  * IP header == 20 Bytes
+ * TCP header == 20 Bytes
  * UDP header == 8 Bytes
  */
+#define UIP_MAX_TCP_PAYLOAD	(64*1024 - 20 - 20 - 1)
 #define UIP_MAX_UDP_PAYLOAD	(64*1024 - 20 -  8 - 1)
 
 struct uip_eth_addr {
@@ -269,6 +271,7 @@ int uip_tx_do_arp(struct uip_tx_arg *arg);
 
 u16 uip_csum_icmp(struct uip_icmp *icmp);
 u16 uip_csum_udp(struct uip_udp *udp);
+u16 uip_csum_tcp(struct uip_tcp *tcp);
 u16 uip_csum_ip(struct uip_ip *ip);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c
index a152a0f..7ca8bad 100644
--- a/tools/kvm/uip/csum.c
+++ b/tools/kvm/uip/csum.c
@@ -60,3 +60,33 @@ u16 uip_csum_udp(struct uip_udp *udp)
 	}
 
 }
+
+u16 uip_csum_tcp(struct uip_tcp *tcp)
+{
+	struct uip_pseudo_hdr hdr;
+	struct uip_ip *ip;
+	u16 tcp_len;
+	u8 *pad;
+
+	ip	  = &tcp->ip;
+	tcp_len   = ntohs(ip->len) - uip_ip_hdrlen(ip);
+
+	hdr.sip   = ip->sip;
+	hdr.dip	  = ip->dip;
+	hdr.zero  = 0;
+	hdr.proto = ip->proto;
+	hdr.len   = htons(tcp_len);
+
+	if (tcp_len > UIP_MAX_TCP_PAYLOAD + 20)
+		pr_warning("tcp_len(%d) is too large", tcp_len);
+
+	if (tcp_len % 2) {
+		pad = (u8 *)&tcp->sport + tcp_len;
+		*pad = 0;
+		memcpy((u8 *)&tcp->sport + tcp_len + 1, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&tcp->sport, tcp_len + 1 + sizeof(hdr));
+	} else {
+		memcpy((u8 *)&tcp->sport + tcp_len, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&tcp->sport, tcp_len + sizeof(hdr));
+	}
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 20/31] kvm tools: Add TCP support for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (18 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 19/31] kvm tools: Implement uip_csum_tcp() to calculate TCP checksum Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 21/31] kvm tools: Introduce uip_init() " Asias He
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |    4 +
 tools/kvm/uip/ipv4.c        |    3 +
 tools/kvm/uip/tcp.c         |  317 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 325 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/tcp.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index f92cfdb..c088718 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -48,6 +48,7 @@ OBJS	+= irq.o
 OBJS	+= uip/arp.o
 OBJS	+= uip/icmp.o
 OBJS	+= uip/ipv4.o
+OBJS	+= uip/tcp.o
 OBJS	+= uip/udp.o
 OBJS	+= uip/buf.o
 OBJS	+= uip/csum.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 37c87c6..893c5f8 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -17,7 +17,10 @@
 #define UIP_IP_HDR_LEN		0X05
 #define UIP_IP_TTL		0X40
 #define UIP_IP_P_UDP		0X11
+#define UIP_IP_P_TCP		0X06
 
+#define UIP_TCP_HDR_LEN		0x50
+#define UIP_TCP_WIN_SIZE	14600
 #define UIP_TCP_FLAG_FIN	1
 #define UIP_TCP_FLAG_SYN	2
 #define UIP_TCP_FLAG_RST	4
@@ -265,6 +268,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 }
 
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c
index 75058cd..4def129 100644
--- a/tools/kvm/uip/ipv4.c
+++ b/tools/kvm/uip/ipv4.c
@@ -15,6 +15,9 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg)
 	case 0x01: /* ICMP */
 		uip_tx_do_ipv4_icmp(arg);
 		break;
+	case 0x06: /* TCP */
+		uip_tx_do_ipv4_tcp(arg);
+		break;
 	case 0x11: /* UDP */
 		uip_tx_do_ipv4_udp(arg);
 		break;
diff --git a/tools/kvm/uip/tcp.c b/tools/kvm/uip/tcp.c
new file mode 100644
index 0000000..586a45c
--- /dev/null
+++ b/tools/kvm/uip/tcp.c
@@ -0,0 +1,317 @@
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+static int uip_tcp_socket_close(struct uip_tcp_socket *sk, int how)
+{
+	shutdown(sk->fd, how);
+
+	if (sk->write_done && sk->read_done) {
+		shutdown(sk->fd, SHUT_RDWR);
+		close(sk->fd);
+
+		mutex_lock(sk->lock);
+		list_del(&sk->list);
+		mutex_unlock(sk->lock);
+
+		free(sk);
+	}
+
+	return 0;
+}
+
+static struct uip_tcp_socket *uip_tcp_socket_find(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	pthread_mutex_t *sk_lock;
+	struct uip_tcp_socket *sk;
+
+	sk_head = &arg->info->tcp_socket_head;
+	sk_lock = &arg->info->tcp_socket_lock;
+
+	mutex_lock(sk_lock);
+	list_for_each_entry(sk, sk_head, list) {
+		if (sk->sip == sip && sk->dip == dip && sk->sport == sport && sk->dport == dport) {
+			mutex_unlock(sk_lock);
+			return sk;
+		}
+	}
+	mutex_unlock(sk_lock);
+
+	return NULL;
+}
+
+static struct uip_tcp_socket *uip_tcp_socket_alloc(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	struct uip_tcp_socket *sk;
+	pthread_mutex_t *sk_lock;
+	struct uip_tcp *tcp;
+	struct uip_ip *ip;
+	int ret;
+
+	tcp = (struct uip_tcp *)arg->eth;
+	ip = (struct uip_ip *)arg->eth;
+
+	sk_head = &arg->info->tcp_socket_head;
+	sk_lock = &arg->info->tcp_socket_lock;
+
+	sk = malloc(sizeof(*sk));
+	memset(sk, 0, sizeof(*sk));
+
+	sk->lock			= sk_lock;
+	sk->info			= arg->info;
+
+	sk->fd				= socket(AF_INET, SOCK_STREAM, 0);
+	sk->addr.sin_family		= AF_INET;
+	sk->addr.sin_addr.s_addr	= dip;
+	sk->addr.sin_port		= dport;
+
+	ret = connect(sk->fd, (struct sockaddr *)&sk->addr, sizeof(sk->addr));
+	if (ret) {
+		free(sk);
+		return NULL;
+	}
+
+	sk->sip		= ip->sip;
+	sk->dip		= ip->dip;
+	sk->sport	= tcp->sport;
+	sk->dport	= tcp->dport;
+
+	mutex_lock(sk_lock);
+	list_add_tail(&sk->list, sk_head);
+	mutex_unlock(sk_lock);
+
+	return sk;
+}
+
+static int uip_tcp_payload_send(struct uip_tcp_socket *sk, u8 flag, u16 payload_len)
+{
+	struct uip_info *info;
+	struct uip_eth *eth2;
+	struct uip_tcp *tcp2;
+	struct uip_buf *buf;
+	struct uip_ip *ip2;
+
+	info		= sk->info;
+
+	/*
+	 * Get free buffer to send data to guest
+	 */
+	buf		= uip_buf_get_free(info);
+
+	/*
+	 * Cook a ethernet frame
+	 */
+	tcp2		= (struct uip_tcp *)buf->eth;
+	eth2		= (struct uip_eth *)buf->eth;
+	ip2		= (struct uip_ip *)buf->eth;
+
+	eth2->src	= info->host_mac;
+	eth2->dst	= info->guest_mac;
+	eth2->type	= htons(UIP_ETH_P_IP);
+
+	ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
+	ip2->tos	= 0;
+	ip2->id		= 0;
+	ip2->flgfrag	= 0;
+	ip2->ttl	= UIP_IP_TTL;
+	ip2->proto	= UIP_IP_P_TCP;
+	ip2->csum	= 0;
+	ip2->sip	= sk->dip;
+	ip2->dip	= sk->sip;
+
+	tcp2->sport	= sk->dport;
+	tcp2->dport	= sk->sport;
+	tcp2->seq	= htonl(sk->seq_server);
+	tcp2->ack	= htonl(sk->ack_server);
+	/*
+	 * Diable TCP options, tcp hdr len equals 20 bytes
+	 */
+	tcp2->off	= UIP_TCP_HDR_LEN;
+	tcp2->flg	= flag;
+	tcp2->win	= htons(UIP_TCP_WIN_SIZE);
+	tcp2->csum	= 0;
+	tcp2->urgent	= 0;
+
+	if (payload_len > 0)
+		memcpy(uip_tcp_payload(tcp2), sk->payload, payload_len);
+
+	ip2->len	= htons(uip_tcp_hdrlen(tcp2) + payload_len + uip_ip_hdrlen(ip2));
+	ip2->csum	= uip_csum_ip(ip2);
+	tcp2->csum	= uip_csum_tcp(tcp2);
+
+	/*
+	 * virtio_net_hdr
+	 */
+	buf->vnet_len	= sizeof(struct virtio_net_hdr);
+	memset(buf->vnet, 0, buf->vnet_len);
+
+	buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
+
+	/*
+	 * Increase server seq
+	 */
+	sk->seq_server  += payload_len;
+
+	/*
+	 * Send data received from socket to guest
+	 */
+	uip_buf_set_used(info, buf);
+
+	return 0;
+}
+
+static void *uip_tcp_socket_thread(void *p)
+{
+	struct uip_tcp_socket *sk;
+	u8 *payload;
+	int ret;
+
+	sk = p;
+
+	payload = malloc(UIP_MAX_TCP_PAYLOAD);
+	sk->payload = payload;
+	if (!sk->payload)
+		goto out;
+
+	while (1) {
+
+		ret = read(sk->fd, payload, UIP_MAX_TCP_PAYLOAD);
+
+		if (ret <= 0 || ret > UIP_MAX_TCP_PAYLOAD)
+			goto out;
+
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, ret);
+
+	}
+
+out:
+	/*
+	 * Close server to guest TCP connection
+	 */
+	uip_tcp_socket_close(sk, SHUT_RD);
+
+	uip_tcp_payload_send(sk, UIP_TCP_FLAG_FIN | UIP_TCP_FLAG_ACK, 0);
+	sk->seq_server += 1;
+
+	sk->read_done = 1;
+
+	free(sk->payload);
+	pthread_exit(NULL);
+
+	return NULL;
+}
+
+static int uip_tcp_socket_receive(struct uip_tcp_socket *sk)
+{
+	if (sk->thread == 0)
+		return pthread_create(&sk->thread, NULL, uip_tcp_socket_thread, (void *)sk);
+
+	return 0;
+}
+
+static int uip_tcp_socket_send(struct uip_tcp_socket *sk, struct uip_tcp *tcp)
+{
+	int len;
+	int ret;
+	u8 *payload;
+
+	if (sk->write_done)
+		return 0;
+
+	payload = uip_tcp_payload(tcp);
+	len = uip_tcp_payloadlen(tcp);
+
+	ret = write(sk->fd, payload, len);
+	if (ret != len)
+		pr_warning("tcp send error");
+
+	return ret;
+}
+
+int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg)
+{
+	struct uip_tcp_socket *sk;
+	struct uip_tcp *tcp;
+	struct uip_ip *ip;
+	int ret;
+
+	tcp = (struct uip_tcp *)arg->eth;
+	ip = (struct uip_ip *)arg->eth;
+
+	/*
+	 * Guest is trying to start a TCP session, let's fake SYN-ACK to guest
+	 */
+	if (uip_tcp_is_syn(tcp)) {
+		sk = uip_tcp_socket_alloc(arg, ip->sip, ip->dip, tcp->sport, tcp->dport);
+		if (!sk)
+			return -1;
+
+		/*
+		 * Setup ISN number
+		 */
+		sk->isn_guest  = uip_tcp_isn(tcp);
+		sk->isn_server = uip_tcp_isn_alloc();
+
+		sk->seq_server = sk->isn_server;
+		sk->ack_server = sk->isn_guest + 1;
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_SYN | UIP_TCP_FLAG_ACK, 0);
+		sk->seq_server += 1;
+
+		/*
+		 * Start receive thread for data from remote to guest
+		 */
+		uip_tcp_socket_receive(sk);
+
+		goto out;
+	}
+
+	/*
+	 * Find socket we have allocated
+	 */
+	sk = uip_tcp_socket_find(arg, ip->sip, ip->dip, tcp->sport, tcp->dport);
+	if (!sk)
+		return -1;
+
+	sk->guest_acked = ntohl(tcp->ack);
+
+	if (uip_tcp_is_fin(tcp)) {
+		if (sk->write_done)
+			goto out;
+
+		sk->write_done = 1;
+		sk->ack_server += 1;
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, 0);
+
+		/*
+		 * Close guest to server TCP connection
+		 */
+		uip_tcp_socket_close(sk, SHUT_WR);
+
+		goto out;
+	}
+
+	/*
+	 * Ignore guest to server frames with zero tcp payload
+	 */
+	if (uip_tcp_payloadlen(tcp) == 0)
+		goto out;
+
+	/*
+	 * Sent out TCP data to remote host
+	 */
+	ret = uip_tcp_socket_send(sk, tcp);
+	if (ret < 0)
+		return -1;
+	/*
+	 * Send ACK to guest imediately
+	 */
+	sk->ack_server += ret;
+	uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, 0);
+
+out:
+	return 0;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 21/31] kvm tools: Introduce uip_init() for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (19 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 20/31] kvm tools: Add TCP support for uip Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 22/31] kvm tools: Introduce uip_tx() " Asias He
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- Initialize TCP/UDP socket list, ethernet buffer list.

- Allocate memory for ethernet buffer.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |    2 +
 tools/kvm/uip/core.c        |   58 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/core.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index c088718..733769d 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -45,6 +45,7 @@ OBJS	+= disk/qcow.o
 OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
 OBJS	+= irq.o
+OBJS	+= uip/core.o
 OBJS	+= uip/arp.o
 OBJS	+= uip/icmp.o
 OBJS	+= uip/ipv4.o
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 893c5f8..c300de0 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -267,6 +267,8 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 	return sizeof(*eth);
 }
 
+int uip_init(struct uip_info *info);
+
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg);
diff --git a/tools/kvm/uip/core.c b/tools/kvm/uip/core.c
new file mode 100644
index 0000000..58eba6b
--- /dev/null
+++ b/tools/kvm/uip/core.c
@@ -0,0 +1,58 @@
+#include "kvm/mutex.h"
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+int uip_init(struct uip_info *info)
+{
+	struct list_head *udp_socket_head;
+	struct list_head *tcp_socket_head;
+	struct list_head *buf_head;
+	struct uip_buf *buf;
+	int buf_nr;
+	int i;
+
+	udp_socket_head	= &info->udp_socket_head;
+	tcp_socket_head	= &info->tcp_socket_head;
+	buf_head	= &info->buf_head;
+	buf_nr		= info->buf_nr;
+
+	INIT_LIST_HEAD(udp_socket_head);
+	INIT_LIST_HEAD(tcp_socket_head);
+	INIT_LIST_HEAD(buf_head);
+
+	pthread_mutex_init(&info->udp_socket_lock, NULL);
+	pthread_mutex_init(&info->tcp_socket_lock, NULL);
+	pthread_mutex_init(&info->buf_lock, NULL);
+
+	pthread_cond_init(&info->buf_used_cond, NULL);
+	pthread_cond_init(&info->buf_free_cond, NULL);
+
+
+	for (i = 0; i < buf_nr; i++) {
+		buf = malloc(sizeof(*buf));
+		memset(buf, 0, sizeof(*buf));
+
+		buf->status	= UIP_BUF_STATUS_FREE;
+		buf->info	= info;
+		buf->id		= i;
+		list_add_tail(&buf->list, buf_head);
+	}
+
+	list_for_each_entry(buf, buf_head, list) {
+		buf->vnet	= malloc(sizeof(struct virtio_net_hdr));
+		buf->vnet_len	= sizeof(struct virtio_net_hdr);
+		buf->eth	= malloc(1024*64 + sizeof(struct uip_pseudo_hdr));
+		buf->eth_len	= 1024*64 + sizeof(struct uip_pseudo_hdr);
+
+		memset(buf->vnet, 0, buf->vnet_len);
+		memset(buf->eth, 0, buf->eth_len);
+	}
+
+	info->buf_free_nr = buf_nr;
+	info->buf_used_nr = 0;
+
+	return 0;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 22/31] kvm tools: Introduce uip_tx() for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (20 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 21/31] kvm tools: Introduce uip_init() " Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 23/31] kvm tools: Introduce uip_rx() " Asias He
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/include/kvm/uip.h |    2 +
 tools/kvm/uip/core.c        |   69 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index c300de0..38ad386 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -12,6 +12,7 @@
 #define UIP_BUF_STATUS_USED	2
 
 #define UIP_ETH_P_IP		0X0800
+#define UIP_ETH_P_ARP		0X0806
 
 #define UIP_IP_VER_4		0X40
 #define UIP_IP_HDR_LEN		0X05
@@ -267,6 +268,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 	return sizeof(*eth);
 }
 
+int uip_tx(struct iovec *iov, u16 out, struct uip_info *info);
 int uip_init(struct uip_info *info);
 
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
diff --git a/tools/kvm/uip/core.c b/tools/kvm/uip/core.c
index 58eba6b..3a37546 100644
--- a/tools/kvm/uip/core.c
+++ b/tools/kvm/uip/core.c
@@ -5,6 +5,75 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 
+int uip_tx(struct iovec *iov, u16 out, struct uip_info *info)
+{
+	struct virtio_net_hdr *vnet;
+	struct uip_tx_arg arg;
+	int eth_len, vnet_len;
+	struct uip_eth *eth;
+	u8 *buf = NULL;
+	u16 proto;
+	int i;
+
+	/*
+	 * Buffer from guest to device
+	 */
+	vnet_len = iov[0].iov_len;
+	vnet	 = iov[0].iov_base;
+
+	eth_len	 = iov[1].iov_len;
+	eth	 = iov[1].iov_base;
+
+	/*
+	 * In case, ethernet frame is in more than one iov entry.
+	 * Copy iov buffer into one linear buffer.
+	 */
+	if (out > 2) {
+		eth_len = 0;
+		for (i = 1; i < out; i++)
+			eth_len += iov[i].iov_len;
+
+		buf = malloc(eth_len);
+		if (!buf)
+			return -1;
+
+		eth = (struct uip_eth *)buf;
+		for (i = 1; i < out; i++) {
+			memcpy(buf, iov[i].iov_base, iov[i].iov_len);
+			buf += iov[i].iov_len;
+		}
+	}
+
+	memset(&arg, 0, sizeof(arg));
+
+	arg.vnet_len = vnet_len;
+	arg.eth_len = eth_len;
+	arg.info = info;
+	arg.vnet = vnet;
+	arg.eth = eth;
+
+	/*
+	 * Check package type
+	 */
+	proto = ntohs(eth->type);
+
+	switch (proto) {
+	case UIP_ETH_P_ARP:
+		uip_tx_do_arp(&arg);
+		break;
+	case UIP_ETH_P_IP:
+		uip_tx_do_ipv4(&arg);
+		break;
+	default:
+		break;
+	}
+
+	if (out > 2 && buf)
+		free(eth);
+
+	return vnet_len + eth_len;
+}
+
 int uip_init(struct uip_info *info)
 {
 	struct list_head *udp_socket_head;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 23/31] kvm tools: Introduce uip_rx() for uip
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (21 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 22/31] kvm tools: Introduce uip_tx() " Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 24/31] kvm tools: Add MACRO for user and tap mode for virtio net Asias He
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

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>
---
 tools/kvm/include/kvm/uip.h |    1 +
 tools/kvm/uip/core.c        |   61 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 38ad386..18849d2 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -269,6 +269,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
 }
 
 int uip_tx(struct iovec *iov, u16 out, struct uip_info *info);
+int uip_rx(struct iovec *iov, u16 in, struct uip_info *info);
 int uip_init(struct uip_info *info);
 
 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
diff --git a/tools/kvm/uip/core.c b/tools/kvm/uip/core.c
index 3a37546..7a4b824 100644
--- a/tools/kvm/uip/core.c
+++ b/tools/kvm/uip/core.c
@@ -74,6 +74,67 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info)
 	return vnet_len + eth_len;
 }
 
+int uip_rx(struct iovec *iov, u16 in, struct uip_info *info)
+{
+	struct virtio_net_hdr *vnet;
+	struct uip_eth *eth;
+	struct uip_buf *buf;
+	int vnet_len;
+	int eth_len;
+	char *p;
+	int len;
+	int cnt;
+	int i;
+
+	/*
+	 * Sleep until there is a buffer for guest
+	 */
+	buf = uip_buf_get_used(info);
+
+	/*
+	 * Fill device to guest buffer, vnet hdr fisrt
+	 */
+	vnet_len = iov[0].iov_len;
+	vnet = iov[0].iov_base;
+	if (buf->vnet_len > vnet_len) {
+		len = -1;
+		goto out;
+	}
+	memcpy(vnet, buf->vnet, buf->vnet_len);
+
+	/*
+	 * Then, the real eth data
+	 * Note: Be sure buf->eth_len is not bigger than the buffer len that guest provides
+	 */
+	cnt = buf->eth_len;
+	p = buf->eth;
+	for (i = 1; i < in; i++) {
+		eth_len = iov[i].iov_len;
+		eth = iov[i].iov_base;
+		if (cnt > eth_len) {
+			memcpy(eth, p, eth_len);
+			cnt -= eth_len;
+			p += eth_len;
+		} else {
+			memcpy(eth, p, cnt);
+			cnt -= cnt;
+			break;
+		}
+	}
+
+	if (cnt) {
+		pr_warning("uip_rx error");
+		len = -1;
+		goto out;
+	}
+
+	len = buf->vnet_len + buf->eth_len;
+
+out:
+	uip_buf_set_free(info, buf);
+	return len;
+}
+
 int uip_init(struct uip_info *info)
 {
 	struct list_head *udp_socket_head;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 24/31] kvm tools: Add MACRO for user and tap mode for virtio net
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (22 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 23/31] kvm tools: Introduce uip_rx() " Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 25/31] kvm tools: Reanme net_device to net_dev Asias He
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

This patch prepares the user and tap mode for virtio net.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/include/kvm/virtio-net.h |    4 ++++
 tools/kvm/virtio/net.c             |    3 +++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/virtio-net.h b/tools/kvm/include/kvm/virtio-net.h
index 00f3220..e93e8e4 100644
--- a/tools/kvm/include/kvm/virtio-net.h
+++ b/tools/kvm/include/kvm/virtio-net.h
@@ -8,8 +8,12 @@ struct virtio_net_parameters {
 	const char *host_ip;
 	char guest_mac[6];
 	const char *script;
+	int mode;
 };
 
 void virtio_net__init(const struct virtio_net_parameters *params);
 
+#define NET_MODE_USER	0
+#define NET_MODE_TAP	1
+
 #endif /* KVM__VIRTIO_NET_H */
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 6916af6..68967f2 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -63,6 +63,9 @@ struct net_device {
 
 	int				tap_fd;
 	char				tap_name[IFNAMSIZ];
+
+	int				mode;
+
 };
 
 static struct net_device ndev = {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 25/31] kvm tools: Reanme net_device to net_dev
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (23 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 24/31] kvm tools: Add MACRO for user and tap mode for virtio net Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 26/31] kvm tools: Introduce -net {user, tap, none} options for virtio net Asias He
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

This patch makes virtio net device's name convention consistent with others in
virtio/*.c.  struct {net_dev, blk_dev, con_dev, rng_dev, p9_dev}.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/virtio/net.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 68967f2..7eebee0 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -40,7 +40,7 @@ static struct pci_device_header pci_header = {
 	.subsys_id			= VIRTIO_ID_NET,
 };
 
-struct net_device {
+struct net_dev {
 	pthread_mutex_t			mutex;
 
 	struct virt_queue		vqs[VIRTIO_NET_NUM_QUEUES];
@@ -68,8 +68,9 @@ struct net_device {
 
 };
 
-static struct net_device ndev = {
-	.mutex				= PTHREAD_MUTEX_INITIALIZER,
+
+static struct net_dev ndev = {
+	.mutex	= PTHREAD_MUTEX_INITIALIZER,
 
 	.config = {
 		.mac			= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 26/31] kvm tools: Introduce -net {user, tap, none} options for virtio net
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (24 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 25/31] kvm tools: Reanme net_device to net_dev Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 27/31] kvm tools: Change default guest MAC address to 00:15:15:15:15:15 Asias He
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Use '-net user' to enable user model network, which enables plain user
without speical privileges to use network in guest.

Use '-net tap' to enable tap based network, which requres special
privileges.

Use '-net none' to disable virtio net.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/kvm-run.c |   34 +++++++++++++++++++---------------
 1 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index 0dece2d..0ac2ed8 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -154,7 +154,7 @@ static const struct option options[] = {
 			"Kernel command line arguments"),
 
 	OPT_GROUP("Networking options:"),
-	OPT_STRING('n', "network", &network, "virtio",
+	OPT_STRING('n', "network", &network, "user, tap, none",
 			"Network to use"),
 	OPT_STRING('\0', "host-ip-addr", &host_ip_addr, "a.b.c.d",
 			"Assign this address to the host side networking"),
@@ -629,20 +629,24 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	if (!network)
 		network = DEFAULT_NETWORK;
 
-	if (!strncmp(network, "virtio", 6)) {
-		net_params = (struct virtio_net_parameters) {
-			.host_ip = host_ip_addr,
-			.kvm = kvm,
-			.script = script
-		};
-		sscanf(guest_mac,	"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-							net_params.guest_mac,
-							net_params.guest_mac+1,
-							net_params.guest_mac+2,
-							net_params.guest_mac+3,
-							net_params.guest_mac+4,
-							net_params.guest_mac+5);
-
+	if (strncmp(network, "none", 4)) {
+		net_params.host_ip = host_ip_addr;
+		net_params.kvm = kvm;
+		net_params.script = script;
+		sscanf(guest_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+			net_params.guest_mac,
+			net_params.guest_mac+1,
+			net_params.guest_mac+2,
+			net_params.guest_mac+3,
+			net_params.guest_mac+4,
+			net_params.guest_mac+5);
+
+		if (!strncmp(network, "user", 4))
+			net_params.mode = NET_MODE_USER;
+		else if (!strncmp(network, "tap", 3))
+			net_params.mode = NET_MODE_TAP;
+		else
+			die("Unkown network mode %s, please use -network user, tap, none", network);
 		virtio_net__init(&net_params);
 	}
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 27/31] kvm tools: Change default guest MAC address to 00:15:15:15:15:15
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (25 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 26/31] kvm tools: Introduce -net {user, tap, none} options for virtio net Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 28/31] kvm tools: Make virtio net work with user mode network Asias He
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

This patch makes guest MAC address the last portion of
default guest IP address which is 192.168.33.15.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/kvm-run.c    |    2 +-
 tools/kvm/virtio/net.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index 0ac2ed8..a16a482 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -44,7 +44,7 @@
 #define DEFAULT_CONSOLE		"serial"
 #define DEFAULT_NETWORK		"virtio"
 #define DEFAULT_HOST_ADDR	"192.168.33.2"
-#define DEFAULT_GUEST_MAC	"00:11:22:33:44:55"
+#define DEFAULT_GUEST_MAC	"00:15:15:15:15:15"
 #define DEFAULT_SCRIPT		"none"
 
 #define MB_SHIFT		(20)
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 7eebee0..38f0c9b 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -73,7 +73,7 @@ static struct net_dev ndev = {
 	.mutex	= PTHREAD_MUTEX_INITIALIZER,
 
 	.config = {
-		.mac			= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
+		.mac			= {0x00, 0x15, 0x15, 0x15, 0x15, 0x15},
 		.status			= VIRTIO_NET_S_LINK_UP,
 	},
 	.host_features			= 1UL << VIRTIO_NET_F_MAC
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 28/31] kvm tools: Make virtio net work with user mode network
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (26 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 27/31] kvm tools: Change default guest MAC address to 00:15:15:15:15:15 Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 29/31] kvm tools: Make default network mode to user mode Asias He
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

- Call uip_rx() and uip_tx() in virtio_net_rx_thread() and
  virtio_net_tx_thread() if user mode network is enabled.

- Initialize uip in virtio_net__init() if user mode network is enabled.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/virtio/net.c |  100 +++++++++++++++++++++++++++++-------------------
 1 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 38f0c9b..98d4120 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -1,5 +1,5 @@
-#include "kvm/virtio-net.h"
 #include "kvm/virtio-pci-dev.h"
+#include "kvm/virtio-net.h"
 #include "kvm/virtio.h"
 #include "kvm/ioport.h"
 #include "kvm/types.h"
@@ -8,6 +8,7 @@
 #include "kvm/kvm.h"
 #include "kvm/pci.h"
 #include "kvm/irq.h"
+#include "kvm/uip.h"
 #include "kvm/ioeventfd.h"
 
 #include <linux/virtio_net.h>
@@ -66,6 +67,7 @@ struct net_dev {
 
 	int				mode;
 
+	struct uip_info			info;
 };
 
 
@@ -84,6 +86,12 @@ static struct net_dev ndev = {
 					| 1UL << VIRTIO_NET_F_GUEST_UFO
 					| 1UL << VIRTIO_NET_F_GUEST_TSO4
 					| 1UL << VIRTIO_NET_F_GUEST_TSO6,
+	.info = {
+		.host_mac.addr		= {0x00, 0x01, 0x01, 0x01, 0x01, 0x01},
+		.guest_mac.addr		= {0x00, 0x15, 0x15, 0x15, 0x15, 0x15},
+		.host_ip		= 0xc0a82101,
+		.buf_nr			= 20,
+	}
 };
 
 static void *virtio_net_rx_thread(void *p)
@@ -99,14 +107,21 @@ static void *virtio_net_rx_thread(void *p)
 	vq	= &ndev.vqs[VIRTIO_NET_RX_QUEUE];
 
 	while (1) {
+
 		mutex_lock(&ndev.io_rx_lock);
 		if (!virt_queue__available(vq))
 			pthread_cond_wait(&ndev.io_rx_cond, &ndev.io_rx_lock);
 		mutex_unlock(&ndev.io_rx_lock);
 
 		while (virt_queue__available(vq)) {
+
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
-			len  = readv(ndev.tap_fd, iov, in);
+
+			if (ndev.mode == NET_MODE_TAP)
+				len = readv(ndev.tap_fd, iov, in);
+			else
+				len = uip_rx(iov, in, &ndev.info);
+
 			virt_queue__set_used_elem(vq, head, len);
 
 			/* We should interrupt guest right now, otherwise latency is huge. */
@@ -139,8 +154,14 @@ static void *virtio_net_tx_thread(void *p)
 		mutex_unlock(&ndev.io_tx_lock);
 
 		while (virt_queue__available(vq)) {
+
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
-			len  = writev(ndev.tap_fd, iov, out);
+
+			if (ndev.mode == NET_MODE_TAP)
+				len = writev(ndev.tap_fd, iov, out);
+			else
+				len = uip_tx(iov, out, &ndev.info);
+
 			virt_queue__set_used_elem(vq, head, len);
 		}
 
@@ -216,18 +237,16 @@ static bool virtio_net_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 por
 static void virtio_net_handle_callback(struct kvm *kvm, u16 queue_index)
 {
 	switch (queue_index) {
-	case VIRTIO_NET_TX_QUEUE: {
+	case VIRTIO_NET_TX_QUEUE:
 		mutex_lock(&ndev.io_tx_lock);
 		pthread_cond_signal(&ndev.io_tx_cond);
 		mutex_unlock(&ndev.io_tx_lock);
 		break;
-	}
-	case VIRTIO_NET_RX_QUEUE: {
+	case VIRTIO_NET_RX_QUEUE:
 		mutex_lock(&ndev.io_rx_lock);
 		pthread_cond_signal(&ndev.io_rx_cond);
 		mutex_unlock(&ndev.io_rx_lock);
 		break;
-	}
 	default:
 		pr_warning("Unknown queue index %u", queue_index);
 	}
@@ -395,37 +414,40 @@ static void virtio_net__io_thread_init(struct kvm *kvm)
 
 void virtio_net__init(const struct virtio_net_parameters *params)
 {
-	if (virtio_net__tap_init(params)) {
-		u8 dev, line, pin;
-		u16 net_base_addr;
-		u64 i;
-		struct ioevent ioevent;
-
-		if (irq__register_device(VIRTIO_ID_NET, &dev, &pin, &line) < 0)
-			return;
-
-		pci_header.irq_pin	= pin;
-		pci_header.irq_line	= line;
-		net_base_addr		= ioport__register(IOPORT_EMPTY, &virtio_net_io_ops, IOPORT_SIZE, NULL);
-		pci_header.bar[0]	= net_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
-		ndev.base_addr		= net_base_addr;
-
-		pci__register(&pci_header, dev);
-
-		virtio_net__io_thread_init(params->kvm);
-
-		for (i = 0; i < VIRTIO_NET_NUM_QUEUES; i++) {
-			ioevent = (struct ioevent) {
-				.io_addr		= net_base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
-				.io_len			= sizeof(u16),
-				.fn			= ioevent_callback,
-				.datamatch		= i,
-				.fn_ptr			= (void *)(long)i,
-				.fn_kvm			= params->kvm,
-				.fd			= eventfd(0, 0),
-			};
-
-			ioeventfd__add_event(&ioevent);
-		}
+	struct ioevent ioevent;
+	u8 dev, line, pin;
+	u16 net_base_addr;
+	int i;
+
+	if (irq__register_device(VIRTIO_ID_NET, &dev, &pin, &line) < 0)
+		return;
+
+	pci_header.irq_pin  = pin;
+	pci_header.irq_line = line;
+	net_base_addr	    = ioport__register(IOPORT_EMPTY, &virtio_net_io_ops, IOPORT_SIZE, NULL);
+	pci_header.bar[0]   = net_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+	ndev.base_addr	    = net_base_addr;
+	pci__register(&pci_header, dev);
+
+	ndev.mode = params->mode;
+	if (ndev.mode == NET_MODE_TAP)
+		virtio_net__tap_init(params);
+	else
+		uip_init(&ndev.info);
+
+	virtio_net__io_thread_init(params->kvm);
+
+	for (i = 0; i < VIRTIO_NET_NUM_QUEUES; i++) {
+		ioevent = (struct ioevent) {
+			.io_addr	= net_base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
+			.io_len		= sizeof(u16),
+			.fn		= ioevent_callback,
+			.datamatch	= i,
+			.fn_ptr		= (void *)(long)i,
+			.fn_kvm		= params->kvm,
+			.fd		= eventfd(0, 0),
+		};
+
+		ioeventfd__add_event(&ioevent);
 	}
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 29/31] kvm tools: Make default network mode to user mode
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (27 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 28/31] kvm tools: Make virtio net work with user mode network Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 30/31] kvm tools: Make default host ip address to 192.168.33.1 Asias He
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/kvm-run.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index a16a482..c293b49 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -42,7 +42,7 @@
 
 #define DEFAULT_KVM_DEV		"/dev/kvm"
 #define DEFAULT_CONSOLE		"serial"
-#define DEFAULT_NETWORK		"virtio"
+#define DEFAULT_NETWORK		"user"
 #define DEFAULT_HOST_ADDR	"192.168.33.2"
 #define DEFAULT_GUEST_MAC	"00:15:15:15:15:15"
 #define DEFAULT_SCRIPT		"none"
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 30/31] kvm tools: Make default host ip address to 192.168.33.1
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (28 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 29/31] kvm tools: Make default network mode to user mode Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:41 ` [PATCH v2 31/31] kvm tools: Introduce struct net_dev_operations Asias He
  2011-06-30  8:56 ` [PATCH v2 00/31] Implement user mode network for kvm tools Stefan Hajnoczi
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/kvm-run.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index c293b49..efae3c0 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -43,7 +43,7 @@
 #define DEFAULT_KVM_DEV		"/dev/kvm"
 #define DEFAULT_CONSOLE		"serial"
 #define DEFAULT_NETWORK		"user"
-#define DEFAULT_HOST_ADDR	"192.168.33.2"
+#define DEFAULT_HOST_ADDR	"192.168.33.1"
 #define DEFAULT_GUEST_MAC	"00:15:15:15:15:15"
 #define DEFAULT_SCRIPT		"none"
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v2 31/31] kvm tools: Introduce struct net_dev_operations
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (29 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 30/31] kvm tools: Make default host ip address to 192.168.33.1 Asias He
@ 2011-06-30  8:41 ` Asias He
  2011-06-30  8:56 ` [PATCH v2 00/31] Implement user mode network for kvm tools Stefan Hajnoczi
  31 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-06-30  8:41 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm, Asias He

virtio_net_{tx, rx}_thread can use ops->{tx, rx} to send and recevie
network package in both tap mode and user mode.

Suggested-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/virtio/net.c |   56 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 98d4120..3a9216d 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -41,6 +41,13 @@ static struct pci_device_header pci_header = {
 	.subsys_id			= VIRTIO_ID_NET,
 };
 
+struct net_dev;
+
+struct net_dev_operations {
+	int (*rx)(struct iovec *iov, u16 in, struct net_dev *ndev);
+	int (*tx)(struct iovec *iov, u16 in, struct net_dev *ndev);
+};
+
 struct net_dev {
 	pthread_mutex_t			mutex;
 
@@ -68,9 +75,9 @@ struct net_dev {
 	int				mode;
 
 	struct uip_info			info;
+	struct net_dev_operations	*ops;
 };
 
-
 static struct net_dev ndev = {
 	.mutex	= PTHREAD_MUTEX_INITIALIZER,
 
@@ -117,10 +124,7 @@ static void *virtio_net_rx_thread(void *p)
 
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
 
-			if (ndev.mode == NET_MODE_TAP)
-				len = readv(ndev.tap_fd, iov, in);
-			else
-				len = uip_rx(iov, in, &ndev.info);
+			len = ndev.ops->rx(iov, in, &ndev);
 
 			virt_queue__set_used_elem(vq, head, len);
 
@@ -157,10 +161,7 @@ static void *virtio_net_tx_thread(void *p)
 
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
 
-			if (ndev.mode == NET_MODE_TAP)
-				len = writev(ndev.tap_fd, iov, out);
-			else
-				len = uip_tx(iov, out, &ndev.info);
+			len = ndev.ops->tx(iov, out, &ndev);
 
 			virt_queue__set_used_elem(vq, head, len);
 		}
@@ -412,6 +413,36 @@ static void virtio_net__io_thread_init(struct kvm *kvm)
 	pthread_create(&ndev.io_tx_thread, NULL, virtio_net_tx_thread, (void *)kvm);
 }
 
+static inline int tap_ops_tx(struct iovec *iov, u16 out, struct net_dev *ndev)
+{
+	return writev(ndev->tap_fd, iov, out);
+}
+
+static inline int tap_ops_rx(struct iovec *iov, u16 in, struct net_dev *ndev)
+{
+	return readv(ndev->tap_fd, iov, in);
+}
+
+static inline int uip_ops_tx(struct iovec *iov, u16 out, struct net_dev *ndev)
+{
+	return uip_tx(iov, out, &ndev->info);
+}
+
+static inline int uip_ops_rx(struct iovec *iov, u16 in, struct net_dev *ndev)
+{
+	return uip_rx(iov, in, &ndev->info);
+}
+
+static struct net_dev_operations tap_ops = {
+	.rx	= tap_ops_rx,
+	.tx	= tap_ops_tx,
+};
+
+static struct net_dev_operations uip_ops = {
+	.rx	= uip_ops_rx,
+	.tx	= uip_ops_tx,
+};
+
 void virtio_net__init(const struct virtio_net_parameters *params)
 {
 	struct ioevent ioevent;
@@ -430,10 +461,13 @@ void virtio_net__init(const struct virtio_net_parameters *params)
 	pci__register(&pci_header, dev);
 
 	ndev.mode = params->mode;
-	if (ndev.mode == NET_MODE_TAP)
+	if (ndev.mode == NET_MODE_TAP) {
 		virtio_net__tap_init(params);
-	else
+		ndev.ops = &tap_ops;
+	} else {
 		uip_init(&ndev.info);
+		ndev.ops = &uip_ops;
+	}
 
 	virtio_net__io_thread_init(params->kvm);
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
                   ` (30 preceding siblings ...)
  2011-06-30  8:41 ` [PATCH v2 31/31] kvm tools: Introduce struct net_dev_operations Asias He
@ 2011-06-30  8:56 ` Stefan Hajnoczi
  2011-06-30 15:32   ` Anthony Liguori
  2011-06-30 23:38   ` Asias He
  31 siblings, 2 replies; 55+ messages in thread
From: Stefan Hajnoczi @ 2011-06-30  8:56 UTC (permalink / raw)
  To: Asias He
  Cc: Pekka Enberg, Cyrill Gorcunov, Ingo Molnar, Sasha Levin,
	Prasad Joshi, kvm

On Thu, Jun 30, 2011 at 9:40 AM, Asias He <asias.hejun@gmail.com> wrote:
> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
> e.g., HTTP, FTP, SSH, DNS.

There is an existing uIP which might cause confusion, not sure if
you've seen it.  First I thought you were using that :).

http://en.wikipedia.org/wiki/UIP_(micro_IP)

Stefan

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-06-30  8:56 ` [PATCH v2 00/31] Implement user mode network for kvm tools Stefan Hajnoczi
@ 2011-06-30 15:32   ` Anthony Liguori
  2011-07-01  0:18     ` Asias He
  2011-06-30 23:38   ` Asias He
  1 sibling, 1 reply; 55+ messages in thread
From: Anthony Liguori @ 2011-06-30 15:32 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Asias He, Pekka Enberg, Cyrill Gorcunov, Ingo Molnar,
	Sasha Levin, Prasad Joshi, kvm

On 06/30/2011 03:56 AM, Stefan Hajnoczi wrote:
> On Thu, Jun 30, 2011 at 9:40 AM, Asias He<asias.hejun@gmail.com>  wrote:
>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
>> e.g., HTTP, FTP, SSH, DNS.
>
> There is an existing uIP which might cause confusion, not sure if
> you've seen it.  First I thought you were using that :).
>
> http://en.wikipedia.org/wiki/UIP_(micro_IP)

Is the primary motivation here to allow unprivileged guests with 
networking without providing unprivileged access to raw networking or 
just to make networking Just Work?

We've explored various things in the past like using a fscap based 
helper to open tap devices which can help with the Just Works parts.

Usermode TCP/IP can be quite cumbersome for users as things like ping 
and ip6 won't work properly.

Regards,

Anthony Liguori

>
> Stefan
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-06-30  8:56 ` [PATCH v2 00/31] Implement user mode network for kvm tools Stefan Hajnoczi
  2011-06-30 15:32   ` Anthony Liguori
@ 2011-06-30 23:38   ` Asias He
  2011-07-01 16:50     ` Stefan Hajnoczi
  1 sibling, 1 reply; 55+ messages in thread
From: Asias He @ 2011-06-30 23:38 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Pekka Enberg, Cyrill Gorcunov, Ingo Molnar, Sasha Levin,
	Prasad Joshi, kvm

On 06/30/2011 04:56 PM, Stefan Hajnoczi wrote:
> On Thu, Jun 30, 2011 at 9:40 AM, Asias He <asias.hejun@gmail.com> wrote:
>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
>> e.g., HTTP, FTP, SSH, DNS.
> 
> There is an existing uIP which might cause confusion, not sure if
> you've seen it.  First I thought you were using that :).

I heard about uIP, but this patchset have nothing to do with uIP ;-)

At first I was naming the user mode network as "UNET" which is User mode
NETwork, however, I though uip looks better because it is shorter.

Anyway, if uip do cause confusion. I'd like to change this naming.

> 
> http://en.wikipedia.org/wiki/UIP_(micro_IP)



-- 
Best Regards,
Asias He

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-06-30 15:32   ` Anthony Liguori
@ 2011-07-01  0:18     ` Asias He
  2011-07-01 11:53       ` Ingo Molnar
  0 siblings, 1 reply; 55+ messages in thread
From: Asias He @ 2011-07-01  0:18 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Stefan Hajnoczi, Pekka Enberg, Cyrill Gorcunov, Ingo Molnar,
	Sasha Levin, Prasad Joshi, kvm

On 06/30/2011 11:32 PM, Anthony Liguori wrote:
> On 06/30/2011 03:56 AM, Stefan Hajnoczi wrote:
>> On Thu, Jun 30, 2011 at 9:40 AM, Asias He<asias.hejun@gmail.com>  wrote:
>>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP,
>>> ICMP,
>>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as
>>> well,
>>> e.g., HTTP, FTP, SSH, DNS.
>>
>> There is an existing uIP which might cause confusion, not sure if
>> you've seen it.  First I thought you were using that :).
>>
>> http://en.wikipedia.org/wiki/UIP_(micro_IP)
> 
> Is the primary motivation here to allow unprivileged guests with
> networking without providing unprivileged access to raw networking or
> just to make networking Just Work?
> 
> We've explored various things in the past like using a fscap based
> helper to open tap devices which can help with the Just Works parts.

Does qemu use fscap?

> 
> Usermode TCP/IP can be quite cumbersome for users as things like ping
> and ip6 won't work properly.

Yes, usermode TCP/IP do have limits. But it's more cumbersome for user
to setup bridge/nat thing with privileged networking. The network setup
is a headache for some users.

This patchset implements things like 'qemu -net user' without the slirp.

I just took at a look the LOC in qemu and uip.

qemu.git$ cat slirp/*.{c,h} net/slirp.{c,h}| wc -l
11514

kernel.git/tools/kvm$ cat uip/*.{c,h} include/kvm/uip.h | wc -l
1312

-- 
Best Regards,
Asias He

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 12/31] kvm tools: Add UDP support for uip
  2011-06-30  8:41 ` [PATCH v2 12/31] kvm tools: Add UDP support for uip Asias He
@ 2011-07-01 11:46   ` Ingo Molnar
  2011-07-01 15:24     ` Asias He
  0 siblings, 1 reply; 55+ messages in thread
From: Ingo Molnar @ 2011-07-01 11:46 UTC (permalink / raw)
  To: Asias He; +Cc: Pekka Enberg, Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


* Asias He <asias.hejun@gmail.com> wrote:

> +static void *uip_udp_socket_thread(void *p)
> +{
> +	struct epoll_event events[UIP_UDP_MAX_EVENTS];
> +	struct uip_udp_socket *sk;
> +	struct uip_info *info;
> +	struct uip_eth *eth2;
> +	struct uip_udp *udp2;
> +	struct uip_buf *buf;
> +	struct uip_ip *ip2;
> +	u8 *payload;
> +	int nfds;
> +	int ret;
> +	int i;
> +
> +	info = p;
> +
> +	do {
> +		payload = malloc(UIP_MAX_UDP_PAYLOAD);
> +	} while (!payload);
> +
> +	while (1) {
> +		nfds = epoll_wait(info->udp_epollfd, events, UIP_UDP_MAX_EVENTS, -1);
> +
> +		if (nfds == -1)
> +			continue;
> +
> +		for (i = 0; i < nfds; i++) {
> +
> +			sk = events[i].data.ptr;
> +			ret = recvfrom(sk->fd, payload, UIP_MAX_UDP_PAYLOAD, 0, NULL, NULL);
> +			if (ret < 0)
> +				continue;
> +
> +			/*
> +			 * Get free buffer to send data to guest
> +			 */
> +			buf		= uip_buf_get_free(info);
> +
> +			/*
> +			 * Cook a ethernet frame
> +			 */
> +			udp2		= (struct uip_udp *)(buf->eth);
> +			eth2		= (struct uip_eth *)buf->eth;
> +			ip2		= (struct uip_ip *)(buf->eth);
> +
> +			eth2->src	= info->host_mac;
> +			eth2->dst	= info->guest_mac;
> +			eth2->type	= htons(UIP_ETH_P_IP);
> +
> +			ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
> +			ip2->tos	= 0;
> +			ip2->id		= 0;
> +			ip2->flgfrag	= 0;
> +			ip2->ttl	= UIP_IP_TTL;
> +			ip2->proto	= UIP_IP_P_UDP;
> +			ip2->csum	= 0;
> +			ip2->sip	= sk->dip;
> +			ip2->dip	= sk->sip;
> +
> +			udp2->sport	= sk->dport;
> +			udp2->dport	= sk->sport;
> +			udp2->len	= htons(ret + uip_udp_hdrlen(udp2));
> +			udp2->csum	= 0;
> +
> +			memcpy(udp2->payload, payload, ret);
> +
> +			ip2->len	= udp2->len + htons(uip_ip_hdrlen(ip2));
> +			ip2->csum	= uip_csum_ip(ip2);
> +			udp2->csum	= uip_csum_udp(udp2);
> +
> +			/*
> +			 * virtio_net_hdr
> +			 */
> +			buf->vnet_len	= sizeof(struct virtio_net_hdr);
> +			memset(buf->vnet, 0, buf->vnet_len);
> +
> +			buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
> +
> +			/*
> +			 * Send data received from socket to guest
> +			 */
> +			uip_buf_set_used(info, buf);
> +		}
> +	}
> +
> +	free(payload);
> +	pthread_exit(NULL);
> +	return NULL;
> +}

This function is way too large, please split out the meat of it into 
a separate helper inline.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01  0:18     ` Asias He
@ 2011-07-01 11:53       ` Ingo Molnar
  2011-07-01 13:46         ` Alexander Graf
  2011-07-02  9:42         ` Pekka Enberg
  0 siblings, 2 replies; 55+ messages in thread
From: Ingo Molnar @ 2011-07-01 11:53 UTC (permalink / raw)
  To: Asias He
  Cc: Anthony Liguori, Stefan Hajnoczi, Pekka Enberg, Cyrill Gorcunov,
	Sasha Levin, Prasad Joshi, kvm


* Asias He <asias.hejun@gmail.com> wrote:

> > Usermode TCP/IP can be quite cumbersome for users as things like 
> > ping and ip6 won't work properly.
> 
> Yes, usermode TCP/IP do have limits. But it's more cumbersome for 
> user to setup bridge/nat thing with privileged networking. The 
> network setup is a headache for some users.

That group of 'some users' includes me for example.

The thing is, when i test an existing distro image there's better 
things to do with my time than to figure out that year's preferred 
method of configuring the network and troubleshooting it if it goes 
wrong. So having zero-config networking (assuming we grow some DHCP 
capability as well) would be a real plus.

> This patchset implements things like 'qemu -net user' without the 
> slirp.
> 
> I just took at a look the LOC in qemu and uip.
> 
> qemu.git$ cat slirp/*.{c,h} net/slirp.{c,h}| wc -l
> 11514
> 
> kernel.git/tools/kvm$ cat uip/*.{c,h} include/kvm/uip.h | wc -l
> 1312

That's pretty impressive (if it does not come at the expensive of 
features that Qemu's slirp code has) - and the thing is that we don't 
actually have to implement the vast majority of TCP-IP features, 
because the transport between the guest and the host is obviously 
reliable.

This patch-set turned out to be a *lot* more simple than i first 
thought it would end up.

Simpler also means potentially faster and potentially more secure.

( The lack of ipv6 is not something we should worry about too much, 
  ipv4 should scale up to a couple of hundred thousand virtual
  machines per box, right? )

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 11:53       ` Ingo Molnar
@ 2011-07-01 13:46         ` Alexander Graf
  2011-07-02  9:45           ` Pekka Enberg
  2011-07-03 19:42           ` Ingo Molnar
  2011-07-02  9:42         ` Pekka Enberg
  1 sibling, 2 replies; 55+ messages in thread
From: Alexander Graf @ 2011-07-01 13:46 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


On 01.07.2011, at 13:53, Ingo Molnar wrote:

> 
> * Asias He <asias.hejun@gmail.com> wrote:
> 
>>> Usermode TCP/IP can be quite cumbersome for users as things like 
>>> ping and ip6 won't work properly.
>> 
>> Yes, usermode TCP/IP do have limits. But it's more cumbersome for 
>> user to setup bridge/nat thing with privileged networking. The 
>> network setup is a headache for some users.
> 
> That group of 'some users' includes me for example.
> 
> The thing is, when i test an existing distro image there's better 
> things to do with my time than to figure out that year's preferred 
> method of configuring the network and troubleshooting it if it goes 
> wrong. So having zero-config networking (assuming we grow some DHCP 
> capability as well) would be a real plus.
> 
>> This patchset implements things like 'qemu -net user' without the 
>> slirp.
>> 
>> I just took at a look the LOC in qemu and uip.
>> 
>> qemu.git$ cat slirp/*.{c,h} net/slirp.{c,h}| wc -l
>> 11514
>> 
>> kernel.git/tools/kvm$ cat uip/*.{c,h} include/kvm/uip.h | wc -l
>> 1312
> 
> That's pretty impressive (if it does not come at the expensive of 
> features that Qemu's slirp code has) - and the thing is that we don't 
> actually have to implement the vast majority of TCP-IP features, 
> because the transport between the guest and the host is obviously 
> reliable.

I don't see how it would. Once you overrun device buffers, you have to do something. Either you drop packets or you stall the guest. I'd usually prefer the former :).

> This patch-set turned out to be a *lot* more simple than i first 
> thought it would end up.
> 
> Simpler also means potentially faster and potentially more secure.
> 
> ( The lack of ipv6 is not something we should worry about too much, 
>  ipv4 should scale up to a couple of hundred thousand virtual
>  machines per box, right? )

Well, if the system you're trying to connect to supports ipv4, sure. If it doesn't, tough luck :).


Alex


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 12/31] kvm tools: Add UDP support for uip
  2011-07-01 11:46   ` Ingo Molnar
@ 2011-07-01 15:24     ` Asias He
  0 siblings, 0 replies; 55+ messages in thread
From: Asias He @ 2011-07-01 15:24 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Pekka Enberg, Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm

On 07/01/2011 07:46 PM, Ingo Molnar wrote:
> 
> * Asias He <asias.hejun@gmail.com> wrote:
> 
>> +static void *uip_udp_socket_thread(void *p)
>> +{
>> +	struct epoll_event events[UIP_UDP_MAX_EVENTS];
>> +	struct uip_udp_socket *sk;
>> +	struct uip_info *info;
>> +	struct uip_eth *eth2;
>> +	struct uip_udp *udp2;
>> +	struct uip_buf *buf;
>> +	struct uip_ip *ip2;
>> +	u8 *payload;
>> +	int nfds;
>> +	int ret;
>> +	int i;
>> +
>> +	info = p;
>> +
>> +	do {
>> +		payload = malloc(UIP_MAX_UDP_PAYLOAD);
>> +	} while (!payload);
>> +
>> +	while (1) {
>> +		nfds = epoll_wait(info->udp_epollfd, events, UIP_UDP_MAX_EVENTS, -1);
>> +
>> +		if (nfds == -1)
>> +			continue;
>> +
>> +		for (i = 0; i < nfds; i++) {
>> +
>> +			sk = events[i].data.ptr;
>> +			ret = recvfrom(sk->fd, payload, UIP_MAX_UDP_PAYLOAD, 0, NULL, NULL);
>> +			if (ret < 0)
>> +				continue;
>> +
>> +			/*
>> +			 * Get free buffer to send data to guest
>> +			 */
>> +			buf		= uip_buf_get_free(info);
>> +
>> +			/*
>> +			 * Cook a ethernet frame
>> +			 */
>> +			udp2		= (struct uip_udp *)(buf->eth);
>> +			eth2		= (struct uip_eth *)buf->eth;
>> +			ip2		= (struct uip_ip *)(buf->eth);
>> +
>> +			eth2->src	= info->host_mac;
>> +			eth2->dst	= info->guest_mac;
>> +			eth2->type	= htons(UIP_ETH_P_IP);
>> +
>> +			ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
>> +			ip2->tos	= 0;
>> +			ip2->id		= 0;
>> +			ip2->flgfrag	= 0;
>> +			ip2->ttl	= UIP_IP_TTL;
>> +			ip2->proto	= UIP_IP_P_UDP;
>> +			ip2->csum	= 0;
>> +			ip2->sip	= sk->dip;
>> +			ip2->dip	= sk->sip;
>> +
>> +			udp2->sport	= sk->dport;
>> +			udp2->dport	= sk->sport;
>> +			udp2->len	= htons(ret + uip_udp_hdrlen(udp2));
>> +			udp2->csum	= 0;
>> +
>> +			memcpy(udp2->payload, payload, ret);
>> +
>> +			ip2->len	= udp2->len + htons(uip_ip_hdrlen(ip2));
>> +			ip2->csum	= uip_csum_ip(ip2);
>> +			udp2->csum	= uip_csum_udp(udp2);
>> +
>> +			/*
>> +			 * virtio_net_hdr
>> +			 */
>> +			buf->vnet_len	= sizeof(struct virtio_net_hdr);
>> +			memset(buf->vnet, 0, buf->vnet_len);
>> +
>> +			buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
>> +
>> +			/*
>> +			 * Send data received from socket to guest
>> +			 */
>> +			uip_buf_set_used(info, buf);
>> +		}
>> +	}
>> +
>> +	free(payload);
>> +	pthread_exit(NULL);
>> +	return NULL;
>> +}
> 
> This function is way too large, please split out the meat of it into 
> a separate helper inline.

Will do. Thanks.

-- 
Best Regards,
Asias He

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-06-30 23:38   ` Asias He
@ 2011-07-01 16:50     ` Stefan Hajnoczi
  2011-07-01 20:36       ` Pekka Enberg
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Hajnoczi @ 2011-07-01 16:50 UTC (permalink / raw)
  To: Asias He
  Cc: Pekka Enberg, Cyrill Gorcunov, Ingo Molnar, Sasha Levin,
	Prasad Joshi, kvm

On Fri, Jul 1, 2011 at 12:38 AM, Asias He <asias.hejun@gmail.com> wrote:
> On 06/30/2011 04:56 PM, Stefan Hajnoczi wrote:
>> On Thu, Jun 30, 2011 at 9:40 AM, Asias He <asias.hejun@gmail.com> wrote:
>>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
>>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
>>> e.g., HTTP, FTP, SSH, DNS.
>>
>> There is an existing uIP which might cause confusion, not sure if
>> you've seen it.  First I thought you were using that :).
>
> I heard about uIP, but this patchset have nothing to do with uIP ;-)
>
> At first I was naming the user mode network as "UNET" which is User mode
> NETwork, however, I though uip looks better because it is shorter.
>
> Anyway, if uip do cause confusion. I'd like to change this naming.

It's up to you but now is the right time to do it.  Consider if
another program wants to reuse this code or if you ever want to make
it a library, it wouldn't help to have a confusing name.

Stefan

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 16:50     ` Stefan Hajnoczi
@ 2011-07-01 20:36       ` Pekka Enberg
  2011-07-02  3:49         ` Asias He
  0 siblings, 1 reply; 55+ messages in thread
From: Pekka Enberg @ 2011-07-01 20:36 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Asias He, Cyrill Gorcunov, Ingo Molnar, Sasha Levin, Prasad Joshi, kvm

On Fri, Jul 1, 2011 at 7:50 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Fri, Jul 1, 2011 at 12:38 AM, Asias He <asias.hejun@gmail.com> wrote:
>> On 06/30/2011 04:56 PM, Stefan Hajnoczi wrote:
>>> On Thu, Jun 30, 2011 at 9:40 AM, Asias He <asias.hejun@gmail.com> wrote:
>>>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
>>>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
>>>> e.g., HTTP, FTP, SSH, DNS.
>>>
>>> There is an existing uIP which might cause confusion, not sure if
>>> you've seen it.  First I thought you were using that :).
>>
>> I heard about uIP, but this patchset have nothing to do with uIP ;-)
>>
>> At first I was naming the user mode network as "UNET" which is User mode
>> NETwork, however, I though uip looks better because it is shorter.
>>
>> Anyway, if uip do cause confusion. I'd like to change this naming.
>
> It's up to you but now is the right time to do it.  Consider if
> another program wants to reuse this code or if you ever want to make
> it a library, it wouldn't help to have a confusing name.

I don't care too much what we use as the namespace prefix but as a
directory name tools/kvm/uip is pretty meaningless. I'd just move the
code under tools/kvm/net to mirror what the kernel already has.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 20:36       ` Pekka Enberg
@ 2011-07-02  3:49         ` Asias He
  2011-07-02  9:02           ` Ingo Molnar
  0 siblings, 1 reply; 55+ messages in thread
From: Asias He @ 2011-07-02  3:49 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Stefan Hajnoczi, Cyrill Gorcunov, Ingo Molnar, Sasha Levin,
	Prasad Joshi, kvm

On 07/02/2011 04:36 AM, Pekka Enberg wrote:
> On Fri, Jul 1, 2011 at 7:50 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> On Fri, Jul 1, 2011 at 12:38 AM, Asias He <asias.hejun@gmail.com> wrote:
>>> On 06/30/2011 04:56 PM, Stefan Hajnoczi wrote:
>>>> On Thu, Jun 30, 2011 at 9:40 AM, Asias He <asias.hejun@gmail.com> wrote:
>>>>> uip stands for user mode {TCP,UDP}/IP. Currently, uip supports ARP, ICMP,
>>>>> IPV4, UDP, TCP. So any network protocols above UDP/TCP should work as well,
>>>>> e.g., HTTP, FTP, SSH, DNS.
>>>>
>>>> There is an existing uIP which might cause confusion, not sure if
>>>> you've seen it.  First I thought you were using that :).
>>>
>>> I heard about uIP, but this patchset have nothing to do with uIP ;-)
>>>
>>> At first I was naming the user mode network as "UNET" which is User mode
>>> NETwork, however, I though uip looks better because it is shorter.
>>>
>>> Anyway, if uip do cause confusion. I'd like to change this naming.
>>
>> It's up to you but now is the right time to do it.  Consider if
>> another program wants to reuse this code or if you ever want to make
>> it a library, it wouldn't help to have a confusing name.
> 
> I don't care too much what we use as the namespace prefix but as a
> directory name tools/kvm/uip is pretty meaningless. I'd just move the
> code under tools/kvm/net to mirror what the kernel already has.
> 

I have thought about putting user mode net code in tools/kvm/net.
However, we have net code in tools/kvm/virtio as well. Is this a problem
in terms of clean code organization?

And I think splitting the tap code in virtio/net.c into tools/kvm/net is
a good idea. Further, we can put macvtap related code into tools/kvm/net
as well.

-- 
Best Regards,
Asias He

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-02  3:49         ` Asias He
@ 2011-07-02  9:02           ` Ingo Molnar
  0 siblings, 0 replies; 55+ messages in thread
From: Ingo Molnar @ 2011-07-02  9:02 UTC (permalink / raw)
  To: Asias He
  Cc: Pekka Enberg, Stefan Hajnoczi, Cyrill Gorcunov, Sasha Levin,
	Prasad Joshi, kvm


* Asias He <asias.hejun@gmail.com> wrote:

> > I don't care too much what we use as the namespace prefix but as 
> > a directory name tools/kvm/uip is pretty meaningless. I'd just 
> > move the code under tools/kvm/net to mirror what the kernel 
> > already has.
> 
> I have thought about putting user mode net code in tools/kvm/net. 
> However, we have net code in tools/kvm/virtio as well. Is this a 
> problem in terms of clean code organization?
> 
> And I think splitting the tap code in virtio/net.c into 
> tools/kvm/net is a good idea. Further, we can put macvtap related 
> code into tools/kvm/net as well.

Well, tools/kvm/net/ is for all things networking - one component of 
which is the Ethernet transport layer (a vring based driver), which 
can then branch in two directions: go straight to a host-side 
ethernet transport facility (TUN device) or can be streamed via TCP 
sockets (unet).

If we want to structure it more we may want to have 
tools/kvm/net/guest/ [handling packets to/from the guest], 
tools/kvm/net/host/ [handling packets to/from the host], etc.

There's 3 conceptual layers here: the guest, the hypervisor and the 
host.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 11:53       ` Ingo Molnar
  2011-07-01 13:46         ` Alexander Graf
@ 2011-07-02  9:42         ` Pekka Enberg
  1 sibling, 0 replies; 55+ messages in thread
From: Pekka Enberg @ 2011-07-02  9:42 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Cyrill Gorcunov,
	Sasha Levin, Prasad Joshi, kvm

On Fri, 2011-07-01 at 13:53 +0200, Ingo Molnar wrote:
> * Asias He <asias.hejun@gmail.com> wrote:
> 
> > > Usermode TCP/IP can be quite cumbersome for users as things like 
> > > ping and ip6 won't work properly.
> > 
> > Yes, usermode TCP/IP do have limits. But it's more cumbersome for 
> > user to setup bridge/nat thing with privileged networking. The 
> > network setup is a headache for some users.
> 
> That group of 'some users' includes me for example.

Me too.

> The thing is, when i test an existing distro image there's better 
> things to do with my time than to figure out that year's preferred 
> method of configuring the network and troubleshooting it if it goes 
> wrong. So having zero-config networking (assuming we grow some DHCP 
> capability as well) would be a real plus.

Yes, we want DHCP or whatever is needed for out-of-the-box distro images
to enable networking in the guest.

			Pekka


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 13:46         ` Alexander Graf
@ 2011-07-02  9:45           ` Pekka Enberg
  2011-07-02 10:30             ` Ingo Molnar
  2011-07-02 11:19             ` Alexander Graf
  2011-07-03 19:42           ` Ingo Molnar
  1 sibling, 2 replies; 55+ messages in thread
From: Pekka Enberg @ 2011-07-02  9:45 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Ingo Molnar, Asias He, Anthony Liguori, Stefan Hajnoczi,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm

On Fri, 2011-07-01 at 15:46 +0200, Alexander Graf wrote:
> > That's pretty impressive (if it does not come at the expensive of 
> > features that Qemu's slirp code has) - and the thing is that we don't 
> > actually have to implement the vast majority of TCP-IP features, 
> > because the transport between the guest and the host is obviously 
> > reliable.
> 
> I don't see how it would. Once you overrun device buffers, you have to
> do something. Either you drop packets or you stall the guest. I'd
> usually prefer the former :).

If we make the buffers large enough, will this matter in practice?

> > This patch-set turned out to be a *lot* more simple than i first 
> > thought it would end up.
> > 
> > Simpler also means potentially faster and potentially more secure.
> > 
> > ( The lack of ipv6 is not something we should worry about too much, 
> >  ipv4 should scale up to a couple of hundred thousand virtual
> >  machines per box, right? )
> 
> Well, if the system you're trying to connect to supports ipv4, sure.
> If it doesn't, tough luck :).

Does that mean that the guests would effectively be ipv4-only? That'd be
unfortunate.

			Pekka


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-02  9:45           ` Pekka Enberg
@ 2011-07-02 10:30             ` Ingo Molnar
  2011-07-02 11:19             ` Alexander Graf
  1 sibling, 0 replies; 55+ messages in thread
From: Ingo Molnar @ 2011-07-02 10:30 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Alexander Graf, Asias He, Anthony Liguori, Stefan Hajnoczi,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


* Pekka Enberg <penberg@kernel.org> wrote:

> On Fri, 2011-07-01 at 15:46 +0200, Alexander Graf wrote:
> > > That's pretty impressive (if it does not come at the expensive of 
> > > features that Qemu's slirp code has) - and the thing is that we don't 
> > > actually have to implement the vast majority of TCP-IP features, 
> > > because the transport between the guest and the host is obviously 
> > > reliable.
> > 
> > I don't see how it would. Once you overrun device buffers, you have to
> > do something. Either you drop packets or you stall the guest. I'd
> > usually prefer the former :).
> 
> If we make the buffers large enough, will this matter in practice?
> 
> > > This patch-set turned out to be a *lot* more simple than i first 
> > > thought it would end up.
> > > 
> > > Simpler also means potentially faster and potentially more secure.
> > > 
> > > ( The lack of ipv6 is not something we should worry about too much, 
> > >  ipv4 should scale up to a couple of hundred thousand virtual
> > >  machines per box, right? )
> > 
> > Well, if the system you're trying to connect to supports ipv4, 
> > sure. If it doesn't, tough luck :).
> 
> Does that mean that the guests would effectively be ipv4-only? 
> That'd be unfortunate.

The guest will effectively be NAT-ed anyway, with it on a private 
network in essence (where the DHCP server gives a dynamic IP), so it 
does not matter at all whether it's using ipv4 or ipv6 for its NAT 
connectivity.

ipv6 might matter for TUN-ed connections, where the guest might be 
visible externally as well.

Unless i'm missing some important ipv6 usecase.

Also, is there any fundamental reason why ipv6 packets couldnt be 
recognized with time? So if there's demand, it could be added.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-02  9:45           ` Pekka Enberg
  2011-07-02 10:30             ` Ingo Molnar
@ 2011-07-02 11:19             ` Alexander Graf
  2011-07-02 11:27               ` Pekka Enberg
  1 sibling, 1 reply; 55+ messages in thread
From: Alexander Graf @ 2011-07-02 11:19 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Ingo Molnar, Asias He, Anthony Liguori, Stefan Hajnoczi,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


On 02.07.2011, at 11:45, Pekka Enberg <penberg@kernel.org> wrote:

> On Fri, 2011-07-01 at 15:46 +0200, Alexander Graf wrote:
>>> That's pretty impressive (if it does not come at the expensive of 
>>> features that Qemu's slirp code has) - and the thing is that we don't 
>>> actually have to implement the vast majority of TCP-IP features, 
>>> because the transport between the guest and the host is obviously 
>>> reliable.
>> 
>> I don't see how it would. Once you overrun device buffers, you have to
>> do something. Either you drop packets or you stall the guest. I'd
>> usually prefer the former :).
> 
> If we make the buffers large enough, will this matter in practice?

Would you trust a system based on statistics? :)

Also, I'm not sure you can easily change the size of the buffers. If your emulated network adapter has a buffer of n bytes for sg lists, that's what you get. No more, no less.

> 
>>> This patch-set turned out to be a *lot* more simple than i first 
>>> thought it would end up.
>>> 
>>> Simpler also means potentially faster and potentially more secure.
>>> 
>>> ( The lack of ipv6 is not something we should worry about too much, 
>>> ipv4 should scale up to a couple of hundred thousand virtual
>>> machines per box, right? )
>> 
>> Well, if the system you're trying to connect to supports ipv4, sure.
>> If it doesn't, tough luck :).
> 
> Does that mean that the guests would effectively be ipv4-only? That'd be
> unfortunate.

Well, for starters, yeah. Unless you also implement ipv6 in the user networking or add networking support an osi level below (tap, macvtap, ...).

User networking is great for quick testing, but it's by no means able to replace network forwarding on the link layer. It's really a matter of use cases. Just imagine you want to use kvm-tool to test an ipx/spx stack :).


 Alex

> 

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-02 11:19             ` Alexander Graf
@ 2011-07-02 11:27               ` Pekka Enberg
  2011-07-02 12:31                 ` Alexander Graf
  0 siblings, 1 reply; 55+ messages in thread
From: Pekka Enberg @ 2011-07-02 11:27 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Ingo Molnar, Asias He, Anthony Liguori, Stefan Hajnoczi,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm

> On 02.07.2011, at 11:45, Pekka Enberg <penberg@kernel.org> wrote:
>> On Fri, 2011-07-01 at 15:46 +0200, Alexander Graf wrote:
>>>> That's pretty impressive (if it does not come at the expensive of
>>>> features that Qemu's slirp code has) - and the thing is that we don't
>>>> actually have to implement the vast majority of TCP-IP features,
>>>> because the transport between the guest and the host is obviously
>>>> reliable.
>>>
>>> I don't see how it would. Once you overrun device buffers, you have to
>>> do something. Either you drop packets or you stall the guest. I'd
>>> usually prefer the former :).
>>
>> If we make the buffers large enough, will this matter in practice?

On Sat, Jul 2, 2011 at 2:19 PM, Alexander Graf <agraf@suse.de> wrote:
> Would you trust a system based on statistics? :)

Yes, absolutely, for my particular use cases (unless the odd out cases
crash my computer and eat my data). The question is if we can make it
good enough as a sensible default for most users or not.

> Also, I'm not sure you can easily change the size of the buffers. If your emulated network adapter has a buffer of n bytes for sg lists, that's what you get. No more, no less.

I simply meant making the buffers large enough when we set everything up.

>>>> This patch-set turned out to be a *lot* more simple than i first
>>>> thought it would end up.
>>>>
>>>> Simpler also means potentially faster and potentially more secure.
>>>>
>>>> ( The lack of ipv6 is not something we should worry about too much,
>>>> ipv4 should scale up to a couple of hundred thousand virtual
>>>> machines per box, right? )
>>>
>>> Well, if the system you're trying to connect to supports ipv4, sure.
>>> If it doesn't, tough luck :).
>>
>> Does that mean that the guests would effectively be ipv4-only? That'd be
>> unfortunate.
>
> Well, for starters, yeah. Unless you also implement ipv6 in the user networking or add networking support an osi level below (tap, macvtap, ...).
>
> User networking is great for quick testing, but it's by no means able to replace network forwarding on the link layer. It's really a matter of use cases. Just imagine you want to use kvm-tool to test an ipx/spx stack :).

You can use the existing tap support for that no? I don't think we
should attempt to cover *everything* with our userspace IP stack, not
for 'power users' anyway.

                          Pekka

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-02 11:27               ` Pekka Enberg
@ 2011-07-02 12:31                 ` Alexander Graf
  0 siblings, 0 replies; 55+ messages in thread
From: Alexander Graf @ 2011-07-02 12:31 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Ingo Molnar, Asias He, Anthony Liguori, Stefan Hajnoczi,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm



Am 02.07.2011 um 13:27 schrieb Pekka Enberg <penberg@kernel.org>:

>> On 02.07.2011, at 11:45, Pekka Enberg <penberg@kernel.org> wrote:
>>> On Fri, 2011-07-01 at 15:46 +0200, Alexander Graf wrote:
>>>>> That's pretty impressive (if it does not come at the expensive of
>>>>> features that Qemu's slirp code has) - and the thing is that we don't
>>>>> actually have to implement the vast majority of TCP-IP features,
>>>>> because the transport between the guest and the host is obviously
>>>>> reliable.
>>>> 
>>>> I don't see how it would. Once you overrun device buffers, you have to
>>>> do something. Either you drop packets or you stall the guest. I'd
>>>> usually prefer the former :).
>>> 
>>> If we make the buffers large enough, will this matter in practice?
> 
> On Sat, Jul 2, 2011 at 2:19 PM, Alexander Graf <agraf@suse.de> wrote:
>> Would you trust a system based on statistics? :)
> 
> Yes, absolutely, for my particular use cases (unless the odd out cases
> crash my computer and eat my data). The question is if we can make it
> good enough as a sensible default for most users or not.

Interesting. I wouldn't want to ship code like that to paying customers :)

> 
>> Also, I'm not sure you can easily change the size of the buffers. If your emulated network adapter has a buffer of n bytes for sg lists, that's what you get. No more, no less.
> 
> I simply meant making the buffers large enough when we set everything up.

I think we're talking about different buffers :)

> 
>>>>> This patch-set turned out to be a *lot* more simple than i first
>>>>> thought it would end up.
>>>>> 
>>>>> Simpler also means potentially faster and potentially more secure.
>>>>> 
>>>>> ( The lack of ipv6 is not something we should worry about too much,
>>>>> ipv4 should scale up to a couple of hundred thousand virtual
>>>>> machines per box, right? )
>>>> 
>>>> Well, if the system you're trying to connect to supports ipv4, sure.
>>>> If it doesn't, tough luck :).
>>> 
>>> Does that mean that the guests would effectively be ipv4-only? That'd be
>>> unfortunate.
>> 
>> Well, for starters, yeah. Unless you also implement ipv6 in the user networking or add networking support an osi level below (tap, macvtap, ...).
>> 
>> User networking is great for quick testing, but it's by no means able to replace network forwarding on the link layer. It's really a matter of use cases. Just imagine you want to use kvm-tool to test an ipx/spx stack :).
> 
> You can use the existing tap support for that no? I don't think we
> should attempt to cover *everything* with our userspace IP stack, not
> for 'power users' anyway.

Yup, and for now for most users ipv4 only is good enough. It's really just something to keep in mind. We already are exceeding ipv4 address space - and it's pretty hard to access an ipv6 server address from ipv4. But we have the same issue in slirp.

Alex

> 

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-01 13:46         ` Alexander Graf
  2011-07-02  9:45           ` Pekka Enberg
@ 2011-07-03 19:42           ` Ingo Molnar
  2011-07-03 22:15             ` Alexander Graf
  1 sibling, 1 reply; 55+ messages in thread
From: Ingo Molnar @ 2011-07-03 19:42 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


* Alexander Graf <agraf@suse.de> wrote:

> > That's pretty impressive (if it does not come at the expensive of 
> > features that Qemu's slirp code has) - and the thing is that we 
> > don't actually have to implement the vast majority of TCP-IP 
> > features, because the transport between the guest and the host is 
> > obviously reliable.
> 
> I don't see how it would. Once you overrun device buffers, you have 
> to do something. Either you drop packets or you stall the guest. 
> I'd usually prefer the former :).

What scenario do you see where we'd have to drop packets?

When the guest sends packets, we send them over to the host TCP 
socket - no blocking.

When the host receives packets it should only read data out of the 
host socket(s) if the vring buffer suggests that there's space 
available.

So i don't see we'd need to drop packets or block things - we just 
have to react to packets and to vring space availability in a 
straightforward way.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-03 19:42           ` Ingo Molnar
@ 2011-07-03 22:15             ` Alexander Graf
  2011-07-04  9:11               ` Ingo Molnar
  0 siblings, 1 reply; 55+ messages in thread
From: Alexander Graf @ 2011-07-03 22:15 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


On 03.07.2011, at 21:42, Ingo Molnar wrote:

> 
> * Alexander Graf <agraf@suse.de> wrote:
> 
>>> That's pretty impressive (if it does not come at the expensive of 
>>> features that Qemu's slirp code has) - and the thing is that we 
>>> don't actually have to implement the vast majority of TCP-IP 
>>> features, because the transport between the guest and the host is 
>>> obviously reliable.
>> 
>> I don't see how it would. Once you overrun device buffers, you have 
>> to do something. Either you drop packets or you stall the guest. 
>> I'd usually prefer the former :).
> 
> What scenario do you see where we'd have to drop packets?
> 
> When the guest sends packets, we send them over to the host TCP 
> socket - no blocking.

When the guest sends packets, I'd hope you have 2 threads:

 * vcpu
 * virtio network queue process

So those two run in parallel now, with the network queue processing packets while the vcpu pushes packets into the ring. What if the network thread is slower than the vcpu fills the ring? You only have so many entries in a vring.

> When the host receives packets it should only read data out of the 
> host socket(s) if the vring buffer suggests that there's space 
> available.

I agree :).

> So i don't see we'd need to drop packets or block things - we just 
> have to react to packets and to vring space availability in a 
> straightforward way.

Well, the only way for the sending path is to stall the vcpu, otherwise the guest figures "oh, I can't push packets into the vring, let's just drop it", no?


Alex


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-03 22:15             ` Alexander Graf
@ 2011-07-04  9:11               ` Ingo Molnar
  2011-07-04  9:30                 ` Alexander Graf
  0 siblings, 1 reply; 55+ messages in thread
From: Ingo Molnar @ 2011-07-04  9:11 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


* Alexander Graf <agraf@suse.de> wrote:

> >> I don't see how it would. Once you overrun device buffers, you 
> >> have to do something. Either you drop packets or you stall the 
> >> guest. I'd usually prefer the former :).
> > 
> > What scenario do you see where we'd have to drop packets?
> > 
> > When the guest sends packets, we send them over to the host TCP 
> > socket - no blocking.
> 
> When the guest sends packets, I'd hope you have 2 threads:
> 
>  * vcpu
>  * virtio network queue process
> 
> So those two run in parallel now, with the network queue processing 
> packets while the vcpu pushes packets into the ring. What if the 
> network thread is slower than the vcpu fills the ring? You only 
> have so many entries in a vring.
>
> > When the host receives packets it should only read data out of 
> > the host socket(s) if the vring buffer suggests that there's 
> > space available.
> 
> I agree :).
> 
> > So i don't see we'd need to drop packets or block things - we 
> > just have to react to packets and to vring space availability in 
> > a straightforward way.
> 
> Well, the only way for the sending path is to stall the vcpu, 
> otherwise the guest figures "oh, I can't push packets into the 
> vring, let's just drop it", no?

No, that's not how the Linux TCP/IP implementation works.

Filled up TX rings are pretty normal on physical hardware: we do not 
drop packets but the TCP state machine keeps buffering and filling 
the device as it can.

The same will happen with virtual guests as well - there's no packet 
dropping nor 'blocking of the whole guest'.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-04  9:11               ` Ingo Molnar
@ 2011-07-04  9:30                 ` Alexander Graf
  2011-07-04  9:43                   ` Ingo Molnar
  0 siblings, 1 reply; 55+ messages in thread
From: Alexander Graf @ 2011-07-04  9:30 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


On 04.07.2011, at 11:11, Ingo Molnar wrote:

> 
> * Alexander Graf <agraf@suse.de> wrote:
> 
>>>> I don't see how it would. Once you overrun device buffers, you 
>>>> have to do something. Either you drop packets or you stall the 
>>>> guest. I'd usually prefer the former :).
>>> 
>>> What scenario do you see where we'd have to drop packets?
>>> 
>>> When the guest sends packets, we send them over to the host TCP 
>>> socket - no blocking.
>> 
>> When the guest sends packets, I'd hope you have 2 threads:
>> 
>> * vcpu
>> * virtio network queue process
>> 
>> So those two run in parallel now, with the network queue processing 
>> packets while the vcpu pushes packets into the ring. What if the 
>> network thread is slower than the vcpu fills the ring? You only 
>> have so many entries in a vring.
>> 
>>> When the host receives packets it should only read data out of 
>>> the host socket(s) if the vring buffer suggests that there's 
>>> space available.
>> 
>> I agree :).
>> 
>>> So i don't see we'd need to drop packets or block things - we 
>>> just have to react to packets and to vring space availability in 
>>> a straightforward way.
>> 
>> Well, the only way for the sending path is to stall the vcpu, 
>> otherwise the guest figures "oh, I can't push packets into the 
>> vring, let's just drop it", no?
> 
> No, that's not how the Linux TCP/IP implementation works.
> 
> Filled up TX rings are pretty normal on physical hardware: we do not 
> drop packets but the TCP state machine keeps buffering and filling 
> the device as it can.
> 
> The same will happen with virtual guests as well - there's no packet 
> dropping nor 'blocking of the whole guest'.

I see. Can you guarantee that other guests (in case that ever gets implemented) behave the same?


Alex


^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH v2 00/31] Implement user mode network for kvm tools
  2011-07-04  9:30                 ` Alexander Graf
@ 2011-07-04  9:43                   ` Ingo Molnar
  0 siblings, 0 replies; 55+ messages in thread
From: Ingo Molnar @ 2011-07-04  9:43 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Asias He, Anthony Liguori, Stefan Hajnoczi, Pekka Enberg,
	Cyrill Gorcunov, Sasha Levin, Prasad Joshi, kvm


* Alexander Graf <agraf@suse.de> wrote:

> 
> On 04.07.2011, at 11:11, Ingo Molnar wrote:
> 
> > 
> > * Alexander Graf <agraf@suse.de> wrote:
> > 
> >>>> I don't see how it would. Once you overrun device buffers, you 
> >>>> have to do something. Either you drop packets or you stall the 
> >>>> guest. I'd usually prefer the former :).
> >>> 
> >>> What scenario do you see where we'd have to drop packets?
> >>> 
> >>> When the guest sends packets, we send them over to the host TCP 
> >>> socket - no blocking.
> >> 
> >> When the guest sends packets, I'd hope you have 2 threads:
> >> 
> >> * vcpu
> >> * virtio network queue process
> >> 
> >> So those two run in parallel now, with the network queue processing 
> >> packets while the vcpu pushes packets into the ring. What if the 
> >> network thread is slower than the vcpu fills the ring? You only 
> >> have so many entries in a vring.
> >> 
> >>> When the host receives packets it should only read data out of 
> >>> the host socket(s) if the vring buffer suggests that there's 
> >>> space available.
> >> 
> >> I agree :).
> >> 
> >>> So i don't see we'd need to drop packets or block things - we 
> >>> just have to react to packets and to vring space availability in 
> >>> a straightforward way.
> >> 
> >> Well, the only way for the sending path is to stall the vcpu, 
> >> otherwise the guest figures "oh, I can't push packets into the 
> >> vring, let's just drop it", no?
> > 
> > No, that's not how the Linux TCP/IP implementation works.
> > 
> > Filled up TX rings are pretty normal on physical hardware: we do not 
> > drop packets but the TCP state machine keeps buffering and filling 
> > the device as it can.
> > 
> > The same will happen with virtual guests as well - there's no packet 
> > dropping nor 'blocking of the whole guest'.
> 
> I see. Can you guarantee that other guests (in case that ever gets 
> implemented) behave the same?

Do you mean can i remove 100% of fear, uncertainty and doubt about an 
unknown 'black box' guest OS? No.

But the queueing logic of TCP/IP stacks is pretty similar in practice 
so i'd be very surprised if Windows (which i guess you must be 
referring to) dropped packets due to TX overflow. It would be very 
stupid to drop packets on TX: the sending stack has to buffer the TCP 
stream *anyway* (and has no choice about that, the app cannot resend 
the socket data), so it achieves nothing from dropping the packet and 
adding resend complexity to itself.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2011-07-04  9:43 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-30  8:40 [PATCH v2 00/31] Implement user mode network for kvm tools Asias He
2011-06-30  8:40 ` [PATCH v2 01/31] kvm tools: Introduce ethernet frame buffer system for uip Asias He
2011-06-30  8:40 ` [PATCH v2 02/31] kvm tools: Add ARP support " Asias He
2011-06-30  8:40 ` [PATCH v2 03/31] kvm tools: Add IPV4 " Asias He
2011-06-30  8:40 ` [PATCH v2 04/31] kvm tools: Implement IP checksum " Asias He
2011-06-30  8:40 ` [PATCH v2 05/31] kvm tools: Add ICMP support " Asias He
2011-06-30  8:40 ` [PATCH v2 06/31] kvm tools: Introduce struct uip_udp to present UDP package Asias He
2011-06-30  8:40 ` [PATCH v2 07/31] kvm tools: Introduce struct uip_pseudo_hdr to present UDP pseudo header Asias He
2011-06-30  8:40 ` [PATCH v2 08/31] kvm tools: Introduce struct uip_udp_socket Asias He
2011-06-30  8:40 ` [PATCH v2 09/31] kvm tools: Add two helpers to return UDP {header, total} length Asias He
2011-06-30  8:40 ` [PATCH v2 10/31] kvm tools: Add helper to return ethernet header length Asias He
2011-06-30  8:40 ` [PATCH v2 11/31] kvm tools: Implement uip_csum_udp() to calculate UDP checksum Asias He
2011-06-30  8:41 ` [PATCH v2 12/31] kvm tools: Add UDP support for uip Asias He
2011-07-01 11:46   ` Ingo Molnar
2011-07-01 15:24     ` Asias He
2011-06-30  8:41 ` [PATCH v2 13/31] kvm tools: Introduce struct uip_tcp to present TCP package Asias He
2011-06-30  8:41 ` [PATCH v2 14/31] kvm tools: Introduce struct uip_tcp_socket Asias He
2011-06-30  8:41 ` [PATCH v2 15/31] kvm tools: Add helpers to return TCP {header, total, payload} length Asias He
2011-06-30  8:41 ` [PATCH v2 16/31] kvm tools: Add helper to return start address of TCP payload Asias He
2011-06-30  8:41 ` [PATCH v2 17/31] kvm tools: Add helpers to test whether SYN or FIN bit is set Asias He
2011-06-30  8:41 ` [PATCH v2 18/31] kvm tools: Add helper to allocate and get TCP initial sequence number Asias He
2011-06-30  8:41 ` [PATCH v2 19/31] kvm tools: Implement uip_csum_tcp() to calculate TCP checksum Asias He
2011-06-30  8:41 ` [PATCH v2 20/31] kvm tools: Add TCP support for uip Asias He
2011-06-30  8:41 ` [PATCH v2 21/31] kvm tools: Introduce uip_init() " Asias He
2011-06-30  8:41 ` [PATCH v2 22/31] kvm tools: Introduce uip_tx() " Asias He
2011-06-30  8:41 ` [PATCH v2 23/31] kvm tools: Introduce uip_rx() " Asias He
2011-06-30  8:41 ` [PATCH v2 24/31] kvm tools: Add MACRO for user and tap mode for virtio net Asias He
2011-06-30  8:41 ` [PATCH v2 25/31] kvm tools: Reanme net_device to net_dev Asias He
2011-06-30  8:41 ` [PATCH v2 26/31] kvm tools: Introduce -net {user, tap, none} options for virtio net Asias He
2011-06-30  8:41 ` [PATCH v2 27/31] kvm tools: Change default guest MAC address to 00:15:15:15:15:15 Asias He
2011-06-30  8:41 ` [PATCH v2 28/31] kvm tools: Make virtio net work with user mode network Asias He
2011-06-30  8:41 ` [PATCH v2 29/31] kvm tools: Make default network mode to user mode Asias He
2011-06-30  8:41 ` [PATCH v2 30/31] kvm tools: Make default host ip address to 192.168.33.1 Asias He
2011-06-30  8:41 ` [PATCH v2 31/31] kvm tools: Introduce struct net_dev_operations Asias He
2011-06-30  8:56 ` [PATCH v2 00/31] Implement user mode network for kvm tools Stefan Hajnoczi
2011-06-30 15:32   ` Anthony Liguori
2011-07-01  0:18     ` Asias He
2011-07-01 11:53       ` Ingo Molnar
2011-07-01 13:46         ` Alexander Graf
2011-07-02  9:45           ` Pekka Enberg
2011-07-02 10:30             ` Ingo Molnar
2011-07-02 11:19             ` Alexander Graf
2011-07-02 11:27               ` Pekka Enberg
2011-07-02 12:31                 ` Alexander Graf
2011-07-03 19:42           ` Ingo Molnar
2011-07-03 22:15             ` Alexander Graf
2011-07-04  9:11               ` Ingo Molnar
2011-07-04  9:30                 ` Alexander Graf
2011-07-04  9:43                   ` Ingo Molnar
2011-07-02  9:42         ` Pekka Enberg
2011-06-30 23:38   ` Asias He
2011-07-01 16:50     ` Stefan Hajnoczi
2011-07-01 20:36       ` Pekka Enberg
2011-07-02  3:49         ` Asias He
2011-07-02  9:02           ` Ingo Molnar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.