aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2025-03-05 15:32:28 +1100
committerStefano Brivio <sbrivio@redhat.com>2025-03-05 21:46:17 +0100
commit008175636c789d36ef585a94eee4d62536cac7d6 (patch)
tree6f64364fb4d365739f7333c20410487a8c9b4e10
parent52419a64f2dfa31707b31148e6a311bb57be6e5f (diff)
downloadpasst-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.h25
-rw-r--r--tap.c4
-rw-r--r--tcp.c4
3 files changed, 27 insertions, 6 deletions
diff --git a/ip.h b/ip.h
index 858cc89..5edb7e7 100644
--- a/ip.h
+++ b/ip.h
@@ -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);
diff --git a/tap.c b/tap.c
index 44b0fc0..3908262 100644
--- a/tap.c
+++ b/tap.c
@@ -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;
}
diff --git a/tcp.c b/tcp.c
index b3aa9a2..7459803 100644
--- a/tcp.c
+++ b/tcp.c
@@ -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,