From 64a0ba3b272dd9ee175e0c6256a6d0cb1733599b Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 21 Jul 2021 12:01:04 +0200 Subject: udp: Introduce recvmmsg()/sendmmsg(), zero-copy path from socket Packets are received directly onto pre-cooked, static buffers for IPv4 (with partial checksum pre-calculation) and IPv6 frames, with pre-filled Ethernet addresses and, partially, IP headers, and sent out from the same buffers with sendmmsg(), for both passt and pasta (non-local traffic only) modes. Signed-off-by: Stefano Brivio --- tap.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tap.c') diff --git a/tap.c b/tap.c index 583344d..264a1a4 100644 --- a/tap.c +++ b/tap.c @@ -219,7 +219,10 @@ static int tap4_handler(struct ctx *c, struct tap_msg *msg, size_t count, iph = (struct iphdr *)(eh + 1); l4h = (char *)iph + iph->ihl * 4; - c->addr4_seen = iph->saddr; + if (c->addr4_seen != iph->saddr) { + c->addr4_seen = iph->saddr; + proto_update_l2_buf(NULL, NULL, &c->addr4_seen); + } msg[i].l4h = l4h; msg[i].l4_len = len - ((intptr_t)l4h - (intptr_t)eh); @@ -332,10 +335,14 @@ static int tap6_handler(struct ctx *c, struct tap_msg *msg, size_t count, msg[i].l4h = l4h; msg[i].l4_len = len - ((intptr_t)l4h - (intptr_t)eh); - if (IN6_IS_ADDR_LINKLOCAL(&ip6h->saddr)) + if (IN6_IS_ADDR_LINKLOCAL(&ip6h->saddr)) { c->addr6_ll_seen = ip6h->saddr; - else + + if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6_seen)) + c->addr6_seen = ip6h->saddr; + } else { c->addr6_seen = ip6h->saddr; + } ip6h->saddr = c->addr6; @@ -458,7 +465,10 @@ static int tap_handler_passt(struct ctx *c, struct timespec *now) while (i < msg_count) { eh = (struct ethhdr *)msg[i].start; - memcpy(c->mac_guest, eh->h_source, ETH_ALEN); + if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) { + memcpy(c->mac_guest, eh->h_source, ETH_ALEN); + proto_update_l2_buf(c->mac_guest, NULL, NULL); + } switch (ntohs(eh->h_proto)) { case ETH_P_ARP: @@ -516,7 +526,10 @@ static int tap_handler_pasta(struct ctx *c, struct timespec *now) pcap(msg.start, msg.len); - memcpy(c->mac_guest, eh->h_source, ETH_ALEN); + if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) { + memcpy(c->mac_guest, eh->h_source, ETH_ALEN); + proto_update_l2_buf(c->mac_guest, NULL, NULL); + } switch (ntohs(eh->h_proto)) { case ETH_P_ARP: -- cgit v1.2.3