tap: Remove unhelpeful vnet_pre optimization from tap_send()
Callers of tap_send() can optionally use a small optimization by adding extra space for the 4 byte length header used on the qemu socket interface. tap_ip_send() is currently the only user of this, but this is used only for "slow path" ICMP and DHCP packets, so there's not a lot of value to the optimization. Worse, having the two paths here complicates the interface and makes future cleanups difficult, so just remove it. I have some plans to bring back the optimization in a more general way in future, but for now it's just in the way. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
f72b63e92f
commit
fb5d1c5d7d
5 changed files with 13 additions and 24 deletions
2
arp.c
2
arp.c
|
@ -81,7 +81,7 @@ int arp(const struct ctx *c, const struct pool *p)
|
||||||
memcpy(eh->h_dest, eh->h_source, sizeof(eh->h_dest));
|
memcpy(eh->h_dest, eh->h_source, sizeof(eh->h_dest));
|
||||||
memcpy(eh->h_source, c->mac, sizeof(eh->h_source));
|
memcpy(eh->h_source, c->mac, sizeof(eh->h_source));
|
||||||
|
|
||||||
if (tap_send(c, eh, len, 0) < 0)
|
if (tap_send(c, eh, len) < 0)
|
||||||
perror("ARP: send");
|
perror("ARP: send");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
dhcp.c
2
dhcp.c
|
@ -377,7 +377,7 @@ int dhcp(const struct ctx *c, const struct pool *p)
|
||||||
memcpy(eh->h_dest, eh->h_source, ETH_ALEN);
|
memcpy(eh->h_dest, eh->h_source, ETH_ALEN);
|
||||||
memcpy(eh->h_source, c->mac, ETH_ALEN);
|
memcpy(eh->h_source, c->mac, ETH_ALEN);
|
||||||
|
|
||||||
if (tap_send(c, eh, len, 0) < 0)
|
if (tap_send(c, eh, len) < 0)
|
||||||
perror("DHCP: send");
|
perror("DHCP: send");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
ndp.c
2
ndp.c
|
@ -200,7 +200,7 @@ dns_done:
|
||||||
memcpy(ehr->h_source, c->mac, ETH_ALEN);
|
memcpy(ehr->h_source, c->mac, ETH_ALEN);
|
||||||
ehr->h_proto = htons(ETH_P_IPV6);
|
ehr->h_proto = htons(ETH_P_IPV6);
|
||||||
|
|
||||||
if (tap_send(c, ehr, len, 0) < 0)
|
if (tap_send(c, ehr, len) < 0)
|
||||||
perror("NDP: send");
|
perror("NDP: send");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
21
tap.c
21
tap.c
|
@ -66,34 +66,24 @@ static PACKET_POOL_NOINIT(pool_tap6, TAP_MSGS, pkt_buf);
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
* @data: Packet buffer
|
* @data: Packet buffer
|
||||||
* @len: Total L2 packet length
|
* @len: Total L2 packet length
|
||||||
* @vnet_pre: Buffer has four-byte headroom
|
|
||||||
*
|
*
|
||||||
* Return: return code from send() or write()
|
* Return: return code from send() or write()
|
||||||
*/
|
*/
|
||||||
int tap_send(const struct ctx *c, const void *data, size_t len, int vnet_pre)
|
int tap_send(const struct ctx *c, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
if (vnet_pre)
|
|
||||||
pcap((char *)data + 4, len);
|
|
||||||
else
|
|
||||||
pcap(data, len);
|
pcap(data, len);
|
||||||
|
|
||||||
if (c->mode == MODE_PASST) {
|
if (c->mode == MODE_PASST) {
|
||||||
int flags = MSG_NOSIGNAL | MSG_DONTWAIT;
|
int flags = MSG_NOSIGNAL | MSG_DONTWAIT;
|
||||||
|
|
||||||
if (vnet_pre) {
|
|
||||||
*((uint32_t *)data) = htonl(len);
|
|
||||||
len += 4;
|
|
||||||
} else {
|
|
||||||
uint32_t vnet_len = htonl(len);
|
uint32_t vnet_len = htonl(len);
|
||||||
|
|
||||||
if (send(c->fd_tap, &vnet_len, 4, flags) < 0)
|
if (send(c->fd_tap, &vnet_len, 4, flags) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return send(c->fd_tap, data, len, flags);
|
return send(c->fd_tap, data, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return write(c->fd_tap, (char *)data + (vnet_pre ? 4 : 0), len);
|
return write(c->fd_tap, (char *)data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,10 +125,9 @@ void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
|
||||||
const char *in, size_t len, uint32_t flow)
|
const char *in, size_t len, uint32_t flow)
|
||||||
{
|
{
|
||||||
char buf[USHRT_MAX];
|
char buf[USHRT_MAX];
|
||||||
char *pkt = buf + 4;
|
|
||||||
struct ethhdr *eh;
|
struct ethhdr *eh;
|
||||||
|
|
||||||
eh = (struct ethhdr *)pkt;
|
eh = (struct ethhdr *)buf;
|
||||||
|
|
||||||
/* TODO: ARP table lookup */
|
/* TODO: ARP table lookup */
|
||||||
memcpy(eh->h_dest, c->mac_guest, ETH_ALEN);
|
memcpy(eh->h_dest, c->mac_guest, ETH_ALEN);
|
||||||
|
@ -174,7 +163,7 @@ void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
|
||||||
csum_icmp4(ih, ih + 1, len - sizeof(*ih));
|
csum_icmp4(ih, ih + 1, len - sizeof(*ih));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tap_send(c, buf, len + sizeof(*iph) + sizeof(*eh), 1) < 0)
|
if (tap_send(c, buf, len + sizeof(*iph) + sizeof(*eh)) < 0)
|
||||||
debug("tap: failed to send %lu bytes (IPv4)", len);
|
debug("tap: failed to send %lu bytes (IPv4)", len);
|
||||||
} else {
|
} else {
|
||||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)(eh + 1);
|
struct ipv6hdr *ip6h = (struct ipv6hdr *)(eh + 1);
|
||||||
|
@ -215,7 +204,7 @@ void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
|
||||||
ip6h->flow_lbl[2] = (flow >> 0) & 0xff;
|
ip6h->flow_lbl[2] = (flow >> 0) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tap_send(c, buf, len + sizeof(*ip6h) + sizeof(*eh), 1) < 1)
|
if (tap_send(c, buf, len + sizeof(*ip6h) + sizeof(*eh)) < 1)
|
||||||
debug("tap: failed to send %lu bytes (IPv6)", len);
|
debug("tap: failed to send %lu bytes (IPv6)", len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
tap.h
2
tap.h
|
@ -11,7 +11,7 @@ const struct in6_addr *tap_ip6_daddr(const struct ctx *c,
|
||||||
const struct in6_addr *src);
|
const struct in6_addr *src);
|
||||||
void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
|
void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
|
||||||
const char *in, size_t len, uint32_t flow);
|
const char *in, size_t len, uint32_t flow);
|
||||||
int tap_send(const struct ctx *c, const void *data, size_t len, int vnet_pre);
|
int tap_send(const struct ctx *c, const void *data, size_t len);
|
||||||
void tap_handler(struct ctx *c, int fd, uint32_t events,
|
void tap_handler(struct ctx *c, int fd, uint32_t events,
|
||||||
const struct timespec *now);
|
const struct timespec *now);
|
||||||
void tap_sock_init(struct ctx *c);
|
void tap_sock_init(struct ctx *c);
|
||||||
|
|
Loading…
Reference in a new issue