This repository has been archived by the owner on Jan 11, 2018. It is now read-only.
forked from openwrt/packages
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
openvswitch: add support for kernel 4.4
Signed-off-by: Alexandru Ardelean <[email protected]>
- Loading branch information
Showing
2 changed files
with
282 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
diff --git a/acinclude.m4 b/acinclude.m4 | ||
index 11c7787..07dd647 100644 | ||
--- a/acinclude.m4 | ||
+++ b/acinclude.m4 | ||
@@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ | ||
AC_MSG_RESULT([$kversion]) | ||
|
||
if test "$version" -ge 4; then | ||
- if test "$version" = 4 && test "$patchlevel" -le 3; then | ||
+ if test "$version" = 4 && test "$patchlevel" -le 4; then | ||
: # Linux 4.x | ||
else | ||
- AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.3.x is not supported (please refer to the FAQ for advice)]) | ||
+ AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.4.x is not supported (please refer to the FAQ for advice)]) | ||
fi | ||
elif test "$version" = 3; then | ||
: # Linux 3.x | ||
diff --git a/datapath/actions.c b/datapath/actions.c | ||
index 20413c9..719c43d 100644 | ||
--- a/datapath/actions.c | ||
+++ b/datapath/actions.c | ||
@@ -706,7 +706,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, | ||
skb_dst_set_noref(skb, &ovs_dst); | ||
IPCB(skb)->frag_max_size = mru; | ||
|
||
- ip_do_fragment(skb->sk, skb, ovs_vport_output); | ||
+ ip_do_fragment(NET_ARG(dev_net(ovs_dst.dev)) | ||
+ skb->sk, skb, ovs_vport_output); | ||
refdst_drop(orig_dst); | ||
} else if (ethertype == htons(ETH_P_IPV6)) { | ||
const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); | ||
@@ -727,7 +728,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, | ||
skb_dst_set_noref(skb, &ovs_rt.dst); | ||
IP6CB(skb)->frag_max_size = mru; | ||
|
||
- v6ops->fragment(skb->sk, skb, ovs_vport_output); | ||
+ v6ops->fragment(NET_ARG(dev_net(ovs_rt.dst.dev)) | ||
+ skb->sk, skb, ovs_vport_output); | ||
refdst_drop(orig_dst); | ||
} else { | ||
WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.", | ||
diff --git a/datapath/conntrack.c b/datapath/conntrack.c | ||
index 795ed91..3b9bfba 100644 | ||
--- a/datapath/conntrack.c | ||
+++ b/datapath/conntrack.c | ||
@@ -323,7 +323,7 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, | ||
int err; | ||
|
||
memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
- err = ip_defrag(skb, user); | ||
+ err = ip_defrag(NET_ARG(net) skb, user); | ||
if (err) | ||
return err; | ||
|
||
@@ -374,7 +374,7 @@ ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone, | ||
{ | ||
struct nf_conntrack_tuple tuple; | ||
|
||
- if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, &tuple)) | ||
+ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, NET_ARG(net) &tuple)) | ||
return NULL; | ||
return __nf_ct_expect_find(net, zone, &tuple); | ||
} | ||
diff --git a/datapath/datapath.c b/datapath/datapath.c | ||
index e3d3c8c..a4157f4 100644 | ||
--- a/datapath/datapath.c | ||
+++ b/datapath/datapath.c | ||
@@ -96,8 +96,12 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, | ||
static void ovs_notify(struct genl_family *family, struct genl_multicast_group *grp, | ||
struct sk_buff *skb, struct genl_info *info) | ||
{ | ||
- genl_notify(family, skb, genl_info_net(info), | ||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+ genl_notify(family, skb, info, GROUP_ID(grp), GFP_KERNEL); | ||
+#else | ||
+ genl_notify(family, skb, genl_info_net(info), | ||
info->snd_portid, GROUP_ID(grp), info->nlhdr, GFP_KERNEL); | ||
+#endif | ||
} | ||
|
||
/** | ||
diff --git a/datapath/linux/compat/include/linux/netfilter_ipv6.h b/datapath/linux/compat/include/linux/netfilter_ipv6.h | ||
index 3939e14..b724623 100644 | ||
--- a/datapath/linux/compat/include/linux/netfilter_ipv6.h | ||
+++ b/datapath/linux/compat/include/linux/netfilter_ipv6.h | ||
@@ -13,7 +13,7 @@ | ||
* the callback parameter needs to be in the form that older kernels accept. | ||
* We don't backport the other ipv6_ops as they're currently unused by OVS. */ | ||
struct ovs_nf_ipv6_ops { | ||
- int (*fragment)(struct sock *sk, struct sk_buff *skb, | ||
+ int (*fragment)(NET_ARG(net) struct sock *sk, struct sk_buff *skb, | ||
int (*output)(OVS_VPORT_OUTPUT_PARAMS)); | ||
}; | ||
#define nf_ipv6_ops ovs_nf_ipv6_ops | ||
diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h | ||
index cd87bcc..b749301 100644 | ||
--- a/datapath/linux/compat/include/net/ip.h | ||
+++ b/datapath/linux/compat/include/net/ip.h | ||
@@ -66,8 +66,20 @@ static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb) | ||
#define ip_skb_dst_mtu rpl_ip_skb_dst_mtu | ||
#endif /* HAVE_IP_SKB_DST_MTU */ | ||
|
||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+#define NET_PARAM(x) struct net *x, | ||
+#define NET_ARG(x) x, | ||
+#define NET_DEV_NET(x) dev_net(x) | ||
+#define NET_DECLARE_INIT(x,y) | ||
+#else | ||
+#define NET_PARAM(x) | ||
+#define NET_ARG(x) | ||
+#define NET_DEV_NET(x) | ||
+#define NET_DECLARE_INIT(x,y) struct net *x = y; | ||
+#endif | ||
+ | ||
#ifdef HAVE_IP_FRAGMENT_TAKES_SOCK | ||
-#define OVS_VPORT_OUTPUT_PARAMS struct sock *sock, struct sk_buff *skb | ||
+#define OVS_VPORT_OUTPUT_PARAMS NET_PARAM(net) struct sock *sock, struct sk_buff *skb | ||
#else | ||
#define OVS_VPORT_OUTPUT_PARAMS struct sk_buff *skb | ||
#endif | ||
@@ -89,12 +101,13 @@ static inline bool ip_defrag_user_in_between(u32 user, | ||
#endif /* < v4.2 */ | ||
|
||
#ifndef HAVE_IP_DO_FRAGMENT | ||
-static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, | ||
+static inline int rpl_ip_do_fragment(NET_PARAM(net) struct sock *sk, struct sk_buff *skb, | ||
int (*output)(OVS_VPORT_OUTPUT_PARAMS)) | ||
{ | ||
unsigned int mtu = ip_skb_dst_mtu(skb); | ||
struct iphdr *iph = ip_hdr(skb); | ||
struct rtable *rt = skb_rtable(skb); | ||
+ NET_DECLARE_INIT(net, dev_net(dev)); | ||
struct net_device *dev = rt->dst.dev; | ||
|
||
if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) || | ||
@@ -102,7 +115,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, | ||
IPCB(skb)->frag_max_size > mtu))) { | ||
|
||
pr_warn("Dropping packet in ip_do_fragment()\n"); | ||
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); | ||
+ IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS); | ||
kfree_skb(skb); | ||
return -EMSGSIZE; | ||
} | ||
@@ -116,8 +129,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, | ||
#define ip_do_fragment rpl_ip_do_fragment | ||
#endif /* IP_DO_FRAGMENT */ | ||
|
||
-int rpl_ip_defrag(struct sk_buff *skb, u32 user); | ||
-#define ip_defrag rpl_ip_defrag | ||
+int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user); | ||
|
||
int __init rpl_ipfrag_init(void); | ||
void rpl_ipfrag_fini(void); | ||
@@ -127,14 +139,15 @@ void rpl_ipfrag_fini(void); | ||
* ("inet: frag: Always orphan skbs inside ip_defrag()"), but it should be | ||
* always included in kernels 4.5+. */ | ||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) | ||
-static inline int rpl_ip_defrag(struct sk_buff *skb, u32 user) | ||
+static inline int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user) | ||
{ | ||
skb_orphan(skb); | ||
- return ip_defrag(skb, user); | ||
+ return ip_defrag(NET_ARG(net) skb, user); | ||
} | ||
-#define ip_defrag rpl_ip_defrag | ||
#endif | ||
|
||
+#define ip_defrag rpl_ip_defrag | ||
+ | ||
static inline int rpl_ipfrag_init(void) { return 0; } | ||
static inline void rpl_ipfrag_fini(void) { } | ||
#endif /* HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ | ||
diff --git a/datapath/linux/compat/include/net/ip6_tunnel.h b/datapath/linux/compat/include/net/ip6_tunnel.h | ||
index ce65087..eacf9ca 100644 | ||
--- a/datapath/linux/compat/include/net/ip6_tunnel.h | ||
+++ b/datapath/linux/compat/include/net/ip6_tunnel.h | ||
@@ -17,11 +17,15 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, | ||
|
||
pkt_len = skb->len - skb_inner_network_offset(skb); | ||
/* TODO: Fix GSO for ipv6 */ | ||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+ err = ip6_local_out(dev_net(dev), sk, skb); | ||
+#else | ||
#ifdef HAVE_IP6_LOCAL_OUT_SK | ||
err = ip6_local_out_sk(sk, skb); | ||
#else | ||
err = ip6_local_out(skb); | ||
#endif | ||
+#endif /* >= kernel 4.4 */ | ||
if (net_xmit_eval(err) != 0) | ||
pkt_len = net_xmit_eval(err); | ||
else | ||
diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h | ||
index b50cd17..230f3ad 100644 | ||
--- a/datapath/linux/compat/include/net/vxlan.h | ||
+++ b/datapath/linux/compat/include/net/vxlan.h | ||
@@ -218,10 +218,20 @@ struct vxlan_dev { | ||
struct net_device *rpl_vxlan_dev_create(struct net *net, const char *name, | ||
u8 name_assign_type, struct vxlan_config *conf); | ||
|
||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan, | ||
+ unsigned short family) | ||
+{ | ||
+ if (family == AF_INET6) | ||
+ return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport; | ||
+ return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport; | ||
+} | ||
+#else | ||
static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan) | ||
{ | ||
return inet_sport(vxlan->vn_sock->sock->sk); | ||
} | ||
+#endif | ||
|
||
static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, | ||
netdev_features_t features) | ||
diff --git a/datapath/linux/compat/ip_fragment.c b/datapath/linux/compat/ip_fragment.c | ||
index cf2daaa..e168196 100644 | ||
--- a/datapath/linux/compat/ip_fragment.c | ||
+++ b/datapath/linux/compat/ip_fragment.c | ||
@@ -674,11 +674,11 @@ out_fail: | ||
} | ||
|
||
/* Process an incoming IP datagram fragment. */ | ||
-int rpl_ip_defrag(struct sk_buff *skb, u32 user) | ||
+int rpl_ip_defrag(NET_ARG(net) struct sk_buff *skb, u32 user) | ||
{ | ||
struct net_device *dev = skb->dev ? : skb_dst(skb)->dev; | ||
int vif = vrf_master_ifindex_rcu(dev); | ||
- struct net *net = dev_net(dev); | ||
+ NET_DECLARE_INIT(net, dev_net(dev)); | ||
struct ipq *qp; | ||
|
||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); | ||
diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c | ||
index eb397e8..5ea3c52 100644 | ||
--- a/datapath/linux/compat/stt.c | ||
+++ b/datapath/linux/compat/stt.c | ||
@@ -1450,7 +1450,11 @@ static void clean_percpu(struct work_struct *work) | ||
} | ||
|
||
#ifdef HAVE_NF_HOOKFN_ARG_OPS | ||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+#define FIRST_PARAM void *priv | ||
+#else | ||
#define FIRST_PARAM const struct nf_hook_ops *ops | ||
+#endif /* >= kernel 4.4 */ | ||
#else | ||
#define FIRST_PARAM unsigned int hooknum | ||
#endif | ||
@@ -1498,7 +1502,9 @@ static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM) | ||
|
||
static struct nf_hook_ops nf_hook_ops __read_mostly = { | ||
.hook = nf_ip_hook, | ||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) | ||
.owner = THIS_MODULE, | ||
+#endif | ||
.pf = NFPROTO_IPV4, | ||
.hooknum = NF_INET_LOCAL_IN, | ||
.priority = INT_MAX, | ||
diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c | ||
index c05f5d4..3cbb568 100644 | ||
--- a/datapath/vport-vxlan.c | ||
+++ b/datapath/vport-vxlan.c | ||
@@ -153,7 +153,12 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, | ||
{ | ||
struct vxlan_dev *vxlan = netdev_priv(vport->dev); | ||
struct net *net = ovs_dp_get_net(vport->dp); | ||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) | ||
+ unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info); | ||
+ __be16 dst_port = vxlan_dev_dst_port(vxlan, family); | ||
+#else | ||
__be16 dst_port = vxlan_dev_dst_port(vxlan); | ||
+#endif | ||
__be16 src_port; | ||
int port_min; | ||
int port_max; |