diff --git a/controller/ofctrl.c b/controller/ofctrl.c index a1676a7883..c19cc7d4a6 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -928,6 +928,14 @@ 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 105f9370be..4ac2c8fd68 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -145,4 +145,7 @@ 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 1349bdb011..50ea1ca9e7 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -5664,6 +5664,7 @@ 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) { diff --git a/include/ovn/features.h b/include/ovn/features.h index 7c3004b271..06de5e081b 100644 --- a/include/ovn/features.h +++ b/include/ovn/features.h @@ -49,5 +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); +uint32_t ovs_feature_max_meters_get(void); +uint32_t ovs_feature_max_select_groups_get(void); #endif diff --git a/lib/features.c b/lib/features.c index d24e8f6c5c..a6de84d1e8 100644 --- a/lib/features.c +++ b/lib/features.c @@ -27,6 +27,7 @@ #include "openvswitch/rconn.h" #include "openvswitch/ofp-msgs.h" #include "openvswitch/ofp-meter.h" +#include "openvswitch/ofp-group.h" #include "openvswitch/ofp-util.h" #include "ovn/features.h" @@ -81,6 +82,9 @@ 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; +static struct ofputil_group_features supported_ovs_group_features; + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); /* ovs-vswitchd connection. */ @@ -149,6 +153,9 @@ ovs_feature_get_openflow_cap(const char *br_name) msg = ofpraw_alloc(OFPRAW_OFPST13_METER_FEATURES_REQUEST, rconn_get_version(swconn), 0); rconn_send(swconn, msg, NULL); + /* dump datapath group capabilities. */ + msg = ofputil_encode_group_features_request(rconn_get_version(swconn)); + rconn_send(swconn, msg, NULL); } bool ret = false; @@ -164,23 +171,29 @@ ovs_feature_get_openflow_cap(const char *br_name) if (type == OFPTYPE_METER_FEATURES_STATS_REPLY) { struct ofputil_meter_features mf; - ofputil_decode_meter_features(oh, &mf); - - bool old_state = supported_ovs_features & OVS_DP_METER_SUPPORT; - bool new_state = mf.max_meters > 0; - if (old_state != new_state) { - ret = true; - if (new_state) { + 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; + } + } 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; } - conn_seq_no = rconn_get_connection_seqno(swconn); } 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); @@ -229,3 +242,17 @@ ovs_feature_support_run(const struct smap *ovs_capabilities, } return updated; } + +/* Returns the number of meters the OVS datapath supports. */ +uint32_t +ovs_feature_max_meters_get(void) +{ + return supported_ovs_meter_features.max_meters; +} + +/* Returns the number of select groups the OVS datapath supports. */ +uint32_t +ovs_feature_max_select_groups_get(void) +{ + return supported_ovs_group_features.max_groups[OFPGT11_SELECT]; +} \ No newline at end of file