[ovs-dev] [PATCH v3] datapath: support upstream ndo_udp_tunnel_add in net_device_ops
Gregory Rose
gvrose8192 at gmail.com
Tue Aug 7 20:53:15 UTC 2018
On 8/4/2018 1:31 AM, wenxu at ucloud.cn wrote:
> From: wenxu <wenxu at 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 at ucloud.cn>
LGTM
Reviewed-by: Greg Rose <gvrose8192 at gmail.com>
Tested-by: Greg Rose <gvrose8192 at 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
> }
>
More information about the dev
mailing list