aboutsummaryrefslogtreecommitdiff
path: root/lib/packets.c
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2012-06-01 14:33:41 -0700
committerEthan Jackson <ethan@nicira.com>2012-06-06 17:43:33 -0700
commit05be4e2c6af8ce22bd262820bc951c9408a6de3d (patch)
treead8f06e08b7034bff99b419df391cad4a8841e76 /lib/packets.c
parent3b842fc2f0f8367d7d1350a80f7c29edca0925b5 (diff)
packets: Generalize reserved RSPAN protocols.
Open vSwitch refuses to mirror certain destination addresses in addition to those classified by eth_addr_is_reserved(). Looking through the uses of eth_addr_is_reserved(), one finds that no callers should be using the additional addresses which mirroring drops. This patch folds the additional addresses dropped in the mirroring code, into the more general eth_addr_is_reserverd() function. This patch also changes the implementation in a way that is slightly less efficient, but much easier to read and extend int he future. Bug #11755. Signed-off-by: Ethan Jackson <ethan@nicira.com>
Diffstat (limited to 'lib/packets.c')
-rw-r--r--lib/packets.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/packets.c b/lib/packets.c
index 631abf83..35829fca 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -43,6 +43,47 @@ 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.
+ *
+ * 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];
+ };
+
+ 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}},
+
+ { /* Cisco Inter Switch Link. */
+ {0x01, 0x00, 0x0c, 0x00, 0x00, 0x00},
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+
+ { /* 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}}};
+
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(mea); i++) {
+ if (eth_addr_equal_except(ea, mea[i].ea, mea[i].mask)) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool
eth_addr_from_string(const char *s, uint8_t ea[ETH_ADDR_LEN])
{