diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2025-03-05 15:32:28 +1100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2025-03-05 21:46:17 +0100 |
commit | 008175636c789d36ef585a94eee4d62536cac7d6 (patch) | |
tree | 6f64364fb4d365739f7333c20410487a8c9b4e10 | |
parent | 52419a64f2dfa31707b31148e6a311bb57be6e5f (diff) | |
download | passt-008175636c789d36ef585a94eee4d62536cac7d6.tar passt-008175636c789d36ef585a94eee4d62536cac7d6.tar.gz passt-008175636c789d36ef585a94eee4d62536cac7d6.tar.bz2 passt-008175636c789d36ef585a94eee4d62536cac7d6.tar.lz passt-008175636c789d36ef585a94eee4d62536cac7d6.tar.xz passt-008175636c789d36ef585a94eee4d62536cac7d6.tar.zst passt-008175636c789d36ef585a94eee4d62536cac7d6.zip |
ip: Helpers to access IPv6 flow label
The flow label is a 20-bit field in the IPv6 header. The length and
alignment make it awkward to pass around as is. Obviously, it can be
packed into a 32-bit integer though, and we do this in two places. We
have some further upcoming places where we want to manipulate the flow
label, so make some helpers for marshalling and unmarshalling it to an
integer.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r-- | ip.h | 25 | ||||
-rw-r--r-- | tap.c | 4 | ||||
-rw-r--r-- | tcp.c | 4 |
3 files changed, 27 insertions, 6 deletions
@@ -91,6 +91,31 @@ struct ipv6_opt_hdr { */ } __attribute__((packed)); /* required for some archs */ +/** + * ip6_set_flow_lbl() - Set flow label in an IPv6 header + * @ip6h: Pointer to IPv6 header, updated + * @flow: Set @ip6h flow label to the low 20 bits of this integer + */ +static inline void ip6_set_flow_lbl(struct ipv6hdr *ip6h, uint32_t flow) +{ + ip6h->flow_lbl[0] = (flow >> 16) & 0xf; + ip6h->flow_lbl[1] = (flow >> 8) & 0xff; + ip6h->flow_lbl[2] = (flow >> 0) & 0xff; +} + +/** ip6_get_flow_lbl() - Get flow label from an IPv6 header + * @ip6h: Pointer to IPv6 header + * + * Return: flow label from @ip6h as an integer (<= 20 bits) + */ +/* cppcheck-suppress unusedFunction */ +static inline uint32_t ip6_get_flow_lbl(const struct ipv6hdr *ip6h) +{ + return (ip6h->flow_lbl[0] & 0xf) << 16 | + ip6h->flow_lbl[1] << 8 | + ip6h->flow_lbl[2]; +} + char *ipv6_l4hdr(const struct pool *p, int idx, size_t offset, uint8_t *proto, size_t *dlen); @@ -241,9 +241,7 @@ static void *tap_push_ip6h(struct ipv6hdr *ip6h, ip6h->hop_limit = 255; ip6h->saddr = *src; ip6h->daddr = *dst; - ip6h->flow_lbl[0] = (flow >> 16) & 0xf; - ip6h->flow_lbl[1] = (flow >> 8) & 0xff; - ip6h->flow_lbl[2] = (flow >> 0) & 0xff; + ip6_set_flow_lbl(ip6h, flow); return ip6h + 1; } @@ -963,9 +963,7 @@ void tcp_fill_headers(const struct tcp_tap_conn *conn, ip6h->version = 6; ip6h->nexthdr = IPPROTO_TCP; - ip6h->flow_lbl[0] = (conn->sock >> 16) & 0xf; - ip6h->flow_lbl[1] = (conn->sock >> 8) & 0xff; - ip6h->flow_lbl[2] = (conn->sock >> 0) & 0xff; + ip6_set_flow_lbl(ip6h, conn->sock); if (!no_tcp_csum) { psum = proto_ipv6_header_psum(l4len, IPPROTO_TCP, |