netfilter: nft_inner: add geneve support
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 17 Oct 2022 11:03:34 +0000 (13:03 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 25 Oct 2022 11:48:42 +0000 (13:48 +0200)
Geneve tunnel header may contain options, parse geneve header and update
offset to point to the link layer header according to the opt_len field.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/uapi/linux/netfilter/nf_tables.h
net/netfilter/nft_inner.c

index 05a15dce8271a4895de0de6b03079441a39b5035..e4b739d57480a51d20a9932da78cb5a15177576d 100644 (file)
@@ -783,6 +783,7 @@ enum nft_payload_csum_flags {
 enum nft_inner_type {
        NFT_INNER_UNSPEC        = 0,
        NFT_INNER_VXLAN,
+       NFT_INNER_GENEVE,
 };
 
 enum nft_inner_flags {
index c43a2fe0ceb7873735c4730239cd931067288aa9..19fdc8c70cd1bf774d2adec835c46e9754e32cd1 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <net/gre.h>
+#include <net/geneve.h>
 #include <net/ip.h>
 #include <linux/icmpv6.h>
 #include <linux/ip.h>
@@ -181,6 +182,22 @@ static int nft_inner_parse_tunhdr(const struct nft_inner *priv,
        ctx->flags |= NFT_PAYLOAD_CTX_INNER_TUN;
        *off += priv->hdrsize;
 
+       switch (priv->type) {
+       case NFT_INNER_GENEVE: {
+               struct genevehdr *gnvh, _gnvh;
+
+               gnvh = skb_header_pointer(pkt->skb, pkt->inneroff,
+                                         sizeof(_gnvh), &_gnvh);
+               if (!gnvh)
+                       return -1;
+
+               *off += gnvh->opt_len * 4;
+               }
+               break;
+       default:
+               break;
+       }
+
        return 0;
 }