* [PATCH 0/4] netfilter: minor cleanups and improvements
@ 2014-02-18 18:06 Patrick McHardy
2014-02-18 18:06 ` [PATCH 1/4] netfilter: ip_set: rename nfnl_dereference()/nfnl_set() Patrick McHardy
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Patrick McHardy @ 2014-02-18 18:06 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
The following four patches have been sitting in my tree for a while, I
need them as preconditions for following patches, but they also make
sense on their own, so I'd like to get rid of them.
The second patch adds a nfnl_dereference() helper, which is a wrapper
around rcu_dereference_protected() that checks that the nfnetlink
subsys mutex is actually held. This is similar to rtnl_dereference()
except that we need to check subsys-specific mutexes.
The first patch renamed a similar named ip_set function, the third patch
introduces a nft_dereference() macro that is to be used in nftables.
The fourth patch is unrelated to this, it changes verdict validation in
nftables to accept flags to NF_QUEUE or errno codes to NF_DROP.
Please apply.
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/4] netfilter: ip_set: rename nfnl_dereference()/nfnl_set() 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy @ 2014-02-18 18:06 ` Patrick McHardy 2014-02-18 18:06 ` [PATCH 2/4] netfilter: nfnetlink: add rcu_dereference_protected() helpers Patrick McHardy ` (3 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Patrick McHardy @ 2014-02-18 18:06 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel The next patch will introduce a nfnl_dereference() macro that actually checks that the appropriate mutex is held and therefore needs a subsystem argument. Signed-off-by: Patrick McHardy <kaber@trash.net> --- net/netfilter/ipset/ip_set_core.c | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index de770ec..728a2cf 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -54,10 +54,10 @@ MODULE_DESCRIPTION("core IP set support"); MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); /* When the nfnl mutex is held: */ -#define nfnl_dereference(p) \ +#define ip_set_dereference(p) \ rcu_dereference_protected(p, 1) -#define nfnl_set(inst, id) \ - nfnl_dereference((inst)->ip_set_list)[id] +#define ip_set(inst, id) \ + ip_set_dereference((inst)->ip_set_list)[id] /* * The set types are implemented in modules and registered set types @@ -640,7 +640,7 @@ ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index) return IPSET_INVALID_ID; nfnl_lock(NFNL_SUBSYS_IPSET); - set = nfnl_set(inst, index); + set = ip_set(inst, index); if (set) __ip_set_get(set); else @@ -666,7 +666,7 @@ ip_set_nfnl_put(struct net *net, ip_set_id_t index) nfnl_lock(NFNL_SUBSYS_IPSET); if (!inst->is_deleted) { /* already deleted from ip_set_net_exit() */ - set = nfnl_set(inst, index); + set = ip_set(inst, index); if (set != NULL) __ip_set_put(set); } @@ -734,7 +734,7 @@ find_set_and_id(struct ip_set_net *inst, const char *name, ip_set_id_t *id) *id = IPSET_INVALID_ID; for (i = 0; i < inst->ip_set_max; i++) { - set = nfnl_set(inst, i); + set = ip_set(inst, i); if (set != NULL && STREQ(set->name, name)) { *id = i; break; @@ -760,7 +760,7 @@ find_free_id(struct ip_set_net *inst, const char *name, ip_set_id_t *index, *index = IPSET_INVALID_ID; for (i = 0; i < inst->ip_set_max; i++) { - s = nfnl_set(inst, i); + s = ip_set(inst, i); if (s == NULL) { if (*index == IPSET_INVALID_ID) *index = i; @@ -883,7 +883,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, if (!list) goto cleanup; /* nfnl mutex is held, both lists are valid */ - tmp = nfnl_dereference(inst->ip_set_list); + tmp = ip_set_dereference(inst->ip_set_list); memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max); rcu_assign_pointer(inst->ip_set_list, list); /* Make sure all current packets have passed through */ @@ -900,7 +900,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, * Finally! Add our shiny new set to the list, and be done. */ pr_debug("create: '%s' created with index %u!\n", set->name, index); - nfnl_set(inst, index) = set; + ip_set(inst, index) = set; return ret; @@ -925,10 +925,10 @@ ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = { static void ip_set_destroy_set(struct ip_set_net *inst, ip_set_id_t index) { - struct ip_set *set = nfnl_set(inst, index); + struct ip_set *set = ip_set(inst, index); pr_debug("set: %s\n", set->name); - nfnl_set(inst, index) = NULL; + ip_set(inst, index) = NULL; /* Must call it without holding any lock */ set->variant->destroy(set); @@ -962,7 +962,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, read_lock_bh(&ip_set_ref_lock); if (!attr[IPSET_ATTR_SETNAME]) { for (i = 0; i < inst->ip_set_max; i++) { - s = nfnl_set(inst, i); + s = ip_set(inst, i); if (s != NULL && s->ref) { ret = -IPSET_ERR_BUSY; goto out; @@ -970,7 +970,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, } read_unlock_bh(&ip_set_ref_lock); for (i = 0; i < inst->ip_set_max; i++) { - s = nfnl_set(inst, i); + s = ip_set(inst, i); if (s != NULL) ip_set_destroy_set(inst, i); } @@ -1020,7 +1020,7 @@ ip_set_flush(struct sock *ctnl, struct sk_buff *skb, if (!attr[IPSET_ATTR_SETNAME]) { for (i = 0; i < inst->ip_set_max; i++) { - s = nfnl_set(inst, i); + s = ip_set(inst, i); if (s != NULL) ip_set_flush_set(s); } @@ -1074,7 +1074,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb, name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); for (i = 0; i < inst->ip_set_max; i++) { - s = nfnl_set(inst, i); + s = ip_set(inst, i); if (s != NULL && STREQ(s->name, name2)) { ret = -IPSET_ERR_EXIST_SETNAME2; goto out; @@ -1134,8 +1134,8 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, write_lock_bh(&ip_set_ref_lock); swap(from->ref, to->ref); - nfnl_set(inst, from_id) = to; - nfnl_set(inst, to_id) = from; + ip_set(inst, from_id) = to; + ip_set(inst, to_id) = from; write_unlock_bh(&ip_set_ref_lock); return 0; @@ -1157,7 +1157,7 @@ ip_set_dump_done(struct netlink_callback *cb) struct ip_set_net *inst = (struct ip_set_net *)cb->args[IPSET_CB_NET]; if (cb->args[IPSET_CB_ARG0]) { pr_debug("release set %s\n", - nfnl_set(inst, cb->args[IPSET_CB_INDEX])->name); + ip_set(inst, cb->args[IPSET_CB_INDEX])->name); __ip_set_put_byindex(inst, (ip_set_id_t) cb->args[IPSET_CB_INDEX]); } @@ -1254,7 +1254,7 @@ dump_last: dump_type, dump_flags, cb->args[IPSET_CB_INDEX]); for (; cb->args[IPSET_CB_INDEX] < max; cb->args[IPSET_CB_INDEX]++) { index = (ip_set_id_t) cb->args[IPSET_CB_INDEX]; - set = nfnl_set(inst, index); + set = ip_set(inst, index); if (set == NULL) { if (dump_type == DUMP_ONE) { ret = -ENOENT; @@ -1332,7 +1332,7 @@ next_set: release_refcount: /* If there was an error or set is done, release set */ if (ret || !cb->args[IPSET_CB_ARG0]) { - pr_debug("release set %s\n", nfnl_set(inst, index)->name); + pr_debug("release set %s\n", ip_set(inst, index)->name); __ip_set_put_byindex(inst, index); cb->args[IPSET_CB_ARG0] = 0; } @@ -1887,7 +1887,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) find_set_and_id(inst, req_get->set.name, &id); req_get->set.index = id; if (id != IPSET_INVALID_ID) - req_get->family = nfnl_set(inst, id)->family; + req_get->family = ip_set(inst, id)->family; nfnl_unlock(NFNL_SUBSYS_IPSET); goto copy; } @@ -1901,7 +1901,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) goto done; } nfnl_lock(NFNL_SUBSYS_IPSET); - set = nfnl_set(inst, req_get->set.index); + set = ip_set(inst, req_get->set.index); strncpy(req_get->set.name, set ? set->name : "", IPSET_MAXNAMELEN); nfnl_unlock(NFNL_SUBSYS_IPSET); @@ -1960,7 +1960,7 @@ ip_set_net_exit(struct net *net) inst->is_deleted = 1; /* flag for ip_set_nfnl_put */ for (i = 0; i < inst->ip_set_max; i++) { - set = nfnl_set(inst, i); + set = ip_set(inst, i); if (set != NULL) ip_set_destroy_set(inst, i); } -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] netfilter: nfnetlink: add rcu_dereference_protected() helpers 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy 2014-02-18 18:06 ` [PATCH 1/4] netfilter: ip_set: rename nfnl_dereference()/nfnl_set() Patrick McHardy @ 2014-02-18 18:06 ` Patrick McHardy 2014-02-18 18:06 ` [PATCH 3/4] netfilter: nf_tables: add nft_dereference() macro Patrick McHardy ` (2 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Patrick McHardy @ 2014-02-18 18:06 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel Add a lockdep_nfnl_is_held() function and a nfnl_dereference() macro for RCU dereferences protected by a NFNL subsystem mutex. Signed-off-by: Patrick McHardy <kaber@trash.net> --- include/linux/netfilter/nfnetlink.h | 21 +++++++++++++++++++++ net/netfilter/nfnetlink.c | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 28c7436..e955d47 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -44,6 +44,27 @@ int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u32 portid, void nfnl_lock(__u8 subsys_id); void nfnl_unlock(__u8 subsys_id); +#ifdef CONFIG_PROVE_LOCKING +int lockdep_nfnl_is_held(__u8 subsys_id); +#else +static inline int lockdep_nfnl_is_held(__u8 subsys_id) +{ + return 1; +} +#endif /* CONFIG_PROVE_LOCKING */ + +/* + * nfnl_dereference - fetch RCU pointer when updates are prevented by subsys mutex + * + * @p: The pointer to read, prior to dereferencing + * @ss: The nfnetlink subsystem ID + * + * Return the value of the specified RCU-protected pointer, but omit + * both the smp_read_barrier_depends() and the ACCESS_ONCE(), because + * caller holds the NFNL subsystem mutex. + */ +#define nfnl_dereference(p, ss) \ + rcu_dereference_protected(p, lockdep_nfnl_is_held(ss)) #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 046aa13..e8138da 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -61,6 +61,14 @@ void nfnl_unlock(__u8 subsys_id) } EXPORT_SYMBOL_GPL(nfnl_unlock); +#ifdef CONFIG_PROVE_LOCKING +int lockdep_nfnl_is_held(u8 subsys_id) +{ + return lockdep_is_held(&table[subsys_id].mutex); +} +EXPORT_SYMBOL_GPL(lockdep_nfnl_is_held); +#endif + int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) { nfnl_lock(n->subsys_id); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] netfilter: nf_tables: add nft_dereference() macro 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy 2014-02-18 18:06 ` [PATCH 1/4] netfilter: ip_set: rename nfnl_dereference()/nfnl_set() Patrick McHardy 2014-02-18 18:06 ` [PATCH 2/4] netfilter: nfnetlink: add rcu_dereference_protected() helpers Patrick McHardy @ 2014-02-18 18:06 ` Patrick McHardy 2014-02-18 18:06 ` [PATCH 4/4] netfilter: nf_tables: accept QUEUE/DROP verdict parameters Patrick McHardy 2014-02-25 16:44 ` [PATCH 0/4] netfilter: minor cleanups and improvements Pablo Neira Ayuso 4 siblings, 0 replies; 6+ messages in thread From: Patrick McHardy @ 2014-02-18 18:06 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel Signed-off-by: Patrick McHardy <kaber@trash.net> --- include/net/netfilter/nf_tables.h | 4 ++++ net/netfilter/nf_tables_api.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index e7e14ff..81abd61 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -3,6 +3,7 @@ #include <linux/list.h> #include <linux/netfilter.h> +#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/nf_tables.h> #include <net/netlink.h> @@ -521,6 +522,9 @@ void nft_unregister_chain_type(const struct nf_chain_type *); int nft_register_expr(struct nft_expr_type *); void nft_unregister_expr(struct nft_expr_type *); +#define nft_dereference(p) \ + nfnl_dereference(p, NFNL_SUBSYS_NFTABLES) + #define MODULE_ALIAS_NFT_FAMILY(family) \ MODULE_ALIAS("nft-afinfo-" __stringify(family)) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index adce01e..4b7e14d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -794,9 +794,8 @@ nf_tables_counters(struct nft_base_chain *chain, const struct nlattr *attr) stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS])); if (chain->stats) { - /* nfnl_lock is held, add some nfnl function for this, later */ struct nft_stats __percpu *oldstats = - rcu_dereference_protected(chain->stats, 1); + nft_dereference(chain->stats); rcu_assign_pointer(chain->stats, newstats); synchronize_rcu(); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] netfilter: nf_tables: accept QUEUE/DROP verdict parameters 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy ` (2 preceding siblings ...) 2014-02-18 18:06 ` [PATCH 3/4] netfilter: nf_tables: add nft_dereference() macro Patrick McHardy @ 2014-02-18 18:06 ` Patrick McHardy 2014-02-25 16:44 ` [PATCH 0/4] netfilter: minor cleanups and improvements Pablo Neira Ayuso 4 siblings, 0 replies; 6+ messages in thread From: Patrick McHardy @ 2014-02-18 18:06 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel Allow userspace to specify the queue number or the errno code for QUEUE and DROP verdicts. Signed-off-by: Patrick McHardy <kaber@trash.net> --- net/netfilter/nf_tables_api.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 4b7e14d..0b56340 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3174,9 +3174,16 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); switch (data->verdict) { - case NF_ACCEPT: - case NF_DROP: - case NF_QUEUE: + default: + switch (data->verdict & NF_VERDICT_MASK) { + case NF_ACCEPT: + case NF_DROP: + case NF_QUEUE: + break; + default: + return -EINVAL; + } + /* fall through */ case NFT_CONTINUE: case NFT_BREAK: case NFT_RETURN: @@ -3197,8 +3204,6 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, data->chain = chain; desc->len = sizeof(data); break; - default: - return -EINVAL; } desc->type = NFT_DATA_VERDICT; -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] netfilter: minor cleanups and improvements 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy ` (3 preceding siblings ...) 2014-02-18 18:06 ` [PATCH 4/4] netfilter: nf_tables: accept QUEUE/DROP verdict parameters Patrick McHardy @ 2014-02-25 16:44 ` Pablo Neira Ayuso 4 siblings, 0 replies; 6+ messages in thread From: Pablo Neira Ayuso @ 2014-02-25 16:44 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Tue, Feb 18, 2014 at 06:06:46PM +0000, Patrick McHardy wrote: > The following four patches have been sitting in my tree for a while, I > need them as preconditions for following patches, but they also make > sense on their own, so I'd like to get rid of them. > > The second patch adds a nfnl_dereference() helper, which is a wrapper > around rcu_dereference_protected() that checks that the nfnetlink > subsys mutex is actually held. This is similar to rtnl_dereference() > except that we need to check subsys-specific mutexes. > > The first patch renamed a similar named ip_set function, the third patch > introduces a nft_dereference() macro that is to be used in nftables. > > The fourth patch is unrelated to this, it changes verdict validation in > nftables to accept flags to NF_QUEUE or errno codes to NF_DROP. > > Please apply. Applied, thanks! ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-02-25 16:44 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-02-18 18:06 [PATCH 0/4] netfilter: minor cleanups and improvements Patrick McHardy 2014-02-18 18:06 ` [PATCH 1/4] netfilter: ip_set: rename nfnl_dereference()/nfnl_set() Patrick McHardy 2014-02-18 18:06 ` [PATCH 2/4] netfilter: nfnetlink: add rcu_dereference_protected() helpers Patrick McHardy 2014-02-18 18:06 ` [PATCH 3/4] netfilter: nf_tables: add nft_dereference() macro Patrick McHardy 2014-02-18 18:06 ` [PATCH 4/4] netfilter: nf_tables: accept QUEUE/DROP verdict parameters Patrick McHardy 2014-02-25 16:44 ` [PATCH 0/4] netfilter: minor cleanups and improvements 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.