[ovs-dev] [PATCH v2 2/2] datapath: Fix Tunnel options TOS

Pravin B Shelar pshelar at nicira.com
Wed May 16 23:13:21 UTC 2012


Fixed according to comments from Jesse.
v1-v2:
	- calculate ToS for packet after route lookup.
	- use RT_TOS bits to validate route cache.

--8<--------------------------cut here-------------------------->8--

Use DSCP bits from ToS set on tunnel.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>

Bug #8822
---
 datapath/tunnel.c    |   18 +++++++++++-------
 vswitchd/vswitch.xml |    3 ++-
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index c2133bb..d3e2d20 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -1002,12 +1002,15 @@ unlock:
 static struct rtable *__find_route(const struct tnl_mutable_config *mutable,
 				   u8 ipproto, u8 tos)
 {
+	/* Tunnel configuration keeps DSCP part of TOS bits, But Linux
+	 * router expect RT_TOS bits only. */
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
 	struct flowi fl = { .nl_u = { .ip4_u = {
 					.daddr = mutable->key.daddr,
 					.saddr = mutable->key.saddr,
-					.tos = tos } },
-			    .proto = ipproto };
+					.tos   = RT_TOS(tos) } },
+					.proto = ipproto };
 	struct rtable *rt;
 
 	if (unlikely(ip_route_output_key(port_key_get_net(&mutable->key), &rt, &fl)))
@@ -1017,7 +1020,7 @@ static struct rtable *__find_route(const struct tnl_mutable_config *mutable,
 #else
 	struct flowi4 fl = { .daddr = mutable->key.daddr,
 			     .saddr = mutable->key.saddr,
-			     .flowi4_tos = tos,
+			     .flowi4_tos = RT_TOS(tos),
 			     .flowi4_proto = ipproto };
 
 	return ip_route_output_key(port_key_get_net(&mutable->key), &fl);
@@ -1034,7 +1037,7 @@ static struct rtable *find_route(struct vport *vport,
 	*cache = NULL;
 	tos = RT_TOS(tos);
 
-	if (likely(tos == mutable->tos &&
+	if (likely(tos == RT_TOS(mutable->tos) &&
 	    check_cache_valid(cur_cache, mutable))) {
 		*cache = cur_cache;
 		return cur_cache->rt;
@@ -1045,7 +1048,7 @@ static struct rtable *find_route(struct vport *vport,
 		if (IS_ERR(rt))
 			return NULL;
 
-		if (likely(tos == mutable->tos))
+		if (likely(tos == RT_TOS(mutable->tos)))
 			*cache = build_cache(vport, mutable, rt);
 
 		return rt;
@@ -1219,7 +1222,6 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
 	else
 		tos = mutable->tos;
 
-	tos = INET_ECN_encapsulate(tos, inner_tos);
 
 	/* Route lookup */
 	rt = find_route(vport, mutable, tos, &cache);
@@ -1270,6 +1272,7 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
 #endif
 	}
 
+	tos = INET_ECN_encapsulate(tos, inner_tos);
 	while (skb) {
 		struct iphdr *iph;
 		struct sk_buff *next_skb = skb->next;
@@ -1402,7 +1405,8 @@ static int tnl_set_config(struct net *net, struct nlattr *options,
 
 	if (a[OVS_TUNNEL_ATTR_TOS]) {
 		mutable->tos = nla_get_u8(a[OVS_TUNNEL_ATTR_TOS]);
-		if (mutable->tos != RT_TOS(mutable->tos))
+		/* Reject ToS config with ECN bits set. */
+		if (mutable->tos & INET_ECN_MASK)
 			return -EINVAL;
 	}
 
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 94760cc..0cd9b30 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1267,7 +1267,8 @@
 
       <column name="options" key="tos">
         Optional.  The value of the ToS bits to be set on the encapsulating
-        packet.  It may also be the word <code>inherit</code>, in which case
+        packet.  ToS is interpreted as DSCP and ECN bits, ECN part must be
+        zero.  It may also be the word <code>inherit</code>, in which case
         the ToS will be copied from the inner packet if it is IPv4 or IPv6
         (otherwise it will be 0).  The ECN fields are always inherited.
         Default is 0.
-- 
1.7.10




More information about the dev mailing list