Re: [PATCH RFC] src: support for arp ether and IP source and destination fields

2018-12-07 Thread Pablo Neira Ayuso
On Fri, Dec 07, 2018 at 02:05:15PM +0100, Florian Westphal wrote:
> Pablo Neira Ayuso  wrote:
> > 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
> 
> 'arp {ip,ether} {s,d}addr' would create ambiguities?

That's my concern moving forward with the grammar, but I can double
check more carefully. I just quickly jumped on this when looking at
one of the bugzilla issues.

> If so, this '-' notation seems ok to me.

Thanks.


Re: [PATCH RFC] src: support for arp ether and IP source and destination fields

2018-12-07 Thread Florian Westphal
Pablo Neira Ayuso  wrote:
> 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

'arp {ip,ether} {s,d}addr' would create ambiguities?

If so, this '-' notation seems ok to me.



[PATCH RFC] src: support for arp ether and IP source and destination fields

2018-12-07 Thread Pablo Neira Ayuso
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 
---
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_tchecksum;
 };
 
+struct arp_hdr {
+   uint16_thtype;
+   uint16_tptype;
+   uint8_t hlen;
+   uint8_t plen;
+   uint16_toper;
+   uint8_t sha[6];
+   uint32_tspa;
+   uint8_t tha[6];
+   uint32_ttpa;
+} __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", _type, 
ar_pro),
-   [ARPHDR_HLN]= ARPHDR_FIELD("hlen", ar_hln),
-   [ARPHDR_PLN]= ARPHDR_FIELD("plen", ar_pln),
-   [ARPHDR_OP] = ARPHDR_TYPE("operation", _type, 
ar_op),
+   [ARPHDR_HRD]= ARPHDR_FIELD("htype", htype),
+   [ARPHDR_PRO]= ARPHDR_TYPE("ptype", _type, 
ptype),
+   [ARPHDR_HLN]= ARPHDR_FIELD("hlen", hlen),
+   [ARPHDR_PLN]= ARPHDR_FIELD("plen", plen),
+   [ARPHDR_OP] = ARPHDR_TYPE("operation", _type, 
oper),
+   [ARPHDR_ETHER_SADDR]= ARPHDR_TYPE("ether-saddr", 
_type, sha),
+   [ARPHDR_ETHER_DADDR]= ARPHDR_TYPE("ether-daddr", 
_type, tha),
+   [ARPHDR_IP_SADDR]   = ARPHDR_TYPE("ip-saddr", _type, 
spa),
+   [ARPHDR_IP_DADDR]   = ARPHDR_TYPE("ip-daddr", _type, 
tpa),
},
.format = {
.filter = (1 << ARPHDR_HRD) | (1 << ARPHDR_PRO) |
- (1 << ARPHDR_HLN) | (1 <<