From patchwork Thu Jun 30 08:06:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pravin Shelar X-Patchwork-Id: 642418 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rgBx30Z91z9s9n for ; Thu, 30 Jun 2016 18:07:51 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 1183B10709; Thu, 30 Jun 2016 01:07:21 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 90E1D106F7 for ; Thu, 30 Jun 2016 01:07:18 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id 28699161A73 for ; Thu, 30 Jun 2016 02:07:18 -0600 (MDT) X-ASG-Debug-ID: 1467274037-0b32371665ebdc0001-byXFYA Received: from mx3-pf2.cudamail.com ([192.168.14.1]) by bar6.cudamail.com with ESMTP id YQ6ngPVsv3lHCpzT (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 30 Jun 2016 02:07:17 -0600 (MDT) X-Barracuda-Envelope-From: pshelar@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.1 Received: from unknown (HELO relay5-d.mail.gandi.net) (217.70.183.197) by mx3-pf2.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 30 Jun 2016 08:07:17 -0000 Received-SPF: pass (mx3-pf2.cudamail.com: SPF record at ovn.org designates 217.70.183.197 as permitted sender) X-Barracuda-Apparent-Source-IP: 217.70.183.197 X-Barracuda-RBL-IP: 217.70.183.197 Received: from mfilter40-d.gandi.net (mfilter40-d.gandi.net [217.70.178.171]) by relay5-d.mail.gandi.net (Postfix) with ESMTP id C05DA41C0D4; Thu, 30 Jun 2016 10:07:15 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter40-d.gandi.net Received: from relay5-d.mail.gandi.net ([IPv6:::ffff:217.70.183.197]) by mfilter40-d.gandi.net (mfilter40-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id PZQfX9KSSQwi; Thu, 30 Jun 2016 10:07:14 +0200 (CEST) X-Originating-IP: 24.130.10.65 Received: from localhost.localdomain.localdomain (c-24-130-10-65.hsd1.ca.comcast.net [24.130.10.65]) (Authenticated sender: pshelar@ovn.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 452E941C0D2; Thu, 30 Jun 2016 10:07:12 +0200 (CEST) X-CudaMail-Envelope-Sender: pshelar@ovn.org From: Pravin B Shelar To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V2-629001508 X-CudaMail-DTE: 063016 X-CudaMail-Originating-IP: 217.70.183.197 Date: Thu, 30 Jun 2016 01:06:25 -0700 X-ASG-Orig-Subj: [##CM-V2-629001508##][PATCH v2 08/24] datapath: backport: ip_tunnel: add support for setting flow label via collect metadata Message-Id: <1467274002-61390-8-git-send-email-pshelar@ovn.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1467274002-61390-1-git-send-email-pshelar@ovn.org> References: <1467274002-61390-1-git-send-email-pshelar@ovn.org> X-Barracuda-Connect: UNKNOWN[192.168.14.1] X-Barracuda-Start-Time: 1467274037 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH v2 08/24] datapath: backport: ip_tunnel: add support for setting flow label via collect metadata X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Update udp_tunnel6_xmit_skb(). Specificaly changes are related to setting ipv6 label. Upstream commit: commit 134611446dc657e1bbc73ca0e4e6b599df687db0 Author: Daniel Borkmann ip_tunnel: add support for setting flow label via collect metadata This patch extends udp_tunnel6_xmit_skb() to pass in the IPv6 flow label from call sites. Currently, there's no such option and it's always set to zero when writing ip6_flow_hdr(). Add a label member to ip_tunnel_key, so that flow-based tunnels via collect metadata frontends can make use of it. vxlan and geneve will be converted to add flow label support separately. Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller Signed-off-by: Pravin B Shelar Acked-by: Jesse Gross --- acinclude.m4 | 9 +++++---- datapath/linux/compat/include/net/dst_metadata.h | 3 ++- datapath/linux/compat/include/net/ip_tunnels.h | 4 +++- datapath/linux/compat/include/net/ipv6.h | 23 +++++++++++++++++++++++ datapath/linux/compat/include/net/udp_tunnel.h | 2 +- datapath/linux/compat/include/net/vxlan.h | 1 + datapath/linux/compat/udp_tunnel.c | 4 ++-- datapath/linux/compat/vxlan.c | 11 +++++++---- 8 files changed, 44 insertions(+), 13 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 05b5f48..f833812 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -432,8 +432,11 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/inetpeer.h], [vif], [OVS_DEFINE([HAVE_INETPEER_VIF_SUPPORT])]) - OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], [iptunnel_pull_offloads], - [OVS_DEFINE([HAVE_METADATA_DST])]) + OVS_FIND_FIELD_IFELSE([$KSRC/include/net/ip_tunnels.h], [ip_tunnel_key], + [label], + [OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], + [iptunnel_pull_offloads], + [OVS_DEFINE([HAVE_METADATA_DST])])]) OVS_GREP_IFELSE([$KSRC/include/linux/net.h], [sock_create_kern.*net], [OVS_DEFINE([HAVE_SOCK_CREATE_KERN_NET])]) @@ -611,8 +614,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_v4_check]) OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_set_csum]) OVS_GREP_IFELSE([$KSRC/include/net/udp_tunnel.h], [udp_tunnel_gro_complete]) - OVS_GREP_IFELSE([$KSRC/include/net/udp_tunnel.h], [ipv6_v6only], - [OVS_DEFINE([HAVE_UDP_TUNNEL_IPV6])]) OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [ignore_df], [OVS_DEFINE([HAVE_IGNORE_DF_RENAME])]) diff --git a/datapath/linux/compat/include/net/dst_metadata.h b/datapath/linux/compat/include/net/dst_metadata.h index b54cfc0..538a7c9 100644 --- a/datapath/linux/compat/include/net/dst_metadata.h +++ b/datapath/linux/compat/include/net/dst_metadata.h @@ -55,7 +55,7 @@ static inline void ovs_ip_tun_rx_dst(struct ip_tunnel_info *tun_info, ovs_tun_rx_dst(tun_info, md_size); ip_tunnel_key_init(&tun_info->key, - iph->saddr, iph->daddr, iph->tos, iph->ttl, + iph->saddr, iph->daddr, iph->tos, iph->ttl, 0, 0, 0, tunnel_id, flags); } @@ -79,6 +79,7 @@ static inline void ovs_ipv6_tun_rx_dst(struct ip_tunnel_info *info, info->key.tos = ipv6_get_dsfield(ip6h); info->key.ttl = ip6h->hop_limit; + info->key.label = ip6_flowlabel(ip6h); } void ovs_ip_tunnel_rcv(struct net_device *dev, struct sk_buff *skb, diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h index b9fa76f..7ee0875 100644 --- a/datapath/linux/compat/include/net/ip_tunnels.h +++ b/datapath/linux/compat/include/net/ip_tunnels.h @@ -126,6 +126,7 @@ struct ip_tunnel_key { __be16 tun_flags; u8 tos; /* TOS for IPv4, TC for IPv6 */ u8 ttl; /* TTL for IPv4, HL for IPv6 */ + __be32 label; /* Flow Label for IPv6 */ __be16 tp_src; __be16 tp_dst; }; @@ -165,7 +166,7 @@ static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info, static inline void ip_tunnel_key_init(struct ip_tunnel_key *key, __be32 saddr, __be32 daddr, - u8 tos, u8 ttl, + u8 tos, u8 ttl, __be32 label, __be16 tp_src, __be16 tp_dst, __be64 tun_id, __be16 tun_flags) { @@ -176,6 +177,7 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key, 0, IP_TUNNEL_KEY_IPV4_PAD_LEN); key->tos = tos; key->ttl = ttl; + key->label = label; key->tun_flags = tun_flags; /* For the tunnel types on the top of IPsec, the tp_src and tp_dst of diff --git a/datapath/linux/compat/include/net/ipv6.h b/datapath/linux/compat/include/net/ipv6.h index ac1564b..dbb66e1 100644 --- a/datapath/linux/compat/include/net/ipv6.h +++ b/datapath/linux/compat/include/net/ipv6.h @@ -54,4 +54,27 @@ static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 unused) } #endif +#define ip6_flowlabel rpl_ip6_flowlabel +static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr) +{ + return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK; +} + +#ifndef IPV6_TCLASS_SHIFT +#define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK) +#define IPV6_TCLASS_SHIFT 20 +#endif + +#define ip6_tclass rpl_ip6_tclass +static inline u8 ip6_tclass(__be32 flowinfo) +{ + return ntohl(flowinfo & IPV6_TCLASS_MASK) >> IPV6_TCLASS_SHIFT; +} + +#define ip6_make_flowinfo rpl_ip6_make_flowinfo +static inline __be32 ip6_make_flowinfo(unsigned int tclass, __be32 flowlabel) +{ + return htonl(tclass << IPV6_TCLASS_SHIFT) | flowlabel; +} + #endif diff --git a/datapath/linux/compat/include/net/udp_tunnel.h b/datapath/linux/compat/include/net/udp_tunnel.h index 065b95a..17f829d 100644 --- a/datapath/linux/compat/include/net/udp_tunnel.h +++ b/datapath/linux/compat/include/net/udp_tunnel.h @@ -81,7 +81,7 @@ int rpl_udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, struct net_device *dev, struct in6_addr *saddr, struct in6_addr *daddr, - __u8 prio, __u8 ttl, __be16 src_port, + __u8 prio, __u8 ttl, __be32 label, __be16 src_port, __be16 dst_port, bool nocheck); #endif diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h index 589e6f2..fa64e38 100644 --- a/datapath/linux/compat/include/net/vxlan.h +++ b/datapath/linux/compat/include/net/vxlan.h @@ -167,6 +167,7 @@ struct vxlan_config { __u16 port_max; __u8 tos; __u8 ttl; + __be32 label; u32 flags; unsigned long age_interval; unsigned int addrmax; diff --git a/datapath/linux/compat/udp_tunnel.c b/datapath/linux/compat/udp_tunnel.c index f72e645..af606a9 100644 --- a/datapath/linux/compat/udp_tunnel.c +++ b/datapath/linux/compat/udp_tunnel.c @@ -228,7 +228,7 @@ int rpl_udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, struct net_device *dev, struct in6_addr *saddr, struct in6_addr *daddr, - __u8 prio, __u8 ttl, __be16 src_port, + __u8 prio, __u8 ttl, __be32 label, __be16 src_port, __be16 dst_port, bool nocheck) { struct udphdr *uh; @@ -253,7 +253,7 @@ int rpl_udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, __skb_push(skb, sizeof(*ip6h)); skb_reset_network_header(skb); ip6h = ipv6_hdr(skb); - ip6_flow_hdr(ip6h, prio, htonl(0)); + ip6_flow_hdr(ip6h, prio, label); ip6h->payload_len = htons(skb->len); ip6h->nexthdr = IPPROTO_UDP; ip6h->hop_limit = ttl; diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index b0d156f..3cdbbda 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -1027,7 +1027,7 @@ static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, u32 vxflags, static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, struct net_device *dev, struct in6_addr *saddr, - struct in6_addr *daddr, __u8 prio, __u8 ttl, + struct in6_addr *daddr, __u8 prio, __u8 ttl, __be32 label, __be16 src_port, __be16 dst_port, __be32 vni, struct vxlan_metadata *md, bool xnet, u32 vxflags) { @@ -1112,7 +1112,7 @@ static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk, ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB)); udp_tunnel6_xmit_skb(dst, sk, skb, dev, saddr, daddr, prio, - ttl, src_port, dst_port, + ttl, label, src_port, dst_port, !!(vxflags & VXLAN_F_UDP_ZERO_CSUM6_TX)); return 0; err: @@ -1219,7 +1219,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, struct vxlan_metadata _md; struct vxlan_metadata *md = &_md; __be16 src_port = 0, dst_port; - u32 vni; + u32 vni, label; __be16 df = 0; __u8 tos, ttl; int err; @@ -1269,6 +1269,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, if (tos == 1) tos = ip_tunnel_get_dsfield(old_iph, skb); + label = vxlan->cfg.label; src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min, vxlan->cfg.port_max, true); @@ -1280,6 +1281,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ttl = info->key.ttl; tos = info->key.tos; + label = info->key.label; if (info->options_len) md = ip_tunnel_info_opts(info); @@ -1356,6 +1358,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr; fl6.flowi6_mark = skb->mark; fl6.flowi6_proto = IPPROTO_UDP; + fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label); #ifdef HAVE_IPV6_DST_LOOKUP_NET if (ipv6_stub->ipv6_dst_lookup(vxlan->net, sk, &ndst, &fl6)) { @@ -1400,7 +1403,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ttl = ttl ? : ip6_dst_hoplimit(ndst); err = vxlan6_xmit_skb(ndst, sk, skb, dev, &fl6.saddr, &fl6.daddr, - 0, ttl, src_port, dst_port, htonl(vni << 8), md, + 0, ttl, label, src_port, dst_port, htonl(vni << 8), md, !net_eq(vxlan->net, dev_net(vxlan->dev)), flags); #endif