History

netfilter: nf_tables: allow to bind table to net_device

This patch adds the internal NFT_AF_NEEDS_DEV flag to indicate that you must attach this table to a net_device. This change is required by the follow up patch that introduces the new netdev table.

Pablo Neira Ayuso committed 11 years ago

Commit ebddf1a1 parent 529985d3 files · +51 −5Browse files

Unified · Split

3 files
  1. include/net/netfilter/nf_tables.h +8 −0
  2. include/uapi/linux/netfilter/nf_tables.h +2 −0
  3. net/netfilter/nf_tables_api.c +41 −5
include/net/netfilter/nf_tables.h+8−0
@@ -819,6 +819,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, · 818 unmodified lines
819819 * @use: number of chain references to this table
820820 * @flags: table flag (see enum nft_table_flags)
821821 * @name: name of the table
822+ * @dev: this table is bound to this device (if any)
822823 */
823824 struct nft_table {
824825 struct list_head list;
@@ -828,6 +829,11 @@ struct nft_table { · 3 unmodified lines
828829 u32 use;
829830 u16 flags;
830831 char name[NFT_TABLE_MAXNAMELEN];
832+ struct net_device *dev;
833+};
834+
835+enum nft_af_flags {
836+ NFT_AF_NEEDS_DEV = (1 << 0),
831837 };
832838
833839 /**
@@ -838,6 +844,7 @@ struct nft_table { · 4 unmodified lines
838844 * @nhooks: number of hooks in this family
839845 * @owner: module owner
840846 * @tables: used internally
847+ * @flags: family flags
841848 * @nops: number of hook ops in this family
842849 * @hook_ops_init: initialization function for chain hook ops
843850 * @hooks: hookfn overrides for packet validation
@@ -848,6 +855,7 @@ struct nft_af_info { · 4 unmodified lines
848855 unsigned int nhooks;
849856 struct module *owner;
850857 struct list_head tables;
858+ u32 flags;
851859 unsigned int nops;
852860 void (*hook_ops_init)(struct nf_hook_ops *,
853861 unsigned int);
include/uapi/linux/netfilter/nf_tables.h+2−0
@@ -146,12 +146,14 @@ enum nft_table_flags { · 145 unmodified lines
146146 * @NFTA_TABLE_NAME: name of the table (NLA_STRING)
147147 * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
148148 * @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
149+ * @NFTA_TABLE_DEV: net device name (NLA_STRING)
149150 */
150151 enum nft_table_attributes {
151152 NFTA_TABLE_UNSPEC,
152153 NFTA_TABLE_NAME,
153154 NFTA_TABLE_FLAGS,
154155 NFTA_TABLE_USE,
156+ NFTA_TABLE_DEV,
155157 __NFTA_TABLE_MAX
156158 };
157159 #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
net/netfilter/nf_tables_api.c+41−5
@@ -399,6 +399,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { · 398 unmodified lines
399399 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
400400 .len = NFT_TABLE_MAXNAMELEN - 1 },
401401 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
402+ [NFTA_TABLE_DEV] = { .type = NLA_STRING,
403+ .len = IFNAMSIZ - 1 },
402404 };
403405
404406 static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
@@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, · 18 unmodified lines
423425 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
424426 goto nla_put_failure;
425427
428+ if (table->dev &&
429+ nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name))
430+ goto nla_put_failure;
431+
426432 nlmsg_end(skb, nlh);
427433 return 0;
428434
@@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx) · 179 unmodified lines
608614 if (flags == ctx->table->flags)
609615 return 0;
610616
617+ if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) &&
618+ ctx->nla[NFTA_TABLE_DEV] &&
619+ nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name))
620+ return -EOPNOTSUPP;
621+
611622 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
612623 sizeof(struct nft_trans_table));
613624 if (trans == NULL)
@@ -645,6 +656,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, · 31 unmodified lines
645656 struct nft_table *table;
646657 struct net *net = sock_net(skb->sk);
647658 int family = nfmsg->nfgen_family;
659+ struct net_device *dev = NULL;
648660 u32 flags = 0;
649661 struct nft_ctx ctx;
650662 int err;
@@ -679,30 +691,50 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, · 28 unmodified lines
679691 return -EINVAL;
680692 }
681693
694+ if (afi->flags & NFT_AF_NEEDS_DEV) {
695+ char ifname[IFNAMSIZ];
696+
697+ if (!nla[NFTA_TABLE_DEV])
698+ return -EOPNOTSUPP;
699+
700+ nla_strlcpy(ifname, nla[NFTA_TABLE_DEV], IFNAMSIZ);
701+ dev = dev_get_by_name(net, ifname);
702+ if (!dev)
703+ return -ENOENT;
704+ } else if (nla[NFTA_TABLE_DEV]) {
705+ return -EOPNOTSUPP;
706+ }
707+
708+ err = -EAFNOSUPPORT;
682709 if (!try_module_get(afi->owner))
683− return -EAFNOSUPPORT;
710+ goto err1;
684711
685712 err = -ENOMEM;
686713 table = kzalloc(sizeof(*table), GFP_KERNEL);
687714 if (table == NULL)
688− goto err1;
715+ goto err2;
689716
690717 nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN);
691718 INIT_LIST_HEAD(&table->chains);
692719 INIT_LIST_HEAD(&table->sets);
693720 table->flags = flags;
721+ table->dev = dev;
694722
695723 nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
696724 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
697725 if (err < 0)
698− goto err2;
726+ goto err3;
699727
700728 list_add_tail_rcu(&table->list, &afi->tables);
701729 return 0;
702−err2:
730+err3:
703731 kfree(table);
704−err1:
732+err2:
705733 module_put(afi->owner);
734+err1:
735+ if (dev != NULL)
736+ dev_put(dev);
737+
706738 return err;
707739 }
708740
@@ -806,6 +838,9 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx) · 97 unmodified lines
806838 {
807839 BUG_ON(ctx->table->use > 0);
808840
841+ if (ctx->table->dev)
842+ dev_put(ctx->table->dev);
843+
809844 kfree(ctx->table);
810845 module_put(ctx->afi->owner);
811846 }
@@ -1361,6 +1396,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, · 549 unmodified lines
13611396 ops->priority = priority;
13621397 ops->priv = chain;
13631398 ops->hook = afi->hooks[ops->hooknum];
1399+ ops->dev = table->dev;
13641400 if (hookfn)
13651401 ops->hook = hookfn;
13661402 if (afi->hook_ops_init)