[nft] ct: support for NFT_CT_{SRC,DST}_{IP,IP6}

Message ID 20180309114335.7085-1-pablo@netfilter.org
State Under Review
Delegated to: Pablo Neira
Headers show
Series
  • [nft] ct: support for NFT_CT_{SRC,DST}_{IP,IP6}
Related show

Commit Message

Pablo Neira Ayuso March 9, 2018, 11:43 a.m.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/ct.h                        |  3 +--
 include/linux/netfilter/nf_tables.h | 12 ++++++++++--
 src/ct.c                            | 21 +++++++++++++++++++--
 src/evaluate.c                      |  2 +-
 src/netlink_delinearize.c           |  2 +-
 src/parser_bison.y                  | 14 ++++++++------
 6 files changed, 40 insertions(+), 14 deletions(-)

Patch

diff --git a/include/ct.h b/include/ct.h
index 2c3392d36c94..27bbdc4ca43a 100644
--- a/include/ct.h
+++ b/include/ct.h
@@ -24,8 +24,7 @@  struct ct_template {
 }
 
 extern struct expr *ct_expr_alloc(const struct location *loc,
-				  enum nft_ct_keys key, int8_t direction,
-				  uint8_t nfproto);
+				  enum nft_ct_keys key, int8_t direction);
 extern void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr);
 
 extern struct stmt *notrack_stmt_alloc(const struct location *loc);
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 517a39a00e3d..9aa29e43f36d 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -909,8 +909,8 @@  enum nft_rt_attributes {
  * @NFT_CT_EXPIRATION: relative conntrack expiration time in ms
  * @NFT_CT_HELPER: connection tracking helper assigned to conntrack
  * @NFT_CT_L3PROTOCOL: conntrack layer 3 protocol
- * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address)
- * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address)
+ * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address, deprecated)
+ * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address, deprecated)
  * @NFT_CT_PROTOCOL: conntrack layer 4 protocol
  * @NFT_CT_PROTO_SRC: conntrack layer 4 protocol source
  * @NFT_CT_PROTO_DST: conntrack layer 4 protocol destination
@@ -920,6 +920,10 @@  enum nft_rt_attributes {
  * @NFT_CT_AVGPKT: conntrack average bytes per packet
  * @NFT_CT_ZONE: conntrack zone
  * @NFT_CT_EVENTMASK: ctnetlink events to be generated for this conntrack
+ * @NFT_CT_SRC_IP: conntrack layer 3 protocol source (IPv4 address)
+ * @NFT_CT_DST_IP: conntrack layer 3 protocol destination (IPv4 address)
+ * @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address)
+ * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
  */
 enum nft_ct_keys {
 	NFT_CT_STATE,
@@ -941,6 +945,10 @@  enum nft_ct_keys {
 	NFT_CT_AVGPKT,
 	NFT_CT_ZONE,
 	NFT_CT_EVENTMASK,
+	NFT_CT_SRC_IP,
+	NFT_CT_DST_IP,
+	NFT_CT_SRC_IP6,
+	NFT_CT_DST_IP6,
 };
 
 /**
diff --git a/src/ct.c b/src/ct.c
index edfe5586ebe6..96d0a931d4af 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -269,6 +269,14 @@  static const struct ct_template ct_templates[] = {
 					      BYTEORDER_HOST_ENDIAN, 16),
 	[NFT_CT_EVENTMASK]	= CT_TEMPLATE("event", &ct_event_type,
 					      BYTEORDER_HOST_ENDIAN, 32),
+	[NFT_CT_SRC_IP]		= CT_TEMPLATE("ip saddr", &ipaddr_type,
+					      BYTEORDER_BIG_ENDIAN, 0),
+	[NFT_CT_DST_IP]		= CT_TEMPLATE("ip daddr", &ipaddr_type,
+					      BYTEORDER_BIG_ENDIAN, 0),
+	[NFT_CT_SRC_IP6]	= CT_TEMPLATE("ip6 saddr", &ip6addr_type,
+					      BYTEORDER_BIG_ENDIAN, 0),
+	[NFT_CT_DST_IP6]	= CT_TEMPLATE("ip6 daddr", &ip6addr_type,
+					      BYTEORDER_BIG_ENDIAN, 0),
 };
 
 static void ct_print(enum nft_ct_keys key, int8_t dir, uint8_t nfproto,
@@ -349,7 +357,7 @@  static const struct expr_ops ct_expr_ops = {
 };
 
 struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key,
-			   int8_t direction, uint8_t nfproto)
+			   int8_t direction)
 {
 	const struct ct_template *tmpl = &ct_templates[key];
 	struct expr *expr;
@@ -358,7 +366,6 @@  struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key,
 			  tmpl->byteorder, tmpl->len);
 	expr->ct.key = key;
 	expr->ct.direction = direction;
-	expr->ct.nfproto = nfproto;
 
 	switch (key) {
 	case NFT_CT_SRC:
@@ -409,6 +416,16 @@  void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr)
 			break;
 		expr->dtype = &inet_service_type;
 		break;
+	case NFT_CT_SRC_IP:
+	case NFT_CT_DST_IP:
+		expr->dtype = &ipaddr_type;
+		expr->len = expr->dtype->size;
+		break;
+	case NFT_CT_SRC_IP6:
+	case NFT_CT_DST_IP6:
+		expr->dtype = &ip6addr_type;
+		expr->len = expr->dtype->size;
+		break;
 	default:
 		break;
 	}
diff --git a/src/evaluate.c b/src/evaluate.c
index a2c1c7283d6a..86337c6e12f2 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -734,7 +734,7 @@  static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct)
 		return 0;
 	}
 
-	left = ct_expr_alloc(&ct->location, NFT_CT_L3PROTOCOL, ct->ct.direction, ct->ct.nfproto);
+	left = ct_expr_alloc(&ct->location, NFT_CT_L3PROTOCOL, ct->ct.direction);
 
 	right = constant_expr_alloc(&ct->location, left->dtype,
 				    left->dtype->byteorder, left->len,
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index d65aacf8b616..2171d2067b22 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -735,7 +735,7 @@  static void netlink_parse_ct_expr(struct netlink_parse_ctx *ctx,
 		dir = nftnl_expr_get_u8(nle, NFTNL_EXPR_CT_DIR);
 
 	key  = nftnl_expr_get_u32(nle, NFTNL_EXPR_CT_KEY);
-	expr = ct_expr_alloc(loc, key, dir, NFPROTO_UNSPEC);
+	expr = ct_expr_alloc(loc, key, dir);
 
 	dreg = netlink_parse_register(nle, NFTNL_EXPR_CT_DREG);
 	netlink_set_register(ctx, dreg, expr);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 2ccaf9abd751..9c32dbb7ff07 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -3548,15 +3548,15 @@  rt_key			:	CLASSID		{ $$ = NFT_RT_CLASSID; }
 
 ct_expr			: 	CT	ct_key
 			{
-				$$ = ct_expr_alloc(&@$, $2, -1, NFPROTO_UNSPEC);
+				$$ = ct_expr_alloc(&@$, $2, -1);
 			}
 			|	CT	ct_dir	ct_key_dir
 			{
-				$$ = ct_expr_alloc(&@$, $3, $2, NFPROTO_UNSPEC);
+				$$ = ct_expr_alloc(&@$, $3, $2);
 			}
-			|	CT	ct_dir	nf_key_proto ct_key_proto_field
+			|	CT	ct_dir	ct_key_proto_field
 			{
-				$$ = ct_expr_alloc(&@$, $4, $2, $3);
+				$$ = ct_expr_alloc(&@$, $3, $2);
 			}
 			;
 
@@ -3590,8 +3590,10 @@  ct_key_dir		:	SADDR		{ $$ = NFT_CT_SRC; }
 			|	ct_key_dir_optional
 			;
 
-ct_key_proto_field	:	SADDR		{ $$ = NFT_CT_SRC; }
-			|	DADDR		{ $$ = NFT_CT_DST; }
+ct_key_proto_field	:	IP	SADDR	{ $$ = NFT_CT_SRC_IP; }
+			|	IP	DADDR	{ $$ = NFT_CT_DST_IP; }
+			|	IP6	SADDR	{ $$ = NFT_CT_SRC_IP6; }
+			|	IP6	DADDR	{ $$ = NFT_CT_DST_IP6; }
 			;
 
 ct_key_dir_optional	:	BYTES		{ $$ = NFT_CT_BYTES; }