packets: First-hop router redundancy protocol MAC addresses are not BPDUs.
authorBen Pfaff <blp@nicira.com>
Thu, 26 Jul 2012 04:37:59 +0000 (21:37 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 26 Jul 2012 23:29:30 +0000 (16:29 -0700)
Commit c93f9a78c349 (packets: Update the reserved protocols list.) added
a number of first-hop router redundancy protocol MAC addresses to the
list of BPDU MAC addresses.  This means that packets destined to those MAC
addresses are dropped when other-config:forward-bpdu is set to false on a
bridge (the default setting).

However, this behavior is incorrect, because these MAC addresses are not
special in the way that, say, STP frames are special.  STP is a
switch-to-switch protocol that end hosts have no use for, but end hosts do
speak directly to routers on the MAC addresses assigned by VRRP and the
other protocols in this category.  Therefore, dropping packets in this
category means that end hosts can no longer talk to their first-hop router,
if that router is running one of these protocols.

This commit also refines the match used for EDP and EAPS, and adds Cisco
CFM to the protocols that are dropped.

After this commit, the following destination MACs are dropped:

    - 01:08:c2:00:00:00
    - 01:08:c2:00:00:01
    - 01:08:c2:00:00:02
    - 01:08:c2:00:00:03
    - 01:08:c2:00:00:04
    - 01:08:c2:00:00:05
    - 01:08:c2:00:00:06
    - 01:08:c2:00:00:07
    - 01:08:c2:00:00:08
    - 01:08:c2:00:00:09
    - 01:08:c2:00:00:0a
    - 01:08:c2:00:00:0b
    - 01:08:c2:00:00:0c
    - 01:08:c2:00:00:0d
    - 01:08:c2:00:00:0e
    - 01:08:c2:00:00:0f

    - 00:e0:2b:00:00:00
    - 00:e0:2b:00:00:04
    - 00:e0:2b:00:00:06

    - 01:00:0c:00:00:00
    - 01:00:0c:cc:cc:cc
    - 01:00:0c:cc:cc:cd
    - 01:00:0c:cd:cd:cd

    - 01:00:0c:cc:cc:c0
    - 01:00:0c:cc:cc:c1
    - 01:00:0c:cc:cc:c2
    - 01:00:0c:cc:cc:c3
    - 01:00:0c:cc:cc:c4
    - 01:00:0c:cc:cc:c5
    - 01:00:0c:cc:cc:c6
    - 01:00:0c:cc:cc:c7

Bug #12618.
CC: Ben Basler <bbasler@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/packets.c
vswitchd/vswitch.xml

index 57291674ac5db6ce38d6bb0379e93dc2560f994c..687a84c5d2a461de791fb8ed28b5e2dd4019c8ad 100644 (file)
@@ -24,6 +24,7 @@
 #include "byte-order.h"
 #include "csum.h"
 #include "flow.h"
+#include "hmap.h"
 #include "dynamic-string.h"
 #include "ofpbuf.h"
 
@@ -43,65 +44,77 @@ dpid_from_string(const char *s, uint64_t *dpidp)
     return *dpidp != 0;
 }
 
-/* Returns true if 'ea' is a reserved multicast address, that a bridge must
- * never forward, false otherwise.  Includes some proprietary vendor protocols
- * that shouldn't be forwarded as well.
+/* Returns true if 'ea' is a reserved address, that a bridge must never
+ * forward, false otherwise.
  *
  * If you change this function's behavior, please update corresponding
  * documentation in vswitch.xml at the same time. */
 bool
 eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN])
 {
-    struct masked_eth_addr {
-        uint8_t ea[ETH_ADDR_LEN];
-        uint8_t mask[ETH_ADDR_LEN];
+    struct eth_addr_node {
+        struct hmap_node hmap_node;
+        uint64_t ea64;
     };
 
-    static struct masked_eth_addr mea[] = {
-        { /* STP, IEEE pause frames, and other reserved protocols. */
-            {0x01, 0x08, 0xc2, 0x00, 0x00, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xff, 0xf0}},
-
-        { /* VRRP IPv4. */
-            {0x00, 0x00, 0x5e, 0x00, 0x01, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xff, 0x00}},
-
-        { /* VRRP IPv6. */
-            {0x00, 0x00, 0x5e, 0x00, 0x02, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xff, 0x00}},
-
-        { /* HSRPv1. */
-            {0x00, 0x00, 0x0c, 0x07, 0xac, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xff, 0x00}},
-
-        { /* HSRPv2. */
-            {0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xf0, 0x00}},
-
-        { /* GLBP. */
-            {0x00, 0x07, 0xb4, 0x00, 0x00, 0x00},
-            {0xff, 0xff, 0xff, 0x00, 0x00, 0x00}},
-
-        { /* Extreme Discovery Protocol. */
-            {0x00, 0xE0, 0x2B, 0x00, 0x00, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xf0, 0x00}},
-
-        { /* Cisco Inter Switch Link. */
-            {0x01, 0x00, 0x0c, 0x00, 0x00, 0x00},
-            {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+    static struct eth_addr_node nodes[] = {
+        /* STP, IEEE pause frames, and other reserved protocols. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000000ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000001ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000002ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000003ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000004ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000005ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000006ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000007ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000008ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000009ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000aULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000bULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000cULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000dULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000eULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000fULL },
+
+        /* Extreme protocols. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000000ULL }, /* EDP. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000004ULL }, /* EAPS. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000006ULL }, /* EAPS. */
+
+        /* Cisco protocols. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000c000000ULL }, /* ISL. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccccULL }, /* PAgP, UDLD, CDP,
+                                                            * DTP, VTP. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000ccccccdULL }, /* PVST+. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000ccdcdcdULL }, /* STP Uplink Fast,
+                                                            * FlexLink. */
+
+        /* Cisco CFM. */
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc0ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc1ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc2ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc3ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc4ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc5ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc6ULL },
+        { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc7ULL },
+    };
 
-        { /* Cisco protocols plus others following the same pattern:
-           *
-           * CDP, VTP, DTP, PAgP  (01-00-0c-cc-cc-cc)
-           * Spanning Tree PVSTP+ (01-00-0c-cc-cc-cd)
-           * STP Uplink Fast      (01-00-0c-cd-cd-cd) */
-            {0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc},
-            {0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe}}};
+    static struct hmap addrs = HMAP_INITIALIZER(&addrs);
+    struct eth_addr_node *node;
+    uint64_t ea64;
 
-    size_t i;
+    if (hmap_is_empty(&addrs)) {
+        for (node = nodes; node < &nodes[ARRAY_SIZE(nodes)]; node++) {
+            hmap_insert(&addrs, &node->hmap_node,
+                        hash_2words(node->ea64, node->ea64 >> 32));
+        }
+    }
 
-    for (i = 0; i < ARRAY_SIZE(mea); i++) {
-        if (eth_addr_equal_except(ea, mea[i].ea, mea[i].mask)) {
+    ea64 = eth_addr_to_uint64(ea);
+    HMAP_FOR_EACH_IN_BUCKET (node, hmap_node, hash_2words(ea64, ea64 >> 32),
+                             &addrs) {
+        if (node->ea64 == ea64) {
             return true;
         }
     }
index e6ea844fe1bc023608b2f6d0d36944f9e941bc2a..13d24b69f47442f50e08640ffbc9435003fa47d9 100644 (file)
           <dt><code>01:80:c2:00:00:0<var>x</var></code></dt>
           <dd>Other reserved protocols.</dd>
 
-          <dt><code>00:00:5e:00:01:<var>x</var><var>x</var></code></dt>
-          <dd> VRRP IPv4 virtual router MAC address. </dd>
+          <dt><code>00:e0:2b:00:00:00</code></dt>
+          <dd>Extreme Discovery Protocol (EDP).</dd>
 
-          <dt><code>00:00:5e:00:02:<var>x</var><var>x</var></code></dt>
-          <dd> VRRP IPv6 virtual router MAC address. </dd>
-
-          <dt><code>00:00:0c:07:ac:<var>x</var><var>x</var></code></dt>
-          <dd> HSRP Version 1. </dd>
-
-          <dt><code>00:00:0c:9f:f<var>x</var>:<var>x</var><var>x</var></code>
-          </dt>
-          <dd> HSRP Version 2. </dd>
-
-          <dt><code>00:07:b4:<var>x</var><var>x</var>:<var>x</var><var>x</var>:<var>x</var><var>x</var></code></dt>
-          <dd> GLBP. </dd>
+          <dt>
+           <code>00:e0:2b:00:00:04</code> and <code>00:e0:2b:00:00:06</code>
+         </dt>
+          <dd>Ethernet Automatic Protection Switching (EAPS).</dd>
 
           <dt><code>01:00:0c:cc:cc:cc</code></dt>
           <dd>
 
           <dt><code>01:00:0c:00:00:00</code></dt>
           <dd>Cisco Inter Switch Link.</dd>
+
+          <dt><code>01:00:0c:cc:cc:c<var>x</var></code></dt>
+          <dd>Cisco CFM.</dd>
         </dl>
       </column>