Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c655bc68 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_conntrack: don't send destroy events from iterator



Let nf_ct_delete handle delivery of the DESTROY event.

Based on earlier patch from Pablo Neira.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 54e35cc5
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -248,7 +248,9 @@ extern void nf_ct_untracked_status_or(unsigned long bits);

/* Iterate over all conntracks: if iter returns true, it's deleted. */
extern void
nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data);
nf_ct_iterate_cleanup(struct net *net,
		      int (*iter)(struct nf_conn *i, void *data),
		      void *data, u32 portid, int report);
extern void nf_conntrack_free(struct nf_conn *ct);
extern struct nf_conn *
nf_conntrack_alloc(struct net *net, u16 zone,
+1 −1
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ static int masq_device_event(struct notifier_block *this,
		NF_CT_ASSERT(dev->ifindex != 0);

		nf_ct_iterate_cleanup(net, device_cmp,
				      (void *)(long)dev->ifindex);
				      (void *)(long)dev->ifindex, 0, 0);
	}

	return NOTIFY_DONE;
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ static int masq_device_event(struct notifier_block *this,

	if (event == NETDEV_DOWN)
		nf_ct_iterate_cleanup(net, device_cmp,
				      (void *)(long)dev->ifindex);
				      (void *)(long)dev->ifindex, 0, 0);

	return NOTIFY_DONE;
}
+4 −32
Original line number Diff line number Diff line
@@ -1246,7 +1246,7 @@ get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),

void nf_ct_iterate_cleanup(struct net *net,
			   int (*iter)(struct nf_conn *i, void *data),
			   void *data)
			   void *data, u32 portid, int report)
{
	struct nf_conn *ct;
	unsigned int bucket = 0;
@@ -1254,7 +1254,7 @@ void nf_ct_iterate_cleanup(struct net *net,
	while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
		/* Time to push up daises... */
		if (del_timer(&ct->timeout))
			death_by_timeout((unsigned long)ct);
			nf_ct_delete(ct, portid, report);

		/* ... else the timer will get him soon. */

@@ -1263,30 +1263,6 @@ void nf_ct_iterate_cleanup(struct net *net,
}
EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);

struct __nf_ct_flush_report {
	u32 portid;
	int report;
};

static int kill_report(struct nf_conn *i, void *data)
{
	struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
	struct nf_conn_tstamp *tstamp;

	tstamp = nf_conn_tstamp_find(i);
	if (tstamp && tstamp->stop == 0)
		tstamp->stop = ktime_to_ns(ktime_get_real());

	/* If we fail to deliver the event, death_by_timeout() will retry */
	if (nf_conntrack_event_report(IPCT_DESTROY, i,
				      fr->portid, fr->report) < 0)
		return 1;

	/* Avoid the delivery of the destroy event in death_by_timeout(). */
	set_bit(IPS_DYING_BIT, &i->status);
	return 1;
}

static int kill_all(struct nf_conn *i, void *data)
{
	return 1;
@@ -1304,11 +1280,7 @@ EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);

void nf_conntrack_flush_report(struct net *net, u32 portid, int report)
{
	struct __nf_ct_flush_report fr = {
		.portid	= portid,
		.report = report,
	};
	nf_ct_iterate_cleanup(net, kill_report, &fr);
	nf_ct_iterate_cleanup(net, kill_all, NULL, portid, report);
}
EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);

@@ -1389,7 +1361,7 @@ void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
i_see_dead_people:
	busy = 0;
	list_for_each_entry(net, net_exit_list, exit_list) {
		nf_ct_iterate_cleanup(net, kill_all, NULL);
		nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0);
		nf_ct_release_dying_list(net);
		if (atomic_read(&net->ct.count) != 0)
			busy = 1;
+2 −2
Original line number Diff line number Diff line
@@ -281,7 +281,7 @@ void nf_ct_l3proto_pernet_unregister(struct net *net,
	nf_ct_l3proto_unregister_sysctl(net, proto);

	/* Remove all contrack entries for this protocol */
	nf_ct_iterate_cleanup(net, kill_l3proto, proto);
	nf_ct_iterate_cleanup(net, kill_l3proto, proto, 0, 0);
}
EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister);

@@ -476,7 +476,7 @@ void nf_ct_l4proto_pernet_unregister(struct net *net,
	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);

	/* Remove all contrack entries for this protocol */
	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto, 0, 0);
}
EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);

Loading