datapath: Set the correct bits for OFPAT_SET_NW_TOS action.
authorBen Pfaff <blp@nicira.com>
Thu, 11 Feb 2010 23:19:26 +0000 (15:19 -0800)
committerJustin Pettit <jpettit@nicira.com>
Sat, 20 Feb 2010 10:22:30 +0000 (02:22 -0800)
The DSCP bits are the high bits, not the low bits.

Reported-by: Jean Tourrilhes <jt@hpl.hp.com>
datapath/actions.c
lib/dpif-netdev.c
lib/flow.c
lib/packets.h

index fccacf2..ab39222 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/udp.h>
 #include <linux/in6.h>
 #include <linux/if_vlan.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/checksum.h>
 #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;
index 1cab12b..ca5e8eb 100644 (file)
@@ -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));
index d22890e..7d368bb 100644 (file)
@@ -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)) {
index eaffca9..7651495 100644 (file)
@@ -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