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:
Jesper Dangaard Brouer
2020-11-15 15:26:12 +01:00
parent 097079cde1
commit c0cd6aedba

View File

@@ -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,