diff --git a/controller/ofctrl.c b/controller/ofctrl.c index 0a898c0831..63b0aa975b 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -928,14 +928,6 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type) } } -//TODO -void -ofctrl_reconnect(void) -{ - VLOG_INFO("Trigger OpenFlow re-connection."); - rconn_reconnect(swconn); -} - static bool flow_action_has_drop(const struct ovn_flow *f) { diff --git a/controller/ofctrl.h b/controller/ofctrl.h index 4ac2c8fd68..105f9370be 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -145,7 +145,4 @@ bool ofctrl_is_connected(void); void ofctrl_set_probe_interval(int probe_interval); void ofctrl_get_memory_usage(struct simap *usage); -//TODO -void ofctrl_reconnect(void); - #endif /* controller/ofctrl.h */ diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 07ca1f8274..c51a18a23d 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -5654,10 +5654,9 @@ main(int argc, char *argv[]) br_int ? br_int->name : NULL)) { VLOG_INFO("OVS feature set changed, force recompute."); engine_set_force_recompute(true); - ofctrl_reconnect(); } - if (br_int) { + if (br_int && ovs_feature_set_negotiated()) { ct_zones_data = engine_get_data(&en_ct_zones); if (ct_zones_data && ofctrl_run(br_int, ovs_table, &ct_zones_data->pending)) { diff --git a/include/ovn/features.h b/include/ovn/features.h index 06de5e081b..863acc7a08 100644 --- a/include/ovn/features.h +++ b/include/ovn/features.h @@ -49,6 +49,7 @@ void ovs_feature_support_destroy(void); bool ovs_feature_is_supported(enum ovs_feature_value feature); bool ovs_feature_support_run(const struct smap *ovs_capabilities, const char *br_name); +bool ovs_feature_set_negotiated(void); uint32_t ovs_feature_max_meters_get(void); uint32_t ovs_feature_max_select_groups_get(void); diff --git a/lib/features.c b/lib/features.c index a1f1ced438..baec95bb53 100644 --- a/lib/features.c +++ b/lib/features.c @@ -82,8 +82,12 @@ static struct ovs_feature all_ovs_features[] = { /* A bitmap of OVS features that have been detected as 'supported'. */ static uint32_t supported_ovs_features; +static struct ofputil_meter_features supported_ovs_meter_features_reply; +static struct ofputil_group_features supported_ovs_group_features_reply; + static struct ofputil_meter_features supported_ovs_meter_features; static struct ofputil_group_features supported_ovs_group_features; +static uint32_t features_reply_expected; static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); @@ -149,14 +153,19 @@ ovs_feature_get_openflow_cap(const char *br_name) /* send new requests just after reconnect. */ if (conn_seq_no != rconn_get_connection_seqno(swconn)) { + features_reply_expected = 0; + /* dump datapath meter capabilities. */ msg = ofpraw_alloc(OFPRAW_OFPST13_METER_FEATURES_REQUEST, rconn_get_version(swconn), 0); rconn_send(swconn, msg, NULL); + features_reply_expected++; /* dump datapath group capabilities. */ msg = ofputil_encode_group_features_request(rconn_get_version(swconn)); rconn_send(swconn, msg, NULL); + features_reply_expected++; } + conn_seq_no = rconn_get_connection_seqno(swconn); bool ret = false; for (int i = 0; i < 50; i++) { @@ -170,35 +179,41 @@ ovs_feature_get_openflow_cap(const char *br_name) ofptype_decode(&type, oh); if (type == OFPTYPE_METER_FEATURES_STATS_REPLY) { - struct ofputil_meter_features mf; - - ofputil_decode_meter_features(oh, &mf); - if (memcmp(&supported_ovs_meter_features, &mf, sizeof mf)) { - supported_ovs_meter_features = mf; - if (supported_ovs_meter_features.max_meters) { - supported_ovs_features |= OVS_DP_METER_SUPPORT; - } else { - supported_ovs_features &= ~OVS_DP_METER_SUPPORT; - } - ret = true; - } + ofputil_decode_meter_features(oh, &supported_ovs_meter_features_reply); + ovs_assert(features_reply_expected); + features_reply_expected--; } else if (type == OFPTYPE_GROUP_FEATURES_STATS_REPLY) { - struct ofputil_group_features gf; - - ofputil_decode_group_features_reply(oh, &gf); - if (memcmp(&supported_ovs_group_features, &gf, sizeof gf)) { - supported_ovs_group_features = gf; - ret = true; - } + ofputil_decode_group_features_reply(oh, &supported_ovs_group_features_reply); + ovs_assert(features_reply_expected); + features_reply_expected--; } else if (type == OFPTYPE_ECHO_REQUEST) { rconn_send(swconn, ofputil_encode_echo_reply(oh), NULL); } - conn_seq_no = rconn_get_connection_seqno(swconn); ofpbuf_delete(msg); } rconn_run_wait(swconn); rconn_recv_wait(swconn); + if (!features_reply_expected) { + if (memcmp(&supported_ovs_meter_features, + &supported_ovs_meter_features_reply, + sizeof supported_ovs_meter_features_reply)) { + supported_ovs_meter_features = supported_ovs_meter_features_reply; + if (supported_ovs_meter_features.max_meters) { + supported_ovs_features |= OVS_DP_METER_SUPPORT; + } else { + supported_ovs_features &= ~OVS_DP_METER_SUPPORT; + } + ret = true; + } + if (memcmp(&supported_ovs_group_features, + &supported_ovs_group_features_reply, + sizeof supported_ovs_group_features_reply)) { + supported_ovs_group_features = supported_ovs_group_features_reply; + ret = true; + } + } + return ret; } @@ -243,6 +258,13 @@ ovs_feature_support_run(const struct smap *ovs_capabilities, return updated; } +bool +ovs_feature_set_negotiated(void) +{ + //TODO: comment + return features_reply_expected == 0; +} + /* Returns the number of meters the OVS datapath supports. */ uint32_t ovs_feature_max_meters_get(void)