Finding a given port is faster.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Daniele Venturino <daniele.venturino@m3s.it>
#include "rstp.h"
#include <stdbool.h>
#include <stdint.h>
+#include "hmap.h"
#include "list.h"
#include "ovs-atomic.h"
#include "packets.h"
struct ovs_refcount ref_cnt;
struct rstp *rstp OVS_GUARDED_BY(rstp_mutex);
- struct list node OVS_GUARDED_BY(rstp_mutex); /* Node in rstp->ports list. */
+ struct hmap_node node OVS_GUARDED_BY(rstp_mutex); /* In rstp->ports. */
void *aux OVS_GUARDED_BY(rstp_mutex);
struct rstp_bpdu received_bpdu_buffer OVS_GUARDED_BY(rstp_mutex);
/*************************************************************************
bool stp_version OVS_GUARDED_BY(rstp_mutex);
/* Ports */
- struct list ports OVS_GUARDED_BY(rstp_mutex);
+ struct hmap ports OVS_GUARDED_BY(rstp_mutex);
struct ovs_refcount ref_cnt;
rstp->changes = false;
port_role_selection_sm(rstp);
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
if (p->rstp_state != RSTP_DISABLED) {
port_receive_sm(p);
bridge_detection_sm(p);
{
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
decrement_timer(&p->hello_when);
decrement_timer(&p->tc_while);
decrement_timer(&p->fd_while);
{
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
p->selected_role = ROLE_DISABLED;
}
}
{
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
p->reselect = false;
}
}
/* Letter c1) */
r->root_times = r->bridge_times;
/* Letters a) b) c) */
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
uint32_t old_root_path_cost;
uint32_t root_path_cost;
VLOG_DBG("%s: new Root is "RSTP_ID_FMT, r->name,
RSTP_ID_ARGS(r->root_priority.root_bridge_id));
/* Letters d) e) */
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
p->designated_priority_vector.root_bridge_id =
r->root_priority.root_bridge_id;
p->designated_priority_vector.root_path_cost =
p->designated_times = r->root_times;
p->designated_times.hello_time = r->bridge_times.hello_time;
}
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
switch (p->info_is) {
case INFO_IS_DISABLED:
p->selected_role = ROLE_DISABLED;
{
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
if (p->reselect) {
return;
}
}
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
p->selected = true;
}
}
PORT_ROLE_SELECTION_SM_ROLE_SELECTION;
/* no break */
case PORT_ROLE_SELECTION_SM_ROLE_SELECTION:
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
if (p->reselect) {
r->port_role_selection_sm_state =
PORT_ROLE_SELECTION_SM_ROLE_SELECTION_EXEC;
struct rstp_port *p1;
r = p->rstp;
- LIST_FOR_EACH (p1, node, &r->ports) {
+ HMAP_FOR_EACH (p1, node, &r->ports) {
p1->re_root = true;
}
}
struct rstp_port *p1;
r = p->rstp;
- LIST_FOR_EACH (p1, node, &r->ports) {
+ HMAP_FOR_EACH (p1, node, &r->ports) {
p1->sync = true;
}
}
struct rstp_port *p1;
r = p->rstp;
- LIST_FOR_EACH (p1, node, &r->ports) {
+ HMAP_FOR_EACH (p1, node, &r->ports) {
if ((p1 != p) && (p1->rr_while != 0)) {
return false;
}
{
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &r->ports) {
+ HMAP_FOR_EACH (p, node, &r->ports) {
if (!(p->selected && p->role == p->selected_role &&
(p->role == ROLE_ROOT || p->synced == true))) {
return false;
struct rstp_port *p1;
r = p->rstp;
- LIST_FOR_EACH (p1, node, &r->ports) {
+ HMAP_FOR_EACH (p1, node, &r->ports) {
/* Set tc_prop on every port, except the one calling this
* function. */
if (p1->port_number != p->port_number) {
* ports from one bridge to another, and holders always
* release their ports before releasing the bridge. This
* means that there should be not ports at this time. */
- ovs_assert(list_is_empty(&rstp->ports));
+ ovs_assert(hmap_is_empty(&rstp->ports));
list_remove(&rstp->node);
ovs_mutex_unlock(&rstp_mutex);
rstp = xzalloc(sizeof *rstp);
rstp->name = xstrdup(name);
- /* Initialize the ports list before calling any setters,
- * so that the state machines will see an empty ports list. */
- list_init(&rstp->ports);
+ /* Initialize the ports map before calling any setters,
+ * so that the state machines will see an empty ports map. */
+ hmap_init(&rstp->ports);
ovs_mutex_lock(&rstp_mutex);
/* Set bridge address. */
/* [17.13] When the bridge address changes, recalculates all priority
* vectors.
*/
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
p->selected = false;
p->reselect = true;
}
OVS_REQUIRES(rstp_mutex)
{
struct rstp temp;
- static struct list ports;
+ static struct hmap ports;
struct rstp_port *p;
/* Copy rstp in temp */
/* Initialize rstp. */
rstp->name = temp.name;
- /* Initialize the ports list before calling any setters,
+ /* Initialize the ports hmap before calling any setters,
* so that the state machines will see an empty ports list. */
- list_init(&rstp->ports);
+ hmap_init(&rstp->ports);
/* Set bridge address. */
rstp_set_bridge_address__(rstp, temp.address);
/* Restore ports. */
rstp->ports = ports;
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
reinitialize_port__(p);
}
/* Resetting txCount on all ports [17.13]. */
rstp->transmit_hold_count = new_transmit_hold_count;
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
p->tx_count = 0;
}
}
needs_flush = false;
ovs_mutex_lock(&rstp_mutex);
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
if (p->fdb_flush) {
needs_flush = true;
/* fdb_flush should be reset by the filtering database
if (*portp == NULL) {
struct rstp_port *p;
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
if (p->state_changed) {
p->state_changed = false;
aux = p->aux;
} else { /* continue */
struct rstp_port *p = *portp;
- LIST_FOR_EACH_CONTINUE (p, node, &rstp->ports) {
+ HMAP_FOR_EACH_CONTINUE (p, node, &rstp->ports) {
if (p->state_changed) {
p->state_changed = false;
aux = p->aux;
ovs_assert(rstp && port_number > 0 && port_number <= RSTP_MAX_PORTS);
- LIST_FOR_EACH (port, node, &rstp->ports) {
+ HMAP_FOR_EACH_WITH_HASH (port, node, hash_int(port_number, 0),
+ &rstp->ports) {
if (port->port_number == port_number) {
return port;
}
p->port_id);
rstp_port_set_state__(p, RSTP_DISCARDING);
- list_push_back(&rstp->ports, &p->node);
+ hmap_insert(&rstp->ports, &p->node, hash_int(p->port_number, 0));
rstp->changes = true;
move_rstp__(rstp);
VLOG_DBG("%s: added port "RSTP_PORT_ID_FMT"", rstp->name, p->port_id);
ovs_mutex_lock(&rstp_mutex);
rstp = rp->rstp;
rstp_port_set_state__(rp, RSTP_DISABLED);
- list_remove(&rp->node);
+ hmap_remove(&rstp->ports, &rp->node);
VLOG_DBG("%s: removed port "RSTP_PORT_ID_FMT"", rstp->name,
rp->port_id);
ovs_mutex_unlock(&rstp_mutex);
struct rstp_port *p;
ovs_mutex_lock(&rstp_mutex);
- LIST_FOR_EACH (p, node, &rstp->ports) {
+ HMAP_FOR_EACH (p, node, &rstp->ports) {
if (p->port_id == rstp->root_port_id) {
ovs_mutex_unlock(&rstp_mutex);
return p;