aboutgitcodebugslistschat
path: root/tap.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-07-21 12:01:04 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-07-21 12:01:04 +0200
commit64a0ba3b272dd9ee175e0c6256a6d0cb1733599b (patch)
tree4a9ab4a8c4a264ad66d12ac8cc597a062f788963 /tap.c
parent7fa3e90290d1966e25f3f8882ee25f14808e8e48 (diff)
downloadpasst-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.gz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.bz2
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.lz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.xz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.zst
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.zip
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 <sbrivio@redhat.com>
Diffstat (limited to 'tap.c')
-rw-r--r--tap.c23
1 files changed, 18 insertions, 5 deletions
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: