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 |
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 > } >
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.
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 --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 }