Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial planned improvements to parsing #73

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions common/parsing_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,14 @@ 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

#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) ||
Expand All @@ -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);
Expand Down Expand Up @@ -102,13 +109,25 @@ 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++;
}

nh->pos = vlh;
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)
Expand Down
9 changes: 7 additions & 2 deletions packet-solutions/xdp_vlan02_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -51,14 +54,16 @@ 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++;
}

nh->pos = vlh;
return h_proto; /* network-byte-order */
}
#endif

SEC("xdp_vlan02")
int xdp_vlan_02(struct xdp_md *ctx)
Expand All @@ -74,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, &eth, &vlans);
eth_type = parse_ethhdr_vlan(&nh, data_end, &eth, &vlans);

if (eth_type < 0)
return XDP_ABORTED;
Expand Down