diff options
author | Ethan Jackson <ethan@nicira.com> | 2012-06-01 14:33:41 -0700 |
---|---|---|
committer | Ethan Jackson <ethan@nicira.com> | 2012-06-06 17:43:33 -0700 |
commit | 05be4e2c6af8ce22bd262820bc951c9408a6de3d (patch) | |
tree | ad8f06e08b7034bff99b419df391cad4a8841e76 /lib/packets.c | |
parent | 3b842fc2f0f8367d7d1350a80f7c29edca0925b5 (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.c | 41 |
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]) { |