Commit 200bd566 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayusosays:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for net:

1) Memleak in commit audit error path, from Dongliang Mu.

2) Avoid possible false sharing for flowtable timeout updates
   and nft_last use.

3) Adjust conntrack timestamp due to garbage collection delay,
   from Florian Westphal.

4) Fix nft_nat without layer 3 address for the inet family.

5) Fix compilation warning in nfnl_hook when ingress support
   is disabled, from Arnd Bergmann.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9986066d 217e26bd
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -670,8 +670,13 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
		return false;

	tstamp = nf_conn_tstamp_find(ct);
	if (tstamp && tstamp->stop == 0)
	if (tstamp) {
		s32 timeout = ct->timeout - nfct_time_stamp;

		tstamp->stop = ktime_get_real_ns();
		if (timeout < 0)
			tstamp->stop -= jiffies_to_nsecs(-timeout);
	}

	if (nf_conntrack_event_report(IPCT_DESTROY, ct,
				    portid, report) < 0) {
+5 −1
Original line number Diff line number Diff line
@@ -331,7 +331,11 @@ EXPORT_SYMBOL_GPL(flow_offload_add);
void flow_offload_refresh(struct nf_flowtable *flow_table,
			  struct flow_offload *flow)
{
	flow->timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
	u32 timeout;

	timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
	if (READ_ONCE(flow->timeout) != timeout)
		WRITE_ONCE(flow->timeout, timeout);

	if (likely(!nf_flowtable_hw_offload(flow_table)))
		return;
+12 −0
Original line number Diff line number Diff line
@@ -8445,6 +8445,16 @@ static int nf_tables_commit_audit_alloc(struct list_head *adl,
	return 0;
}

static void nf_tables_commit_audit_free(struct list_head *adl)
{
	struct nft_audit_data *adp, *adn;

	list_for_each_entry_safe(adp, adn, adl, list) {
		list_del(&adp->list);
		kfree(adp);
	}
}

static void nf_tables_commit_audit_collect(struct list_head *adl,
					   struct nft_table *table, u32 op)
{
@@ -8509,6 +8519,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
		ret = nf_tables_commit_audit_alloc(&adl, trans->ctx.table);
		if (ret) {
			nf_tables_commit_chain_prepare_cancel(net);
			nf_tables_commit_audit_free(&adl);
			return ret;
		}
		if (trans->msg_type == NFT_MSG_NEWRULE ||
@@ -8518,6 +8529,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
			ret = nf_tables_commit_chain_prepare(net, chain);
			if (ret < 0) {
				nf_tables_commit_chain_prepare_cancel(net);
				nf_tables_commit_audit_free(&adl);
				return ret;
			}
		}
+2 −0
Original line number Diff line number Diff line
@@ -174,7 +174,9 @@ static const struct nf_hook_entries *
nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *dev)
{
	const struct nf_hook_entries *hook_head = NULL;
#ifdef CONFIG_NETFILTER_INGRESS
	struct net_device *netdev;
#endif

	switch (pf) {
	case NFPROTO_IPV4:
+13 −7
Original line number Diff line number Diff line
@@ -48,24 +48,30 @@ static void nft_last_eval(const struct nft_expr *expr,
{
	struct nft_last_priv *priv = nft_expr_priv(expr);

	priv->last_jiffies = jiffies;
	priv->last_set = 1;
	if (READ_ONCE(priv->last_jiffies) != jiffies)
		WRITE_ONCE(priv->last_jiffies, jiffies);
	if (READ_ONCE(priv->last_set) == 0)
		WRITE_ONCE(priv->last_set, 1);
}

static int nft_last_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
	struct nft_last_priv *priv = nft_expr_priv(expr);
	unsigned long last_jiffies = READ_ONCE(priv->last_jiffies);
	u32 last_set = READ_ONCE(priv->last_set);
	__be64 msecs;

	if (time_before(jiffies, priv->last_jiffies))
		priv->last_set = 0;
	if (time_before(jiffies, last_jiffies)) {
		WRITE_ONCE(priv->last_set, 0);
		last_set = 0;
	}

	if (priv->last_set)
		msecs = nf_jiffies64_to_msecs(jiffies - priv->last_jiffies);
	if (last_set)
		msecs = nf_jiffies64_to_msecs(jiffies - last_jiffies);
	else
		msecs = 0;

	if (nla_put_be32(skb, NFTA_LAST_SET, htonl(priv->last_set)) ||
	if (nla_put_be32(skb, NFTA_LAST_SET, htonl(last_set)) ||
	    nla_put_be64(skb, NFTA_LAST_MSECS, msecs, NFTA_LAST_PAD))
		goto nla_put_failure;

Loading