summaryrefslogtreecommitdiff
path: root/backport-include/net
diff options
context:
space:
mode:
Diffstat (limited to 'backport-include/net')
-rw-r--r--backport-include/net/addrconf.h25
-rw-r--r--backport-include/net/flow_keys.h21
-rw-r--r--backport-include/net/genetlink.h205
-rw-r--r--backport-include/net/inet_frag.h76
-rw-r--r--backport-include/net/ip.h14
-rw-r--r--backport-include/net/ip6_fib.h26
-rw-r--r--backport-include/net/ipv6.h60
-rw-r--r--backport-include/net/iw_handler.h40
-rw-r--r--backport-include/net/net_namespace.h44
-rw-r--r--backport-include/net/netlink.h360
-rw-r--r--backport-include/net/sch_generic.h20
-rw-r--r--backport-include/net/sock.h66
-rw-r--r--backport-include/net/tso.h33
13 files changed, 990 insertions, 0 deletions
diff --git a/backport-include/net/addrconf.h b/backport-include/net/addrconf.h
new file mode 100644
index 0000000..f1e8e62
--- /dev/null
+++ b/backport-include/net/addrconf.h
@@ -0,0 +1,25 @@
+#ifndef _BACKPORT_NET_ADDRCONF_H
+#define _BACKPORT_NET_ADDRCONF_H 1
+
+#include_next <net/addrconf.h>
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_IS_LESS(3,9,0)
+static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+ __u64 *p = (__u64 *)addr;
+ return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
+ ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
+ cpu_to_be64(0xffffffffff000000UL))) == 0UL;
+#else
+ return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+ addr->s6_addr32[1] |
+ (addr->s6_addr32[2] ^ htonl(0x00000001)) |
+ (addr->s6_addr[12] ^ 0xff)) == 0;
+#endif
+}
+#endif /* LINUX_VERSION_IS_LESS(3,9,0) */
+
+#endif /* _BACKPORT_NET_ADDRCONF_H */
diff --git a/backport-include/net/flow_keys.h b/backport-include/net/flow_keys.h
new file mode 100644
index 0000000..093bc80
--- /dev/null
+++ b/backport-include/net/flow_keys.h
@@ -0,0 +1,21 @@
+#if LINUX_VERSION_IS_GEQ(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..b655d24
--- /dev/null
+++ b/backport-include/net/genetlink.h
@@ -0,0 +1,205 @@
+#ifndef __BACKPORT_NET_GENETLINK_H
+#define __BACKPORT_NET_GENETLINK_H
+#include_next <net/genetlink.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_IS_LESS(4,12,0)
+#define GENL_SET_ERR_MSG(info, msg) do { } while (0)
+
+static inline int genl_err_attr(struct genl_info *info, int err,
+ struct nlattr *attr)
+{
+#if LINUX_VERSION_IS_GEQ(4,12,0)
+ info->extack->bad_attr = attr;
+#endif
+
+ return err;
+}
+#endif
+
+/* this is for patches we apply */
+static inline struct netlink_ext_ack *genl_info_extack(struct genl_info *info)
+{
+#if LINUX_VERSION_IS_GEQ(4,12,0)
+ return info->extack;
+#else
+ return NULL;
+#endif
+}
+
+/* this is for patches we apply */
+#if LINUX_VERSION_IS_LESS(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_IS_LESS(3,1,0)
+#define genl_dump_check_consistent(cb, user_hdr, family)
+#endif
+
+#if LINUX_VERSION_IS_LESS(3,13,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
+static inline int __real_genl_register_family(struct genl_family *family)
+{
+ return genl_register_family(family);
+}
+
+/* Needed for the mcgrps pointer */
+struct backport_genl_family {
+ struct genl_family family;
+
+ unsigned int id, hdrsize, version, maxattr;
+ char name[GENL_NAMSIZ];
+ bool netnsok;
+ bool parallel_ops;
+
+ 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);
+
+ struct genl_multicast_group *mcgrps;
+ struct genl_ops *ops;
+ unsigned int n_mcgrps, n_ops;
+
+ struct module *module;
+};
+#define genl_family LINUX_BACKPORT(genl_family)
+
+int __backport_genl_register_family(struct genl_family *family);
+
+#define genl_register_family LINUX_BACKPORT(genl_register_family)
+static inline int
+genl_register_family(struct genl_family *family)
+{
+ family->module = THIS_MODULE;
+ return __backport_genl_register_family(family);
+}
+
+#define _genl_register_family_with_ops_grps \
+ _backport_genl_register_family_with_ops_grps
+static inline int
+_genl_register_family_with_ops_grps(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops,
+ struct genl_multicast_group *mcgrps,
+ size_t n_mcgrps)
+{
+ family->ops = ops;
+ family->n_ops = n_ops;
+ family->mcgrps = mcgrps;
+ family->n_mcgrps = n_mcgrps;
+ return genl_register_family(family);
+}
+
+#define genl_register_family_with_ops(family, ops) \
+ _genl_register_family_with_ops_grps((family), \
+ (ops), ARRAY_SIZE(ops), \
+ NULL, 0)
+#define genl_register_family_with_ops_groups(family, ops, grps) \
+ _genl_register_family_with_ops_grps((family), \
+ (ops), ARRAY_SIZE(ops), \
+ (grps), ARRAY_SIZE(grps))
+
+#define genl_unregister_family backport_genl_unregister_family
+int genl_unregister_family(struct genl_family *family);
+
+#if LINUX_VERSION_IS_LESS(3,3,0)
+extern void genl_notify(struct sk_buff *skb, struct net *net, u32 pid,
+ u32 group, struct nlmsghdr *nlh, gfp_t flags);
+#endif
+#define genl_notify(_fam, _skb, _info, _group, _flags) \
+ genl_notify(_skb, genl_info_net(_info), \
+ genl_info_snd_portid(_info), \
+ (_fam)->mcgrps[_group].id, _info->nlhdr, _flags)
+#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) \
+ genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd)
+#define genlmsg_nlhdr(_hdr, _fam) \
+ genlmsg_nlhdr(_hdr, &(_fam)->family)
+#ifndef genl_dump_check_consistent
+#define genl_dump_check_consistent(_cb, _hdr, _fam) \
+ genl_dump_check_consistent(_cb, _hdr, &(_fam)->family)
+#endif
+#ifndef genlmsg_put_reply /* might already be there from _info override above */
+#define genlmsg_put_reply(_skb, _info, _fam, _flags, _cmd) \
+ genlmsg_put_reply(_skb, _info, &(_fam)->family, _flags, _cmd)
+#endif
+#define genlmsg_multicast_netns LINUX_BACKPORT(genlmsg_multicast_netns)
+static inline int genlmsg_multicast_netns(struct genl_family *family,
+ struct net *net, struct sk_buff *skb,
+ u32 portid, unsigned int group,
+ gfp_t flags)
+{
+ if (WARN_ON_ONCE(group >= family->n_mcgrps))
+ return -EINVAL;
+ group = family->mcgrps[group].id;
+ return nlmsg_multicast(
+ net->genl_sock,
+ skb, portid, group, flags);
+}
+#define genlmsg_multicast LINUX_BACKPORT(genlmsg_multicast)
+static inline int genlmsg_multicast(struct genl_family *family,
+ struct sk_buff *skb, u32 portid,
+ unsigned int group, gfp_t flags)
+{
+ if (WARN_ON_ONCE(group >= family->n_mcgrps))
+ return -EINVAL;
+ group = family->mcgrps[group].id;
+ return nlmsg_multicast(
+ init_net.genl_sock,
+ skb, portid, group, flags);
+}
+static inline int
+backport_genlmsg_multicast_allns(struct genl_family *family,
+ struct sk_buff *skb, u32 portid,
+ unsigned int group, gfp_t flags)
+{
+ if (WARN_ON_ONCE(group >= family->n_mcgrps))
+ return -EINVAL;
+ group = family->mcgrps[group].id;
+ return genlmsg_multicast_allns(skb, portid, group, flags);
+}
+#define genlmsg_multicast_allns LINUX_BACKPORT(genlmsg_multicast_allns)
+
+#define __genl_const
+#else /* < 3.13 */
+#define __genl_const const
+#if LINUX_VERSION_IS_LESS(4,4,0)
+#define genl_notify(_fam, _skb, _info, _group, _flags) \
+ genl_notify(_fam, _skb, genl_info_net(_info), \
+ genl_info_snd_portid(_info), \
+ _group, _info->nlhdr, _flags)
+#endif /* < 4.4 */
+#endif /* < 3.13 */
+
+#if LINUX_VERSION_IS_LESS(4,10,0)
+/**
+ * genl_family_attrbuf - return family's attrbuf
+ * @family: the family
+ *
+ * Return the family's attrbuf, while validating that it's
+ * actually valid to access it.
+ *
+ * You cannot use this function with a family that has parallel_ops
+ * and you can only use it within (pre/post) doit/dumpit callbacks.
+ */
+#define genl_family_attrbuf LINUX_BACKPORT(genl_family_attrbuf)
+static inline struct nlattr **genl_family_attrbuf(struct genl_family *family)
+{
+ WARN_ON(family->parallel_ops);
+
+ return family->attrbuf;
+}
+
+#define __genl_ro_after_init
+#else
+#define __genl_ro_after_init __ro_after_init
+#endif
+
+#endif /* __BACKPORT_NET_GENETLINK_H */
diff --git a/backport-include/net/inet_frag.h b/backport-include/net/inet_frag.h
new file mode 100644
index 0000000..e95eac3
--- /dev/null
+++ b/backport-include/net/inet_frag.h
@@ -0,0 +1,76 @@
+#ifndef __BACKPORT__NET_FRAG_H__
+#define __BACKPORT__NET_FRAG_H__
+#include_next <net/inet_frag.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_IS_LESS(3,9,0)
+/* Memory Tracking Functions. */
+#define frag_mem_limit LINUX_BACKPORT(frag_mem_limit)
+static inline int frag_mem_limit(struct netns_frags *nf)
+{
+ return atomic_read(&nf->mem);
+}
+
+#define init_frag_mem_limit LINUX_BACKPORT(init_frag_mem_limit)
+static inline void init_frag_mem_limit(struct netns_frags *nf)
+{
+ atomic_set(&nf->mem, 0);
+}
+
+#define sum_frag_mem_limit LINUX_BACKPORT(sum_frag_mem_limit)
+static inline int sum_frag_mem_limit(struct netns_frags *nf)
+{
+ return atomic_read(&nf->mem);
+}
+
+#define inet_frag_maybe_warn_overflow LINUX_BACKPORT(inet_frag_maybe_warn_overflow)
+void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
+ const char *prefix);
+#endif /* LINUX_VERSION_IS_LESS(3,9,0) */
+
+/* the type of the paramater changed with kernel 4.3 */
+#if LINUX_VERSION_IS_LESS(3,9,0)
+#define sub_frag_mem_limit LINUX_BACKPORT(sub_frag_mem_limit)
+static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)
+{
+ atomic_sub(i, &nf->mem);
+}
+
+#define add_frag_mem_limit LINUX_BACKPORT(add_frag_mem_limit)
+static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
+{
+ atomic_add(i, &nf->mem);
+}
+#elif LINUX_VERSION_IS_LESS(4,3,0)
+#define sub_frag_mem_limit LINUX_BACKPORT(sub_frag_mem_limit)
+static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)
+{
+ __percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch);
+}
+
+#define add_frag_mem_limit LINUX_BACKPORT(add_frag_mem_limit)
+static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
+{
+ __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch);
+}
+#endif /* LINUX_VERSION_IS_LESS(4,3,0) */
+
+#if LINUX_VERSION_IS_LESS(4,4,0) && \
+ LINUX_VERSION_IS_GEQ(3,9,0)
+#define inet_frags_uninit_net LINUX_BACKPORT(inet_frags_uninit_net)
+static inline void inet_frags_uninit_net(struct netns_frags *nf)
+{
+ percpu_counter_destroy(&nf->mem);
+}
+#endif /* < 4.4 && >= 3.9 */
+
+#if LINUX_VERSION_IS_LESS(4,4,0)
+static inline int backport_inet_frags_init_net(struct netns_frags *nf)
+{
+ inet_frags_init_net(nf);
+ return 0;
+}
+#define inet_frags_init_net LINUX_BACKPORT(inet_frags_init_net)
+#endif /* < 4.4 */
+
+#endif /* __BACKPORT__NET_FRAG_H__ */
diff --git a/backport-include/net/ip.h b/backport-include/net/ip.h
new file mode 100644
index 0000000..6893ba5
--- /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_IS_LESS(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/ip6_fib.h b/backport-include/net/ip6_fib.h
new file mode 100644
index 0000000..2f21163
--- /dev/null
+++ b/backport-include/net/ip6_fib.h
@@ -0,0 +1,26 @@
+#ifndef __BACKPORT_NET_IP6_ROUTE_H
+#define __BACKPORT_NET_IP6_ROUTE_H
+#include_next <net/ip6_fib.h>
+#include <net/ip6_route.h>
+#include <linux/route.h>
+#include <linux/version.h>
+
+/*
+ * This function is avaliable with one argument since kernel 3.10, but the
+ * secound one was added in 4.2.
+ */
+#if LINUX_VERSION_IS_LESS(4,2,0)
+#define rt6_nexthop LINUX_BACKPORT(rt6_nexthop)
+static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
+ struct in6_addr *daddr)
+{
+ if (rt->rt6i_flags & RTF_GATEWAY)
+ return &rt->rt6i_gateway;
+ else if (rt->rt6i_flags & RTF_CACHE)
+ return &rt->rt6i_dst.addr;
+ else
+ return daddr;
+}
+#endif /* LINUX_VERSION_IS_LESS(4,2,0) */
+
+#endif /* __BACKPORT_NET_IP6_ROUTE_H */
diff --git a/backport-include/net/ipv6.h b/backport-include/net/ipv6.h
new file mode 100644
index 0000000..7416d6b
--- /dev/null
+++ b/backport-include/net/ipv6.h
@@ -0,0 +1,60 @@
+#ifndef __BACKPORT_NET_IPV6_H
+#define __BACKPORT_NET_IPV6_H
+#include_next <net/ipv6.h>
+#include <linux/version.h>
+#include <net/addrconf.h>
+#include <net/inet_frag.h>
+
+#if LINUX_VERSION_IS_LESS(3,7,0)
+/*
+ * Equivalent of ipv4 struct ip
+ */
+struct frag_queue {
+ struct inet_frag_queue q;
+
+ __be32 id; /* fragment id */
+ u32 user;
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+
+ int iif;
+ unsigned int csum;
+ __u16 nhoffset;
+};
+#endif /* LINUX_VERSION_IS_LESS(3,7,0) */
+
+#if LINUX_VERSION_IS_LESS(3,6,0)
+#define ipv6_addr_hash LINUX_BACKPORT(ipv6_addr_hash)
+static inline u32 ipv6_addr_hash(const struct in6_addr *a)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+ const unsigned long *ul = (const unsigned long *)a;
+ unsigned long x = ul[0] ^ ul[1];
+
+ return (u32)(x ^ (x >> 32));
+#else
+ return (__force u32)(a->s6_addr32[0] ^ a->s6_addr32[1] ^
+ a->s6_addr32[2] ^ a->s6_addr32[3]);
+#endif
+}
+#endif
+
+#if LINUX_VERSION_IS_LESS(4,5,0)
+#define ipv6_addr_prefix_copy LINUX_BACKPORT(ipv6_addr_prefix_copy)
+static inline void ipv6_addr_prefix_copy(struct in6_addr *addr,
+ const struct in6_addr *pfx,
+ int plen)
+{
+ /* caller must guarantee 0 <= plen <= 128 */
+ int o = plen >> 3,
+ b = plen & 0x7;
+
+ memcpy(addr->s6_addr, pfx, o);
+ if (b != 0) {
+ addr->s6_addr[o] &= ~(0xff00 >> b);
+ addr->s6_addr[o] |= (pfx->s6_addr[o] & (0xff00 >> b));
+ }
+}
+#endif
+
+#endif /* __BACKPORT_NET_IPV6_H */
diff --git a/backport-include/net/iw_handler.h b/backport-include/net/iw_handler.h
new file mode 100644
index 0000000..84d63b3
--- /dev/null
+++ b/backport-include/net/iw_handler.h
@@ -0,0 +1,40 @@
+#ifndef __BACKPORT_IW_HANDLER_H
+#define __BACKPORT_IW_HANDLER_H
+#include_next <net/iw_handler.h>
+
+#if LINUX_VERSION_IS_LESS(4,1,0)
+static inline char *
+iwe_stream_add_event_check(struct iw_request_info *info, char *stream,
+ char *ends, struct iw_event *iwe, int event_len)
+{
+ char *res = iwe_stream_add_event(info, stream, ends, iwe, event_len);
+
+ if (res == stream)
+ return ERR_PTR(-E2BIG);
+ return res;
+}
+
+static inline char *
+iwe_stream_add_point_check(struct iw_request_info *info, char *stream,
+ char *ends, struct iw_event *iwe, char *extra)
+{
+ char *res = iwe_stream_add_point(info, stream, ends, iwe, extra);
+
+ if (res == stream)
+ return ERR_PTR(-E2BIG);
+ return res;
+}
+#endif /* LINUX_VERSION_IS_LESS(4,1,0) */
+
+/* this was added in v3.2.79, v3.18.30, v4.1.21, v4.4.6 and 4.5 */
+#if !(LINUX_VERSION_IS_GEQ(4,4,6) || \
+ (LINUX_VERSION_IS_GEQ(4,1,21) && \
+ LINUX_VERSION_IS_LESS(4,2,0)) || \
+ (LINUX_VERSION_IS_GEQ(3,18,30) && \
+ LINUX_VERSION_IS_LESS(3,19,0)) || \
+ (LINUX_VERSION_IS_GEQ(3,2,79) && \
+ LINUX_VERSION_IS_LESS(3,3,0)))
+#define wireless_nlevent_flush LINUX_BACKPORT(wireless_nlevent_flush)
+static inline void wireless_nlevent_flush(void) {}
+#endif
+#endif /* __BACKPORT_IW_HANDLER_H */
diff --git a/backport-include/net/net_namespace.h b/backport-include/net/net_namespace.h
new file mode 100644
index 0000000..1e84297
--- /dev/null
+++ b/backport-include/net/net_namespace.h
@@ -0,0 +1,44 @@
+#ifndef _COMPAT_NET_NET_NAMESPACE_H
+#define _COMPAT_NET_NET_NAMESPACE_H 1
+
+#include_next <net/net_namespace.h>
+
+#if LINUX_VERSION_IS_LESS(3,20,0)
+/*
+ * In older kernels we simply fail this function.
+ */
+#define get_net_ns_by_fd LINUX_BACKPORT(get_net_ns_by_fd)
+static inline struct net *get_net_ns_by_fd(int fd)
+{
+ return ERR_PTR(-EINVAL);
+}
+#endif
+
+#if LINUX_VERSION_IS_LESS(4,1,0)
+typedef struct {
+#ifdef CONFIG_NET_NS
+ struct net *net;
+#endif
+} possible_net_t;
+
+static inline void possible_write_pnet(possible_net_t *pnet, struct net *net)
+{
+#ifdef CONFIG_NET_NS
+ pnet->net = net;
+#endif
+}
+
+static inline struct net *possible_read_pnet(const possible_net_t *pnet)
+{
+#ifdef CONFIG_NET_NS
+ return pnet->net;
+#else
+ return &init_net;
+#endif
+}
+#else
+#define possible_write_pnet(pnet, net) write_pnet(pnet, net)
+#define possible_read_pnet(pnet) read_pnet(pnet)
+#endif /* LINUX_VERSION_IS_LESS(4,1,0) */
+
+#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..37c899b
--- /dev/null
+++ b/backport-include/net/netlink.h
@@ -0,0 +1,360 @@
+#ifndef __BACKPORT_NET_NETLINK_H
+#define __BACKPORT_NET_NETLINK_H
+#include_next <net/netlink.h>
+#include <linux/version.h>
+#include <linux/in6.h>
+
+#if LINUX_VERSION_IS_LESS(4,12,0)
+#include <backport/magic.h>
+
+static inline int nla_validate5(const struct nlattr *head,
+ int len, int maxtype,
+ const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nla_validate(head, len, maxtype, policy);
+}
+#define nla_validate4 nla_validate
+#define nla_validate(...) \
+ macro_dispatcher(nla_validate, __VA_ARGS__)(__VA_ARGS__)
+
+static inline int nla_parse6(struct nlattr **tb, int maxtype,
+ const struct nlattr *head,
+ int len, const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nla_parse(tb, maxtype, head, len, policy);
+}
+#define nla_parse5(...) nla_parse(__VA_ARGS__)
+#define nla_parse(...) \
+ macro_dispatcher(nla_parse, __VA_ARGS__)(__VA_ARGS__)
+
+static inline int nlmsg_parse6(const struct nlmsghdr *nlh, int hdrlen,
+ struct nlattr *tb[], int maxtype,
+ const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nlmsg_parse(nlh, hdrlen, tb, maxtype, policy);
+}
+#define nlmsg_parse5 nlmsg_parse
+#define nlmsg_parse(...) \
+ macro_dispatcher(nlmsg_parse, __VA_ARGS__)(__VA_ARGS__)
+
+static inline int nlmsg_validate5(const struct nlmsghdr *nlh,
+ int hdrlen, int maxtype,
+ const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nlmsg_validate(nlh, hdrlen, maxtype, policy);
+}
+#define nlmsg_validate4 nlmsg_validate
+#define nlmsg_validate(...) \
+ macro_dispatcher(nlmsg_validate, __VA_ARGS__)(__VA_ARGS__)
+
+static inline int nla_parse_nested5(struct nlattr *tb[], int maxtype,
+ const struct nlattr *nla,
+ const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nla_parse_nested(tb, maxtype, nla, policy);
+}
+#define nla_parse_nested4 nla_parse_nested
+#define nla_parse_nested(...) \
+ macro_dispatcher(nla_parse_nested, __VA_ARGS__)(__VA_ARGS__)
+
+static inline int nla_validate_nested4(const struct nlattr *start, int maxtype,
+ const struct nla_policy *policy,
+ struct netlink_ext_ack *extack)
+{
+ return nla_validate_nested(start, maxtype, policy);
+}
+#define nla_validate_nested3 nla_validate_nested
+#define nla_validate_nested(...) \
+ macro_dispatcher(nla_validate_nested, __VA_ARGS__)(__VA_ARGS__)
+#endif /* LINUX_VERSION_IS_LESS(4,12,0) */
+
+#if LINUX_VERSION_IS_LESS(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
+ */
+#define nla_put_s8 LINUX_BACKPORT(nla_put_s8)
+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
+ */
+#define nla_put_s16 LINUX_BACKPORT(nla_put_s16)
+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
+ */
+#define nla_put_s32 LINUX_BACKPORT(nla_put_s32)
+static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
+{
+ return nla_put(skb, attrtype, sizeof(s32), &value);
+}
+
+/**
+ * nla_get_s32 - return payload of s32 attribute
+ * @nla: s32 netlink attribute
+ */
+#define nla_get_s32 LINUX_BACKPORT(nla_get_s32)
+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
+ */
+#define nla_get_s16 LINUX_BACKPORT(nla_get_s16)
+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
+ */
+#define nla_get_s8 LINUX_BACKPORT(nla_get_s8)
+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
+ */
+#define nla_get_s64 LINUX_BACKPORT(nla_get_s64)
+static inline s64 nla_get_s64(const struct nlattr *nla)
+{
+ s64 tmp;
+
+ nla_memcpy(&tmp, nla, sizeof(tmp));
+
+ return tmp;
+}
+#endif /* < 3.7.0 */
+
+#if LINUX_VERSION_IS_LESS(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.
+ */
+
+#define nla_put_be16 LINUX_BACKPORT(nla_put_be16)
+static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be16), &value);
+}
+
+#define nla_put_be32 LINUX_BACKPORT(nla_put_be32)
+static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be32), &value);
+}
+
+#define nla_put_be64 LINUX_BACKPORT(nla_put_be64)
+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 */
+
+#if LINUX_VERSION_IS_LESS(3,7,0)
+#define NLA_S8 (NLA_BINARY + 1)
+#define NLA_S16 (NLA_BINARY + 2)
+#define NLA_S32 (NLA_BINARY + 3)
+#define NLA_S64 (NLA_BINARY + 4)
+#define __NLA_TYPE_MAX (NLA_BINARY + 5)
+
+#undef NLA_TYPE_MAX
+#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+#endif
+
+#if LINUX_VERSION_IS_LESS(4,1,0)
+#define nla_put_in_addr LINUX_BACKPORT(nla_put_in_addr)
+static inline int nla_put_in_addr(struct sk_buff *skb, int attrtype,
+ __be32 addr)
+{
+ return nla_put_be32(skb, attrtype, addr);
+}
+
+#define nla_put_in6_addr LINUX_BACKPORT(nla_put_in6_addr)
+static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
+ const struct in6_addr *addr)
+{
+ return nla_put(skb, attrtype, sizeof(*addr), addr);
+}
+
+static inline __be32 nla_get_in_addr(const struct nlattr *nla)
+{
+ return *(__be32 *) nla_data(nla);
+}
+
+static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
+{
+ struct in6_addr tmp;
+
+ nla_memcpy(&tmp, nla, sizeof(tmp));
+ return tmp;
+}
+#endif /* < 4.1 */
+
+#if LINUX_VERSION_IS_LESS(4,4,0)
+/**
+ * nla_get_le32 - return payload of __le32 attribute
+ * @nla: __le32 netlink attribute
+ */
+#define nla_get_le32 LINUX_BACKPORT(nla_get_le32)
+static inline __le32 nla_get_le32(const struct nlattr *nla)
+{
+ return *(__le32 *) nla_data(nla);
+}
+
+/**
+ * nla_get_le64 - return payload of __le64 attribute
+ * @nla: __le64 netlink attribute
+ */
+#define nla_get_le64 LINUX_BACKPORT(nla_get_le64)
+static inline __le64 nla_get_le64(const struct nlattr *nla)
+{
+ return *(__le64 *) nla_data(nla);
+}
+#endif /* < 4.4 */
+
+#if LINUX_VERSION_IS_LESS(4,7,0)
+/**
+ * nla_need_padding_for_64bit - test 64-bit alignment of the next attribute
+ * @skb: socket buffer the message is stored in
+ *
+ * Return true if padding is needed to align the next attribute (nla_data()) to
+ * a 64-bit aligned area.
+ */
+#define nla_need_padding_for_64bit LINUX_BACKPORT(nla_need_padding_for_64bit)
+static inline bool nla_need_padding_for_64bit(struct sk_buff *skb)
+{
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ /* The nlattr header is 4 bytes in size, that's why we test
+ * if the skb->data _is_ aligned. A NOP attribute, plus
+ * nlattr header for next attribute, will make nla_data()
+ * 8-byte aligned.
+ */
+ if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8))
+ return true;
+#endif
+ return false;
+}
+/**
+ * nla_align_64bit - 64-bit align the nla_data() of next attribute
+ * @skb: socket buffer the message is stored in
+ * @padattr: attribute type for the padding
+ *
+ * Conditionally emit a padding netlink attribute in order to make
+ * the next attribute we emit have a 64-bit aligned nla_data() area.
+ * This will only be done in architectures which do not have
+ * HAVE_EFFICIENT_UNALIGNED_ACCESS defined.
+ *
+ * Returns zero on success or a negative error code.
+ */
+#define nla_align_64bit LINUX_BACKPORT(nla_align_64bit)
+static inline int nla_align_64bit(struct sk_buff *skb, int padattr)
+{
+ if (nla_need_padding_for_64bit(skb) &&
+ !nla_reserve(skb, padattr, 0))
+ return -EMSGSIZE;
+ return 0;
+}
+
+/**
+ * nla_total_size_64bit - total length of attribute including padding
+ * @payload: length of payload
+ */
+#define nla_total_size_64bit LINUX_BACKPORT(nla_total_size_64bit)
+static inline int nla_total_size_64bit(int payload)
+{
+ return NLA_ALIGN(nla_attr_size(payload))
+#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
+ + NLA_ALIGN(nla_attr_size(0))
+#endif
+ ;
+}
+#define __nla_reserve_64bit LINUX_BACKPORT(__nla_reserve_64bit)
+struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
+ int attrlen, int padattr);
+#define nla_reserve_64bit LINUX_BACKPORT(nla_reserve_64bit)
+struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype,
+ int attrlen, int padattr);
+#define __nla_put_64bit LINUX_BACKPORT(__nla_put_64bit)
+void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
+ const void *data, int padattr);
+#define nla_put_64bit LINUX_BACKPORT(nla_put_64bit)
+int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
+ const void *data, int padattr);
+/**
+ * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ * @padattr: attribute type for the padding
+ */
+#define nla_put_u64_64bit LINUX_BACKPORT(nla_put_u64_64bit)
+static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
+ u64 value, int padattr)
+{
+ return nla_put_64bit(skb, attrtype, sizeof(u64), &value, padattr);
+}
+
+
+/**
+ * nla_put_s64 - Add a s64 netlink attribute to a socket buffer and align it
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ * @padattr: attribute type for the padding
+ */
+#define nla_put_s64 LINUX_BACKPORT(nla_put_s64)
+static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value,
+ int padattr)
+{
+ return nla_put_64bit(skb, attrtype, sizeof(s64), &value, padattr);
+}
+#endif /* < 4.7 */
+
+#if LINUX_VERSION_IS_LESS(4,10,0)
+/**
+ * nla_memdup - duplicate attribute memory (kmemdup)
+ * @src: netlink attribute to duplicate from
+ * @gfp: GFP mask
+ */
+#define nla_memdump LINUX_BACKPORT(nla_memdup)
+static inline void *nla_memdup(const struct nlattr *src, gfp_t gfp)
+{
+ return kmemdup(nla_data(src), nla_len(src), gfp);
+}
+#endif /* < 4.9 */
+
+#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..cabc601
--- /dev/null
+++ b/backport-include/net/sch_generic.h
@@ -0,0 +1,20 @@
+#ifndef __BACKPORT_NET_SCH_GENERIC_H
+#define __BACKPORT_NET_SCH_GENERIC_H
+#include_next <net/sch_generic.h>
+
+#if LINUX_VERSION_IS_LESS(3,3,0)
+#if !((LINUX_VERSION_IS_GEQ(3,2,9) && LINUX_VERSION_IS_LESS(3,3,0)) || (LINUX_VERSION_IS_GEQ(3,0,23) && LINUX_VERSION_IS_LESS(3,1,0)))
+/* 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);
+}
+#endif
+#endif /* LINUX_VERSION_IS_LESS(3,3,0) */
+
+#ifndef TCQ_F_CAN_BYPASS
+#define TCQ_F_CAN_BYPASS 4
+#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..89191f3
--- /dev/null
+++ b/backport-include/net/sock.h
@@ -0,0 +1,66 @@
+#ifndef __BACKPORT_NET_SOCK_H
+#define __BACKPORT_NET_SOCK_H
+#include_next <net/sock.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_IS_LESS(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_IS_LESS(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
+
+#ifndef sock_skb_cb_check_size
+#define sock_skb_cb_check_size(size) \
+ BUILD_BUG_ON((size) > FIELD_SIZEOF(struct sk_buff, cb))
+#endif
+
+#if LINUX_VERSION_IS_LESS(4,2,0)
+#define sk_alloc(net, family, priority, prot, kern) sk_alloc(net, family, priority, prot)
+#endif
+
+#if LINUX_VERSION_IS_LESS(4,5,0)
+#define sk_set_bit LINUX_BACKPORT(sk_set_bit)
+static inline void sk_set_bit(int nr, struct sock *sk)
+{
+ set_bit(nr, &sk->sk_socket->flags);
+}
+#endif /* < 4.5 */
+
+#if LINUX_VERSION_IS_LESS(4,5,0)
+#define sk_clear_bit LINUX_BACKPORT(sk_clear_bit)
+static inline void sk_clear_bit(int nr, struct sock *sk)
+{
+ clear_bit(nr, &sk->sk_socket->flags);
+}
+#endif /* < 4.5 */
+
+#endif /* __BACKPORT_NET_SOCK_H */
diff --git a/backport-include/net/tso.h b/backport-include/net/tso.h
new file mode 100644
index 0000000..3a3f50b
--- /dev/null
+++ b/backport-include/net/tso.h
@@ -0,0 +1,33 @@
+#ifndef BACKPORT_TSO_H
+#define BACKPORT_TSO_H
+
+#include <net/ip.h>
+
+#if LINUX_VERSION_IS_LESS(4,4,0)
+
+#define tso_t LINUX_BACKPORT(tso_t)
+struct tso_t {
+ int next_frag_idx;
+ void *data;
+ size_t size;
+ u16 ip_id;
+ bool ipv6;
+ u32 tcp_seq;
+};
+
+#define tso_count_descs LINUX_BACKPORT(tso_count_descs)
+int tso_count_descs(struct sk_buff *skb);
+
+#define tso_build_hdr LINUX_BACKPORT(tso_build_hdr)
+void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
+ int size, bool is_last);
+#define tso_build_data LINUX_BACKPORT(tso_build_data)
+void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);
+#define tso_start LINUX_BACKPORT(tso_start)
+void tso_start(struct sk_buff *skb, struct tso_t *tso);
+
+#else
+#include_next <net/tso.h>
+#endif
+
+#endif /* BACKPORT_TSO_H */