aboutgitcodebugslistschat
path: root/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'udp.c')
-rw-r--r--udp.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/udp.c b/udp.c
index adca819..c940749 100644
--- a/udp.c
+++ b/udp.c
@@ -186,39 +186,40 @@ static struct udp_payload_t {
#endif
udp_payload[UDP_MAX_FRAMES];
+/* Ethernet header for IPv4 frames */
+static struct ethhdr udp4_eth_hdr;
+
/**
* udp4_l2_buf_t - Pre-cooked IPv4 packet buffers for tap connections
* @s_in: Source socket address, filled in by recvmmsg()
* @taph: Tap backend specific header
- * @eh: Prefilled ethernet header
* @iph: Pre-filled IP header (except for tot_len and saddr)
*/
static struct udp4_l2_buf_t {
struct sockaddr_in s_in;
struct tap_hdr taph;
- struct ethhdr eh;
struct iphdr iph;
} __attribute__ ((packed, aligned(__alignof__(unsigned int))))
udp4_l2_buf[UDP_MAX_FRAMES];
+/* Ethernet header for IPv6 frames */
+static struct ethhdr udp6_eth_hdr;
+
/**
* udp6_l2_buf_t - Pre-cooked IPv6 packet buffers for tap connections
* @s_in6: Source socket address, filled in by recvmmsg()
* @taph: Tap backend specific header
- * @eh: Pre-filled ethernet header
* @ip6h: Pre-filled IP header (except for payload_len and addresses)
*/
struct udp6_l2_buf_t {
struct sockaddr_in6 s_in6;
#ifdef __AVX2__
/* Align ip6h to 32-byte boundary. */
- uint8_t pad[64 - (sizeof(struct sockaddr_in6) + sizeof(struct ethhdr) +
- sizeof(struct tap_hdr))];
+ uint8_t pad[64 - (sizeof(struct sockaddr_in6) + sizeof(struct tap_hdr))];
#endif
struct tap_hdr taph;
- struct ethhdr eh;
struct ipv6hdr ip6h;
#ifdef __AVX2__
} __attribute__ ((packed, aligned(32)))
@@ -307,15 +308,8 @@ static void udp_invert_portmap(struct udp_fwd_ports *fwd)
*/
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s)
{
- int i;
-
- for (i = 0; i < UDP_MAX_FRAMES; i++) {
- struct udp4_l2_buf_t *b4 = &udp4_l2_buf[i];
- struct udp6_l2_buf_t *b6 = &udp6_l2_buf[i];
-
- eth_update_mac(&b4->eh, eth_d, eth_s);
- eth_update_mac(&b6->eh, eth_d, eth_s);
- }
+ eth_update_mac(&udp4_eth_hdr, eth_d, eth_s);
+ eth_update_mac(&udp6_eth_hdr, eth_d, eth_s);
}
/**
@@ -329,6 +323,8 @@ static void udp_iov_init_one(const struct ctx *c, size_t i)
struct iovec *siov = &udp_l2_iov_sock[i];
*siov = IOV_OF_LVALUE(payload->data);
+ udp4_eth_hdr.h_proto = htons_constant(ETH_P_IP);
+ udp6_eth_hdr.h_proto = htons_constant(ETH_P_IPV6);
if (c->ifi4) {
struct msghdr *mh = &udp4_l2_mh_sock[i].msg_hdr;
@@ -336,7 +332,6 @@ static void udp_iov_init_one(const struct ctx *c, size_t i)
struct iovec *tiov = udp4_l2_iov_tap[i];
*buf = (struct udp4_l2_buf_t) {
- .eh = ETH_HDR_INIT(ETH_P_IP),
.iph = L2_BUF_IP4_INIT(IPPROTO_UDP)
};
@@ -346,7 +341,7 @@ static void udp_iov_init_one(const struct ctx *c, size_t i)
mh->msg_iovlen = 1;
tiov[UDP_IOV_TAP] = tap_hdr_iov(c, &buf->taph);
- tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(buf->eh);
+ tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(udp4_eth_hdr);
tiov[UDP_IOV_IP] = IOV_OF_LVALUE(buf->iph);
tiov[UDP_IOV_PAYLOAD].iov_base = payload;
}
@@ -357,7 +352,6 @@ static void udp_iov_init_one(const struct ctx *c, size_t i)
struct iovec *tiov = udp6_l2_iov_tap[i];
*buf = (struct udp6_l2_buf_t) {
- .eh = ETH_HDR_INIT(ETH_P_IPV6),
.ip6h = L2_BUF_IP6_INIT(IPPROTO_UDP)
};
@@ -367,7 +361,7 @@ static void udp_iov_init_one(const struct ctx *c, size_t i)
mh->msg_iovlen = 1;
tiov[UDP_IOV_TAP] = tap_hdr_iov(c, &buf->taph);
- tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(buf->eh);
+ tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(udp6_eth_hdr);
tiov[UDP_IOV_IP] = IOV_OF_LVALUE(buf->ip6h);
tiov[UDP_IOV_PAYLOAD].iov_base = payload;
}
@@ -631,7 +625,7 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *bh,
bp->uh.len = htons(l4len);
csum_udp4(&bp->uh, src, dst, bp->data, dlen);
- tap_hdr_update(&bh->taph, l3len + sizeof(bh->eh));
+ tap_hdr_update(&bh->taph, l3len + sizeof(udp4_eth_hdr));
return l4len;
}
@@ -702,7 +696,7 @@ static size_t udp_update_hdr6(const struct ctx *c, struct udp6_l2_buf_t *bh,
bp->uh.len = bh->ip6h.payload_len;
csum_udp6(&bp->uh, src, dst, bp->data, dlen);
- tap_hdr_update(&bh->taph, l4len + sizeof(bh->ip6h) + sizeof(bh->eh));
+ tap_hdr_update(&bh->taph, l4len + sizeof(bh->ip6h) + sizeof(udp6_eth_hdr));
return l4len;
}