[packages/kernel] - removed ESFQ, no upstream updates for 8 years - updated IMQ patch
baggins
baggins at pld-linux.org
Sun Oct 9 15:22:43 CEST 2016
commit d5ed51b7363a66e1296f45ec0a857f0267013ee3
Author: Jan Rękorajski <baggins at pld-linux.org>
Date: Sun Oct 9 15:21:23 2016 +0200
- removed ESFQ, no upstream updates for 8 years
- updated IMQ patch
kernel-esfq.patch | 793 ------------------------------------------------------
kernel-imq.patch | 220 +++++++--------
kernel.spec | 9 -
3 files changed, 98 insertions(+), 924 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 7c22b8f..512f49c 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -27,7 +27,6 @@
%bcond_with nfsroot # build with root on NFS support
%bcond_without imq # imq support
-%bcond_with esfq # esfq support
%bcond_without ipv6 # ipv6 support
%bcond_with vserver # support for VServer
@@ -168,9 +167,6 @@ Patch40: kernel-layer7.patch
# http://www.linuximq.net
Patch50: kernel-imq.patch
-# http://fatooh.org/esfq-2.6/sfq-2.6.24.1.tar.bz2
-Patch53: kernel-esfq.patch
-
# by Baggins request:
# derived from ftp://ftp.cmf.nrl.navy.mil/pub/chas/linux-atm/vbr/vbr-kernel-diffs
Patch55: kernel-atm-vbr.patch
@@ -670,11 +666,6 @@ cd linux-%{basever}
%patch50 -p1
%endif
-# esfq
-%if %{with esfq}
-%patch53 -p1
-%endif
-
%patch55 -p1
%patch56 -p1
diff --git a/kernel-esfq.patch b/kernel-esfq.patch
deleted file mode 100644
index 355a644..0000000
--- a/kernel-esfq.patch
+++ /dev/null
@@ -1,793 +0,0 @@
-diff -Naur linux-2.6.24.orig/include/uapi/linux/pkt_sched.h linux-2.6.24/include/uapi/linux/pkt_sched.h
---- linux-2.6.24.orig/include/uapi/linux/pkt_sched.h 2008-01-24 14:58:37.000000000 -0800
-+++ linux-2.6.24/include/uapi/linux/pkt_sched.h 2008-01-28 00:27:12.000000000 -0800
-@@ -157,6 +157,33 @@
- * to change these parameters in compile time.
- */
-
-+/* ESFQ section */
-+
-+enum
-+{
-+ /* traditional */
-+ TCA_ESFQ_HASH_CLASSIC,
-+ TCA_ESFQ_HASH_DST,
-+ TCA_ESFQ_HASH_SRC,
-+ TCA_ESFQ_HASH_FWMARK,
-+ /* conntrack */
-+ TCA_ESFQ_HASH_CTORIGDST,
-+ TCA_ESFQ_HASH_CTORIGSRC,
-+ TCA_ESFQ_HASH_CTREPLDST,
-+ TCA_ESFQ_HASH_CTREPLSRC,
-+ TCA_ESFQ_HASH_CTNATCHG,
-+};
-+
-+struct tc_esfq_qopt
-+{
-+ unsigned quantum; /* Bytes per round allocated to flow */
-+ int perturb_period; /* Period of hash perturbation */
-+ __u32 limit; /* Maximal packets in queue */
-+ unsigned divisor; /* Hash divisor */
-+ unsigned flows; /* Maximal number of flows */
-+ unsigned hash_kind; /* Hash function to use for flow identification */
-+};
-+
- /* RED section */
-
- enum
-diff -Naur linux-2.6.24.orig/net/sched/Kconfig linux-2.6.24/net/sched/Kconfig
---- linux-2.6.24.orig/net/sched/Kconfig 2008-01-24 14:58:37.000000000 -0800
-+++ linux-2.6.24/net/sched/Kconfig 2008-01-28 00:27:12.000000000 -0800
-@@ -139,6 +139,37 @@
- To compile this code as a module, choose M here: the
- module will be called sch_sfq.
-
-+config NET_SCH_ESFQ
-+ tristate "Enhanced Stochastic Fairness Queueing (ESFQ)"
-+ ---help---
-+ Say Y here if you want to use the Enhanced Stochastic Fairness
-+ Queueing (ESFQ) packet scheduling algorithm for some of your network
-+ devices or as a leaf discipline for a classful qdisc such as HTB or
-+ CBQ (see the top of <file:net/sched/sch_esfq.c> for details and
-+ references to the SFQ algorithm).
-+
-+ This is an enchanced SFQ version which allows you to control some
-+ hardcoded values in the SFQ scheduler.
-+
-+ ESFQ also adds control of the hash function used to identify packet
-+ flows. The original SFQ discipline hashes by connection; ESFQ add
-+ several other hashing methods, such as by src IP or by dst IP, which
-+ can be more fair to users in some networking situations.
-+
-+ To compile this code as a module, choose M here: the
-+ module will be called sch_esfq.
-+
-+config NET_SCH_ESFQ_NFCT
-+ bool "Connection Tracking Hash Types"
-+ depends on NET_SCH_ESFQ && NF_CONNTRACK
-+ ---help---
-+ Say Y here to enable support for hashing based on netfilter connection
-+ tracking information. This is useful for a router that is also using
-+ NAT to connect privately-addressed hosts to the Internet. If you want
-+ to provide fair distribution of upstream bandwidth, ESFQ must use
-+ connection tracking information, since all outgoing packets will share
-+ the same source address.
-+
- config NET_SCH_TEQL
- tristate "True Link Equalizer (TEQL)"
- ---help---
-diff -Naur linux-2.6.24.orig/net/sched/Makefile linux-2.6.24/net/sched/Makefile
---- linux-2.6.24.orig/net/sched/Makefile 2008-01-24 14:58:37.000000000 -0800
-+++ linux-2.6.24/net/sched/Makefile 2008-01-28 00:27:12.000000000 -0800
-@@ -23,6 +23,7 @@
- obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o
- obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
- obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
-+obj-$(CONFIG_NET_SCH_ESFQ) += sch_esfq.o
- obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
- obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
- obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
-diff -Naur linux-2.6.24.orig/net/sched/sch_esfq.c linux-2.6.24/net/sched/sch_esfq.c
---- linux-2.6.24.orig/net/sched/sch_esfq.c 1969-12-31 16:00:00.000000000 -0800
-+++ linux-2.6.24/net/sched/sch_esfq.c 2008-01-28 00:27:22.000000000 -0800
-@@ -0,0 +1,700 @@
-+/*
-+ * net/sched/sch_esfq.c Extended Stochastic Fairness Queueing discipline.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ * Authors: Alexey Kuznetsov, <kuznet at ms2.inr.ac.ru>
-+ *
-+ * Changes: Alexander Atanasov, <alex at ssi.bg>
-+ * Added dynamic depth,limit,divisor,hash_kind options.
-+ * Added dst and src hashes.
-+ *
-+ * Alexander Clouter, <alex at digriz.org.uk>
-+ * Ported ESFQ to Linux 2.6.
-+ *
-+ * Corey Hickey, <bugfood-c at fatooh.org>
-+ * Maintenance of the Linux 2.6 port.
-+ * Added fwmark hash (thanks to Robert Kurjata).
-+ * Added usage of jhash.
-+ * Added conntrack support.
-+ * Added ctnatchg hash (thanks to Ben Pfountz).
-+ */
-+
-+#include <linux/module.h>
-+#include <asm/uaccess.h>
-+
-+#include <linux/bitops.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/jiffies.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/in.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/if_ether.h>
-+#include <linux/inet.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/notifier.h>
-+#include <linux/init.h>
-+#include <net/ip.h>
-+#include <net/netlink.h>
-+#include <linux/ipv6.h>
-+#include <net/route.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <net/pkt_sched.h>
-+#include <linux/jhash.h>
-+#include <net/netfilter/nf_conntrack.h>
-+
-+/* Stochastic Fairness Queuing algorithm.
-+ For more comments look at sch_sfq.c.
-+ The difference is that you can change limit, depth,
-+ hash table size and choose alternate hash types.
-+
-+ classic: same as in sch_sfq.c
-+ dst: destination IP address
-+ src: source IP address
-+ fwmark: netfilter mark value
-+ ctorigdst: original destination IP address
-+ ctorigsrc: original source IP address
-+ ctrepldst: reply destination IP address
-+ ctreplsrc: reply source IP
-+
-+*/
-+
-+#define ESFQ_HEAD 0
-+#define ESFQ_TAIL 1
-+
-+/* This type should contain at least SFQ_DEPTH*2 values */
-+typedef unsigned int esfq_index;
-+
-+struct esfq_head
-+{
-+ esfq_index next;
-+ esfq_index prev;
-+};
-+
-+struct esfq_sched_data
-+{
-+/* Parameters */
-+ int perturb_period;
-+ unsigned quantum; /* Allotment per round: MUST BE >= MTU */
-+ int limit;
-+ unsigned depth;
-+ unsigned hash_divisor;
-+ unsigned hash_kind;
-+/* Variables */
-+ struct timer_list perturb_timer;
-+ int perturbation;
-+ esfq_index tail; /* Index of current slot in round */
-+ esfq_index max_depth; /* Maximal depth */
-+
-+ esfq_index *ht; /* Hash table */
-+ esfq_index *next; /* Active slots link */
-+ short *allot; /* Current allotment per slot */
-+ unsigned short *hash; /* Hash value indexed by slots */
-+ struct sk_buff_head *qs; /* Slot queue */
-+ struct esfq_head *dep; /* Linked list of slots, indexed by depth */
-+};
-+
-+/* This contains the info we will hash. */
-+struct esfq_packet_info
-+{
-+ u32 proto; /* protocol or port */
-+ u32 src; /* source from packet header */
-+ u32 dst; /* destination from packet header */
-+ u32 ctorigsrc; /* original source from conntrack */
-+ u32 ctorigdst; /* original destination from conntrack */
-+ u32 ctreplsrc; /* reply source from conntrack */
-+ u32 ctrepldst; /* reply destination from conntrack */
-+ u32 mark; /* netfilter mark (fwmark) */
-+};
-+
-+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a)
-+{
-+ return jhash_1word(a, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b)
-+{
-+ return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c)
-+{
-+ return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
-+{
-+ struct esfq_packet_info info;
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+ enum ip_conntrack_info ctinfo;
-+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-+#endif
-+
-+ switch (skb->protocol) {
-+ case __constant_htons(ETH_P_IP):
-+ {
-+ struct iphdr *iph = ip_hdr(skb);
-+ info.dst = iph->daddr;
-+ info.src = iph->saddr;
-+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
-+ (iph->protocol == IPPROTO_TCP ||
-+ iph->protocol == IPPROTO_UDP ||
-+ iph->protocol == IPPROTO_SCTP ||
-+ iph->protocol == IPPROTO_DCCP ||
-+ iph->protocol == IPPROTO_ESP))
-+ info.proto = *(((u32*)iph) + iph->ihl);
-+ else
-+ info.proto = iph->protocol;
-+ break;
-+ }
-+ case __constant_htons(ETH_P_IPV6):
-+ {
-+ struct ipv6hdr *iph = ipv6_hdr(skb);
-+ /* Hash ipv6 addresses into a u32. This isn't ideal,
-+ * but the code is simple. */
-+ info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation);
-+ info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation);
-+ if (iph->nexthdr == IPPROTO_TCP ||
-+ iph->nexthdr == IPPROTO_UDP ||
-+ iph->nexthdr == IPPROTO_SCTP ||
-+ iph->nexthdr == IPPROTO_DCCP ||
-+ iph->nexthdr == IPPROTO_ESP)
-+ info.proto = *(u32*)&iph[1];
-+ else
-+ info.proto = iph->nexthdr;
-+ break;
-+ }
-+ default:
-+ info.dst = (u32)(unsigned long)skb_dst(skb);
-+ info.src = (u32)(unsigned long)skb->sk;
-+ info.proto = skb->protocol;
-+ }
-+
-+ info.mark = skb->mark;
-+
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+ /* defaults if there is no conntrack info */
-+ info.ctorigsrc = info.src;
-+ info.ctorigdst = info.dst;
-+ info.ctreplsrc = info.dst;
-+ info.ctrepldst = info.src;
-+ /* collect conntrack info */
-+ if (ct && ct != &nf_conntrack_untracked) {
-+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
-+ info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
-+ info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;
-+ info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
-+ info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
-+ }
-+ else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
-+ /* Again, hash ipv6 addresses into a single u32. */
-+ info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation);
-+ info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation);
-+ info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation);
-+ info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation);
-+ }
-+
-+ }
-+#endif
-+
-+ switch(q->hash_kind) {
-+ case TCA_ESFQ_HASH_CLASSIC:
-+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+ case TCA_ESFQ_HASH_DST:
-+ return esfq_jhash_1word(q, info.dst);
-+ case TCA_ESFQ_HASH_SRC:
-+ return esfq_jhash_1word(q, info.src);
-+ case TCA_ESFQ_HASH_FWMARK:
-+ return esfq_jhash_1word(q, info.mark);
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+ case TCA_ESFQ_HASH_CTORIGDST:
-+ return esfq_jhash_1word(q, info.ctorigdst);
-+ case TCA_ESFQ_HASH_CTORIGSRC:
-+ return esfq_jhash_1word(q, info.ctorigsrc);
-+ case TCA_ESFQ_HASH_CTREPLDST:
-+ return esfq_jhash_1word(q, info.ctrepldst);
-+ case TCA_ESFQ_HASH_CTREPLSRC:
-+ return esfq_jhash_1word(q, info.ctreplsrc);
-+ case TCA_ESFQ_HASH_CTNATCHG:
-+ {
-+ if (info.ctorigdst == info.ctreplsrc)
-+ return esfq_jhash_1word(q, info.ctorigsrc);
-+ return esfq_jhash_1word(q, info.ctreplsrc);
-+ }
-+#endif
-+ default:
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
-+ }
-+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+}
-+
-+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x)
-+{
-+ esfq_index p, n;
-+ int d = q->qs[x].qlen + q->depth;
-+
-+ p = d;
-+ n = q->dep[d].next;
-+ q->dep[x].next = n;
-+ q->dep[x].prev = p;
-+ q->dep[p].next = q->dep[n].prev = x;
-+}
-+
-+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x)
-+{
-+ esfq_index p, n;
-+
-+ n = q->dep[x].next;
-+ p = q->dep[x].prev;
-+ q->dep[p].next = n;
-+ q->dep[n].prev = p;
-+
-+ if (n == p && q->max_depth == q->qs[x].qlen + 1)
-+ q->max_depth--;
-+
-+ esfq_link(q, x);
-+}
-+
-+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x)
-+{
-+ esfq_index p, n;
-+ int d;
-+
-+ n = q->dep[x].next;
-+ p = q->dep[x].prev;
-+ q->dep[p].next = n;
-+ q->dep[n].prev = p;
-+ d = q->qs[x].qlen;
-+ if (q->max_depth < d)
-+ q->max_depth = d;
-+
-+ esfq_link(q, x);
-+}
-+
-+static unsigned int esfq_drop(struct Qdisc *sch)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ esfq_index d = q->max_depth;
-+ struct sk_buff *skb;
-+ unsigned int len;
-+
-+ /* Queue is full! Find the longest slot and
-+ drop a packet from it */
-+
-+ if (d > 1) {
-+ esfq_index x = q->dep[d+q->depth].next;
-+ skb = q->qs[x].prev;
-+ len = skb->len;
-+ __skb_unlink(skb, &q->qs[x]);
-+ kfree_skb(skb);
-+ esfq_dec(q, x);
-+ sch->q.qlen--;
-+ sch->qstats.drops++;
-+ sch->qstats.backlog -= len;
-+ return len;
-+ }
-+
-+ if (d == 1) {
-+ /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
-+ d = q->next[q->tail];
-+ q->next[q->tail] = q->next[d];
-+ q->allot[q->next[d]] += q->quantum;
-+ skb = q->qs[d].prev;
-+ len = skb->len;
-+ __skb_unlink(skb, &q->qs[d]);
-+ kfree_skb(skb);
-+ esfq_dec(q, d);
-+ sch->q.qlen--;
-+ q->ht[q->hash[d]] = q->depth;
-+ sch->qstats.drops++;
-+ sch->qstats.backlog -= len;
-+ return len;
-+ }
-+
-+ return 0;
-+}
-+
-+static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end)
-+{
-+ unsigned hash = esfq_hash(q, skb);
-+ unsigned depth = q->depth;
-+ esfq_index x;
-+
-+ x = q->ht[hash];
-+ if (x == depth) {
-+ q->ht[hash] = x = q->dep[depth].next;
-+ q->hash[x] = hash;
-+ }
-+
-+ if (end == ESFQ_TAIL)
-+ __skb_queue_tail(&q->qs[x], skb);
-+ else
-+ __skb_queue_head(&q->qs[x], skb);
-+
-+ esfq_inc(q, x);
-+ if (q->qs[x].qlen == 1) { /* The flow is new */
-+ if (q->tail == depth) { /* It is the first flow */
-+ q->tail = x;
-+ q->next[x] = x;
-+ q->allot[x] = q->quantum;
-+ } else {
-+ q->next[x] = q->next[q->tail];
-+ q->next[q->tail] = x;
-+ q->tail = x;
-+ }
-+ }
-+}
-+
-+static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ esfq_q_enqueue(skb, q, ESFQ_TAIL);
-+ sch->qstats.backlog += skb->len;
-+ if (++sch->q.qlen < q->limit-1) {
-+ sch->bstats.bytes += skb->len;
-+ sch->bstats.packets++;
-+ return 0;
-+ }
-+
-+ sch->qstats.drops++;
-+ esfq_drop(sch);
-+ return NET_XMIT_CN;
-+}
-+
-+static struct sk_buff *esfq_peek(struct Qdisc* sch)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ esfq_index a;
-+
-+ /* No active slots */
-+ if (q->tail == q->depth)
-+ return NULL;
-+
-+ a = q->next[q->tail];
-+ return skb_peek(&q->qs[a]);
-+}
-+
-+static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q)
-+{
-+ struct sk_buff *skb;
-+ unsigned depth = q->depth;
-+ esfq_index a, old_a;
-+
-+ /* No active slots */
-+ if (q->tail == depth)
-+ return NULL;
-+
-+ a = old_a = q->next[q->tail];
-+
-+ /* Grab packet */
-+ skb = __skb_dequeue(&q->qs[a]);
-+ esfq_dec(q, a);
-+
-+ /* Is the slot empty? */
-+ if (q->qs[a].qlen == 0) {
-+ q->ht[q->hash[a]] = depth;
-+ a = q->next[a];
-+ if (a == old_a) {
-+ q->tail = depth;
-+ return skb;
-+ }
-+ q->next[q->tail] = a;
-+ q->allot[a] += q->quantum;
-+ } else if ((q->allot[a] -= skb->len) <= 0) {
-+ q->tail = a;
-+ a = q->next[a];
-+ q->allot[a] += q->quantum;
-+ }
-+
-+ return skb;
-+}
-+
-+static struct sk_buff *esfq_dequeue(struct Qdisc* sch)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ struct sk_buff *skb;
-+
-+ skb = esfq_q_dequeue(q);
-+ if (skb == NULL)
-+ return NULL;
-+ sch->q.qlen--;
-+ sch->qstats.backlog -= skb->len;
-+ return skb;
-+}
-+
-+static void esfq_q_destroy(struct esfq_sched_data *q)
-+{
-+ del_timer(&q->perturb_timer);
-+ if(q->ht)
-+ kfree(q->ht);
-+ if(q->dep)
-+ kfree(q->dep);
-+ if(q->next)
-+ kfree(q->next);
-+ if(q->allot)
-+ kfree(q->allot);
-+ if(q->hash)
-+ kfree(q->hash);
-+ if(q->qs)
-+ kfree(q->qs);
-+}
-+
-+static void esfq_destroy(struct Qdisc *sch)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ esfq_q_destroy(q);
-+}
-+
-+
-+static void esfq_reset(struct Qdisc* sch)
-+{
-+ struct sk_buff *skb;
-+
-+ while ((skb = esfq_dequeue(sch)) != NULL)
-+ kfree_skb(skb);
-+}
-+
-+static void esfq_perturbation(unsigned long arg)
-+{
-+ struct Qdisc *sch = (struct Qdisc*)arg;
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+
-+ q->perturbation = prandom_u32() & 0x1F;
-+
-+ if (q->perturb_period) {
-+ q->perturb_timer.expires = jiffies + q->perturb_period;
-+ add_timer(&q->perturb_timer);
-+ }
-+}
-+
-+static unsigned int esfq_check_hash(unsigned int kind)
-+{
-+ switch (kind) {
-+ case TCA_ESFQ_HASH_CTORIGDST:
-+ case TCA_ESFQ_HASH_CTORIGSRC:
-+ case TCA_ESFQ_HASH_CTREPLDST:
-+ case TCA_ESFQ_HASH_CTREPLSRC:
-+ case TCA_ESFQ_HASH_CTNATCHG:
-+#ifndef CONFIG_NET_SCH_ESFQ_NFCT
-+ {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n");
-+ return TCA_ESFQ_HASH_CLASSIC;
-+ }
-+#endif
-+ case TCA_ESFQ_HASH_CLASSIC:
-+ case TCA_ESFQ_HASH_DST:
-+ case TCA_ESFQ_HASH_SRC:
-+ case TCA_ESFQ_HASH_FWMARK:
-+ return kind;
-+ default:
-+ {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n");
-+ return TCA_ESFQ_HASH_CLASSIC;
-+ }
-+ }
-+}
-+
-+static int esfq_q_init(struct esfq_sched_data *q, struct nlattr *opt)
-+{
-+ struct tc_esfq_qopt *ctl = nla_data(opt);
-+ esfq_index p = ~0U/2;
-+ int i;
-+
-+ if (opt && opt->nla_len < nla_attr_size(sizeof(*ctl)))
-+ return -EINVAL;
-+
-+ q->perturbation = 0;
-+ q->hash_kind = TCA_ESFQ_HASH_CLASSIC;
-+ q->max_depth = 0;
-+ if (opt == NULL) {
-+ q->perturb_period = 0;
-+ q->hash_divisor = 1024;
-+ q->tail = q->limit = q->depth = 128;
-+
-+ } else {
-+ struct tc_esfq_qopt *ctl = nla_data(opt);
-+ if (ctl->quantum)
-+ q->quantum = ctl->quantum;
-+ q->perturb_period = ctl->perturb_period*HZ;
-+ q->hash_divisor = ctl->divisor ? : 1024;
-+ q->tail = q->limit = q->depth = ctl->flows ? : 128;
-+
-+ if ( q->depth > p - 1 )
-+ return -EINVAL;
-+
-+ if (ctl->limit)
-+ q->limit = min_t(u32, ctl->limit, q->depth);
-+
-+ if (ctl->hash_kind) {
-+ q->hash_kind = esfq_check_hash(ctl->hash_kind);
-+ }
-+ }
-+
-+ q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL);
-+ if (!q->ht)
-+ goto err_case;
-+ q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL);
-+ if (!q->dep)
-+ goto err_case;
-+ q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL);
-+ if (!q->next)
-+ goto err_case;
-+ q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL);
-+ if (!q->allot)
-+ goto err_case;
-+ q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL);
-+ if (!q->hash)
-+ goto err_case;
-+ q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL);
-+ if (!q->qs)
-+ goto err_case;
-+
-+ for (i=0; i< q->hash_divisor; i++)
-+ q->ht[i] = q->depth;
-+ for (i=0; i<q->depth; i++) {
-+ skb_queue_head_init(&q->qs[i]);
-+ q->dep[i+q->depth].next = i+q->depth;
-+ q->dep[i+q->depth].prev = i+q->depth;
-+ }
-+
-+ for (i=0; i<q->depth; i++)
-+ esfq_link(q, i);
-+ return 0;
-+err_case:
-+ esfq_q_destroy(q);
-+ return -ENOBUFS;
-+}
-+
-+static int esfq_init(struct Qdisc *sch, struct nlattr *opt)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ int err;
-+
-+ q->quantum = psched_mtu(qdisc_dev(sch)); /* default */
-+ if ((err = esfq_q_init(q, opt)))
-+ return err;
-+
-+ init_timer(&q->perturb_timer);
-+ q->perturb_timer.data = (unsigned long)sch;
-+ q->perturb_timer.function = esfq_perturbation;
-+ if (q->perturb_period) {
-+ q->perturb_timer.expires = jiffies + q->perturb_period;
-+ add_timer(&q->perturb_timer);
-+ }
-+
-+ return 0;
-+}
-+
-+static int esfq_change(struct Qdisc *sch, struct nlattr *opt)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ struct esfq_sched_data new;
-+ struct sk_buff *skb;
-+ int err;
-+
-+ /* set up new queue */
-+ memset(&new, 0, sizeof(struct esfq_sched_data));
-+ new.quantum = psched_mtu(qdisc_dev(sch)); /* default */
-+ if ((err = esfq_q_init(&new, opt)))
-+ return err;
-+
-+ /* copy all packets from the old queue to the new queue */
-+ sch_tree_lock(sch);
-+ while ((skb = esfq_q_dequeue(q)) != NULL)
-+ esfq_q_enqueue(skb, &new, ESFQ_TAIL);
-+
-+ /* clean up the old queue */
-+ esfq_q_destroy(q);
-+
-+ /* copy elements of the new queue into the old queue */
-+ q->perturb_period = new.perturb_period;
-+ q->quantum = new.quantum;
-+ q->limit = new.limit;
-+ q->depth = new.depth;
-+ q->hash_divisor = new.hash_divisor;
-+ q->hash_kind = new.hash_kind;
-+ q->tail = new.tail;
-+ q->max_depth = new.max_depth;
-+ q->ht = new.ht;
-+ q->dep = new.dep;
-+ q->next = new.next;
-+ q->allot = new.allot;
-+ q->hash = new.hash;
-+ q->qs = new.qs;
-+
-+ /* finish up */
-+ if (q->perturb_period) {
-+ q->perturb_timer.expires = jiffies + q->perturb_period;
-+ add_timer(&q->perturb_timer);
-+ } else {
-+ q->perturbation = 0;
-+ }
-+ sch_tree_unlock(sch);
-+ return 0;
-+}
-+
-+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb)
-+{
-+ struct esfq_sched_data *q = qdisc_priv(sch);
-+ unsigned char *b = skb_tail_pointer(skb);
-+ struct tc_esfq_qopt opt;
-+
-+ opt.quantum = q->quantum;
-+ opt.perturb_period = q->perturb_period/HZ;
-+
-+ opt.limit = q->limit;
-+ opt.divisor = q->hash_divisor;
-+ opt.flows = q->depth;
-+ opt.hash_kind = q->hash_kind;
-+
-+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
-+ goto nla_put_failure;
-+ return skb->len;
-+
-+nla_put_failure:
-+ nlmsg_trim(skb, b);
-+ return -1;
-+}
-+
-+static struct Qdisc_ops esfq_qdisc_ops =
-+{
-+ .next = NULL,
-+ .cl_ops = NULL,
-+ .id = "esfq",
-+ .priv_size = sizeof(struct esfq_sched_data),
-+ .enqueue = esfq_enqueue,
-+ .dequeue = esfq_dequeue,
-+ .peek = esfq_peek,
-+ .drop = esfq_drop,
-+ .init = esfq_init,
-+ .reset = esfq_reset,
-+ .destroy = esfq_destroy,
-+ .change = esfq_change,
-+ .dump = esfq_dump,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int __init esfq_module_init(void)
-+{
-+ return register_qdisc(&esfq_qdisc_ops);
-+}
-+static void __exit esfq_module_exit(void)
-+{
-+ unregister_qdisc(&esfq_qdisc_ops);
-+}
-+module_init(esfq_module_init)
-+module_exit(esfq_module_exit)
-+MODULE_LICENSE("GPL");
diff --git a/kernel-imq.patch b/kernel-imq.patch
index cc4028b..cbfd042 100644
--- a/kernel-imq.patch
+++ b/kernel-imq.patch
@@ -1,7 +1,7 @@
-diff -Naupr linux-4.7_orig/drivers/net/imq.c linux-4.7/drivers/net/imq.c
---- linux-4.7_orig/drivers/net/imq.c 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/drivers/net/imq.c 2016-07-26 20:58:55.635901659 +0700
-@@ -0,0 +1,903 @@
+diff -Naupr linux-4.8_orig/drivers/net/imq.c linux-4.8/drivers/net/imq.c
+--- linux-4.8_orig/drivers/net/imq.c 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/drivers/net/imq.c 2016-10-03 07:59:56.140345020 +0700
+@@ -0,0 +1,904 @@
+/*
+ * Pseudo-driver for the intermediate queue device.
+ *
@@ -553,6 +553,7 @@ diff -Naupr linux-4.7_orig/drivers/net/imq.c linux-4.7/drivers/net/imq.c
+{
+ struct sk_buff *skb_orig, *skb, *skb_shared, *skb_popd;
+ struct Qdisc *q;
++ struct sk_buff **to_free;
+ struct netdev_queue *txq;
+ spinlock_t *root_lock;
+ int users;
@@ -611,7 +612,7 @@ diff -Naupr linux-4.7_orig/drivers/net/imq.c linux-4.7/drivers/net/imq.c
+
+ /* backup skb->cb, as qdisc layer will overwrite it */
+ skb_save_cb(skb_shared);
-+ qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
++ qdisc_enqueue_root(skb_shared, q, to_free); /* might kfree_skb */
+ if (likely(atomic_read(&skb_shared->users) == users + 1)) {
+ bool validate;
+
@@ -901,13 +902,13 @@ diff -Naupr linux-4.7_orig/drivers/net/imq.c linux-4.7/drivers/net/imq.c
+MODULE_PARM_DESC(numqueues, "number of queues per IMQ device");
+MODULE_PARM_DESC(imq_dev_accurate_stats, "Notify if need the accurate imq device stats");
+
-+MODULE_AUTHOR("http://https://github.com/imq/linuximq");
++MODULE_AUTHOR("https://github.com/imq/linuximq");
+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See https://github.com/imq/linuximq/wiki for more information.");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("imq");
-diff -Naupr linux-4.7_orig/drivers/net/Kconfig linux-4.7/drivers/net/Kconfig
---- linux-4.7_orig/drivers/net/Kconfig 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/drivers/net/Kconfig 2016-07-26 20:58:55.635901659 +0700
+diff -Naupr linux-4.8_orig/drivers/net/Kconfig linux-4.8/drivers/net/Kconfig
+--- linux-4.8_orig/drivers/net/Kconfig 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/drivers/net/Kconfig 2016-10-03 07:59:56.140345020 +0700
@@ -258,6 +258,125 @@ config RIONET_RX_SIZE
depends on RIONET
default "128"
@@ -1034,9 +1035,9 @@ diff -Naupr linux-4.7_orig/drivers/net/Kconfig linux-4.7/drivers/net/Kconfig
config TUN
tristate "Universal TUN/TAP device driver support"
depends on INET
-diff -Naupr linux-4.7_orig/drivers/net/Makefile linux-4.7/drivers/net/Makefile
---- linux-4.7_orig/drivers/net/Makefile 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/drivers/net/Makefile 2016-07-26 20:58:55.635901659 +0700
+diff -Naupr linux-4.8_orig/drivers/net/Makefile linux-4.8/drivers/net/Makefile
+--- linux-4.8_orig/drivers/net/Makefile 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/drivers/net/Makefile 2016-10-03 07:59:56.200344939 +0700
@@ -11,6 +11,7 @@ obj-$(CONFIG_DUMMY) += dummy.o
obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_IFB) += ifb.o
@@ -1045,9 +1046,9 @@ diff -Naupr linux-4.7_orig/drivers/net/Makefile linux-4.7/drivers/net/Makefile
obj-$(CONFIG_MACVLAN) += macvlan.o
obj-$(CONFIG_MACVTAP) += macvtap.o
obj-$(CONFIG_MII) += mii.o
-diff -Naupr linux-4.7_orig/include/linux/imq.h linux-4.7/include/linux/imq.h
---- linux-4.7_orig/include/linux/imq.h 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/include/linux/imq.h 2016-07-26 20:58:55.639235009 +0700
+diff -Naupr linux-4.8_orig/include/linux/imq.h linux-4.8/include/linux/imq.h
+--- linux-4.8_orig/include/linux/imq.h 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/include/linux/imq.h 2016-10-03 07:59:56.200344939 +0700
@@ -0,0 +1,13 @@
+#ifndef _IMQ_H
+#define _IMQ_H
@@ -1062,10 +1063,10 @@ diff -Naupr linux-4.7_orig/include/linux/imq.h linux-4.7/include/linux/imq.h
+
+#endif /* _IMQ_H */
+
-diff -Naupr linux-4.7_orig/include/linux/netdevice.h linux-4.7/include/linux/netdevice.h
---- linux-4.7_orig/include/linux/netdevice.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/linux/netdevice.h 2016-07-26 20:58:55.639235009 +0700
-@@ -3558,6 +3558,19 @@ static inline void netif_tx_unlock_bh(st
+diff -Naupr linux-4.8_orig/include/linux/netdevice.h linux-4.8/include/linux/netdevice.h
+--- linux-4.8_orig/include/linux/netdevice.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/linux/netdevice.h 2016-10-03 07:59:56.200344939 +0700
+@@ -3602,6 +3602,19 @@ static inline void netif_tx_unlock_bh(st
} \
}
@@ -1085,9 +1086,9 @@ diff -Naupr linux-4.7_orig/include/linux/netdevice.h linux-4.7/include/linux/net
static inline void netif_tx_disable(struct net_device *dev)
{
unsigned int i;
-diff -Naupr linux-4.7_orig/include/linux/netfilter/xt_IMQ.h linux-4.7/include/linux/netfilter/xt_IMQ.h
---- linux-4.7_orig/include/linux/netfilter/xt_IMQ.h 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/include/linux/netfilter/xt_IMQ.h 2016-07-26 20:58:55.639235009 +0700
+diff -Naupr linux-4.8_orig/include/linux/netfilter/xt_IMQ.h linux-4.8/include/linux/netfilter/xt_IMQ.h
+--- linux-4.8_orig/include/linux/netfilter/xt_IMQ.h 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/include/linux/netfilter/xt_IMQ.h 2016-10-03 07:59:56.200344939 +0700
@@ -0,0 +1,9 @@
+#ifndef _XT_IMQ_H
+#define _XT_IMQ_H
@@ -1098,9 +1099,9 @@ diff -Naupr linux-4.7_orig/include/linux/netfilter/xt_IMQ.h linux-4.7/include/li
+
+#endif /* _XT_IMQ_H */
+
-diff -Naupr linux-4.7_orig/include/linux/netfilter_ipv4/ipt_IMQ.h linux-4.7/include/linux/netfilter_ipv4/ipt_IMQ.h
---- linux-4.7_orig/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/include/linux/netfilter_ipv4/ipt_IMQ.h 2016-07-26 20:58:55.639235009 +0700
+diff -Naupr linux-4.8_orig/include/linux/netfilter_ipv4/ipt_IMQ.h linux-4.8/include/linux/netfilter_ipv4/ipt_IMQ.h
+--- linux-4.8_orig/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/include/linux/netfilter_ipv4/ipt_IMQ.h 2016-10-03 07:59:56.200344939 +0700
@@ -0,0 +1,10 @@
+#ifndef _IPT_IMQ_H
+#define _IPT_IMQ_H
@@ -1112,9 +1113,9 @@ diff -Naupr linux-4.7_orig/include/linux/netfilter_ipv4/ipt_IMQ.h linux-4.7/incl
+
+#endif /* _IPT_IMQ_H */
+
-diff -Naupr linux-4.7_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-4.7/include/linux/netfilter_ipv6/ip6t_IMQ.h
---- linux-4.7_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/include/linux/netfilter_ipv6/ip6t_IMQ.h 2016-07-26 20:58:55.639235009 +0700
+diff -Naupr linux-4.8_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-4.8/include/linux/netfilter_ipv6/ip6t_IMQ.h
+--- linux-4.8_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/include/linux/netfilter_ipv6/ip6t_IMQ.h 2016-10-03 07:59:56.200344939 +0700
@@ -0,0 +1,10 @@
+#ifndef _IP6T_IMQ_H
+#define _IP6T_IMQ_H
@@ -1126,12 +1127,12 @@ diff -Naupr linux-4.7_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-4.7/inc
+
+#endif /* _IP6T_IMQ_H */
+
-diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff.h
---- linux-4.7_orig/include/linux/skbuff.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/linux/skbuff.h 2016-07-26 20:58:55.639235009 +0700
-@@ -38,6 +38,10 @@
- #include <linux/splice.h>
+diff -Naupr linux-4.8_orig/include/linux/skbuff.h linux-4.8/include/linux/skbuff.h
+--- linux-4.8_orig/include/linux/skbuff.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/linux/skbuff.h 2016-10-03 07:59:56.200344939 +0700
+@@ -39,6 +39,10 @@
#include <linux/in6.h>
+ #include <linux/if_packet.h>
#include <net/flow.h>
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+#include <linux/imq.h>
@@ -1140,7 +1141,7 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
/* The interface for checksum offload between the stack and networking drivers
* is as follows...
-@@ -647,6 +651,9 @@ struct sk_buff {
+@@ -655,6 +659,9 @@ struct sk_buff {
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48] __aligned(8);
@@ -1150,7 +1151,7 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
unsigned long _skb_refdst;
void (*destructor)(struct sk_buff *skb);
-@@ -656,6 +663,9 @@ struct sk_buff {
+@@ -664,6 +671,9 @@ struct sk_buff {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
#endif
@@ -1160,7 +1161,7 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct nf_bridge_info *nf_bridge;
#endif
-@@ -723,6 +733,9 @@ struct sk_buff {
+@@ -731,6 +741,9 @@ struct sk_buff {
__u8 inner_protocol_type:1;
__u8 remcsum_offload:1;
/* 3 or 5 bit hole */
@@ -1170,7 +1171,7 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
-@@ -879,6 +892,12 @@ void kfree_skb_list(struct sk_buff *segs
+@@ -896,6 +909,12 @@ void kfree_skb_list(struct sk_buff *segs
void skb_tx_error(struct sk_buff *skb);
void consume_skb(struct sk_buff *skb);
void __kfree_skb(struct sk_buff *skb);
@@ -1183,7 +1184,7 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
extern struct kmem_cache *skbuff_head_cache;
void kfree_skb_partial(struct sk_buff *skb, bool head_stolen);
-@@ -3523,6 +3542,10 @@ static inline void __nf_copy(struct sk_b
+@@ -3555,6 +3574,10 @@ static inline void __nf_copy(struct sk_b
if (copy)
dst->nfctinfo = src->nfctinfo;
#endif
@@ -1194,9 +1195,9 @@ diff -Naupr linux-4.7_orig/include/linux/skbuff.h linux-4.7/include/linux/skbuff
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
dst->nf_bridge = src->nf_bridge;
nf_bridge_get(src->nf_bridge);
-diff -Naupr linux-4.7_orig/include/net/netfilter/nf_queue.h linux-4.7/include/net/netfilter/nf_queue.h
---- linux-4.7_orig/include/net/netfilter/nf_queue.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/net/netfilter/nf_queue.h 2016-07-26 20:58:55.642568359 +0700
+diff -Naupr linux-4.8_orig/include/net/netfilter/nf_queue.h linux-4.8/include/net/netfilter/nf_queue.h
+--- linux-4.8_orig/include/net/netfilter/nf_queue.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/net/netfilter/nf_queue.h 2016-10-03 07:59:56.200344939 +0700
@@ -31,6 +31,12 @@ struct nf_queue_handler {
void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
void nf_unregister_queue_handler(struct net *net);
@@ -1210,9 +1211,9 @@ diff -Naupr linux-4.7_orig/include/net/netfilter/nf_queue.h linux-4.7/include/ne
void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-diff -Naupr linux-4.7_orig/include/net/pkt_sched.h linux-4.7/include/net/pkt_sched.h
---- linux-4.7_orig/include/net/pkt_sched.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/net/pkt_sched.h 2016-07-26 20:58:55.642568359 +0700
+diff -Naupr linux-4.8_orig/include/net/pkt_sched.h linux-4.8/include/net/pkt_sched.h
+--- linux-4.8_orig/include/net/pkt_sched.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/net/pkt_sched.h 2016-10-03 07:59:56.200344939 +0700
@@ -105,6 +105,8 @@ int sch_direct_xmit(struct sk_buff *skb,
void __qdisc_run(struct Qdisc *q);
@@ -1222,25 +1223,26 @@ diff -Naupr linux-4.7_orig/include/net/pkt_sched.h linux-4.7/include/net/pkt_sch
static inline void qdisc_run(struct Qdisc *q)
{
if (qdisc_run_begin(q))
-diff -Naupr linux-4.7_orig/include/net/sch_generic.h linux-4.7/include/net/sch_generic.h
---- linux-4.7_orig/include/net/sch_generic.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/net/sch_generic.h 2016-07-26 20:58:55.642568359 +0700
-@@ -523,6 +523,12 @@ static inline int qdisc_enqueue(struct s
- return sch->enqueue(skb, sch);
+diff -Naupr linux-4.8_orig/include/net/sch_generic.h linux-4.8/include/net/sch_generic.h
+--- linux-4.8_orig/include/net/sch_generic.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/net/sch_generic.h 2016-10-03 07:59:56.200344939 +0700
+@@ -510,6 +510,13 @@ static inline int qdisc_enqueue(struct s
+ return sch->enqueue(skb, sch, to_free);
}
-+static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
++static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch,
++ struct sk_buff **to_free)
+{
+ qdisc_skb_cb(skb)->pkt_len = skb->len;
-+ return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
++ return qdisc_enqueue(skb, sch, to_free) & NET_XMIT_MASK;
+}
+
static inline bool qdisc_is_percpu_stats(const struct Qdisc *q)
{
return q->flags & TCQ_F_CPUSTATS;
-diff -Naupr linux-4.7_orig/include/uapi/linux/netfilter.h linux-4.7/include/uapi/linux/netfilter.h
---- linux-4.7_orig/include/uapi/linux/netfilter.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/include/uapi/linux/netfilter.h 2016-07-26 20:58:55.642568359 +0700
+diff -Naupr linux-4.8_orig/include/uapi/linux/netfilter.h linux-4.8/include/uapi/linux/netfilter.h
+--- linux-4.8_orig/include/uapi/linux/netfilter.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/include/uapi/linux/netfilter.h 2016-10-03 07:59:56.203678268 +0700
@@ -14,7 +14,8 @@
#define NF_QUEUE 3
#define NF_REPEAT 4
@@ -1251,10 +1253,10 @@ diff -Naupr linux-4.7_orig/include/uapi/linux/netfilter.h linux-4.7/include/uapi
/* we overload the higher bits for encoding auxiliary data such as the queue
* number or errno values. Not nice, but better than additional function
-diff -Naupr linux-4.7_orig/net/core/dev.c linux-4.7/net/core/dev.c
---- linux-4.7_orig/net/core/dev.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/core/dev.c 2016-07-26 20:58:55.642568359 +0700
-@@ -139,6 +139,9 @@
+diff -Naupr linux-4.8_orig/net/core/dev.c linux-4.8/net/core/dev.c
+--- linux-4.8_orig/net/core/dev.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/core/dev.c 2016-10-03 07:59:56.203678268 +0700
+@@ -141,6 +141,9 @@
#include <linux/netfilter_ingress.h>
#include <linux/sctp.h>
#include <linux/crash_dump.h>
@@ -1264,39 +1266,10 @@ diff -Naupr linux-4.7_orig/net/core/dev.c linux-4.7/net/core/dev.c
#include "net-sysfs.h"
-@@ -2908,7 +2911,12 @@ static int xmit_one(struct sk_buff *skb,
- unsigned int len;
- int rc;
-
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) &&
-+ !(skb->imq_flags & IMQ_F_ENQUEUE))
-+#else
- if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
-+#endif
- dev_queue_xmit_nit(skb, dev);
-
- len = skb->len;
-@@ -2946,6 +2954,7 @@ out:
- *ret = rc;
- return skb;
- }
-+EXPORT_SYMBOL(dev_hard_start_xmit);
-
- static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb,
- netdev_features_t features)
-@@ -3032,6 +3041,7 @@ struct sk_buff *validate_xmit_skb_list(s
- }
- return head;
- }
-+EXPORT_SYMBOL(validate_xmit_skb_list);
-
- static void qdisc_pkt_len_init(struct sk_buff *skb)
- {
-diff -Naupr linux-4.7_orig/net/core/skbuff.c linux-4.7/net/core/skbuff.c
---- linux-4.7_orig/net/core/skbuff.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/core/skbuff.c 2016-07-26 20:58:55.645901708 +0700
-@@ -81,6 +81,87 @@ struct kmem_cache *skbuff_head_cache __r
+diff -Naupr linux-4.8_orig/net/core/skbuff.c linux-4.8/net/core/skbuff.c
+--- linux-4.8_orig/net/core/skbuff.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/core/skbuff.c 2016-10-03 07:59:56.203678268 +0700
+@@ -82,6 +82,87 @@ struct kmem_cache *skbuff_head_cache __r
static struct kmem_cache *skbuff_fclone_cache __read_mostly;
int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
EXPORT_SYMBOL(sysctl_max_skb_frags);
@@ -1384,7 +1357,7 @@ diff -Naupr linux-4.7_orig/net/core/skbuff.c linux-4.7/net/core/skbuff.c
/**
* skb_panic - private function for out-of-line support
-@@ -653,6 +734,28 @@ static void skb_release_head_state(struc
+@@ -654,6 +735,28 @@ static void skb_release_head_state(struc
WARN_ON(in_irq());
skb->destructor(skb);
}
@@ -1413,7 +1386,7 @@ diff -Naupr linux-4.7_orig/net/core/skbuff.c linux-4.7/net/core/skbuff.c
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
nf_conntrack_put(skb->nfct);
#endif
-@@ -842,6 +945,10 @@ static void __copy_skb_header(struct sk_
+@@ -843,6 +946,10 @@ static void __copy_skb_header(struct sk_
new->sp = secpath_get(old->sp);
#endif
__nf_copy(new, old, false);
@@ -1424,7 +1397,7 @@ diff -Naupr linux-4.7_orig/net/core/skbuff.c linux-4.7/net/core/skbuff.c
/* Note : this field could be in headers_start/headers_end section
* It is not yet because we do not want to have a 16 bit hole
-@@ -3433,6 +3540,13 @@ void __init skb_init(void)
+@@ -3439,6 +3546,13 @@ void __init skb_init(void)
0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
@@ -1438,9 +1411,9 @@ diff -Naupr linux-4.7_orig/net/core/skbuff.c linux-4.7/net/core/skbuff.c
}
/**
-diff -Naupr linux-4.7_orig/net/ipv6/ip6_output.c linux-4.7/net/ipv6/ip6_output.c
---- linux-4.7_orig/net/ipv6/ip6_output.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/ipv6/ip6_output.c 2016-07-26 20:58:55.645901708 +0700
+diff -Naupr linux-4.8_orig/net/ipv6/ip6_output.c linux-4.8/net/ipv6/ip6_output.c
+--- linux-4.8_orig/net/ipv6/ip6_output.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/ipv6/ip6_output.c 2016-10-03 07:59:56.203678268 +0700
@@ -65,9 +65,6 @@ static int ip6_finish_output2(struct net
struct in6_addr *nexthop;
int ret;
@@ -1465,10 +1438,10 @@ diff -Naupr linux-4.7_orig/net/ipv6/ip6_output.c linux-4.7/net/ipv6/ip6_output.c
return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
net, sk, skb, NULL, dev,
ip6_finish_output,
-diff -Naupr linux-4.7_orig/net/netfilter/core.c linux-4.7/net/netfilter/core.c
---- linux-4.7_orig/net/netfilter/core.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/netfilter/core.c 2016-07-26 20:58:55.645901708 +0700
-@@ -311,9 +311,11 @@ next_hook:
+diff -Naupr linux-4.8_orig/net/netfilter/core.c linux-4.8/net/netfilter/core.c
+--- linux-4.8_orig/net/netfilter/core.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/netfilter/core.c 2016-10-03 07:59:56.203678268 +0700
+@@ -311,10 +311,14 @@ next_hook:
ret = NF_DROP_GETERR(verdict);
if (ret == 0)
ret = -EPERM;
@@ -1480,12 +1453,15 @@ diff -Naupr linux-4.7_orig/net/netfilter/core.c linux-4.7/net/netfilter/core.c
+ verdict >> NF_VERDICT_QBITS,
+ verdict & NF_VERDICT_MASK);
if (err < 0) {
++ if (err == -ECANCELED)
++ goto next_hook;
if (err == -ESRCH &&
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
-diff -Naupr linux-4.7_orig/net/netfilter/Kconfig linux-4.7/net/netfilter/Kconfig
---- linux-4.7_orig/net/netfilter/Kconfig 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/netfilter/Kconfig 2016-07-26 20:58:55.645901708 +0700
-@@ -807,6 +807,18 @@ config NETFILTER_XT_TARGET_LOG
+ goto next_hook;
+diff -Naupr linux-4.8_orig/net/netfilter/Kconfig linux-4.8/net/netfilter/Kconfig
+--- linux-4.8_orig/net/netfilter/Kconfig 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/netfilter/Kconfig 2016-10-03 07:59:56.203678268 +0700
+@@ -805,6 +805,18 @@ config NETFILTER_XT_TARGET_LOG
To compile it as a module, choose M here. If unsure, say N.
@@ -1504,9 +1480,9 @@ diff -Naupr linux-4.7_orig/net/netfilter/Kconfig linux-4.7/net/netfilter/Kconfig
config NETFILTER_XT_TARGET_MARK
tristate '"MARK" target support'
depends on NETFILTER_ADVANCED
-diff -Naupr linux-4.7_orig/net/netfilter/Makefile linux-4.7/net/netfilter/Makefile
---- linux-4.7_orig/net/netfilter/Makefile 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/netfilter/Makefile 2016-07-26 20:58:55.645901708 +0700
+diff -Naupr linux-4.8_orig/net/netfilter/Makefile linux-4.8/net/netfilter/Makefile
+--- linux-4.8_orig/net/netfilter/Makefile 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/netfilter/Makefile 2016-10-03 07:59:56.203678268 +0700
@@ -115,6 +115,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) +=
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
@@ -1515,9 +1491,9 @@ diff -Naupr linux-4.7_orig/net/netfilter/Makefile linux-4.7/net/netfilter/Makefi
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o
-diff -Naupr linux-4.7_orig/net/netfilter/nf_internals.h linux-4.7/net/netfilter/nf_internals.h
---- linux-4.7_orig/net/netfilter/nf_internals.h 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/netfilter/nf_internals.h 2016-07-26 20:58:55.645901708 +0700
+diff -Naupr linux-4.8_orig/net/netfilter/nf_internals.h linux-4.8/net/netfilter/nf_internals.h
+--- linux-4.8_orig/net/netfilter/nf_internals.h 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/netfilter/nf_internals.h 2016-10-03 07:59:56.203678268 +0700
@@ -18,7 +18,7 @@ unsigned int nf_iterate(struct list_head
/* nf_queue.c */
@@ -1527,9 +1503,9 @@ diff -Naupr linux-4.7_orig/net/netfilter/nf_internals.h linux-4.7/net/netfilter/
void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops);
int __init netfilter_queue_init(void);
-diff -Naupr linux-4.7_orig/net/netfilter/nf_queue.c linux-4.7/net/netfilter/nf_queue.c
---- linux-4.7_orig/net/netfilter/nf_queue.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/netfilter/nf_queue.c 2016-07-26 20:58:55.649235058 +0700
+diff -Naupr linux-4.8_orig/net/netfilter/nf_queue.c linux-4.8/net/netfilter/nf_queue.c
+--- linux-4.8_orig/net/netfilter/nf_queue.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/netfilter/nf_queue.c 2016-10-03 07:59:56.203678268 +0700
@@ -27,6 +27,23 @@
* receives, no matter what.
*/
@@ -1595,9 +1571,9 @@ diff -Naupr linux-4.7_orig/net/netfilter/nf_queue.c linux-4.7/net/netfilter/nf_q
if (err < 0) {
if (err == -ESRCH &&
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
-diff -Naupr linux-4.7_orig/net/netfilter/xt_IMQ.c linux-4.7/net/netfilter/xt_IMQ.c
---- linux-4.7_orig/net/netfilter/xt_IMQ.c 1970-01-01 07:00:00.000000000 +0700
-+++ linux-4.7/net/netfilter/xt_IMQ.c 2016-07-26 20:58:55.649235058 +0700
+diff -Naupr linux-4.8_orig/net/netfilter/xt_IMQ.c linux-4.8/net/netfilter/xt_IMQ.c
+--- linux-4.8_orig/net/netfilter/xt_IMQ.c 1970-01-01 07:00:00.000000000 +0700
++++ linux-4.8/net/netfilter/xt_IMQ.c 2016-10-03 07:59:56.203678268 +0700
@@ -0,0 +1,72 @@
+/*
+ * This target marks packets to be enqueued to an imq device
@@ -1671,10 +1647,10 @@ diff -Naupr linux-4.7_orig/net/netfilter/xt_IMQ.c linux-4.7/net/netfilter/xt_IMQ
+MODULE_ALIAS("ipt_IMQ");
+MODULE_ALIAS("ip6t_IMQ");
+
-diff -Naupr linux-4.7_orig/net/sched/sch_generic.c linux-4.7/net/sched/sch_generic.c
---- linux-4.7_orig/net/sched/sch_generic.c 2016-07-25 02:23:50.000000000 +0700
-+++ linux-4.7/net/sched/sch_generic.c 2016-07-26 20:58:55.649235058 +0700
-@@ -110,6 +110,14 @@ static struct sk_buff *dequeue_skb(struc
+diff -Naupr linux-4.8_orig/net/sched/sch_generic.c linux-4.8/net/sched/sch_generic.c
+--- linux-4.8_orig/net/sched/sch_generic.c 2016-10-03 06:24:33.000000000 +0700
++++ linux-4.8/net/sched/sch_generic.c 2016-10-03 07:59:56.207011597 +0700
+@@ -154,6 +154,14 @@ bulk:
return skb;
}
@@ -1688,4 +1664,4 @@ diff -Naupr linux-4.7_orig/net/sched/sch_generic.c linux-4.7/net/sched/sch_gener
+
/*
* Transmit possibly several skbs, and handle the return status as
- * required. Holding the __QDISC___STATE_RUNNING bit guarantees that
+ * required. Owning running seqcount bit guarantees that
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/aa0e7109250278ddee50ff7cfd4f16643b574dd5
More information about the pld-cvs-commit
mailing list