source: trunk/target/linux/generic/patches-2.6.35/150-netfilter_imq.patch @ 23970

Last change on this file since 23970 was 23970, checked in by acoul, 5 years ago

linux/generic: add imq patches for linux kernels 2.6.35,36,37. (closes #8211)

File size: 36.1 KB
  • new file drivers/net/imq.c

    - +  
     1/* 
     2 *             Pseudo-driver for the intermediate queue device. 
     3 * 
     4 *             This program is free software; you can redistribute it and/or 
     5 *             modify it under the terms of the GNU General Public License 
     6 *             as published by the Free Software Foundation; either version 
     7 *             2 of the License, or (at your option) any later version. 
     8 * 
     9 * Authors:    Patrick McHardy, <kaber@trash.net> 
     10 * 
     11 *            The first version was written by Martin Devera, <devik@cdi.cz> 
     12 * 
     13 * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz> 
     14 *              - Update patch to 2.4.21 
     15 *             Sebastian Strollo <sstrollo@nortelnetworks.com> 
     16 *              - Fix "Dead-loop on netdevice imq"-issue 
     17 *             Marcel Sebek <sebek64@post.cz> 
     18 *              - Update to 2.6.2-rc1 
     19 * 
     20 *             After some time of inactivity there is a group taking care 
     21 *             of IMQ again: http://www.linuximq.net 
     22 * 
     23 * 
     24 *             2004/06/30 - New version of IMQ patch to kernels <=2.6.7 
     25 *             including the following changes: 
     26 * 
     27 *             - Correction of ipv6 support "+"s issue (Hasso Tepper) 
     28 *             - Correction of imq_init_devs() issue that resulted in 
     29 *             kernel OOPS unloading IMQ as module (Norbert Buchmuller) 
     30 *             - Addition of functionality to choose number of IMQ devices 
     31 *             during kernel config (Andre Correa) 
     32 *             - Addition of functionality to choose how IMQ hooks on 
     33 *             PRE and POSTROUTING (after or before NAT) (Andre Correa) 
     34 *             - Cosmetic corrections (Norbert Buchmuller) (Andre Correa) 
     35 * 
     36 * 
     37 *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were 
     38 *             released with almost no problems. 2.6.14-x was released 
     39 *             with some important changes: nfcache was removed; After 
     40 *             some weeks of trouble we figured out that some IMQ fields 
     41 *             in skb were missing in skbuff.c - skb_clone and copy_skb_header. 
     42 *             These functions are correctly patched by this new patch version. 
     43 * 
     44 *             Thanks for all who helped to figure out all the problems with 
     45 *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX, 
     46 *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully 
     47 *             I didn't forget anybody). I apologize again for my lack of time. 
     48 * 
     49 * 
     50 *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead  
     51 *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid 
     52 *             recursive locking. New initialization routines to fix 'rmmod' not 
     53 *             working anymore. Used code from ifb.c. (Jussi Kivilinna) 
     54 * 
     55 *             2008/08/06 - 2.6.26 - (JK) 
     56 *              - Replaced tasklet with 'netif_schedule()'. 
     57 *              - Cleaned up and added comments for imq_nf_queue(). 
     58 * 
     59 *             2009/04/12 
     60 *              - Add skb_save_cb/skb_restore_cb helper functions for backuping 
     61 *                control buffer. This is needed because qdisc-layer on kernels 
     62 *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna) 
     63 *              - Add better locking for IMQ device. Hopefully this will solve 
     64 *                SMP issues. (Jussi Kivilinna) 
     65 *              - Port to 2.6.27 
     66 *              - Port to 2.6.28 
     67 *              - Port to 2.6.29 + fix rmmod not working 
     68 * 
     69 *             2009/04/20 - (Jussi Kivilinna) 
     70 *              - Use netdevice feature flags to avoid extra packet handling 
     71 *                by core networking layer and possibly increase performance. 
     72 * 
     73 *             2009/09/26 - (Jussi Kivilinna) 
     74 *              - Add imq_nf_reinject_lockless to fix deadlock with 
     75 *                imq_nf_queue/imq_nf_reinject. 
     76 * 
     77 *             2009/12/08 - (Jussi Kivilinna) 
     78 *              - Port to 2.6.32 
     79 *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit() 
     80 *              - Also add better error checking for skb->nf_queue_entry usage 
     81 * 
     82 *             2010/02/25 - (Jussi Kivilinna) 
     83 *              - Port to 2.6.33 
     84 * 
     85 *             2010/08/12 - (Jussi Kivilinna) 
     86 *              - Port to 2.6.35 
     87 * 
     88 *             Also, many thanks to pablo Sebastian Greco for making the initial 
     89 *             patch and to those who helped the testing. 
     90 * 
     91 *             More info at: http://www.linuximq.net/ (Andre Correa) 
     92 */ 
     93 
     94#include <linux/module.h> 
     95#include <linux/kernel.h> 
     96#include <linux/moduleparam.h> 
     97#include <linux/list.h> 
     98#include <linux/skbuff.h> 
     99#include <linux/netdevice.h> 
     100#include <linux/etherdevice.h> 
     101#include <linux/rtnetlink.h> 
     102#include <linux/if_arp.h> 
     103#include <linux/netfilter.h> 
     104#include <linux/netfilter_ipv4.h> 
     105#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     106        #include <linux/netfilter_ipv6.h> 
     107#endif 
     108#include <linux/imq.h> 
     109#include <net/pkt_sched.h> 
     110#include <net/netfilter/nf_queue.h> 
     111 
     112static nf_hookfn imq_nf_hook; 
     113 
     114static struct nf_hook_ops imq_ingress_ipv4 = { 
     115        .hook           = imq_nf_hook, 
     116        .owner          = THIS_MODULE, 
     117        .pf             = PF_INET, 
     118        .hooknum        = NF_INET_PRE_ROUTING, 
     119#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     120        .priority       = NF_IP_PRI_MANGLE + 1 
     121#else 
     122        .priority       = NF_IP_PRI_NAT_DST + 1 
     123#endif 
     124}; 
     125 
     126static struct nf_hook_ops imq_egress_ipv4 = { 
     127        .hook           = imq_nf_hook, 
     128        .owner          = THIS_MODULE, 
     129        .pf             = PF_INET, 
     130        .hooknum        = NF_INET_POST_ROUTING, 
     131#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 
     132        .priority       = NF_IP_PRI_LAST 
     133#else 
     134        .priority       = NF_IP_PRI_NAT_SRC - 1 
     135#endif 
     136}; 
     137 
     138#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     139static struct nf_hook_ops imq_ingress_ipv6 = { 
     140        .hook           = imq_nf_hook, 
     141        .owner          = THIS_MODULE, 
     142        .pf             = PF_INET6, 
     143        .hooknum        = NF_INET_PRE_ROUTING, 
     144#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     145        .priority       = NF_IP6_PRI_MANGLE + 1 
     146#else 
     147        .priority       = NF_IP6_PRI_NAT_DST + 1 
     148#endif 
     149}; 
     150 
     151static struct nf_hook_ops imq_egress_ipv6 = { 
     152        .hook           = imq_nf_hook, 
     153        .owner          = THIS_MODULE, 
     154        .pf             = PF_INET6, 
     155        .hooknum        = NF_INET_POST_ROUTING, 
     156#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 
     157        .priority       = NF_IP6_PRI_LAST 
     158#else 
     159        .priority       = NF_IP6_PRI_NAT_SRC - 1 
     160#endif 
     161}; 
     162#endif 
     163 
     164#if defined(CONFIG_IMQ_NUM_DEVS) 
     165static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS; 
     166#else 
     167static unsigned int numdevs = IMQ_MAX_DEVS; 
     168#endif 
     169 
     170static DEFINE_SPINLOCK(imq_nf_queue_lock); 
     171 
     172static struct net_device *imq_devs_cache[IMQ_MAX_DEVS]; 
     173 
     174 
     175static struct net_device_stats *imq_get_stats(struct net_device *dev) 
     176{ 
     177        return &dev->stats; 
     178} 
     179 
     180/* called for packets kfree'd in qdiscs at places other than enqueue */ 
     181static void imq_skb_destructor(struct sk_buff *skb) 
     182{ 
     183        struct nf_queue_entry *entry = skb->nf_queue_entry; 
     184 
     185        skb->nf_queue_entry = NULL; 
     186 
     187        if (entry) { 
     188                nf_queue_entry_release_refs(entry); 
     189                kfree(entry); 
     190        } 
     191 
     192        skb_restore_cb(skb); /* kfree backup */ 
     193} 
     194 
     195/* locking not needed when called from imq_nf_queue */ 
     196static void imq_nf_reinject_lockless(struct nf_queue_entry *entry, 
     197                                                unsigned int verdict) 
     198{ 
     199        int status; 
     200 
     201        if (!entry->next_outfn) { 
     202                nf_reinject(entry, verdict); 
     203                return; 
     204        } 
     205 
     206        status = entry->next_outfn(entry, entry->next_queuenum); 
     207        if (status < 0) { 
     208                nf_queue_entry_release_refs(entry); 
     209                kfree_skb(entry->skb); 
     210                kfree(entry); 
     211        } 
     212} 
     213 
     214static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 
     215{ 
     216        int status; 
     217 
     218        if (!entry->next_outfn) { 
     219                spin_lock_bh(&imq_nf_queue_lock); 
     220                nf_reinject(entry, verdict); 
     221                spin_unlock_bh(&imq_nf_queue_lock); 
     222                return; 
     223        } 
     224 
     225        rcu_read_lock(); 
     226        local_bh_disable(); 
     227        status = entry->next_outfn(entry, entry->next_queuenum); 
     228        local_bh_enable(); 
     229        if (status < 0) { 
     230                nf_queue_entry_release_refs(entry); 
     231                kfree_skb(entry->skb); 
     232                kfree(entry); 
     233        } 
     234 
     235        rcu_read_unlock(); 
     236} 
     237 
     238static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 
     239{ 
     240        struct nf_queue_entry *entry = skb->nf_queue_entry; 
     241 
     242        skb->nf_queue_entry = NULL; 
     243        dev->trans_start = jiffies; 
     244 
     245        dev->stats.tx_bytes += skb->len; 
     246        dev->stats.tx_packets++; 
     247 
     248        if (entry == NULL) { 
     249                /* We don't know what is going on here.. packet is queued for 
     250                 * imq device, but (probably) not by us. 
     251                 * 
     252                 * If this packet was not send here by imq_nf_queue(), then 
     253                 * skb_save_cb() was not used and skb_free() should not show: 
     254                 *   WARNING: IMQ: kfree_skb: skb->cb_next:.. 
     255                 * and/or 
     256                 *   WARNING: IMQ: kfree_skb: skb->nf_queue_entry... 
     257                 * 
     258                 * However if this message is shown, then IMQ is somehow broken 
     259                 * and you should report this to linuximq.net. 
     260                 */ 
     261 
     262                /* imq_dev_xmit is black hole that eats all packets, report that 
     263                 * we eat this packet happily and increase dropped counters. 
     264                 */ 
     265 
     266                dev->stats.tx_dropped++; 
     267                dev_kfree_skb(skb); 
     268 
     269                return NETDEV_TX_OK; 
     270        } 
     271 
     272        skb_restore_cb(skb); /* restore skb->cb */ 
     273 
     274        skb->imq_flags = 0; 
     275        skb->destructor = NULL; 
     276 
     277        imq_nf_reinject(entry, NF_ACCEPT); 
     278 
     279        return NETDEV_TX_OK; 
     280} 
     281 
     282static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num) 
     283{ 
     284        struct net_device *dev; 
     285        struct sk_buff *skb_orig, *skb, *skb_shared; 
     286        struct Qdisc *q; 
     287        struct netdev_queue *txq; 
     288        int users, index; 
     289        int retval = -EINVAL; 
     290 
     291        index = entry->skb->imq_flags & IMQ_F_IFMASK; 
     292        if (unlikely(index > numdevs - 1)) { 
     293                if (net_ratelimit()) 
     294                        printk(KERN_WARNING 
     295                               "IMQ: invalid device specified, highest is %u\n", 
     296                               numdevs - 1); 
     297                retval = -EINVAL; 
     298                goto out; 
     299        } 
     300 
     301        /* check for imq device by index from cache */ 
     302        dev = imq_devs_cache[index]; 
     303        if (unlikely(!dev)) { 
     304                char buf[8]; 
     305 
     306                /* get device by name and cache result */ 
     307                snprintf(buf, sizeof(buf), "imq%d", index); 
     308                dev = dev_get_by_name(&init_net, buf); 
     309                if (!dev) { 
     310                        /* not found ?!*/ 
     311                        BUG(); 
     312                        retval = -ENODEV; 
     313                        goto out; 
     314                } 
     315 
     316                imq_devs_cache[index] = dev; 
     317                dev_put(dev); 
     318        } 
     319 
     320        if (unlikely(!(dev->flags & IFF_UP))) { 
     321                entry->skb->imq_flags = 0; 
     322                imq_nf_reinject_lockless(entry, NF_ACCEPT); 
     323                retval = 0; 
     324                goto out; 
     325        } 
     326        dev->last_rx = jiffies; 
     327 
     328        skb = entry->skb; 
     329        skb_orig = NULL; 
     330 
     331        /* skb has owner? => make clone */ 
     332        if (unlikely(skb->destructor)) { 
     333                skb_orig = skb; 
     334                skb = skb_clone(skb, GFP_ATOMIC); 
     335                if (!skb) { 
     336                        retval = -ENOMEM; 
     337                        goto out; 
     338                } 
     339                entry->skb = skb; 
     340        } 
     341 
     342        skb->nf_queue_entry = entry; 
     343 
     344        dev->stats.rx_bytes += skb->len; 
     345        dev->stats.rx_packets++; 
     346 
     347        txq = dev_pick_tx(dev, skb); 
     348 
     349        q = rcu_dereference(txq->qdisc); 
     350        if (unlikely(!q->enqueue)) 
     351                goto packet_not_eaten_by_imq_dev; 
     352 
     353        spin_lock_bh(qdisc_lock(q)); 
     354 
     355        users = atomic_read(&skb->users); 
     356 
     357        skb_shared = skb_get(skb); /* increase reference count by one */ 
     358        skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will 
     359                                        overwrite it */ 
     360        qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */ 
     361 
     362        if (likely(atomic_read(&skb_shared->users) == users + 1)) { 
     363                kfree_skb(skb_shared); /* decrease reference count by one */ 
     364 
     365                skb->destructor = &imq_skb_destructor; 
     366 
     367                /* cloned? */ 
     368                if (skb_orig) 
     369                        kfree_skb(skb_orig); /* free original */ 
     370 
     371                spin_unlock_bh(qdisc_lock(q)); 
     372 
     373                /* schedule qdisc dequeue */ 
     374                __netif_schedule(q); 
     375 
     376                retval = 0; 
     377                goto out; 
     378        } else { 
     379                skb_restore_cb(skb_shared); /* restore skb->cb */ 
     380                skb->nf_queue_entry = NULL; 
     381                /* qdisc dropped packet and decreased skb reference count of 
     382                 * skb, so we don't really want to and try refree as that would 
     383                 * actually destroy the skb. */ 
     384                spin_unlock_bh(qdisc_lock(q)); 
     385                goto packet_not_eaten_by_imq_dev; 
     386        } 
     387 
     388packet_not_eaten_by_imq_dev: 
     389        /* cloned? restore original */ 
     390        if (skb_orig) { 
     391                kfree_skb(skb); 
     392                entry->skb = skb_orig; 
     393        } 
     394        retval = -1; 
     395out: 
     396        return retval; 
     397} 
     398 
     399static struct nf_queue_handler nfqh = { 
     400        .name  = "imq", 
     401        .outfn = imq_nf_queue, 
     402}; 
     403 
     404static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb, 
     405                                const struct net_device *indev, 
     406                                const struct net_device *outdev, 
     407                                int (*okfn)(struct sk_buff *)) 
     408{ 
     409        if (pskb->imq_flags & IMQ_F_ENQUEUE) 
     410                return NF_QUEUE; 
     411 
     412        return NF_ACCEPT; 
     413} 
     414 
     415static int imq_close(struct net_device *dev) 
     416{ 
     417        netif_stop_queue(dev); 
     418        return 0; 
     419} 
     420 
     421static int imq_open(struct net_device *dev) 
     422{ 
     423        netif_start_queue(dev); 
     424        return 0; 
     425} 
     426 
     427static const struct net_device_ops imq_netdev_ops = { 
     428        .ndo_open               = imq_open, 
     429        .ndo_stop               = imq_close, 
     430        .ndo_start_xmit         = imq_dev_xmit, 
     431        .ndo_get_stats          = imq_get_stats, 
     432}; 
     433 
     434static void imq_setup(struct net_device *dev) 
     435{ 
     436        dev->netdev_ops         = &imq_netdev_ops; 
     437        dev->type               = ARPHRD_VOID; 
     438        dev->mtu                = 16000; 
     439        dev->tx_queue_len       = 11000; 
     440        dev->flags              = IFF_NOARP; 
     441        dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST | 
     442                                  NETIF_F_GSO | NETIF_F_HW_CSUM | 
     443                                  NETIF_F_HIGHDMA; 
     444        dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE; 
     445} 
     446 
     447static int imq_validate(struct nlattr *tb[], struct nlattr *data[]) 
     448{ 
     449        int ret = 0; 
     450 
     451        if (tb[IFLA_ADDRESS]) { 
     452                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) { 
     453                        ret = -EINVAL; 
     454                        goto end; 
     455                } 
     456                if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) { 
     457                        ret = -EADDRNOTAVAIL; 
     458                        goto end; 
     459                } 
     460        } 
     461        return 0; 
     462end: 
     463        printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret); 
     464        return ret; 
     465} 
     466 
     467static struct rtnl_link_ops imq_link_ops __read_mostly = { 
     468        .kind           = "imq", 
     469        .priv_size      = 0, 
     470        .setup          = imq_setup, 
     471        .validate       = imq_validate, 
     472}; 
     473 
     474static int __init imq_init_hooks(void) 
     475{ 
     476        int err; 
     477 
     478        nf_register_queue_imq_handler(&nfqh); 
     479 
     480        err = nf_register_hook(&imq_ingress_ipv4); 
     481        if (err) 
     482                goto err1; 
     483 
     484        err = nf_register_hook(&imq_egress_ipv4); 
     485        if (err) 
     486                goto err2; 
     487 
     488#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     489        err = nf_register_hook(&imq_ingress_ipv6); 
     490        if (err) 
     491                goto err3; 
     492 
     493        err = nf_register_hook(&imq_egress_ipv6); 
     494        if (err) 
     495                goto err4; 
     496#endif 
     497 
     498        return 0; 
     499 
     500#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     501err4: 
     502        nf_unregister_hook(&imq_ingress_ipv6); 
     503err3: 
     504        nf_unregister_hook(&imq_egress_ipv4); 
     505#endif 
     506err2: 
     507        nf_unregister_hook(&imq_ingress_ipv4); 
     508err1: 
     509        nf_unregister_queue_imq_handler(); 
     510        return err; 
     511} 
     512 
     513static int __init imq_init_one(int index) 
     514{ 
     515        struct net_device *dev; 
     516        int ret; 
     517 
     518        dev = alloc_netdev(0, "imq%d", imq_setup); 
     519        if (!dev) 
     520                return -ENOMEM; 
     521 
     522        ret = dev_alloc_name(dev, dev->name); 
     523        if (ret < 0) 
     524                goto fail; 
     525 
     526        dev->rtnl_link_ops = &imq_link_ops; 
     527        ret = register_netdevice(dev); 
     528        if (ret < 0) 
     529                goto fail; 
     530 
     531        return 0; 
     532fail: 
     533        free_netdev(dev); 
     534        return ret; 
     535} 
     536 
     537static int __init imq_init_devs(void) 
     538{ 
     539        int err, i; 
     540 
     541        if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) { 
     542                printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n", 
     543                       IMQ_MAX_DEVS); 
     544                return -EINVAL; 
     545        } 
     546 
     547        rtnl_lock(); 
     548        err = __rtnl_link_register(&imq_link_ops); 
     549 
     550        for (i = 0; i < numdevs && !err; i++) 
     551                err = imq_init_one(i); 
     552 
     553        if (err) { 
     554                __rtnl_link_unregister(&imq_link_ops); 
     555                memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     556        } 
     557        rtnl_unlock(); 
     558 
     559        return err; 
     560} 
     561 
     562static int __init imq_init_module(void) 
     563{ 
     564        int err; 
     565 
     566#if defined(CONFIG_IMQ_NUM_DEVS) 
     567        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16); 
     568        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2); 
     569        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK); 
     570#endif 
     571 
     572        err = imq_init_devs(); 
     573        if (err) { 
     574                printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n"); 
     575                return err; 
     576        } 
     577 
     578        err = imq_init_hooks(); 
     579        if (err) { 
     580                printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n"); 
     581                rtnl_link_unregister(&imq_link_ops); 
     582                memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     583                return err; 
     584        } 
     585 
     586        printk(KERN_INFO "IMQ driver loaded successfully.\n"); 
     587 
     588#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     589        printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n"); 
     590#else 
     591        printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n"); 
     592#endif 
     593#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     594        printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n"); 
     595#else 
     596        printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n"); 
     597#endif 
     598 
     599        return 0; 
     600} 
     601 
     602static void __exit imq_unhook(void) 
     603{ 
     604#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     605        nf_unregister_hook(&imq_ingress_ipv6); 
     606        nf_unregister_hook(&imq_egress_ipv6); 
     607#endif 
     608        nf_unregister_hook(&imq_ingress_ipv4); 
     609        nf_unregister_hook(&imq_egress_ipv4); 
     610 
     611        nf_unregister_queue_imq_handler(); 
     612} 
     613 
     614static void __exit imq_cleanup_devs(void) 
     615{ 
     616        rtnl_link_unregister(&imq_link_ops); 
     617        memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     618} 
     619 
     620static void __exit imq_exit_module(void) 
     621{ 
     622        imq_unhook(); 
     623        imq_cleanup_devs(); 
     624        printk(KERN_INFO "IMQ driver unloaded successfully.\n"); 
     625} 
     626 
     627module_init(imq_init_module); 
     628module_exit(imq_exit_module); 
     629 
     630module_param(numdevs, int, 0); 
     631MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will " 
     632                        "be created)"); 
     633MODULE_AUTHOR("http://www.linuximq.net"); 
     634MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See " 
     635                        "http://www.linuximq.net/ for more information."); 
     636MODULE_LICENSE("GPL"); 
     637MODULE_ALIAS_RTNL_LINK("imq"); 
     638 
  • drivers/net/Kconfig

    a b config EQUALIZER 
    121121          To compile this driver as a module, choose M here: the module 
    122122          will be called eql.  If unsure, say N. 
    123123 
     124config IMQ 
     125        tristate "IMQ (intermediate queueing device) support" 
     126        depends on NETDEVICES && NETFILTER 
     127        ---help--- 
     128          The IMQ device(s) is used as placeholder for QoS queueing 
     129          disciplines. Every packet entering/leaving the IP stack can be 
     130          directed through the IMQ device where it's enqueued/dequeued to the 
     131          attached qdisc. This allows you to treat network devices as classes 
     132          and distribute bandwidth among them. Iptables is used to specify 
     133          through which IMQ device, if any, packets travel. 
     134 
     135          More information at: http://www.linuximq.net/ 
     136 
     137          To compile this driver as a module, choose M here: the module 
     138          will be called imq.  If unsure, say N. 
     139 
     140choice 
     141        prompt "IMQ behavior (PRE/POSTROUTING)" 
     142        depends on IMQ 
     143        default IMQ_BEHAVIOR_AB 
     144        help 
     145 
     146                This settings defines how IMQ behaves in respect to its 
     147                hooking in PREROUTING and POSTROUTING. 
     148 
     149                IMQ can work in any of the following ways: 
     150 
     151                    PREROUTING   |      POSTROUTING 
     152                -----------------|------------------- 
     153                #1  After NAT    |      After NAT 
     154                #2  After NAT    |      Before NAT 
     155                #3  Before NAT   |      After NAT 
     156                #4  Before NAT   |      Before NAT 
     157 
     158                The default behavior is to hook before NAT on PREROUTING 
     159                and after NAT on POSTROUTING (#3). 
     160 
     161                This settings are specially usefull when trying to use IMQ 
     162                to shape NATed clients. 
     163 
     164                More information can be found at: www.linuximq.net 
     165 
     166                If not sure leave the default settings alone. 
     167 
     168config IMQ_BEHAVIOR_AA 
     169        bool "IMQ AA" 
     170        help 
     171                This settings defines how IMQ behaves in respect to its 
     172                hooking in PREROUTING and POSTROUTING. 
     173 
     174                Choosing this option will make IMQ hook like this: 
     175 
     176                PREROUTING:   After NAT 
     177                POSTROUTING:  After NAT 
     178 
     179                More information can be found at: www.linuximq.net 
     180 
     181                If not sure leave the default settings alone. 
     182 
     183config IMQ_BEHAVIOR_AB 
     184        bool "IMQ AB" 
     185        help 
     186                This settings defines how IMQ behaves in respect to its 
     187                hooking in PREROUTING and POSTROUTING. 
     188 
     189                Choosing this option will make IMQ hook like this: 
     190 
     191                PREROUTING:   After NAT 
     192                POSTROUTING:  Before NAT 
     193 
     194                More information can be found at: www.linuximq.net 
     195 
     196                If not sure leave the default settings alone. 
     197 
     198config IMQ_BEHAVIOR_BA 
     199        bool "IMQ BA" 
     200        help 
     201                This settings defines how IMQ behaves in respect to its 
     202                hooking in PREROUTING and POSTROUTING. 
     203 
     204                Choosing this option will make IMQ hook like this: 
     205 
     206                PREROUTING:   Before NAT 
     207                POSTROUTING:  After NAT 
     208 
     209                More information can be found at: www.linuximq.net 
     210 
     211                If not sure leave the default settings alone. 
     212 
     213config IMQ_BEHAVIOR_BB 
     214        bool "IMQ BB" 
     215        help 
     216                This settings defines how IMQ behaves in respect to its 
     217                hooking in PREROUTING and POSTROUTING. 
     218 
     219                Choosing this option will make IMQ hook like this: 
     220 
     221                PREROUTING:   Before NAT 
     222                POSTROUTING:  Before NAT 
     223 
     224                More information can be found at: www.linuximq.net 
     225 
     226                If not sure leave the default settings alone. 
     227 
     228endchoice 
     229 
     230config IMQ_NUM_DEVS 
     231 
     232        int "Number of IMQ devices" 
     233        range 2 16 
     234        depends on IMQ 
     235        default "16" 
     236        help 
     237 
     238                This settings defines how many IMQ devices will be 
     239                created. 
     240 
     241                The default value is 16. 
     242 
     243                More information can be found at: www.linuximq.net 
     244 
     245                If not sure leave the default settings alone. 
     246 
    124247config TUN 
    125248        tristate "Universal TUN/TAP device driver support" 
    126249        select CRC32 
  • drivers/net/Makefile

    a b obj-$(CONFIG_SLHC) += slhc.o 
    169169obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o 
    170170 
    171171obj-$(CONFIG_DUMMY) += dummy.o 
     172obj-$(CONFIG_IMQ) += imq.o 
    172173obj-$(CONFIG_IFB) += ifb.o 
    173174obj-$(CONFIG_MACVLAN) += macvlan.o 
    174175obj-$(CONFIG_MACVTAP) += macvtap.o 
  • new file include/linux/imq.h

    - +  
     1#ifndef _IMQ_H 
     2#define _IMQ_H 
     3 
     4/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */ 
     5#define IMQ_F_BITS      5 
     6 
     7#define IMQ_F_IFMASK    0x0f 
     8#define IMQ_F_ENQUEUE   0x10 
     9 
     10#define IMQ_MAX_DEVS    (IMQ_F_IFMASK + 1) 
     11 
     12#endif /* _IMQ_H */ 
     13 
  • include/linux/netdevice.h

    a b extern int dev_alloc_name(struct net_de 
    12811281extern int              dev_open(struct net_device *dev); 
    12821282extern int              dev_close(struct net_device *dev); 
    12831283extern void             dev_disable_lro(struct net_device *dev); 
     1284extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb); 
    12841285extern int              dev_queue_xmit(struct sk_buff *skb); 
    12851286extern int              register_netdevice(struct net_device *dev); 
    12861287extern void             unregister_netdevice_queue(struct net_device *dev, 
  • new file include/linux/netfilter/xt_IMQ.h

    - +  
     1#ifndef _XT_IMQ_H 
     2#define _XT_IMQ_H 
     3 
     4struct xt_imq_info { 
     5        unsigned int todev;     /* target imq device */ 
     6}; 
     7 
     8#endif /* _XT_IMQ_H */ 
     9 
  • new file include/linux/netfilter_ipv4/ipt_IMQ.h

    - +  
     1#ifndef _IPT_IMQ_H 
     2#define _IPT_IMQ_H 
     3 
     4/* Backwards compatibility for old userspace */ 
     5#include <linux/netfilter/xt_IMQ.h> 
     6 
     7#define ipt_imq_info xt_imq_info 
     8 
     9#endif /* _IPT_IMQ_H */ 
     10 
  • new file include/linux/netfilter_ipv6/ip6t_IMQ.h

    - +  
     1#ifndef _IP6T_IMQ_H 
     2#define _IP6T_IMQ_H 
     3 
     4/* Backwards compatibility for old userspace */ 
     5#include <linux/netfilter/xt_IMQ.h> 
     6 
     7#define ip6t_imq_info xt_imq_info 
     8 
     9#endif /* _IP6T_IMQ_H */ 
     10 
  • include/linux/skbuff.h

    a b  
    2929#include <linux/rcupdate.h> 
    3030#include <linux/dmaengine.h> 
    3131#include <linux/hrtimer.h> 
     32#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     33#include <linux/imq.h> 
     34#endif 
    3235 
    3336/* Don't change this without changing skb_csum_unnecessary! */ 
    3437#define CHECKSUM_NONE 0 
    struct sk_buff { 
    329332         * first. This is owned by whoever has the skb queued ATM. 
    330333         */ 
    331334        char                    cb[48] __aligned(8); 
     335#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     336        void                    *cb_next; 
     337#endif 
    332338 
    333339        unsigned long           _skb_refdst; 
    334340#ifdef CONFIG_XFRM 
    struct sk_buff { 
    365371        struct nf_conntrack     *nfct; 
    366372        struct sk_buff          *nfct_reasm; 
    367373#endif 
     374#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     375        struct nf_queue_entry   *nf_queue_entry; 
     376#endif 
    368377#ifdef CONFIG_BRIDGE_NETFILTER 
    369378        struct nf_bridge_info   *nf_bridge; 
    370379#endif 
    struct sk_buff { 
    391400 
    392401        /* 0/14 bit hole */ 
    393402 
     403#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     404        __u8                    imq_flags:IMQ_F_BITS; 
     405#endif 
     406 
    394407#ifdef CONFIG_NET_DMA 
    395408        dma_cookie_t            dma_cookie; 
    396409#endif 
    static inline struct rtable *skb_rtable( 
    489502        return (struct rtable *)skb_dst(skb); 
    490503} 
    491504 
     505 
     506#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     507extern int skb_save_cb(struct sk_buff *skb); 
     508extern int skb_restore_cb(struct sk_buff *skb); 
     509#endif 
     510 
    492511extern void kfree_skb(struct sk_buff *skb); 
    493512extern void consume_skb(struct sk_buff *skb); 
    494513extern void            __kfree_skb(struct sk_buff *skb); 
    static inline void __nf_copy(struct sk_b 
    20362055        dst->nfct_reasm = src->nfct_reasm; 
    20372056        nf_conntrack_get_reasm(src->nfct_reasm); 
    20382057#endif 
     2058#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     2059        dst->imq_flags = src->imq_flags; 
     2060        dst->nf_queue_entry = src->nf_queue_entry; 
     2061#endif 
    20392062#ifdef CONFIG_BRIDGE_NETFILTER 
    20402063        dst->nf_bridge  = src->nf_bridge; 
    20412064        nf_bridge_get(src->nf_bridge); 
  • include/net/netfilter/nf_queue.h

    a b struct nf_queue_entry { 
    1313        struct net_device       *indev; 
    1414        struct net_device       *outdev; 
    1515        int                     (*okfn)(struct sk_buff *); 
     16 
     17#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     18        int                     (*next_outfn)(struct nf_queue_entry *entry, 
     19                                              unsigned int queuenum); 
     20        unsigned int            next_queuenum; 
     21#endif 
    1622}; 
    1723 
    1824#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry)) 
    extern int nf_unregister_queue_handler(u 
    3036                                       const struct nf_queue_handler *qh); 
    3137extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh); 
    3238extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); 
     39extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry); 
     40 
     41#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     42extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh); 
     43extern void nf_unregister_queue_imq_handler(void); 
     44#endif 
    3345 
    3446#endif /* _NF_QUEUE_H */ 
  • net/core/dev.c

    a b  
    9898#include <net/net_namespace.h> 
    9999#include <net/sock.h> 
    100100#include <linux/rtnetlink.h> 
     101#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     102#include <linux/imq.h> 
     103#endif 
    101104#include <linux/proc_fs.h> 
    102105#include <linux/seq_file.h> 
    103106#include <linux/stat.h> 
    int dev_hard_start_xmit(struct sk_buff * 
    19311934        int rc = NETDEV_TX_OK; 
    19321935 
    19331936        if (likely(!skb->next)) { 
    1934                 if (!list_empty(&ptype_all)) 
     1937                if (!list_empty(&ptype_all) 
     1938#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     1939                        && !(skb->imq_flags & IMQ_F_ENQUEUE) 
     1940#endif 
     1941                   ) 
    19351942                        dev_queue_xmit_nit(skb, dev); 
    19361943 
    19371944                /* 
    static inline u16 dev_cap_txqueue(struct 
    20272034        return queue_index; 
    20282035} 
    20292036 
    2030 static struct netdev_queue *dev_pick_tx(struct net_device *dev, 
    2031                                         struct sk_buff *skb) 
     2037struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb) 
    20322038{ 
    20332039        int queue_index; 
    20342040        struct sock *sk = skb->sk; 
    static struct netdev_queue *dev_pick_tx( 
    20572063        skb_set_queue_mapping(skb, queue_index); 
    20582064        return netdev_get_tx_queue(dev, queue_index); 
    20592065} 
     2066EXPORT_SYMBOL(dev_pick_tx); 
    20602067 
    20612068static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, 
    20622069                                 struct net_device *dev, 
  • net/core/skbuff.c

    a b  
    7272 
    7373static struct kmem_cache *skbuff_head_cache __read_mostly; 
    7474static struct kmem_cache *skbuff_fclone_cache __read_mostly; 
     75#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     76static struct kmem_cache *skbuff_cb_store_cache __read_mostly; 
     77#endif 
    7578 
    7679static void sock_pipe_buf_release(struct pipe_inode_info *pipe, 
    7780                                  struct pipe_buffer *buf) 
    static int sock_pipe_buf_steal(struct pi 
    9194        return 1; 
    9295} 
    9396 
     97#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     98/* Control buffer save/restore for IMQ devices */ 
     99struct skb_cb_table { 
     100        void                    *cb_next; 
     101        atomic_t                refcnt; 
     102        char                    cb[48]; 
     103}; 
     104 
     105static DEFINE_SPINLOCK(skb_cb_store_lock); 
     106 
     107int skb_save_cb(struct sk_buff *skb) 
     108{ 
     109        struct skb_cb_table *next; 
     110 
     111        next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC); 
     112        if (!next) 
     113                return -ENOMEM; 
     114 
     115        BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb)); 
     116 
     117        memcpy(next->cb, skb->cb, sizeof(skb->cb)); 
     118        next->cb_next = skb->cb_next; 
     119 
     120        atomic_set(&next->refcnt, 1); 
     121 
     122        skb->cb_next = next; 
     123        return 0; 
     124} 
     125EXPORT_SYMBOL(skb_save_cb); 
     126 
     127int skb_restore_cb(struct sk_buff *skb) 
     128{ 
     129        struct skb_cb_table *next; 
     130 
     131        if (!skb->cb_next) 
     132                return 0; 
     133 
     134        next = skb->cb_next; 
     135 
     136        BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb)); 
     137 
     138        memcpy(skb->cb, next->cb, sizeof(skb->cb)); 
     139        skb->cb_next = next->cb_next; 
     140 
     141        spin_lock(&skb_cb_store_lock); 
     142 
     143        if (atomic_dec_and_test(&next->refcnt)) { 
     144                kmem_cache_free(skbuff_cb_store_cache, next); 
     145        } 
     146 
     147        spin_unlock(&skb_cb_store_lock); 
     148 
     149        return 0; 
     150} 
     151EXPORT_SYMBOL(skb_restore_cb); 
     152 
     153static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old) 
     154{ 
     155        struct skb_cb_table *next; 
     156        struct sk_buff *old; 
     157 
     158        if (!__old->cb_next) { 
     159                new->cb_next = NULL; 
     160                return; 
     161        } 
     162 
     163        spin_lock(&skb_cb_store_lock); 
     164 
     165        old = (struct sk_buff *)__old; 
     166 
     167        next = old->cb_next; 
     168        atomic_inc(&next->refcnt); 
     169        new->cb_next = next; 
     170 
     171        spin_unlock(&skb_cb_store_lock); 
     172} 
     173#endif 
    94174 
    95175/* Pipe buffer operations for a socket. */ 
    96176static const struct pipe_buf_operations sock_pipe_buf_ops = { 
    static void skb_release_head_state(struc 
    391471                WARN_ON(in_irq()); 
    392472                skb->destructor(skb); 
    393473        } 
     474#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     475        /* This should not happen. When it does, avoid memleak by restoring 
     476        the chain of cb-backups. */ 
     477        while(skb->cb_next != NULL) { 
     478                if (net_ratelimit()) 
     479                        printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: " 
     480                                "%08x\n", (unsigned int)skb->cb_next); 
     481 
     482                skb_restore_cb(skb); 
     483        } 
     484        /* This should not happen either, nf_queue_entry is nullified in 
     485         * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are 
     486         * leaking entry pointers, maybe memory. We don't know if this is 
     487         * pointer to already freed memory, or should this be freed. 
     488         * If this happens we need to add refcounting, etc for nf_queue_entry. 
     489         */ 
     490        if (skb->nf_queue_entry && net_ratelimit()) 
     491                printk(KERN_WARNING 
     492                                "IMQ: kfree_skb: skb->nf_queue_entry != NULL"); 
     493#endif 
    394494#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 
    395495        nf_conntrack_put(skb->nfct); 
    396496        nf_conntrack_put_reasm(skb->nfct_reasm); 
    static void __copy_skb_header(struct sk_ 
    526626        new->sp                 = secpath_get(old->sp); 
    527627#endif 
    528628        memcpy(new->cb, old->cb, sizeof(old->cb)); 
     629#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     630        skb_copy_stored_cb(new, old); 
     631#endif 
    529632        new->csum               = old->csum; 
    530633        new->local_df           = old->local_df; 
    531634        new->pkt_type           = old->pkt_type; 
    void __init skb_init(void) 
    27802883                                                0, 
    27812884                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC, 
    27822885                                                NULL); 
     2886#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     2887        skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache", 
     2888                                                  sizeof(struct skb_cb_table), 
     2889                                                  0, 
     2890                                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, 
     2891                                                  NULL); 
     2892#endif 
    27832893} 
    27842894 
    27852895/** 
  • net/netfilter/Kconfig

    a b config NETFILTER_XT_TARGET_LED 
    448448          For more information on the LEDs available on your system, see 
    449449          Documentation/leds-class.txt 
    450450 
     451config NETFILTER_XT_TARGET_IMQ 
     452        tristate '"IMQ" target support' 
     453        depends on NETFILTER_XTABLES 
     454        depends on IP_NF_MANGLE || IP6_NF_MANGLE 
     455        select IMQ 
     456        default m if NETFILTER_ADVANCED=n 
     457        help 
     458          This option adds a `IMQ' target which is used to specify if and 
     459          to which imq device packets should get enqueued/dequeued. 
     460 
     461          To compile it as a module, choose M here.  If unsure, say N. 
     462 
    451463config NETFILTER_XT_TARGET_MARK 
    452464        tristate '"MARK" target support' 
    453465        depends on NETFILTER_ADVANCED 
  • net/netfilter/Makefile

    a b obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC 
    5050obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o 
    5151obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 
    5252obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o 
     53obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o 
    5354obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o 
    5455obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 
    5556obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 
  • net/netfilter/nf_queue.c

    a b static const struct nf_queue_handler *qu 
    2222 
    2323static DEFINE_MUTEX(queue_handler_mutex); 
    2424 
     25#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     26static const struct nf_queue_handler *queue_imq_handler; 
     27 
     28void nf_register_queue_imq_handler(const struct nf_queue_handler *qh) 
     29{ 
     30        mutex_lock(&queue_handler_mutex); 
     31        rcu_assign_pointer(queue_imq_handler, qh); 
     32        mutex_unlock(&queue_handler_mutex); 
     33} 
     34EXPORT_SYMBOL(nf_register_queue_imq_handler); 
     35 
     36void nf_unregister_queue_imq_handler(void) 
     37{ 
     38        mutex_lock(&queue_handler_mutex); 
     39        rcu_assign_pointer(queue_imq_handler, NULL); 
     40        mutex_unlock(&queue_handler_mutex); 
     41} 
     42EXPORT_SYMBOL(nf_unregister_queue_imq_handler); 
     43#endif 
     44 
    2545/* return EBUSY when somebody else is registered, return EEXIST if the 
    2646 * same handler is registered, return 0 in case of success. */ 
    2747int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh) 
    void nf_unregister_queue_handlers(const 
    82102} 
    83103EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); 
    84104 
    85 static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) 
     105void nf_queue_entry_release_refs(struct nf_queue_entry *entry) 
    86106{ 
    87107        /* Release those devices we held, or Alexey will kill me. */ 
    88108        if (entry->indev) 
    static void nf_queue_entry_release_refs( 
    102122        /* Drop reference to owner of hook which queued us. */ 
    103123        module_put(entry->elem->owner); 
    104124} 
     125EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs); 
    105126 
    106127/* 
    107128 * Any packet that leaves via this function must come back 
    static int __nf_queue(struct sk_buff *sk 
    123144#endif 
    124145        const struct nf_afinfo *afinfo; 
    125146        const struct nf_queue_handler *qh; 
     147#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     148        const struct nf_queue_handler *qih = NULL; 
     149#endif 
    126150 
    127151        /* QUEUE == DROP if noone is waiting, to be safe. */ 
    128152        rcu_read_lock(); 
    129153 
    130154        qh = rcu_dereference(queue_handler[pf]); 
     155#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     156#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     157        if (pf == PF_INET || pf == PF_INET6) 
     158#else 
     159        if (pf == PF_INET) 
     160#endif 
     161                qih = rcu_dereference(queue_imq_handler); 
     162 
     163        if (!qh && !qih) 
     164#else /* !IMQ */ 
    131165        if (!qh) 
     166#endif 
    132167                goto err_unlock; 
    133168 
    134169        afinfo = nf_get_afinfo(pf); 
    static int __nf_queue(struct sk_buff *sk 
    147182                .indev  = indev, 
    148183                .outdev = outdev, 
    149184                .okfn   = okfn, 
     185#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     186                .next_outfn = qh ? qh->outfn : NULL, 
     187                .next_queuenum = queuenum, 
     188#endif 
    150189        }; 
    151190 
    152191        /* If it's going away, ignore hook. */ 
    static int __nf_queue(struct sk_buff *sk 
    173212#endif 
    174213        skb_dst_force(skb); 
    175214        afinfo->saveroute(skb, entry); 
     215 
     216#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     217        if (qih) { 
     218                status = qih->outfn(entry, queuenum); 
     219                goto imq_skip_queue; 
     220        } 
     221#endif 
     222 
    176223        status = qh->outfn(entry, queuenum); 
    177224 
     225#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     226imq_skip_queue: 
     227#endif 
    178228        rcu_read_unlock(); 
    179229 
    180230        if (status < 0) { 
  • new file net/netfilter/xt_IMQ.c

    - +  
     1/* 
     2 * This target marks packets to be enqueued to an imq device 
     3 */ 
     4#include <linux/module.h> 
     5#include <linux/skbuff.h> 
     6#include <linux/netfilter/x_tables.h> 
     7#include <linux/netfilter/xt_IMQ.h> 
     8#include <linux/imq.h> 
     9 
     10static unsigned int imq_target(struct sk_buff *pskb, 
     11                                const struct xt_action_param *par) 
     12{ 
     13        const struct xt_imq_info *mr = par->targinfo; 
     14 
     15        pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE; 
     16 
     17        return XT_CONTINUE; 
     18} 
     19 
     20static int imq_checkentry(const struct xt_tgchk_param *par) 
     21{ 
     22        struct xt_imq_info *mr = par->targinfo; 
     23 
     24        if (mr->todev > IMQ_MAX_DEVS - 1) { 
     25                printk(KERN_WARNING 
     26                       "IMQ: invalid device specified, highest is %u\n", 
     27                       IMQ_MAX_DEVS - 1); 
     28                return -EINVAL; 
     29        } 
     30 
     31        return 0; 
     32} 
     33 
     34static struct xt_target xt_imq_reg[] __read_mostly = { 
     35        { 
     36                .name           = "IMQ", 
     37                .family         = AF_INET, 
     38                .checkentry     = imq_checkentry, 
     39                .target         = imq_target, 
     40                .targetsize     = sizeof(struct xt_imq_info), 
     41                .table          = "mangle", 
     42                .me             = THIS_MODULE 
     43        }, 
     44        { 
     45                .name           = "IMQ", 
     46                .family         = AF_INET6, 
     47                .checkentry     = imq_checkentry, 
     48                .target         = imq_target, 
     49                .targetsize     = sizeof(struct xt_imq_info), 
     50                .table          = "mangle", 
     51                .me             = THIS_MODULE 
     52        }, 
     53}; 
     54 
     55static int __init imq_init(void) 
     56{ 
     57        return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg)); 
     58} 
     59 
     60static void __exit imq_fini(void) 
     61{ 
     62        xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg)); 
     63} 
     64 
     65module_init(imq_init); 
     66module_exit(imq_fini); 
     67 
     68MODULE_AUTHOR("http://www.linuximq.net"); 
     69MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information."); 
     70MODULE_LICENSE("GPL"); 
     71MODULE_ALIAS("ipt_IMQ"); 
     72MODULE_ALIAS("ip6t_IMQ"); 
     73 
Note: See TracBrowser for help on using the repository browser.