diff mbox series

[ovs-dev,v3] datapath: support upstream ndo_udp_tunnel_add in net_device_ops

Message ID 1533371496-26588-1-git-send-email-wenxu@ucloud.cn
State Accepted
Headers show
Series [ovs-dev,v3] datapath: support upstream ndo_udp_tunnel_add in net_device_ops | expand

Commit Message

wenxu Aug. 4, 2018, 8:31 a.m. UTC
From: wenxu <wenxu@ucloud.cn>

It makes datapath can support both ndo_add_udp_tunnel_port and
ndo_add_vxlan/geneve_port. The newer kernels don't support vxlan/geneve
specific NDO's anymore

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 acinclude.m4                                   |  1 +
 datapath/linux/compat/geneve.c                 | 41 ++++++++++++++++++--
 datapath/linux/compat/include/net/udp_tunnel.h | 14 +++++++
 datapath/linux/compat/vxlan.c                  | 52 ++++++++++++++++++++++++--
 4 files changed, 102 insertions(+), 6 deletions(-)

Comments

Gregory Rose Aug. 7, 2018, 8:53 p.m. UTC | #1
On 8/4/2018 1:31 AM, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
>
> It makes datapath can support both ndo_add_udp_tunnel_port and
> ndo_add_vxlan/geneve_port. The newer kernels don't support vxlan/geneve
> specific NDO's anymore
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>

LGTM

Reviewed-by: Greg Rose <gvrose8192@gmail.com>
Tested-by: Greg Rose <gvrose8192@gmail.com>

> ---
>   acinclude.m4                                   |  1 +
>   datapath/linux/compat/geneve.c                 | 41 ++++++++++++++++++--
>   datapath/linux/compat/include/net/udp_tunnel.h | 14 +++++++
>   datapath/linux/compat/vxlan.c                  | 52 ++++++++++++++++++++++++--
>   4 files changed, 102 insertions(+), 6 deletions(-)
>
> diff --git a/acinclude.m4 b/acinclude.m4
> index d6e0d33..7899307 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -553,6 +553,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
>                     [OVS_DEFINE([USE_UPSTREAM_TUNNEL_GSO])])
>     OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_add_vxlan_port])
>     OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_add_geneve_port])
> +  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_udp_tunnel_add])
>     OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netdev_features_t])
>     dnl Ubuntu kernel 3.13 has defined this struct but not used for netdev->tstats.
>     dnl So check type of tstats.
> diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
> index 435a23f..5b5bbae 100644
> --- a/datapath/linux/compat/geneve.c
> +++ b/datapath/linux/compat/geneve.c
> @@ -432,6 +432,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs)
>   		if (dev->netdev_ops->ndo_add_geneve_port)
>   			dev->netdev_ops->ndo_add_geneve_port(dev, sa_family,
>   					port);
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +		struct udp_tunnel_info ti;
> +		ti.type = UDP_TUNNEL_TYPE_GENEVE;
> +		ti.sa_family = sa_family;
> +		ti.port = inet_sk(sk)->inet_sport;
> +
> +		if (dev->netdev_ops->ndo_udp_tunnel_add)
> +			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
>   #endif
>   	}
>   	rcu_read_unlock();
> @@ -452,6 +460,14 @@ static void geneve_notify_del_rx_port(struct geneve_sock *gs)
>   		if (dev->netdev_ops->ndo_del_geneve_port)
>   			dev->netdev_ops->ndo_del_geneve_port(dev, sa_family,
>   					port);
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +		struct udp_tunnel_info ti;
> +		ti.type = UDP_TUNNEL_TYPE_GENEVE;
> +		ti.port = inet_sk(sk)->inet_sport;
> +		ti.sa_family = sa_family;
> +
> +		if (dev->netdev_ops->ndo_udp_tunnel_del)
> +			dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti);
>   #endif
>   	}
>   
> @@ -1301,9 +1317,9 @@ static struct device_type geneve_type = {
>   	.name = "geneve",
>   };
>   
> -/* Calls the ndo_add_geneve_port of the caller in order to
> - * supply the listening GENEVE udp ports. Callers are expected
> - * to implement the ndo_add_geneve_port.
> +/* Calls the ndo_add_geneve_port or ndo_udp_tunnel_add of the caller
> + * in order to supply the listening GENEVE udp ports. Callers are
> + * expected to implement the ndo_add_geneve_port.
>    */
>   static void geneve_push_rx_ports(struct net_device *dev)
>   {
> @@ -1326,6 +1342,25 @@ static void geneve_push_rx_ports(struct net_device *dev)
>   		dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port);
>   	}
>   	rcu_read_unlock();
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +	struct net *net = dev_net(dev);
> +	struct geneve_net *gn = net_generic(net, geneve_net_id);
> +	struct geneve_sock *gs;
> +	struct sock *sk;
> +
> +	if (!dev->netdev_ops->ndo_udp_tunnel_add)
> +		return;
> +
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(gs, &gn->sock_list, list) {
> +		struct udp_tunnel_info ti;
> +		ti.type = UDP_TUNNEL_TYPE_GENEVE;
> +		sk = gs->sock->sk;
> +		ti.port = inet_sk(sk)->inet_sport;
> +		ti.sa_family = sk->sk_family;
> +		dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
> +	}
> +	rcu_read_unlock();
>   #endif
>   }
>   
> diff --git a/datapath/linux/compat/include/net/udp_tunnel.h b/datapath/linux/compat/include/net/udp_tunnel.h
> index 6b5e540..6e40633 100644
> --- a/datapath/linux/compat/include/net/udp_tunnel.h
> +++ b/datapath/linux/compat/include/net/udp_tunnel.h
> @@ -43,6 +43,20 @@ struct udp_port_cfg {
>   				ipv6_v6only:1;
>   };
>   
> +#ifdef HAVE_NDO_UDP_TUNNEL_ADD
> +enum udp_parsable_tunnel_type {
> +	UDP_TUNNEL_TYPE_VXLAN,      /* RFC 7348 */
> +	UDP_TUNNEL_TYPE_GENEVE,     /* draft-ietf-nvo3-geneve */
> +	UDP_TUNNEL_TYPE_VXLAN_GPE,  /* draft-ietf-nvo3-vxlan-gpe */
> +};
> +
> +struct udp_tunnel_info {
> +	unsigned short type;
> +	sa_family_t sa_family;
> +	__be16 port;
> +};
> +#endif
> +
>   #define udp_sock_create4 rpl_udp_sock_create4
>   int rpl_udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
>   		     struct socket **sockp);
> diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
> index 7f5d5ce..57b7866 100644
> --- a/datapath/linux/compat/vxlan.c
> +++ b/datapath/linux/compat/vxlan.c
> @@ -396,6 +396,17 @@ static void vxlan_notify_add_rx_port(struct vxlan_sock *vs)
>   		if (dev->netdev_ops->ndo_add_vxlan_port)
>   			dev->netdev_ops->ndo_add_vxlan_port(dev, sa_family,
>   					port);
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +		struct udp_tunnel_info ti;
> +		if (vs->flags & VXLAN_F_GPE)
> +			ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
> +		else
> +			ti.type = UDP_TUNNEL_TYPE_VXLAN;
> +		ti.sa_family = sa_family;
> +		ti.port = inet_sk(sk)->inet_sport;
> +
> +		if (dev->netdev_ops->ndo_udp_tunnel_add)
> +			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
>   #endif
>   	}
>   	rcu_read_unlock();
> @@ -417,6 +428,17 @@ static void vxlan_notify_del_rx_port(struct vxlan_sock *vs)
>   		if (dev->netdev_ops->ndo_del_vxlan_port)
>   			dev->netdev_ops->ndo_del_vxlan_port(dev, sa_family,
>   					port);
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +		struct udp_tunnel_info ti;
> +		if (vs->flags & VXLAN_F_GPE)
> +			ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
> +		else
> +			ti.type = UDP_TUNNEL_TYPE_VXLAN;
> +		ti.port = inet_sk(sk)->inet_sport;
> +		ti.sa_family = sa_family;
> +
> +		if (dev->netdev_ops->ndo_udp_tunnel_del)
> +			dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti);
>   #endif
>   	}
>   	rcu_read_unlock();
> @@ -1518,9 +1540,9 @@ static struct device_type vxlan_type = {
>   	.name = "vxlan",
>   };
>   
> -/* Calls the ndo_add_vxlan_port of the caller in order to
> - * supply the listening VXLAN udp ports. Callers are expected
> - * to implement the ndo_add_vxlan_port.
> +/* Calls the ndo_add_vxlan_port or ndo_udp_tunnel_add of the caller
> + * in order to supply the listening VXLAN udp ports. Callers are
> + * expected to implement the ndo_add_vxlan_port.
>    */
>   static void vxlan_push_rx_ports(struct net_device *dev)
>   {
> @@ -1545,6 +1567,30 @@ static void vxlan_push_rx_ports(struct net_device *dev)
>   		}
>   	}
>   	spin_unlock(&vn->sock_lock);
> +#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
> +	struct vxlan_sock *vs;
> +	struct net *net = dev_net(dev);
> +	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
> +	unsigned int i;
> +
> +	if (!dev->netdev_ops->ndo_udp_tunnel_add)
> +		return;
> +
> +	spin_lock(&vn->sock_lock);
> +	for (i = 0; i < PORT_HASH_SIZE; ++i) {
> +		hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist) {
> +			struct udp_tunnel_info ti;
> +			if (vs->flags & VXLAN_F_GPE)
> +				ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
> +			else
> +				ti.type = UDP_TUNNEL_TYPE_VXLAN;
> +			ti.port = inet_sk(vs->sock->sk)->inet_sport;
> +			ti.sa_family = vxlan_get_sk_family(vs);
> +
> +			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
> +		}
> +	}
> +	spin_unlock(&vn->sock_lock);
>   #endif
>   }
>
Ben Pfaff Aug. 7, 2018, 10:08 p.m. UTC | #2
On Tue, Aug 07, 2018 at 01:53:15PM -0700, Gregory Rose wrote:
> On 8/4/2018 1:31 AM, wenxu@ucloud.cn wrote:
> >From: wenxu <wenxu@ucloud.cn>
> >
> >It makes datapath can support both ndo_add_udp_tunnel_port and
> >ndo_add_vxlan/geneve_port. The newer kernels don't support vxlan/geneve
> >specific NDO's anymore
> >
> >Signed-off-by: wenxu <wenxu@ucloud.cn>
> 
> LGTM
> 
> Reviewed-by: Greg Rose <gvrose8192@gmail.com>
> Tested-by: Greg Rose <gvrose8192@gmail.com>

Applied to master.  If it should be backported, please let me know.
Gregory Rose Aug. 7, 2018, 10:10 p.m. UTC | #3
On 8/7/2018 3:08 PM, Ben Pfaff wrote:
> On Tue, Aug 07, 2018 at 01:53:15PM -0700, Gregory Rose wrote:
>> On 8/4/2018 1:31 AM, wenxu@ucloud.cn wrote:
>>> From: wenxu <wenxu@ucloud.cn>
>>>
>>> It makes datapath can support both ndo_add_udp_tunnel_port and
>>> ndo_add_vxlan/geneve_port. The newer kernels don't support vxlan/geneve
>>> specific NDO's anymore
>>>
>>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>> LGTM
>>
>> Reviewed-by: Greg Rose <gvrose8192@gmail.com>
>> Tested-by: Greg Rose <gvrose8192@gmail.com>
> Applied to master.  If it should be backported, please let me know.

It will only apply to branches with erspan so I think 2.10 is as far 
back as it can go.

Thanks,

- Greg
diff mbox series

Patch

diff --git a/acinclude.m4 b/acinclude.m4
index d6e0d33..7899307 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -553,6 +553,7 @@  AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
                   [OVS_DEFINE([USE_UPSTREAM_TUNNEL_GSO])])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_add_vxlan_port])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_add_geneve_port])
+  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_udp_tunnel_add])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netdev_features_t])
   dnl Ubuntu kernel 3.13 has defined this struct but not used for netdev->tstats.
   dnl So check type of tstats.
diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
index 435a23f..5b5bbae 100644
--- a/datapath/linux/compat/geneve.c
+++ b/datapath/linux/compat/geneve.c
@@ -432,6 +432,14 @@  static void geneve_notify_add_rx_port(struct geneve_sock *gs)
 		if (dev->netdev_ops->ndo_add_geneve_port)
 			dev->netdev_ops->ndo_add_geneve_port(dev, sa_family,
 					port);
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+		struct udp_tunnel_info ti;
+		ti.type = UDP_TUNNEL_TYPE_GENEVE;
+		ti.sa_family = sa_family;
+		ti.port = inet_sk(sk)->inet_sport;
+
+		if (dev->netdev_ops->ndo_udp_tunnel_add)
+			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
 #endif
 	}
 	rcu_read_unlock();
@@ -452,6 +460,14 @@  static void geneve_notify_del_rx_port(struct geneve_sock *gs)
 		if (dev->netdev_ops->ndo_del_geneve_port)
 			dev->netdev_ops->ndo_del_geneve_port(dev, sa_family,
 					port);
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+		struct udp_tunnel_info ti;
+		ti.type = UDP_TUNNEL_TYPE_GENEVE;
+		ti.port = inet_sk(sk)->inet_sport;
+		ti.sa_family = sa_family;
+
+		if (dev->netdev_ops->ndo_udp_tunnel_del)
+			dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti);
 #endif
 	}
 
@@ -1301,9 +1317,9 @@  static struct device_type geneve_type = {
 	.name = "geneve",
 };
 
-/* Calls the ndo_add_geneve_port of the caller in order to
- * supply the listening GENEVE udp ports. Callers are expected
- * to implement the ndo_add_geneve_port.
+/* Calls the ndo_add_geneve_port or ndo_udp_tunnel_add of the caller
+ * in order to supply the listening GENEVE udp ports. Callers are
+ * expected to implement the ndo_add_geneve_port.
  */
 static void geneve_push_rx_ports(struct net_device *dev)
 {
@@ -1326,6 +1342,25 @@  static void geneve_push_rx_ports(struct net_device *dev)
 		dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port);
 	}
 	rcu_read_unlock();
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+	struct net *net = dev_net(dev);
+	struct geneve_net *gn = net_generic(net, geneve_net_id);
+	struct geneve_sock *gs;
+	struct sock *sk;
+
+	if (!dev->netdev_ops->ndo_udp_tunnel_add)
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(gs, &gn->sock_list, list) {
+		struct udp_tunnel_info ti;
+		ti.type = UDP_TUNNEL_TYPE_GENEVE;
+		sk = gs->sock->sk;
+		ti.port = inet_sk(sk)->inet_sport;
+		ti.sa_family = sk->sk_family;
+		dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
+	}
+	rcu_read_unlock();
 #endif
 }
 
diff --git a/datapath/linux/compat/include/net/udp_tunnel.h b/datapath/linux/compat/include/net/udp_tunnel.h
index 6b5e540..6e40633 100644
--- a/datapath/linux/compat/include/net/udp_tunnel.h
+++ b/datapath/linux/compat/include/net/udp_tunnel.h
@@ -43,6 +43,20 @@  struct udp_port_cfg {
 				ipv6_v6only:1;
 };
 
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+enum udp_parsable_tunnel_type {
+	UDP_TUNNEL_TYPE_VXLAN,      /* RFC 7348 */
+	UDP_TUNNEL_TYPE_GENEVE,     /* draft-ietf-nvo3-geneve */
+	UDP_TUNNEL_TYPE_VXLAN_GPE,  /* draft-ietf-nvo3-vxlan-gpe */
+};
+
+struct udp_tunnel_info {
+	unsigned short type;
+	sa_family_t sa_family;
+	__be16 port;
+};
+#endif
+
 #define udp_sock_create4 rpl_udp_sock_create4
 int rpl_udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
 		     struct socket **sockp);
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index 7f5d5ce..57b7866 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -396,6 +396,17 @@  static void vxlan_notify_add_rx_port(struct vxlan_sock *vs)
 		if (dev->netdev_ops->ndo_add_vxlan_port)
 			dev->netdev_ops->ndo_add_vxlan_port(dev, sa_family,
 					port);
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+		struct udp_tunnel_info ti;
+		if (vs->flags & VXLAN_F_GPE)
+			ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
+		else
+			ti.type = UDP_TUNNEL_TYPE_VXLAN;
+		ti.sa_family = sa_family;
+		ti.port = inet_sk(sk)->inet_sport;
+
+		if (dev->netdev_ops->ndo_udp_tunnel_add)
+			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
 #endif
 	}
 	rcu_read_unlock();
@@ -417,6 +428,17 @@  static void vxlan_notify_del_rx_port(struct vxlan_sock *vs)
 		if (dev->netdev_ops->ndo_del_vxlan_port)
 			dev->netdev_ops->ndo_del_vxlan_port(dev, sa_family,
 					port);
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+		struct udp_tunnel_info ti;
+		if (vs->flags & VXLAN_F_GPE)
+			ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
+		else
+			ti.type = UDP_TUNNEL_TYPE_VXLAN;
+		ti.port = inet_sk(sk)->inet_sport;
+		ti.sa_family = sa_family;
+
+		if (dev->netdev_ops->ndo_udp_tunnel_del)
+			dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti);
 #endif
 	}
 	rcu_read_unlock();
@@ -1518,9 +1540,9 @@  static struct device_type vxlan_type = {
 	.name = "vxlan",
 };
 
-/* Calls the ndo_add_vxlan_port of the caller in order to
- * supply the listening VXLAN udp ports. Callers are expected
- * to implement the ndo_add_vxlan_port.
+/* Calls the ndo_add_vxlan_port or ndo_udp_tunnel_add of the caller
+ * in order to supply the listening VXLAN udp ports. Callers are
+ * expected to implement the ndo_add_vxlan_port.
  */
 static void vxlan_push_rx_ports(struct net_device *dev)
 {
@@ -1545,6 +1567,30 @@  static void vxlan_push_rx_ports(struct net_device *dev)
 		}
 	}
 	spin_unlock(&vn->sock_lock);
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+	struct vxlan_sock *vs;
+	struct net *net = dev_net(dev);
+	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+	unsigned int i;
+
+	if (!dev->netdev_ops->ndo_udp_tunnel_add)
+		return;
+
+	spin_lock(&vn->sock_lock);
+	for (i = 0; i < PORT_HASH_SIZE; ++i) {
+		hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist) {
+			struct udp_tunnel_info ti;
+			if (vs->flags & VXLAN_F_GPE)
+				ti.type = UDP_TUNNEL_TYPE_VXLAN_GPE;
+			else
+				ti.type = UDP_TUNNEL_TYPE_VXLAN;
+			ti.port = inet_sk(vs->sock->sk)->inet_sport;
+			ti.sa_family = vxlan_get_sk_family(vs);
+
+			dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti);
+		}
+	}
+	spin_unlock(&vn->sock_lock);
 #endif
 }