@@ -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);
@@ -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;
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(-)