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@gmail.com>
Tested-by: Hiroshi Miyata <miyahiro.dazu@gmail.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Hector Oron hector.oron@gmail.com
Henrik Amren henrik@nicira.com
Hiroshi Tanaka htanaka@nicira.com
+Hiroshi Miyata miyahiro.dazu@gmail.com
Igor Ganichev iganichev@nicira.com
Jacob Cherkas jcherkas@nicira.com
Jad Naous jnaous@gmail.com
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,
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);
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:
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;
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;
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;
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;
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:
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;
/*
- * 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.
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) */
/*
- * 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.
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) {
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)
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