* [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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).