From f6e2e6573ed0c5aa52bd85309911e96e09a40bf5 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Tue, 3 Sep 2019 13:54:38 +0200 Subject: [PATCH 1/3] common: parsing_headers.h reduce default VLAN depth to 2 Given XDP is very performance focused, it is unwise to default parse many VLAN layers. Those 2 as it is very uncommon to have more. Signed-off-by: Jesper Dangaard Brouer --- common/parsing_helpers.h | 2 +- libbpf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/parsing_helpers.h b/common/parsing_helpers.h index 84985ec3..b41385d8 100644 --- a/common/parsing_helpers.h +++ b/common/parsing_helpers.h @@ -56,7 +56,7 @@ struct icmphdr_common { /* Allow users of header file to redefine VLAN max depth */ #ifndef VLAN_MAX_DEPTH -#define VLAN_MAX_DEPTH 4 +#define VLAN_MAX_DEPTH 2 #endif static __always_inline int proto_is_vlan(__u16 h_proto) diff --git a/libbpf b/libbpf index 476e158b..910c475f 160000 --- a/libbpf +++ b/libbpf @@ -1 +1 @@ -Subproject commit 476e158b07ea5f36f4475735330c1152ffe15acc +Subproject commit 910c475f09e5c269f441d7496c27dace30dc2335 From 3d4bd924708d65033a1cdb96e2d72981d16ca2b3 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Tue, 3 Sep 2019 14:01:19 +0200 Subject: [PATCH 2/3] packet-solutionsi xdp_vlan02_kern VLAN extraction missed bpf_ntohs() Signed-off-by: Jesper Dangaard Brouer --- packet-solutions/xdp_vlan02_kern.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packet-solutions/xdp_vlan02_kern.c b/packet-solutions/xdp_vlan02_kern.c index a3a5ed54..8641ad90 100644 --- a/packet-solutions/xdp_vlan02_kern.c +++ b/packet-solutions/xdp_vlan02_kern.c @@ -51,7 +51,8 @@ static __always_inline int __parse_ethhdr_vlan(struct hdr_cursor *nh, h_proto = vlh->h_vlan_encapsulated_proto; if (vlans) { - vlans->id[i] = vlh->h_vlan_TCI & VLAN_VID_MASK; + vlans->id[i] = + bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK; } vlh++; } From c2b44a22018ca460d96e982b2f094561cf6673eb Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Tue, 3 Sep 2019 16:47:21 +0200 Subject: [PATCH 3/3] Create parse_ethhdr_vlan() in parsing_helpers.h This is based on same function from packet-solutions/xdp_vlan02_kern.c that also extracts VLANs. It needs to be removed from packet-solutions/xdp_vlan02_kern.c, but for now its just ifdef defined out-of-code. Need to run some tests and look at BPF byte-code to make sure it does the right thing. The original parse_ethhdr() is implemented by calling parse_ethhdr_vlan() with NULL argument for stucture to collect IDs into. The compiler should remove the parts that are not needed. Signed-off-by: Jesper Dangaard Brouer --- common/parsing_helpers.h | 23 +++++++++++++++++++++-- packet-solutions/xdp_vlan02_kern.c | 6 +++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/common/parsing_helpers.h b/common/parsing_helpers.h index b41385d8..d1298663 100644 --- a/common/parsing_helpers.h +++ b/common/parsing_helpers.h @@ -59,6 +59,11 @@ struct icmphdr_common { #define VLAN_MAX_DEPTH 2 #endif +#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ +struct vlans { + __u16 id[VLAN_MAX_DEPTH]; +}; + static __always_inline int proto_is_vlan(__u16 h_proto) { return !!(h_proto == bpf_htons(ETH_P_8021Q) || @@ -70,8 +75,10 @@ static __always_inline int proto_is_vlan(__u16 h_proto) * Ethernet header. Thus, caller can look at eth->h_proto to see if this was a * VLAN tagged packet. */ -static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end, - struct ethhdr **ethhdr) +static __always_inline int parse_ethhdr_vlan(struct hdr_cursor *nh, + void *data_end, + struct ethhdr **ethhdr, + struct vlans *vlans) { struct ethhdr *eth = nh->pos; int hdrsize = sizeof(*eth); @@ -102,6 +109,10 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end, break; h_proto = vlh->h_vlan_encapsulated_proto; + if (vlans) /* collect VLAN ids */ + vlans->id[i] = + (bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK); + vlh++; } @@ -109,6 +120,14 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end, return h_proto; /* network-byte-order */ } +static __always_inline int parse_ethhdr(struct hdr_cursor *nh, + void *data_end, + struct ethhdr **ethhdr) +{ + /* Expect compiler to remove collect VLAN ids */ + return parse_ethhdr_vlan(nh, data_end, ethhdr, NULL); +} + static __always_inline int parse_ip6hdr(struct hdr_cursor *nh, void *data_end, struct ipv6hdr **ip6hdr) diff --git a/packet-solutions/xdp_vlan02_kern.c b/packet-solutions/xdp_vlan02_kern.c index 8641ad90..da3cc31c 100644 --- a/packet-solutions/xdp_vlan02_kern.c +++ b/packet-solutions/xdp_vlan02_kern.c @@ -10,11 +10,14 @@ #define VLAN_MAX_DEPTH 10 #include "../common/parsing_helpers.h" +#if 0 #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ struct vlans { __u16 id[VLAN_MAX_DEPTH]; }; +#endif +#if 0 /* moved to parsing_helpers.h */ /* Based on parse_ethhdr() */ static __always_inline int __parse_ethhdr_vlan(struct hdr_cursor *nh, void *data_end, @@ -60,6 +63,7 @@ static __always_inline int __parse_ethhdr_vlan(struct hdr_cursor *nh, nh->pos = vlh; return h_proto; /* network-byte-order */ } +#endif SEC("xdp_vlan02") int xdp_vlan_02(struct xdp_md *ctx) @@ -75,7 +79,7 @@ int xdp_vlan_02(struct xdp_md *ctx) struct vlans vlans; struct ethhdr *eth; - eth_type = __parse_ethhdr_vlan(&nh, data_end, ð, &vlans); + eth_type = parse_ethhdr_vlan(&nh, data_end, ð, &vlans); if (eth_type < 0) return XDP_ABORTED;