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

Commit f5c5440d authored by Eric Dumazet's avatar Eric Dumazet Committed by Patrick McHardy
Browse files

netfilter: nfnetlink_log: RCU conversion, part 2



- must use atomic_inc_not_zero() in instance_lookup_get()

- must use hlist_add_head_rcu() instead of hlist_add_head()

- must use hlist_del_rcu() instead of hlist_del()

- Introduce NFULNL_COPY_DISABLED to stop lockless reader from using an
instance, before we do final instance_put() on it.

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent bed1be20
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ enum nfulnl_attr_config {
#define NFULNL_COPY_NONE	0x00
#define NFULNL_COPY_META	0x01
#define NFULNL_COPY_PACKET	0x02
#define NFULNL_COPY_DISABLED	0x03

#define NFULNL_CFG_F_SEQ	0x0001
#define NFULNL_CFG_F_SEQ_GLOBAL	0x0002
+12 −6
Original line number Diff line number Diff line
@@ -109,8 +109,8 @@ instance_lookup_get(u_int16_t group_num)

	rcu_read_lock_bh();
	inst = __instance_lookup(group_num);
	if (inst)
		instance_get(inst);
	if (inst && !atomic_inc_not_zero(&inst->use))
		inst = NULL;
	rcu_read_unlock_bh();

	return inst;
@@ -171,7 +171,7 @@ instance_create(u_int16_t group_num, int pid)
	inst->copy_mode 	= NFULNL_COPY_PACKET;
	inst->copy_range 	= NFULNL_COPY_RANGE_MAX;

	hlist_add_head(&inst->hlist,
	hlist_add_head_rcu(&inst->hlist,
		       &instance_table[instance_hashfn(group_num)]);

	spin_unlock_bh(&instances_lock);
@@ -185,18 +185,23 @@ out_unlock:

static void __nfulnl_flush(struct nfulnl_instance *inst);

/* called with BH disabled */
static void
__instance_destroy(struct nfulnl_instance *inst)
{
	/* first pull it out of the global list */
	hlist_del(&inst->hlist);
	hlist_del_rcu(&inst->hlist);

	/* then flush all pending packets from skb */

	spin_lock_bh(&inst->lock);
	spin_lock(&inst->lock);

	/* lockless readers wont be able to use us */
	inst->copy_mode = NFULNL_COPY_DISABLED;

	if (inst->skb)
		__nfulnl_flush(inst);
	spin_unlock_bh(&inst->lock);
	spin_unlock(&inst->lock);

	/* and finally put the refcount */
	instance_put(inst);
@@ -624,6 +629,7 @@ nfulnl_log_packet(u_int8_t pf,
		size += nla_total_size(data_len);
		break;

	case NFULNL_COPY_DISABLED:
	default:
		goto unlock_and_release;
	}