[ovs-dev] [PATCH 2/5 V6] Flow changes for 802.1ad

Thomas F Herbert thomasfherbert at entpnt.com
Thu Jan 8 21:29:12 UTC 2015


This patch adds support for 802.1ad by adding customer tci and tpid to the
flow structure.

Signed-off-by: Thomas F Herbert <thomasfherbert at entpnt.com>
---
 lib/flow.c     | 22 +++++++++++++---------
 lib/flow.h     | 15 ++++++++++-----
 lib/match.c    |  2 +-
 lib/nx-match.c |  2 +-
 lib/odp-util.h |  2 +-
 lib/ofp-util.c |  2 +-
 6 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/lib/flow.c b/lib/flow.c
index d8a7981..af0cfc8 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -119,7 +119,7 @@ struct mf_ctx {
  * away.  Some GCC versions gave warnings on ALWAYS_INLINE, so these are
  * defined as macros. */
 
-#if (FLOW_WC_SEQ != 29)
+#if (FLOW_WC_SEQ != 30)
 #define MINIFLOW_ASSERT(X) ovs_assert(X)
 BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
                "assertions enabled. Consider updating FLOW_WC_SEQ after "
@@ -287,7 +287,7 @@ parse_vlan(void **datap, size_t *sizep)
 
     data_pull(datap, sizep, ETH_ADDR_LEN * 2);
 
-    if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
+    if (eth_type_vlan(eth->eth_type)) {
         if (OVS_LIKELY(*sizep
                        >= sizeof(struct qtag_prefix) + sizeof(ovs_be16))) {
             const struct qtag_prefix *qp = data_pull(datap, sizep, sizeof *qp);
@@ -762,7 +762,7 @@ flow_unwildcard_tp_ports(const struct flow *flow, struct flow_wildcards *wc)
 void
 flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     fmd->dp_hash = flow->dp_hash;
     fmd->recirc_id = flow->recirc_id;
@@ -909,7 +909,7 @@ void flow_wildcards_init_for_packet(struct flow_wildcards *wc,
     memset(&wc->masks, 0x0, sizeof wc->masks);
 
     /* Update this function whenever struct flow changes. */
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     if (flow->tunnel.ip_dst) {
         if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
@@ -1006,7 +1006,7 @@ uint64_t
 flow_wc_map(const struct flow *flow)
 {
     /* Update this function whenever struct flow changes. */
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     uint64_t map = (flow->tunnel.ip_dst) ? MINIFLOW_MAP(tunnel) : 0;
 
@@ -1058,7 +1058,7 @@ void
 flow_wildcards_clear_non_packet_fields(struct flow_wildcards *wc)
 {
     /* Update this function whenever struct flow changes. */
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
     memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
@@ -1616,7 +1616,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
         flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label));
 
         /* Clear all L3 and L4 fields and dp_hash. */
-        BUILD_ASSERT(FLOW_WC_SEQ == 29);
+        BUILD_ASSERT(FLOW_WC_SEQ == 30);
         memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
                sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
         flow->dp_hash = 0;
@@ -1803,8 +1803,12 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
         return;
     }
 
-    if (flow->vlan_tci & htons(VLAN_CFI)) {
-        eth_push_vlan(b, htons(ETH_TYPE_VLAN), flow->vlan_tci);
+    if (flow->vlan_tci & htons(VLAN_CFI) &&
+        (flow->vlan_ctci & htons(VLAN_CFI))) {
+        eth_push_vlan(b, htons(ETH_TYPE_VLAN_8021Q), flow->vlan_ctci);
+        eth_push_vlan(b, htons(ETH_TYPE_VLAN_8021AD), flow->vlan_tci);
+    } else if (flow->vlan_tci & htons(VLAN_CFI)) {
+        eth_push_vlan(b, htons(ETH_TYPE_VLAN_8021Q), flow->vlan_tci);
     }
 
     if (flow->dl_type == htons(ETH_TYPE_IP)) {
diff --git a/lib/flow.h b/lib/flow.h
index 17b9b86..0335044 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -38,7 +38,7 @@ struct pkt_metadata;
 /* This sequence number should be incremented whenever anything involving flows
  * or the wildcarding of flows changes.  This will cause build assertion
  * failures in places which likely need to be updated. */
-#define FLOW_WC_SEQ 29
+#define FLOW_WC_SEQ 30
 
 /* Number of Open vSwitch extension 32-bit registers. */
 #define FLOW_N_REGS 8
@@ -112,7 +112,12 @@ struct flow {
     uint8_t dl_dst[ETH_ADDR_LEN]; /* Ethernet destination address. */
     uint8_t dl_src[ETH_ADDR_LEN]; /* Ethernet source address. */
     ovs_be16 dl_type;           /* Ethernet frame type. */
-    ovs_be16 vlan_tci;          /* If 802.1Q, TCI | VLAN_CFI; otherwise 0. */
+    ovs_be16 vlan_tci;          /* If 802.1Q, TCI | VLAN_CFI; If 802.1ad,
+                                   outer tag | VLAN_CFI */
+    ovs_be16 vlan_ctci;         /* If 802.1ad, This is Customer TCI | VLAN_CFI,
+                                   inner tag */
+    ovs_be16 vlan_tpid;         /* Vlan protocol type, either 802.1ad or 802.1q. */
+    ovs_be32 pad2;              /* Pad to 64 bits. */
     ovs_be32 mpls_lse[ROUND_UP(FLOW_MAX_MPLS_LABELS, 2)]; /* MPLS label stack
                                                              (with padding). */
     /* L3 (64-bit aligned) */
@@ -129,7 +134,7 @@ struct flow {
     uint8_t arp_sha[ETH_ADDR_LEN]; /* ARP/ND source hardware address. */
     uint8_t arp_tha[ETH_ADDR_LEN]; /* ARP/ND target hardware address. */
     ovs_be16 tcp_flags;         /* TCP flags. With L3 to avoid matching L4. */
-    ovs_be16 pad2;              /* Pad to 64 bits. */
+    ovs_be16 pad3;              /* Pad to 64 bits. */
 
     /* L4 (64-bit aligned) */
     ovs_be16 tp_src;            /* TCP/UDP/SCTP source port. */
@@ -154,8 +159,8 @@ BUILD_ASSERT_DECL(sizeof(struct flow) % sizeof(uint64_t) == 0);
 
 /* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
 BUILD_ASSERT_DECL(offsetof(struct flow, igmp_group_ip4) + sizeof(uint32_t)
-                  == sizeof(struct flow_tnl) + 184
-                  && FLOW_WC_SEQ == 29);
+                  == sizeof(struct flow_tnl) + 192
+                  && FLOW_WC_SEQ == 30);
 
 /* Incremental points at which flow classification may be performed in
  * segments.
diff --git a/lib/match.c b/lib/match.c
index b5bea5d..1711e51 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -870,7 +870,7 @@ match_format(const struct match *match, struct ds *s, int priority)
 
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     if (priority != OFP_DEFAULT_PRIORITY) {
         ds_put_format(s, "priority=%d,", priority);
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 1f72a84..19214eb 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -817,7 +817,7 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
     int match_len;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     /* Metadata. */
     if (match->wc.masks.dp_hash) {
diff --git a/lib/odp-util.h b/lib/odp-util.h
index b361795..87004db 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -133,7 +133,7 @@ void odp_portno_names_destroy(struct hmap *portno_names);
  * add another field and forget to adjust this value.
  */
 #define ODPUTIL_FLOW_KEY_BYTES 512
-BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
 /* A buffer with sufficient size and alignment to hold an nlattr-formatted flow
  * key.  An array of "struct nlattr" might not, in theory, be sufficiently
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 53982d5..92e68d5 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -186,7 +186,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
 void
 ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 29);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 30);
 
     /* Initialize most of wc. */
     flow_wildcards_init_catchall(wc);
-- 
1.8.3.2




More information about the dev mailing list