mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-09-05 13:11:44 +00:00
kvm tools: Introduce uip_tx() for uip
This patch implement tx interface for uip. uip_tx() can be called in virtio_net_tx_thread(). It dispatches ethernet frame to ARP or IP handling code. Signed-off-by: Asias He <asias.hejun@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
@@ -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);
|
||||
|
||||
+69
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user