From 5e9ceccdb69b7e8f519ebeb9d2825b2686810610 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 17 Nov 2011 17:11:53 -0800 Subject: [PATCH] Implement a new port setting "other-config:priority-tags". Linux hosts (and probably others) tend to ignore priority-tagged frames, so this new setting allows Open vSwitch to suppress sending them. Reported-by: Michael Mao Bug #8320. --- ofproto/ofproto-dpif.c | 15 ++++++++++---- ofproto/ofproto.h | 1 + tests/ofproto-dpif.at | 46 ++++++++++++++++++++---------------------- vswitchd/bridge.c | 2 ++ vswitchd/vswitch.xml | 43 +++++++++++++++++++++++++++++++-------- 5 files changed, 71 insertions(+), 36 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index e220d96b3..951ed18c9 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -145,6 +145,7 @@ struct ofbundle { * NULL if all VLANs are trunked. */ struct lacp *lacp; /* LACP if LACP is enabled, otherwise NULL. */ struct bond *bond; /* Nonnull iff more than one port. */ + bool use_priority_tags; /* Use 802.1p tag for frames in VLAN 0? */ /* Status. */ bool floodable; /* True if no port has OFPPC_NO_FLOOD set. */ @@ -1364,6 +1365,7 @@ bundle_set(struct ofproto *ofproto_, void *aux, bundle->vlan_mode = PORT_VLAN_TRUNK; bundle->vlan = -1; bundle->trunks = NULL; + bundle->use_priority_tags = s->use_priority_tags; bundle->lacp = NULL; bundle->bond = NULL; @@ -1422,8 +1424,10 @@ bundle_set(struct ofproto *ofproto_, void *aux, } /* Set VLAN tagging mode */ - if (s->vlan_mode != bundle->vlan_mode) { + if (s->vlan_mode != bundle->vlan_mode + || s->use_priority_tags != bundle->use_priority_tags) { bundle->vlan_mode = s->vlan_mode; + bundle->use_priority_tags = s->use_priority_tags; need_flush = true; } @@ -4497,9 +4501,12 @@ output_normal(struct action_xlate_ctx *ctx, const struct ofbundle *out_bundle, } } - tci = htons(vid) | (ctx->flow.vlan_tci & htons(VLAN_PCP_MASK)); - if (tci) { - tci |= htons(VLAN_CFI); + tci = htons(vid); + if (tci || out_bundle->use_priority_tags) { + tci |= ctx->flow.vlan_tci & htons(VLAN_PCP_MASK); + if (tci) { + tci |= htons(VLAN_CFI); + } } commit_vlan_action(ctx, tci); diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index eed4e5083..5a99d4692 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -251,6 +251,7 @@ struct ofproto_bundle_settings { enum port_vlan_mode vlan_mode; /* Selects mode for vlan and trunks */ int vlan; /* VLAN VID, except for PORT_VLAN_TRUNK. */ unsigned long *trunks; /* vlan_bitmap, except for PORT_VLAN_ACCESS. */ + bool use_priority_tags; /* Use 802.1p tag for frames in VLAN 0? */ struct bond_settings *bond; /* Must be nonnull iff if n_slaves > 1. */ uint32_t *bond_stable_ids; /* Array of n_slaves elements. */ diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index e805c202e..397c42ecb 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -85,12 +85,14 @@ OVS_VSWITCHD_START( [set Bridge br0 fail-mode=standalone -- \ add-port br0 p1 trunks=10,12 -- \ add-port br0 p2 tag=10 -- \ - add-port br0 p3 tag=12 -- \ + add-port br0 p3 tag=12 \ + other-config:priority-tags=true -- \ add-port br0 p4 tag=12 -- \ add-port br0 p5 vlan_mode=native-tagged tag=10 -- \ add-port br0 p6 vlan_mode=native-tagged tag=10 trunks=10,12 -- \ add-port br0 p7 vlan_mode=native-untagged tag=12 -- \ - add-port br0 p8 vlan_mode=native-untagged tag=12 trunks=10,12 -- \ + add-port br0 p8 vlan_mode=native-untagged tag=12 trunks=10,12 \ + other-config:priority-tags=true -- \ set Interface p1 type=dummy -- \ set Interface p2 type=dummy -- \ set Interface p3 type=dummy -- \ @@ -117,29 +119,25 @@ br0=0 p1=$1 p2=$2 p3=$3 p4=$4 p5=$5 p6=$6 p7=$7 p8=$8 dnl Each of these specifies an in_port, a VLAN VID (or "none"), a VLAN dnl PCP (used if the VID isn't "none") and the expected set of datapath dnl actions. -dnl -dnl XXX Some of these actually output an 802.1Q header to an access port -dnl (see for example the actions for in_port=p3, vlan=0) to qualify the -dnl packet with a priority. That should be configurable. for tuple in \ "br0 none 0 drop" \ "br0 0 0 drop" \ "br0 0 1 drop" \ "br0 10 0 p1,p5,p6,p7,p8,pop_vlan,p2" \ - "br0 10 1 p1,p5,p6,p7,p8,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "br0 10 1 p1,p5,p6,p7,p8,pop_vlan,p2" \ "br0 11 0 p5,p7" \ "br0 11 1 p5,p7" \ "br0 12 0 p1,p5,p6,pop_vlan,p3,p4,p7,p8" \ - "br0 12 1 p1,p5,p6,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p7,p8" \ + "br0 12 1 p1,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \ "p1 none 0 drop" \ "p1 0 0 drop" \ "p1 0 1 drop" \ "p1 10 0 br0,p5,p6,p7,p8,pop_vlan,p2" \ - "p1 10 1 br0,p5,p6,p7,p8,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "p1 10 1 br0,p5,p6,p7,p8,pop_vlan,p2" \ "p1 11 0 drop" \ "p1 11 1 drop" \ "p1 12 0 br0,p5,p6,pop_vlan,p3,p4,p7,p8" \ - "p1 12 1 br0,p5,p6,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p7,p8" \ + "p1 12 1 br0,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \ "p2 none 0 push_vlan(vid=10,pcp=0),br0,p1,p5,p6,p7,p8" \ "p2 0 0 pop_vlan,push_vlan(vid=10,pcp=0),br0,p1,p5,p6,p7,p8" \ "p2 0 1 pop_vlan,push_vlan(vid=10,pcp=1),br0,p1,p5,p6,p7,p8" \ @@ -151,7 +149,7 @@ for tuple in \ "p2 12 1 drop" \ "p3 none 0 p4,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ "p3 0 0 pop_vlan,p4,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ - "p3 0 1 p4,p7,p8,pop_vlan,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ + "p3 0 1 p8,pop_vlan,p4,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ "p3 10 0 drop" \ "p3 10 1 drop" \ "p3 11 0 drop" \ @@ -160,7 +158,7 @@ for tuple in \ "p3 12 1 drop" \ "p4 none 0 p3,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ "p4 0 0 pop_vlan,p3,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ - "p4 0 1 p3,p7,p8,pop_vlan,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ + "p4 0 1 p3,p8,pop_vlan,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ "p4 10 0 drop" \ "p4 10 1 drop" \ "p4 11 0 drop" \ @@ -169,40 +167,40 @@ for tuple in \ "p4 12 1 drop" \ "p5 none 0 p2,push_vlan(vid=10,pcp=0),br0,p1,p6,p7,p8" \ "p5 0 0 pop_vlan,p2,push_vlan(vid=10,pcp=0),br0,p1,p6,p7,p8" \ - "p5 0 1 p2,pop_vlan,push_vlan(vid=10,pcp=1),br0,p1,p6,p7,p8" \ + "p5 0 1 pop_vlan,p2,push_vlan(vid=10,pcp=1),br0,p1,p6,p7,p8" \ "p5 10 0 br0,p1,p6,p7,p8,pop_vlan,p2" \ - "p5 10 1 br0,p1,p6,p7,p8,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "p5 10 1 br0,p1,p6,p7,p8,pop_vlan,p2" \ "p5 11 0 br0,p7" \ "p5 11 1 br0,p7" \ "p5 12 0 br0,p1,p6,pop_vlan,p3,p4,p7,p8" \ - "p5 12 1 br0,p1,p6,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p7,p8" \ + "p5 12 1 br0,p1,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \ "p6 none 0 p2,push_vlan(vid=10,pcp=0),br0,p1,p5,p7,p8" \ "p6 0 0 pop_vlan,p2,push_vlan(vid=10,pcp=0),br0,p1,p5,p7,p8" \ - "p6 0 1 p2,pop_vlan,push_vlan(vid=10,pcp=1),br0,p1,p5,p7,p8" \ + "p6 0 1 pop_vlan,p2,push_vlan(vid=10,pcp=1),br0,p1,p5,p7,p8" \ "p6 10 0 br0,p1,p5,p7,p8,pop_vlan,p2" \ - "p6 10 1 br0,p1,p5,p7,p8,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "p6 10 1 br0,p1,p5,p7,p8,pop_vlan,p2" \ "p6 11 0 drop" \ "p6 11 1 drop" \ "p6 12 0 br0,p1,p5,pop_vlan,p3,p4,p7,p8" \ - "p6 12 1 br0,p1,p5,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p7,p8" \ + "p6 12 1 br0,p1,p5,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \ "p7 none 0 p3,p4,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ "p7 0 0 pop_vlan,p3,p4,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ - "p7 0 1 p3,p4,p8,pop_vlan,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ + "p7 0 1 p3,p8,pop_vlan,p4,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ "p7 10 0 br0,p1,p5,p6,p8,pop_vlan,p2" \ - "p7 10 1 br0,p1,p5,p6,p8,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "p7 10 1 br0,p1,p5,p6,p8,pop_vlan,p2" \ "p7 11 0 br0,p5" \ "p7 11 1 br0,p5" \ "p7 12 0 br0,p1,p5,p6,pop_vlan,p3,p4,p8" \ - "p7 12 1 br0,p1,p5,p6,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p8" \ + "p7 12 1 br0,p1,p5,p6,pop_vlan,p4,push_vlan(vid=0,pcp=1),p3,p8" \ "p8 none 0 p3,p4,p7,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ "p8 0 0 pop_vlan,p3,p4,p7,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \ - "p8 0 1 p3,p4,p7,pop_vlan,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ + "p8 0 1 p3,pop_vlan,p4,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \ "p8 10 0 br0,p1,p5,p6,p7,pop_vlan,p2" \ - "p8 10 1 br0,p1,p5,p6,p7,pop_vlan,push_vlan(vid=0,pcp=1),p2" \ + "p8 10 1 br0,p1,p5,p6,p7,pop_vlan,p2" \ "p8 11 0 drop" \ "p8 11 1 drop" \ "p8 12 0 br0,p1,p5,p6,pop_vlan,p3,p4,p7" \ - "p8 12 1 br0,p1,p5,p6,pop_vlan,push_vlan(vid=0,pcp=1),p3,p4,p7" + "p8 12 1 br0,p1,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3" do set $tuple in_port=$1 diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 6a25b9590..378a08cb5 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -546,6 +546,8 @@ port_configure(struct port *port) s.vlan_mode = PORT_VLAN_TRUNK; } } + s.use_priority_tags = !strcmp("true", get_port_other_config( + cfg, "priority-tags", "")); /* Get LACP settings. */ s.lacp = port_configure_lacp(port, &lacp_settings); diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index d53d9d79f..746a11aac 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -609,8 +609,7 @@ VLAN). A packet that ingresses on a trunk port is in the VLAN specified in its 802.1Q header, or VLAN 0 if the packet has no 802.1Q header. A packet that egresses through a trunk port will - have a 802.1Q header if it has a nonzero VLAN ID (or a nonzero - 802.1Q priority). + have an 802.1Q header if it has a nonzero VLAN ID.

@@ -623,14 +622,14 @@

An access port carries packets on exactly one VLAN specified in the - column. Packets ingressing and egressing on an - access port have no 802.1Q header. + column. Packets egressing on an access port + have no 802.1Q header.

- Any packet with an 802.1Q header that ingresses on an access port - is dropped, regardless of whether the VLAN ID in the header is the - access port's VLAN ID. + Any packet with an 802.1Q header with a nonzero VLAN ID that + ingresses on an access port is dropped, regardless of whether the + VLAN ID in the header is the access port's VLAN ID.

@@ -646,7 +645,7 @@
A native-untagged port resembles a native-tagged port, with the exception that a packet that egresses on a native-untagged port in - the native VLAN not have an 802.1Q header. + the native VLAN will not have an 802.1Q header.

@@ -691,6 +690,34 @@ VLAN.

+ + +

+ An 802.1Q header contains two important pieces of information: a VLAN + ID and a priority. A frame with a zero VLAN ID, called a + ``priority-tagged'' frame, is supposed to be treated the same way as + a frame without an 802.1Q header at all (except for the priority). +

+ +

+ However, some network elements ignore any frame that has 802.1Q + header at all, even when the VLAN ID is zero. Therefore, by default + Open vSwitch does not output priority-tagged frames, instead omitting + the 802.1Q header entirely if the VLAN ID is zero. Set this key to + true to enable priority-tagged frames on a port. +

+ +

+ Regardless of this setting, Open vSwitch omits the 802.1Q header on + output if both the VLAN ID and priority would be zero. +

+ +

+ All frames output to native-tagged ports have a nonzero VLAN ID, so + this setting is not meaningful on native-tagged ports. +

+
-- 2.43.0