summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2012-05-21 12:18:50 -0700
committerBen Pfaff <blp@nicira.com>2012-10-25 12:36:00 -0700
commit5d98c83b9dec5f86af52df52695c7f43d2a63602 (patch)
tree56025ec20aed06ad8387b0c343dab13a8e082d0e
parent827fdb29c2f11cfb32d73209fb8416db123eee8d (diff)
downloadopenvswitch-5d98c83b9dec5f86af52df52695c7f43d2a63602.tar.gz
datapath: Fix Tunnel options TOS
Use DSCP bits from ToS set on tunnel. This is a crossport of commit 749ae9504293dbb695dd67402acbd47acbcbeb83 from master. Bug #8822. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--datapath/tunnel.c20
-rw-r--r--vswitchd/vswitch.xml3
2 files changed, 14 insertions, 9 deletions
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 4ce830ff6..1ebbc7706 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -991,12 +991,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(&init_net, &rt, &fl)))
@@ -1006,7 +1009,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(&init_net, &fl);
@@ -1023,7 +1026,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;
@@ -1034,7 +1037,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;
@@ -1208,8 +1211,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);
if (unlikely(!rt))
@@ -1217,6 +1218,8 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
if (unlikely(!cache))
unattached_dst = &rt_dst(rt);
+ tos = INET_ECN_encapsulate(tos, inner_tos);
+
/* Reset SKB */
nf_reset(skb);
secpath_reset(skb);
@@ -1389,7 +1392,8 @@ static int tnl_set_config(struct nlattr *options, const struct tnl_ops *tnl_ops,
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 ebbcbe79b..303a98d48 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1259,7 +1259,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.