From f1193301162788fadc0f6faa1af9441f93a623d8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 11 Feb 2010 15:19:26 -0800 Subject: [PATCH] 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 --- datapath/actions.c | 7 ++++--- lib/dpif-netdev.c | 4 ++-- lib/flow.c | 2 +- lib/packets.h | 4 ++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index fccacf21..ab392222 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include "datapath.h" @@ -298,10 +299,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 1cab12ba..ca5e8eb2 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1179,8 +1179,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 d22890e5..7d368bb6 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 eaffca93..7651495e 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -224,6 +224,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 -- 2.30.2