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_ipv4.h>
  14#include <linux/netfilter_ipv6.h>
  15#include <linux/netfilter_bridge.h>
  16#include <linux/seq_file.h>
  17#include <linux/rcupdate.h>
  18#include <net/protocol.h>
  19#include <net/netfilter/nf_queue.h>
  20#include <net/dst.h>
  21
  22#include "nf_internals.h"
  23
  24/*
  25 * Hook for nfnetlink_queue to register its queue handler.
  26 * We do this so that most of the NFQUEUE code can be modular.
  27 *
  28 * Once the queue is registered it must reinject all packets it
  29 * receives, no matter what.
  30 */
  31
  32/* return EBUSY when somebody else is registered, return EEXIST if the
  33 * same handler is registered, return 0 in case of success. */
  34void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh)
  35{
  36        /* should never happen, we only have one queueing backend in kernel */
  37        WARN_ON(rcu_access_pointer(net->nf.queue_handler));
  38        rcu_assign_pointer(net->nf.queue_handler, qh);
  39}
  40EXPORT_SYMBOL(nf_register_queue_handler);
  41
  42/* The caller must flush their queue before this */
  43void nf_unregister_queue_handler(struct net *net)
  44{
  45        RCU_INIT_POINTER(net->nf.queue_handler, NULL);
  46}
  47EXPORT_SYMBOL(nf_unregister_queue_handler);
  48
  49void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
  50{
  51        struct nf_hook_state *state = &entry->state;
  52
  53        /* Release those devices we held, or Alexey will kill me. */
  54        if (state->in)
  55                dev_put(state->in);
  56        if (state->out)
  57                dev_put(state->out);
  58        if (state->sk)
  59                sock_put(state->sk);
  60#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
  61        if (entry->skb->nf_bridge) {
  62                struct net_device *physdev;
  63
  64                physdev = nf_bridge_get_physindev(entry->skb);
  65                if (physdev)
  66                        dev_put(physdev);
  67                physdev = nf_bridge_get_physoutdev(entry->skb);
  68                if (physdev)
  69                        dev_put(physdev);
  70        }
  71#endif
  72}
  73EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
  74
  75/* Bump dev refs so they don't vanish while packet is out */
  76void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
  77{
  78        struct nf_hook_state *state = &entry->state;
  79
  80        if (state->in)
  81                dev_hold(state->in);
  82        if (state->out)
  83                dev_hold(state->out);
  84        if (state->sk)
  85                sock_hold(state->sk);
  86#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
  87        if (entry->skb->nf_bridge) {
  88                struct net_device *physdev;
  89
  90                physdev = nf_bridge_get_physindev(entry->skb);
  91                if (physdev)
  92                        dev_hold(physdev);
  93                physdev = nf_bridge_get_physoutdev(entry->skb);
  94                if (physdev)
  95                        dev_hold(physdev);
  96        }
  97#endif
  98}
  99EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
 100
 101void nf_queue_nf_hook_drop(struct net *net)
 102{
 103        const struct nf_queue_handler *qh;
 104
 105        rcu_read_lock();
 106        qh = rcu_dereference(net->nf.queue_handler);
 107        if (qh)
 108                qh->nf_hook_drop(net);
 109        rcu_read_unlock();
 110}
 111EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
 112
 113static void nf_ip_saveroute(const struct sk_buff *skb,
 114                            struct nf_queue_entry *entry)
 115{
 116        struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
 117
 118        if (entry->state.hook == NF_INET_LOCAL_OUT) {
 119                const struct iphdr *iph = ip_hdr(skb);
 120
 121                rt_info->tos = iph->tos;
 122                rt_info->daddr = iph->daddr;
 123                rt_info->saddr = iph->saddr;
 124                rt_info->mark = skb->mark;
 125        }
 126}
 127
 128static void nf_ip6_saveroute(const struct sk_buff *skb,
 129                             struct nf_queue_entry *entry)
 130{
 131        struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
 132
 133        if (entry->state.hook == NF_INET_LOCAL_OUT) {
 134                const struct ipv6hdr *iph = ipv6_hdr(skb);
 135
 136                rt_info->daddr = iph->daddr;
 137                rt_info->saddr = iph->saddr;
 138                rt_info->mark = skb->mark;
 139        }
 140}
 141
 142static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
 143                      const struct nf_hook_entries *entries,
 144                      unsigned int index, unsigned int queuenum)
 145{
 146        int status = -ENOENT;
 147        struct nf_queue_entry *entry = NULL;
 148        const struct nf_queue_handler *qh;
 149        struct net *net = state->net;
 150        unsigned int route_key_size;
 151
 152        /* QUEUE == DROP if no one is waiting, to be safe. */
 153        qh = rcu_dereference(net->nf.queue_handler);
 154        if (!qh) {
 155                status = -ESRCH;
 156                goto err;
 157        }
 158
 159        switch (state->pf) {
 160        case AF_INET:
 161                route_key_size = sizeof(struct ip_rt_info);
 162                break;
 163        case AF_INET6:
 164                route_key_size = sizeof(struct ip6_rt_info);
 165                break;
 166        default:
 167                route_key_size = 0;
 168                break;
 169        }
 170
 171        entry = kmalloc(sizeof(*entry) + route_key_size, GFP_ATOMIC);
 172        if (!entry) {
 173                status = -ENOMEM;
 174                goto err;
 175        }
 176
 177        *entry = (struct nf_queue_entry) {
 178                .skb    = skb,
 179                .state  = *state,
 180                .hook_index = index,
 181                .size   = sizeof(*entry) + route_key_size,
 182        };
 183
 184        nf_queue_entry_get_refs(entry);
 185        skb_dst_force(skb);
 186
 187        switch (entry->state.pf) {
 188        case AF_INET:
 189                nf_ip_saveroute(skb, entry);
 190                break;
 191        case AF_INET6:
 192                nf_ip6_saveroute(skb, entry);
 193                break;
 194        }
 195
 196        status = qh->outfn(entry, queuenum);
 197
 198        if (status < 0) {
 199                nf_queue_entry_release_refs(entry);
 200                goto err;
 201        }
 202
 203        return 0;
 204
 205err:
 206        kfree(entry);
 207        return status;
 208}
 209
 210/* Packets leaving via this function must come back through nf_reinject(). */
 211int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
 212             const struct nf_hook_entries *entries, unsigned int index,
 213             unsigned int verdict)
 214{
 215        int ret;
 216
 217        ret = __nf_queue(skb, state, entries, index, verdict >> NF_VERDICT_QBITS);
 218        if (ret < 0) {
 219                if (ret == -ESRCH &&
 220                    (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
 221                        return 1;
 222                kfree_skb(skb);
 223        }
 224
 225        return 0;
 226}
 227
 228static unsigned int nf_iterate(struct sk_buff *skb,
 229                               struct nf_hook_state *state,
 230                               const struct nf_hook_entries *hooks,
 231                               unsigned int *index)
 232{
 233        const struct nf_hook_entry *hook;
 234        unsigned int verdict, i = *index;
 235
 236        while (i < hooks->num_hook_entries) {
 237                hook = &hooks->hooks[i];
 238repeat:
 239                verdict = nf_hook_entry_hookfn(hook, skb, state);
 240                if (verdict != NF_ACCEPT) {
 241                        if (verdict != NF_REPEAT)
 242                                return verdict;
 243                        goto repeat;
 244                }
 245                i++;
 246        }
 247
 248        *index = i;
 249        return NF_ACCEPT;
 250}
 251
 252static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
 253{
 254        switch (pf) {
 255#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
 256        case NFPROTO_BRIDGE:
 257                return rcu_dereference(net->nf.hooks_bridge[hooknum]);
 258#endif
 259        case NFPROTO_IPV4:
 260                return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
 261        case NFPROTO_IPV6:
 262                return rcu_dereference(net->nf.hooks_ipv6[hooknum]);
 263        default:
 264                WARN_ON_ONCE(1);
 265                return NULL;
 266        }
 267
 268        return NULL;
 269}
 270
 271/* Caller must hold rcu read-side lock */
 272void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
 273{
 274        const struct nf_hook_entry *hook_entry;
 275        const struct nf_hook_entries *hooks;
 276        struct sk_buff *skb = entry->skb;
 277        const struct net *net;
 278        unsigned int i;
 279        int err;
 280        u8 pf;
 281
 282        net = entry->state.net;
 283        pf = entry->state.pf;
 284
 285        hooks = nf_hook_entries_head(net, pf, entry->state.hook);
 286
 287        nf_queue_entry_release_refs(entry);
 288
 289        i = entry->hook_index;
 290        if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) {
 291                kfree_skb(skb);
 292                kfree(entry);
 293                return;
 294        }
 295
 296        hook_entry = &hooks->hooks[i];
 297
 298        /* Continue traversal iff userspace said ok... */
 299        if (verdict == NF_REPEAT)
 300                verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
 301
 302        if (verdict == NF_ACCEPT) {
 303                if (nf_reroute(skb, entry) < 0)
 304                        verdict = NF_DROP;
 305        }
 306
 307        if (verdict == NF_ACCEPT) {
 308next_hook:
 309                ++i;
 310                verdict = nf_iterate(skb, &entry->state, hooks, &i);
 311        }
 312
 313        switch (verdict & NF_VERDICT_MASK) {
 314        case NF_ACCEPT:
 315        case NF_STOP:
 316                local_bh_disable();
 317                entry->state.okfn(entry->state.net, entry->state.sk, skb);
 318                local_bh_enable();
 319                break;
 320        case NF_QUEUE:
 321                err = nf_queue(skb, &entry->state, hooks, i, verdict);
 322                if (err == 1)
 323                        goto next_hook;
 324                break;
 325        case NF_STOLEN:
 326                break;
 327        default:
 328                kfree_skb(skb);
 329        }
 330
 331        kfree(entry);
 332}
 333EXPORT_SYMBOL(nf_reinject);
 334