[ovs-dev] [PATCH 1/2] datapath: Set the correct bits for OFPAT_SET_NW_TOS action.
Ben Pfaff
blp at nicira.com
Thu Feb 11 23:22:15 UTC 2010
The DSCP bits are the high bits, not the low bits.
Reported-by: Jean Tourrilhes <jt at hpl.hp.com>
---
datapath/actions.c | 9 +++++----
lib/dpif-netdev.c | 4 ++--
lib/flow.c | 2 +-
lib/packets.h | 6 +++++-
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/datapath/actions.c b/datapath/actions.c
index 3eea532..0aefb8d 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 <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"
@@ -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 54fff5e..d576c73 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 d22890e..7d368bb 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 4595c12..6fab659 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
--
1.6.6.1
More information about the dev
mailing list