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.
Unified · Split
| @@ -783,6 +783,7 @@ enum nft_payload_csum_flags { · 782 unmodified lines | ||
| 783 | 783 | enum nft_inner_type { |
| 784 | 784 | NFT_INNER_UNSPEC = 0, |
| 785 | 785 | NFT_INNER_VXLAN, |
| 786 | + NFT_INNER_GENEVE, | |
| 786 | 787 | }; |
| 787 | 788 | |
| 788 | 789 | enum nft_inner_flags { |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/tcp.h> |
| 18 | 18 | #include <linux/udp.h> |
| 19 | 19 | #include <net/gre.h> |
| 20 | +#include <net/geneve.h> | |
| 20 | 21 | #include <net/ip.h> |
| 21 | 22 | #include <linux/icmpv6.h> |
| 22 | 23 | #include <linux/ip.h> |
| @@ -181,6 +182,22 @@ static int nft_inner_parse_tunhdr(const struct nft_inner *priv, · 158 unmodified lines | ||
| 181 | 182 | ctx->flags |= NFT_PAYLOAD_CTX_INNER_TUN; |
| 182 | 183 | *off += priv->hdrsize; |
| 183 | 184 | |
| 185 | + switch (priv->type) { | |
| 186 | + case NFT_INNER_GENEVE: { | |
| 187 | + struct genevehdr *gnvh, _gnvh; | |
| 188 | + | |
| 189 | + gnvh = skb_header_pointer(pkt->skb, pkt->inneroff, | |
| 190 | + sizeof(_gnvh), &_gnvh); | |
| 191 | + if (!gnvh) | |
| 192 | + return -1; | |
| 193 | + | |
| 194 | + *off += gnvh->opt_len * 4; | |
| 195 | + } | |
| 196 | + break; | |
| 197 | + default: | |
| 198 | + break; | |
| 199 | + } | |
| 200 | + | |
| 184 | 201 | return 0; |
| 185 | 202 | } |
| 186 | 203 | |