mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
parsing_helpers.h re-add IPv6 skip of extension headers
This code comes from xdp-tools repo. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
This commit is contained in:
@@ -61,6 +61,11 @@ struct icmphdr_common {
|
||||
#define VLAN_MAX_DEPTH 2
|
||||
#endif
|
||||
|
||||
/* Longest chain of IPv6 extension headers to resolve */
|
||||
#ifndef IPV6_EXT_MAX_CHAIN
|
||||
#define IPV6_EXT_MAX_CHAIN 6
|
||||
#endif
|
||||
|
||||
#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
|
||||
/* Struct for collecting VLANs after parsing via parse_ethhdr_vlan */
|
||||
struct collect_vlans {
|
||||
@@ -131,6 +136,41 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh,
|
||||
return parse_ethhdr_vlan(nh, data_end, ethhdr, NULL);
|
||||
}
|
||||
|
||||
static __always_inline int skip_ip6hdrext(struct hdr_cursor *nh,
|
||||
void *data_end,
|
||||
__u8 next_hdr_type)
|
||||
{
|
||||
for (int i = 0; i < IPV6_EXT_MAX_CHAIN; ++i) {
|
||||
struct ipv6_opt_hdr *hdr = nh->pos;
|
||||
|
||||
if (hdr + 1 > data_end)
|
||||
return -1;
|
||||
|
||||
switch (next_hdr_type) {
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
case IPPROTO_MH:
|
||||
nh->pos = (char *)hdr + (hdr->hdrlen + 1) * 8;
|
||||
next_hdr_type = hdr->nexthdr;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
nh->pos = (char *)hdr + (hdr->hdrlen + 2) * 4;
|
||||
next_hdr_type = hdr->nexthdr;
|
||||
break;
|
||||
case IPPROTO_FRAGMENT:
|
||||
nh->pos = (char *)hdr + 8;
|
||||
next_hdr_type = hdr->nexthdr;
|
||||
break;
|
||||
default:
|
||||
/* Found a header that is not an IPv6 extension header */
|
||||
return next_hdr_type;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static __always_inline int parse_ip6hdr(struct hdr_cursor *nh,
|
||||
void *data_end,
|
||||
struct ipv6hdr **ip6hdr)
|
||||
@@ -147,7 +187,7 @@ static __always_inline int parse_ip6hdr(struct hdr_cursor *nh,
|
||||
nh->pos = ip6h + 1;
|
||||
*ip6hdr = ip6h;
|
||||
|
||||
return ip6h->nexthdr;
|
||||
return skip_ip6hdrext(nh, data_end, ip6h->nexthdr);
|
||||
}
|
||||
|
||||
static __always_inline int parse_iphdr(struct hdr_cursor *nh,
|
||||
|
Reference in New Issue
Block a user