Skip to content

Commit

Permalink
netfilter: nft_payload: access GRE payload via inner offset
Browse files Browse the repository at this point in the history
Parse GRE v0 packets to properly set up inner offset, this allow for
matching on inner headers.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Pablo Neira Ayuso committed Oct 25, 2022
1 parent d037abc commit c247897
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions net/netfilter/nft_payload.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
/* For layer 4 checksum field offset. */
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/gre.h>
#include <linux/icmpv6.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
Expand Down Expand Up @@ -100,6 +101,37 @@ static int __nft_payload_inner_offset(struct nft_pktinfo *pkt)
pkt->inneroff = thoff + __tcp_hdrlen(th);
}
break;
case IPPROTO_GRE: {
u32 offset = sizeof(struct gre_base_hdr), version;
struct gre_base_hdr *gre, _gre;

gre = skb_header_pointer(pkt->skb, thoff, sizeof(_gre), &_gre);
if (!gre)
return -1;

version = gre->flags & GRE_VERSION;
switch (version) {
case GRE_VERSION_0:
if (gre->flags & GRE_ROUTING)
return -1;

if (gre->flags & GRE_CSUM) {
offset += sizeof_field(struct gre_full_hdr, csum) +
sizeof_field(struct gre_full_hdr, reserved1);
}
if (gre->flags & GRE_KEY)
offset += sizeof_field(struct gre_full_hdr, key);

if (gre->flags & GRE_SEQ)
offset += sizeof_field(struct gre_full_hdr, seq);
break;
default:
return -1;
}

pkt->inneroff = thoff + offset;
}
break;
default:
return -1;
}
Expand Down

0 comments on commit c247897

Please sign in to comment.