You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
10 KiB

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