summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/payload-expression.txt9
-rw-r--r--include/proto.h7
-rw-r--r--src/parser_bison.y16
-rw-r--r--src/payload.c23
-rw-r--r--src/proto.c12
-rw-r--r--tests/py/any/rawpayload.t2
-rwxr-xr-xtests/shell/testcases/sets/0037_set_with_inet_service_06
-rw-r--r--tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft16
8 files changed, 90 insertions, 1 deletions
diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
index b98a6077..dba42fd5 100644
--- a/doc/payload-expression.txt
+++ b/doc/payload-expression.txt
@@ -498,6 +498,15 @@ Transport Header, for example TCP
----------------------------------------------
inet filter input meta l4proto {tcp, udp} @th,16,16 { 53, 80 }
-----------------------------------------------------------------
+The above can also be written as
+-----------------------------------------------------------------
+inet filter input meta l4proto {tcp, udp} th dport { 53, 80 }
+-----------------------------------------------------------------
+it is more convenient, but like the raw expression notation no
+dependencies are created or checked. It is the users responsibility
+to restrict matching to those header types that have a notion of ports.
+Otherwise, rules using raw expressions will errnously match unrelated
+packets, e.g. mis-interpreting ESP packets SPI field as a port.
.Rewrite arp packet target hardware address if target protocol address matches a given address
----------------------------------------------------------------------------------------------
diff --git a/include/proto.h b/include/proto.h
index 92b25edb..fab48c1b 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -310,6 +310,12 @@ enum sctp_hdr_fields {
SCTPHDR_CHECKSUM,
};
+enum th_hdr_fields {
+ THDR_INVALID,
+ THDR_SPORT,
+ THDR_DPORT,
+};
+
extern const struct proto_desc proto_icmp;
extern const struct proto_desc proto_igmp;
extern const struct proto_desc proto_ah;
@@ -320,6 +326,7 @@ extern const struct proto_desc proto_udplite;
extern const struct proto_desc proto_tcp;
extern const struct proto_desc proto_dccp;
extern const struct proto_desc proto_sctp;
+extern const struct proto_desc proto_th;
extern const struct proto_desc proto_icmp6;
extern const struct proto_desc proto_ip;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index a4905f2a..0a387f61 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -719,6 +719,9 @@ int nft_lex(void *, void *, void *);
%type <expr> dccp_hdr_expr sctp_hdr_expr
%destructor { expr_free($$); } dccp_hdr_expr sctp_hdr_expr
%type <val> dccp_hdr_field sctp_hdr_field
+%type <expr> th_hdr_expr
+%destructor { expr_free($$); } th_hdr_expr
+%type <val> th_hdr_field
%type <expr> exthdr_expr
%destructor { expr_free($$); } exthdr_expr
@@ -4198,6 +4201,7 @@ payload_expr : payload_raw_expr
| tcp_hdr_expr
| dccp_hdr_expr
| sctp_hdr_expr
+ | th_hdr_expr
;
payload_raw_expr : AT payload_base_spec COMMA NUM COMMA NUM
@@ -4487,6 +4491,18 @@ sctp_hdr_field : SPORT { $$ = SCTPHDR_SPORT; }
| CHECKSUM { $$ = SCTPHDR_CHECKSUM; }
;
+th_hdr_expr : TRANSPORT_HDR th_hdr_field
+ {
+ $$ = payload_expr_alloc(&@$, &proto_th, $2);
+ if ($$)
+ $$->payload.is_raw = true;
+ }
+ ;
+
+th_hdr_field : SPORT { $$ = THDR_SPORT; }
+ | DPORT { $$ = THDR_DPORT; }
+ ;
+
exthdr_expr : hbh_hdr_expr
| rt_hdr_expr
| rt0_hdr_expr
diff --git a/src/payload.c b/src/payload.c
index 3bf1ecc7..abd5339c 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -172,10 +172,33 @@ struct expr *payload_expr_alloc(const struct location *loc,
void payload_init_raw(struct expr *expr, enum proto_bases base,
unsigned int offset, unsigned int len)
{
+ enum th_hdr_fields thf;
+
expr->payload.base = base;
expr->payload.offset = offset;
expr->len = len;
expr->dtype = &integer_type;
+
+ if (base != PROTO_BASE_TRANSPORT_HDR)
+ return;
+ if (len != 16)
+ return;
+
+ switch (offset) {
+ case 0:
+ thf = THDR_SPORT;
+ /* fall through */
+ case 16:
+ if (offset == 16)
+ thf = THDR_DPORT;
+ expr->payload.tmpl = &proto_th.templates[thf];
+ expr->payload.desc = &proto_th;
+ expr->dtype = &inet_service_type;
+ expr->payload.desc = &proto_th;
+ break;
+ default:
+ break;
+ }
}
unsigned int payload_hdr_field(const struct expr *expr)
diff --git a/src/proto.c b/src/proto.c
index 67e86f20..40ce590e 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -562,6 +562,18 @@ const struct proto_desc proto_sctp = {
};
/*
+ * Dummy Transpor Header (common udp/tcp/dccp/sctp fields)
+ */
+const struct proto_desc proto_th = {
+ .name = "th",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [THDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
+ [THDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
+ },
+};
+
+/*
* IPv4
*/
diff --git a/tests/py/any/rawpayload.t b/tests/py/any/rawpayload.t
index 9a3402f1..c3382a96 100644
--- a/tests/py/any/rawpayload.t
+++ b/tests/py/any/rawpayload.t
@@ -4,7 +4,7 @@
*inet;test-inet;input
*netdev;test-netdev;ingress
-meta l4proto { tcp, udp, sctp} @th,16,16 { 22, 23, 80 };ok;meta l4proto { 6, 17, 132} @th,16,16 { 22, 23, 80}
+meta l4proto { tcp, udp, sctp} @th,16,16 { 22, 23, 80 };ok;meta l4proto { 6, 17, 132} th dport { 22, 23, 80}
meta l4proto tcp @th,16,16 { 22, 23, 80};ok;tcp dport { 22, 23, 80}
@nh,8,8 255;ok
@nh,8,16 0;ok
diff --git a/tests/shell/testcases/sets/0037_set_with_inet_service_0 b/tests/shell/testcases/sets/0037_set_with_inet_service_0
new file mode 100755
index 00000000..07820b7c
--- /dev/null
+++ b/tests/shell/testcases/sets/0037_set_with_inet_service_0
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile"
diff --git a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
new file mode 100644
index 00000000..0e85f7c2
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
@@ -0,0 +1,16 @@
+table inet filter {
+ set myset {
+ type ipv4_addr . inet_proto . inet_service
+ elements = { 192.168.0.12 . tcp . 53,
+ 192.168.0.12 . tcp . 80,
+ 192.168.0.12 . udp . 53,
+ 192.168.0.13 . tcp . 80,
+ 192.168.0.113 . tcp . 22 }
+ }
+
+ chain forward {
+ type filter hook forward priority filter; policy drop;
+ ct state established,related accept
+ ct state new ip daddr . ip protocol . th dport @myset accept
+ }
+}