]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add geneve matching support
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 2 Jan 2023 14:36:39 +0000 (15:36 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 2 Jan 2023 14:36:39 +0000 (15:36 +0100)
Add support for GENEVE vni and (ether) type header field.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/proto.h
src/parser_bison.y
src/proto.c
src/scanner.l

index 4b0c71467638636d3ebc85bf36a069c541703b38..c2c973f383cfa4dfe284be3f597b77e81a3d091e 100644 (file)
@@ -97,6 +97,7 @@ enum proto_desc_id {
        PROTO_DESC_VLAN,
        PROTO_DESC_ETHER,
        PROTO_DESC_VXLAN,
+       PROTO_DESC_GENEVE,
        PROTO_DESC_GRE,
        __PROTO_DESC_MAX
 };
@@ -397,6 +398,17 @@ enum vxlan_hdr_fields {
        VXLANHDR_FLAGS,
 };
 
+struct gnvhdr {
+       uint16_t flags;
+       uint16_t type;
+       uint32_t vni;
+};
+enum geneve_hdr_fields {
+       GNVHDR_INVALID,
+       GNVHDR_VNI,
+       GNVHDR_TYPE,
+};
+
 struct grehdr {
        uint16_t flags;
        uint16_t protocol;
@@ -410,6 +422,7 @@ enum gre_hdr_fields {
 };
 
 extern const struct proto_desc proto_vxlan;
+extern const struct proto_desc proto_geneve;
 extern const struct proto_desc proto_gre;
 
 extern const struct proto_desc proto_icmp;
index b29739951374eb40c49f8f2a6d763fb4e6da282b..10270f12e479cbf5bc7dc6069d178956a5c36a30 100644 (file)
@@ -444,6 +444,8 @@ int nft_lex(void *, void *, void *);
 
 %token GRE                     "gre"
 
+%token GENEVE                  "geneve"
+
 %token SCTP                    "sctp"
 %token CHUNK                   "chunk"
 %token DATA                    "data"
@@ -904,9 +906,12 @@ int nft_lex(void *, void *, void *);
 %type <val>                    tcpopt_field_maxseg     tcpopt_field_mptcp      tcpopt_field_sack        tcpopt_field_tsopt     tcpopt_field_window
 %type <tcp_kind_field>         tcp_hdr_option_kind_and_field
 
-%type <expr>                   inner_eth_expr inner_inet_expr inner_expr vxlan_hdr_expr gre_hdr_expr
-%destructor { expr_free($$); } inner_eth_expr inner_inet_expr inner_expr vxlan_hdr_expr gre_hdr_expr
-%type <val>                    vxlan_hdr_field gre_hdr_field
+%type <expr>                   inner_eth_expr inner_inet_expr inner_expr
+%destructor { expr_free($$); } inner_eth_expr inner_inet_expr inner_expr
+
+%type <expr>                   vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr
+%destructor { expr_free($$); } vxlan_hdr_expr geneve_hdr_expr gre_hdr_expr
+%type <val>                    vxlan_hdr_field geneve_hdr_field gre_hdr_field
 
 %type <stmt>                   optstrip_stmt
 %destructor { stmt_free($$); } optstrip_stmt
@@ -5347,6 +5352,7 @@ payload_expr              :       payload_raw_expr
                        |       sctp_hdr_expr
                        |       th_hdr_expr
                        |       vxlan_hdr_expr
+                       |       geneve_hdr_expr
                        |       gre_hdr_expr
                        ;
 
@@ -5644,6 +5650,26 @@ vxlan_hdr_field          :       VNI                     { $$ = VXLANHDR_VNI; }
                        |       FLAGS                   { $$ = VXLANHDR_FLAGS; }
                        ;
 
+geneve_hdr_expr                :       GENEVE  geneve_hdr_field
+                       {
+                               struct expr *expr;
+
+                               expr = payload_expr_alloc(&@$, &proto_geneve, $2);
+                               expr->payload.inner_desc = &proto_geneve;
+                               $$ = expr;
+                       }
+                       |       GENEVE  inner_expr
+                       {
+                               $$ = $2;
+                               $$->location = @$;
+                               $$->payload.inner_desc = &proto_geneve;
+                       }
+                       ;
+
+geneve_hdr_field       :       VNI                     { $$ = GNVHDR_VNI; }
+                       |       TYPE                    { $$ = GNVHDR_TYPE; }
+                       ;
+
 gre_hdr_expr           :       GRE     gre_hdr_field   close_scope_gre
                        {
                                $$ = payload_expr_alloc(&@$, &proto_gre, $2);
index 3bb4ae74a439940bddc187eb64b81e61a9bafe49..0986a38000008d4463e14eeba228604e7d01fdbc 100644 (file)
@@ -90,6 +90,7 @@ int proto_find_num(const struct proto_desc *base,
 
 static const struct proto_desc *inner_protocols[] = {
        &proto_vxlan,
+       &proto_geneve,
        &proto_gre,
 };
 
@@ -542,6 +543,7 @@ const struct proto_desc proto_udp = {
        },
        .protocols      = {
                PROTO_LINK(0,   &proto_vxlan),
+               PROTO_LINK(0,   &proto_geneve),
        },
 };
 
@@ -1215,6 +1217,32 @@ const struct proto_desc proto_vxlan = {
        },
 };
 
+/*
+ * GENEVE
+ */
+
+const struct proto_desc proto_geneve = {
+       .name           = "geneve",
+       .id             = PROTO_DESC_GENEVE,
+       .base           = PROTO_BASE_INNER_HDR,
+       .templates      = {
+               [GNVHDR_TYPE]   = HDR_TYPE("type", &ethertype_type, struct gnvhdr, type),
+               [GNVHDR_VNI]    = HDR_BITFIELD("vni", &integer_type, (4 * BITS_PER_BYTE), 24),
+       },
+       .protocols      = {
+               PROTO_LINK(__constant_htons(ETH_P_IP),          &proto_ip),
+               PROTO_LINK(__constant_htons(ETH_P_ARP),         &proto_arp),
+               PROTO_LINK(__constant_htons(ETH_P_IPV6),        &proto_ip6),
+               PROTO_LINK(__constant_htons(ETH_P_8021Q),       &proto_vlan),
+       },
+       .inner          = {
+               .hdrsize        = sizeof(struct gnvhdr),
+               .flags          = NFT_INNER_HDRSIZE | NFT_INNER_LL | NFT_INNER_NH | NFT_INNER_TH,
+               .type           = NFT_INNER_GENEVE,
+       },
+};
+
+
 /*
  * Dummy protocol for netdev tables.
  */
index 3d9888ab674700ef64c64d006eade2b3dce25070..1ac46d1a8a3e8c67bd36f70ec1efd81a19422c7f 100644 (file)
@@ -625,6 +625,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "vxlan"                        { return VXLAN; }
 "vni"                  { return VNI; }
 
+"geneve"               { return GENEVE; }
+
 "gre"                  { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRE; }
 
 "tcp"                  { scanner_push_start_cond(yyscanner, SCANSTATE_TCP); return TCP; }