[ovs-dev] [PATCH 2/7] Add new port VLAN mode "dot1q-tunnel"

Ben Pfaff blp at ovn.org
Fri Mar 17 15:39:01 UTC 2017


On Wed, Mar 01, 2017 at 05:48:00PM -0500, Eric Garver wrote:
>  - Example:
>      ovs-vsctl set Port p1 vlan_mode=dot1q-tunnel tag=100
>    Pushes another VLAN 100 header on packets (tagged and untagged) on
>    ingress, and pops it on egress.
>  - Customer VLAN check:
>      ovs-vsctl set Port p1 vlan_mode=dot1q-tunnel tag=100 cvlans=10,20
>    Only customer VLAN of 10 and 20 are allowed.
> 
> Co-authored-by: Xiao Liang <shaw.leon at gmail.com>
> Signed-off-by: Xiao Liang <shaw.leon at gmail.com>
> Signed-off-by: Eric Garver <e at erig.me>

Thanks Eric and Xiao.

I applied this commit to master, folding in the following changes.  The
important changes were:

* Clarified log message.

* Moved qinq_ethtype from a column of its own to other_config, because I
  did not think that this was an important configuration setting.

* Rewrote and expanded the documentation, because I had never heard of
  dot1-tunnel ports and thought that others deserved a detailed
  explanation of what they do.

Eric, would you mind rebasing and resubmitting patches 3 through 7?  I
imagine that I've mostly broken them with my changes, although I hope
that the fixes are simple.

Thanks,

Ben.

--8<--------------------------cut here-------------------------->8--

diff --git a/NEWS b/NEWS
index 2994b82b6a76..83a7c97c3cd9 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,6 @@ Post-v2.7.0
    - Tunnels:
      * Added support to set packet mark for tunnel endpoint using
        `egress_pkt_mark` OVSDB option.
-     * New dot1q-tunnel (CVLAN) type via 802.1ad support.
    - EMC insertion probability is reduced to 1% and is configurable via
      the new 'other_config:emc-insert-inv-prob' option.
    - DPDK:
@@ -12,7 +11,8 @@ Post-v2.7.0
        'ovs-appctl vlog' commands for 'dpdk' module. Lower bound
        still can be configured via extra arguments for DPDK EAL.
    - The "learn" action now supports a "limit" option (see ovs-ofctl(8)).
-   - New support for multiple VLANs (802.1ad or "QinQ").
+   - New support for multiple VLANs (802.1ad or "QinQ"), including a new
+     "dot1q-tunnel" port VLAN mode.
 
 v2.7.0 - 21 Feb 2017
 ---------------------
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index bc16e92847d7..1a82b8d569be 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -1968,8 +1968,8 @@ input_vid_is_valid(const struct xlate_ctx *ctx,
     case PORT_VLAN_DOT1Q_TUNNEL:
         if (!xbundle_allows_cvlan(in_xbundle, vid)) {
             xlate_report_error(ctx, "dropping VLAN %"PRIu16" packet received "
-                               "on port %s not configured for dot1q tunneling"
-                               "VLAN %"PRIu16, vid, in_xbundle->name, vid);
+                               "on dot1q-tunnel port %s that excludes this "
+                               "VLAN", vid, in_xbundle->name);
             return false;
         }
         return true;
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 8cc2fee234ff..6611c23a5903 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -2968,7 +2968,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
     }
 
     if (s->qinq_ethtype != bundle->qinq_ethtype) {
-        bundle->qinq_ethtype= s->qinq_ethtype;
+        bundle->qinq_ethtype = s->qinq_ethtype;
         need_flush = true;
     }
 
@@ -3032,7 +3032,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
 
     if (!vlan_bitmap_equal(cvlans, bundle->cvlans)) {
         free(bundle->cvlans);
-        if (cvlans== s->cvlans) {
+        if (cvlans == s->cvlans) {
             bundle->cvlans = vlan_bitmap_clone(cvlans);
         } else {
             bundle->cvlans = cvlans;
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index d44845ce3cf6..1e48e1952aa2 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -390,7 +390,7 @@ enum port_vlan_mode {
      * Other VLANs in 'trunks' are trunked. */
     PORT_VLAN_NATIVE_UNTAGGED,
 
-    /* 802.1q tunnel port. Incomming packets are added an outer vlan tag
+    /* 802.1q tunnel port. Incoming packets are added an outer vlan tag
      * 'vlan'. If 'cvlans' is set, only allows VLANs in 'cvlans'. */
     PORT_VLAN_DOT1Q_TUNNEL
 };
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 0a0d36800449..e3d79bd0788d 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -3182,10 +3182,10 @@ OVS_VSWITCHD_START(
    add-port br0 p7 vlan_mode=native-untagged tag=12              -- \
    add-port br0 p8 vlan_mode=native-untagged tag=12 trunks=10,12 \
                    other-config:priority-tags=true               -- \
-   add-port br0 p9 vlan_mode=dot1q-tunnel    tag=10              qinq_ethtype=802.1q  -- \
-   add-port br0 p10 vlan_mode=dot1q-tunnel   tag=10 cvlans=10,12 qinq_ethtype=802.1q  -- \
-   add-port br0 p11 vlan_mode=dot1q-tunnel   tag=12              qinq_ethtype=802.1q  -- \
-   add-port br0 p12 vlan_mode=dot1q-tunnel   tag=12              qinq_ethtype=802.1q  \
+   add-port br0 p9 vlan_mode=dot1q-tunnel    tag=10              other-config:qinq-ethtype=802.1q  -- \
+   add-port br0 p10 vlan_mode=dot1q-tunnel   tag=10 cvlans=10,12 other-config:qinq-ethtype=802.1q  -- \
+   add-port br0 p11 vlan_mode=dot1q-tunnel   tag=12              other-config:qinq-ethtype=802.1q  -- \
+   add-port br0 p12 vlan_mode=dot1q-tunnel   tag=12              other-config:qinq-ethtype=802.1q  \
                    other-config:priority-tags=true               -- \
    set Interface p1 type=dummy -- \
    set Interface p2 type=dummy -- \
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 77fe686a51f2..b182e0a5a37c 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
+/* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1013,22 +1013,10 @@ port_configure(struct port *port)
         }
     }
 
-    if (cfg->qinq_ethtype) {
-        if (!strcmp(cfg->qinq_ethtype, "802.1q") ||
-            !strcmp(cfg->qinq_ethtype, "0x8100")) {
-            s.qinq_ethtype = ETH_TYPE_VLAN_8021Q;
-        } else if (!strcmp(cfg->qinq_ethtype, "802.1ad") ||
-                   !strcmp(cfg->qinq_ethtype, "0x88a8")) {
-            s.qinq_ethtype = ETH_TYPE_VLAN_8021AD;
-        } else {
-            /* This "can't happen" because ovsdb-server should prevent it. */
-            VLOG_WARN("port %s: invalid QinQ ethertype %s, falling "
-                      "back to 802.1ad", port->name, cfg->qinq_ethtype);
-            s.qinq_ethtype = ETH_TYPE_VLAN_8021AD;
-        }
-    } else {
-        s.qinq_ethtype = ETH_TYPE_VLAN_8021AD;
-    }
+    const char *qe = smap_get_def(&cfg->other_config, "qinq-ethtype", "");
+    s.qinq_ethtype = (!strcmp(qe, "802.1q")
+                      ? ETH_TYPE_VLAN_8021Q
+                      : ETH_TYPE_VLAN_8021AD);
 
     s.use_priority_tags = smap_get_bool(&cfg->other_config, "priority-tags",
                                         false);
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 97fad0621fe3..19b49daf118c 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
  "version": "7.15.0",
- "cksum": "2427506207 23400",
+ "cksum": "544856471 23228",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -160,10 +160,6 @@
            "enum": ["set", ["trunk", "access", "native-tagged",
                             "native-untagged", "dot1q-tunnel"]]},
          "min": 0, "max": 1}},
-       "qinq_ethtype": {
-         "type": {"key": {"type": "string",
-           "enum": ["set", ["802.1q", "802.1ad", "0x88a8", "0x8100"]]},
-         "min": 0, "max": 1}},
        "qos": {
          "type": {"key": {"type": "uuid",
                           "refTable": "QoS"},
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 45cc6437f412..14297bf9ad98 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1281,7 +1281,39 @@
     </column>
 
     <group title="VLAN Configuration">
-      <p>Bridge ports support the following types of VLAN configuration:</p>
+      <p>
+        In short, a VLAN (short for ``virtual LAN'') is a way to partition a
+        single switch into multiple switches.  VLANs can be confusing, so for
+        an introduction, please refer to the question ``What's a VLAN?'' in the
+        Open vSwitch FAQ.
+      </p>
+
+      <p>
+        A VLAN is sometimes encoded into a packet using a 802.1Q or 802.1ad
+        VLAN header, but every packet is part of some VLAN whether or not it is
+        encoded in the packet.  (A packet that appears to have no VLAN is part
+        of VLAN 0, by default.)  As a result, it's useful to think of a VLAN as
+        a metadata property of a packet, separate from how the VLAN is encoded.
+        For a given port, this column determines how the encoding of a packet
+        that ingresses or egresses the port maps to the packet's VLAN.  When a
+        packet enters the switch, its VLAN is determined based on its setting
+        in this column and its VLAN headers, if any, and then, conceptually,
+        the VLAN headers are then stripped off.  Conversely, when a packet
+        exits the switch, its VLAN and the settings in this column determine
+        what VLAN headers, if any, are pushed onto the packet before it
+        egresses the port.
+      </p>
+
+      <p>
+        The VLAN configuration in this column affects Open vSwitch only when it
+        is doing ``normal switching.''  It does not affect flows set up by an
+        OpenFlow controller, outside of the OpenFlow ``normal action.''
+      </p>
+
+      <p>
+        Bridge ports support the following types of VLAN configuration:
+      </p>
+
       <dl>
         <dt>trunk</dt>
         <dd>
@@ -1333,16 +1365,23 @@
         <dt>dot1q-tunnel</dt>
         <dd>
           <p>
-            A dot1q-tunnel port tunnels packets with VLAN specified in
-            <ref column="tag"/> column. That is it adds 802.1Q header, with
-            ethertype and VLAN ID specified in <ref column="qinq-ethtype"/>
-            and <ref column="tag"/>, to both tagged and untagged packets on
-            ingress, and pops dot1q header of this VLAN on egress.
+            A dot1q-tunnel port is somewhat like an access port.  Like an
+            access port, it carries packets on the single VLAN specified in the
+            <ref column="tag"/> column and this VLAN, called the service VLAN,
+            does not appear in an 802.1Q header for packets that ingress or
+            egress on the port.  The main difference lies in the behavior when
+            packets that include a 802.1Q header ingress on the port.  Whereas
+            an access port drops such packets, a dot1q-tunnel port treats these
+            as double-tagged with the outer service VLAN <ref column="tag"/>
+            and the inner customer VLAN taken from the 802.1Q header.
+            Correspondingly, to egress on the port, a packet outer VLAN (or
+            only VLAN) must be <ref column="tag"/>, which is removed before
+            egress, which exposes the inner (customer) VLAN if one is present.
           </p>
-
+            
           <p>
-            If <ref column="cvlans"/> is set, only allows packets of these
-            VLANs.
+            If <ref column="cvlans"/> is set, only allows packets in the
+            specified customer VLANs.
           </p>
         </dd>
       </dl>
@@ -1368,13 +1407,6 @@
         </ul>
       </column>
 
-      <column name="qinq_ethtype">
-        <p>
-          Ethertype of dot1q-tunnel port, could be either "802.1q"(0x8100) or
-          "802.1ad"(0x88a8). Defaults to "802.1ad".
-        </p>
-      </column>
-
       <column name="tag">
         <p>
           For an access port, the port's implicitly tagged VLAN.  For a
@@ -1398,9 +1430,32 @@
 
       <column name="cvlans">
         <p>
-          For a trunk-qinq port if specific cvlans are specified only those
-          cvlans are 1ad tunneled, others are dropped. If no cvlans specified
-          explicitly then all cvlans are 1ad tunneled.
+          For a dot1q-tunnel port, the customer VLANs that this port includes.
+          If this is empty, the port includes all customer VLANs.
+        </p>
+        <p>
+          For other kinds of ports, this setting is ignored.
+        </p>
+      </column>
+
+      <column name="other_config" key="qinq-ethtype"
+              type='{"type": "string", "enum": ["set", ["802.1ad", "802.1q"]]}'>
+        <p>
+          For a dot1q-tunnel port, this is the TPID for the service tag, that
+          is, for the 802.1Q header that contains the service VLAN ID.  Because
+          packets that actually ingress and egress a dot1q-tunnel port do not
+          include an 802.1Q header for the service VLAN, this does not affect
+          packets on the dot1q-tunnel port itself.  Rather, it determines the
+          service VLAN for a packet that ingresses on a dot1q-tunnel port and
+          egresses on a trunk port.
+        </p>
+        <p>
+          The value <code>802.1ad</code> specifies TPID 0x88a8, which is also
+          the default if the setting is omitted.  The value <code>802.1q</code>
+          specifies TPID 0x8100.
+        </p>
+        <p>
+          For other kinds of ports, this setting is ignored.
         </p>
       </column>
 


More information about the dev mailing list