Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== netfilter fixes for net The following patchset contains netfilter updates for your net tree, they are: 1) Fix refcount leak when dumping the dying/unconfirmed conntrack lists, from Florian Westphal. 2) Fix crash in NAT when removing a netnamespace, also from Florian. 3) Fix a crash in IPVS when trying to remove an estimator out of the sysctl scope, from Julian Anastasov. 4) Add zone attribute to the routing to calculate the message size in ctnetlink events, from Ken-ichirou MATSUZAWA. 5) Another fix for the dying/unconfirmed list which was preventing to dump more than one memory page of entries (~17 entries in x86_64). 6) Fix missing RCU-safe list insertion in the rule replacement code in nf_tables. 7) Since the new transaction infrastructure is in place, we have to upgrade the chain use counter from u16 to u32 to avoid overflow after more than 2^16 rules are added. 8) Fix refcount leak when replacing rule in nf_tables. This problem was also introduced in new transaction. 9) Call the ->destroy() callback when releasing nft-xt rules to fix module refcount leaks. 10) Set the family in the netlink messages that contain set elements in nf_tables to make it consistent with other object types. 11) Don't dump NAT port information if it is unset in nft_nat. 12) Update the MAINTAINERS file, I have merged the ebtables entry into netfilter. While at it, also removed the netfilter users mailing list, the development list should be enough. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3a3ec1b2ba
11
MAINTAINERS
11
MAINTAINERS
|
@ -3189,14 +3189,6 @@ L: linux-scsi@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/scsi/eata_pio.*
|
||||
|
||||
EBTABLES
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
W: http://ebtables.sourceforge.net/
|
||||
S: Orphan
|
||||
F: include/linux/netfilter_bridge/ebt_*.h
|
||||
F: include/uapi/linux/netfilter_bridge/ebt_*.h
|
||||
F: net/bridge/netfilter/ebt*.c
|
||||
|
||||
EC100 MEDIA DRIVER
|
||||
M: Antti Palosaari <crope@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -6105,12 +6097,11 @@ F: Documentation/networking/s2io.txt
|
|||
F: Documentation/networking/vxge.txt
|
||||
F: drivers/net/ethernet/neterion/
|
||||
|
||||
NETFILTER/IPTABLES
|
||||
NETFILTER ({IP,IP6,ARP,EB,NF}TABLES)
|
||||
M: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
M: Patrick McHardy <kaber@trash.net>
|
||||
M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
L: netfilter@vger.kernel.org
|
||||
L: coreteam@netfilter.org
|
||||
W: http://www.netfilter.org/
|
||||
W: http://www.iptables.org/
|
||||
|
|
|
@ -503,9 +503,9 @@ enum nft_chain_flags {
|
|||
* @net: net namespace that this chain belongs to
|
||||
* @table: table that this chain belongs to
|
||||
* @handle: chain handle
|
||||
* @flags: bitmask of enum nft_chain_flags
|
||||
* @use: number of jump references to this chain
|
||||
* @level: length of longest path to this chain
|
||||
* @flags: bitmask of enum nft_chain_flags
|
||||
* @name: name of the chain
|
||||
*/
|
||||
struct nft_chain {
|
||||
|
@ -514,9 +514,9 @@ struct nft_chain {
|
|||
struct net *net;
|
||||
struct nft_table *table;
|
||||
u64 handle;
|
||||
u8 flags;
|
||||
u16 use;
|
||||
u32 use;
|
||||
u16 level;
|
||||
u8 flags;
|
||||
char name[NFT_CHAIN_MAXNAMELEN];
|
||||
};
|
||||
|
||||
|
|
|
@ -3778,6 +3778,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
|
|||
cancel_delayed_work_sync(&ipvs->defense_work);
|
||||
cancel_work_sync(&ipvs->defense_work.work);
|
||||
unregister_net_sysctl_table(ipvs->sysctl_hdr);
|
||||
ip_vs_stop_estimator(net, &ipvs->tot_stats);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -3840,7 +3841,6 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
|
|||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
ip_vs_trash_cleanup(net);
|
||||
ip_vs_stop_estimator(net, &ipvs->tot_stats);
|
||||
ip_vs_control_net_cleanup_sysctl(net);
|
||||
remove_proc_entry("ip_vs_stats_percpu", net->proc_net);
|
||||
remove_proc_entry("ip_vs_stats", net->proc_net);
|
||||
|
|
|
@ -596,6 +596,9 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
|
|||
#endif
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
+ nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
|
||||
#endif
|
||||
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||
+ nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
|
||||
#endif
|
||||
+ ctnetlink_proto_size(ct)
|
||||
+ ctnetlink_label_size(ct)
|
||||
|
@ -1150,7 +1153,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
|
|||
static int
|
||||
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
|
||||
{
|
||||
struct nf_conn *ct, *last = NULL;
|
||||
struct nf_conn *ct, *last;
|
||||
struct nf_conntrack_tuple_hash *h;
|
||||
struct hlist_nulls_node *n;
|
||||
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
|
||||
|
@ -1163,8 +1166,7 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
|
|||
if (cb->args[2])
|
||||
return 0;
|
||||
|
||||
if (cb->args[0] == nr_cpu_ids)
|
||||
return 0;
|
||||
last = (struct nf_conn *)cb->args[1];
|
||||
|
||||
for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
|
||||
struct ct_pcpu *pcpu;
|
||||
|
@ -1174,7 +1176,6 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
|
|||
|
||||
pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
|
||||
spin_lock_bh(&pcpu->lock);
|
||||
last = (struct nf_conn *)cb->args[1];
|
||||
list = dying ? &pcpu->dying : &pcpu->unconfirmed;
|
||||
restart:
|
||||
hlist_nulls_for_each_entry(h, n, list, hnnode) {
|
||||
|
@ -1193,7 +1194,9 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
|
|||
ct);
|
||||
rcu_read_unlock();
|
||||
if (res < 0) {
|
||||
nf_conntrack_get(&ct->ct_general);
|
||||
if (!atomic_inc_not_zero(&ct->ct_general.use))
|
||||
continue;
|
||||
cb->args[0] = cpu;
|
||||
cb->args[1] = (unsigned long)ct;
|
||||
spin_unlock_bh(&pcpu->lock);
|
||||
goto out;
|
||||
|
@ -1202,10 +1205,10 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
|
|||
if (cb->args[1]) {
|
||||
cb->args[1] = 0;
|
||||
goto restart;
|
||||
} else
|
||||
cb->args[2] = 1;
|
||||
}
|
||||
spin_unlock_bh(&pcpu->lock);
|
||||
}
|
||||
cb->args[2] = 1;
|
||||
out:
|
||||
if (last)
|
||||
nf_ct_put(last);
|
||||
|
@ -2039,6 +2042,9 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
|
|||
#endif
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
+ nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
|
||||
#endif
|
||||
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||
+ nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
|
||||
#endif
|
||||
+ ctnetlink_proto_size(ct)
|
||||
;
|
||||
|
|
|
@ -525,6 +525,39 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data)
|
|||
return i->status & IPS_NAT_MASK ? 1 : 0;
|
||||
}
|
||||
|
||||
static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
|
||||
{
|
||||
struct nf_conn_nat *nat = nfct_nat(ct);
|
||||
|
||||
if (nf_nat_proto_remove(ct, data))
|
||||
return 1;
|
||||
|
||||
if (!nat || !nat->ct)
|
||||
return 0;
|
||||
|
||||
/* This netns is being destroyed, and conntrack has nat null binding.
|
||||
* Remove it from bysource hash, as the table will be freed soon.
|
||||
*
|
||||
* Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
|
||||
* will delete entry from already-freed table.
|
||||
*/
|
||||
if (!del_timer(&ct->timeout))
|
||||
return 1;
|
||||
|
||||
spin_lock_bh(&nf_nat_lock);
|
||||
hlist_del_rcu(&nat->bysource);
|
||||
ct->status &= ~IPS_NAT_DONE_MASK;
|
||||
nat->ct = NULL;
|
||||
spin_unlock_bh(&nf_nat_lock);
|
||||
|
||||
add_timer(&ct->timeout);
|
||||
|
||||
/* don't delete conntrack. Although that would make things a lot
|
||||
* simpler, we'd end up flushing all conntracks on nat rmmod.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
|
||||
{
|
||||
struct nf_nat_proto_clean clean = {
|
||||
|
@ -795,7 +828,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
|
|||
{
|
||||
struct nf_nat_proto_clean clean = {};
|
||||
|
||||
nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
|
||||
nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
|
||||
synchronize_rcu();
|
||||
nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
|
||||
}
|
||||
|
|
|
@ -1730,6 +1730,9 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
|
|||
if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
|
||||
return -EINVAL;
|
||||
handle = nf_tables_alloc_handle(table);
|
||||
|
||||
if (chain->use == UINT_MAX)
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
if (nla[NFTA_RULE_POSITION]) {
|
||||
|
@ -1789,14 +1792,15 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
|
|||
|
||||
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
|
||||
if (nft_rule_is_active_next(net, old_rule)) {
|
||||
trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE,
|
||||
trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
|
||||
old_rule);
|
||||
if (trans == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
nft_rule_disactivate_next(net, old_rule);
|
||||
list_add_tail(&rule->list, &old_rule->list);
|
||||
chain->use--;
|
||||
list_add_tail_rcu(&rule->list, &old_rule->list);
|
||||
} else {
|
||||
err = -ENOENT;
|
||||
goto err2;
|
||||
|
@ -1826,6 +1830,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
|
|||
list_del_rcu(&nft_trans_rule(trans)->list);
|
||||
nft_rule_clear(net, nft_trans_rule(trans));
|
||||
nft_trans_destroy(trans);
|
||||
chain->use++;
|
||||
}
|
||||
err2:
|
||||
nf_tables_rule_destroy(&ctx, rule);
|
||||
|
@ -2845,7 +2850,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
goto nla_put_failure;
|
||||
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = NFPROTO_UNSPEC;
|
||||
nfmsg->nfgen_family = ctx.afi->family;
|
||||
nfmsg->version = NFNETLINK_V0;
|
||||
nfmsg->res_id = 0;
|
||||
|
||||
|
|
|
@ -195,6 +195,15 @@ static void
|
|||
nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
|
||||
{
|
||||
struct xt_target *target = expr->ops->data;
|
||||
void *info = nft_expr_priv(expr);
|
||||
struct xt_tgdtor_param par;
|
||||
|
||||
par.net = ctx->net;
|
||||
par.target = target;
|
||||
par.targinfo = info;
|
||||
par.family = ctx->afi->family;
|
||||
if (par.target->destroy != NULL)
|
||||
par.target->destroy(&par);
|
||||
|
||||
module_put(target->me);
|
||||
}
|
||||
|
@ -382,6 +391,15 @@ static void
|
|||
nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
|
||||
{
|
||||
struct xt_match *match = expr->ops->data;
|
||||
void *info = nft_expr_priv(expr);
|
||||
struct xt_mtdtor_param par;
|
||||
|
||||
par.net = ctx->net;
|
||||
par.match = match;
|
||||
par.matchinfo = info;
|
||||
par.family = ctx->afi->family;
|
||||
if (par.match->destroy != NULL)
|
||||
par.match->destroy(&par);
|
||||
|
||||
module_put(match->me);
|
||||
}
|
||||
|
|
|
@ -175,12 +175,14 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
|||
if (nla_put_be32(skb,
|
||||
NFTA_NAT_REG_ADDR_MAX, htonl(priv->sreg_addr_max)))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_be32(skb,
|
||||
NFTA_NAT_REG_PROTO_MIN, htonl(priv->sreg_proto_min)))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_be32(skb,
|
||||
NFTA_NAT_REG_PROTO_MAX, htonl(priv->sreg_proto_max)))
|
||||
goto nla_put_failure;
|
||||
if (priv->sreg_proto_min) {
|
||||
if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN,
|
||||
htonl(priv->sreg_proto_min)))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX,
|
||||
htonl(priv->sreg_proto_max)))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
|
|
Loading…
Reference in New Issue