Add ip-saddr, ip-daddr, ether-saddr, ether-daddr for arp, eg. # nft add table arp x # nft add chain arp x y { type filter hook input priority 0\; } # nft add rule arp x y arp ip-saddr 192.168.2.1 counter Testing this: # ip neigh flush dev eth0 # ping 8.8.8.8 # nft list ruleset table arp x { chain y { type filter hook input priority filter; policy accept; arp ip-saddr 192.168.2.1 counter packets 1 bytes 46 } } Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- Documentation is still missing, and we should generate dependencies to restrict htype and ptype. include/headers.h | 12 ++++++++++++ include/proto.h | 4 ++++ src/parser_bison.y | 8 ++++++++ src/proto.c | 22 ++++++++++++++-------- src/scanner.l | 4 ++++ 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/include/headers.h b/include/headers.h index 3d564debf8b0..759f93bf8c7a 100644 --- a/include/headers.h +++ b/include/headers.h @@ -78,6 +78,18 @@ struct sctphdr { uint32_t checksum; }; +struct arp_hdr { + uint16_t htype; + uint16_t ptype; + uint8_t hlen; + uint8_t plen; + uint16_t oper; + uint8_t sha[6]; + uint32_t spa; + uint8_t tha[6]; + uint32_t tpa; +} __attribute__((__packed__)); + struct ipv6hdr { uint8_t version:4, priority:4; diff --git a/include/proto.h b/include/proto.h index 9a9f9255f047..b097e8fcbc2b 100644 --- a/include/proto.h +++ b/include/proto.h @@ -182,6 +182,10 @@ enum arp_hdr_fields { ARPHDR_HLN, ARPHDR_PLN, ARPHDR_OP, + ARPHDR_IP_SADDR, + ARPHDR_IP_DADDR, + ARPHDR_ETHER_SADDR, + ARPHDR_ETHER_DADDR, }; enum ip_hdr_fields { diff --git a/src/parser_bison.y b/src/parser_bison.y index 34202b0415ec..e94282a43615 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -296,6 +296,10 @@ int nft_lex(void *, void *, void *); %token HLEN "hlen" %token PLEN "plen" %token OPERATION "operation" +%token ETHER_SADDR "ether-saddr" +%token ETHER_DADDR "ether-daddr" +%token IP_SADDR "ip-saddr" +%token IP_DADDR "ip-daddr" %token IP "ip" %token HDRVERSION "version" @@ -4204,6 +4208,10 @@ arp_hdr_field : HTYPE { $$ = ARPHDR_HRD; } | HLEN { $$ = ARPHDR_HLN; } | PLEN { $$ = ARPHDR_PLN; } | OPERATION { $$ = ARPHDR_OP; } + | ETHER_SADDR { $$ = ARPHDR_ETHER_SADDR; } + | ETHER_DADDR { $$ = ARPHDR_ETHER_DADDR; } + | IP_SADDR { $$ = ARPHDR_IP_SADDR; } + | IP_DADDR { $$ = ARPHDR_IP_DADDR; } ; ip_hdr_expr : IP ip_hdr_field diff --git a/src/proto.c b/src/proto.c index d178bf39ea90..d52f11ce6f30 100644 --- a/src/proto.c +++ b/src/proto.c @@ -822,23 +822,29 @@ const struct datatype arpop_type = { }; #define ARPHDR_TYPE(__name, __type, __member) \ - HDR_TYPE(__name, __type, struct arphdr, __member) + HDR_TYPE(__name, __type, struct arp_hdr, __member) #define ARPHDR_FIELD(__name, __member) \ - HDR_FIELD(__name, struct arphdr, __member) + HDR_FIELD(__name, struct arp_hdr, __member) const struct proto_desc proto_arp = { .name = "arp", .base = PROTO_BASE_NETWORK_HDR, .templates = { - [ARPHDR_HRD] = ARPHDR_FIELD("htype", ar_hrd), - [ARPHDR_PRO] = ARPHDR_TYPE("ptype", ðertype_type, ar_pro), - [ARPHDR_HLN] = ARPHDR_FIELD("hlen", ar_hln), - [ARPHDR_PLN] = ARPHDR_FIELD("plen", ar_pln), - [ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, ar_op), + [ARPHDR_HRD] = ARPHDR_FIELD("htype", htype), + [ARPHDR_PRO] = ARPHDR_TYPE("ptype", ðertype_type, ptype), + [ARPHDR_HLN] = ARPHDR_FIELD("hlen", hlen), + [ARPHDR_PLN] = ARPHDR_FIELD("plen", plen), + [ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, oper), + [ARPHDR_ETHER_SADDR] = ARPHDR_TYPE("ether-saddr", ðeraddr_type, sha), + [ARPHDR_ETHER_DADDR] = ARPHDR_TYPE("ether-daddr", ðeraddr_type, tha), + [ARPHDR_IP_SADDR] = ARPHDR_TYPE("ip-saddr", &ipaddr_type, spa), + [ARPHDR_IP_DADDR] = ARPHDR_TYPE("ip-daddr", &ipaddr_type, tpa), }, .format = { .filter = (1 << ARPHDR_HRD) | (1 << ARPHDR_PRO) | - (1 << ARPHDR_HLN) | (1 << ARPHDR_PLN), + (1 << ARPHDR_HLN) | (1 << ARPHDR_PLN) | + (1 << ARPHDR_ETHER_SADDR) | (1 << ARPHDR_ETHER_DADDR) | + (1 << ARPHDR_IP_SADDR) | (1 << ARPHDR_IP_DADDR), }, }; diff --git a/src/scanner.l b/src/scanner.l index f96944e976b3..5221086e38e5 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -389,6 +389,10 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "hlen" { return HLEN; } "plen" { return PLEN; } "operation" { return OPERATION; } +"ip-saddr" { return IP_SADDR; } +"ip-daddr" { return IP_DADDR; } +"ether-saddr" { return ETHER_SADDR; } +"ether-daddr" { return ETHER_DADDR; } "ip" { return IP; } "version" { return HDRVERSION; } -- 2.11.0