Commit 4696ad36 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for net-next:

1) Replace unnecessary list_for_each_entry_continue() in nf_tables,
   from Jakob Koschel.

2) Add struct nf_conntrack_net_ecache to conntrack event cache and
   use it, from Florian Westphal.

3) Refactor ctnetlink_dump_list(), also from Florian.

4) Bump module reference counter on cttimeout object addition/removal,
   from Florian.

5) Consolidate nf_log MAC printer, from Phil Sutter.

6) Add basic logging support for unknown ethertype, from Phil Sutter.

7) Consolidate check for sysctl nf_log_all_netns toggle, also from Phil.

8) Replace hardcode value in nft_bitwise, from Jeremy Sowden.

9) Rename BASIC-like goto tags in nft_bitwise to more meaningful names,
   also from Jeremy.

10) nft_fib support for reverse path filtering with policy-based routing
    on iif. Extend selftests to cover for this new usecase, from Florian.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a21437d2 0c7b2761
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@ union nf_conntrack_expect_proto {
	/* insert expect proto private data here */
};

struct nf_conntrack_net_ecache {
	struct delayed_work dwork;
	struct netns_ct *ct_net;
};

struct nf_conntrack_net {
	/* only used when new connection is allocated: */
	atomic_t count;
@@ -58,8 +63,7 @@ struct nf_conntrack_net {
	struct ctl_table_header	*sysctl_header;
#endif
#ifdef CONFIG_NF_CONNTRACK_EVENTS
	struct delayed_work ecache_dwork;
	struct netns_ct *ct_net;
	struct nf_conntrack_net_ecache ecache;
#endif
};

+4 −0
Original line number Diff line number Diff line
@@ -112,6 +112,10 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
		fl4.daddr = iph->daddr;
		fl4.saddr = get_saddr(iph->saddr);
	} else {
		if (nft_hook(pkt) == NF_INET_FORWARD &&
		    priv->flags & NFTA_FIB_F_IIF)
			fl4.flowi4_iif = nft_out(pkt)->ifindex;

		fl4.daddr = iph->saddr;
		fl4.saddr = get_saddr(iph->daddr);
	}
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
		fl6->daddr = iph->daddr;
		fl6->saddr = iph->saddr;
	} else {
		if (nft_hook(pkt) == NF_INET_FORWARD &&
		    priv->flags & NFTA_FIB_F_IIF)
			fl6->flowi6_iif = nft_out(pkt)->ifindex;

		fl6->daddr = iph->saddr;
		fl6->saddr = iph->daddr;
	}
+10 −9
Original line number Diff line number Diff line
@@ -96,8 +96,8 @@ static enum retry_state ecache_work_evict_list(struct ct_pcpu *pcpu)

static void ecache_work(struct work_struct *work)
{
	struct nf_conntrack_net *cnet = container_of(work, struct nf_conntrack_net, ecache_dwork.work);
	struct netns_ct *ctnet = cnet->ct_net;
	struct nf_conntrack_net *cnet = container_of(work, struct nf_conntrack_net, ecache.dwork.work);
	struct netns_ct *ctnet = cnet->ecache.ct_net;
	int cpu, delay = -1;
	struct ct_pcpu *pcpu;

@@ -127,7 +127,7 @@ static void ecache_work(struct work_struct *work)

	ctnet->ecache_dwork_pending = delay > 0;
	if (delay >= 0)
		schedule_delayed_work(&cnet->ecache_dwork, delay);
		schedule_delayed_work(&cnet->ecache.dwork, delay);
}

static int __nf_conntrack_eventmask_report(struct nf_conntrack_ecache *e,
@@ -293,12 +293,12 @@ void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state)
	struct nf_conntrack_net *cnet = nf_ct_pernet(net);

	if (state == NFCT_ECACHE_DESTROY_FAIL &&
	    !delayed_work_pending(&cnet->ecache_dwork)) {
		schedule_delayed_work(&cnet->ecache_dwork, HZ);
	    !delayed_work_pending(&cnet->ecache.dwork)) {
		schedule_delayed_work(&cnet->ecache.dwork, HZ);
		net->ct.ecache_dwork_pending = true;
	} else if (state == NFCT_ECACHE_DESTROY_SENT) {
		net->ct.ecache_dwork_pending = false;
		mod_delayed_work(system_wq, &cnet->ecache_dwork, 0);
		mod_delayed_work(system_wq, &cnet->ecache.dwork, 0);
	}
}

@@ -310,8 +310,9 @@ void nf_conntrack_ecache_pernet_init(struct net *net)
	struct nf_conntrack_net *cnet = nf_ct_pernet(net);

	net->ct.sysctl_events = nf_ct_events;
	cnet->ct_net = &net->ct;
	INIT_DELAYED_WORK(&cnet->ecache_dwork, ecache_work);

	cnet->ecache.ct_net = &net->ct;
	INIT_DELAYED_WORK(&cnet->ecache.dwork, ecache_work);

	BUILD_BUG_ON(__IPCT_MAX >= 16);	/* e->ctmask is u16 */
}
@@ -320,5 +321,5 @@ void nf_conntrack_ecache_pernet_fini(struct net *net)
{
	struct nf_conntrack_net *cnet = nf_ct_pernet(net);

	cancel_delayed_work_sync(&cnet->ecache_dwork);
	cancel_delayed_work_sync(&cnet->ecache.dwork);
}
+43 −25
Original line number Diff line number Diff line
@@ -1708,6 +1708,47 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
	return 0;
}

static int ctnetlink_dump_one_entry(struct sk_buff *skb,
				    struct netlink_callback *cb,
				    struct nf_conn *ct,
				    bool dying)
{
	struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
	struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
	u8 l3proto = nfmsg->nfgen_family;
	int res;

	if (l3proto && nf_ct_l3num(ct) != l3proto)
		return 0;

	if (ctx->last) {
		if (ct != ctx->last)
			return 0;

		ctx->last = NULL;
	}

	/* We can't dump extension info for the unconfirmed
	 * list because unconfirmed conntracks can have
	 * ct->ext reallocated (and thus freed).
	 *
	 * In the dying list case ct->ext can't be free'd
	 * until after we drop pcpu->lock.
	 */
	res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
				  cb->nlh->nlmsg_seq,
				  NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
				  ct, dying, 0);
	if (res < 0) {
		if (!refcount_inc_not_zero(&ct->ct_general.use))
			return 0;

		ctx->last = ct;
	}

	return res;
}

static int
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
{
@@ -1715,12 +1756,9 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
	struct nf_conn *ct, *last;
	struct nf_conntrack_tuple_hash *h;
	struct hlist_nulls_node *n;
	struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
	u_int8_t l3proto = nfmsg->nfgen_family;
	int res;
	int cpu;
	struct hlist_nulls_head *list;
	struct net *net = sock_net(skb->sk);
	int res, cpu;

	if (ctx->done)
		return 0;
@@ -1739,30 +1777,10 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
restart:
		hlist_nulls_for_each_entry(h, n, list, hnnode) {
			ct = nf_ct_tuplehash_to_ctrack(h);
			if (l3proto && nf_ct_l3num(ct) != l3proto)
				continue;
			if (ctx->last) {
				if (ct != last)
					continue;
				ctx->last = NULL;
			}

			/* We can't dump extension info for the unconfirmed
			 * list because unconfirmed conntracks can have
			 * ct->ext reallocated (and thus freed).
			 *
			 * In the dying list case ct->ext can't be free'd
			 * until after we drop pcpu->lock.
			 */
			res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
						  cb->nlh->nlmsg_seq,
						  NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
						  ct, dying, 0);
			res = ctnetlink_dump_one_entry(skb, cb, ct, dying);
			if (res < 0) {
				if (!refcount_inc_not_zero(&ct->ct_general.use))
					continue;
				ctx->cpu = cpu;
				ctx->last = ct;
				spin_unlock_bh(&pcpu->lock);
				goto out;
			}
Loading