On Tue, Sep 16, 2014 at 10:44 AM, Thomas Graf <tg...@noironetworks.com> wrote: > Port datapath to work with kernrels up to 3.17 and use 3.16.2 as > the new kernel for CI testing. > > Tested with 3.14, 3.16.2, and net-next (3.17). > Thanks for working on this. I have couple of comments.
> Signed-off-by: Thomas Graf <tg...@noironetworks.com> > Co-authored-by: Madhu Challa <cha...@noironetworks.com> > --- > .travis.yml | 2 +- > .travis/build.sh | 6 ++-- > acinclude.m4 | 12 ++++++-- > datapath/linux/Modules.mk | 1 + > datapath/linux/compat/include/linux/if.h | 12 -------- > datapath/linux/compat/include/linux/netdevice.h | 14 ++++++++++ > datapath/linux/compat/include/linux/skbuff.h | 4 +++ > datapath/linux/compat/include/net/ip_tunnels.h | 2 +- > datapath/linux/compat/include/net/udp.h | 37 > +++++++++++++++++++++++++ > datapath/linux/compat/include/net/vxlan.h | 5 ++++ > datapath/linux/compat/ip_tunnels_core.c | 2 +- > datapath/linux/compat/vxlan.c | 3 +- > datapath/vport-geneve.c | 8 ++++-- > datapath/vport-gre.c | 2 +- > datapath/vport-internal_dev.c | 7 ++++- > datapath/vport-lisp.c | 2 +- > datapath/vport-netdev.c | 3 +- > datapath/vport-vxlan.c | 10 ++----- > 18 files changed, 96 insertions(+), 36 deletions(-) > create mode 100644 datapath/linux/compat/include/net/udp.h > > diff --git a/.travis.yml b/.travis.yml > index b66f821..4dfe15e 100644 > --- a/.travis.yml > +++ b/.travis.yml > @@ -7,7 +7,7 @@ before_install: ./.travis/prepare.sh > > env: > - OPTS="--disable-ssl" > - - TESTSUITE=1 KERNEL=1 OPTS="--with-linux=./linux-3.14.7" > + - TESTSUITE=1 KERNEL=1 OPTS="--with-linux=./linux-3.16.2" > - KERNEL=1 DPDK=1 OPTS="--with-dpdk=./dpdk-1.7.0/build" > > script: ./.travis/build.sh $OPTS > diff --git a/.travis/build.sh b/.travis/build.sh > index 0a23969..b7ce5a0 100755 > --- a/.travis/build.sh > +++ b/.travis/build.sh > @@ -7,9 +7,9 @@ CFLAGS="-Werror" > > function install_kernel() > { > - wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.7.tar.gz > - tar xzvf linux-3.14.7.tar.gz > /dev/null > - cd linux-3.14.7 > + wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.2.tar.gz > + tar xzvf linux-3.16.2.tar.gz > /dev/null > + cd linux-3.16.2 > make allmodconfig > make net/openvswitch/ > KERNELSRC=$(pwd) > diff --git a/acinclude.m4 b/acinclude.m4 > index e3a694b..6e31d88 100644 > --- a/acinclude.m4 > +++ b/acinclude.m4 > @@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ > AC_MSG_RESULT([$kversion]) > > if test "$version" -ge 3; then > - if test "$version" = 3 && test "$patchlevel" -le 14; then > + if test "$version" = 3 && test "$patchlevel" -le 17; then > : # Linux 3.x > else > - AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version > newer than 3.14.x is not supported (please refer to the FAQ for advice)]) > + AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version > newer than 3.17.x is not supported (please refer to the FAQ for advice)]) > fi > else > if test "$version" -le 1 || test "$patchlevel" -le 5 || test > "$sublevel" -le 31; then > @@ -370,6 +370,14 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ > > OVS_GREP_IFELSE([$KSRC/include/linux/openvswitch.h], > [openvswitch_handle_frame_hook], > [OVS_DEFINE([HAVE_RHEL_OVS_HOOK])]) > + OVS_GREP_IFELSE([$KSRC/include/net/vxlan.h], [bool xnet], > + [OVS_DEFINE([HAVE_VXLAN_XMIT_SKB_XNET_ARG])]) > + OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_flow_src_port], > + [OVS_DEFINE([HAVE_UDP_FLOW_SRC_PORT])]) > + OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [ignore_df:1], > + [OVS_DEFINE([HAVE_IGNORE_DF_RENAME])]) > + OVS_GREP_IFELSE([$KSRC/include/uapi/linux/netdevice.h], [NET_NAME_UNKNOWN], > + [OVS_DEFINE([HAVE_NET_NAME_UNKNOWN])]) > > OVS_CHECK_LOG2_H > > diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk > index f7c64e2..274b1f1 100644 > --- a/datapath/linux/Modules.mk > +++ b/datapath/linux/Modules.mk > @@ -72,6 +72,7 @@ openvswitch_headers += \ > linux/compat/include/net/ipv6.h \ > linux/compat/include/net/net_namespace.h \ > linux/compat/include/net/netlink.h \ > + linux/compat/include/net/udp.h \ > linux/compat/include/net/sock.h \ > linux/compat/include/net/vxlan.h \ > linux/compat/include/net/sctp/checksum.h > diff --git a/datapath/linux/compat/include/linux/if.h > b/datapath/linux/compat/include/linux/if.h > index c4c656c..3beb61d 100644 > --- a/datapath/linux/compat/include/linux/if.h > +++ b/datapath/linux/compat/include/linux/if.h > @@ -3,16 +3,4 @@ > > #include_next <linux/if.h> > > -#ifndef IFF_TX_SKB_SHARING > -#define IFF_TX_SKB_SHARING 0 > -#endif > - > -#ifndef IFF_OVS_DATAPATH > -#define IFF_OVS_DATAPATH 0 > -#endif > - > -#ifndef IFF_LIVE_ADDR_CHANGE > -#define IFF_LIVE_ADDR_CHANGE 0 > -#endif > - > #endif > diff --git a/datapath/linux/compat/include/linux/netdevice.h > b/datapath/linux/compat/include/linux/netdevice.h > index 5502288..d01434e 100644 > --- a/datapath/linux/compat/include/linux/netdevice.h > +++ b/datapath/linux/compat/include/linux/netdevice.h > @@ -8,6 +8,20 @@ struct net; > > #include <linux/version.h> > > +#ifndef IFF_TX_SKB_SHARING > +#define IFF_TX_SKB_SHARING 0 > +#endif > + > +#ifndef IFF_OVS_DATAPATH > +#define IFF_OVS_DATAPATH 0 > +#else > +#define HAVE_OVS_DATAPATH > +#endif > + > +#ifndef IFF_LIVE_ADDR_CHANGE > +#define IFF_LIVE_ADDR_CHANGE 0 > +#endif > + > #ifndef to_net_dev > #define to_net_dev(class) container_of(class, struct net_device, > NETDEV_DEV_MEMBER) > #endif > diff --git a/datapath/linux/compat/include/linux/skbuff.h > b/datapath/linux/compat/include/linux/skbuff.h > index 9abd582..8fce98c 100644 > --- a/datapath/linux/compat/include/linux/skbuff.h > +++ b/datapath/linux/compat/include/linux/skbuff.h > @@ -6,6 +6,10 @@ > #include <linux/jhash.h> > #include <linux/version.h> > > +#ifdef HAVE_IGNORE_DF_RENAME > +#define local_df ignore_df > +#endif > + We do reverse of this. i.e. define ignore_df for old kernels. So that ovs external module and upstream module code looks same. > #ifndef HAVE_SKB_COPY_FROM_LINEAR_DATA_OFFSET > static inline void skb_copy_from_linear_data_offset(const struct sk_buff > *skb, > const int offset, void > *to, > diff --git a/datapath/linux/compat/include/net/ip_tunnels.h > b/datapath/linux/compat/include/net/ip_tunnels.h > index 2a6470a..2a28a72 100644 > --- a/datapath/linux/compat/include/net/ip_tunnels.h > +++ b/datapath/linux/compat/include/net/ip_tunnels.h > @@ -36,7 +36,7 @@ struct tnl_ptk_info { > #define PACKET_RCVD 0 > #define PACKET_REJECT 1 > > -int iptunnel_xmit(struct rtable *rt, > +int iptunnel_xmit(struct sock *sk, struct rtable *rt, > struct sk_buff *skb, > __be32 src, __be32 dst, __u8 proto, > __u8 tos, __u8 ttl, __be16 df, bool xnet); > diff --git a/datapath/linux/compat/include/net/udp.h > b/datapath/linux/compat/include/net/udp.h > new file mode 100644 > index 0000000..88174ae > --- /dev/null > +++ b/datapath/linux/compat/include/net/udp.h > @@ -0,0 +1,37 @@ > +#ifndef __NET_UDP_WRAPPER_H > +#define __NET_UDP_WRAPPER_H 1 > + > +#include_next <net/udp.h> > + > +#ifndef HAVE_UDP_FLOW_SRC_PORT > +static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb, > + int min, int max, bool use_eth) > +{ > + u32 hash; > + > + if (min >= max) { > + /* Use default range */ > + inet_get_local_port_range(net, &min, &max); > + } > + > + hash = skb_get_hash(skb); > + if (unlikely(!hash) && use_eth) { > + /* Can't find a normal hash, caller has indicated an Ethernet > + * packet so use that to compute a hash. > + */ > + hash = jhash(skb->data, 2 * ETH_ALEN, > + (__force u32) skb->protocol); > + } > + > + /* Since this is being sent on the wire obfuscate hash a bit > + * to minimize possbility that any useful information to an > + * attacker is leaked. Only upper 16 bits are relevant in the > + * computation for 16 bit port value. > + */ > + hash ^= hash << 16; > + > + return htons((((u64) hash * (max - min)) >> 32) + min); > +} > +#endif > + > +#endif > diff --git a/datapath/linux/compat/include/net/vxlan.h > b/datapath/linux/compat/include/net/vxlan.h > index d64630b..2e56a9b 100644 > --- a/datapath/linux/compat/include/net/vxlan.h > +++ b/datapath/linux/compat/include/net/vxlan.h > @@ -19,8 +19,13 @@ static inline int rpl_vxlan_xmit_skb(struct vxlan_sock *vs, > return -ENOSYS; > } > > +#ifdef HAVE_VXLAN_XMIT_SKB_XNET_ARG > + return vxlan_xmit_skb(vs, rt, skb, src, dst, tos, ttl, df, > + src_port, dst_port, vni, false); > +#else > return vxlan_xmit_skb(vs, rt, skb, src, dst, tos, ttl, df, > src_port, dst_port, vni); > +#endif > } > > #define vxlan_xmit_skb rpl_vxlan_xmit_skb > diff --git a/datapath/linux/compat/ip_tunnels_core.c > b/datapath/linux/compat/ip_tunnels_core.c > index a70aefc..549df3d 100644 > --- a/datapath/linux/compat/ip_tunnels_core.c > +++ b/datapath/linux/compat/ip_tunnels_core.c > @@ -37,7 +37,7 @@ > #include "compat.h" > #include "gso.h" > > -int iptunnel_xmit(struct rtable *rt, > +int iptunnel_xmit(struct sock *sk, struct rtable *rt, > struct sk_buff *skb, > __be32 src, __be32 dst, __u8 proto, > __u8 tos, __u8 ttl, __be16 df, bool xnet) > diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c > index b8b8fa7..9278c37 100644 > --- a/datapath/linux/compat/vxlan.c > +++ b/datapath/linux/compat/vxlan.c > @@ -226,7 +226,8 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, > if (err) > return err; > > - return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, > false); > + return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP, > + tos, ttl, df, false); > } > > static void rcu_free_vs(struct rcu_head *rcu) > diff --git a/datapath/vport-geneve.c b/datapath/vport-geneve.c > index ce5b509..6ed1e1f 100644 > --- a/datapath/vport-geneve.c > +++ b/datapath/vport-geneve.c > @@ -132,12 +132,13 @@ static void geneve_build_header(const struct vport > *vport, > struct sk_buff *skb) > { > struct geneve_port *geneve_port = geneve_vport(vport); > + struct net *net = ovs_dp_get_net(vport->dp); > struct udphdr *udph = udp_hdr(skb); > struct genevehdr *geneveh = (struct genevehdr *)(udph + 1); > const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->egress_tun_info; > > udph->dest = inet_sport(geneve_port->sock->sk); > - udph->source = vxlan_src_port(1, USHRT_MAX, skb); > + udph->source = udp_flow_src_port(net, skb, 0, 0, true); > udph->check = 0; > udph->len = htons(skb->len - skb_transport_offset(skb)); > > @@ -423,7 +424,7 @@ static int geneve_send(struct vport *vport, struct > sk_buff *skb) > > df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; > > - sent_len = iptunnel_xmit(rt, skb, > + sent_len = iptunnel_xmit(skb->sk, rt, skb, > saddr, tun_key->ipv4_dst, > IPPROTO_UDP, tun_key->ipv4_tos, > tun_key->ipv4_ttl, > @@ -447,6 +448,7 @@ static int geneve_get_egress_tun_info(struct vport > *vport, struct sk_buff *skb, > struct ovs_tunnel_info *egress_tun_info) > { > struct geneve_port *geneve_port = geneve_vport(vport); > + struct net *net = ovs_dp_get_net(vport->dp); > > /* > * Get tp_src and tp_dst, refert to geneve_build_header(). > @@ -455,7 +457,7 @@ static int geneve_get_egress_tun_info(struct vport > *vport, struct sk_buff *skb, > ovs_dp_get_net(vport->dp), > OVS_CB(skb)->egress_tun_info, > IPPROTO_UDP, skb->mark, > - vxlan_src_port(1, USHRT_MAX, skb), > + udp_flow_src_port(net, skb, 0, 0, > true), > inet_sport(geneve_port->sock->sk)); > > } > diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c > index ce203b8..7decaa2 100644 > --- a/datapath/vport-gre.c > +++ b/datapath/vport-gre.c > @@ -194,7 +194,7 @@ static int __send(struct vport *vport, struct sk_buff > *skb, > df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; > skb->local_df = 1; > > - return iptunnel_xmit(rt, skb, saddr, > + return iptunnel_xmit(skb->sk, rt, skb, saddr, > tun_key->ipv4_dst, IPPROTO_GRE, > tun_key->ipv4_tos, > tun_key->ipv4_ttl, df, false); > diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c > index 8a454df..c9b35d3 100644 > --- a/datapath/vport-internal_dev.c > +++ b/datapath/vport-internal_dev.c > @@ -151,7 +151,7 @@ static void do_setup(struct net_device *netdev) > netdev->priv_flags &= ~IFF_TX_SKB_SHARING; > netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE; > netdev->destructor = internal_dev_destructor; > - SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops); > + netdev->ethtool_ops = &internal_dev_ethtool_ops; > netdev->tx_queue_len = 0; > > netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST | > @@ -188,8 +188,13 @@ static struct vport *internal_dev_create(const struct > vport_parms *parms) > > netdev_vport = netdev_vport_priv(vport); > > +#ifdef HAVE_NET_NAME_UNKNOWN > + netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), > + parms->name, NET_NAME_UNKNOWN, > do_setup); > +#else > netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), > parms->name, do_setup); > +#endif We can define compat alloc_netdev() to avoid #ifdef here. > if (!netdev_vport->dev) { > err = -ENOMEM; > goto error_free_vport; > diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c > index 3335aa5..d7b9b15 100644 > --- a/datapath/vport-lisp.c > +++ b/datapath/vport-lisp.c > @@ -498,7 +498,7 @@ static int lisp_send(struct vport *vport, struct sk_buff > *skb) > skb->local_df = 1; > > df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; > - sent_len = iptunnel_xmit(rt, skb, > + sent_len = iptunnel_xmit(skb->sk, rt, skb, > saddr, tun_key->ipv4_dst, > IPPROTO_UDP, tun_key->ipv4_tos, > tun_key->ipv4_ttl, df, false); > diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c > index c15923b..a00276b 100644 > --- a/datapath/vport-netdev.c > +++ b/datapath/vport-netdev.c > @@ -26,6 +26,7 @@ > #include <linux/rtnetlink.h> > #include <linux/skbuff.h> > #include <linux/openvswitch.h> > +#include <linux/netdevice.h> > > #include <net/llc.h> > > @@ -255,7 +256,7 @@ struct vport *ovs_netdev_get_vport(struct net_device *dev) > { > #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) || \ > defined HAVE_RHEL_OVS_HOOK > -#if IFF_OVS_DATAPATH != 0 > +#ifdef HAVE_OVS_DATAPATH > if (likely(dev->priv_flags & IFF_OVS_DATAPATH)) > #else > if (likely(rcu_access_pointer(dev->rx_handler) == netdev_frame_hook)) > diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c > index 34dd919..60379a0 100644 > --- a/datapath/vport-vxlan.c > +++ b/datapath/vport-vxlan.c > @@ -149,8 +149,6 @@ static int vxlan_tnl_send(struct vport *vport, struct > sk_buff *skb) > __be16 src_port; > __be32 saddr; > __be16 df; > - int port_min; > - int port_max; > int err; > > if (unlikely(!OVS_CB(skb)->egress_tun_info)) { > @@ -174,8 +172,7 @@ static int vxlan_tnl_send(struct vport *vport, struct > sk_buff *skb) > df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; > skb->local_df = 1; > > - inet_get_local_port_range(net, &port_min, &port_max); > - src_port = vxlan_src_port(port_min, port_max, skb); > + src_port = udp_flow_src_port(net, skb, 0, 0, true); > > err = vxlan_xmit_skb(vxlan_port->vs, rt, skb, > saddr, tun_key->ipv4_dst, > @@ -196,11 +193,8 @@ static int vxlan_get_egress_tun_info(struct vport > *vport, struct sk_buff *skb, > struct vxlan_port *vxlan_port = vxlan_vport(vport); > __be16 dst_port = inet_sport(vxlan_port->vs->sock->sk); > __be16 src_port; > - int port_min; > - int port_max; > > - inet_get_local_port_range(net, &port_min, &port_max); > - src_port = vxlan_src_port(port_min, port_max, skb); > + src_port = udp_flow_src_port(net, skb, 0, 0, true); > > return ovs_tunnel_get_egress_info(egress_tun_info, net, > OVS_CB(skb)->egress_tun_info, > -- > 1.9.3 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev