All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH libnfnl] chain: add netdev family support
@ 2015-06-16 15:30 Pablo Neira Ayuso
  0 siblings, 0 replies; only message in thread
From: Pablo Neira Ayuso @ 2015-06-16 15:30 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

Add support for the new NFT_CHAIN_ATTR_DEV attribute that indicates that the
basechain is attached to a net_device.

This partially reworks 1dd9ba1ea23c ("table: add netdev family support").

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/libnftnl/chain.h            |    1 +
 include/libnftnl/table.h            |    1 -
 include/linux/netfilter/nf_tables.h |    4 +--
 src/chain.c                         |   47 +++++++++++++++++++++++++++++++++--
 src/table.c                         |   37 ++-------------------------
 tests/nft-chain-test.c              |    4 +++
 tests/nft-table-test.c              |    9 +++----
 7 files changed, 57 insertions(+), 46 deletions(-)

diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index c11cb5e..3968e6b 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -29,6 +29,7 @@ enum {
 	NFT_CHAIN_ATTR_PACKETS	= 8,
 	NFT_CHAIN_ATTR_HANDLE,
 	NFT_CHAIN_ATTR_TYPE,
+	NFT_CHAIN_ATTR_DEV,
 	__NFT_CHAIN_ATTR_MAX
 };
 #define NFT_CHAIN_ATTR_MAX (__NFT_CHAIN_ATTR_MAX - 1)
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index 16df5fa..fac79e7 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -22,7 +22,6 @@ enum {
 	NFT_TABLE_ATTR_FAMILY,
 	NFT_TABLE_ATTR_FLAGS,
 	NFT_TABLE_ATTR_USE,
-	NFT_TABLE_ATTR_DEV,
 	__NFT_TABLE_ATTR_MAX
 };
 #define NFT_TABLE_ATTR_MAX (__NFT_TABLE_ATTR_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 89a671e..a99e6a9 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -122,11 +122,13 @@ enum nft_list_attributes {
  *
  * @NFTA_HOOK_HOOKNUM: netfilter hook number (NLA_U32)
  * @NFTA_HOOK_PRIORITY: netfilter hook priority (NLA_U32)
+ * @NFTA_HOOK_DEV: netdevice name (NLA_STRING)
  */
 enum nft_hook_attributes {
 	NFTA_HOOK_UNSPEC,
 	NFTA_HOOK_HOOKNUM,
 	NFTA_HOOK_PRIORITY,
+	NFTA_HOOK_DEV,
 	__NFTA_HOOK_MAX
 };
 #define NFTA_HOOK_MAX		(__NFTA_HOOK_MAX - 1)
@@ -146,14 +148,12 @@ enum nft_table_flags {
  * @NFTA_TABLE_NAME: name of the table (NLA_STRING)
  * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
  * @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
- * @NFTA_TABLE_DEV: net device name (NLA_STRING)
  */
 enum nft_table_attributes {
 	NFTA_TABLE_UNSPEC,
 	NFTA_TABLE_NAME,
 	NFTA_TABLE_FLAGS,
 	NFTA_TABLE_USE,
-	NFTA_TABLE_DEV,
 	__NFTA_TABLE_MAX
 };
 #define NFTA_TABLE_MAX		(__NFTA_TABLE_MAX - 1)
diff --git a/src/chain.c b/src/chain.c
index 74e5925..ed9d9e4 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -35,6 +35,7 @@ struct nft_chain {
 	char		name[NFT_CHAIN_MAXNAMELEN];
 	const char	*type;
 	const char	*table;
+	const char	*dev;
 	uint32_t	family;
 	uint32_t	policy;
 	uint32_t	hooknum;
@@ -98,6 +99,8 @@ void nft_chain_free(struct nft_chain *c)
 		xfree(c->table);
 	if (c->type != NULL)
 		xfree(c->type);
+	if (c->dev != NULL)
+		xfree(c->dev);
 
 	xfree(c);
 }
@@ -138,6 +141,12 @@ void nft_chain_attr_unset(struct nft_chain *c, uint16_t attr)
 	case NFT_CHAIN_ATTR_HANDLE:
 	case NFT_CHAIN_ATTR_FAMILY:
 		break;
+	case NFT_CHAIN_ATTR_DEV:
+		if (c->dev) {
+			xfree(c->dev);
+			c->dev = NULL;
+		}
+		break;
 	default:
 		return;
 	}
@@ -204,6 +213,12 @@ void nft_chain_attr_set_data(struct nft_chain *c, uint16_t attr,
 
 		c->type = strdup(data);
 		break;
+	case NFT_CHAIN_ATTR_DEV:
+		if (c->dev)
+			xfree(c->dev);
+
+		c->dev = strdup(data);
+		break;
 	}
 	c->flags |= (1 << attr);
 }
@@ -283,6 +298,8 @@ const void *nft_chain_attr_get_data(struct nft_chain *c, uint16_t attr,
 	case NFT_CHAIN_ATTR_TYPE:
 		*data_len = sizeof(uint32_t);
 		return c->type;
+	case NFT_CHAIN_ATTR_DEV:
+		return c->dev;
 	}
 	return NULL;
 }
@@ -358,6 +375,8 @@ void nft_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_chain
 		nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
 		mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(c->hooknum));
 		mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
+		if (c->flags & (1 << NFT_CHAIN_ATTR_DEV))
+			mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev);
 		mnl_attr_nest_end(nlh, nest);
 	}
 	if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY))
@@ -467,6 +486,10 @@ static int nft_chain_parse_hook_cb(const struct nlattr *attr, void *data)
 		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
 			abi_breakage();
 		break;
+	case NFTA_HOOK_DEV:
+		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+			abi_breakage();
+		break;
 	}
 
 	tb[type] = attr;
@@ -488,6 +511,10 @@ static int nft_chain_parse_hook(struct nlattr *attr, struct nft_chain *c)
 		c->prio = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_PRIORITY]));
 		c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
 	}
+	if (tb[NFTA_HOOK_DEV]) {
+		c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
+		c->flags |= (1 << NFT_CHAIN_ATTR_DEV);
+	}
 
 	return 0;
 }
@@ -563,7 +590,7 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree,
 	uint64_t handle, bytes, packets;
 	int policy_num;
 	int32_t family, prio, hooknum, use;
-	const char *name, *table, *type, *hooknum_str, *policy;
+	const char *name, *table, *type, *hooknum_str, *policy, *dev;
 
 	root = nft_jansson_get_node(tree, "chain", err);
 	if (root == NULL)
@@ -626,6 +653,10 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree,
 			nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY,
 					       policy_num);
 		}
+
+		dev = nft_jansson_parse_str(root, "device", err);
+		if (dev != NULL)
+			nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_DEV, dev);
 	}
 
 	return 0;
@@ -660,7 +691,7 @@ static int nft_chain_json_parse(struct nft_chain *c, const void *json,
 int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c,
 			 struct nft_parse_err *err)
 {
-	const char *table, *name, *hooknum_str, *policy_str, *type;
+	const char *table, *name, *hooknum_str, *policy_str, *type, *dev;
 	int family, hooknum, policy;
 	uint64_t handle, bytes, packets, prio, use;
 
@@ -729,6 +760,11 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c,
 			nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY,
 					       policy);
 		}
+		dev = nft_mxml_str_parse(tree, "device", MXML_DESCEND_FIRST,
+					 NFT_XML_MAND, err);
+
+		if (table != NULL)
+			nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_DEV, dev);
 	}
 
 	return 0;
@@ -824,6 +860,8 @@ static int nft_chain_export(char *buf, size_t size, struct nft_chain *c,
 			nft_buf_s32(&b, type, c->prio, PRIO);
 		if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY))
 			nft_buf_str(&b, type, nft_verdict2str(c->policy), POLICY);
+		if (c->flags & (1 << NFT_CHAIN_ATTR_DEV))
+			nft_buf_str(&b, type, c->dev, DEVICE);
 	}
 
 	nft_buf_close(&b, type, CHAIN);
@@ -848,6 +886,11 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 			       c->prio, nft_verdict2str(c->policy),
 			       c->packets, c->bytes);
 		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		if (c->flags & (1 << NFT_CHAIN_ATTR_DEV)) {
+			ret = snprintf(buf+offset, len, " dev %s ", c->dev);
+			SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		}
 	}
 
 	return offset;
diff --git a/src/table.c b/src/table.c
index f748d6d..ab0a8ea 100644
--- a/src/table.c
+++ b/src/table.c
@@ -32,7 +32,6 @@ struct nft_table {
 	const char	*name;
 	uint32_t	family;
 	uint32_t	table_flags;
-	const char	*dev;
 	uint32_t	use;
 	uint32_t	flags;
 };
@@ -75,12 +74,6 @@ void nft_table_attr_unset(struct nft_table *t, uint16_t attr)
 		break;
 	case NFT_TABLE_ATTR_USE:
 		break;
-	case NFT_TABLE_ATTR_DEV:
-		if (t->dev) {
-			xfree(t->dev);
-			t->dev = NULL;
-		}
-		break;
 	}
 	t->flags &= ~(1 << attr);
 }
@@ -115,12 +108,6 @@ void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
 	case NFT_TABLE_ATTR_USE:
 		t->use = *((uint32_t *)data);
 		break;
-	case NFT_TABLE_ATTR_DEV:
-		if (t->dev)
-			xfree(t->dev);
-
-		t->dev = strdup(data);
-		break;
 	}
 	t->flags |= (1 << attr);
 }
@@ -168,8 +155,6 @@ const void *nft_table_attr_get_data(struct nft_table *t, uint16_t attr,
 	case NFT_TABLE_ATTR_USE:
 		*data_len = sizeof(uint32_t);
 		return &t->use;
-	case NFT_TABLE_ATTR_DEV:
-		return t->dev;
 	}
 	return NULL;
 }
@@ -208,8 +193,6 @@ void nft_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_table
 		mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, t->name);
 	if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS))
 		mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
-	if (t->flags & (1 << NFT_TABLE_ATTR_DEV))
-		mnl_attr_put_str(nlh, NFTA_TABLE_DEV, t->dev);
 }
 EXPORT_SYMBOL(nft_table_nlmsg_build_payload);
 
@@ -223,7 +206,6 @@ static int nft_table_parse_attr_cb(const struct nlattr *attr, void *data)
 
 	switch(type) {
 	case NFTA_TABLE_NAME:
-	case NFTA_TABLE_DEV:
 		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
 			abi_breakage();
 		break;
@@ -258,10 +240,6 @@ int nft_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_table *t)
 		t->use = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_USE]));
 		t->flags |= (1 << NFT_TABLE_ATTR_USE);
 	}
-	if (tb[NFTA_TABLE_DEV]) {
-		t->dev = strdup(mnl_attr_get_str(tb[NFTA_TABLE_DEV]));
-		t->flags |= (1 << NFT_TABLE_ATTR_DEV);
-	}
 
 	t->family = nfg->nfgen_family;
 	t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
@@ -274,7 +252,7 @@ EXPORT_SYMBOL(nft_table_nlmsg_parse);
 int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
 			 struct nft_parse_err *err)
 {
-	const char *name, *dev;
+	const char *name;
 	int family;
 	uint32_t flags, use;
 
@@ -292,11 +270,6 @@ int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
 			       &flags, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
 		nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
 
-	dev = nft_mxml_str_parse(tree, "device", MXML_DESCEND_FIRST,
-				 NFT_XML_MAND, err);
-	if (dev != NULL)
-		nft_table_attr_set_str(t, NFT_TABLE_ATTR_DEV, dev);
-
 	if (nft_mxml_num_parse(tree, "use", MXML_DESCEND, BASE_DEC,
 			       &use, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
 		nft_table_attr_set_u32(t, NFT_TABLE_ATTR_USE, use);
@@ -330,7 +303,7 @@ int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
 {
 	json_t *root;
 	uint32_t flags, use;
-	const char *str, *dev;
+	const char *str;
 	int family;
 
 	root = nft_jansson_get_node(tree, "table", err);
@@ -348,10 +321,6 @@ int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
 				  err) == 0)
 		nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
 
-	dev = nft_jansson_parse_str(root, "device", err);
-	if (dev != NULL)
-		nft_table_attr_set_str(t, NFT_TABLE_ATTR_DEV, dev);
-
 	if (nft_jansson_parse_val(root, "use", NFT_TYPE_U32, &use, err) == 0)
 		nft_table_attr_set_u32(t, NFT_TABLE_ATTR_USE, use);
 
@@ -435,8 +404,6 @@ static int nft_table_export(char *buf, size_t size, struct nft_table *t,
 		nft_buf_str(&b, type, nft_family2str(t->family), FAMILY);
 	if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS))
 		nft_buf_u32(&b, type, t->table_flags, FLAGS);
-	if (t->flags & (1 << NFT_TABLE_ATTR_DEV))
-		nft_buf_str(&b, type, t->dev, DEVICE);
 	if (t->flags & (1 << NFT_TABLE_ATTR_USE))
 		nft_buf_u32(&b, type, t->use, USE);
 
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index 1ff8334..ff8afed 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -59,6 +59,9 @@ static void cmp_nft_chain(struct nft_chain *a, struct nft_chain *b)
 	if (strcmp(nft_chain_attr_get_str(a, NFT_CHAIN_ATTR_TYPE),
 		   nft_chain_attr_get_str(b, NFT_CHAIN_ATTR_TYPE)) != 0)
 		print_err("Chain type mismatches");
+	if (strcmp(nft_chain_attr_get_str(a, NFT_CHAIN_ATTR_DEV),
+		   nft_chain_attr_get_str(b, NFT_CHAIN_ATTR_DEV)) != 0)
+		print_err("Chain device mismatches");
 }
 
 int main(int argc, char *argv[])
@@ -83,6 +86,7 @@ int main(int argc, char *argv[])
 	nft_chain_attr_set_u64(a, NFT_CHAIN_ATTR_BYTES, 0x1234567812345678);
 	nft_chain_attr_set_u64(a, NFT_CHAIN_ATTR_HANDLE, 0x1234567812345678);
 	nft_chain_attr_set_str(a, NFT_CHAIN_ATTR_TYPE, "Prueba");
+	nft_chain_attr_set_str(a, NFT_CHAIN_ATTR_DEV, "eth0");
 
 	/* cmd extracted from include/linux/netfilter/nf_tables.h */
 	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET,
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 4714131..2096ea5 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -35,27 +35,24 @@ static void cmp_nft_table(struct nft_table *a, struct nft_table *b)
 	if (nft_table_attr_get_u32(a, NFT_TABLE_ATTR_FAMILY) !=
 	    nft_table_attr_get_u32(b, NFT_TABLE_ATTR_FAMILY))
 		print_err("tabke family mismatches");
-	if (strcmp(nft_table_attr_get_str(a, NFT_TABLE_ATTR_DEV),
-		   nft_table_attr_get_str(b, NFT_TABLE_ATTR_DEV)) != 0)
-		print_err("table name mismatches");
 }
 
 int main(int argc, char *argv[])
 {
 	char buf[4096];
 	struct nlmsghdr *nlh;
-	struct nft_table *a;
-	struct nft_table *b;
 
+	struct nft_table *a = NULL;
+	struct nft_table *b = NULL;
 	a = nft_table_alloc();
 	b = nft_table_alloc();
+
 	if (a == NULL || b == NULL)
 		print_err("OOM");
 
 	nft_table_attr_set_str(a, NFT_TABLE_ATTR_NAME, "test");
 	nft_table_attr_set_u32(a, NFT_TABLE_ATTR_FAMILY, AF_INET);
 	nft_table_attr_set_u32(a, NFT_TABLE_ATTR_FLAGS, 0);
-	nft_table_attr_set_str(a, NFT_TABLE_ATTR_DEV, "test");
 
 	/* cmd extracted from include/linux/netfilter/nf_tables.h */
 	nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, AF_INET, 0,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-06-16 15:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-16 15:30 [PATCH libnfnl] chain: add netdev family support Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.