source: trunk/target/linux/generic/patches-2.6.32/150-netfilter_imq.patch @ 23735

Last change on this file since 23735 was 23735, checked in by florian, 6 years ago

[kernel] refresh 2.6.32 patches

File size: 36.0 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 *             Also, many thanks to pablo Sebastian Greco for making the initial 
     83 *             patch and to those who helped the testing. 
     84 * 
     85 *             More info at: http://www.linuximq.net/ (Andre Correa) 
     86 */ 
     87 
     88#include <linux/module.h> 
     89#include <linux/kernel.h> 
     90#include <linux/moduleparam.h> 
     91#include <linux/list.h> 
     92#include <linux/skbuff.h> 
     93#include <linux/netdevice.h> 
     94#include <linux/etherdevice.h> 
     95#include <linux/rtnetlink.h> 
     96#include <linux/if_arp.h> 
     97#include <linux/netfilter.h> 
     98#include <linux/netfilter_ipv4.h> 
     99#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     100        #include <linux/netfilter_ipv6.h> 
     101#endif 
     102#include <linux/imq.h> 
     103#include <net/pkt_sched.h> 
     104#include <net/netfilter/nf_queue.h> 
     105 
     106static nf_hookfn imq_nf_hook; 
     107 
     108static struct nf_hook_ops imq_ingress_ipv4 = { 
     109        .hook           = imq_nf_hook, 
     110        .owner          = THIS_MODULE, 
     111        .pf             = PF_INET, 
     112        .hooknum        = NF_INET_PRE_ROUTING, 
     113#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     114        .priority       = NF_IP_PRI_MANGLE + 1 
     115#else 
     116        .priority       = NF_IP_PRI_NAT_DST + 1 
     117#endif 
     118}; 
     119 
     120static struct nf_hook_ops imq_egress_ipv4 = { 
     121        .hook           = imq_nf_hook, 
     122        .owner          = THIS_MODULE, 
     123        .pf             = PF_INET, 
     124        .hooknum        = NF_INET_POST_ROUTING, 
     125#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 
     126        .priority       = NF_IP_PRI_LAST 
     127#else 
     128        .priority       = NF_IP_PRI_NAT_SRC - 1 
     129#endif 
     130}; 
     131 
     132#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     133static struct nf_hook_ops imq_ingress_ipv6 = { 
     134        .hook           = imq_nf_hook, 
     135        .owner          = THIS_MODULE, 
     136        .pf             = PF_INET6, 
     137        .hooknum        = NF_INET_PRE_ROUTING, 
     138#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     139        .priority       = NF_IP6_PRI_MANGLE + 1 
     140#else 
     141        .priority       = NF_IP6_PRI_NAT_DST + 1 
     142#endif 
     143}; 
     144 
     145static struct nf_hook_ops imq_egress_ipv6 = { 
     146        .hook           = imq_nf_hook, 
     147        .owner          = THIS_MODULE, 
     148        .pf             = PF_INET6, 
     149        .hooknum        = NF_INET_POST_ROUTING, 
     150#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 
     151        .priority       = NF_IP6_PRI_LAST 
     152#else 
     153        .priority       = NF_IP6_PRI_NAT_SRC - 1 
     154#endif 
     155}; 
     156#endif 
     157 
     158#if defined(CONFIG_IMQ_NUM_DEVS) 
     159static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS; 
     160#else 
     161static unsigned int numdevs = IMQ_MAX_DEVS; 
     162#endif 
     163 
     164static DEFINE_SPINLOCK(imq_nf_queue_lock); 
     165 
     166static struct net_device *imq_devs_cache[IMQ_MAX_DEVS]; 
     167 
     168 
     169static struct net_device_stats *imq_get_stats(struct net_device *dev) 
     170{ 
     171        return &dev->stats; 
     172} 
     173 
     174/* called for packets kfree'd in qdiscs at places other than enqueue */ 
     175static void imq_skb_destructor(struct sk_buff *skb) 
     176{ 
     177        struct nf_queue_entry *entry = skb->nf_queue_entry; 
     178 
     179        skb->nf_queue_entry = NULL; 
     180 
     181        if (entry) { 
     182                nf_queue_entry_release_refs(entry); 
     183                kfree(entry); 
     184        } 
     185 
     186        skb_restore_cb(skb); /* kfree backup */ 
     187} 
     188 
     189/* locking not needed when called from imq_nf_queue */ 
     190static void imq_nf_reinject_lockless(struct nf_queue_entry *entry, 
     191                                                unsigned int verdict) 
     192{ 
     193        int status; 
     194 
     195        if (!entry->next_outfn) { 
     196                nf_reinject(entry, verdict); 
     197                return; 
     198        } 
     199 
     200        status = entry->next_outfn(entry, entry->next_queuenum); 
     201        if (status < 0) { 
     202                nf_queue_entry_release_refs(entry); 
     203                kfree_skb(entry->skb); 
     204                kfree(entry); 
     205        } 
     206} 
     207 
     208static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 
     209{ 
     210        int status; 
     211 
     212        if (!entry->next_outfn) { 
     213                spin_lock_bh(&imq_nf_queue_lock); 
     214                nf_reinject(entry, verdict); 
     215                spin_unlock_bh(&imq_nf_queue_lock); 
     216                return; 
     217        } 
     218 
     219        rcu_read_lock(); 
     220        local_bh_disable(); 
     221        status = entry->next_outfn(entry, entry->next_queuenum); 
     222        local_bh_enable(); 
     223        if (status < 0) { 
     224                nf_queue_entry_release_refs(entry); 
     225                kfree_skb(entry->skb); 
     226                kfree(entry); 
     227        } 
     228 
     229        rcu_read_unlock(); 
     230} 
     231 
     232static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 
     233{ 
     234        struct nf_queue_entry *entry = skb->nf_queue_entry; 
     235 
     236        skb->nf_queue_entry = NULL; 
     237        dev->trans_start = jiffies; 
     238 
     239        dev->stats.tx_bytes += skb->len; 
     240        dev->stats.tx_packets++; 
     241 
     242        if (entry == NULL) { 
     243                /* We don't know what is going on here.. packet is queued for 
     244                 * imq device, but (probably) not by us. 
     245                 * 
     246                 * If this packet was not send here by imq_nf_queue(), then 
     247                 * skb_save_cb() was not used and skb_free() should not show: 
     248                 *   WARNING: IMQ: kfree_skb: skb->cb_next:.. 
     249                 * and/or 
     250                 *   WARNING: IMQ: kfree_skb: skb->nf_queue_entry... 
     251                 * 
     252                 * However if this message is shown, then IMQ is somehow broken 
     253                 * and you should report this to linuximq.net. 
     254                 */ 
     255 
     256                /* imq_dev_xmit is black hole that eats all packets, report that 
     257                 * we eat this packet happily and increase dropped counters. 
     258                 */ 
     259 
     260                dev->stats.tx_dropped++; 
     261                dev_kfree_skb(skb); 
     262 
     263                return NETDEV_TX_OK; 
     264        } 
     265 
     266        skb_restore_cb(skb); /* restore skb->cb */ 
     267 
     268        skb->imq_flags = 0; 
     269        skb->destructor = NULL; 
     270 
     271        imq_nf_reinject(entry, NF_ACCEPT); 
     272 
     273        return NETDEV_TX_OK; 
     274} 
     275 
     276static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num) 
     277{ 
     278        struct net_device *dev; 
     279        struct sk_buff *skb_orig, *skb, *skb_shared; 
     280        struct Qdisc *q; 
     281        struct netdev_queue *txq; 
     282        int users, index; 
     283        int retval = -EINVAL; 
     284 
     285        index = entry->skb->imq_flags & IMQ_F_IFMASK; 
     286        if (unlikely(index > numdevs - 1)) { 
     287                if (net_ratelimit()) 
     288                        printk(KERN_WARNING 
     289                               "IMQ: invalid device specified, highest is %u\n", 
     290                               numdevs - 1); 
     291                retval = -EINVAL; 
     292                goto out; 
     293        } 
     294 
     295        /* check for imq device by index from cache */ 
     296        dev = imq_devs_cache[index]; 
     297        if (unlikely(!dev)) { 
     298                char buf[8]; 
     299 
     300                /* get device by name and cache result */ 
     301                snprintf(buf, sizeof(buf), "imq%d", index); 
     302                dev = dev_get_by_name(&init_net, buf); 
     303                if (!dev) { 
     304                        /* not found ?!*/ 
     305                        BUG(); 
     306                        retval = -ENODEV; 
     307                        goto out; 
     308                } 
     309 
     310                imq_devs_cache[index] = dev; 
     311                dev_put(dev); 
     312        } 
     313 
     314        if (unlikely(!(dev->flags & IFF_UP))) { 
     315                entry->skb->imq_flags = 0; 
     316                imq_nf_reinject_lockless(entry, NF_ACCEPT); 
     317                retval = 0; 
     318                goto out; 
     319        } 
     320        dev->last_rx = jiffies; 
     321 
     322        skb = entry->skb; 
     323        skb_orig = NULL; 
     324 
     325        /* skb has owner? => make clone */ 
     326        if (unlikely(skb->destructor)) { 
     327                skb_orig = skb; 
     328                skb = skb_clone(skb, GFP_ATOMIC); 
     329                if (!skb) { 
     330                        retval = -ENOMEM; 
     331                        goto out; 
     332                } 
     333                entry->skb = skb; 
     334        } 
     335 
     336        skb->nf_queue_entry = entry; 
     337 
     338        dev->stats.rx_bytes += skb->len; 
     339        dev->stats.rx_packets++; 
     340 
     341        txq = dev_pick_tx(dev, skb); 
     342 
     343        q = rcu_dereference(txq->qdisc); 
     344        if (unlikely(!q->enqueue)) 
     345                goto packet_not_eaten_by_imq_dev; 
     346 
     347        spin_lock_bh(qdisc_lock(q)); 
     348 
     349        users = atomic_read(&skb->users); 
     350 
     351        skb_shared = skb_get(skb); /* increase reference count by one */ 
     352        skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will 
     353                                        overwrite it */ 
     354        qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */ 
     355 
     356        if (likely(atomic_read(&skb_shared->users) == users + 1)) { 
     357                kfree_skb(skb_shared); /* decrease reference count by one */ 
     358 
     359                skb->destructor = &imq_skb_destructor; 
     360 
     361                /* cloned? */ 
     362                if (skb_orig) 
     363                        kfree_skb(skb_orig); /* free original */ 
     364 
     365                spin_unlock_bh(qdisc_lock(q)); 
     366 
     367                /* schedule qdisc dequeue */ 
     368                __netif_schedule(q); 
     369 
     370                retval = 0; 
     371                goto out; 
     372        } else { 
     373                skb_restore_cb(skb_shared); /* restore skb->cb */ 
     374                skb->nf_queue_entry = NULL; 
     375                /* qdisc dropped packet and decreased skb reference count of 
     376                 * skb, so we don't really want to and try refree as that would 
     377                 * actually destroy the skb. */ 
     378                spin_unlock_bh(qdisc_lock(q)); 
     379                goto packet_not_eaten_by_imq_dev; 
     380        } 
     381 
     382packet_not_eaten_by_imq_dev: 
     383        /* cloned? restore original */ 
     384        if (skb_orig) { 
     385                kfree_skb(skb); 
     386                entry->skb = skb_orig; 
     387        } 
     388        retval = -1; 
     389out: 
     390        return retval; 
     391} 
     392 
     393static struct nf_queue_handler nfqh = { 
     394        .name  = "imq", 
     395        .outfn = imq_nf_queue, 
     396}; 
     397 
     398static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb, 
     399                                const struct net_device *indev, 
     400                                const struct net_device *outdev, 
     401                                int (*okfn)(struct sk_buff *)) 
     402{ 
     403        if (pskb->imq_flags & IMQ_F_ENQUEUE) 
     404                return NF_QUEUE; 
     405 
     406        return NF_ACCEPT; 
     407} 
     408 
     409static int imq_close(struct net_device *dev) 
     410{ 
     411        netif_stop_queue(dev); 
     412        return 0; 
     413} 
     414 
     415static int imq_open(struct net_device *dev) 
     416{ 
     417        netif_start_queue(dev); 
     418        return 0; 
     419} 
     420 
     421static const struct net_device_ops imq_netdev_ops = { 
     422        .ndo_open               = imq_open, 
     423        .ndo_stop               = imq_close, 
     424        .ndo_start_xmit         = imq_dev_xmit, 
     425        .ndo_get_stats          = imq_get_stats, 
     426}; 
     427 
     428static void imq_setup(struct net_device *dev) 
     429{ 
     430        dev->netdev_ops         = &imq_netdev_ops; 
     431        dev->type               = ARPHRD_VOID; 
     432        dev->mtu                = 16000; 
     433        dev->tx_queue_len       = 11000; 
     434        dev->flags              = IFF_NOARP; 
     435        dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST | 
     436                                  NETIF_F_GSO | NETIF_F_HW_CSUM | 
     437                                  NETIF_F_HIGHDMA; 
     438        dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE; 
     439} 
     440 
     441static int imq_validate(struct nlattr *tb[], struct nlattr *data[]) 
     442{ 
     443        int ret = 0; 
     444 
     445        if (tb[IFLA_ADDRESS]) { 
     446                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) { 
     447                        ret = -EINVAL; 
     448                        goto end; 
     449                } 
     450                if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) { 
     451                        ret = -EADDRNOTAVAIL; 
     452                        goto end; 
     453                } 
     454        } 
     455        return 0; 
     456end: 
     457        printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret); 
     458        return ret; 
     459} 
     460 
     461static struct rtnl_link_ops imq_link_ops __read_mostly = { 
     462        .kind           = "imq", 
     463        .priv_size      = 0, 
     464        .setup          = imq_setup, 
     465        .validate       = imq_validate, 
     466}; 
     467 
     468static int __init imq_init_hooks(void) 
     469{ 
     470        int err; 
     471 
     472        nf_register_queue_imq_handler(&nfqh); 
     473 
     474        err = nf_register_hook(&imq_ingress_ipv4); 
     475        if (err) 
     476                goto err1; 
     477 
     478        err = nf_register_hook(&imq_egress_ipv4); 
     479        if (err) 
     480                goto err2; 
     481 
     482#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     483        err = nf_register_hook(&imq_ingress_ipv6); 
     484        if (err) 
     485                goto err3; 
     486 
     487        err = nf_register_hook(&imq_egress_ipv6); 
     488        if (err) 
     489                goto err4; 
     490#endif 
     491 
     492        return 0; 
     493 
     494#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     495err4: 
     496        nf_unregister_hook(&imq_ingress_ipv6); 
     497err3: 
     498        nf_unregister_hook(&imq_egress_ipv4); 
     499#endif 
     500err2: 
     501        nf_unregister_hook(&imq_ingress_ipv4); 
     502err1: 
     503        nf_unregister_queue_imq_handler(); 
     504        return err; 
     505} 
     506 
     507static int __init imq_init_one(int index) 
     508{ 
     509        struct net_device *dev; 
     510        int ret; 
     511 
     512        dev = alloc_netdev(0, "imq%d", imq_setup); 
     513        if (!dev) 
     514                return -ENOMEM; 
     515 
     516        ret = dev_alloc_name(dev, dev->name); 
     517        if (ret < 0) 
     518                goto fail; 
     519 
     520        dev->rtnl_link_ops = &imq_link_ops; 
     521        ret = register_netdevice(dev); 
     522        if (ret < 0) 
     523                goto fail; 
     524 
     525        return 0; 
     526fail: 
     527        free_netdev(dev); 
     528        return ret; 
     529} 
     530 
     531static int __init imq_init_devs(void) 
     532{ 
     533        int err, i; 
     534 
     535        if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) { 
     536                printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n", 
     537                       IMQ_MAX_DEVS); 
     538                return -EINVAL; 
     539        } 
     540 
     541        rtnl_lock(); 
     542        err = __rtnl_link_register(&imq_link_ops); 
     543 
     544        for (i = 0; i < numdevs && !err; i++) 
     545                err = imq_init_one(i); 
     546 
     547        if (err) { 
     548                __rtnl_link_unregister(&imq_link_ops); 
     549                memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     550        } 
     551        rtnl_unlock(); 
     552 
     553        return err; 
     554} 
     555 
     556static int __init imq_init_module(void) 
     557{ 
     558        int err; 
     559 
     560#if defined(CONFIG_IMQ_NUM_DEVS) 
     561        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16); 
     562        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2); 
     563        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK); 
     564#endif 
     565 
     566        err = imq_init_devs(); 
     567        if (err) { 
     568                printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n"); 
     569                return err; 
     570        } 
     571 
     572        err = imq_init_hooks(); 
     573        if (err) { 
     574                printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n"); 
     575                rtnl_link_unregister(&imq_link_ops); 
     576                memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     577                return err; 
     578        } 
     579 
     580        printk(KERN_INFO "IMQ driver loaded successfully.\n"); 
     581 
     582#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     583        printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n"); 
     584#else 
     585        printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n"); 
     586#endif 
     587#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB) 
     588        printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n"); 
     589#else 
     590        printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n"); 
     591#endif 
     592 
     593        return 0; 
     594} 
     595 
     596static void __exit imq_unhook(void) 
     597{ 
     598#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     599        nf_unregister_hook(&imq_ingress_ipv6); 
     600        nf_unregister_hook(&imq_egress_ipv6); 
     601#endif 
     602        nf_unregister_hook(&imq_ingress_ipv4); 
     603        nf_unregister_hook(&imq_egress_ipv4); 
     604 
     605        nf_unregister_queue_imq_handler(); 
     606} 
     607 
     608static void __exit imq_cleanup_devs(void) 
     609{ 
     610        rtnl_link_unregister(&imq_link_ops); 
     611        memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 
     612} 
     613 
     614static void __exit imq_exit_module(void) 
     615{ 
     616        imq_unhook(); 
     617        imq_cleanup_devs(); 
     618        printk(KERN_INFO "IMQ driver unloaded successfully.\n"); 
     619} 
     620 
     621module_init(imq_init_module); 
     622module_exit(imq_exit_module); 
     623 
     624module_param(numdevs, int, 0); 
     625MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will " 
     626                        "be created)"); 
     627MODULE_AUTHOR("http://www.linuximq.net"); 
     628MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See " 
     629                        "http://www.linuximq.net/ for more information."); 
     630MODULE_LICENSE("GPL"); 
     631MODULE_ALIAS_RTNL_LINK("imq"); 
     632 
  • drivers/net/Kconfig

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

    a b obj-$(CONFIG_SLHC) += slhc.o 
    165165obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o 
    166166 
    167167obj-$(CONFIG_DUMMY) += dummy.o 
     168obj-$(CONFIG_IMQ) += imq.o 
    168169obj-$(CONFIG_IFB) += ifb.o 
    169170obj-$(CONFIG_MACVLAN) += macvlan.o 
    170171obj-$(CONFIG_DE600) += de600.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 
    11141114extern int              dev_open(struct net_device *dev); 
    11151115extern int              dev_close(struct net_device *dev); 
    11161116extern void             dev_disable_lro(struct net_device *dev); 
     1117extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb); 
    11171118extern int              dev_queue_xmit(struct sk_buff *skb); 
    11181119extern int              register_netdevice(struct net_device *dev); 
    11191120extern void             unregister_netdevice(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 { 
    330333         * first. This is owned by whoever has the skb queued ATM. 
    331334         */ 
    332335        char                    cb[48]; 
     336#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     337        void                    *cb_next; 
     338#endif 
    333339 
    334340        unsigned int            len, 
    335341                                data_len; 
    struct sk_buff { 
    362368        struct nf_conntrack     *nfct; 
    363369        struct sk_buff          *nfct_reasm; 
    364370#endif 
     371#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     372        struct nf_queue_entry   *nf_queue_entry; 
     373#endif 
    365374#ifdef CONFIG_BRIDGE_NETFILTER 
    366375        struct nf_bridge_info   *nf_bridge; 
    367376#endif 
    struct sk_buff { 
    383392 
    384393        /* 0/14 bit hole */ 
    385394 
     395#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     396        __u8                    imq_flags:IMQ_F_BITS; 
     397#endif 
     398 
    386399#ifdef CONFIG_NET_DMA 
    387400        dma_cookie_t            dma_cookie; 
    388401#endif 
    static inline struct rtable *skb_rtable( 
    437450        return (struct rtable *)skb_dst(skb); 
    438451} 
    439452 
     453 
     454#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     455extern int skb_save_cb(struct sk_buff *skb); 
     456extern int skb_restore_cb(struct sk_buff *skb); 
     457#endif 
     458 
    440459extern void kfree_skb(struct sk_buff *skb); 
    441460extern void consume_skb(struct sk_buff *skb); 
    442461extern void            __kfree_skb(struct sk_buff *skb); 
    static inline void __nf_copy(struct sk_b 
    19721991        dst->nfct_reasm = src->nfct_reasm; 
    19731992        nf_conntrack_get_reasm(src->nfct_reasm); 
    19741993#endif 
     1994#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     1995        dst->imq_flags = src->imq_flags; 
     1996        dst->nf_queue_entry = src->nf_queue_entry; 
     1997#endif 
    19751998#ifdef CONFIG_BRIDGE_NETFILTER 
    19761999        dst->nf_bridge  = src->nf_bridge; 
    19772000        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  
    9696#include <net/net_namespace.h> 
    9797#include <net/sock.h> 
    9898#include <linux/rtnetlink.h> 
     99#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     100#include <linux/imq.h> 
     101#endif 
    99102#include <linux/proc_fs.h> 
    100103#include <linux/seq_file.h> 
    101104#include <linux/stat.h> 
    int dev_hard_start_xmit(struct sk_buff * 
    17041707        int rc; 
    17051708 
    17061709        if (likely(!skb->next)) { 
    1707                 if (!list_empty(&ptype_all)) 
     1710                if (!list_empty(&ptype_all) 
     1711#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     1712                    && !(skb->imq_flags & IMQ_F_ENQUEUE) 
     1713#endif 
     1714                    ) 
    17081715                        dev_queue_xmit_nit(skb, dev); 
    17091716 
    17101717                if (netif_needs_gso(dev, skb)) { 
    u16 skb_tx_hash(const struct net_device 
    17891796} 
    17901797EXPORT_SYMBOL(skb_tx_hash); 
    17911798 
    1792 static struct netdev_queue *dev_pick_tx(struct net_device *dev, 
    1793                                         struct sk_buff *skb) 
     1799struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb) 
    17941800{ 
    17951801        const struct net_device_ops *ops = dev->netdev_ops; 
    17961802        u16 queue_index = 0; 
    static struct netdev_queue *dev_pick_tx( 
    18031809        skb_set_queue_mapping(skb, queue_index); 
    18041810        return netdev_get_tx_queue(dev, queue_index); 
    18051811} 
     1812EXPORT_SYMBOL(dev_pick_tx); 
    18061813 
    18071814static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, 
    18081815                                 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 struct pipe_buf_operations sock_pipe_buf_ops = { 
    static void skb_release_head_state(struc 
    398478                WARN_ON(in_irq()); 
    399479                skb->destructor(skb); 
    400480        } 
     481#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     482        /* This should not happen. When it does, avoid memleak by restoring 
     483        the chain of cb-backups. */ 
     484        while(skb->cb_next != NULL) { 
     485                if (net_ratelimit()) 
     486                        printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: " 
     487                                "%08x\n", (unsigned int)skb->cb_next); 
     488 
     489                skb_restore_cb(skb); 
     490        } 
     491        /* This should not happen either, nf_queue_entry is nullified in 
     492         * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are 
     493         * leaking entry pointers, maybe memory. We don't know if this is 
     494         * pointer to already freed memory, or should this be freed. 
     495         * If this happens we need to add refcounting, etc for nf_queue_entry. 
     496         */ 
     497        if (skb->nf_queue_entry && net_ratelimit()) 
     498                printk(KERN_WARNING 
     499                                "IMQ: kfree_skb: skb->nf_queue_entry != NULL"); 
     500#endif 
    401501#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 
    402502        nf_conntrack_put(skb->nfct); 
    403503        nf_conntrack_put_reasm(skb->nfct_reasm); 
    static void __copy_skb_header(struct sk_ 
    535635        new->sp                 = secpath_get(old->sp); 
    536636#endif 
    537637        memcpy(new->cb, old->cb, sizeof(old->cb)); 
     638#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     639        skb_copy_stored_cb(new, old); 
     640#endif 
    538641        new->csum               = old->csum; 
    539642        new->local_df           = old->local_df; 
    540643        new->pkt_type           = old->pkt_type; 
    void __init skb_init(void) 
    27812884                                                0, 
    27822885                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC, 
    27832886                                                NULL); 
     2887#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     2888        skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache", 
     2889                                                  sizeof(struct skb_cb_table), 
     2890                                                  0, 
     2891                                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, 
     2892                                                  NULL); 
     2893#endif 
    27842894} 
    27852895 
    27862896/** 
  • net/netfilter/Kconfig

    a b config NETFILTER_XT_TARGET_LED 
    396396          For more information on the LEDs available on your system, see 
    397397          Documentation/leds-class.txt 
    398398 
     399config NETFILTER_XT_TARGET_IMQ 
     400        tristate '"IMQ" target support' 
     401        depends on NETFILTER_XTABLES 
     402        depends on IP_NF_MANGLE || IP6_NF_MANGLE 
     403        select IMQ 
     404        default m if NETFILTER_ADVANCED=n 
     405        help 
     406          This option adds a `IMQ' target which is used to specify if and 
     407          to which imq device packets should get enqueued/dequeued. 
     408 
     409          To compile it as a module, choose M here.  If unsure, say N. 
     410 
    399411config NETFILTER_XT_TARGET_MARK 
    400412        tristate '"MARK" target support' 
    401413        default m if NETFILTER_ADVANCED=n 
  • net/netfilter/Makefile

    a b obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMAR 
    4646obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o 
    4747obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 
    4848obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o 
     49obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o 
    4950obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o 
    5051obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 
    5152obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 
  • net/netfilter/nf_queue.c

    a b static const struct nf_queue_handler *qu 
    2020 
    2121static DEFINE_MUTEX(queue_handler_mutex); 
    2222 
     23#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     24static const struct nf_queue_handler *queue_imq_handler; 
     25 
     26void nf_register_queue_imq_handler(const struct nf_queue_handler *qh) 
     27{ 
     28        mutex_lock(&queue_handler_mutex); 
     29        rcu_assign_pointer(queue_imq_handler, qh); 
     30        mutex_unlock(&queue_handler_mutex); 
     31} 
     32EXPORT_SYMBOL(nf_register_queue_imq_handler); 
     33 
     34void nf_unregister_queue_imq_handler(void) 
     35{ 
     36        mutex_lock(&queue_handler_mutex); 
     37        rcu_assign_pointer(queue_imq_handler, NULL); 
     38        mutex_unlock(&queue_handler_mutex); 
     39} 
     40EXPORT_SYMBOL(nf_unregister_queue_imq_handler); 
     41#endif 
     42 
    2343/* return EBUSY when somebody else is registered, return EEXIST if the 
    2444 * same handler is registered, return 0 in case of success. */ 
    2545int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh) 
    void nf_unregister_queue_handlers(const 
    80100} 
    81101EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); 
    82102 
    83 static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) 
     103void nf_queue_entry_release_refs(struct nf_queue_entry *entry) 
    84104{ 
    85105        /* Release those devices we held, or Alexey will kill me. */ 
    86106        if (entry->indev) 
    static void nf_queue_entry_release_refs( 
    100120        /* Drop reference to owner of hook which queued us. */ 
    101121        module_put(entry->elem->owner); 
    102122} 
     123EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs); 
    103124 
    104125/* 
    105126 * Any packet that leaves via this function must come back 
    static int __nf_queue(struct sk_buff *sk 
    121142#endif 
    122143        const struct nf_afinfo *afinfo; 
    123144        const struct nf_queue_handler *qh; 
     145#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     146        const struct nf_queue_handler *qih = NULL; 
     147#endif 
    124148 
    125149        /* QUEUE == DROP if noone is waiting, to be safe. */ 
    126150        rcu_read_lock(); 
    127151 
    128152        qh = rcu_dereference(queue_handler[pf]); 
     153#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     154#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 
     155        if (pf == PF_INET || pf == PF_INET6) 
     156#else 
     157        if (pf == PF_INET) 
     158#endif 
     159                qih = rcu_dereference(queue_imq_handler); 
     160 
     161        if (!qh && !qih) 
     162#else /* !IMQ */ 
    129163        if (!qh) 
     164#endif 
    130165                goto err_unlock; 
    131166 
    132167        afinfo = nf_get_afinfo(pf); 
    static int __nf_queue(struct sk_buff *sk 
    145180                .indev  = indev, 
    146181                .outdev = outdev, 
    147182                .okfn   = okfn, 
     183#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     184                .next_outfn = qh ? qh->outfn : NULL, 
     185                .next_queuenum = queuenum, 
     186#endif 
    148187        }; 
    149188 
    150189        /* If it's going away, ignore hook. */ 
    static int __nf_queue(struct sk_buff *sk 
    170209        } 
    171210#endif 
    172211        afinfo->saveroute(skb, entry); 
     212 
     213#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     214        if (qih) { 
     215                status = qih->outfn(entry, queuenum); 
     216                goto imq_skip_queue; 
     217        } 
     218#endif 
     219 
    173220        status = qh->outfn(entry, queuenum); 
    174221 
     222#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 
     223imq_skip_queue: 
     224#endif 
    175225        rcu_read_unlock(); 
    176226 
    177227        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_target_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 bool 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 0; 
     29        } 
     30 
     31        return 1; 
     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.