From: Ben Pfaff Date: Thu, 11 Feb 2010 23:19:26 +0000 (-0800) Subject: datapath: Set the correct bits for OFPAT_SET_NW_TOS action. X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=776fb430bfbc575c16c4db3be7ffdeb507325a6a;p=sliver-openvswitch.git datapath: Set the correct bits for OFPAT_SET_NW_TOS action. The DSCP bits are the high bits, not the low bits. Reported-by: Jean Tourrilhes --- diff --git a/datapath/actions.c b/datapath/actions.c index 3eea5323f..0aefb8d53 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -1,6 +1,6 @@ /* * Distributed under the terms of the GNU GPL version 2. - * Copyright (c) 2007, 2008, 2009 Nicira Networks. + * Copyright (c) 2007, 2008, 2009, 2010 Nicira Networks. * * Significant portions of this file may be copied from parts of the Linux * kernel, by Linus Torvalds and others. @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include "datapath.h" @@ -265,10 +266,10 @@ static struct sk_buff *set_nw_tos(struct sk_buff *skb, struct iphdr *nh = ip_hdr(skb); u8 *f = &nh->tos; u8 old = *f; + u8 new; - /* We only set the lower 6 bits. */ - u8 new = (a->nw_tos & 0x3f) | (nh->tos & 0xc0); - + /* Set the DSCP bits and preserve the ECN bits. */ + new = (a->nw_tos & ~INET_ECN_MASK) | (nh->tos & INET_ECN_MASK); update_csum(&nh->check, skb, htons((uint16_t)old), htons((uint16_t)new), 0); *f = new; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 54fff5e18..d576c7350 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1180,8 +1180,8 @@ dp_netdev_set_nw_tos(struct ofpbuf *packet, flow_t *key, struct ip_header *nh = packet->l3; uint8_t *field = &nh->ip_tos; - /* We only set the lower 6 bits. */ - uint8_t new = (a->nw_tos & 0x3f) | (nh->ip_tos & 0xc0); + /* Set the DSCP bits and preserve the ECN bits. */ + uint8_t new = (a->nw_tos & IP_DSCP_MASK) | (nh->ip_tos & IP_ECN_MASK); nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field), htons((uint16_t)a->nw_tos)); diff --git a/lib/flow.c b/lib/flow.c index d22890e54..7d368bb6d 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -151,7 +151,7 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, flow_t *flow) if (nh) { flow->nw_src = nh->ip_src; flow->nw_dst = nh->ip_dst; - flow->nw_tos = nh->ip_tos & 0xfc; + flow->nw_tos = nh->ip_tos & IP_DSCP_MASK; flow->nw_proto = nh->ip_proto; packet->l4 = b.data; if (!IP_IS_FRAGMENT(nh->ip_frag_off)) { diff --git a/lib/packets.h b/lib/packets.h index 4595c12cb..6fab65937 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -213,6 +213,10 @@ BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); #define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) #define IP_IHL_VER(ihl, ver) (((ver) << 4) | (ihl)) +/* TOS fields. */ +#define IP_ECN_MASK 0x03 +#define IP_DSCP_MASK 0xfc + #define IP_TYPE_ICMP 1 #define IP_TYPE_TCP 6 #define IP_TYPE_UDP 17