source: npl/kernel/linux_src/linux-4.4.5-imq.diff @ 480e6a7

gcc484perl-5.22
Last change on this file since 480e6a7 was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 45.4 KB
  • drivers/net/Kconfig

    diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
    index f184fb5..0e08522 100644
    a b config RIONET_RX_SIZE 
    234234        depends on RIONET
    235235        default "128"
    236236
     237config IMQ
     238        tristate "IMQ (intermediate queueing device) support"
     239        depends on NETDEVICES && NETFILTER
     240        ---help---
     241          The IMQ device(s) is used as placeholder for QoS queueing
     242          disciplines. Every packet entering/leaving the IP stack can be
     243          directed through the IMQ device where it's enqueued/dequeued to the
     244          attached qdisc. This allows you to treat network devices as classes
     245          and distribute bandwidth among them. Iptables is used to specify
     246          through which IMQ device, if any, packets travel.
     247
     248          More information at: https://github.com/imq/linuximq
     249
     250          To compile this driver as a module, choose M here: the module
     251          will be called imq.  If unsure, say N.
     252
     253choice
     254        prompt "IMQ behavior (PRE/POSTROUTING)"
     255        depends on IMQ
     256        default IMQ_BEHAVIOR_AB
     257        help
     258          This setting defines how IMQ behaves in respect to its
     259          hooking in PREROUTING and POSTROUTING.
     260
     261          IMQ can work in any of the following ways:
     262
     263              PREROUTING   |      POSTROUTING
     264          -----------------|-------------------
     265          #1  After NAT    |      After NAT
     266          #2  After NAT    |      Before NAT
     267          #3  Before NAT   |      After NAT
     268          #4  Before NAT   |      Before NAT
     269
     270          The default behavior is to hook before NAT on PREROUTING
     271          and after NAT on POSTROUTING (#3).
     272
     273          This settings are specially usefull when trying to use IMQ
     274          to shape NATed clients.
     275
     276          More information can be found at: https://github.com/imq/linuximq
     277
     278          If not sure leave the default settings alone.
     279
     280config IMQ_BEHAVIOR_AA
     281        bool "IMQ AA"
     282        help
     283          This setting defines how IMQ behaves in respect to its
     284          hooking in PREROUTING and POSTROUTING.
     285
     286          Choosing this option will make IMQ hook like this:
     287
     288          PREROUTING:   After NAT
     289          POSTROUTING:  After NAT
     290
     291          More information can be found at: https://github.com/imq/linuximq
     292
     293          If not sure leave the default settings alone.
     294
     295config IMQ_BEHAVIOR_AB
     296        bool "IMQ AB"
     297        help
     298          This setting defines how IMQ behaves in respect to its
     299          hooking in PREROUTING and POSTROUTING.
     300
     301          Choosing this option will make IMQ hook like this:
     302
     303          PREROUTING:   After NAT
     304          POSTROUTING:  Before NAT
     305
     306          More information can be found at: https://github.com/imq/linuximq
     307
     308          If not sure leave the default settings alone.
     309
     310config IMQ_BEHAVIOR_BA
     311        bool "IMQ BA"
     312        help
     313          This setting defines how IMQ behaves in respect to its
     314          hooking in PREROUTING and POSTROUTING.
     315
     316          Choosing this option will make IMQ hook like this:
     317
     318          PREROUTING:   Before NAT
     319          POSTROUTING:  After NAT
     320
     321          More information can be found at: https://github.com/imq/linuximq
     322
     323          If not sure leave the default settings alone.
     324
     325config IMQ_BEHAVIOR_BB
     326        bool "IMQ BB"
     327        help
     328          This setting defines how IMQ behaves in respect to its
     329          hooking in PREROUTING and POSTROUTING.
     330
     331          Choosing this option will make IMQ hook like this:
     332
     333          PREROUTING:   Before NAT
     334          POSTROUTING:  Before NAT
     335
     336          More information can be found at: https://github.com/imq/linuximq
     337
     338          If not sure leave the default settings alone.
     339
     340endchoice
     341
     342config IMQ_NUM_DEVS
     343        int "Number of IMQ devices"
     344        range 2 16
     345        depends on IMQ
     346        default "16"
     347        help
     348          This setting defines how many IMQ devices will be created.
     349
     350          The default value is 16.
     351
     352          More information can be found at: https://github.com/imq/linuximq
     353
     354          If not sure leave the default settings alone.
     355
    237356config TUN
    238357        tristate "Universal TUN/TAP device driver support"
    239358        depends on INET
  • drivers/net/Makefile

    diff --git a/drivers/net/Makefile b/drivers/net/Makefile
    index 900b0c5..e093402 100644
    a b obj-$(CONFIG_IPVLAN) += ipvlan/ 
    1010obj-$(CONFIG_DUMMY) += dummy.o
    1111obj-$(CONFIG_EQUALIZER) += eql.o
    1212obj-$(CONFIG_IFB) += ifb.o
     13obj-$(CONFIG_IMQ) += imq.o
    1314obj-$(CONFIG_MACVLAN) += macvlan.o
    1415obj-$(CONFIG_MACVTAP) += macvtap.o
    1516obj-$(CONFIG_MII) += mii.o
  • new file drivers/net/imq.c

    diff --git a/drivers/net/imq.c b/drivers/net/imq.c
    new file mode 100644
    index 0000000..f80258f
    - +  
     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 *                         See Creditis.txt
     14 */
     15
     16#include <linux/module.h>
     17#include <linux/kernel.h>
     18#include <linux/moduleparam.h>
     19#include <linux/list.h>
     20#include <linux/skbuff.h>
     21#include <linux/netdevice.h>
     22#include <linux/etherdevice.h>
     23#include <linux/rtnetlink.h>
     24#include <linux/if_arp.h>
     25#include <linux/netfilter.h>
     26#include <linux/netfilter_ipv4.h>
     27#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
     28        #include <linux/netfilter_ipv6.h>
     29#endif
     30#include <linux/imq.h>
     31#include <net/pkt_sched.h>
     32#include <net/netfilter/nf_queue.h>
     33#include <net/sock.h>
     34#include <linux/ip.h>
     35#include <linux/ipv6.h>
     36#include <linux/if_vlan.h>
     37#include <linux/if_pppox.h>
     38#include <net/ip.h>
     39#include <net/ipv6.h>
     40
     41static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num);
     42
     43static nf_hookfn imq_nf_hook;
     44
     45static struct nf_hook_ops imq_ops[] = {
     46        {
     47        /* imq_ingress_ipv4 */
     48                .hook           = imq_nf_hook,
     49                .pf             = PF_INET,
     50                .hooknum        = NF_INET_PRE_ROUTING,
     51#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
     52                .priority       = NF_IP_PRI_MANGLE + 1,
     53#else
     54                .priority       = NF_IP_PRI_NAT_DST + 1,
     55#endif
     56        },
     57        {
     58        /* imq_egress_ipv4 */
     59                .hook           = imq_nf_hook,
     60                .pf             = PF_INET,
     61                .hooknum        = NF_INET_POST_ROUTING,
     62#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
     63                .priority       = NF_IP_PRI_LAST,
     64#else
     65                .priority       = NF_IP_PRI_NAT_SRC - 1,
     66#endif
     67        },
     68#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
     69        {
     70        /* imq_ingress_ipv6 */
     71                .hook           = imq_nf_hook,
     72                .pf             = PF_INET6,
     73                .hooknum        = NF_INET_PRE_ROUTING,
     74#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
     75                .priority       = NF_IP6_PRI_MANGLE + 1,
     76#else
     77                .priority       = NF_IP6_PRI_NAT_DST + 1,
     78#endif
     79        },
     80        {
     81        /* imq_egress_ipv6 */
     82                .hook           = imq_nf_hook,
     83                .pf             = PF_INET6,
     84                .hooknum        = NF_INET_POST_ROUTING,
     85#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
     86                .priority       = NF_IP6_PRI_LAST,
     87#else
     88                .priority       = NF_IP6_PRI_NAT_SRC - 1,
     89#endif
     90        },
     91#endif
     92};
     93
     94#if defined(CONFIG_IMQ_NUM_DEVS)
     95static int numdevs = CONFIG_IMQ_NUM_DEVS;
     96#else
     97static int numdevs = IMQ_MAX_DEVS;
     98#endif
     99
     100static struct net_device *imq_devs_cache[IMQ_MAX_DEVS];
     101
     102#define IMQ_MAX_QUEUES 32
     103static int numqueues = 1;
     104static u32 imq_hashrnd;
     105static int imq_dev_accurate_stats = 1;
     106
     107static inline __be16 pppoe_proto(const struct sk_buff *skb)
     108{
     109        return *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
     110                        sizeof(struct pppoe_hdr)));
     111}
     112
     113static u16 imq_hash(struct net_device *dev, struct sk_buff *skb)
     114{
     115        unsigned int pull_len;
     116        u16 protocol = skb->protocol;
     117        u32 addr1, addr2;
     118        u32 hash, ihl = 0;
     119        union {
     120                u16 in16[2];
     121                u32 in32;
     122        } ports;
     123        u8 ip_proto;
     124
     125        pull_len = 0;
     126
     127recheck:
     128        switch (protocol) {
     129        case htons(ETH_P_8021Q): {
     130                if (unlikely(skb_pull(skb, VLAN_HLEN) == NULL))
     131                        goto other;
     132
     133                pull_len += VLAN_HLEN;
     134                skb->network_header += VLAN_HLEN;
     135
     136                protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
     137                goto recheck;
     138        }
     139
     140        case htons(ETH_P_PPP_SES): {
     141                if (unlikely(skb_pull(skb, PPPOE_SES_HLEN) == NULL))
     142                        goto other;
     143
     144                pull_len += PPPOE_SES_HLEN;
     145                skb->network_header += PPPOE_SES_HLEN;
     146
     147                protocol = pppoe_proto(skb);
     148                goto recheck;
     149        }
     150
     151        case htons(ETH_P_IP): {
     152                const struct iphdr *iph = ip_hdr(skb);
     153
     154                if (unlikely(!pskb_may_pull(skb, sizeof(struct iphdr))))
     155                        goto other;
     156
     157                addr1 = iph->daddr;
     158                addr2 = iph->saddr;
     159
     160                ip_proto = !(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) ?
     161                                 iph->protocol : 0;
     162                ihl = ip_hdrlen(skb);
     163
     164                break;
     165        }
     166#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
     167        case htons(ETH_P_IPV6): {
     168                const struct ipv6hdr *iph = ipv6_hdr(skb);
     169                __be16 fo = 0;
     170
     171                if (unlikely(!pskb_may_pull(skb, sizeof(struct ipv6hdr))))
     172                        goto other;
     173
     174                addr1 = iph->daddr.s6_addr32[3];
     175                addr2 = iph->saddr.s6_addr32[3];
     176                ihl = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &ip_proto,
     177                                       &fo);
     178                if (unlikely(ihl < 0))
     179                        goto other;
     180
     181                break;
     182        }
     183#endif
     184        default:
     185other:
     186                if (pull_len != 0) {
     187                        skb_push(skb, pull_len);
     188                        skb->network_header -= pull_len;
     189                }
     190
     191                return (u16)(ntohs(protocol) % dev->real_num_tx_queues);
     192        }
     193
     194        if (addr1 > addr2)
     195                swap(addr1, addr2);
     196
     197        switch (ip_proto) {
     198        case IPPROTO_TCP:
     199        case IPPROTO_UDP:
     200        case IPPROTO_DCCP:
     201        case IPPROTO_ESP:
     202        case IPPROTO_AH:
     203        case IPPROTO_SCTP:
     204        case IPPROTO_UDPLITE: {
     205                if (likely(skb_copy_bits(skb, ihl, &ports.in32, 4) >= 0)) {
     206                        if (ports.in16[0] > ports.in16[1])
     207                                swap(ports.in16[0], ports.in16[1]);
     208                        break;
     209                }
     210                /* fall-through */
     211        }
     212        default:
     213                ports.in32 = 0;
     214                break;
     215        }
     216
     217        if (pull_len != 0) {
     218                skb_push(skb, pull_len);
     219                skb->network_header -= pull_len;
     220        }
     221
     222        hash = jhash_3words(addr1, addr2, ports.in32, imq_hashrnd ^ ip_proto);
     223
     224        return (u16)(((u64)hash * dev->real_num_tx_queues) >> 32);
     225}
     226
     227static inline bool sk_tx_queue_recorded(struct sock *sk)
     228{
     229        return (sk_tx_queue_get(sk) >= 0);
     230}
     231
     232static struct netdev_queue *imq_select_queue(struct net_device *dev,
     233                                                struct sk_buff *skb)
     234{
     235        u16 queue_index = 0;
     236        u32 hash;
     237
     238        if (likely(dev->real_num_tx_queues == 1))
     239                goto out;
     240
     241        /* IMQ can be receiving ingress or engress packets. */
     242
     243        /* Check first for if rx_queue is set */
     244        if (skb_rx_queue_recorded(skb)) {
     245                queue_index = skb_get_rx_queue(skb);
     246                goto out;
     247        }
     248
     249        /* Check if socket has tx_queue set */
     250        if (sk_tx_queue_recorded(skb->sk)) {
     251                queue_index = sk_tx_queue_get(skb->sk);
     252                goto out;
     253        }
     254
     255        /* Try use socket hash */
     256        if (skb->sk && skb->sk->sk_hash) {
     257                hash = skb->sk->sk_hash;
     258                queue_index =
     259                        (u16)(((u64)hash * dev->real_num_tx_queues) >> 32);
     260                goto out;
     261        }
     262
     263        /* Generate hash from packet data */
     264        queue_index = imq_hash(dev, skb);
     265
     266out:
     267        if (unlikely(queue_index >= dev->real_num_tx_queues))
     268                queue_index = (u16)((u32)queue_index % dev->real_num_tx_queues);
     269
     270        skb_set_queue_mapping(skb, queue_index);
     271        return netdev_get_tx_queue(dev, queue_index);
     272}
     273
     274static struct net_device_stats *imq_get_stats(struct net_device *dev)
     275{
     276        return &dev->stats;
     277}
     278
     279/* called for packets kfree'd in qdiscs at places other than enqueue */
     280static void imq_skb_destructor(struct sk_buff *skb)
     281{
     282        struct nf_queue_entry *entry = skb->nf_queue_entry;
     283
     284        skb->nf_queue_entry = NULL;
     285
     286        if (entry) {
     287                nf_queue_entry_release_refs(entry);
     288                kfree(entry);
     289        }
     290
     291        skb_restore_cb(skb); /* kfree backup */
     292}
     293
     294static void imq_done_check_queue_mapping(struct sk_buff *skb,
     295                                         struct net_device *dev)
     296{
     297        unsigned int queue_index;
     298
     299        /* Don't let queue_mapping be left too large after exiting IMQ */
     300        if (likely(skb->dev != dev && skb->dev != NULL)) {
     301                queue_index = skb_get_queue_mapping(skb);
     302                if (unlikely(queue_index >= skb->dev->real_num_tx_queues)) {
     303                        queue_index = (u16)((u32)queue_index %
     304                                                skb->dev->real_num_tx_queues);
     305                        skb_set_queue_mapping(skb, queue_index);
     306                }
     307        } else {
     308                /* skb->dev was IMQ device itself or NULL, be on safe side and
     309                 * just clear queue mapping.
     310                 */
     311                skb_set_queue_mapping(skb, 0);
     312        }
     313}
     314
     315static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
     316{
     317        struct nf_queue_entry *entry = skb->nf_queue_entry;
     318
     319        skb->nf_queue_entry = NULL;
     320        dev->trans_start = jiffies;
     321
     322        dev->stats.tx_bytes += skb->len;
     323        dev->stats.tx_packets++;
     324
     325        if (unlikely(entry == NULL)) {
     326                /* We don't know what is going on here.. packet is queued for
     327                 * imq device, but (probably) not by us.
     328                 *
     329                 * If this packet was not send here by imq_nf_queue(), then
     330                 * skb_save_cb() was not used and skb_free() should not show:
     331                 *   WARNING: IMQ: kfree_skb: skb->cb_next:..
     332                 * and/or
     333                 *   WARNING: IMQ: kfree_skb: skb->nf_queue_entry...
     334                 *
     335                 * However if this message is shown, then IMQ is somehow broken
     336                 * and you should report this to linuximq.net.
     337                 */
     338
     339                /* imq_dev_xmit is black hole that eats all packets, report that
     340                 * we eat this packet happily and increase dropped counters.
     341                 */
     342
     343                dev->stats.tx_dropped++;
     344                dev_kfree_skb(skb);
     345
     346                return NETDEV_TX_OK;
     347        }
     348
     349        skb_restore_cb(skb); /* restore skb->cb */
     350
     351        skb->imq_flags = 0;
     352        skb->destructor = NULL;
     353
     354        imq_done_check_queue_mapping(skb, dev);
     355
     356        nf_reinject(entry, NF_ACCEPT);
     357
     358        return NETDEV_TX_OK;
     359}
     360
     361static struct net_device *get_imq_device_by_index(int index)
     362{
     363        struct net_device *dev = NULL;
     364        struct net *net;
     365        char buf[8];
     366
     367        /* get device by name and cache result */
     368        snprintf(buf, sizeof(buf), "imq%d", index);
     369
     370        /* Search device from all namespaces. */
     371        for_each_net(net) {
     372                dev = dev_get_by_name(net, buf);
     373                if (dev)
     374                        break;
     375        }
     376
     377        if (WARN_ON_ONCE(dev == NULL)) {
     378                /* IMQ device not found. Exotic config? */
     379                return ERR_PTR(-ENODEV);
     380        }
     381
     382        imq_devs_cache[index] = dev;
     383        dev_put(dev);
     384
     385        return dev;
     386}
     387
     388static struct nf_queue_entry *nf_queue_entry_dup(struct nf_queue_entry *e)
     389{
     390        struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
     391        if (entry) {
     392                nf_queue_entry_get_refs(entry);
     393                        return entry;
     394        }
     395        return NULL;
     396}
     397
     398#ifdef CONFIG_BRIDGE_NETFILTER
     399/* When called from bridge netfilter, skb->data must point to MAC header
     400 * before calling skb_gso_segment(). Else, original MAC header is lost
     401 * and segmented skbs will be sent to wrong destination.
     402 */
     403static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
     404{
     405        if (skb->nf_bridge)
     406                __skb_push(skb, skb->network_header - skb->mac_header);
     407}
     408
     409static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
     410{
     411        if (skb->nf_bridge)
     412                __skb_pull(skb, skb->network_header - skb->mac_header);
     413}
     414#else
     415#define nf_bridge_adjust_skb_data(s) do {} while (0)
     416#define nf_bridge_adjust_segmented_data(s) do {} while (0)
     417#endif
     418
     419static void free_entry(struct nf_queue_entry *entry)
     420{
     421        nf_queue_entry_release_refs(entry);
     422        kfree(entry);
     423}
     424
     425static int __imq_nf_queue(struct nf_queue_entry *entry, struct net_device *dev);
     426
     427static int __imq_nf_queue_gso(struct nf_queue_entry *entry,
     428                              struct net_device *dev, struct sk_buff *skb)
     429{
     430        int ret = -ENOMEM;
     431        struct nf_queue_entry *entry_seg;
     432
     433        nf_bridge_adjust_segmented_data(skb);
     434
     435        if (skb->next == NULL) { /* last packet, no need to copy entry */
     436                struct sk_buff *gso_skb = entry->skb;
     437                entry->skb = skb;
     438                ret = __imq_nf_queue(entry, dev);
     439                if (ret)
     440                        entry->skb = gso_skb;
     441                return ret;
     442        }
     443
     444        skb->next = NULL;
     445
     446        entry_seg = nf_queue_entry_dup(entry);
     447        if (entry_seg) {
     448                entry_seg->skb = skb;
     449                ret = __imq_nf_queue(entry_seg, dev);
     450                if (ret)
     451                        free_entry(entry_seg);
     452        }
     453        return ret;
     454}
     455
     456static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num)
     457{
     458        struct sk_buff *skb, *segs;
     459        struct net_device *dev;
     460        unsigned int queued;
     461        int index, retval, err;
     462
     463        index = entry->skb->imq_flags & IMQ_F_IFMASK;
     464        if (unlikely(index > numdevs - 1)) {
     465                if (net_ratelimit())
     466                        pr_warn("IMQ: invalid device specified, highest is %u\n",
     467                                numdevs - 1);
     468                retval = -EINVAL;
     469                goto out_no_dev;
     470        }
     471
     472        /* check for imq device by index from cache */
     473        dev = imq_devs_cache[index];
     474        if (unlikely(!dev)) {
     475                dev = get_imq_device_by_index(index);
     476                if (IS_ERR(dev)) {
     477                        retval = PTR_ERR(dev);
     478                        goto out_no_dev;
     479                }
     480        }
     481
     482        if (unlikely(!(dev->flags & IFF_UP))) {
     483                entry->skb->imq_flags = 0;
     484                retval = -ECANCELED;
     485                goto out_no_dev;
     486        }
     487
     488        /* Since 3.10.x, GSO handling moved here as result of upstream commit
     489         * a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2 (netfilter: move
     490         * skb_gso_segment into nfnetlink_queue module).
     491         *
     492         * Following code replicates the gso handling from
     493         * 'net/netfilter/nfnetlink_queue_core.c':nfqnl_enqueue_packet().
     494         */
     495
     496        skb = entry->skb;
     497
     498        switch (entry->state.pf) {
     499        case NFPROTO_IPV4:
     500                skb->protocol = htons(ETH_P_IP);
     501                break;
     502        case NFPROTO_IPV6:
     503                skb->protocol = htons(ETH_P_IPV6);
     504                break;
     505        }
     506
     507        if (!skb_is_gso(entry->skb))
     508                return __imq_nf_queue(entry, dev);
     509
     510        nf_bridge_adjust_skb_data(skb);
     511        segs = skb_gso_segment(skb, 0);
     512        /* Does not use PTR_ERR to limit the number of error codes that can be
     513         * returned by nf_queue.  For instance, callers rely on -ECANCELED to
     514         * mean 'ignore this hook'.
     515         */
     516        err = -ENOBUFS;
     517        if (IS_ERR(segs))
     518                goto out_err;
     519        queued = 0;
     520        err = 0;
     521        do {
     522                struct sk_buff *nskb = segs->next;
     523                if (nskb && nskb->next)
     524                        nskb->cb_next = NULL;
     525                if (err == 0)
     526                        err = __imq_nf_queue_gso(entry, dev, segs);
     527                if (err == 0)
     528                        queued++;
     529                else
     530                        kfree_skb(segs);
     531                segs = nskb;
     532        } while (segs);
     533
     534        if (queued) {
     535                if (err) /* some segments are already queued */
     536                        free_entry(entry);
     537                kfree_skb(skb);
     538                return 0;
     539        }
     540
     541out_err:
     542        nf_bridge_adjust_segmented_data(skb);
     543        retval = err;
     544out_no_dev:
     545        return retval;
     546}
     547
     548static int __imq_nf_queue(struct nf_queue_entry *entry, struct net_device *dev)
     549{
     550        struct sk_buff *skb_orig, *skb, *skb_shared, *skb_popd;
     551        struct Qdisc *q;
     552        struct netdev_queue *txq;
     553        spinlock_t *root_lock;
     554        int users;
     555        int retval = -EINVAL;
     556        unsigned int orig_queue_index;
     557
     558        dev->last_rx = jiffies;
     559
     560        skb = entry->skb;
     561        skb_orig = NULL;
     562
     563        /* skb has owner? => make clone */
     564        if (unlikely(skb->destructor)) {
     565                skb_orig = skb;
     566                skb = skb_clone(skb, GFP_ATOMIC);
     567                if (unlikely(!skb)) {
     568                        retval = -ENOMEM;
     569                        goto out;
     570                }
     571                skb->cb_next = NULL;
     572                entry->skb = skb;
     573        }
     574
     575        dev->stats.rx_bytes += skb->len;
     576        dev->stats.rx_packets++;
     577
     578        if (!skb->dev) {
     579                /* skb->dev == NULL causes problems, try the find cause. */
     580                if (net_ratelimit()) {
     581                        dev_warn(&dev->dev,
     582                                 "received packet with skb->dev == NULL\n");
     583                        dump_stack();
     584                }
     585
     586                skb->dev = dev;
     587        }
     588
     589        /* Disables softirqs for lock below */
     590        rcu_read_lock_bh();
     591
     592        /* Multi-queue selection */
     593        orig_queue_index = skb_get_queue_mapping(skb);
     594        txq = imq_select_queue(dev, skb);
     595
     596        q = rcu_dereference(txq->qdisc);
     597        if (unlikely(!q->enqueue))
     598                goto packet_not_eaten_by_imq_dev;
     599
     600        skb->nf_queue_entry = entry;
     601        root_lock = qdisc_lock(q);
     602        spin_lock(root_lock);
     603
     604        users = atomic_read(&skb->users);
     605
     606        skb_shared = skb_get(skb); /* increase reference count by one */
     607
     608        /* backup skb->cb, as qdisc layer will overwrite it */
     609        skb_save_cb(skb_shared);
     610        qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
     611        if (likely(atomic_read(&skb_shared->users) == users + 1)) {
     612                bool validate;
     613
     614                kfree_skb(skb_shared); /* decrease reference count by one */
     615
     616                skb->destructor = &imq_skb_destructor;
     617
     618                skb_popd = qdisc_dequeue_skb(q, &validate);
     619
     620                /* cloned? */
     621                if (unlikely(skb_orig))
     622                        kfree_skb(skb_orig); /* free original */
     623
     624                spin_unlock(root_lock);
     625
     626#if 0
     627                /* schedule qdisc dequeue */
     628                __netif_schedule(q);
     629#else
     630                if (likely(skb_popd)) {
     631                        /* Note that we validate skb (GSO, checksum, ...) outside of locks */
     632                        if (validate)
     633                        skb_popd = validate_xmit_skb_list(skb_popd, dev);
     634                       
     635                        if (skb_popd) {
     636                                int dummy_ret;
     637                                int cpu = smp_processor_id(); /* ok because BHs are off */
     638
     639                                txq = skb_get_tx_queue(dev, skb_popd);
     640                                /*
     641                                IMQ device will not be frozen or stoped, and it always be successful.
     642                                So we need not check its status and return value to accelerate.
     643                                */
     644                                if (imq_dev_accurate_stats && txq->xmit_lock_owner != cpu) {
     645                                        HARD_TX_LOCK(dev, txq, cpu);
     646                                        if (!netif_xmit_frozen_or_stopped(txq)) {
     647                                                dev_hard_start_xmit(skb_popd, dev, txq, &dummy_ret);
     648                                        }
     649                                        HARD_TX_UNLOCK(dev, txq);
     650                                } else {
     651                                        if (!netif_xmit_frozen_or_stopped(txq)) {
     652                                                dev_hard_start_xmit(skb_popd, dev, txq, &dummy_ret);
     653                                        }
     654                                }
     655                        }
     656                } else {
     657                        /* No ready skb, then schedule it */
     658                        __netif_schedule(q);
     659                }
     660#endif
     661                rcu_read_unlock_bh();
     662                retval = 0;
     663                goto out;
     664        } else {
     665                skb_restore_cb(skb_shared); /* restore skb->cb */
     666                skb->nf_queue_entry = NULL;
     667                /*
     668                 * qdisc dropped packet and decreased skb reference count of
     669                 * skb, so we don't really want to and try refree as that would
     670                 * actually destroy the skb.
     671                 */
     672                spin_unlock(root_lock);
     673                goto packet_not_eaten_by_imq_dev;
     674        }
     675
     676packet_not_eaten_by_imq_dev:
     677        skb_set_queue_mapping(skb, orig_queue_index);
     678        rcu_read_unlock_bh();
     679
     680        /* cloned? restore original */
     681        if (unlikely(skb_orig)) {
     682                kfree_skb(skb);
     683                entry->skb = skb_orig;
     684        }
     685        retval = -1;
     686out:
     687        return retval;
     688}
     689static unsigned int imq_nf_hook(void *priv,
     690                                struct sk_buff *skb,
     691                                const struct nf_hook_state *state)
     692{
     693        return (skb->imq_flags & IMQ_F_ENQUEUE) ? NF_IMQ_QUEUE : NF_ACCEPT;
     694}
     695
     696static int imq_close(struct net_device *dev)
     697{
     698        netif_stop_queue(dev);
     699        return 0;
     700}
     701
     702static int imq_open(struct net_device *dev)
     703{
     704        netif_start_queue(dev);
     705        return 0;
     706}
     707
     708static const struct net_device_ops imq_netdev_ops = {
     709        .ndo_open               = imq_open,
     710        .ndo_stop               = imq_close,
     711        .ndo_start_xmit         = imq_dev_xmit,
     712        .ndo_get_stats          = imq_get_stats,
     713};
     714
     715static void imq_setup(struct net_device *dev)
     716{
     717        dev->netdev_ops         = &imq_netdev_ops;
     718        dev->type               = ARPHRD_VOID;
     719        dev->mtu                = 16000; /* too small? */
     720        dev->tx_queue_len       = 11000; /* too big? */
     721        dev->flags              = IFF_NOARP;
     722        dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
     723                                  NETIF_F_GSO | NETIF_F_HW_CSUM |
     724                                  NETIF_F_HIGHDMA;
     725        dev->priv_flags         &= ~(IFF_XMIT_DST_RELEASE |
     726                                     IFF_TX_SKB_SHARING);
     727}
     728
     729static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
     730{
     731        int ret = 0;
     732
     733        if (tb[IFLA_ADDRESS]) {
     734                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
     735                        ret = -EINVAL;
     736                        goto end;
     737                }
     738                if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
     739                        ret = -EADDRNOTAVAIL;
     740                        goto end;
     741                }
     742        }
     743        return 0;
     744end:
     745        pr_warn("IMQ: imq_validate failed (%d)\n", ret);
     746        return ret;
     747}
     748
     749static struct rtnl_link_ops imq_link_ops __read_mostly = {
     750        .kind           = "imq",
     751        .priv_size      = 0,
     752        .setup          = imq_setup,
     753        .validate       = imq_validate,
     754};
     755
     756static const struct nf_queue_handler imq_nfqh = {
     757        .outfn = imq_nf_queue,
     758};
     759
     760static int __init imq_init_hooks(void)
     761{
     762        int ret;
     763
     764        nf_register_queue_imq_handler(&imq_nfqh);
     765
     766        ret = nf_register_hooks(imq_ops, ARRAY_SIZE(imq_ops));
     767        if (ret < 0)
     768                nf_unregister_queue_imq_handler();
     769
     770        return ret;
     771}
     772
     773static int __init imq_init_one(int index)
     774{
     775        struct net_device *dev;
     776        int ret;
     777
     778        dev = alloc_netdev_mq(0, "imq%d", NET_NAME_UNKNOWN, imq_setup, numqueues);
     779        if (!dev)
     780                return -ENOMEM;
     781
     782        ret = dev_alloc_name(dev, dev->name);
     783        if (ret < 0)
     784                goto fail;
     785
     786        dev->rtnl_link_ops = &imq_link_ops;
     787        ret = register_netdevice(dev);
     788        if (ret < 0)
     789                goto fail;
     790
     791        return 0;
     792fail:
     793        free_netdev(dev);
     794        return ret;
     795}
     796
     797static int __init imq_init_devs(void)
     798{
     799        int err, i;
     800
     801        if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
     802                pr_err("IMQ: numdevs has to be betweed 1 and %u\n",
     803                       IMQ_MAX_DEVS);
     804                return -EINVAL;
     805        }
     806
     807        if (numqueues < 1 || numqueues > IMQ_MAX_QUEUES) {
     808                pr_err("IMQ: numqueues has to be betweed 1 and %u\n",
     809                       IMQ_MAX_QUEUES);
     810                return -EINVAL;
     811        }
     812
     813        get_random_bytes(&imq_hashrnd, sizeof(imq_hashrnd));
     814
     815        rtnl_lock();
     816        err = __rtnl_link_register(&imq_link_ops);
     817
     818        for (i = 0; i < numdevs && !err; i++)
     819                err = imq_init_one(i);
     820
     821        if (err) {
     822                __rtnl_link_unregister(&imq_link_ops);
     823                memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
     824        }
     825        rtnl_unlock();
     826
     827        return err;
     828}
     829
     830static int __init imq_init_module(void)
     831{
     832        int err;
     833
     834#if defined(CONFIG_IMQ_NUM_DEVS)
     835        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
     836        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
     837        BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
     838#endif
     839
     840        err = imq_init_devs();
     841        if (err) {
     842                pr_err("IMQ: Error trying imq_init_devs(net)\n");
     843                return err;
     844        }
     845
     846        err = imq_init_hooks();
     847        if (err) {
     848                pr_err(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
     849                rtnl_link_unregister(&imq_link_ops);
     850                memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
     851                return err;
     852        }
     853
     854        pr_info("IMQ driver loaded successfully. (numdevs = %d, numqueues = %d, imq_dev_accurate_stats = %d)\n",
     855                numdevs, numqueues, imq_dev_accurate_stats);
     856
     857#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
     858        pr_info("\tHooking IMQ before NAT on PREROUTING.\n");
     859#else
     860        pr_info("\tHooking IMQ after NAT on PREROUTING.\n");
     861#endif
     862#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
     863        pr_info("\tHooking IMQ before NAT on POSTROUTING.\n");
     864#else
     865        pr_info("\tHooking IMQ after NAT on POSTROUTING.\n");
     866#endif
     867
     868        return 0;
     869}
     870
     871static void __exit imq_unhook(void)
     872{
     873        nf_unregister_hooks(imq_ops, ARRAY_SIZE(imq_ops));
     874        nf_unregister_queue_imq_handler();
     875}
     876
     877static void __exit imq_cleanup_devs(void)
     878{
     879        rtnl_link_unregister(&imq_link_ops);
     880        memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
     881}
     882
     883static void __exit imq_exit_module(void)
     884{
     885        imq_unhook();
     886        imq_cleanup_devs();
     887        pr_info("IMQ driver unloaded successfully.\n");
     888}
     889
     890module_init(imq_init_module);
     891module_exit(imq_exit_module);
     892
     893module_param(numdevs, int, 0);
     894module_param(numqueues, int, 0);
     895module_param(imq_dev_accurate_stats, int, 0);
     896MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)");
     897MODULE_PARM_DESC(numqueues, "number of queues per IMQ device");
     898MODULE_PARM_DESC(imq_dev_accurate_stats, "Notify if need the accurate imq device stats");
     899
     900MODULE_AUTHOR("http://https://github.com/imq/linuximq");
     901MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See https://github.com/imq/linuximq/wiki for more information.");
     902MODULE_LICENSE("GPL");
     903MODULE_ALIAS_RTNL_LINK("imq");
  • new file include/linux/imq.h

    diff --git a/include/linux/imq.h b/include/linux/imq.h
    new file mode 100644
    index 0000000..1babb09
    - +  
     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

    diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
    index 3143c84..e213b31 100644
    a b static inline void netif_tx_unlock_bh(struct net_device *dev) 
    33413341        }                                               \
    33423342}
    33433343
     3344#define HARD_TX_LOCK_BH(dev, txq) {           \
     3345    if ((dev->features & NETIF_F_LLTX) == 0) {  \
     3346        __netif_tx_lock_bh(txq);      \
     3347    }                       \
     3348}
     3349
     3350#define HARD_TX_UNLOCK_BH(dev, txq) {          \
     3351    if ((dev->features & NETIF_F_LLTX) == 0) {  \
     3352        __netif_tx_unlock_bh(txq);         \
     3353    }                       \
     3354}
     3355
     3356
    33443357static inline void netif_tx_disable(struct net_device *dev)
    33453358{
    33463359        unsigned int i;
  • new file include/linux/netfilter/xt_IMQ.h

    diff --git a/include/linux/netfilter/xt_IMQ.h b/include/linux/netfilter/xt_IMQ.h
    new file mode 100644
    index 0000000..9b07230
    - +  
     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

    diff --git a/include/linux/netfilter_ipv4/ipt_IMQ.h b/include/linux/netfilter_ipv4/ipt_IMQ.h
    new file mode 100644
    index 0000000..7af320f
    - +  
     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

    diff --git a/include/linux/netfilter_ipv6/ip6t_IMQ.h b/include/linux/netfilter_ipv6/ip6t_IMQ.h
    new file mode 100644
    index 0000000..198ac01
    - +  
     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

    diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
    index 4355129..47914c0 100644
    a b  
    3838#include <linux/splice.h>
    3939#include <linux/in6.h>
    4040#include <net/flow.h>
     41#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     42#include <linux/imq.h>
     43#endif
     44
    4145
    4246/* A. Checksumming of received packets by device.
    4347 *
    struct sk_buff { 
    566570         * first. This is owned by whoever has the skb queued ATM.
    567571         */
    568572        char                    cb[48] __aligned(8);
     573#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     574        void                    *cb_next;
     575#endif
    569576
    570577        unsigned long           _skb_refdst;
    571578        void                    (*destructor)(struct sk_buff *skb);
    struct sk_buff { 
    575582#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
    576583        struct nf_conntrack     *nfct;
    577584#endif
     585#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     586       struct nf_queue_entry   *nf_queue_entry;
     587#endif
    578588#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
    579589        struct nf_bridge_info   *nf_bridge;
    580590#endif
    struct sk_buff { 
    642652        __u8                    inner_protocol_type:1;
    643653        __u8                    remcsum_offload:1;
    644654        /* 3 or 5 bit hole */
     655        #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     656        __u8                    imq_flags:IMQ_F_BITS;
     657        #endif
    645658
    646659#ifdef CONFIG_NET_SCHED
    647660        __u16                   tc_index;       /* traffic control index */
    void kfree_skb_list(struct sk_buff *segs); 
    798811void skb_tx_error(struct sk_buff *skb);
    799812void consume_skb(struct sk_buff *skb);
    800813void  __kfree_skb(struct sk_buff *skb);
     814
     815#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     816int skb_save_cb(struct sk_buff *skb);
     817int skb_restore_cb(struct sk_buff *skb);
     818#endif
     819
    801820extern struct kmem_cache *skbuff_head_cache;
    802821
    803822void kfree_skb_partial(struct sk_buff *skb, bool head_stolen);
    static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, 
    33443363        if (copy)
    33453364                dst->nfctinfo = src->nfctinfo;
    33463365#endif
     3366#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     3367       dst->imq_flags = src->imq_flags;
     3368       dst->nf_queue_entry = src->nf_queue_entry;
     3369#endif
    33473370#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
    33483371        dst->nf_bridge  = src->nf_bridge;
    33493372        nf_bridge_get(src->nf_bridge);
  • include/net/netfilter/nf_queue.h

    diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
    index 9c5638a..b173aa7 100644
    a b struct nf_queue_handler { 
    3131void nf_register_queue_handler(const struct nf_queue_handler *qh);
    3232void nf_unregister_queue_handler(void);
    3333void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
     34void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
     35
     36#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     37void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
     38void nf_unregister_queue_imq_handler(void);
     39#endif
    3440
    3541void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
    3642void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
  • include/net/pkt_sched.h

    diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
    index 401038d..4668849 100644
    a b int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, 
    104104
    105105void __qdisc_run(struct Qdisc *q);
    106106
     107struct sk_buff *qdisc_dequeue_skb(struct Qdisc *q, bool *validate);
     108
    107109static inline void qdisc_run(struct Qdisc *q)
    108110{
    109111        if (qdisc_run_begin(q))
  • include/net/sch_generic.h

    diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
    index b2a8e63..d9feaa3 100644
    a b static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 
    506506        return sch->enqueue(skb, sch);
    507507}
    508508
     509static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
     510{
     511    qdisc_skb_cb(skb)->pkt_len = skb->len;
     512    return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
     513}
     514
    509515static inline bool qdisc_is_percpu_stats(const struct Qdisc *q)
    510516{
    511517        return q->flags & TCQ_F_CPUSTATS;
  • include/uapi/linux/netfilter.h

    diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h
    index d93f949..23fb6d1 100644
    a b  
    1414#define NF_QUEUE 3
    1515#define NF_REPEAT 4
    1616#define NF_STOP 5
    17 #define NF_MAX_VERDICT NF_STOP
     17#define NF_IMQ_QUEUE 6
     18#define NF_MAX_VERDICT NF_IMQ_QUEUE
    1819
    1920/* we overload the higher bits for encoding auxiliary data such as the queue
    2021 * number or errno values. Not nice, but better than additional function
  • net/core/dev.c

    diff --git a/net/core/dev.c b/net/core/dev.c
    index ae00b89..1cdcd02 100644
    a b  
    137137#include <linux/errqueue.h>
    138138#include <linux/hrtimer.h>
    139139#include <linux/netfilter_ingress.h>
     140#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     141#include <linux/imq.h>
     142#endif
    140143
    141144#include "net-sysfs.h"
    142145
    static int xmit_one(struct sk_buff *skb, struct net_device *dev, 
    27052708        unsigned int len;
    27062709        int rc;
    27072710
     2711#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     2712        if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) &&
     2713                !(skb->imq_flags & IMQ_F_ENQUEUE))
     2714#else
    27082715        if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
     2716#endif
    27092717                dev_queue_xmit_nit(skb, dev);
    27102718
    27112719        len = skb->len;
    out: 
    27432751        *ret = rc;
    27442752        return skb;
    27452753}
     2754EXPORT_SYMBOL(dev_hard_start_xmit);
    27462755
    27472756static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb,
    27482757                                          netdev_features_t features)
    struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d 
    28312840        }
    28322841        return head;
    28332842}
     2843//EXPORT_SYMBOL(validate_xmit_skb_list);
    28342844
    28352845static void qdisc_pkt_len_init(struct sk_buff *skb)
    28362846{
  • net/core/skbuff.c

    diff --git a/net/core/skbuff.c b/net/core/skbuff.c
    index b2df375..bc3c51e 100644
    a b  
    7979static struct kmem_cache *skbuff_fclone_cache __read_mostly;
    8080int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
    8181EXPORT_SYMBOL(sysctl_max_skb_frags);
     82#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     83static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
     84#endif
     85
     86#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     87/* Control buffer save/restore for IMQ devices */
     88struct skb_cb_table {
     89        char                    cb[48] __aligned(8);
     90        void                    *cb_next;
     91        atomic_t                refcnt;
     92};
     93
     94static DEFINE_SPINLOCK(skb_cb_store_lock);
     95
     96int skb_save_cb(struct sk_buff *skb)
     97{
     98        struct skb_cb_table *next;
     99
     100        next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
     101        if (!next)
     102                return -ENOMEM;
     103
     104        BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
     105
     106        memcpy(next->cb, skb->cb, sizeof(skb->cb));
     107        next->cb_next = skb->cb_next;
     108
     109        atomic_set(&next->refcnt, 1);
     110
     111        skb->cb_next = next;
     112        return 0;
     113}
     114EXPORT_SYMBOL(skb_save_cb);
     115
     116int skb_restore_cb(struct sk_buff *skb)
     117{
     118        struct skb_cb_table *next;
     119
     120        if (!skb->cb_next)
     121                return 0;
     122
     123        next = skb->cb_next;
     124
     125        BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
     126
     127        memcpy(skb->cb, next->cb, sizeof(skb->cb));
     128        skb->cb_next = next->cb_next;
     129
     130        spin_lock(&skb_cb_store_lock);
     131
     132        if (atomic_dec_and_test(&next->refcnt))
     133                kmem_cache_free(skbuff_cb_store_cache, next);
     134
     135        spin_unlock(&skb_cb_store_lock);
     136
     137        return 0;
     138}
     139EXPORT_SYMBOL(skb_restore_cb);
     140
     141static void skb_copy_stored_cb(struct sk_buff *   , const struct sk_buff *     ) __attribute__ ((unused));
     142static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
     143{
     144        struct skb_cb_table *next;
     145        struct sk_buff *old;
     146
     147        if (!__old->cb_next) {
     148                new->cb_next = NULL;
     149                return;
     150        }
     151
     152        spin_lock(&skb_cb_store_lock);
     153
     154        old = (struct sk_buff *)__old;
     155
     156        next = old->cb_next;
     157        atomic_inc(&next->refcnt);
     158        new->cb_next = next;
     159
     160        spin_unlock(&skb_cb_store_lock);
     161}
     162#endif
    82163
    83164/**
    84165 *      skb_panic - private function for out-of-line support
    static void skb_release_head_state(struct sk_buff *skb) 
    643724                WARN_ON(in_irq());
    644725                skb->destructor(skb);
    645726        }
     727#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     728        /*
     729         * This should not happen. When it does, avoid memleak by restoring
     730         * the chain of cb-backups.
     731         */
     732        while (skb->cb_next != NULL) {
     733                if (net_ratelimit())
     734                        pr_warn("IMQ: kfree_skb: skb->cb_next: %08x\n",
     735                                (unsigned int)(uintptr_t)skb->cb_next);
     736
     737                skb_restore_cb(skb);
     738        }
     739        /*
     740         * This should not happen either, nf_queue_entry is nullified in
     741         * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
     742         * leaking entry pointers, maybe memory. We don't know if this is
     743         * pointer to already freed memory, or should this be freed.
     744         * If this happens we need to add refcounting, etc for nf_queue_entry.
     745         */
     746        if (skb->nf_queue_entry && net_ratelimit())
     747                pr_warn("%s\n", "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
     748#endif
    646749#if IS_ENABLED(CONFIG_NF_CONNTRACK)
    647750        nf_conntrack_put(skb->nfct);
    648751#endif
    static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) 
    765868        new->sp                 = secpath_get(old->sp);
    766869#endif
    767870        __nf_copy(new, old, false);
     871#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     872        new->cb_next = NULL;
     873        /*skb_copy_stored_cb(new, old);*/
     874#endif
    768875
    769876        /* Note : this field could be in headers_start/headers_end section
    770877         * It is not yet because we do not want to have a 16 bit hole
    void __init skb_init(void) 
    33253432                                                0,
    33263433                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
    33273434                                                NULL);
     3435#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     3436        skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
     3437                                                  sizeof(struct skb_cb_table),
     3438                                                  0,
     3439                                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC,
     3440                                                  NULL);
     3441#endif
    33283442}
    33293443
    33303444/**
  • net/ipv6/ip6_output.c

    diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
    index e6a7bd15..c81496e 100644
    a b static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * 
    6565        struct in6_addr *nexthop;
    6666        int ret;
    6767
    68         skb->protocol = htons(ETH_P_IPV6);
    69         skb->dev = dev;
    70 
    7168        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
    7269                struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
    7370
    int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) 
    142139                return 0;
    143140        }
    144141
     142        /*
     143        * IMQ-patch: moved setting skb->dev and skb->protocol from
     144        * ip6_finish_output2 to fix crashing at netif_skb_features().
     145        */
     146        skb->protocol = htons(ETH_P_IPV6);
     147        skb->dev = dev;
     148
    145149        return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
    146150                            net, sk, skb, NULL, dev,
    147151                            ip6_finish_output,
  • net/netfilter/Kconfig

    diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
    index 4692782..dce47db 100644
    a b config NETFILTER_XT_TARGET_LOG 
    785785
    786786          To compile it as a module, choose M here.  If unsure, say N.
    787787
     788config NETFILTER_XT_TARGET_IMQ
     789        tristate '"IMQ" target support'
     790        depends on NETFILTER_XTABLES
     791        depends on IP_NF_MANGLE || IP6_NF_MANGLE
     792        select IMQ
     793        default m if NETFILTER_ADVANCED=n
     794        help
     795          This option adds a `IMQ' target which is used to specify if and
     796          to which imq device packets should get enqueued/dequeued.
     797
     798          To compile it as a module, choose M here.  If unsure, say N.
     799
    788800config NETFILTER_XT_TARGET_MARK
    789801        tristate '"MARK" target support'
    790802        depends on NETFILTER_ADVANCED
  • net/netfilter/Makefile

    diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
    index 7638c36..614ad8a 100644
    a b obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o 
    108108obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
    109109obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
    110110obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
     111obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
    111112obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
    112113obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o
    113114obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o
  • net/netfilter/core.c

    diff --git a/net/netfilter/core.c b/net/netfilter/core.c
    index f39276d..9877a27 100644
    a b next_hook: 
    311311                ret = NF_DROP_GETERR(verdict);
    312312                if (ret == 0)
    313313                        ret = -EPERM;
    314         } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
     314        } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE ||
     315                (verdict & NF_VERDICT_MASK) == NF_IMQ_QUEUE) {
    315316                int err = nf_queue(skb, elem, state,
    316                                    verdict >> NF_VERDICT_QBITS);
     317                                   verdict >> NF_VERDICT_QBITS,
     318                                  verdict & NF_VERDICT_MASK);
    317319                if (err < 0) {
    318320                        if (err == -ESRCH &&
    319321                           (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
  • net/netfilter/nf_internals.h

    diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
    index 0655225..25d4141 100644
    a b unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb, 
    1818
    1919/* nf_queue.c */
    2020int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem,
    21              struct nf_hook_state *state, unsigned int queuenum);
     21             struct nf_hook_state *state, unsigned int queuenum, unsigned int queuetype);
    2222void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops);
    2323int __init netfilter_queue_init(void);
    2424
  • net/netfilter/nf_queue.c

    diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
    index 5baa8e2..9740e8c 100644
    a b  
    2828 */
    2929static const struct nf_queue_handler __rcu *queue_handler __read_mostly;
    3030
     31#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     32static const struct nf_queue_handler __rcu *queue_imq_handler __read_mostly;
     33
     34void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
     35{
     36        rcu_assign_pointer(queue_imq_handler, qh);
     37}
     38EXPORT_SYMBOL_GPL(nf_register_queue_imq_handler);
     39
     40void nf_unregister_queue_imq_handler(void)
     41{
     42        RCU_INIT_POINTER(queue_imq_handler, NULL);
     43        synchronize_rcu();
     44}
     45EXPORT_SYMBOL_GPL(nf_unregister_queue_imq_handler);
     46#endif
     47
    3148/* return EBUSY when somebody else is registered, return EEXIST if the
    3249 * same handler is registered, return 0 in case of success. */
    3350void nf_register_queue_handler(const struct nf_queue_handler *qh)
    void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops) 
    116133int nf_queue(struct sk_buff *skb,
    117134             struct nf_hook_ops *elem,
    118135             struct nf_hook_state *state,
    119              unsigned int queuenum)
     136             unsigned int queuenum,
     137                 unsigned int queuetype)
    120138{
    121139        int status = -ENOENT;
    122140        struct nf_queue_entry *entry = NULL;
    int nf_queue(struct sk_buff *skb, 
    124142        const struct nf_queue_handler *qh;
    125143
    126144        /* QUEUE == DROP if no one is waiting, to be safe. */
    127         qh = rcu_dereference(queue_handler);
     145        if (queuetype == NF_IMQ_QUEUE) {
     146#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
     147                qh = rcu_dereference(queue_imq_handler);
     148#else
     149                BUG();
     150                goto err_unlock;
     151#endif
     152        } else {
     153                qh = rcu_dereference(queue_handler);
     154        }
     155
    128156        if (!qh) {
    129157                status = -ESRCH;
    130158                goto err;
    void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 
    199227                local_bh_enable();
    200228                break;
    201229        case NF_QUEUE:
     230        case NF_IMQ_QUEUE:
    202231                err = nf_queue(skb, elem, &entry->state,
    203                                verdict >> NF_VERDICT_QBITS);
     232                               verdict >> NF_VERDICT_QBITS,
     233                                   verdict & NF_VERDICT_MASK);
    204234                if (err < 0) {
    205235                        if (err == -ESRCH &&
    206236                           (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
  • new file net/netfilter/xt_IMQ.c

    diff --git a/net/netfilter/xt_IMQ.c b/net/netfilter/xt_IMQ.c
    new file mode 100644
    index 0000000..86d7b84
    - +  
     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                pr_warn("IMQ: invalid device specified, highest is %u\n",
     26                        IMQ_MAX_DEVS - 1);
     27                return -EINVAL;
     28        }
     29
     30        return 0;
     31}
     32
     33static struct xt_target xt_imq_reg[] __read_mostly = {
     34        {
     35                .name           = "IMQ",
     36                .family         = AF_INET,
     37                .checkentry     = imq_checkentry,
     38                .target         = imq_target,
     39                .targetsize     = sizeof(struct xt_imq_info),
     40                .table          = "mangle",
     41                .me             = THIS_MODULE
     42        },
     43        {
     44                .name           = "IMQ",
     45                .family         = AF_INET6,
     46                .checkentry     = imq_checkentry,
     47                .target         = imq_target,
     48                .targetsize     = sizeof(struct xt_imq_info),
     49                .table          = "mangle",
     50                .me             = THIS_MODULE
     51        },
     52};
     53
     54static int __init imq_init(void)
     55{
     56        return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
     57}
     58
     59static void __exit imq_fini(void)
     60{
     61        xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
     62}
     63
     64module_init(imq_init);
     65module_exit(imq_fini);
     66
     67MODULE_AUTHOR("http://https://github.com/imq/linuximq");
     68MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See https://github.com/imq/linuximq/wiki for more information.");
     69MODULE_LICENSE("GPL");
     70MODULE_ALIAS("ipt_IMQ");
     71MODULE_ALIAS("ip6t_IMQ");
     72
  • net/sched/sch_generic.c

    diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
    index e82a1ad..b55331d 100644
    a b static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, 
    108108        return skb;
    109109}
    110110
     111struct sk_buff *qdisc_dequeue_skb(struct Qdisc *q, bool *validate)
     112{
     113        int packets;
     114
     115        return dequeue_skb(q, validate, &packets);
     116}
     117EXPORT_SYMBOL(qdisc_dequeue_skb);
     118
    111119static inline int handle_dev_cpu_collision(struct sk_buff *skb,
    112120                                           struct netdev_queue *dev_queue,
    113121                                           struct Qdisc *q)
Note: See TracBrowser for help on using the repository browser.