[ovs-dev] [PATCH 05/12] datapath: compat: Update udp-tunnel-xmit

Pravin B Shelar pshelar at ovn.org
Wed May 4 23:35:32 UTC 2016


Update udp_tunnel6_xmit_skb(). Specificaly changes are
related to setting ipv6 label.

Signed-off-by: Pravin B Shelar <pshelar at ovn.org>
---
 datapath/linux/compat/include/net/ip_tunnels.h |  1 +
 datapath/linux/compat/include/net/ipv6.h       | 17 +++++++++++++++++
 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 +++++++----
 6 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h
index 1a4b1b7..70b391a 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -136,6 +136,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;
 };
diff --git a/datapath/linux/compat/include/net/ipv6.h b/datapath/linux/compat/include/net/ipv6.h
index ac1564b..4e60283 100644
--- a/datapath/linux/compat/include/net/ipv6.h
+++ b/datapath/linux/compat/include/net/ipv6.h
@@ -54,4 +54,21 @@ static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 unused)
 }
 #endif
 
+#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 65adc02..feec6c7 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
-- 
2.5.5




More information about the dev mailing list