summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-05-25 12:51:54 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-05-29 00:25:42 +0200
commit1dd9ba1ea23c46d2c9ea1685b458afb9af459e58 (patch)
tree49e9a89063b1ecddb047e495fcbafb74b8337cd1
parent1c9b43818b9c7bd48b36626d04c9cea94c52fd87 (diff)
table: add netdev family support
This adds support for the new 'netdev' family tables. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/buffer.h1
-rw-r--r--include/libnftnl/table.h1
-rw-r--r--include/linux/netfilter.h8
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--src/chain.c6
-rw-r--r--src/table.c37
-rw-r--r--tests/nft-table-test.c9
7 files changed, 59 insertions, 5 deletions
diff --git a/include/buffer.h b/include/buffer.h
index 52942ed..38b6136 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -41,6 +41,7 @@ int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg,
#define CHAIN "chain"
#define CODE "code"
#define DATA "data"
+#define DEVICE "device"
#define DIR "dir"
#define DREG "dreg"
#define EXTHDR_TYPE "exthdr_type"
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index fac79e7..16df5fa 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -22,6 +22,7 @@ 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.h b/include/linux/netfilter.h
index be0bc18..18075f9 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -32,6 +32,7 @@
#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
/* only for userspace compatibility */
+#ifndef __KERNEL__
/* Generic cache responses from hook functions.
<= 0x2000 is used for protocol-flags. */
#define NFC_UNKNOWN 0x4000
@@ -39,6 +40,7 @@
/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
#define NF_VERDICT_BITS 16
+#endif
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
@@ -49,11 +51,17 @@ enum nf_inet_hooks {
NF_INET_NUMHOOKS
};
+enum nf_dev_hooks {
+ NF_NETDEV_INGRESS,
+ NF_NETDEV_NUMHOOKS
+};
+
enum {
NFPROTO_UNSPEC = 0,
NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
+ NFPROTO_NETDEV = 5,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 5fa1cd0..89a671e 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -146,12 +146,14 @@ 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 84851e0..74e5925 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -76,6 +76,12 @@ static const char *nft_hooknum2str(int family, int hooknum)
return "forward";
}
break;
+ case NFPROTO_NETDEV:
+ switch (hooknum) {
+ case NF_NETDEV_INGRESS:
+ return "ingress";
+ }
+ break;
}
return "unknown";
}
diff --git a/src/table.c b/src/table.c
index ab0a8ea..f748d6d 100644
--- a/src/table.c
+++ b/src/table.c
@@ -32,6 +32,7 @@ struct nft_table {
const char *name;
uint32_t family;
uint32_t table_flags;
+ const char *dev;
uint32_t use;
uint32_t flags;
};
@@ -74,6 +75,12 @@ 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);
}
@@ -108,6 +115,12 @@ 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);
}
@@ -155,6 +168,8 @@ 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;
}
@@ -193,6 +208,8 @@ 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);
@@ -206,6 +223,7 @@ 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;
@@ -240,6 +258,10 @@ 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);
@@ -252,7 +274,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;
+ const char *name, *dev;
int family;
uint32_t flags, use;
@@ -270,6 +292,11 @@ 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);
@@ -303,7 +330,7 @@ int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
{
json_t *root;
uint32_t flags, use;
- const char *str;
+ const char *str, *dev;
int family;
root = nft_jansson_get_node(tree, "table", err);
@@ -321,6 +348,10 @@ 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);
@@ -404,6 +435,8 @@ 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-table-test.c b/tests/nft-table-test.c
index 2096ea5..4714131 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -35,24 +35,27 @@ 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,