From ec9e7ef14fcb3e83985378407e960d561e289c91 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 15 Jan 2009 16:33:51 -0800 Subject: [PATCH] vswitchd: Avoid mishandling duplicate object names. If a port was named twice in bridge.BRNAME.port, we would add two different ports with the same name to bridge BRNAME. Fix the problem. Also, be more vigilant about duplicate names for other kinds of objects, even though it should be difficult or impossible to end up with them. --- vswitchd/bridge.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 78c1f2db..c0d0eabc 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -292,6 +292,8 @@ bridge_reconfigure(void) /* Get rid of deleted bridges and add new bridges. */ svec_sort(&old_br); svec_sort(&new_br); + assert(svec_is_unique(&old_br)); + assert(svec_is_unique(&new_br)); LIST_FOR_EACH_SAFE (br, next, struct bridge, node, &all_bridges) { if (!svec_contains(&new_br, br->name)) { bridge_destroy(br); @@ -321,8 +323,6 @@ bridge_reconfigure(void) bridge_fetch_dp_ifaces(br, &cur_ifaces); bridge_get_all_ifaces(br, &want_ifaces); - svec_sort(&want_ifaces); - svec_sort(&cur_ifaces); svec_diff(&want_ifaces, &cur_ifaces, NULL, NULL, &del_ifaces); for (i = 0; i < del_ifaces.n; i++) { const char *if_name = del_ifaces.names[i]; @@ -345,8 +345,6 @@ bridge_reconfigure(void) bridge_fetch_dp_ifaces(br, &cur_ifaces); bridge_get_all_ifaces(br, &want_ifaces); - svec_sort(&want_ifaces); - svec_sort(&cur_ifaces); svec_diff(&want_ifaces, &cur_ifaces, &add_ifaces, NULL, NULL); for (i = 0; i < add_ifaces.n; i++) { const char *if_name = add_ifaces.names[i]; @@ -849,7 +847,13 @@ bridge_reconfigure_one(struct bridge *br) /* Get rid of deleted ports and add new ports. */ svec_sort(&old_ports); + assert(svec_is_unique(&old_ports)); svec_sort(&new_ports); + if (!svec_is_unique(&new_ports)) { + VLOG_WARN("bridge %s: %s specified twice as bridge port", + br->name, svec_get_duplicate(&new_ports)); + svec_unique(&new_ports); + } for (i = 0; i < br->n_ports; ) { struct port *port = br->ports[i]; if (!svec_contains(&new_ports, port->name)) { @@ -955,6 +959,8 @@ bridge_get_all_ifaces(const struct bridge *br, struct svec *ifaces) svec_add(ifaces, iface->name); } } + svec_sort(ifaces); + assert(svec_is_unique(ifaces)); } static bool @@ -1050,6 +1056,15 @@ bridge_fetch_dp_ifaces(struct bridge *br, struct svec *iface_names) } retval = 0; + if (iface_names) { + svec_sort(iface_names); + if (!svec_is_unique(iface_names)) { + VLOG_WARN("datapath nl:%d reported interface named %s twice", + br->dp_idx, svec_get_duplicate(iface_names)); + svec_unique(iface_names); + } + } + done: vconn_close(vconn); ofpbuf_delete(reply); @@ -2618,7 +2633,9 @@ mirror_reconfigure(struct bridge *br) /* Get rid of deleted mirrors and add new mirrors. */ svec_sort(&old_mirrors); + assert(svec_is_unique(&old_mirrors)); svec_sort(&new_mirrors); + assert(svec_is_unique(&new_mirrors)); for (i = 0; i < MAX_MIRRORS; i++) { struct mirror *m = br->mirrors[i]; if (m && !svec_contains(&new_mirrors, m->name)) { @@ -2714,8 +2731,7 @@ prune_ports(struct mirror *m, struct svec *ports) struct svec tmp; size_t i; - svec_sort(ports); - svec_unique(ports); + svec_sort_unique(ports); svec_init(&tmp); for (i = 0; i < ports->n; i++) { @@ -2739,8 +2755,7 @@ prune_vlans(struct mirror *m, struct svec *vlan_strings, int **vlans) /* This isn't perfect: it won't combine "0" and "00", and the textual sort * order won't give us numeric sort order. But that's good enough for what * we need right now. */ - svec_sort(vlan_strings); - svec_unique(vlan_strings); + svec_sort_unique(vlan_strings); *vlans = xmalloc(sizeof *vlans * vlan_strings->n); n_vlans = 0; -- 2.30.2