Skip to content

Commit b43d8d8

Browse files
kaberdavem330
authored andcommitted
[NETFILTER]: nfnetlink_queue: deobfuscate entry lookups
A queue entry lookup currently looks like this: find_dequeue_entry -> __find_dequeue_entry -> __find_entry -> cmpfn -> id_cmp Use simple open-coded list walking and kill the cmpfn for find_dequeue_entry. Instead add it to nfqnl_flush (after similar cleanups) and use nfqnl_flush for both complete flushes and flushing entries related to a device. Signed-off-by: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0ac41e8 commit b43d8d8

File tree

1 file changed

+31
-69
lines changed

1 file changed

+31
-69
lines changed

net/netfilter/nfnetlink_queue.c

Lines changed: 31 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ instance_create(u_int16_t queue_num, int pid)
171171
return NULL;
172172
}
173173

174-
static void nfqnl_flush(struct nfqnl_instance *queue, int verdict);
174+
static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
175+
unsigned long data);
175176

176177
static void
177178
_instance_destroy2(struct nfqnl_instance *inst, int lock)
@@ -188,7 +189,7 @@ _instance_destroy2(struct nfqnl_instance *inst, int lock)
188189
write_unlock_bh(&instances_lock);
189190

190191
/* then flush all pending skbs from the queue */
191-
nfqnl_flush(inst, NF_DROP);
192+
nfqnl_flush(inst, NULL, 0);
192193

193194
/* and finally put the refcount */
194195
instance_put(inst);
@@ -235,54 +236,6 @@ __enqueue_entry(struct nfqnl_instance *queue,
235236
queue->queue_total++;
236237
}
237238

238-
/*
239-
* Find and return a queued entry matched by cmpfn, or return the last
240-
* entry if cmpfn is NULL.
241-
*/
242-
static inline struct nfqnl_queue_entry *
243-
__find_entry(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
244-
unsigned long data)
245-
{
246-
struct nfqnl_queue_entry *entry;
247-
248-
list_for_each_entry(entry, &queue->queue_list, list) {
249-
if (!cmpfn || cmpfn(entry, data))
250-
return entry;
251-
}
252-
return NULL;
253-
}
254-
255-
static inline void
256-
__dequeue_entry(struct nfqnl_instance *q, struct nfqnl_queue_entry *entry)
257-
{
258-
list_del(&entry->list);
259-
q->queue_total--;
260-
}
261-
262-
static inline struct nfqnl_queue_entry *
263-
__find_dequeue_entry(struct nfqnl_instance *queue,
264-
nfqnl_cmpfn cmpfn, unsigned long data)
265-
{
266-
struct nfqnl_queue_entry *entry;
267-
268-
entry = __find_entry(queue, cmpfn, data);
269-
if (entry == NULL)
270-
return NULL;
271-
272-
__dequeue_entry(queue, entry);
273-
return entry;
274-
}
275-
276-
277-
static inline void
278-
__nfqnl_flush(struct nfqnl_instance *queue, int verdict)
279-
{
280-
struct nfqnl_queue_entry *entry;
281-
282-
while ((entry = __find_dequeue_entry(queue, NULL, 0)))
283-
issue_verdict(entry, verdict);
284-
}
285-
286239
static inline int
287240
__nfqnl_set_mode(struct nfqnl_instance *queue,
288241
unsigned char mode, unsigned int range)
@@ -313,23 +266,42 @@ __nfqnl_set_mode(struct nfqnl_instance *queue,
313266
}
314267

315268
static struct nfqnl_queue_entry *
316-
find_dequeue_entry(struct nfqnl_instance *queue,
317-
nfqnl_cmpfn cmpfn, unsigned long data)
269+
find_dequeue_entry(struct nfqnl_instance *queue, unsigned int id)
318270
{
319-
struct nfqnl_queue_entry *entry;
271+
struct nfqnl_queue_entry *entry = NULL, *i;
320272

321273
spin_lock_bh(&queue->lock);
322-
entry = __find_dequeue_entry(queue, cmpfn, data);
274+
275+
list_for_each_entry(i, &queue->queue_list, list) {
276+
if (i->id == id) {
277+
entry = i;
278+
break;
279+
}
280+
}
281+
282+
if (entry) {
283+
list_del(&entry->list);
284+
queue->queue_total--;
285+
}
286+
323287
spin_unlock_bh(&queue->lock);
324288

325289
return entry;
326290
}
327291

328292
static void
329-
nfqnl_flush(struct nfqnl_instance *queue, int verdict)
293+
nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
330294
{
295+
struct nfqnl_queue_entry *entry, *next;
296+
331297
spin_lock_bh(&queue->lock);
332-
__nfqnl_flush(queue, verdict);
298+
list_for_each_entry_safe(entry, next, &queue->queue_list, list) {
299+
if (!cmpfn || cmpfn(entry, data)) {
300+
list_del(&entry->list);
301+
queue->queue_total--;
302+
issue_verdict(entry, NF_DROP);
303+
}
304+
}
333305
spin_unlock_bh(&queue->lock);
334306
}
335307

@@ -644,12 +616,6 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
644616
return 0;
645617
}
646618

647-
static inline int
648-
id_cmp(struct nfqnl_queue_entry *e, unsigned long id)
649-
{
650-
return (id == e->id);
651-
}
652-
653619
static int
654620
nfqnl_set_mode(struct nfqnl_instance *queue,
655621
unsigned char mode, unsigned int range)
@@ -706,12 +672,8 @@ nfqnl_dev_drop(int ifindex)
706672
struct nfqnl_instance *inst;
707673
struct hlist_head *head = &instance_table[i];
708674

709-
hlist_for_each_entry(inst, tmp, head, hlist) {
710-
struct nfqnl_queue_entry *entry;
711-
while ((entry = find_dequeue_entry(inst, dev_cmp,
712-
ifindex)) != NULL)
713-
issue_verdict(entry, NF_DROP);
714-
}
675+
hlist_for_each_entry(inst, tmp, head, hlist)
676+
nfqnl_flush(inst, dev_cmp, ifindex);
715677
}
716678

717679
read_unlock_bh(&instances_lock);
@@ -811,7 +773,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
811773
goto err_out_put;
812774
}
813775

814-
entry = find_dequeue_entry(queue, id_cmp, ntohl(vhdr->id));
776+
entry = find_dequeue_entry(queue, ntohl(vhdr->id));
815777
if (entry == NULL) {
816778
err = -ENOENT;
817779
goto err_out_put;

0 commit comments

Comments
 (0)