Skip to content

Commit f5c5440

Browse files
Eric Dumazetkaber
authored andcommitted
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: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
1 parent bed1be2 commit f5c5440

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

include/linux/netfilter/nfnetlink_log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ enum nfulnl_attr_config {
8989
#define NFULNL_COPY_NONE 0x00
9090
#define NFULNL_COPY_META 0x01
9191
#define NFULNL_COPY_PACKET 0x02
92+
#define NFULNL_COPY_DISABLED 0x03
9293

9394
#define NFULNL_CFG_F_SEQ 0x0001
9495
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002

net/netfilter/nfnetlink_log.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ instance_lookup_get(u_int16_t group_num)
109109

110110
rcu_read_lock_bh();
111111
inst = __instance_lookup(group_num);
112-
if (inst)
113-
instance_get(inst);
112+
if (inst && !atomic_inc_not_zero(&inst->use))
113+
inst = NULL;
114114
rcu_read_unlock_bh();
115115

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

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

177177
spin_unlock_bh(&instances_lock);
@@ -185,18 +185,23 @@ instance_create(u_int16_t group_num, int pid)
185185

186186
static void __nfulnl_flush(struct nfulnl_instance *inst);
187187

188+
/* called with BH disabled */
188189
static void
189190
__instance_destroy(struct nfulnl_instance *inst)
190191
{
191192
/* first pull it out of the global list */
192-
hlist_del(&inst->hlist);
193+
hlist_del_rcu(&inst->hlist);
193194

194195
/* then flush all pending packets from skb */
195196

196-
spin_lock_bh(&inst->lock);
197+
spin_lock(&inst->lock);
198+
199+
/* lockless readers wont be able to use us */
200+
inst->copy_mode = NFULNL_COPY_DISABLED;
201+
197202
if (inst->skb)
198203
__nfulnl_flush(inst);
199-
spin_unlock_bh(&inst->lock);
204+
spin_unlock(&inst->lock);
200205

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

632+
case NFULNL_COPY_DISABLED:
627633
default:
628634
goto unlock_and_release;
629635
}

0 commit comments

Comments
 (0)