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