summaryrefslogtreecommitdiffstats
path: root/backport-include/net
diff options
context:
space:
mode:
authorroot <root@artemis.panaceas.org>2015-12-25 15:00:15 +0000
committerroot <root@artemis.panaceas.org>2015-12-25 15:00:15 +0000
commitddd86436f4e3643c04b797f858dab95d5f2e4de9 (patch)
treebfe7a780cf9a2f4fc33aec32c82e625e79dece1f /backport-include/net
downloadbackports-3.10.19-1-master.tar.gz
backports-3.10.19-1-master.tar.bz2
backports-3.10.19-1-master.zip
Diffstat (limited to 'backport-include/net')
-rw-r--r--backport-include/net/codel.h363
-rw-r--r--backport-include/net/dst.h35
-rw-r--r--backport-include/net/flow_keys.h21
-rw-r--r--backport-include/net/genetlink.h101
-rw-r--r--backport-include/net/ip.h14
-rw-r--r--backport-include/net/iw_handler.h27
-rw-r--r--backport-include/net/mac80211.h8
-rw-r--r--backport-include/net/net_namespace.h63
-rw-r--r--backport-include/net/netlink.h122
-rw-r--r--backport-include/net/sch_generic.h132
-rw-r--r--backport-include/net/sock.h76
11 files changed, 962 insertions, 0 deletions
diff --git a/backport-include/net/codel.h b/backport-include/net/codel.h
new file mode 100644
index 0000000..eee0359
--- /dev/null
+++ b/backport-include/net/codel.h
@@ -0,0 +1,363 @@
+#include <linux/version.h>
+#include <linux/pkt_sched.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) || (defined(TCA_CODEL_MAX) && !defined(COMPAT_CODEL_BACKPORT))
+#include_next <net/codel.h>
+#else
+
+#ifndef __NET_SCHED_CODEL_H
+#define __NET_SCHED_CODEL_H
+
+/*
+ * Codel - The Controlled-Delay Active Queue Management algorithm
+ *
+ * Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com>
+ * Copyright (C) 2011-2012 Van Jacobson <van@pollere.net>
+ * Copyright (C) 2012 Michael D. Taht <dave.taht@bufferbloat.net>
+ * Copyright (C) 2012 Eric Dumazet <edumazet@google.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/ktime.h>
+#include <linux/skbuff.h>
+#include <net/pkt_sched.h>
+#include <net/inet_ecn.h>
+#include <linux/reciprocal_div.h>
+
+/* Controlling Queue Delay (CoDel) algorithm
+ * =========================================
+ * Source : Kathleen Nichols and Van Jacobson
+ * http://queue.acm.org/detail.cfm?id=2209336
+ *
+ * Implemented on linux by Dave Taht and Eric Dumazet
+ */
+
+
+/* CoDel uses a 1024 nsec clock, encoded in u32
+ * This gives a range of 2199 seconds, because of signed compares
+ */
+typedef u32 codel_time_t;
+typedef s32 codel_tdiff_t;
+#define CODEL_SHIFT 10
+#define MS2TIME(a) ((a * NSEC_PER_MSEC) >> CODEL_SHIFT)
+
+static inline codel_time_t codel_get_time(void)
+{
+ u64 ns = ktime_to_ns(ktime_get());
+
+ return ns >> CODEL_SHIFT;
+}
+
+#define codel_time_after(a, b) ((s32)(a) - (s32)(b) > 0)
+#define codel_time_after_eq(a, b) ((s32)(a) - (s32)(b) >= 0)
+#define codel_time_before(a, b) ((s32)(a) - (s32)(b) < 0)
+#define codel_time_before_eq(a, b) ((s32)(a) - (s32)(b) <= 0)
+
+/* Qdiscs using codel plugin must use codel_skb_cb in their own cb[] */
+struct codel_skb_cb {
+ codel_time_t enqueue_time;
+};
+
+static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb)
+{
+ qdisc_cb_private_validate(skb, sizeof(struct codel_skb_cb));
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37))
+ return (struct codel_skb_cb *)qdisc_skb_cb((struct sk_buff *) skb)->data;
+#else
+ return (struct codel_skb_cb *)qdisc_skb_cb(skb)->data;
+#endif
+}
+
+static codel_time_t codel_get_enqueue_time(const struct sk_buff *skb)
+{
+ return get_codel_cb(skb)->enqueue_time;
+}
+
+static void codel_set_enqueue_time(struct sk_buff *skb)
+{
+ get_codel_cb(skb)->enqueue_time = codel_get_time();
+}
+
+static inline u32 codel_time_to_us(codel_time_t val)
+{
+ u64 valns = ((u64)val << CODEL_SHIFT);
+
+ do_div(valns, NSEC_PER_USEC);
+ return (u32)valns;
+}
+
+/**
+ * struct codel_params - contains codel parameters
+ * @target: target queue size (in time units)
+ * @interval: width of moving time window
+ * @ecn: is Explicit Congestion Notification enabled
+ */
+struct codel_params {
+ codel_time_t target;
+ codel_time_t interval;
+ bool ecn;
+};
+
+/**
+ * struct codel_vars - contains codel variables
+ * @count: how many drops we've done since the last time we
+ * entered dropping state
+ * @lastcount: count at entry to dropping state
+ * @dropping: set to true if in dropping state
+ * @rec_inv_sqrt: reciprocal value of sqrt(count) >> 1
+ * @first_above_time: when we went (or will go) continuously above target
+ * for interval
+ * @drop_next: time to drop next packet, or when we dropped last
+ * @ldelay: sojourn time of last dequeued packet
+ */
+struct codel_vars {
+ u32 count;
+ u32 lastcount;
+ bool dropping;
+ u16 rec_inv_sqrt;
+ codel_time_t first_above_time;
+ codel_time_t drop_next;
+ codel_time_t ldelay;
+};
+
+#define REC_INV_SQRT_BITS (8 * sizeof(u16)) /* or sizeof_in_bits(rec_inv_sqrt) */
+/* needed shift to get a Q0.32 number from rec_inv_sqrt */
+#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS)
+
+/**
+ * struct codel_stats - contains codel shared variables and stats
+ * @maxpacket: largest packet we've seen so far
+ * @drop_count: temp count of dropped packets in dequeue()
+ * ecn_mark: number of packets we ECN marked instead of dropping
+ */
+struct codel_stats {
+ u32 maxpacket;
+ u32 drop_count;
+ u32 ecn_mark;
+};
+
+static void codel_params_init(struct codel_params *params)
+{
+ params->interval = MS2TIME(100);
+ params->target = MS2TIME(5);
+ params->ecn = false;
+}
+
+static void codel_vars_init(struct codel_vars *vars)
+{
+ memset(vars, 0, sizeof(*vars));
+}
+
+static void codel_stats_init(struct codel_stats *stats)
+{
+ stats->maxpacket = 256;
+}
+
+/*
+ * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots
+ * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2)
+ *
+ * Here, invsqrt is a fixed point number (< 1.0), 32bit mantissa, aka Q0.32
+ */
+static void codel_Newton_step(struct codel_vars *vars)
+{
+ u32 invsqrt = ((u32)vars->rec_inv_sqrt) << REC_INV_SQRT_SHIFT;
+ u32 invsqrt2 = ((u64)invsqrt * invsqrt) >> 32;
+ u64 val = (3LL << 32) - ((u64)vars->count * invsqrt2);
+
+ val >>= 2; /* avoid overflow in following multiply */
+ val = (val * invsqrt) >> (32 - 2 + 1);
+
+ vars->rec_inv_sqrt = val >> REC_INV_SQRT_SHIFT;
+}
+
+/*
+ * CoDel control_law is t + interval/sqrt(count)
+ * We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid
+ * both sqrt() and divide operation.
+ */
+static codel_time_t codel_control_law(codel_time_t t,
+ codel_time_t interval,
+ u32 rec_inv_sqrt)
+{
+ return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
+}
+
+
+static bool codel_should_drop(const struct sk_buff *skb,
+ struct Qdisc *sch,
+ struct codel_vars *vars,
+ struct codel_params *params,
+ struct codel_stats *stats,
+ codel_time_t now)
+{
+ bool ok_to_drop;
+
+ if (!skb) {
+ vars->first_above_time = 0;
+ return false;
+ }
+
+ vars->ldelay = now - codel_get_enqueue_time(skb);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37))
+ sch->qstats.backlog -= qdisc_pkt_len((struct sk_buff *)skb);
+#else
+ sch->qstats.backlog -= qdisc_pkt_len(skb);
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37))
+ if (unlikely(qdisc_pkt_len((struct sk_buff *)skb) > stats->maxpacket))
+ stats->maxpacket = qdisc_pkt_len((struct sk_buff *)skb);
+#else
+ if (unlikely(qdisc_pkt_len(skb) > stats->maxpacket))
+ stats->maxpacket = qdisc_pkt_len(skb);
+#endif
+
+ if (codel_time_before(vars->ldelay, params->target) ||
+ sch->qstats.backlog <= stats->maxpacket) {
+ /* went below - stay below for at least interval */
+ vars->first_above_time = 0;
+ return false;
+ }
+ ok_to_drop = false;
+ if (vars->first_above_time == 0) {
+ /* just went above from below. If we stay above
+ * for at least interval we'll say it's ok to drop
+ */
+ vars->first_above_time = now + params->interval;
+ } else if (codel_time_after(now, vars->first_above_time)) {
+ ok_to_drop = true;
+ }
+ return ok_to_drop;
+}
+
+typedef struct sk_buff * (*codel_skb_dequeue_t)(struct codel_vars *vars,
+ struct Qdisc *sch);
+
+static struct sk_buff *codel_dequeue(struct Qdisc *sch,
+ struct codel_params *params,
+ struct codel_vars *vars,
+ struct codel_stats *stats,
+ codel_skb_dequeue_t dequeue_func)
+{
+ struct sk_buff *skb = dequeue_func(vars, sch);
+ codel_time_t now;
+ bool drop;
+
+ if (!skb) {
+ vars->dropping = false;
+ return skb;
+ }
+ now = codel_get_time();
+ drop = codel_should_drop(skb, sch, vars, params, stats, now);
+ if (vars->dropping) {
+ if (!drop) {
+ /* sojourn time below target - leave dropping state */
+ vars->dropping = false;
+ } else if (codel_time_after_eq(now, vars->drop_next)) {
+ /* It's time for the next drop. Drop the current
+ * packet and dequeue the next. The dequeue might
+ * take us out of dropping state.
+ * If not, schedule the next drop.
+ * A large backlog might result in drop rates so high
+ * that the next drop should happen now,
+ * hence the while loop.
+ */
+ while (vars->dropping &&
+ codel_time_after_eq(now, vars->drop_next)) {
+ vars->count++; /* dont care of possible wrap
+ * since there is no more divide
+ */
+ codel_Newton_step(vars);
+ if (params->ecn && INET_ECN_set_ce(skb)) {
+ stats->ecn_mark++;
+ vars->drop_next =
+ codel_control_law(vars->drop_next,
+ params->interval,
+ vars->rec_inv_sqrt);
+ goto end;
+ }
+ qdisc_drop(skb, sch);
+ stats->drop_count++;
+ skb = dequeue_func(vars, sch);
+ if (!codel_should_drop(skb, sch,
+ vars, params, stats, now)) {
+ /* leave dropping state */
+ vars->dropping = false;
+ } else {
+ /* and schedule the next drop */
+ vars->drop_next =
+ codel_control_law(vars->drop_next,
+ params->interval,
+ vars->rec_inv_sqrt);
+ }
+ }
+ }
+ } else if (drop) {
+ if (params->ecn && INET_ECN_set_ce(skb)) {
+ stats->ecn_mark++;
+ } else {
+ qdisc_drop(skb, sch);
+ stats->drop_count++;
+
+ skb = dequeue_func(vars, sch);
+ drop = codel_should_drop(skb, sch, vars, params,
+ stats, now);
+ }
+ vars->dropping = true;
+ /* if min went above target close to when we last went below it
+ * assume that the drop rate that controlled the queue on the
+ * last cycle is a good starting point to control it now.
+ */
+ if (codel_time_before(now - vars->drop_next,
+ 16 * params->interval)) {
+ vars->count = (vars->count - vars->lastcount) | 1;
+ /* we dont care if rec_inv_sqrt approximation
+ * is not very precise :
+ * Next Newton steps will correct it quadratically.
+ */
+ codel_Newton_step(vars);
+ } else {
+ vars->count = 1;
+ vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT;
+ }
+ vars->lastcount = vars->count;
+ vars->drop_next = codel_control_law(now, params->interval,
+ vars->rec_inv_sqrt);
+ }
+end:
+ return skb;
+}
+#endif
+#endif
diff --git a/backport-include/net/dst.h b/backport-include/net/dst.h
new file mode 100644
index 0000000..e4e3d8f
--- /dev/null
+++ b/backport-include/net/dst.h
@@ -0,0 +1,35 @@
+#ifndef __BACKPORT_NET_DST_H
+#define __BACKPORT_NET_DST_H
+#include_next <net/dst.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+/*
+ * Added via adf30907d63893e4208dfe3f5c88ae12bc2f25d5
+ *
+ * There is no _sk_dst on older kernels, so just set the
+ * old dst to NULL and release it directly.
+ */
+static inline void skb_dst_drop(struct sk_buff *skb)
+{
+ dst_release(skb->dst);
+ skb->dst = NULL;
+}
+
+static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
+{
+ return (struct dst_entry *)skb->dst;
+}
+
+static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
+{
+ skb->dst = dst;
+}
+
+static inline struct rtable *skb_rtable(const struct sk_buff *skb)
+{
+ return (struct rtable *)skb_dst(skb);
+}
+#endif
+
+#endif /* __BACKPORT_NET_DST_H */
diff --git a/backport-include/net/flow_keys.h b/backport-include/net/flow_keys.h
new file mode 100644
index 0000000..a875ee6
--- /dev/null
+++ b/backport-include/net/flow_keys.h
@@ -0,0 +1,21 @@
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
+#include_next <net/flow_keys.h>
+#else
+
+#ifndef _NET_FLOW_KEYS_H
+#define _NET_FLOW_KEYS_H
+
+struct flow_keys {
+ /* (src,dst) must be grouped, in the same way than in IP header */
+ __be32 src;
+ __be32 dst;
+ union {
+ __be32 ports;
+ __be16 port16[2];
+ };
+ u8 ip_proto;
+};
+
+extern bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
+#endif
+#endif
diff --git a/backport-include/net/genetlink.h b/backport-include/net/genetlink.h
new file mode 100644
index 0000000..4458a10
--- /dev/null
+++ b/backport-include/net/genetlink.h
@@ -0,0 +1,101 @@
+#ifndef __BACKPORT_NET_GENETLINK_H
+#define __BACKPORT_NET_GENETLINK_H
+#include_next <net/genetlink.h>
+
+/* this is for patches we apply */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+#define genl_info_snd_portid(__genl_info) (__genl_info->snd_pid)
+#else
+#define genl_info_snd_portid(__genl_info) (__genl_info->snd_portid)
+#endif
+
+#ifndef GENLMSG_DEFAULT_SIZE
+#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
+#define genl_dump_check_consistent(cb, user_hdr, family)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+struct compat_genl_info {
+ struct genl_info *info;
+
+ u32 snd_seq;
+ u32 snd_pid;
+ struct genlmsghdr *genlhdr;
+ struct nlattr **attrs;
+ void *user_ptr[2];
+};
+#define genl_info compat_genl_info
+
+struct compat_genl_ops {
+ struct genl_ops ops;
+
+ u8 cmd;
+ u8 internal_flags;
+ unsigned int flags;
+ const struct nla_policy *policy;
+
+ int (*doit)(struct sk_buff *skb, struct genl_info *info);
+ int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
+ int (*done)(struct netlink_callback *cb);
+};
+#define genl_ops compat_genl_ops
+
+struct compat_genl_family {
+ struct genl_family family;
+
+ struct list_head list;
+
+ unsigned int id, hdrsize, version, maxattr;
+ const char *name;
+ bool netnsok;
+
+ struct nlattr **attrbuf;
+
+ int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+
+ void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+};
+
+#define genl_family compat_genl_family
+
+#define genl_register_family_with_ops compat_genl_register_family_with_ops
+
+int genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops);
+
+#define genl_unregister_family compat_genl_unregister_family
+
+int genl_unregister_family(struct genl_family *family);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
+#define genl_info_net(_info) genl_info_net((_info)->info)
+#endif
+
+#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info)
+#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd)
+#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp)
+#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp)
+#endif /* < 2.6.37 */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+/*
+ * struct genl_multicast_group was made netns aware through
+ * patch "genetlink: make netns aware" by johannes, we just
+ * force this to always use the default init_net
+ */
+#define genl_info_net(x) &init_net
+/* Just use init_net for older kernels */
+#define get_net_ns_by_pid(x) &init_net
+
+/* net namespace is lost */
+#define genlmsg_multicast_netns(a, b, c, d, e) genlmsg_multicast(b, c, d, e)
+#define genlmsg_multicast_allns(a, b, c, d) genlmsg_multicast(a, b, c, d)
+#define genlmsg_unicast(net, skb, pid) genlmsg_unicast(skb, pid)
+#endif
+
+#endif /* __BACKPORT_NET_GENETLINK_H */
diff --git a/backport-include/net/ip.h b/backport-include/net/ip.h
new file mode 100644
index 0000000..909e603
--- /dev/null
+++ b/backport-include/net/ip.h
@@ -0,0 +1,14 @@
+#ifndef __BACKPORT_NET_IP_H
+#define __BACKPORT_NET_IP_H
+#include_next <net/ip.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
+/* Backports 56f8a75c */
+static inline bool ip_is_fragment(const struct iphdr *iph)
+{
+ return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
+}
+#endif
+
+#endif /* __BACKPORT_NET_IP_H */
diff --git a/backport-include/net/iw_handler.h b/backport-include/net/iw_handler.h
new file mode 100644
index 0000000..c418d7d
--- /dev/null
+++ b/backport-include/net/iw_handler.h
@@ -0,0 +1,27 @@
+#ifndef __BACKPORT_NET_IW_HANDLER_H
+#define __BACKPORT_NET_IW_HANDLER_H
+#include_next <net/iw_handler.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+#define wireless_send_event(a, b, c, d) wireless_send_event(a, b, c, (char * ) d)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#define iwe_stream_add_value(info, event, value, ends, iwe, event_len) iwe_stream_add_value(event, value, ends, iwe, event_len)
+#define iwe_stream_add_point(info, stream, ends, iwe, extra) iwe_stream_add_point(stream, ends, iwe, extra)
+#define iwe_stream_add_event(info, stream, ends, iwe, event_len) iwe_stream_add_event(stream, ends, iwe, event_len)
+
+#define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */
+
+static inline int iwe_stream_lcp_len(struct iw_request_info *info)
+{
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ return IW_EV_COMPAT_LCP_LEN;
+#endif
+ return IW_EV_LCP_LEN;
+}
+#endif
+
+#endif /* __BACKPORT_NET_IW_HANDLER_H */
diff --git a/backport-include/net/mac80211.h b/backport-include/net/mac80211.h
new file mode 100644
index 0000000..c31b462
--- /dev/null
+++ b/backport-include/net/mac80211.h
@@ -0,0 +1,8 @@
+#ifndef __BACKPORT_NET_MAC80211_H
+#define __BACKPORT_NET_MAC80211_H
+
+/* on some kernels, libipw also uses this, so override */
+#define ieee80211_rx mac80211_ieee80211_rx
+#include_next <net/mac80211.h>
+
+#endif /* __BACKPORT_NET_MAC80211_H */
diff --git a/backport-include/net/net_namespace.h b/backport-include/net/net_namespace.h
new file mode 100644
index 0000000..f23702f
--- /dev/null
+++ b/backport-include/net/net_namespace.h
@@ -0,0 +1,63 @@
+#ifndef _COMPAT_NET_NET_NAMESPACE_H
+#define _COMPAT_NET_NET_NAMESPACE_H 1
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23))
+#include_next <net/net_namespace.h>
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#ifdef CONFIG_NET_NS
+static inline void write_pnet(struct net **pnet, struct net *net)
+{
+ *pnet = net;
+}
+
+static inline struct net *read_pnet(struct net * const *pnet)
+{
+ return *pnet;
+}
+
+#else
+#define write_pnet(pnet, net) do { (void)(net);} while (0)
+#define read_pnet(pnet) (&init_net)
+#endif
+#endif /* < 2.6.29 */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+#ifdef CONFIG_NET_NS
+static inline
+int net_eq(const struct net *net1, const struct net *net2)
+{
+ return net1 == net2;
+}
+#else
+static inline
+int net_eq(const struct net *net1, const struct net *net2)
+{
+ return 1;
+}
+#endif
+
+static inline
+void dev_net_set(struct net_device *dev, struct net *net)
+{
+#ifdef CONFIG_NET_NS
+ release_net(dev->nd_net);
+ dev->nd_net = hold_net(net);
+#endif
+}
+
+static inline
+struct net *sock_net(const struct sock *sk)
+{
+#ifdef CONFIG_NET_NS
+ return sk->sk_net;
+#else
+ return &init_net;
+#endif
+}
+#endif /* < 2.6.26 */
+
+#endif /* _COMPAT_NET_NET_NAMESPACE_H */
diff --git a/backport-include/net/netlink.h b/backport-include/net/netlink.h
new file mode 100644
index 0000000..39e0149
--- /dev/null
+++ b/backport-include/net/netlink.h
@@ -0,0 +1,122 @@
+#ifndef __BACKPORT_NET_NETLINK_H
+#define __BACKPORT_NET_NETLINK_H
+#include_next <net/netlink.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+/**
+ * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
+{
+ return nla_put(skb, attrtype, sizeof(s8), &value);
+}
+
+/**
+ * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
+{
+ return nla_put(skb, attrtype, sizeof(s16), &value);
+}
+
+/**
+ * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
+{
+ return nla_put(skb, attrtype, sizeof(s32), &value);
+}
+
+/**
+ * nla_put_s64 - Add a s64 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value)
+{
+ return nla_put(skb, attrtype, sizeof(s64), &value);
+}
+
+/**
+ * nla_get_s32 - return payload of s32 attribute
+ * @nla: s32 netlink attribute
+ */
+static inline s32 nla_get_s32(const struct nlattr *nla)
+{
+ return *(s32 *) nla_data(nla);
+}
+
+/**
+ * nla_get_s16 - return payload of s16 attribute
+ * @nla: s16 netlink attribute
+ */
+static inline s16 nla_get_s16(const struct nlattr *nla)
+{
+ return *(s16 *) nla_data(nla);
+}
+
+/**
+ * nla_get_s8 - return payload of s8 attribute
+ * @nla: s8 netlink attribute
+ */
+static inline s8 nla_get_s8(const struct nlattr *nla)
+{
+ return *(s8 *) nla_data(nla);
+}
+
+/**
+ * nla_get_s64 - return payload of s64 attribute
+ * @nla: s64 netlink attribute
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+static inline s64 nla_get_s64(const struct nlattr *nla)
+#else
+static inline s64 nla_get_s64(struct nlattr *nla)
+#endif
+{
+ s64 tmp;
+
+ nla_memcpy(&tmp, nla, sizeof(tmp));
+
+ return tmp;
+}
+#endif /* < 3.7.0 */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0))
+/*
+ * This backports:
+ * commit 569a8fc38367dfafd87454f27ac646c8e6b54bca
+ * Author: David S. Miller <davem@davemloft.net>
+ * Date: Thu Mar 29 23:18:53 2012 -0400
+ *
+ * netlink: Add nla_put_be{16,32,64}() helpers.
+ */
+
+static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be16), &value);
+}
+
+static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be32), &value);
+}
+
+static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be64), &value);
+}
+#endif /* < 3.5 */
+
+#endif /* __BACKPORT_NET_NETLINK_H */
diff --git a/backport-include/net/sch_generic.h b/backport-include/net/sch_generic.h
new file mode 100644
index 0000000..04997c7
--- /dev/null
+++ b/backport-include/net/sch_generic.h
@@ -0,0 +1,132 @@
+#ifndef __BACKPORT_NET_SCH_GENERIC_H
+#define __BACKPORT_NET_SCH_GENERIC_H
+#include_next <net/sch_generic.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
+#if !((LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,9) && LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,23) && LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)))
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)
+/* mask qdisc_cb_private_validate as RHEL6 backports this */
+#define qdisc_cb_private_validate(a,b) compat_qdisc_cb_private_validate(a,b)
+static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
+{
+ BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct qdisc_skb_cb) + sz);
+}
+#else
+/* mask qdisc_cb_private_validate as RHEL6 backports this */
+#define qdisc_cb_private_validate(a,b) compat_qdisc_cb_private_validate(a,b)
+static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
+{
+ /* XXX ? */
+}
+#endif
+#endif
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
+{
+ return qdisc->dev;
+}
+
+/*
+ * Backports 378a2f09 and c27f339a
+ * This may need a bit more work.
+ */
+enum net_xmit_qdisc_t {
+ __NET_XMIT_STOLEN = 0x00010000,
+ __NET_XMIT_BYPASS = 0x00020000,
+};
+
+struct qdisc_skb_cb {
+ unsigned int pkt_len;
+ char data[];
+};
+
+static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb)
+{
+ return (struct qdisc_skb_cb *)skb->cb;
+}
+
+static inline unsigned int qdisc_pkt_len(struct sk_buff *skb)
+{
+ return qdisc_skb_cb(skb)->pkt_len;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+static inline void bstats_update(struct gnet_stats_basic_packed *bstats,
+ const struct sk_buff *skb)
+{
+ bstats->bytes += qdisc_pkt_len((struct sk_buff *) skb);
+ bstats->packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+}
+static inline void qdisc_bstats_update(struct Qdisc *sch,
+ const struct sk_buff *skb)
+{
+ bstats_update(&sch->bstats, skb);
+}
+#else
+/*
+ * kernels <= 2.6.30 do not pass a const skb to qdisc_pkt_len, and
+ * gnet_stats_basic_packed did not exist (see c1a8f1f1c8)
+ */
+static inline void bstats_update(struct gnet_stats_basic *bstats,
+ struct sk_buff *skb)
+{
+ bstats->bytes += qdisc_pkt_len(skb);
+ bstats->packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+}
+static inline void qdisc_bstats_update(struct Qdisc *sch,
+ struct sk_buff *skb)
+{
+ bstats_update(&sch->bstats, skb);
+}
+#endif
+#endif /* < 2.6.38 */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+
+#define qdisc_reset_all_tx_gt LINUX_BACKPORT(qdisc_reset_all_tx_gt)
+
+/* Reset all TX qdiscs greater then index of a device. */
+static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
+{
+ struct Qdisc *qdisc;
+
+ for (; i < dev->num_tx_queues; i++) {
+ qdisc = netdev_get_tx_queue(dev, i)->qdisc;
+ if (qdisc) {
+ spin_lock_bh(qdisc_lock(qdisc));
+ qdisc_reset(qdisc);
+ spin_unlock_bh(qdisc_lock(qdisc));
+ }
+ }
+}
+#else
+static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
+{
+}
+#endif /* >= 2.6.27 */
+#endif /* < 2.6.35 */
+
+#ifndef TCQ_F_CAN_BYPASS
+#define TCQ_F_CAN_BYPASS 4
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+static inline int qdisc_qlen(const struct Qdisc *q)
+{
+ return q->q.qlen;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+static inline bool qdisc_all_tx_empty(const struct net_device *dev)
+{
+ return skb_queue_empty(&dev->qdisc->q);
+}
+#endif
+
+#endif /* __BACKPORT_NET_SCH_GENERIC_H */
diff --git a/backport-include/net/sock.h b/backport-include/net/sock.h
new file mode 100644
index 0000000..b4f3e6a
--- /dev/null
+++ b/backport-include/net/sock.h
@@ -0,0 +1,76 @@
+#ifndef __BACKPORT_NET_SOCK_H
+#define __BACKPORT_NET_SOCK_H
+#include_next <net/sock.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
+#include <backport/magic.h>
+
+#define sk_for_each3(__sk, node, list) \
+ hlist_for_each_entry(__sk, node, list, sk_node)
+
+#define sk_for_each_safe4(__sk, node, tmp, list) \
+ hlist_for_each_entry_safe(__sk, node, tmp, list, sk_node)
+
+#define sk_for_each2(__sk, list) \
+ hlist_for_each_entry(__sk, list, sk_node)
+
+#define sk_for_each_safe3(__sk, tmp, list) \
+ hlist_for_each_entry_safe(__sk, tmp, list, sk_node)
+
+#undef sk_for_each
+#define sk_for_each(...) \
+ macro_dispatcher(sk_for_each, __VA_ARGS__)(__VA_ARGS__)
+#undef sk_for_each_safe
+#define sk_for_each_safe(...) \
+ macro_dispatcher(sk_for_each_safe, __VA_ARGS__)(__VA_ARGS__)
+
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+/*
+ * backport SOCK_SELECT_ERR_QUEUE -- see commit
+ * "net: add option to enable error queue packets waking select"
+ *
+ * Adding 14 to SOCK_QUEUE_SHRUNK will reach a bet that can't be
+ * set on older kernels, so sock_flag() will always return false.
+ */
+#define SOCK_SELECT_ERR_QUEUE (SOCK_QUEUE_SHRUNK + 14)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+static inline wait_queue_head_t *sk_sleep(struct sock *sk)
+{
+ return sk->sk_sleep;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
+static inline struct sock *sk_entry(const struct hlist_node *node)
+{
+ return hlist_entry(node, struct sock, sk_node);
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+#define sock_recv_ts_and_drops(msg, sk, skb) sock_recv_timestamp(msg, sk, skb)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+static inline int sk_rmem_alloc_get(const struct sock *sk)
+{
+ return atomic_read(&sk->sk_rmem_alloc);
+}
+
+static inline int sk_wmem_alloc_get(const struct sock *sk)
+{
+ return atomic_read(&sk->sk_wmem_alloc) - 1;
+}
+
+static inline bool sk_has_allocations(const struct sock *sk)
+{
+ return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk);
+}
+#endif
+
+#endif /* __BACKPORT_NET_SOCK_H */