Netfilter updates for next-net (part 2)
Subsystems (6)
Pablo Neira Ayuso
maintainercover Netfilter updates for next-net (part 2)
Hi David,
The following patchset contains Netfilter updates for net-next. This patchset includes updates for nf_tables, removal of CONFIG_NETFILTER_DEBUG and a new mode for xt_hashlimit. More specifically, they:
1) Add new rate match mode for hashlimit, this introduces a new revision for this match. The idea is to stop matching packets until ratelimit criteria stands true. Patch from Vishwanath Pai.
2) Add ->select_ops indirection to nf_tables named objects, so we can choose between different flavours of the same object type, patch from Pablo M. Bermudo.
3) Shorter function names in nft_limit, basically:
s/nft_limit_pkt_bytes/nft_limit_bytes, also from Pablo M. Bermudo.
4) Add new stateful limit named object type, this allows us to create limit policies that you can identify via name, also from Pablo.
5) Remove unused hooknum parameter in conntrack ->packet indirection. From Florian Westphal.
6) Patches to remove CONFIG_NETFILTER_DEBUG and macros such as IP_NF_ASSERT and IP_NF_ASSERT. From Varsha Rao.
7) Add nf_tables_updchain() helper function and use it from nf_tables_newchain() to make it more maintainable. Similarly, add nf_tables_addchain() and use it too.
8) Add new netlink NLM_F_NONREC flag, this flag should only be used for deletion requests, specifically, to support non-recursive deletion. Based on what we discussed during NFWS'17 in Faro.
9) Use NLM_F_NONREC from table and sets in nf_tables.
10) Support for recursive chain deletion. Table and set deletion commands come with an implicit content flush on deletion, while chains do not. This patch addresses this inconsistency by adding the code to perform recursive chain deletions. This also comes with the bits to deal with the new NLM_F_NONREC netlink flag.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks a lot!
----------------------------------------------------------------
The following changes since commit 3cf2e08f5ace79d57c8edba06deb59b25bd1dd33:
Merge branch 'nfp-refactor-app-init-and-minor-flower-fixes' (2017-09-03 21:22:05 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to 9dee1474121550b20542321f9e0579801c6b587c:
netfilter: nf_tables: support for recursive chain deletion (2017-09-04 17:34:55 +0200)
----------------------------------------------------------------
Florian Westphal (1):
netfilter: remove unused hooknum arg from packet functions
Pablo M. Bermudo Garay (3):
netfilter: nf_tables: add select_ops for stateful objects
netfilter: nft_limit: replace pkt_bytes with bytes
netfilter: nft_limit: add stateful object type
Pablo Neira Ayuso (5):
netfilter: nf_tables: add nf_tables_updchain()
netfilter: nf_tables: add nf_tables_addchain()
netlink: add NLM_F_NONREC flag for deletion requests
netfilter: nf_tables: use NLM_F_NONREC for deletion requests
netfilter: nf_tables: support for recursive chain deletion
Varsha Rao (2):
net: Replace NF_CT_ASSERT() with WARN_ON().
net: Remove CONFIG_NETFILTER_DEBUG and _ASSERT() macros.
Vishwanath Pai (1):
netfilter: xt_hashlimit: add rate match mode
arch/parisc/configs/c3000_defconfig | 1 - arch/sh/configs/se7751_defconfig | 1 - include/linux/netfilter/xt_hashlimit.h | 3 +- include/net/netfilter/nf_conntrack.h | 8 +- include/net/netfilter/nf_conntrack_l4proto.h | 1 - include/net/netfilter/nf_tables.h | 35 ++- include/uapi/linux/netfilter/nf_tables.h | 3 +- include/uapi/linux/netfilter/xt_hashlimit.h | 36 ++- include/uapi/linux/netlink.h | 3 + net/Kconfig | 7 - net/bridge/netfilter/ebtables.c | 20 +- net/ipv4/netfilter/ip_tables.c | 12 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 3 +- net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 6 +- net/ipv4/netfilter/nf_nat_masquerade_ipv4.c | 8 +- net/ipv6/netfilter/ip6_tables.c | 12 +- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 8 +- net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 6 +- net/ipv6/netfilter/nf_nat_masquerade_ipv6.c | 4 +- net/netfilter/nf_conntrack_core.c | 13 +- net/netfilter/nf_conntrack_expect.c | 4 +- net/netfilter/nf_conntrack_extend.c | 2 +- net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_generic.c | 1 - net/netfilter/nf_conntrack_proto_gre.c | 1 - net/netfilter/nf_conntrack_proto_sctp.c | 1 - net/netfilter/nf_conntrack_proto_tcp.c | 1 - net/netfilter/nf_conntrack_proto_udp.c | 1 - net/netfilter/nf_conntrack_standalone.c | 6 +- net/netfilter/nf_nat_core.c | 4 +- net/netfilter/nf_nat_redirect.c | 6 +- net/netfilter/nf_tables_api.c | 403 ++++++++++++++----------- net/netfilter/nft_counter.c | 20 +- net/netfilter/nft_ct.c | 18 +- net/netfilter/nft_limit.c | 148 ++++++++- net/netfilter/nft_objref.c | 7 +- net/netfilter/nft_quota.c | 20 +- net/netfilter/xt_NETMAP.c | 8 +- net/netfilter/xt_hashlimit.c | 277 +++++++++++++++-- net/netfilter/xt_nat.c | 20 +- 40 files changed, 788 insertions(+), 352 deletions(-)
Pablo Neira Ayuso
maintainerPATCH 1/12 netfilter: xt_hashlimit: add rate match mode
From: Vishwanath Pai <[email protected]>
This patch adds a new feature to hashlimit that allows matching on the current packet/byte rate without rate limiting. This can be enabled with a new flag --hashlimit-rate-match. The match returns true if the current rate of packets is above/below the user specified value.
The main difference between the existing algorithm and the new one is that the existing algorithm rate-limits the flow whereas the new algorithm does not. Instead it *classifies* the flow based on whether it is above or below a certain rate. I will demonstrate this with an example below. Let us assume this rule:
iptables -A INPUT -m hashlimit --hashlimit-above 10/s -j new_chain
If the packet rate is 15/s, the existing algorithm would ACCEPT 10 packets every second and send 5 packets to "new_chain".
But with the new algorithm, as long as the rate of 15/s is sustained, all packets will continue to match and every packet is sent to new_chain.
This new functionality will let us classify different flows based on their current rate, so that further decisions can be made on them based on what the current rate is.
This is how the new algorithm works:
We divide time into intervals of 1 (sec/min/hour) as specified by the user. We keep track of the number of packets/bytes processed in the current interval. After each interval we reset the counter to 0.
When we receive a packet for match, we look at the packet rate during the current interval and the previous interval to make a decision:
if [ prev_rate < user and cur_rate < user ]
return Below
else
return Above
Where cur_rate is the number of packets/bytes seen in the current interval, prev is the number of packets/bytes seen in the previous interval and 'user' is the rate specified by the user.
We also provide flexibility to the user for choosing the time interval using the option --hashilmit-interval. For example the user can keep a low rate like x/hour but still keep the interval as small as 1 second.
To preserve backwards compatibility we have to add this feature in a new revision, so I've created revision 3 for hashlimit. The two new options we add are:
--hashlimit-rate-match
--hashlimit-rate-interval
I have updated the help text to add these new options. Also added a few tests for the new options.
--- include/linux/netfilter/xt_hashlimit.h | 3 +- include/uapi/linux/netfilter/xt_hashlimit.h | 36 +++- net/netfilter/xt_hashlimit.c | 277 +++++++++++++++++++++++++--- 3 files changed, 285 insertions(+), 31 deletions(-)
include/linux/netfilter/xt_hashlimit.h +2 -1
@@ -5,5 +5,6 @@#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \ - XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES) + XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES |\ + XT_HASHLIMIT_RATE_MATCH)#endif /*_XT_HASHLIMIT_H*/
include/uapi/linux/netfilter/xt_hashlimit.h +30 -6
@@ -19,12 +19,13 @@struct xt_hashlimit_htable ;enum { -XT_HASHLIMIT_HASH_DIP =1 <<0 , -XT_HASHLIMIT_HASH_DPT =1 <<1 , -XT_HASHLIMIT_HASH_SIP =1 <<2 , -XT_HASHLIMIT_HASH_SPT =1 <<3 , -XT_HASHLIMIT_INVERT =1 <<4 , -XT_HASHLIMIT_BYTES =1 <<5 , +XT_HASHLIMIT_HASH_DIP =1 <<0 , +XT_HASHLIMIT_HASH_DPT =1 <<1 , +XT_HASHLIMIT_HASH_SIP =1 <<2 , +XT_HASHLIMIT_HASH_SPT =1 <<3 , +XT_HASHLIMIT_INVERT =1 <<4 , +XT_HASHLIMIT_BYTES =1 <<5 , +XT_HASHLIMIT_RATE_MATCH =1 <<6 , };struct hashlimit_cfg {
@@ -79,6 +80,21 @@ struct hashlimit_cfg2 {__u8 srcmask, dstmask; }; +struct hashlimit_cfg3 { +__u64 avg;/* Average secs between packets * scale */ +__u64 burst;/* Period multiplier for upper limit. */ +__u32 mode;/* bitmask of XT_HASHLIMIT_HASH_* */ + +/* user specified */ +__u32 size;/* how many buckets */ +__u32 max;/* max number of entries */ +__u32 gc_interval;/* gc interval */ +__u32 expire;/* when do entries expire? */ + +__u32 interval; +__u8 srcmask, dstmask; +}; +struct xt_hashlimit_mtinfo1 {char name[IFNAMSIZ ];struct hashlimit_cfg1 cfg;
@@ -95,4 +111,12 @@ struct xt_hashlimit_mtinfo2 { struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); }; +struct xt_hashlimit_mtinfo3 { +char name[NAME_MAX ]; +struct hashlimit_cfg3 cfg; + +/* Used internally by the kernel */ +struct xt_hashlimit_htable *hinfo __attribute__((aligned (8 ))); +}; +#endif /* _UAPI_XT_HASHLIMIT_H */
net/netfilter/xt_hashlimit.c +253 -24
475 lines not on this page · raw message
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 2/12 netfilter: nf_tables: add select_ops for stateful objects
In reply to Pablo Neira AyusoFrom: "Pablo M. Bermudo Garay" <[email protected]>
This patch adds support for overloading stateful objects operations through the select_ops() callback, just as it is implemented for expressions.
This change is needed for upcoming additions to the stateful objects infrastructure.
--- include/net/netfilter/nf_tables.h | 35 ++++++++++++++++++++++++----------- net/netfilter/nf_tables_api.c | 36 ++++++++++++++++++++++++------------ net/netfilter/nft_counter.c | 20 +++++++++++++------- net/netfilter/nft_ct.c | 18 ++++++++++++------ net/netfilter/nft_objref.c | 7 ++++--- net/netfilter/nft_quota.c | 20 +++++++++++++------- 6 files changed, 90 insertions(+), 46 deletions(-)
include/net/netfilter/nf_tables.h +24 -11
@@ -1007,12 +1007,12 @@ int nft_verdict_dump(struct sk_buff *skb, int type,* * @list: table stateful object list node * @table: table this object belongs to -* @type: pointer to object type -* @data: pointer to object data * @name: name of this stateful object * @genmask: generation mask * @use: number of references to this stateful object * @data: object data, layout depends on type +* @ops: object operations +* @data: pointer to object data */ struct nft_object {struct list_head list;
@@ -1021,7 +1021,7 @@ struct nft_object { u32 genmask:2, use:30;/* runtime data below here */ -const struct nft_object_type *type____cacheline_aligned ; +const struct nft_object_ops *ops____cacheline_aligned ; unsigned char data[] __attribute__((aligned(__alignof__(u64)))); };
@@ -1044,27 +1044,39 @@ void nft_obj_notify(struct net *net, struct nft_table *table,/** * struct nft_object_type - stateful object type * -* @eval: stateful object evaluation function +* @select_ops: function to select nft_object_ops +* @ops: default ops, used when no select_ops functions is present * @list: list node in list of object types * @type: stateful object numeric type -* @size: stateful object size * @owner: module owner * @maxattr: maximum netlink attribute * @policy: netlink attribute policy +*/ +struct nft_object_type { +const struct nft_object_ops *(*select_ops)(const struct nft_ctx *, +const struct nlattr *const tb[]); +const struct nft_object_ops *ops; +struct list_head list; +u32 type; +unsigned int maxattr; +struct module *owner; +const struct nla_policy *policy; +}; + +/** +* struct nft_object_ops - stateful object operations +* +* @eval: stateful object evaluation function +* @size: stateful object size * @init: initialize object from netlink attributes * @destroy: release existing stateful object * @dump: netlink dump stateful object */ -struct nft_object_type { +struct nft_object_ops {void (*eval)(struct nft_object *obj,struct nft_regs *regs,const struct nft_pktinfo *pkt); -struct list_head list; -u32 type;unsigned int size; -unsigned int maxattr; -struct module *owner; -const struct nla_policy *policy;int (*init)(const struct nft_ctx *ctx,const struct nlattr *const tb[],struct nft_object *obj);
@@ -1072,6 +1084,7 @@ struct nft_object_type {int (*dump)(struct sk_buff *skb,struct nft_object *obj,bool reset); +const struct nft_object_type *type; };int nft_register_obj (struct nft_object_type *obj_type);
net/netfilter/nf_tables_api.c +24 -12
@@ -4248,7 +4248,7 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,list_for_each_entry (obj, &table->objects, list) {if (!nla_strcmp (nla, obj->name) && - objtype == obj->type->type && + objtype == obj->ops->type->type &&nft_active_genmask (obj, genmask))return obj; }
@@ -4270,6 +4270,7 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, const struct nlattr *attr) {struct nlattr *tb[type->maxattr +1 ]; +const struct nft_object_ops *ops;struct nft_object *obj;int err;
@@ -4282,16 +4283,27 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,memset (tb,0 ,sizeof (tb[0 ]) * (type->maxattr +1 )); } +if (type->select_ops) { + ops = type->select_ops (ctx, (const struct nlattr *const *)tb); +if (IS_ERR (ops)) { + err =PTR_ERR (ops); + goto err1; + } + }else { + ops = type->ops; + } + err = -ENOMEM ; - obj =kzalloc (sizeof (struct nft_object ) + type->size,GFP_KERNEL ); + obj =kzalloc (sizeof (*obj) + ops->size,GFP_KERNEL );if (obj ==NULL ) goto err1; - err = type->init (ctx, (const struct nlattr *const *)tb, obj); + err = ops->init (ctx, (const struct nlattr *const *)tb, obj);if (err <0 ) goto err2; - obj->type = type; + obj->ops = ops; +return obj; err2:kfree (obj);
@@ -4307,7 +4319,7 @@ static int nft_object_dump(struct sk_buff *skb, unsigned int attr, nest =nla_nest_start (skb, attr);if (!nest) goto nla_put_failure; -if (obj->type->dump (skb, obj, reset) <0 ) +if (obj->ops->dump (skb, obj, reset) <0 ) goto nla_put_failure;nla_nest_end (skb, nest);return 0 ;
@@ -4418,8 +4430,8 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, err3:kfree (obj->name); err2: -if (obj->type->destroy) - obj->type->destroy (obj); +if (obj->ops->destroy) + obj->ops->destroy (obj);kfree (obj); err1:module_put (type->owner);
@@ -4446,7 +4458,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,if (nla_put_string (skb,NFTA_OBJ_TABLE , table->name) ||nla_put_string (skb,NFTA_OBJ_NAME , obj->name) || -nla_put_be32 (skb,NFTA_OBJ_TYPE ,htonl (obj->type->type)) || +nla_put_be32 (skb,NFTA_OBJ_TYPE ,htonl (obj->ops->type->type)) ||nla_put_be32 (skb,NFTA_OBJ_USE ,htonl (obj->use)) ||nft_object_dump (skb,NFTA_OBJ_DATA , obj, reset)) goto nla_put_failure;
@@ -4500,7 +4512,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) goto cont;if (filter && filter->type !=NFT_OBJECT_UNSPEC && - obj->type->type != filter->type) + obj->ops->type->type != filter->type) goto cont; if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
@@ -4628,10 +4640,10 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,static void nft_obj_destroy (struct nft_object *obj) { -if (obj->type->destroy) - obj->type->destroy (obj); +if (obj->ops->destroy) + obj->ops->destroy (obj); -module_put (obj->type->owner); +module_put (obj->ops->type->owner);kfree (obj->name);kfree (obj); }
net/netfilter/nft_counter.c +13 -7
@@ -175,15 +175,21 @@ static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = { [NFTA_COUNTER_BYTES] = { .type = NLA_U64 }, }; -static struct nft_object_type nft_counter_obj__read_mostly = { - .type =NFT_OBJECT_COUNTER , +static struct nft_object_type nft_counter_obj_type; +static const struct nft_object_ops nft_counter_obj_ops = { + .type = &nft_counter_obj_type, .size =sizeof (struct nft_counter_percpu_priv ), - .maxattr =NFTA_COUNTER_MAX , - .policy = nft_counter_policy, .eval = nft_counter_obj_eval, .init = nft_counter_obj_init, .destroy = nft_counter_obj_destroy, .dump = nft_counter_obj_dump, +}; + +static struct nft_object_type nft_counter_obj_type__read_mostly = { + .type =NFT_OBJECT_COUNTER , + .ops = &nft_counter_obj_ops, + .maxattr =NFTA_COUNTER_MAX , + .policy = nft_counter_policy, .owner =THIS_MODULE , };
@@ -271,7 +277,7 @@ static int __init nft_counter_module_init(void)for_each_possible_cpu (cpu)seqcount_init (per_cpu_ptr (&nft_counter_seq, cpu)); - err =nft_register_obj (&nft_counter_obj); + err =nft_register_obj (&nft_counter_obj_type);if (err <0 )return err;
@@ -281,14 +287,14 @@ static int __init nft_counter_module_init(void)return 0 ; err1: -nft_unregister_obj (&nft_counter_obj); +nft_unregister_obj (&nft_counter_obj_type);return err; } static void __exit nft_counter_module_exit(void) {nft_unregister_expr (&nft_counter_type); -nft_unregister_obj (&nft_counter_obj); +nft_unregister_obj (&nft_counter_obj_type); }module_init (nft_counter_module_init);
net/netfilter/nft_ct.c +12 -6
@@ -904,15 +904,21 @@ static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = { [NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 }, }; -static struct nft_object_type nft_ct_helper_obj__read_mostly = { - .type =NFT_OBJECT_CT_HELPER , +static struct nft_object_type nft_ct_helper_obj_type; +static const struct nft_object_ops nft_ct_helper_obj_ops = { + .type = &nft_ct_helper_obj_type, .size =sizeof (struct nft_ct_helper_obj ), - .maxattr =NFTA_CT_HELPER_MAX , - .policy = nft_ct_helper_policy, .eval = nft_ct_helper_obj_eval, .init = nft_ct_helper_obj_init, .destroy = nft_ct_helper_obj_destroy, .dump = nft_ct_helper_obj_dump, +}; + +static struct nft_object_type nft_ct_helper_obj_type__read_mostly = { + .type =NFT_OBJECT_CT_HELPER , + .ops = &nft_ct_helper_obj_ops, + .maxattr =NFTA_CT_HELPER_MAX , + .policy = nft_ct_helper_policy, .owner =THIS_MODULE , };
@@ -930,7 +936,7 @@ static int __init nft_ct_module_init(void)if (err <0 ) goto err1; - err =nft_register_obj (&nft_ct_helper_obj); + err =nft_register_obj (&nft_ct_helper_obj_type);if (err <0 ) goto err2;
@@ -945,7 +951,7 @@ static int __init nft_ct_module_init(void) static void __exit nft_ct_module_exit(void) { -nft_unregister_obj (&nft_ct_helper_obj); +nft_unregister_obj (&nft_ct_helper_obj_type);nft_unregister_expr (&nft_notrack_type);nft_unregister_expr (&nft_ct_type); }
net/netfilter/nft_objref.c +4 -3
@@ -22,7 +22,7 @@ static void nft_objref_eval(const struct nft_expr *expr, {struct nft_object *obj =nft_objref_priv (expr); - obj->type->eval (obj, regs, pkt); + obj->ops->eval (obj, regs, pkt); } static int nft_objref_init(const struct nft_ctx *ctx,
@@ -54,7 +54,8 @@ static int nft_objref_dump(struct sk_buff *skb, const struct nft_expr *expr)const struct nft_object *obj =nft_objref_priv (expr);if (nla_put_string (skb,NFTA_OBJREF_IMM_NAME , obj->name) || -nla_put_be32 (skb,NFTA_OBJREF_IMM_TYPE ,htonl (obj->type->type))) +nla_put_be32 (skb,NFTA_OBJREF_IMM_TYPE , +htonl (obj->ops->type->type))) goto nla_put_failure;return 0 ;
@@ -104,7 +105,7 @@ static void nft_objref_map_eval(const struct nft_expr *expr,return ; } obj = *nft_set_ext_obj (ext); - obj->type->eval (obj, regs, pkt); + obj->ops->eval (obj, regs, pkt); } static int nft_objref_map_init(const struct nft_ctx *ctx,
net/netfilter/nft_quota.c +13 -7
@@ -151,14 +151,20 @@ static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,return nft_quota_do_dump (skb, priv, reset); } -static struct nft_object_type nft_quota_obj__read_mostly = { - .type =NFT_OBJECT_QUOTA , +static struct nft_object_type nft_quota_obj_type; +static const struct nft_object_ops nft_quota_obj_ops = { + .type = &nft_quota_obj_type, .size =sizeof (struct nft_quota ), - .maxattr =NFTA_QUOTA_MAX , - .policy = nft_quota_policy, .init = nft_quota_obj_init, .eval = nft_quota_obj_eval, .dump = nft_quota_obj_dump, +}; + +static struct nft_object_type nft_quota_obj_type__read_mostly = { + .type =NFT_OBJECT_QUOTA , + .ops = &nft_quota_obj_ops, + .maxattr =NFTA_QUOTA_MAX , + .policy = nft_quota_policy, .owner =THIS_MODULE , };
@@ -209,7 +215,7 @@ static int __init nft_quota_module_init(void) {int err; - err =nft_register_obj (&nft_quota_obj); + err =nft_register_obj (&nft_quota_obj_type);if (err <0 )return err;
@@ -219,14 +225,14 @@ static int __init nft_quota_module_init(void)return 0 ; err1: -nft_unregister_obj (&nft_quota_obj); +nft_unregister_obj (&nft_quota_obj_type);return err; } static void __exit nft_quota_module_exit(void) {nft_unregister_expr (&nft_quota_type); -nft_unregister_obj (&nft_quota_obj); +nft_unregister_obj (&nft_quota_obj_type); }module_init (nft_quota_module_init);
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 3/12 netfilter: nft_limit: replace pkt_bytes with bytes
In reply to Pablo Neira AyusoFrom: "Pablo M. Bermudo Garay" <[email protected]>
Just a small refactor patch in order to improve the code readability.
--- net/netfilter/nft_limit.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
net/netfilter/nft_limit.c +13 -13
@@ -168,9 +168,9 @@ static const struct nft_expr_ops nft_limit_pkts_ops = { .dump = nft_limit_pkts_dump, }; -static void nft_limit_pkt_bytes_eval (const struct nft_expr *expr, -struct nft_regs *regs, -const struct nft_pktinfo *pkt) +static void nft_limit_bytes_eval (const struct nft_expr *expr, +struct nft_regs *regs, +const struct nft_pktinfo *pkt) {struct nft_limit *priv =nft_expr_priv (expr);u64 cost =div64_u64 (priv->nsecs * pkt->skb->len, priv->rate);
@@ -179,29 +179,29 @@ static void nft_limit_pkt_bytes_eval(const struct nft_expr *expr, regs->verdict.code =NFT_BREAK ; } -static int nft_limit_pkt_bytes_init (const struct nft_ctx *ctx, -const struct nft_expr *expr, -const struct nlattr *const tb[]) +static int nft_limit_bytes_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]) {struct nft_limit *priv =nft_expr_priv (expr);return nft_limit_init (priv, tb); } -static int nft_limit_pkt_bytes_dump (struct sk_buff *skb, -const struct nft_expr *expr) +static int nft_limit_bytes_dump (struct sk_buff *skb, +const struct nft_expr *expr) {const struct nft_limit *priv =nft_expr_priv (expr);return nft_limit_dump (skb, priv,NFT_LIMIT_PKT_BYTES ); } -static const struct nft_expr_ops nft_limit_pkt_bytes_ops = { +static const struct nft_expr_ops nft_limit_bytes_ops = { .type = &nft_limit_type, .size =NFT_EXPR_SIZE (sizeof (struct nft_limit )), - .eval = nft_limit_pkt_bytes_eval, - .init = nft_limit_pkt_bytes_init, - .dump = nft_limit_pkt_bytes_dump, + .eval = nft_limit_bytes_eval, + .init = nft_limit_bytes_init, + .dump = nft_limit_bytes_dump, }; static const struct nft_expr_ops *
@@ -215,7 +215,7 @@ nft_limit_select_ops(const struct nft_ctx *ctx,case NFT_LIMIT_PKTS :return &nft_limit_pkts_ops;case NFT_LIMIT_PKT_BYTES : -return &nft_limit_pkt_bytes_ops; +return &nft_limit_bytes_ops; }return ERR_PTR (-EOPNOTSUPP ); }
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 4/12 netfilter: nft_limit: add stateful object type
In reply to Pablo Neira AyusoFrom: "Pablo M. Bermudo Garay" <[email protected]>
Register a new limit stateful object type into the stateful object infrastructure.
--- include/uapi/linux/netfilter/nf_tables.h | 3 +- net/netfilter/nft_limit.c | 122 ++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 2 deletions(-)
include/uapi/linux/netfilter/nf_tables.h +2 -1
@@ -1282,7 +1282,8 @@ enum nft_ct_helper_attributes {#define NFT_OBJECT_COUNTER 1#define NFT_OBJECT_QUOTA 2#define NFT_OBJECT_CT_HELPER 3 -#define __NFT_OBJECT_MAX 4 +#define NFT_OBJECT_LIMIT 4 +#define __NFT_OBJECT_MAX 5#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)/**
net/netfilter/nft_limit.c +121 -1
138 lines not on this page · raw message
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 5/12 netfilter: remove unused hooknum arg from packet functions
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
tested with allmodconfig build.
--- include/net/netfilter/nf_conntrack_l4proto.h | 1 - net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 1 - net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 6 ++---- net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_generic.c | 1 - net/netfilter/nf_conntrack_proto_gre.c | 1 - net/netfilter/nf_conntrack_proto_sctp.c | 1 - net/netfilter/nf_conntrack_proto_tcp.c | 1 - net/netfilter/nf_conntrack_proto_udp.c | 1 - 10 files changed, 4 insertions(+), 13 deletions(-)
include/net/netfilter/nf_conntrack_l4proto.h +0 -1
@@ -43,7 +43,6 @@ struct nf_conntrack_l4proto {unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts);/* Called when a new connection for this protocol found;
net/ipv4/netfilter/nf_conntrack_proto_icmp.c +0 -1
@@ -82,7 +82,6 @@ static int icmp_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) {/* Do not immediately delete the connection after the first
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +2 -4
@@ -95,7 +95,6 @@ static int icmpv6_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) {/* Do not immediately delete the connection after the first
@@ -129,8 +128,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,static int icmpv6_error_message (struct net *net,struct nf_conn *tmpl,struct sk_buff *skb, -unsigned int icmp6off, -unsigned int hooknum) +unsigned int icmp6off) {struct nf_conntrack_tuple intuple, origtuple;const struct nf_conntrack_tuple_hash *h;
@@ -214,7 +212,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl,if (icmp6h->icmp6_type >=128 )return NF_ACCEPT ; -return icmpv6_error_message (net, tmpl, skb, dataoff, hooknum); +return icmpv6_error_message (net, tmpl, skb, dataoff); }#if IS_ENABLED (CONFIG_NF_CT_NETLINK )
net/netfilter/nf_conntrack_core.c +1 -1
@@ -1414,7 +1414,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,/* Decide what timeout policy we want to apply to this flow. */ timeouts =nf_ct_timeout_lookup (net, ct, l4proto); - ret = l4proto->packet (ct, skb, dataoff, ctinfo, pf, hooknum, timeouts); + ret = l4proto->packet (ct, skb, dataoff, ctinfo, pf, timeouts);if (ret <=0 ) {/* Invalid: inverse of the return code tells * the netfilter core what to do */
net/netfilter/nf_conntrack_proto_dccp.c +1 -1
@@ -469,7 +469,7 @@ static unsigned int *dccp_get_timeouts(struct net *net)static int dccp_packet (struct nf_conn *ct,const struct sk_buff *skb,unsigned int dataoff,enum ip_conntrack_info ctinfo, -u_int8_t pf,unsigned int hooknum, +u_int8_t pf,unsigned int *timeouts) {struct net *net =nf_ct_net (ct);
net/netfilter/nf_conntrack_proto_generic.c +0 -1
@@ -61,7 +61,6 @@ static int generic_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) { nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
net/netfilter/nf_conntrack_proto_gre.c +0 -1
@@ -245,7 +245,6 @@ static int gre_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) {/* If we've seen traffic both ways, this is a GRE connection.
net/netfilter/nf_conntrack_proto_sctp.c +0 -1
@@ -307,7 +307,6 @@ static int sctp_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { enum sctp_conntrack new_state, old_state;
net/netfilter/nf_conntrack_proto_tcp.c +0 -1
@@ -803,7 +803,6 @@ static int tcp_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { struct net *net = nf_ct_net(ct);
net/netfilter/nf_conntrack_proto_udp.c +0 -1
@@ -74,7 +74,6 @@ static int udp_packet(struct nf_conn *ct,unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) {/* If we've seen traffic both ways, this is some kind of UDP
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 6/12 net: Replace NF_CT_ASSERT() with WARN_ON().
In reply to Pablo Neira AyusoFrom: Varsha Rao <[email protected]>
This patch removes NF_CT_ASSERT() and instead uses WARN_ON().
--- include/net/netfilter/nf_conntrack.h | 2 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 +- net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 6 +++--- net/ipv4/netfilter/nf_nat_masquerade_ipv4.c | 8 ++++---- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 2 +- net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 6 +++--- net/ipv6/netfilter/nf_nat_masquerade_ipv6.c | 4 ++-- net/netfilter/nf_conntrack_core.c | 11 +++++------ net/netfilter/nf_conntrack_expect.c | 4 ++-- net/netfilter/nf_conntrack_extend.c | 2 +- net/netfilter/nf_conntrack_standalone.c | 6 +++--- net/netfilter/nf_nat_core.c | 4 ++-- net/netfilter/nf_nat_redirect.c | 6 +++--- net/netfilter/xt_NETMAP.c | 8 ++++---- net/netfilter/xt_nat.c | 20 ++++++++++---------- 15 files changed, 45 insertions(+), 46 deletions(-)
include/net/netfilter/nf_conntrack.h +1 -1
@@ -159,7 +159,7 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)/* decrement reference count on a conntrack */ static inline void nf_ct_put (struct nf_conn *ct) { -NF_CT_ASSERT (ct); +WARN_ON (!ct);nf_conntrack_put (&ct->ct_general); }
net/ipv4/netfilter/nf_conntrack_proto_icmp.c +1 -1
@@ -126,7 +126,7 @@ icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,enum ip_conntrack_info ctinfo;struct nf_conntrack_zone tmp; -NF_CT_ASSERT (!skb_nfct (skb)); +WARN_ON (skb_nfct (skb)); zone =nf_ct_zone_tmpl (tmpl, skb, &tmp);/* Are they talking about one of our connections? */
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c +3 -3
@@ -190,7 +190,7 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb,struct nf_conntrack_tuple target;unsigned long statusbit; -NF_CT_ASSERT (ctinfo ==IP_CT_RELATED || ctinfo ==IP_CT_RELATED_REPLY ); +WARN_ON (ctinfo !=IP_CT_RELATED && ctinfo !=IP_CT_RELATED_REPLY );if (!skb_make_writable (skb, hdrlen +sizeof (*inside)))return 0 ;
@@ -306,8 +306,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,default :/* ESTABLISHED */ -NF_CT_ASSERT (ctinfo ==IP_CT_ESTABLISHED || - ctinfo ==IP_CT_ESTABLISHED_REPLY ); +WARN_ON (ctinfo !=IP_CT_ESTABLISHED && + ctinfo !=IP_CT_ESTABLISHED_REPLY );if (nf_nat_oif_changed (state->hook, ctinfo, nat, state->out)) goto oif_changed; }
net/ipv4/netfilter/nf_nat_masquerade_ipv4.c +4 -4
@@ -34,12 +34,12 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,const struct rtable *rt;__be32 newsrc, nh; -NF_CT_ASSERT (hooknum ==NF_INET_POST_ROUTING ); +WARN_ON (hooknum !=NF_INET_POST_ROUTING ); ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || - ctinfo ==IP_CT_RELATED_REPLY )); +WARN_ON (!(ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || + ctinfo ==IP_CT_RELATED_REPLY )));/* Source address is 0.0.0.0 - locally generated packet that is * probably not supposed to be masqueraded.
@@ -96,7 +96,7 @@ static int masq_device_event(struct notifier_block *this,* conntracks which were associated with that device, * and forget them. */ -NF_CT_ASSERT (dev->ifindex !=0 ); +WARN_ON (dev->ifindex ==0 );nf_ct_iterate_cleanup_net (net, device_cmp, (void *)(long )dev->ifindex,0 ,0 );
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +1 -1
@@ -136,7 +136,7 @@ icmpv6_error_message(struct net *net, struct nf_conn *tmpl,enum ip_conntrack_info ctinfo;struct nf_conntrack_zone tmp; -NF_CT_ASSERT (!skb_nfct (skb)); +WARN_ON (skb_nfct (skb));/* Are they talking about one of our connections? */ if (!nf_ct_get_tuplepr(skb,
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c +3 -3
@@ -196,7 +196,7 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,struct nf_conntrack_tuple target;unsigned long statusbit; -NF_CT_ASSERT (ctinfo ==IP_CT_RELATED || ctinfo ==IP_CT_RELATED_REPLY ); +WARN_ON (ctinfo !=IP_CT_RELATED && ctinfo !=IP_CT_RELATED_REPLY );if (!skb_make_writable (skb, hdrlen +sizeof (*inside)))return 0 ;
@@ -319,8 +319,8 @@ nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,default :/* ESTABLISHED */ -NF_CT_ASSERT (ctinfo ==IP_CT_ESTABLISHED || - ctinfo ==IP_CT_ESTABLISHED_REPLY ); +WARN_ON (ctinfo !=IP_CT_ESTABLISHED && + ctinfo !=IP_CT_ESTABLISHED_REPLY );if (nf_nat_oif_changed (state->hook, ctinfo, nat, state->out)) goto oif_changed; }
net/ipv6/netfilter/nf_nat_masquerade_ipv6.c +2 -2
@@ -36,8 +36,8 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,struct nf_nat_range newrange; ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || - ctinfo ==IP_CT_RELATED_REPLY )); +WARN_ON (!(ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || + ctinfo ==IP_CT_RELATED_REPLY )));if (ipv6_dev_get_saddr (nf_ct_net (ct), out, &ipv6_hdr (skb)->daddr,0 , &src) <0 )
net/netfilter/nf_conntrack_core.c +5 -6
@@ -403,7 +403,7 @@ destroy_conntrack(struct nf_conntrack *nfct)const struct nf_conntrack_l4proto *l4proto;pr_debug ("destroy_conntrack(%p)\n" , ct); -NF_CT_ASSERT (atomic_read (&nfct->use) ==0 ); +WARN_ON (atomic_read (&nfct->use) !=0 );if (unlikely (nf_ct_is_template (ct))) {nf_ct_tmpl_free (ct);
@@ -756,12 +756,11 @@ __nf_conntrack_confirm(struct sk_buff *skb)* connections for unconfirmed conns. But packet copies and * REJECT will give spurious warnings here. */ -/* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */ /* No external references means no one else could have * confirmed us. */ -NF_CT_ASSERT (!nf_ct_is_confirmed (ct)); +WARN_ON (nf_ct_is_confirmed (ct));pr_debug ("Confirming conntrack %p\n" , ct);/* We have to check the DYING flag after unlink to prevent * a race against nf_ct_get_next_corpse() possibly called from
@@ -1160,7 +1159,7 @@ void nf_conntrack_free(struct nf_conn *ct)/* A freed object has refcnt == 0, that's * the golden rule for SLAB_TYPESAFE_BY_RCU */ -NF_CT_ASSERT (atomic_read (&ct->ct_general.use) ==0 ); +WARN_ON (atomic_read (&ct->ct_general.use) !=0 );nf_ct_ext_destroy (ct);nf_ct_ext_free (ct);
@@ -1468,7 +1467,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,struct nf_conn_help *help =nfct_help (ct);/* Should be unconfirmed, so not in hash table yet */ -NF_CT_ASSERT (!nf_ct_is_confirmed (ct)); +WARN_ON (nf_ct_is_confirmed (ct));pr_debug ("Altering reply tuple of %p to " , ct);nf_ct_dump_tuple (newreply);
@@ -1490,7 +1489,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, unsigned long extra_jiffies, int do_acct) { -NF_CT_ASSERT (skb ); +WARN_ON (!skb);/* Only update if this is not a fixed timeout */ if (test_bit (IPS_FIXED_TIMEOUT_BIT , &ct->status))
net/netfilter/nf_conntrack_expect.c +2 -2
@@ -51,8 +51,8 @@ void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,struct nf_conn_help *master_help =nfct_help (exp->master);struct net *net =nf_ct_exp_net (exp); -NF_CT_ASSERT (master_help); -NF_CT_ASSERT (!timer_pending (&exp->timeout)); +WARN_ON (!master_help); +WARN_ON (timer_pending (&exp->timeout));hlist_del_rcu (&exp->hnode); net->ct.expect_count--;
net/netfilter/nf_conntrack_extend.c +1 -1
@@ -47,7 +47,7 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)struct nf_ct_ext_type *t;/* Conntrack must not be confirmed to avoid races on reallocation. */ -NF_CT_ASSERT (!nf_ct_is_confirmed (ct)); +WARN_ON (nf_ct_is_confirmed (ct)); old = ct->ext;
net/netfilter/nf_conntrack_standalone.c +3 -3
@@ -287,7 +287,7 @@ static int ct_seq_show(struct seq_file *s, void *v)struct net *net =seq_file_net (s);int ret =0 ; -NF_CT_ASSERT (ct); +WARN_ON (!ct);if (unlikely (!atomic_inc_not_zero (&ct->ct_general.use)))return 0 ;
@@ -304,9 +304,9 @@ static int ct_seq_show(struct seq_file *s, void *v) goto release; l3proto =__nf_ct_l3proto_find (nf_ct_l3num (ct)); -NF_CT_ASSERT (l3proto); +WARN_ON (!l3proto); l4proto =__nf_ct_l4proto_find (nf_ct_l3num (ct),nf_ct_protonum (ct)); -NF_CT_ASSERT (l4proto); +WARN_ON (!l4proto); ret = -ENOSPC ; seq_printf(s, "%-8s %u %-8s %u %ld ",
net/netfilter/nf_nat_core.c +2 -2
@@ -414,8 +414,8 @@ nf_nat_setup_info(struct nf_conn *ct,if (nf_ct_is_confirmed (ct))return NF_ACCEPT ; -NF_CT_ASSERT (maniptype ==NF_NAT_MANIP_SRC || - maniptype ==NF_NAT_MANIP_DST ); +WARN_ON (maniptype !=NF_NAT_MANIP_SRC && + maniptype !=NF_NAT_MANIP_DST );BUG_ON (nf_nat_initialized (ct, maniptype));/* What we've got will look like inverse of reply. Normally
net/netfilter/nf_nat_redirect.c +3 -3
@@ -38,11 +38,11 @@ nf_nat_redirect_ipv4(struct sk_buff *skb,__be32 newdst;struct nf_nat_range newrange; -NF_CT_ASSERT (hooknum ==NF_INET_PRE_ROUTING || - hooknum ==NF_INET_LOCAL_OUT ); +WARN_ON (hooknum !=NF_INET_PRE_ROUTING && + hooknum !=NF_INET_LOCAL_OUT ); ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )); +WARN_ON (!(ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )));/* Local packets: make them go to loopback */ if (hooknum ==NF_INET_LOCAL_OUT ) {
net/netfilter/xt_NETMAP.c +4 -4
@@ -77,10 +77,10 @@ netmap_tg4(struct sk_buff *skb, const struct xt_action_param *par)const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;struct nf_nat_range newrange; -NF_CT_ASSERT (xt_hooknum (par) ==NF_INET_PRE_ROUTING || -xt_hooknum (par) ==NF_INET_POST_ROUTING || -xt_hooknum (par) ==NF_INET_LOCAL_OUT || -xt_hooknum (par) ==NF_INET_LOCAL_IN ); +WARN_ON (xt_hooknum (par) !=NF_INET_PRE_ROUTING && +xt_hooknum (par) !=NF_INET_POST_ROUTING && +xt_hooknum (par) !=NF_INET_LOCAL_OUT && +xt_hooknum (par) !=NF_INET_LOCAL_IN ); ct =nf_ct_get (skb, &ctinfo); netmask = ~(mr->range[0 ].min_ip ^ mr->range[0 ].max_ip);
net/netfilter/xt_nat.c +10 -10
@@ -58,9 +58,9 @@ xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)struct nf_conn *ct; ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct !=NULL && - (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || - ctinfo ==IP_CT_RELATED_REPLY )); +WARN_ON (!(ct !=NULL && + (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || + ctinfo ==IP_CT_RELATED_REPLY )));xt_nat_convert_range (&range, &mr->range[0 ]);return nf_nat_setup_info (ct, &range,NF_NAT_MANIP_SRC );
@@ -75,8 +75,8 @@ xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)struct nf_conn *ct; ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct !=NULL && - (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )); +WARN_ON (!(ct !=NULL && + (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )));xt_nat_convert_range (&range, &mr->range[0 ]);return nf_nat_setup_info (ct, &range,NF_NAT_MANIP_DST );
@@ -90,9 +90,9 @@ xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)struct nf_conn *ct; ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct !=NULL && - (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || - ctinfo ==IP_CT_RELATED_REPLY )); +WARN_ON (!(ct !=NULL && + (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || + ctinfo ==IP_CT_RELATED_REPLY )));return nf_nat_setup_info (ct, range,NF_NAT_MANIP_SRC ); }
@@ -105,8 +105,8 @@ xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)struct nf_conn *ct; ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct !=NULL && - (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )); +WARN_ON (!(ct !=NULL && + (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )));return nf_nat_setup_info (ct, range,NF_NAT_MANIP_DST ); }
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 7/12 net: Remove CONFIG_NETFILTER_DEBUG and _ASSERT() macros.
In reply to Pablo Neira AyusoFrom: Varsha Rao <[email protected]>
This patch removes CONFIG_NETFILTER_DEBUG and _ASSERT() macros as they are no longer required. Replace _ASSERT() macros with WARN_ON().
--- arch/parisc/configs/c3000_defconfig | 1 - arch/sh/configs/se7751_defconfig | 1 - include/net/netfilter/nf_conntrack.h | 6 ------ net/Kconfig | 7 ------- net/bridge/netfilter/ebtables.c | 20 ++++++++------------ net/ipv4/netfilter/ip_tables.c | 12 +++--------- net/ipv6/netfilter/ip6_tables.c | 12 +++--------- 7 files changed, 14 insertions(+), 45 deletions(-)
arch/parisc/configs/c3000_defconfig +0 -1
@@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y CONFIG_NET_PKTGEN=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y
arch/sh/configs/se7751_defconfig +0 -1
@@ -28,7 +28,6 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y CONFIG_IP_NF_QUEUE=y CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y
include/net/netfilter/nf_conntrack.h +0 -6
@@ -44,12 +44,6 @@ union nf_conntrack_expect_proto {#include <linux/types.h> #include <linux/skbuff.h> -#ifdef CONFIG_NETFILTER_DEBUG -#define NF_CT_ASSERT (x) WARN_ON(!(x)) -#else -#define NF_CT_ASSERT (x) -#endif -#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
net/Kconfig +0 -7
@@ -166,13 +166,6 @@ menuconfig NETFILTER if NETFILTER -config NETFILTER_DEBUG - bool "Network packet filtering debugging" - depends on NETFILTER - help - You can say Y here if you want to get additional messages useful in - debugging the netfilter code. - config NETFILTER_ADVANCED bool "Advanced netfilter configuration" depends on NETFILTER
net/bridge/netfilter/ebtables.c +8 -12
@@ -252,13 +252,11 @@ unsigned int ebt_do_table(struct sk_buff *skb, }if (verdict ==EBT_RETURN ) { letsreturn: -#ifdef CONFIG_NETFILTER_DEBUG -if (sp ==0 ) { -BUGPRINT ("RETURN on base chain" ); +if (WARN (sp ==0 ,"RETURN on base chain" )) {/* act like this is EBT_CONTINUE */ goto letscontinue; } -#endif + sp--;/* put all the local variables right */ i = cs[sp].n;
@@ -271,26 +269,24 @@ unsigned int ebt_do_table(struct sk_buff *skb, }if (verdict ==EBT_CONTINUE ) goto letscontinue; -#ifdef CONFIG_NETFILTER_DEBUG -if (verdict <0 ) { -BUGPRINT ("bogus standard verdict\n" ); + +if (WARN (verdict <0 ,"bogus standard verdict\n" )) {read_unlock_bh (&table->lock);return NF_DROP ; } -#endif +/* jump to a udc */ cs[sp].n = i +1 ; cs[sp].chaininfo = chaininfo; cs[sp].e =ebt_next_entry (point); i =0 ; chaininfo = (struct ebt_entries *) (base + verdict); -#ifdef CONFIG_NETFILTER_DEBUG -if (chaininfo->distinguisher) { -BUGPRINT ("jump to non-chain\n" ); + +if (WARN (chaininfo->distinguisher,"jump to non-chain\n" )) {read_unlock_bh (&table->lock);return NF_DROP ; } -#endif + nentries = chaininfo->nentries; point = (struct ebt_entry *)chaininfo->data; counter_base = cb_base + chaininfo->counter_offset;
net/ipv4/netfilter/ip_tables.c +3 -9
@@ -35,12 +35,6 @@ MODULE_LICENSE("GPL");MODULE_AUTHOR ("Netfilter Core Team <[email protected]>" );MODULE_DESCRIPTION ("IPv4 packet filter" ); -#ifdef CONFIG_NETFILTER_DEBUG -#define IP_NF_ASSERT (x) WARN_ON(!(x)) -#else -#define IP_NF_ASSERT (x) -#endif -void *ipt_alloc_initial_table (const struct xt_table *info) {return xt_alloc_initial_table (ipt,IPT );
@@ -263,7 +257,7 @@ ipt_do_table(struct sk_buff *skb, acpar.hotdrop = false; acpar.state = state; -IP_NF_ASSERT (table->valid_hooks & (1 << hook)); +WARN_ON (!(table->valid_hooks & (1 << hook)));local_bh_disable (); addend =xt_write_recseq_begin (); private = table->private;
@@ -293,7 +287,7 @@ ipt_do_table(struct sk_buff *skb,const struct xt_entry_match *ematch;struct xt_counters *counter; -IP_NF_ASSERT (e); +WARN_ON (!e);if (!ip_packet_match (ip, indev, outdev, &e->ip, acpar.fragoff)) { no_match:
@@ -312,7 +306,7 @@ ipt_do_table(struct sk_buff *skb,ADD_COUNTER (*counter, skb->len,1 ); t =ipt_get_target (e); -IP_NF_ASSERT (t->u.kernel.target); +WARN_ON (!t->u.kernel.target);#if IS_ENABLED (CONFIG_NETFILTER_XT_TARGET_TRACE )/* The packet is traced: log it */
net/ipv6/netfilter/ip6_tables.c +3 -9
@@ -39,12 +39,6 @@ MODULE_LICENSE("GPL");MODULE_AUTHOR ("Netfilter Core Team <[email protected]>" );MODULE_DESCRIPTION ("IPv6 packet filter" ); -#ifdef CONFIG_NETFILTER_DEBUG -#define IP_NF_ASSERT (x) WARN_ON(!(x)) -#else -#define IP_NF_ASSERT (x) -#endif -void *ip6t_alloc_initial_table (const struct xt_table *info) {return xt_alloc_initial_table (ip6t,IP6T );
@@ -284,7 +278,7 @@ ip6t_do_table(struct sk_buff *skb, acpar.hotdrop = false; acpar.state = state; -IP_NF_ASSERT (table->valid_hooks & (1 << hook)); +WARN_ON (!(table->valid_hooks & (1 << hook)));local_bh_disable (); addend =xt_write_recseq_begin ();
@@ -315,7 +309,7 @@ ip6t_do_table(struct sk_buff *skb,const struct xt_entry_match *ematch;struct xt_counters *counter; -IP_NF_ASSERT (e); +WARN_ON (!e); acpar.thoff =0 ;if (!ip6_packet_match (skb, indev, outdev, &e->ipv6, &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) {
@@ -335,7 +329,7 @@ ip6t_do_table(struct sk_buff *skb,ADD_COUNTER (*counter, skb->len,1 ); t =ip6t_get_target_c (e); -IP_NF_ASSERT (t->u.kernel.target); +WARN_ON (!t->u.kernel.target);#if IS_ENABLED (CONFIG_NETFILTER_XT_TARGET_TRACE )/* The packet is traced: log it */
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 8/12 netfilter: nf_tables: add nf_tables_updchain()
In reply to Pablo Neira Ayusonf_tables_newchain() is too large, wrap the chain update path in a function to make it more maintainable.
--- net/netfilter/nf_tables_api.c | 170 +++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 78 deletions(-)
net/netfilter/nf_tables_api.c +92 -78
@@ -1335,6 +1335,97 @@ static void nft_chain_release_hook(struct nft_chain_hook *hook)dev_put (hook->dev); } +static int nf_tables_updchain (struct nft_ctx *ctx,u8 genmask,u8 policy, +bool create) +{ +const struct nlattr *const *nla = ctx->nla; +struct nft_table *table = ctx->table; +struct nft_chain *chain = ctx->chain; +struct nft_af_info *afi = ctx->afi; +struct nft_base_chain *basechain; +struct nft_stats *stats =NULL ; +struct nft_chain_hook hook; +const struct nlattr *name; +struct nf_hook_ops *ops; +struct nft_trans *trans; +int err, i; + +if (nla[NFTA_CHAIN_HOOK ]) { +if (!nft_is_base_chain (chain)) +return -EBUSY ; + + err =nft_chain_parse_hook (ctx->net, nla, ctx->afi, &hook, + create); +if (err <0 ) +return err; + + basechain =nft_base_chain (chain); +if (basechain->type != hook.type) { +nft_chain_release_hook (&hook); +return -EBUSY ; + } + +for (i =0 ; i < afi->nops; i++) { + ops = &basechain->ops[i]; +if (ops->hooknum != hook.num || + ops->priority != hook.priority || + ops->dev != hook.dev) { +nft_chain_release_hook (&hook); +return -EBUSY ; + } + } +nft_chain_release_hook (&hook); + } + +if (nla[NFTA_CHAIN_HANDLE ] && + nla[NFTA_CHAIN_NAME ]) { +struct nft_chain *chain2; + + chain2 =nf_tables_chain_lookup (table, nla[NFTA_CHAIN_NAME ], + genmask); +if (IS_ERR (chain2)) +return PTR_ERR (chain2); + } + +if (nla[NFTA_CHAIN_COUNTERS ]) { +if (!nft_is_base_chain (chain)) +return -EOPNOTSUPP ; + + stats =nft_stats_alloc (nla[NFTA_CHAIN_COUNTERS ]); +if (IS_ERR (stats)) +return PTR_ERR (stats); + } + + trans =nft_trans_alloc (ctx,NFT_MSG_NEWCHAIN , +sizeof (struct nft_trans_chain )); +if (trans ==NULL ) { +free_percpu (stats); +return -ENOMEM ; + } + +nft_trans_chain_stats (trans) = stats; +nft_trans_chain_update (trans) = true; + +if (nla[NFTA_CHAIN_POLICY ]) +nft_trans_chain_policy (trans) = policy; +else +nft_trans_chain_policy (trans) =-1 ; + + name = nla[NFTA_CHAIN_NAME ]; +if (nla[NFTA_CHAIN_HANDLE ] && name) { +nft_trans_chain_name (trans) = +nla_strdup (name,GFP_KERNEL ); +if (!nft_trans_chain_name (trans)) { +kfree (trans); +free_percpu (stats); +return -ENOMEM ; + } + } +list_add_tail (&trans->list, &ctx->net->nft.commit_list); + +return 0 ; +} + static int nf_tables_newchain(struct net *net, struct sock *nlsk, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nla[],
@@ -1403,91 +1494,14 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, }if (chain !=NULL ) { -struct nft_stats *stats =NULL ; -struct nft_trans *trans; -if (nlh->nlmsg_flags &NLM_F_EXCL )return -EEXIST ;if (nlh->nlmsg_flags &NLM_F_REPLACE )return -EOPNOTSUPP ; -if (nla[NFTA_CHAIN_HOOK ]) { -struct nft_base_chain *basechain; -struct nft_chain_hook hook; -struct nf_hook_ops *ops; - -if (!nft_is_base_chain (chain)) -return -EBUSY ; - - err =nft_chain_parse_hook (net, nla, afi, &hook, - create); -if (err <0 ) -return err; - - basechain =nft_base_chain (chain); -if (basechain->type != hook.type) { -nft_chain_release_hook (&hook); -return -EBUSY ; - } - -for (i =0 ; i < afi->nops; i++) { - ops = &basechain->ops[i]; -if (ops->hooknum != hook.num || - ops->priority != hook.priority || - ops->dev != hook.dev) { -nft_chain_release_hook (&hook); -return -EBUSY ; - } - } -nft_chain_release_hook (&hook); - } - -if (nla[NFTA_CHAIN_HANDLE ] && name) { -struct nft_chain *chain2; - - chain2 =nf_tables_chain_lookup (table, - nla[NFTA_CHAIN_NAME ], - genmask); -if (IS_ERR (chain2)) -return PTR_ERR (chain2); - } - -if (nla[NFTA_CHAIN_COUNTERS ]) { -if (!nft_is_base_chain (chain)) -return -EOPNOTSUPP ; - - stats =nft_stats_alloc (nla[NFTA_CHAIN_COUNTERS ]); -if (IS_ERR (stats)) -return PTR_ERR (stats); - } -nft_ctx_init (&ctx, net, skb, nlh, afi, table, chain, nla); - trans =nft_trans_alloc (&ctx,NFT_MSG_NEWCHAIN , -sizeof (struct nft_trans_chain )); -if (trans ==NULL ) { -free_percpu (stats); -return -ENOMEM ; - } - -nft_trans_chain_stats (trans) = stats; -nft_trans_chain_update (trans) = true; -if (nla[NFTA_CHAIN_POLICY ]) -nft_trans_chain_policy (trans) = policy; -else -nft_trans_chain_policy (trans) =-1 ; - -if (nla[NFTA_CHAIN_HANDLE ] && name) { -nft_trans_chain_name (trans) = -nla_strdup (name,GFP_KERNEL ); -if (!nft_trans_chain_name (trans)) { -kfree (trans); -free_percpu (stats); -return -ENOMEM ; - } - } -list_add_tail (&trans->list, &net->nft.commit_list); -return 0 ; +return nf_tables_updchain (&ctx, genmask, policy, create); }if (table->use ==UINT_MAX )
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 9/12 netfilter: nf_tables: add nf_tables_addchain()
In reply to Pablo Neira AyusoWrap the chain addition path in a function to make it more maintainable.
--- net/netfilter/nf_tables_api.c | 199 ++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 93 deletions(-)
net/netfilter/nf_tables_api.c +106 -93
@@ -1335,6 +1335,106 @@ static void nft_chain_release_hook(struct nft_chain_hook *hook)dev_put (hook->dev); } +static int nf_tables_addchain (struct nft_ctx *ctx,u8 family,u8 genmask, +u8 policy,bool create) +{ +const struct nlattr *const *nla = ctx->nla; +struct nft_table *table = ctx->table; +struct nft_af_info *afi = ctx->afi; +struct nft_base_chain *basechain; +struct nft_stats __percpu *stats; +struct net *net = ctx->net; +struct nft_chain *chain; +unsigned int i; +int err; + +if (table->use ==UINT_MAX ) +return -EOVERFLOW ; + +if (nla[NFTA_CHAIN_HOOK ]) { +struct nft_chain_hook hook; +struct nf_hook_ops *ops; +nf_hookfn *hookfn; + + err =nft_chain_parse_hook (net, nla, afi, &hook, create); +if (err <0 ) +return err; + + basechain =kzalloc (sizeof (*basechain),GFP_KERNEL ); +if (basechain ==NULL ) { +nft_chain_release_hook (&hook); +return -ENOMEM ; + } + +if (hook.dev !=NULL ) +strncpy (basechain->dev_name, hook.dev->name,IFNAMSIZ ); + +if (nla[NFTA_CHAIN_COUNTERS ]) { + stats =nft_stats_alloc (nla[NFTA_CHAIN_COUNTERS ]); +if (IS_ERR (stats)) { +nft_chain_release_hook (&hook); +kfree (basechain); +return PTR_ERR (stats); + } + basechain->stats = stats; +static_branch_inc (&nft_counters_enabled); + } + + hookfn = hook.type->hooks[hook.num]; + basechain->type = hook.type; + chain = &basechain->chain; + +for (i =0 ; i < afi->nops; i++) { + ops = &basechain->ops[i]; + ops->pf = family; + ops->hooknum = hook.num; + ops->priority = hook.priority; + ops->priv = chain; + ops->hook = afi->hooks[ops->hooknum]; + ops->dev = hook.dev; +if (hookfn) + ops->hook = hookfn; +if (afi->hook_ops_init) + afi->hook_ops_init (ops, i); + } + + chain->flags |=NFT_BASE_CHAIN ; + basechain->policy = policy; + }else { + chain =kzalloc (sizeof (*chain),GFP_KERNEL ); +if (chain ==NULL ) +return -ENOMEM ; + } +INIT_LIST_HEAD (&chain->rules); + chain->handle =nf_tables_alloc_handle (table); + chain->table = table; + chain->name =nla_strdup (nla[NFTA_CHAIN_NAME ],GFP_KERNEL ); +if (!chain->name) { + err = -ENOMEM ; + goto err1; + } + + err =nf_tables_register_hooks (net, table, chain, afi->nops); +if (err <0 ) + goto err1; + + ctx->chain = chain; + err =nft_trans_chain_add (ctx,NFT_MSG_NEWCHAIN ); +if (err <0 ) + goto err2; + + table->use++; +list_add_tail_rcu (&chain->list, &table->chains); + +return 0 ; +err2: +nf_tables_unregister_hooks (net, table, chain, afi->nops); +err1: +nf_tables_chain_destroy (chain); + +return err; +} +static int nf_tables_updchain (struct nft_ctx *ctx,u8 genmask,u8 policy,bool create) {
@@ -1433,19 +1533,15 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, {const struct nfgenmsg *nfmsg =nlmsg_data (nlh);const struct nlattr *uninitialized_var (name ); +u8 genmask =nft_genmask_next (net); +int family = nfmsg->nfgen_family;struct nft_af_info *afi;struct nft_table *table;struct nft_chain *chain; -struct nft_base_chain *basechain =NULL ; -u8 genmask =nft_genmask_next (net); -int family = nfmsg->nfgen_family;u8 policy =NF_ACCEPT ; +struct nft_ctx ctx;u64 handle =0 ; -unsigned int i; -struct nft_stats __percpu *stats; -int err;bool create; -struct nft_ctx ctx; create = nlh->nlmsg_flags &NLM_F_CREATE ? true : false;
@@ -1493,101 +1589,18 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, } } +nft_ctx_init (&ctx, net, skb, nlh, afi, table, chain, nla); +if (chain !=NULL ) {if (nlh->nlmsg_flags &NLM_F_EXCL )return -EEXIST ;if (nlh->nlmsg_flags &NLM_F_REPLACE )return -EOPNOTSUPP ; -nft_ctx_init (&ctx, net, skb, nlh, afi, table, chain, nla); -return nf_tables_updchain (&ctx, genmask, policy, create); } -if (table->use ==UINT_MAX ) -return -EOVERFLOW ; - -if (nla[NFTA_CHAIN_HOOK ]) { -struct nft_chain_hook hook; -struct nf_hook_ops *ops; -nf_hookfn *hookfn; - - err =nft_chain_parse_hook (net, nla, afi, &hook, create); -if (err <0 ) -return err; - - basechain =kzalloc (sizeof (*basechain),GFP_KERNEL ); -if (basechain ==NULL ) { -nft_chain_release_hook (&hook); -return -ENOMEM ; - } - -if (hook.dev !=NULL ) -strncpy (basechain->dev_name, hook.dev->name,IFNAMSIZ ); - -if (nla[NFTA_CHAIN_COUNTERS ]) { - stats =nft_stats_alloc (nla[NFTA_CHAIN_COUNTERS ]); -if (IS_ERR (stats)) { -nft_chain_release_hook (&hook); -kfree (basechain); -return PTR_ERR (stats); - } - basechain->stats = stats; -static_branch_inc (&nft_counters_enabled); - } - - hookfn = hook.type->hooks[hook.num]; - basechain->type = hook.type; - chain = &basechain->chain; - -for (i =0 ; i < afi->nops; i++) { - ops = &basechain->ops[i]; - ops->pf = family; - ops->hooknum = hook.num; - ops->priority = hook.priority; - ops->priv = chain; - ops->hook = afi->hooks[ops->hooknum]; - ops->dev = hook.dev; -if (hookfn) - ops->hook = hookfn; -if (afi->hook_ops_init) - afi->hook_ops_init (ops, i); - } - - chain->flags |=NFT_BASE_CHAIN ; - basechain->policy = policy; - }else { - chain =kzalloc (sizeof (*chain),GFP_KERNEL ); -if (chain ==NULL ) -return -ENOMEM ; - } - -INIT_LIST_HEAD (&chain->rules); - chain->handle =nf_tables_alloc_handle (table); - chain->table = table; - chain->name =nla_strdup (name,GFP_KERNEL ); -if (!chain->name) { - err = -ENOMEM ; - goto err1; - } - - err =nf_tables_register_hooks (net, table, chain, afi->nops); -if (err <0 ) - goto err1; - -nft_ctx_init (&ctx, net, skb, nlh, afi, table, chain, nla); - err =nft_trans_chain_add (&ctx,NFT_MSG_NEWCHAIN ); -if (err <0 ) - goto err2; - - table->use++; -list_add_tail_rcu (&chain->list, &table->chains); -return 0 ; -err2: -nf_tables_unregister_hooks (net, table, chain, afi->nops); -err1: -nf_tables_chain_destroy (chain); -return err; +return nf_tables_addchain (&ctx, family, genmask, policy, create); } static int nf_tables_delchain(struct net *net, struct sock *nlsk,
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 10/12 netlink: add NLM_F_NONREC flag for deletion requests
In reply to Pablo Neira AyusoIn the last NFWS in Faro, Portugal, we discussed that netlink is lacking the semantics to request non recursive deletions, ie. do not delete an object iff it has child objects that hang from this parent object that the user requests to be deleted.
We need this new flag to solve a problem for the iptables-compat backward compatibility utility, that runs iptables commands using the existing nf_tables netlink interface. Specifically, custom chains in iptables cannot be deleted if there are rules in it, however, nf_tables allows to remove any chain that is populated with content. To sort out this asymmetry, iptables-compat userspace sets this new NLM_F_NONREC flag to obtain the same semantics that iptables provides.
This new flag should only be used for deletion requests. Note this new flag value overlaps with the existing:
* NLM_F_ROOT for get requests.
* NLM_F_REPLACE for new requests.
However, those flags should not ever be used in deletion requests.
--- include/uapi/linux/netlink.h | 3 +++ 1 file changed, 3 insertions(+)
include/uapi/linux/netlink.h +3 -0
@@ -69,6 +69,9 @@ struct nlmsghdr {#define NLM_F_CREATE 0x400/* Create, if it does not exist */ #define NLM_F_APPEND 0x800/* Add to end of list */ +/* Modifiers to DELETE request */ +#define NLM_F_NONREC 0x100/* Do not delete recursively */ +/* Flags for ACK message */ #define NLM_F_CAPPED 0x100/* request was capped */ #define NLM_F_ACK_TLVS 0x200/* extended ACK TVLs were included */
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 11/12 netfilter: nf_tables: use NLM_F_NONREC for deletion requests
In reply to Pablo Neira AyusoBail out if user requests non-recursive deletion for tables and sets. This new flags tells nf_tables netlink interface to reject deletions if tables and sets have content.
--- net/netfilter/nf_tables_api.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +7 -1
@@ -860,6 +860,10 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,if (IS_ERR (table))return PTR_ERR (table); +if (nlh->nlmsg_flags &NLM_F_NONREC && + table->use >0 ) +return -EBUSY ; + ctx.afi = afi; ctx.table = table;
@@ -3225,7 +3229,9 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, set =nf_tables_set_lookup (ctx.table, nla[NFTA_SET_NAME ], genmask);if (IS_ERR (set))return PTR_ERR (set); -if (!list_empty (&set->bindings)) + +if (!list_empty (&set->bindings) || + (nlh->nlmsg_flags &NLM_F_NONREC &&atomic_read (&set->nelems) >0 ))return -EBUSY ;return nft_delset (&ctx, set);
Signature · 1 line
2.1.4
Pablo Neira Ayuso
maintainerPATCH 12/12 netfilter: nf_tables: support for recursive chain deletion
In reply to Pablo Neira AyusoThis patch sorts out an asymmetry in deletions. Currently, table and set deletion commands come with an implicit content flush on deletion. However, chain deletion results in -EBUSY if there is content in this chain, so no implicit flush happens. So you have to send a flush command in first place to delete chains, this is inconsistent and it can be annoying in terms of user experience.
This patch uses the new NLM_F_NONREC flag to request non-recursive chain deletion, ie. if the chain to be removed contains rules, then this returns EBUSY. This problem was discussed during the NFWS'17 in Faro, Portugal. In iptables, you hit -EBUSY if you try to delete a chain that contains rules, so you have to flush first before you can remove anything. Since iptables-compat uses the nf_tables netlink interface, it has to use the NLM_F_NONREC flag from userspace to retain the original iptables semantics, ie. bail out on removing chains that contain rules.
--- net/netfilter/nf_tables_api.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +23 -1
@@ -1617,8 +1617,11 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,struct nft_af_info *afi;struct nft_table *table;struct nft_chain *chain; +struct nft_rule *rule;int family = nfmsg->nfgen_family;struct nft_ctx ctx; +u32 use; +int err; afi =nf_tables_afinfo_lookup (net, family, false);if (IS_ERR (afi))
@@ -1631,11 +1634,30 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, chain =nf_tables_chain_lookup (table, nla[NFTA_CHAIN_NAME ], genmask);if (IS_ERR (chain))return PTR_ERR (chain); -if (chain->use >0 ) + +if (nlh->nlmsg_flags &NLM_F_NONREC && + chain->use >0 )return -EBUSY ;nft_ctx_init (&ctx, net, skb, nlh, afi, table, chain, nla); + use = chain->use; +list_for_each_entry (rule, &chain->rules, list) { +if (!nft_is_active_next (net, rule)) +continue ; + use--; + + err =nft_delrule (&ctx, rule); +if (err <0 ) +return err; + } + +/* There are rules and elements that are still holding references to us, +* we cannot do a recursive removal in this case. +*/ +if (use >0 ) +return -EBUSY ; +return nft_delchain (&ctx); }
Signature · 1 line
2.1.4
David Miller
maintainerFrom: Pablo Neira Ayuso <[email protected]>
Date: Mon, 4 Sep 2017 22:11:02 +0200
Quoted 4 lines
The following patchset contains Netfilter updates for net-next. This patchset includes updates for
nf_tables, removal ofCONFIG_NETFILTER_DEBUGand a new mode forxt_hashlimit. More specifically, they:
Pulled, thanks.
Since there wasn't much review on netdev for the NONREC stuff I reserve the right to revert if serious objections are raised.
Thanks.