X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Ftunnel.c;h=d651c11833885a573cc743d1a08bc6d2a40e001e;hb=b10a4760be32849e33a2b85084491b7ab058efcd;hp=d406dbc46640e4e0ae51ecc64e8bac339a7fa87d;hpb=c3cc8c031bb7be42b5b818c23d0e708a0cc11a26;p=sliver-openvswitch.git diff --git a/datapath/tunnel.c b/datapath/tunnel.c index d406dbc46..d651c1183 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2012 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -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,8 +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); if (unlikely(!rt)) @@ -1228,6 +1229,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); @@ -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; }