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)))
#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);
*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;
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;
else
tos = mutable->tos;
- tos = INET_ECN_encapsulate(tos, inner_tos);
-
/* Route lookup */
rt = find_route(vport, mutable, tos, &cache);
if (unlikely(!rt))
if (unlikely(!cache))
unattached_dst = &rt_dst(rt);
+ tos = INET_ECN_encapsulate(tos, inner_tos);
+
/* Reset SKB */
nf_reset(skb);
secpath_reset(skb);
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;
}
<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.