linux/net/netfilter/nf_queue.c
<<
>>
Prefs
   1/*
   2 * Rusty Russell (C)2000 -- This code is GPL.
   3 * Patrick McHardy (c) 2006-2012
   4 */
   5
   6#include <linux/kernel.h>
   7#include <linux/slab.h>
   8#include <linux/init.h>
   9#include <linux/module.h>
  10#include <linux/proc_fs.h>
  11#include <linux/skbuff.h>
  12#include <linux/netfilter.h>
  13#include <linux/netfilter_bridge.h>
  14#include <linux/seq_file.h>
  15#include <linux/rcupdate.h>
  16#include <net/protocol.h>
  17#include <net/netfilter/nf_queue.h>
  18#include <net/dst.h>
  19
  20#include "nf_internals.h"
  21
  22/*
  23 * Hook for nfnetlink_queue to register its queue handler.
  24 * We do this so that most of the NFQUEUE code can be modular.
  25 *
  26 * Once the queue is registered it must reinject all packets it
  27 * receives, no matter what.
  28 */
  29
  30/* return EBUSY when somebody else is registered, return EEXIST if the
  31 * same handler is registered, return 0 in case of success. */
  32void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh)
  33{
  34        /* should never happen, we only have one queueing backend in kernel */
  35        WARN_ON(rcu_access_pointer(net->nf.queue_handler));
  36        rcu_assign_pointer(net->nf.queue_handler, qh);
  37}
  38EXPORT_SYMBOL(nf_register_queue_handler);
  39
  40/* The caller must flush their queue before this */
  41void nf_unregister_queue_handler(struct net *net)
  42{
  43        RCU_INIT_POINTER(net->nf.queue_handler, NULL);
  44}
  45EXPORT_SYMBOL(nf_unregister_queue_handler);
  46
  47void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
  48{
  49        struct nf_hook_state *state = &entry->state;
  50
  51        /* Release those devices we held, or Alexey will kill me. */
  52        if (state->in)
  53                dev_put(state->in);
  54        if (state->out)
  55                dev_put(state->out);
  56        if (state->sk)
  57                sock_put(state->sk);
  58#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
  59        if (entry->skb->nf_bridge) {
  60                struct net_device *physdev;
  61
  62                physdev = nf_bridge_get_physindev(entry->skb);
  63                if (physdev)
  64                        dev_put(physdev);
  65                physdev = nf_bridge_get_physoutdev(entry->skb);
  66                if (physdev)
  67                        dev_put(physdev);
  68        }
  69#endif
  70}
  71EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
  72
  73/* Bump dev refs so they don't vanish while packet is out */
  74void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
  75{
  76        struct nf_hook_state *state = &entry->state;
  77
  78        if (state->in)
  79                dev_hold(state->in);
  80        if (state->out)
  81                dev_hold(state->out);
  82        if (state->sk)
  83                sock_hold(state->sk);
  84#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
  85        if (entry->skb->nf_bridge) {
  86                struct net_device *physdev;
  87
  88                physdev = nf_bridge_get_physindev(entry->skb);
  89                if (physdev)
  90                        dev_hold(physdev);
  91                physdev = nf_bridge_get_physoutdev(entry->skb);
  92                if (physdev)
  93                        dev_hold(physdev);
  94        }
  95#endif
  96}
  97EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
  98
  99unsigned int nf_queue_nf_hook_drop(struct net *net)
 100{
 101        const struct nf_queue_handler *qh;
 102        unsigned int count = 0;
 103
 104        rcu_read_lock();
 105        qh = rcu_dereference(net->nf.queue_handler);
 106        if (qh)
 107                count = qh->nf_hook_drop(net);
 108        rcu_read_unlock();
 109
 110        return count;
 111}
 112EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
 113
 114static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
 115                      const struct nf_hook_entries *entries,
 116                      unsigned int index, unsigned int queuenum)
 117{
 118        int status = -ENOENT;
 119        struct nf_queue_entry *entry = NULL;
 120        const struct nf_afinfo *afinfo;
 121        const struct nf_queue_handler *qh;
 122        struct net *net = state->net;
 123
 124        /* QUEUE == DROP if no one is waiting, to be safe. */
 125        qh = rcu_dereference(net->nf.queue_handler);
 126        if (!qh) {
 127                status = -ESRCH;
 128                goto err;
 129        }
 130
 131        afinfo = nf_get_afinfo(state->pf);
 132        if (!afinfo)
 133                goto err;
 134
 135        entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
 136        if (!entry) {
 137                status = -ENOMEM;
 138                goto err;
 139        }
 140
 141        *entry = (struct nf_queue_entry) {
 142                .skb    = skb,
 143                .state  = *state,
 144                .hook_index = index,
 145                .size   = sizeof(*entry) + afinfo->route_key_size,
 146        };
 147
 148        nf_queue_entry_get_refs(entry);
 149        skb_dst_force(skb);
 150        afinfo->saveroute(skb, entry);
 151        status = qh->outfn(entry, queuenum);
 152
 153        if (status < 0) {
 154                nf_queue_entry_release_refs(entry);
 155                goto err;
 156        }
 157
 158        return 0;
 159
 160err:
 161        kfree(entry);
 162        return status;
 163}
 164
 165/* Packets leaving via this function must come back through nf_reinject(). */
 166int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
 167             const struct nf_hook_entries *entries, unsigned int index,
 168             unsigned int verdict)
 169{
 170        int ret;
 171
 172        ret = __nf_queue(skb, state, entries, index, verdict >> NF_VERDICT_QBITS);
 173        if (ret < 0) {
 174                if (ret == -ESRCH &&
 175                    (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
 176                        return 1;
 177                kfree_skb(skb);
 178        }
 179
 180        return 0;
 181}
 182
 183static unsigned int nf_iterate(struct sk_buff *skb,
 184                               struct nf_hook_state *state,
 185                               const struct nf_hook_entries *hooks,
 186                               unsigned int *index)
 187{
 188        const struct nf_hook_entry *hook;
 189        unsigned int verdict, i = *index;
 190
 191        while (i < hooks->num_hook_entries) {
 192                hook = &hooks->hooks[i];
 193repeat:
 194                verdict = nf_hook_entry_hookfn(hook, skb, state);
 195                if (verdict != NF_ACCEPT) {
 196                        if (verdict != NF_REPEAT)
 197                                return verdict;
 198                        goto repeat;
 199                }
 200                i++;
 201        }
 202
 203        *index = i;
 204        return NF_ACCEPT;
 205}
 206
 207/* Caller must hold rcu read-side lock */
 208void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
 209{
 210        const struct nf_hook_entry *hook_entry;
 211        const struct nf_hook_entries *hooks;
 212        struct sk_buff *skb = entry->skb;
 213        const struct nf_afinfo *afinfo;
 214        const struct net *net;
 215        unsigned int i;
 216        int err;
 217        u8 pf;
 218
 219        net = entry->state.net;
 220        pf = entry->state.pf;
 221
 222        hooks = rcu_dereference(net->nf.hooks[pf][entry->state.hook]);
 223
 224        nf_queue_entry_release_refs(entry);
 225
 226        i = entry->hook_index;
 227        if (WARN_ON_ONCE(i >= hooks->num_hook_entries)) {
 228                kfree_skb(skb);
 229                kfree(entry);
 230                return;
 231        }
 232
 233        hook_entry = &hooks->hooks[i];
 234
 235        /* Continue traversal iff userspace said ok... */
 236        if (verdict == NF_REPEAT)
 237                verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
 238
 239        if (verdict == NF_ACCEPT) {
 240                afinfo = nf_get_afinfo(entry->state.pf);
 241                if (!afinfo || afinfo->reroute(entry->state.net, skb, entry) < 0)
 242                        verdict = NF_DROP;
 243        }
 244
 245        if (verdict == NF_ACCEPT) {
 246next_hook:
 247                ++i;
 248                verdict = nf_iterate(skb, &entry->state, hooks, &i);
 249        }
 250
 251        switch (verdict & NF_VERDICT_MASK) {
 252        case NF_ACCEPT:
 253        case NF_STOP:
 254                local_bh_disable();
 255                entry->state.okfn(entry->state.net, entry->state.sk, skb);
 256                local_bh_enable();
 257                break;
 258        case NF_QUEUE:
 259                err = nf_queue(skb, &entry->state, hooks, i, verdict);
 260                if (err == 1)
 261                        goto next_hook;
 262                break;
 263        case NF_STOLEN:
 264                break;
 265        default:
 266                kfree_skb(skb);
 267        }
 268
 269        kfree(entry);
 270}
 271EXPORT_SYMBOL(nf_reinject);
 272