1f229f6ce481ceb33a966311722b8ef0cb6c25de7Patrick McHardy/*
2f229f6ce481ceb33a966311722b8ef0cb6c25de7Patrick McHardy * Rusty Russell (C)2000 -- This code is GPL.
3f229f6ce481ceb33a966311722b8ef0cb6c25de7Patrick McHardy * Patrick McHardy (c) 2006-2012
4f229f6ce481ceb33a966311722b8ef0cb6c25de7Patrick McHardy */
5f229f6ce481ceb33a966311722b8ef0cb6c25de7Patrick McHardy
6f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/kernel.h>
75a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
8f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/init.h>
9f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/module.h>
10f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/proc_fs.h>
11f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/skbuff.h>
12f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <linux/netfilter.h>
13bbd86b9fc469b7e91dc7444e6abb8930811d79cbHarald Welte#include <linux/seq_file.h>
147a11b9848ae27e571f219fab5541bd84700f0d68Patrick McHardy#include <linux/rcupdate.h>
15f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include <net/protocol.h>
16c01cd429fc118c5db92475c5f08b307718aa4efcPatrick McHardy#include <net/netfilter/nf_queue.h>
177fee226ad2397b635e2fd565a59ca3ae08a164cdEric Dumazet#include <net/dst.h>
18f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
19f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte#include "nf_internals.h"
20f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
21601e68e100b6bf8ba13a32db8faf92d43acaa997YOSHIFUJI Hideaki/*
220360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal * Hook for nfnetlink_queue to register its queue handler.
230360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal * We do this so that most of the NFQUEUE code can be modular.
240360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal *
250360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal * Once the queue is registered it must reinject all packets it
260360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal * receives, no matter what.
27f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte */
280360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphalstatic const struct nf_queue_handler __rcu *queue_handler __read_mostly;
29f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
30d72367b6f36e557f122beefaa8c6b80eb1c7f245Harald Welte/* return EBUSY when somebody else is registered, return EEXIST if the
31d72367b6f36e557f122beefaa8c6b80eb1c7f245Harald Welte * same handler is registered, return 0 in case of success. */
320360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphalvoid nf_register_queue_handler(const struct nf_queue_handler *qh)
33601e68e100b6bf8ba13a32db8faf92d43acaa997YOSHIFUJI Hideaki{
340360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal	/* should never happen, we only have one queueing backend in kernel */
350360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal	WARN_ON(rcu_access_pointer(queue_handler));
360360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal	rcu_assign_pointer(queue_handler, qh);
37f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte}
38f6ebe77f955d77a988ce726f0818ec0103b11323Harald WelteEXPORT_SYMBOL(nf_register_queue_handler);
39f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
40f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte/* The caller must flush their queue before this */
410360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphalvoid nf_unregister_queue_handler(void)
42f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte{
430360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal	RCU_INIT_POINTER(queue_handler, NULL);
44585426fdc5b4cccaacf0afc8cf821ff763750ae8Yasuyuki Kozakai	synchronize_rcu();
45f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte}
46f6ebe77f955d77a988ce726f0818ec0103b11323Harald WelteEXPORT_SYMBOL(nf_unregister_queue_handler);
47f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
48a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphalvoid nf_queue_entry_release_refs(struct nf_queue_entry *entry)
49daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy{
50daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	/* Release those devices we held, or Alexey will kill me. */
51daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	if (entry->indev)
52daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		dev_put(entry->indev);
53daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	if (entry->outdev)
54daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		dev_put(entry->outdev);
551109a90c01177e8f4a5fd95c5b685ad02f1fe9bbPablo Neira Ayuso#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
56daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	if (entry->skb->nf_bridge) {
57daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
58daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy
59daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		if (nf_bridge->physindev)
60daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy			dev_put(nf_bridge->physindev);
61daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		if (nf_bridge->physoutdev)
62daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy			dev_put(nf_bridge->physoutdev);
63daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	}
64daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy#endif
65daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	/* Drop reference to owner of hook which queued us. */
66daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	module_put(entry->elem->owner);
67daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy}
68a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian WestphalEXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
69daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy
704bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal/* Bump dev refs so they don't vanish while packet is out */
71a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphalbool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
724bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal{
734bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	if (!try_module_get(entry->elem->owner))
744bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		return false;
754bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal
764bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	if (entry->indev)
774bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		dev_hold(entry->indev);
784bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	if (entry->outdev)
794bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		dev_hold(entry->outdev);
801109a90c01177e8f4a5fd95c5b685ad02f1fe9bbPablo Neira Ayuso#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
814bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	if (entry->skb->nf_bridge) {
824bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
834bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		struct net_device *physdev;
844bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal
854bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		physdev = nf_bridge->physindev;
864bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		if (physdev)
874bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal			dev_hold(physdev);
884bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		physdev = nf_bridge->physoutdev;
894bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal		if (physdev)
904bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal			dev_hold(physdev);
914bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	}
924bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal#endif
934bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal
944bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	return true;
954bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal}
96a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian WestphalEXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
974bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal
98601e68e100b6bf8ba13a32db8faf92d43acaa997YOSHIFUJI Hideaki/*
99601e68e100b6bf8ba13a32db8faf92d43acaa997YOSHIFUJI Hideaki * Any packet that leaves via this function must come back
100f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte * through nf_reinject().
101f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte */
102a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphalint nf_queue(struct sk_buff *skb,
1031c15b677097fc133cc23108d98e0f0846e94cd48Michael Wang		      struct nf_hook_ops *elem,
10476108cea065cda58366d16a7eb6ca90d717a1396Jan Engelhardt		      u_int8_t pf, unsigned int hook,
105394f545db6e7e4d7a6a2fa3f543b755ca39d58acPatrick McHardy		      struct net_device *indev,
106394f545db6e7e4d7a6a2fa3f543b755ca39d58acPatrick McHardy		      struct net_device *outdev,
107394f545db6e7e4d7a6a2fa3f543b755ca39d58acPatrick McHardy		      int (*okfn)(struct sk_buff *),
108394f545db6e7e4d7a6a2fa3f543b755ca39d58acPatrick McHardy		      unsigned int queuenum)
109f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte{
110f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	int status = -ENOENT;
111daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	struct nf_queue_entry *entry = NULL;
1121e796fda00f06bac584f0e4ad8750ab9430d79d3Patrick McHardy	const struct nf_afinfo *afinfo;
113e3ac5298159c5286cef86f0865d4fa6a606bd391Patrick McHardy	const struct nf_queue_handler *qh;
114f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
11525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* QUEUE == DROP if no one is waiting, to be safe. */
116585426fdc5b4cccaacf0afc8cf821ff763750ae8Yasuyuki Kozakai	rcu_read_lock();
117585426fdc5b4cccaacf0afc8cf821ff763750ae8Yasuyuki Kozakai
1180360ae412d09bc6f4864c801effcb20bfd84520eFlorian Westphal	qh = rcu_dereference(queue_handler);
11994b27cc36123069966616670c3653cd6873babe9Florian Westphal	if (!qh) {
12094b27cc36123069966616670c3653cd6873babe9Florian Westphal		status = -ESRCH;
121daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		goto err_unlock;
12294b27cc36123069966616670c3653cd6873babe9Florian Westphal	}
123f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
124bce8032ef3cc58170ab3550e9e271dba7b4c4764Patrick McHardy	afinfo = nf_get_afinfo(pf);
125daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	if (!afinfo)
126daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		goto err_unlock;
127bce8032ef3cc58170ab3550e9e271dba7b4c4764Patrick McHardy
12802f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
129f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	if (!entry) {
130f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal		status = -ENOMEM;
131daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		goto err_unlock;
132f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	}
133f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
13402f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	*entry = (struct nf_queue_entry) {
13502f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.skb	= skb,
1361c15b677097fc133cc23108d98e0f0846e94cd48Michael Wang		.elem	= elem,
13702f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.pf	= pf,
13802f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.hook	= hook,
13902f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.indev	= indev,
14002f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.outdev	= outdev,
14102f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		.okfn	= okfn,
142a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphal		.size	= sizeof(*entry) + afinfo->route_key_size,
14302f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	};
144f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
1454bd60443cc44c93ff37d483d69674647a0c48e4eFlorian Westphal	if (!nf_queue_entry_get_refs(entry)) {
14606cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal		status = -ECANCELED;
14706cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal		goto err_unlock;
148f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	}
1497fee226ad2397b635e2fd565a59ca3ae08a164cdEric Dumazet	skb_dst_force(skb);
15002f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	afinfo->saveroute(skb, entry);
15102f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	status = qh->outfn(entry, queuenum);
152f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
153585426fdc5b4cccaacf0afc8cf821ff763750ae8Yasuyuki Kozakai	rcu_read_unlock();
154f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
155f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	if (status < 0) {
156daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		nf_queue_entry_release_refs(entry);
157daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy		goto err;
158f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	}
159f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
160f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	return 0;
161daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy
162daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardyerr_unlock:
163daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	rcu_read_unlock();
164daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardyerr:
165daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	kfree(entry);
166f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	return status;
167f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte}
168f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
16902f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardyvoid nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
170f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte{
17102f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	struct sk_buff *skb = entry->skb;
1722a6decfd8a5fae0422c98a22aa6bc30224b8a3ecMichael Wang	struct nf_hook_ops *elem = entry->elem;
1731e796fda00f06bac584f0e4ad8750ab9430d79d3Patrick McHardy	const struct nf_afinfo *afinfo;
174f15850861860636c905b33a9a5be3dcbc2b0d56aFlorian Westphal	int err;
175f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
176f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	rcu_read_lock();
177f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
178daaa8be2e0ec1c27d11e6724c8ebd8ed53914ae2Patrick McHardy	nf_queue_entry_release_refs(entry);
179f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
180f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	/* Continue traversal iff userspace said ok... */
181f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	if (verdict == NF_REPEAT) {
1822a6decfd8a5fae0422c98a22aa6bc30224b8a3ecMichael Wang		elem = list_entry(elem->list.prev, struct nf_hook_ops, list);
183f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte		verdict = NF_ACCEPT;
184f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	}
185f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
186f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	if (verdict == NF_ACCEPT) {
18702f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		afinfo = nf_get_afinfo(entry->pf);
18802f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		if (!afinfo || afinfo->reroute(skb, entry) < 0)
1897a11b9848ae27e571f219fab5541bd84700f0d68Patrick McHardy			verdict = NF_DROP;
1907a11b9848ae27e571f219fab5541bd84700f0d68Patrick McHardy	}
1917a11b9848ae27e571f219fab5541bd84700f0d68Patrick McHardy
1927a11b9848ae27e571f219fab5541bd84700f0d68Patrick McHardy	if (verdict == NF_ACCEPT) {
193f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	next_hook:
19402f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		verdict = nf_iterate(&nf_hooks[entry->pf][entry->hook],
19502f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy				     skb, entry->hook,
19602f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy				     entry->indev, entry->outdev, &elem,
19702f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy				     entry->okfn, INT_MIN);
198f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	}
199f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte
200f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	switch (verdict & NF_VERDICT_MASK) {
201f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	case NF_ACCEPT:
2023bc38712e3a6e0596ccb6f8299043a826f983701Patrick McHardy	case NF_STOP:
2034b3d15ef4a88683d93d1b76351297d2298a02a99Patrick McHardy		local_bh_disable();
20402f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy		entry->okfn(skb);
2054b3d15ef4a88683d93d1b76351297d2298a02a99Patrick McHardy		local_bh_enable();
206f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte		break;
207f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	case NF_QUEUE:
208a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphal		err = nf_queue(skb, elem, entry->pf, entry->hook,
209a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphal				entry->indev, entry->outdev, entry->okfn,
210a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2Florian Westphal				verdict >> NF_VERDICT_QBITS);
21106cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal		if (err < 0) {
21206cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal			if (err == -ECANCELED)
21306cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal				goto next_hook;
21494b27cc36123069966616670c3653cd6873babe9Florian Westphal			if (err == -ESRCH &&
21594b27cc36123069966616670c3653cd6873babe9Florian Westphal			   (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
21694b27cc36123069966616670c3653cd6873babe9Florian Westphal				goto next_hook;
21706cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal			kfree_skb(skb);
21806cdb6349c1f3fd439398dbc04ce4c696f0a41abFlorian Westphal		}
219f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte		break;
22064507fdbc29c3a622180378210ecea8659b14e40Eric Dumazet	case NF_STOLEN:
221fad54440438a7c231a6ae347738423cbabc936d9Julian Anastasov		break;
2223bc38712e3a6e0596ccb6f8299043a826f983701Patrick McHardy	default:
2233bc38712e3a6e0596ccb6f8299043a826f983701Patrick McHardy		kfree_skb(skb);
224f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	}
225f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte	rcu_read_unlock();
22602f014d88831f73b895c1fe09badb66c88e932d3Patrick McHardy	kfree(entry);
227f6ebe77f955d77a988ce726f0818ec0103b11323Harald Welte}
228f6ebe77f955d77a988ce726f0818ec0103b11323Harald WelteEXPORT_SYMBOL(nf_reinject);
229