Rebase fuel-plugin for kvmfornfv to fuel 9.0
[kvmfornfv.git] / patches / ovs / 0001-Add-Linux-4.4-support.patch
1 From a4c2305b6190ce24ceaafb9f85fc5a67787fb71d Mon Sep 17 00:00:00 2001
2 From: Donald Dugger <n0ano@n0ano.com>
3 Date: Mon, 9 May 2016 05:14:12 +0000
4 Subject: [PATCH] Add Linux 4.4 support
5
6 A bit cleaner than my previous patch.
7   http://patchwork.ozlabs.org/patch/595969/
8
9 Though I couldn't figure out a clean solution for ip6_local_out(),
10 genl_notify(), and vport-vxlan
11
12 Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
13
14 Note that this patch has been rejected for the upstream OVS tree as
15 the maintainers feel a different apporach (backporting all Linux
16 patches that affect the OVS code).  We'll just use this patch until
17 the official OVS tree is updated to support Linux 4.4.
18
19 Upstream status: NA
20
21 Signed-off-by: Don Dugger <n0ano@n0ano.com>
22 ---
23  acinclude.m4                                         |  4 ++--
24  datapath/actions.c                                   |  6 ++++--
25  datapath/datapath.c                                  |  6 +++++-
26  datapath/linux/compat/include/linux/netfilter_ipv6.h |  2 +-
27  datapath/linux/compat/include/net/ip.h               | 19 ++++++++++++++++---
28  datapath/linux/compat/include/net/ip6_tunnel.h       |  4 ++++
29  datapath/linux/compat/include/net/vxlan.h            | 10 ++++++++++
30  datapath/linux/compat/stt.c                          |  6 ++++++
31  datapath/vport-vxlan.c                               |  5 +++++
32  9 files changed, 53 insertions(+), 9 deletions(-)
33
34 diff --git a/acinclude.m4 b/acinclude.m4
35 index 23015fe..22e75ec 100644
36 --- a/acinclude.m4
37 +++ b/acinclude.m4
38 @@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [
39      AC_MSG_RESULT([$kversion])
40  
41      if test "$version" -ge 4; then
42 -       if test "$version" = 4 && test "$patchlevel" -le 3; then
43 +       if test "$version" = 4 && test "$patchlevel" -le 4; then
44            : # Linux 4.x
45         else
46 -          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)])
47 +          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)])
48         fi
49      elif test "$version" = 3 && test "$patchlevel" -ge 10; then
50         : # Linux 3.x
51 diff --git a/datapath/actions.c b/datapath/actions.c
52 index dcf8591..242e710 100644
53 --- a/datapath/actions.c
54 +++ b/datapath/actions.c
55 @@ -702,7 +702,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
56                 skb_dst_set_noref(skb, &ovs_dst);
57                 IPCB(skb)->frag_max_size = mru;
58  
59 -               ip_do_fragment(skb->sk, skb, ovs_vport_output);
60 +               ip_do_fragment(NET_ARG(dev_net(ovs_dst.dev))
61 +                       skb->sk, skb, ovs_vport_output);
62                 refdst_drop(orig_dst);
63         } else if (ethertype == htons(ETH_P_IPV6)) {
64                 const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
65 @@ -723,7 +724,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
66                 skb_dst_set_noref(skb, &ovs_rt.dst);
67                 IP6CB(skb)->frag_max_size = mru;
68  
69 -               v6ops->fragment(skb->sk, skb, ovs_vport_output);
70 +               v6ops->fragment(NET_ARG(dev_net(ovs_rt.dst.dev))
71 +                       skb->sk, skb, ovs_vport_output);
72                 refdst_drop(orig_dst);
73         } else {
74                 WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.",
75 diff --git a/datapath/datapath.c b/datapath/datapath.c
76 index 5bec072..ba19c01 100644
77 --- a/datapath/datapath.c
78 +++ b/datapath/datapath.c
79 @@ -95,8 +95,12 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info,
80  static void ovs_notify(struct genl_family *family, struct genl_multicast_group *grp,
81                        struct sk_buff *skb, struct genl_info *info)
82  {
83 -       genl_notify(family, skb, genl_info_net(info),
84 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
85 +       genl_notify(family, skb, info, GROUP_ID(grp), GFP_KERNEL);
86 +#else
87 +       genl_notify(family, skb, genl_info_net(info),
88                     info->snd_portid, GROUP_ID(grp), info->nlhdr, GFP_KERNEL);
89 +#endif
90  }
91  
92  /**
93 diff --git a/datapath/linux/compat/include/linux/netfilter_ipv6.h b/datapath/linux/compat/include/linux/netfilter_ipv6.h
94 index 8d896fb..9f64002 100644
95 --- a/datapath/linux/compat/include/linux/netfilter_ipv6.h
96 +++ b/datapath/linux/compat/include/linux/netfilter_ipv6.h
97 @@ -13,7 +13,7 @@
98   * the callback parameter needs to be in the form that older kernels accept.
99   * We don't backport the other ipv6_ops as they're currently unused by OVS. */
100  struct ovs_nf_ipv6_ops {
101 -       int (*fragment)(struct sock *sk, struct sk_buff *skb,
102 +       int (*fragment)(NET_ARG(net) struct sock *sk, struct sk_buff *skb,
103                         int (*output)(OVS_VPORT_OUTPUT_PARAMS));
104  };
105  #define nf_ipv6_ops ovs_nf_ipv6_ops
106 diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h
107 index c283ad0..483662c 100644
108 --- a/datapath/linux/compat/include/net/ip.h
109 +++ b/datapath/linux/compat/include/net/ip.h
110 @@ -59,8 +59,20 @@ static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb)
111  #define ip_skb_dst_mtu rpl_ip_skb_dst_mtu
112  #endif /* HAVE_IP_SKB_DST_MTU */
113  
114 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
115 +#define NET_PARAM(x) struct net *x,
116 +#define NET_ARG(x) x,
117 +#define NET_DEV_NET(x) dev_net(x)
118 +#define NET_DECLARE_INIT(x,y)
119 +#else
120 +#define NET_PARAM(x)
121 +#define NET_ARG(x)
122 +#define NET_DEV_NET(x)
123 +#define NET_DECLARE_INIT(x,y) struct net *x = y;
124 +#endif
125 +
126  #ifdef HAVE_IP_FRAGMENT_TAKES_SOCK
127 -#define OVS_VPORT_OUTPUT_PARAMS struct sock *sock, struct sk_buff *skb
128 +#define OVS_VPORT_OUTPUT_PARAMS NET_PARAM(net) struct sock *sock, struct sk_buff *skb
129  #else
130  #define OVS_VPORT_OUTPUT_PARAMS struct sk_buff *skb
131  #endif
132 @@ -82,12 +94,13 @@ static inline bool ip_defrag_user_in_between(u32 user,
133  #endif /* < v4.2 */
134  
135  #ifndef HAVE_IP_DO_FRAGMENT
136 -static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb,
137 +static inline int rpl_ip_do_fragment(NET_PARAM(net) struct sock *sk, struct sk_buff *skb,
138                                      int (*output)(OVS_VPORT_OUTPUT_PARAMS))
139  {
140         unsigned int mtu = ip_skb_dst_mtu(skb);
141         struct iphdr *iph = ip_hdr(skb);
142         struct rtable *rt = skb_rtable(skb);
143 +       NET_DECLARE_INIT(net, dev_net(dev));
144         struct net_device *dev = rt->dst.dev;
145  
146         if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) ||
147 @@ -95,7 +108,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb,
148                       IPCB(skb)->frag_max_size > mtu))) {
149  
150                 pr_warn("Dropping packet in ip_do_fragment()\n");
151 -               IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
152 +               IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
153                 kfree_skb(skb);
154                 return -EMSGSIZE;
155         }
156 diff --git a/datapath/linux/compat/include/net/ip6_tunnel.h b/datapath/linux/compat/include/net/ip6_tunnel.h
157 index ce65087..eacf9ca 100644
158 --- a/datapath/linux/compat/include/net/ip6_tunnel.h
159 +++ b/datapath/linux/compat/include/net/ip6_tunnel.h
160 @@ -17,11 +17,15 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
161  
162         pkt_len = skb->len - skb_inner_network_offset(skb);
163         /* TODO: Fix GSO for ipv6 */
164 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
165 +       err = ip6_local_out(dev_net(dev), sk, skb);
166 +#else
167  #ifdef HAVE_IP6_LOCAL_OUT_SK
168         err = ip6_local_out_sk(sk, skb);
169  #else
170         err = ip6_local_out(skb);
171  #endif
172 +#endif /* >= kernel 4.4 */
173         if (net_xmit_eval(err) != 0)
174                 pkt_len = net_xmit_eval(err);
175         else
176 diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h
177 index 75a5a7a..589cc0d 100644
178 --- a/datapath/linux/compat/include/net/vxlan.h
179 +++ b/datapath/linux/compat/include/net/vxlan.h
180 @@ -218,10 +218,20 @@ struct vxlan_dev {
181  struct net_device *rpl_vxlan_dev_create(struct net *net, const char *name,
182                                     u8 name_assign_type, struct vxlan_config *conf);
183  
184 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
185 +static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan,
186 +                                       unsigned short family)
187 +{
188 +       if (family == AF_INET6)
189 +               return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport;
190 +       return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport;
191 +}
192 +#else
193  static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan)
194  {
195         return inet_sk(vxlan->vn_sock->sock->sk)->inet_sport;
196  }
197 +#endif
198  
199  static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
200                                                      netdev_features_t features)
201 diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c
202 index 86d225e..6b1e3a3 100644
203 --- a/datapath/linux/compat/stt.c
204 +++ b/datapath/linux/compat/stt.c
205 @@ -1544,7 +1544,11 @@ static void clean_percpu(struct work_struct *work)
206  }
207  
208  #ifdef HAVE_NF_HOOKFN_ARG_OPS
209 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
210 +#define FIRST_PARAM void *priv
211 +#else
212  #define FIRST_PARAM const struct nf_hook_ops *ops
213 +#endif /* >= kernel 4.4 */
214  #else
215  #define FIRST_PARAM unsigned int hooknum
216  #endif
217 @@ -1592,7 +1596,9 @@ static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM)
218  
219  static struct nf_hook_ops nf_hook_ops __read_mostly = {
220         .hook           = nf_ip_hook,
221 +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)
222         .owner          = THIS_MODULE,
223 +#endif
224         .pf             = NFPROTO_IPV4,
225         .hooknum        = NF_INET_LOCAL_IN,
226         .priority       = INT_MAX,
227 diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
228 index c05f5d4..3cbb568 100644
229 --- a/datapath/vport-vxlan.c
230 +++ b/datapath/vport-vxlan.c
231 @@ -153,7 +153,12 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
232  {
233         struct vxlan_dev *vxlan = netdev_priv(vport->dev);
234         struct net *net = ovs_dp_get_net(vport->dp);
235 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
236 +       unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info);
237 +       __be16 dst_port = vxlan_dev_dst_port(vxlan, family);
238 +#else
239         __be16 dst_port = vxlan_dev_dst_port(vxlan);
240 +#endif
241         __be16 src_port;
242         int port_min;
243         int port_max;
244 -- 
245 1.9.1
246