[ovs-dev] [PATCH] Implement a new port setting "other-config:priority-tags".

Ben Pfaff blp at nicira.com
Fri Nov 18 00:01:06 UTC 2011


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 <mmao at nicira.com>
Bug #8320.
---
 ofproto/ofproto-dpif.c |   15 +++++++++++----
 ofproto/ofproto.h      |    1 +
 tests/ofproto-dpif.at  |   46 ++++++++++++++++++++++------------------------
 vswitchd/bridge.c      |    2 ++
 vswitchd/vswitch.xml   |   44 ++++++++++++++++++++++++++++++++++++--------
 5 files changed, 72 insertions(+), 36 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 86723e1..d9c4268 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 eed4e50..5a99d46 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 e805c20..397c42e 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 6a25b95..378a08c 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 d53d9d7..2d6e2db 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 a 802.1Q header if it has a nonzero VLAN ID.
           </p>
 
           <p>
@@ -623,14 +622,15 @@
         <dd>
           <p>
             An access port carries packets on exactly one VLAN specified in the
-            <ref column="tag"/> column.  Packets ingressing and egressing on an
-            access port have no 802.1Q header.
+            <ref column="tag"/> column.  Packets egressing on an access port
+            have no 802.1Q header.
           </p>
 
           <p>
-            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.
+            (Priority-tagged frames are allowed on ingress.)
           </p>
         </dd>
 
@@ -646,7 +646,7 @@
         <dd>
           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.
         </dd>
       </dl>
       <p>
@@ -691,6 +691,34 @@
           VLAN.
         </p>
       </column>
+
+      <column name="other_config" key="priority-tags"
+              type='{"type": "boolean"}'>
+        <p>
+          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).
+        </p>
+
+        <p>
+          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
+          <code>true</code> to enable priority-tagged frames on a port.
+        </p>
+
+        <p>
+          Regardless of this setting, Open vSwitch omits the 802.1Q header on
+          output if both the VLAN ID and priority would be zero.
+        </p>
+
+        <p>
+          All frames output to native-tagged ports have a nonzero VLAN ID, so
+          this setting is not meaningful on native-tagged ports.
+        </p>
+      </column>
     </group>
 
     <group title="Bonding Configuration">
-- 
1.7.4.4




More information about the dev mailing list