[ovs-dev] [PATCH] Correctly implement the OpenFlow 1.2+ OXM_OF_IP_DSCP field.
Ben Pfaff
blp at nicira.com
Mon Apr 15 21:02:28 UTC 2013
NXM puts the DSCP value in bits 2-7 of NXM_OF_IP_TOS.
OXM puts the DSCP value in bits 0-6 of OXM_OF_IP_DSCP.
Before this commit, Open vSwitch incorrectly implemented OXM_OF_IP_DSCP
with the same format as NXM_OF_IP_TOS. This commit fixes the problem and
adds a test (previously missing but I don't know why).
Reported-by: Hiroshi Miyata <miyahiro.dazu at gmail.com>
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
AUTHORS | 1 +
lib/meta-flow.c | 31 +++++++++++++++++++++++++++++++
lib/meta-flow.h | 12 +++++++++++-
lib/nx-match.c | 9 ++++++---
tests/ovs-ofctl.at | 12 ++++++++++++
5 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index f9343de..b30fd69 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -139,6 +139,7 @@ Hassan Khan hassan.khan at seecs.edu.pk
Hector Oron hector.oron at gmail.com
Henrik Amren henrik at nicira.com
Hiroshi Tanaka htanaka at nicira.com
+Hiroshi Miyata miyahiro.dazu at gmail.com
Igor Ganichev iganichev at nicira.com
Jacob Cherkas jcherkas at nicira.com
Jad Naous jnaous at gmail.com
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 6f7a3aa..9296faa 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -359,6 +359,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
MFP_IP_ANY,
true,
NXM_OF_IP_TOS, "NXM_OF_IP_TOS",
+ NXM_OF_IP_TOS, "NXM_OF_IP_TOS",
+ }, {
+ MFF_IP_DSCP_SHIFTED, "nw_tos_shifted", NULL,
+ MF_FIELD_SIZES(u8),
+ MFM_NONE,
+ MFS_DECIMAL,
+ MFP_IP_ANY,
+ true,
+ OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP",
OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP",
}, {
MFF_IP_ECN, "nw_ecn", NULL,
@@ -733,6 +742,7 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
case MFF_IP_PROTO:
return !wc->masks.nw_proto;
case MFF_IP_DSCP:
+ case MFF_IP_DSCP_SHIFTED:
return !(wc->masks.nw_tos & IP_DSCP_MASK);
case MFF_IP_ECN:
return !(wc->masks.nw_tos & IP_ECN_MASK);
@@ -916,6 +926,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
case MFF_IP_DSCP:
return !(value->u8 & ~IP_DSCP_MASK);
+ case MFF_IP_DSCP_SHIFTED:
+ return !(value->u8 & (~IP_DSCP_MASK >> 2));
case MFF_IP_ECN:
return !(value->u8 & ~IP_ECN_MASK);
case MFF_IP_FRAG:
@@ -1065,6 +1077,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
value->u8 = flow->nw_tos & IP_DSCP_MASK;
break;
+ case MFF_IP_DSCP_SHIFTED:
+ value->u8 = flow->nw_tos >> 2;
+ break;
+
case MFF_IP_ECN:
value->u8 = flow->nw_tos & IP_ECN_MASK;
break;
@@ -1244,6 +1260,10 @@ mf_set_value(const struct mf_field *mf,
match_set_nw_dscp(match, value->u8);
break;
+ case MFF_IP_DSCP_SHIFTED:
+ match_set_nw_dscp(match, value->u8 << 2);
+ break;
+
case MFF_IP_ECN:
match_set_nw_ecn(match, value->u8);
break;
@@ -1424,6 +1444,11 @@ mf_set_flow_value(const struct mf_field *mf,
flow->nw_tos |= value->u8 & IP_DSCP_MASK;
break;
+ case MFF_IP_DSCP_SHIFTED:
+ flow->nw_tos &= ~IP_DSCP_MASK;
+ flow->nw_tos |= value->u8 << 2;
+ break;
+
case MFF_IP_ECN:
flow->nw_tos &= ~IP_ECN_MASK;
flow->nw_tos |= value->u8 & IP_ECN_MASK;
@@ -1624,6 +1649,7 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
break;
case MFF_IP_DSCP:
+ case MFF_IP_DSCP_SHIFTED:
match->wc.masks.nw_tos &= ~IP_DSCP_MASK;
match->flow.nw_tos &= ~IP_DSCP_MASK;
break;
@@ -1726,6 +1752,7 @@ mf_set(const struct mf_field *mf,
case MFF_IP_PROTO:
case MFF_IP_TTL:
case MFF_IP_DSCP:
+ case MFF_IP_DSCP_SHIFTED:
case MFF_IP_ECN:
case MFF_ARP_OP:
case MFF_ICMPV4_TYPE:
@@ -1956,6 +1983,10 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
value->u8 &= IP_DSCP_MASK;
break;
+ case MFF_IP_DSCP_SHIFTED:
+ value->u8 &= IP_DSCP_MASK >> 2;
+ break;
+
case MFF_IP_ECN:
value->u8 &= IP_ECN_MASK;
break;
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 57f6df5..9577a10 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,8 +91,18 @@ enum mf_field_id {
MFF_IPV6_DST, /* ipv6 */
MFF_IPV6_LABEL, /* be32 */
+ /* The IPv4/IPv6 DSCP field has two different views:
+ *
+ * - MFF_IP_DSCP has the DSCP in bits 2-7, their bit positions in the
+ * IPv4 and IPv6 "traffic class" field, as used in OpenFlow 1.0 and 1.1
+ * flow format and in NXM's NXM_OF_IP_TOS
+ *
+ * - MFF_IP_DSCP has the DSCP in bits 0-5, shifted right two bits from
+ * their positions in the IPv4 and IPv6 "traffic class" field, as used
+ * in OpenFlow 1.2+ OXM's OXM_OF_IP_DSCP. */
MFF_IP_PROTO, /* u8 (used for IPv4 or IPv6) */
MFF_IP_DSCP, /* u8 (used for IPv4 or IPv6) */
+ MFF_IP_DSCP_SHIFTED, /* u8 (used for IPv4 or IPv6) (OF1.2 compat) */
MFF_IP_ECN, /* u8 (used for IPv4 or IPv6) */
MFF_IP_TTL, /* u8 (used for IPv4 or IPv6) */
MFF_IP_FRAG, /* u8 (used for IPv4 or IPv6) */
diff --git a/lib/nx-match.c b/lib/nx-match.c
index bfead68..b328f02 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -517,8 +517,11 @@ nxm_put_ip(struct ofpbuf *b, const struct match *match,
nxm_put_frag(b, match);
if (match->wc.masks.nw_tos & IP_DSCP_MASK) {
- nxm_put_8(b, oxm ? OXM_OF_IP_DSCP : NXM_OF_IP_TOS,
- flow->nw_tos & IP_DSCP_MASK);
+ if (oxm) {
+ nxm_put_8(b, OXM_OF_IP_DSCP, flow->nw_tos >> 2);
+ } else {
+ nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & IP_DSCP_MASK);
+ }
}
if (match->wc.masks.nw_tos & IP_ECN_MASK) {
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 075f2e4..d62b085 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -1466,6 +1466,12 @@ OXM_OF_VLAN_VID_W(1123/1f0f), OXM_OF_VLAN_PCP(01) # Packets with VID=123 (maske
OXM_OF_VLAN_VID_W(1000/1000) # Packets with any VID, any PCP
OXM_OF_VLAN_VID_W(1000/1000), OXM_OF_VLAN_PCP(01) # Packets with any VID, PCP=1.
+# IP TOS
+OXM_OF_ETH_TYPE(0800) OXM_OF_IP_DSCP(f0)
+OXM_OF_ETH_TYPE(0800) OXM_OF_IP_DSCP(41)
+OXM_OF_ETH_TYPE(0800) OXM_OF_IP_DSCP(3f)
+OXM_OF_IP_DSCP(f0)
+
# IP ECN
OXM_OF_ETH_TYPE(0800) OXM_OF_IP_ECN(03)
OXM_OF_ETH_TYPE(0800) OXM_OF_IP_ECN(06)
@@ -1662,6 +1668,12 @@ OXM_OF_VLAN_VID_W(1103/1f0f), OXM_OF_VLAN_PCP(01)
OXM_OF_VLAN_VID_W(1000/1000)
OXM_OF_VLAN_VID_W(1000/1000), OXM_OF_VLAN_PCP(01)
+# IP TOS
+nx_pull_match() returned error OFPBMC_BAD_VALUE
+nx_pull_match() returned error OFPBMC_BAD_VALUE
+OXM_OF_ETH_TYPE(0800), OXM_OF_IP_DSCP(3f)
+nx_pull_match() returned error OFPBMC_BAD_PREREQ
+
# IP ECN
OXM_OF_ETH_TYPE(0800), OXM_OF_IP_ECN(03)
nx_pull_match() returned error OFPBMC_BAD_VALUE
--
1.7.2.5
More information about the dev
mailing list