[ovs-dev] Subject: [PATCH V2] Add support for 802.1ad (qinq)

Thomas F Herbert thomasfherbert at gmail.com
Fri Apr 11 19:50:23 UTC 2014


This is Version 2 of a patch to add 802.1ad (qinq) to OVS. It accepts
0x88a8 tpid. It incorporates comments from Andy Zhou and fixes a problem 
that showed up in testing and is merged with MASTER.
I plan to do real-world compatibility testing. I will
send out a V3 in response to comments and results of testing.

 From 1cd913bbcf1aa28c82e588abc537d5e3512915b4 Mon Sep 17 00:00:00 2001
From: Tom Herbert <thomasfherbert at gmail.com>
Date: Fri, 11 Apr 2014 15:41:57 +0000
Subject: [PATCH 2/2] Add Support for 802.1qad V2

Signed-off-by: Tom Herbert <thomasfherbert at gmail.com>
---
  datapath/actions.c      |    6 +++---
  datapath/flow_netlink.c |    2 +-
  lib/odp-execute.c       |    2 +-
  lib/odp-util.c          |    2 +-
  lib/ofp-parse.c         |    3 ++-
  lib/packets.c           |    5 +++--
  6 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index 91375d1..771a444 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -84,9 +84,9 @@ static int pop_vlan(struct sk_buff *skb)
  	if (likely(vlan_tx_tag_present(skb))) {
  		vlan_set_tci(skb, 0);
  	} else {
-		if (unlikely(skb->protocol != htons(ETH_P_8021Q) ||
-		    skb->protocol != htons(ETH_P_8021AD) ||
-			     skb->len < VLAN_ETH_HLEN))
+		if (unlikely(((skb->protocol != htons(ETH_P_8021Q)) &&
+		    (skb->protocol != htons(ETH_P_8021AD))) ||
+			     (skb->len < VLAN_ETH_HLEN)))
  			return 0;

  		err = __pop_vlan_tci(skb, &tci);
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 855af32..22cfa65 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1465,7 +1465,7 @@ int ovs_nla_copy_actions(const struct nlattr *attr,

  		case OVS_ACTION_ATTR_PUSH_VLAN:
  			vlan = nla_data(a);
-			if ((vlan->vlan_tpid != htons(ETH_P_8021Q)) ||
+			if ((vlan->vlan_tpid != htons(ETH_P_8021Q)) &&
  			    (vlan->vlan_tpid != htons(ETH_P_8021AD)))
  				return -EINVAL;
  			if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index e5aa0ce..88e3580 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -217,7 +217,7 @@ odp_execute_actions__(void *dp, struct ofpbuf 
*packet, bool steal,

          case OVS_ACTION_ATTR_PUSH_VLAN: {
              const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
-            eth_push_vlan(packet, htons(ETH_TYPE_VLAN), vlan->vlan_tci);
+            eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);
              break;
          }

diff --git a/lib/odp-util.c b/lib/odp-util.c
index 956fef1..a802495 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -432,7 +432,7 @@ format_odp_action(struct ds *ds, const struct nlattr *a)
      case OVS_ACTION_ATTR_PUSH_VLAN:
          vlan = nl_attr_get(a);
          ds_put_cstr(ds, "push_vlan(");
-        if (vlan->vlan_tpid != htons(ETH_TYPE_VLAN)) {
+        if (vlan->vlan_tpid != htons(ETH_TYPE_VLAN_8021Q)) {
              ds_put_format(ds, "tpid=0x%04"PRIx16",", 
ntohs(vlan->vlan_tpid));
          }
          format_vlan_tci(ds, vlan->vlan_tci);
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 5c5bb06..c3389da 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -704,7 +704,8 @@ parse_named_action(enum ofputil_action_code code,
              return error;
          }

-        if (ethertype != ETH_TYPE_VLAN_8021Q) {
+        if ((ethertype != ETH_TYPE_VLAN_8021Q) &&
+            (ethertype != ETH_TYPE_VLAN_8021AD)) {
              /* XXX ETH_TYPE_VLAN_8021AD case isn't supported */
              return xasprintf("%s: not a valid VLAN ethertype", arg);
          }
diff --git a/lib/packets.c b/lib/packets.c
index 3366089..4acf1b9 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -196,8 +196,9 @@ eth_pop_vlan(struct ofpbuf *packet)
  {
      struct vlan_eth_header *veh = packet->l2;

-    if (packet->size >= sizeof *veh
-        && veh->veth_type == htons(ETH_TYPE_VLAN)) {
+    if (packet->size >= sizeof *veh &&
+	((veh->veth_type == htons(ETH_TYPE_VLAN_8021Q)) ||
+         ((veh->veth_type == htons(ETH_TYPE_VLAN_8021AD))))) {

          memmove((char *)veh + VLAN_HEADER_LEN, veh, 2 * ETH_ADDR_LEN);
          ofpbuf_resize_l2(packet, -VLAN_HEADER_LEN);
-- 
1.7.10.4






More information about the dev mailing list