0011-kernel-4-4-support.patch (10723B)
1 diff --git a/acinclude.m4 b/acinclude.m4 2 index 11c7787..07dd647 100644 3 --- a/acinclude.m4 4 +++ b/acinclude.m4 5 @@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ 6 AC_MSG_RESULT([$kversion]) 7 8 if test "$version" -ge 4; then 9 - if test "$version" = 4 && test "$patchlevel" -le 3; then 10 + if test "$version" = 4 && test "$patchlevel" -le 4; then 11 : # Linux 4.x 12 else 13 - 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)]) 14 + 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)]) 15 fi 16 elif test "$version" = 3; then 17 : # Linux 3.x 18 diff --git a/datapath/actions.c b/datapath/actions.c 19 index 20413c9..719c43d 100644 20 --- a/datapath/actions.c 21 +++ b/datapath/actions.c 22 @@ -706,7 +706,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, 23 skb_dst_set_noref(skb, &ovs_dst); 24 IPCB(skb)->frag_max_size = mru; 25 26 - ip_do_fragment(skb->sk, skb, ovs_vport_output); 27 + ip_do_fragment(NET_ARG(dev_net(ovs_dst.dev)) 28 + skb->sk, skb, ovs_vport_output); 29 refdst_drop(orig_dst); 30 } else if (ethertype == htons(ETH_P_IPV6)) { 31 const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); 32 @@ -727,7 +728,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, 33 skb_dst_set_noref(skb, &ovs_rt.dst); 34 IP6CB(skb)->frag_max_size = mru; 35 36 - v6ops->fragment(skb->sk, skb, ovs_vport_output); 37 + v6ops->fragment(NET_ARG(dev_net(ovs_rt.dst.dev)) 38 + skb->sk, skb, ovs_vport_output); 39 refdst_drop(orig_dst); 40 } else { 41 WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.", 42 diff --git a/datapath/conntrack.c b/datapath/conntrack.c 43 index 795ed91..3b9bfba 100644 44 --- a/datapath/conntrack.c 45 +++ b/datapath/conntrack.c 46 @@ -323,7 +323,7 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, 47 int err; 48 49 memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); 50 - err = ip_defrag(skb, user); 51 + err = ip_defrag(NET_ARG(net) skb, user); 52 if (err) 53 return err; 54 55 @@ -374,7 +374,7 @@ ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone, 56 { 57 struct nf_conntrack_tuple tuple; 58 59 - if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, &tuple)) 60 + if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, NET_ARG(net) &tuple)) 61 return NULL; 62 return __nf_ct_expect_find(net, zone, &tuple); 63 } 64 diff --git a/datapath/datapath.c b/datapath/datapath.c 65 index e3d3c8c..a4157f4 100644 66 --- a/datapath/datapath.c 67 +++ b/datapath/datapath.c 68 @@ -96,8 +96,12 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, 69 static void ovs_notify(struct genl_family *family, struct genl_multicast_group *grp, 70 struct sk_buff *skb, struct genl_info *info) 71 { 72 - genl_notify(family, skb, genl_info_net(info), 73 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 74 + genl_notify(family, skb, info, GROUP_ID(grp), GFP_KERNEL); 75 +#else 76 + genl_notify(family, skb, genl_info_net(info), 77 info->snd_portid, GROUP_ID(grp), info->nlhdr, GFP_KERNEL); 78 +#endif 79 } 80 81 /** 82 diff --git a/datapath/linux/compat/include/linux/netfilter_ipv6.h b/datapath/linux/compat/include/linux/netfilter_ipv6.h 83 index 3939e14..b724623 100644 84 --- a/datapath/linux/compat/include/linux/netfilter_ipv6.h 85 +++ b/datapath/linux/compat/include/linux/netfilter_ipv6.h 86 @@ -13,7 +13,7 @@ 87 * the callback parameter needs to be in the form that older kernels accept. 88 * We don't backport the other ipv6_ops as they're currently unused by OVS. */ 89 struct ovs_nf_ipv6_ops { 90 - int (*fragment)(struct sock *sk, struct sk_buff *skb, 91 + int (*fragment)(NET_ARG(net) struct sock *sk, struct sk_buff *skb, 92 int (*output)(OVS_VPORT_OUTPUT_PARAMS)); 93 }; 94 #define nf_ipv6_ops ovs_nf_ipv6_ops 95 diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h 96 index cd87bcc..b749301 100644 97 --- a/datapath/linux/compat/include/net/ip.h 98 +++ b/datapath/linux/compat/include/net/ip.h 99 @@ -66,8 +66,20 @@ static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb) 100 #define ip_skb_dst_mtu rpl_ip_skb_dst_mtu 101 #endif /* HAVE_IP_SKB_DST_MTU */ 102 103 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 104 +#define NET_PARAM(x) struct net *x, 105 +#define NET_ARG(x) x, 106 +#define NET_DEV_NET(x) dev_net(x) 107 +#define NET_DECLARE_INIT(x,y) 108 +#else 109 +#define NET_PARAM(x) 110 +#define NET_ARG(x) 111 +#define NET_DEV_NET(x) 112 +#define NET_DECLARE_INIT(x,y) struct net *x = y; 113 +#endif 114 + 115 #ifdef HAVE_IP_FRAGMENT_TAKES_SOCK 116 -#define OVS_VPORT_OUTPUT_PARAMS struct sock *sock, struct sk_buff *skb 117 +#define OVS_VPORT_OUTPUT_PARAMS NET_PARAM(net) struct sock *sock, struct sk_buff *skb 118 #else 119 #define OVS_VPORT_OUTPUT_PARAMS struct sk_buff *skb 120 #endif 121 @@ -89,12 +101,13 @@ static inline bool ip_defrag_user_in_between(u32 user, 122 #endif /* < v4.2 */ 123 124 #ifndef HAVE_IP_DO_FRAGMENT 125 -static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, 126 +static inline int rpl_ip_do_fragment(NET_PARAM(net) struct sock *sk, struct sk_buff *skb, 127 int (*output)(OVS_VPORT_OUTPUT_PARAMS)) 128 { 129 unsigned int mtu = ip_skb_dst_mtu(skb); 130 struct iphdr *iph = ip_hdr(skb); 131 struct rtable *rt = skb_rtable(skb); 132 struct net_device *dev = rt->dst.dev; 133 + NET_DECLARE_INIT(net, dev_net(dev)); 134 135 if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) || 136 @@ -102,7 +115,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, 137 IPCB(skb)->frag_max_size > mtu))) { 138 139 pr_warn("Dropping packet in ip_do_fragment()\n"); 140 - IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); 141 + IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS); 142 kfree_skb(skb); 143 return -EMSGSIZE; 144 } 145 @@ -116,8 +129,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, 146 #define ip_do_fragment rpl_ip_do_fragment 147 #endif /* IP_DO_FRAGMENT */ 148 149 -int rpl_ip_defrag(struct sk_buff *skb, u32 user); 150 -#define ip_defrag rpl_ip_defrag 151 +int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user); 152 153 int __init rpl_ipfrag_init(void); 154 void rpl_ipfrag_fini(void); 155 @@ -127,14 +139,15 @@ void rpl_ipfrag_fini(void); 156 * ("inet: frag: Always orphan skbs inside ip_defrag()"), but it should be 157 * always included in kernels 4.5+. */ 158 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) 159 -static inline int rpl_ip_defrag(struct sk_buff *skb, u32 user) 160 +static inline int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user) 161 { 162 skb_orphan(skb); 163 - return ip_defrag(skb, user); 164 + return ip_defrag(NET_ARG(net) skb, user); 165 } 166 -#define ip_defrag rpl_ip_defrag 167 #endif 168 169 +#define ip_defrag rpl_ip_defrag 170 + 171 static inline int rpl_ipfrag_init(void) { return 0; } 172 static inline void rpl_ipfrag_fini(void) { } 173 #endif /* HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ 174 diff --git a/datapath/linux/compat/include/net/ip6_tunnel.h b/datapath/linux/compat/include/net/ip6_tunnel.h 175 index ce65087..eacf9ca 100644 176 --- a/datapath/linux/compat/include/net/ip6_tunnel.h 177 +++ b/datapath/linux/compat/include/net/ip6_tunnel.h 178 @@ -17,11 +17,15 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, 179 180 pkt_len = skb->len - skb_inner_network_offset(skb); 181 /* TODO: Fix GSO for ipv6 */ 182 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 183 + err = ip6_local_out(dev_net(dev), sk, skb); 184 +#else 185 #ifdef HAVE_IP6_LOCAL_OUT_SK 186 err = ip6_local_out_sk(sk, skb); 187 #else 188 err = ip6_local_out(skb); 189 #endif 190 +#endif /* >= kernel 4.4 */ 191 if (net_xmit_eval(err) != 0) 192 pkt_len = net_xmit_eval(err); 193 else 194 diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h 195 index b50cd17..230f3ad 100644 196 --- a/datapath/linux/compat/include/net/vxlan.h 197 +++ b/datapath/linux/compat/include/net/vxlan.h 198 @@ -218,10 +218,20 @@ struct vxlan_dev { 199 struct net_device *rpl_vxlan_dev_create(struct net *net, const char *name, 200 u8 name_assign_type, struct vxlan_config *conf); 201 202 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 203 +static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan, 204 + unsigned short family) 205 +{ 206 + if (family == AF_INET6) 207 + return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport; 208 + return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport; 209 +} 210 +#else 211 static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan) 212 { 213 return inet_sport(vxlan->vn_sock->sock->sk); 214 } 215 +#endif 216 217 static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, 218 netdev_features_t features) 219 diff --git a/datapath/linux/compat/ip_fragment.c b/datapath/linux/compat/ip_fragment.c 220 index cf2daaa..e168196 100644 221 --- a/datapath/linux/compat/ip_fragment.c 222 +++ b/datapath/linux/compat/ip_fragment.c 223 @@ -674,11 +674,11 @@ out_fail: 224 } 225 226 /* Process an incoming IP datagram fragment. */ 227 -int rpl_ip_defrag(struct sk_buff *skb, u32 user) 228 +int rpl_ip_defrag(NET_ARG(net) struct sk_buff *skb, u32 user) 229 { 230 struct net_device *dev = skb->dev ? : skb_dst(skb)->dev; 231 int vif = vrf_master_ifindex_rcu(dev); 232 - struct net *net = dev_net(dev); 233 + NET_DECLARE_INIT(net, dev_net(dev)); 234 struct ipq *qp; 235 236 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); 237 diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c 238 index eb397e8..5ea3c52 100644 239 --- a/datapath/linux/compat/stt.c 240 +++ b/datapath/linux/compat/stt.c 241 @@ -1450,7 +1450,11 @@ static void clean_percpu(struct work_struct *work) 242 } 243 244 #ifdef HAVE_NF_HOOKFN_ARG_OPS 245 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 246 +#define FIRST_PARAM void *priv 247 +#else 248 #define FIRST_PARAM const struct nf_hook_ops *ops 249 +#endif /* >= kernel 4.4 */ 250 #else 251 #define FIRST_PARAM unsigned int hooknum 252 #endif 253 @@ -1498,7 +1502,9 @@ static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM) 254 255 static struct nf_hook_ops nf_hook_ops __read_mostly = { 256 .hook = nf_ip_hook, 257 +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) 258 .owner = THIS_MODULE, 259 +#endif 260 .pf = NFPROTO_IPV4, 261 .hooknum = NF_INET_LOCAL_IN, 262 .priority = INT_MAX, 263 diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c 264 index c05f5d4..3cbb568 100644 265 --- a/datapath/vport-vxlan.c 266 +++ b/datapath/vport-vxlan.c 267 @@ -153,7 +153,12 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, 268 { 269 struct vxlan_dev *vxlan = netdev_priv(vport->dev); 270 struct net *net = ovs_dp_get_net(vport->dp); 271 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) 272 + unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info); 273 + __be16 dst_port = vxlan_dev_dst_port(vxlan, family); 274 +#else 275 __be16 dst_port = vxlan_dev_dst_port(vxlan); 276 +#endif 277 __be16 src_port; 278 int port_min; 279 int port_max;