X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Flearning-switch.c;h=9c1aff7a4fcee08c2ce1249f6755c7cd71d2e058;hb=de8d2ef9dd141f4a96d4b79afbfadb3c4eb042c7;hp=9e028608c72d6270ba1e98f1fd60f9a9938692f1;hpb=10a89ef04df5669c5cdd02f786150a7ab8454e01;p=sliver-openvswitch.git diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 9e028608c..9c1aff7a4 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -251,7 +251,9 @@ lswitch_run(struct lswitch *sw) int i; if (sw->ml) { - mac_learning_run(sw->ml, NULL); + ovs_rwlock_wrlock(&sw->ml->rwlock); + mac_learning_run(sw->ml); + ovs_rwlock_unlock(&sw->ml->rwlock); } rconn_run(sw->rconn); @@ -283,7 +285,9 @@ void lswitch_wait(struct lswitch *sw) { if (sw->ml) { + ovs_rwlock_rdlock(&sw->ml->rwlock); mac_learning_wait(sw->ml); + ovs_rwlock_unlock(&sw->ml->rwlock); } rconn_run_wait(sw->rconn); rconn_recv_wait(sw->rconn); @@ -378,20 +382,20 @@ lswitch_process_packet(struct lswitch *sw, const struct ofpbuf *msg) case OFPTYPE_GET_ASYNC_REPLY: case OFPTYPE_SET_ASYNC_CONFIG: case OFPTYPE_METER_MOD: - case OFPTYPE_GROUP_REQUEST: - case OFPTYPE_GROUP_REPLY: - case OFPTYPE_GROUP_DESC_REQUEST: - case OFPTYPE_GROUP_DESC_REPLY: - case OFPTYPE_GROUP_FEATURES_REQUEST: - case OFPTYPE_GROUP_FEATURES_REPLY: - case OFPTYPE_METER_REQUEST: - case OFPTYPE_METER_REPLY: - case OFPTYPE_METER_CONFIG_REQUEST: - case OFPTYPE_METER_CONFIG_REPLY: - case OFPTYPE_METER_FEATURES_REQUEST: - case OFPTYPE_METER_FEATURES_REPLY: - case OFPTYPE_TABLE_FEATURES_REQUEST: - case OFPTYPE_TABLE_FEATURES_REPLY: + case OFPTYPE_GROUP_STATS_REQUEST: + case OFPTYPE_GROUP_STATS_REPLY: + case OFPTYPE_GROUP_DESC_STATS_REQUEST: + case OFPTYPE_GROUP_DESC_STATS_REPLY: + case OFPTYPE_GROUP_FEATURES_STATS_REQUEST: + case OFPTYPE_GROUP_FEATURES_STATS_REPLY: + case OFPTYPE_METER_STATS_REQUEST: + case OFPTYPE_METER_STATS_REPLY: + case OFPTYPE_METER_CONFIG_STATS_REQUEST: + case OFPTYPE_METER_CONFIG_STATS_REPLY: + case OFPTYPE_METER_FEATURES_STATS_REQUEST: + case OFPTYPE_METER_FEATURES_STATS_REPLY: + case OFPTYPE_TABLE_FEATURES_STATS_REQUEST: + case OFPTYPE_TABLE_FEATURES_STATS_REPLY: default: if (VLOG_IS_DBG_ENABLED()) { char *s = ofp_to_string(msg->data, msg->size, 2); @@ -472,18 +476,19 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) ofp_port_t out_port; /* Learn the source MAC. */ + ovs_rwlock_wrlock(&sw->ml->rwlock); if (mac_learning_may_learn(sw->ml, flow->dl_src, 0)) { struct mac_entry *mac = mac_learning_insert(sw->ml, flow->dl_src, 0); - if (mac_entry_is_new(mac) - || mac->port.ofp_port != flow->in_port.ofp_port) { + if (mac->port.ofp_port != flow->in_port.ofp_port) { VLOG_DBG_RL(&rl, "%016llx: learned that "ETH_ADDR_FMT" is on " "port %"PRIu16, sw->datapath_id, ETH_ADDR_ARGS(flow->dl_src), flow->in_port.ofp_port); mac->port.ofp_port = flow->in_port.ofp_port; - mac_learning_changed(sw->ml, mac); + mac_learning_changed(sw->ml); } } + ovs_rwlock_unlock(&sw->ml->rwlock); /* Drop frames for reserved multicast addresses. */ if (eth_addr_is_reserved(flow->dl_dst)) { @@ -494,14 +499,17 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) if (sw->ml) { struct mac_entry *mac; - mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0, NULL); + ovs_rwlock_rdlock(&sw->ml->rwlock); + mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0); if (mac) { out_port = mac->port.ofp_port; if (out_port == flow->in_port.ofp_port) { /* Don't send a packet back out its input port. */ + ovs_rwlock_unlock(&sw->ml->rwlock); return OFPP_NONE; } } + ovs_rwlock_unlock(&sw->ml->rwlock); } /* Check if we need to use "NORMAL" action. */