#include "odp-util.h"
#include "ofp-util.h"
#include "ofpbuf.h"
+#include "ofproto-provider.h"
#include "pinsched.h"
#include "poll-loop.h"
#include "pktbuf.h"
-#include "private.h"
#include "rconn.h"
#include "shash.h"
#include "timeval.h"
/* In-band control. */
struct in_band *in_band;
- long long int next_in_band_update;
struct sockaddr_in *extra_in_band_remotes;
size_t n_extra_remotes;
int in_band_queue;
mgr->fail_mode = OFPROTO_FAIL_SECURE;
mgr->in_band = NULL;
- mgr->next_in_band_update = LLONG_MAX;
mgr->extra_in_band_remotes = NULL;
mgr->n_extra_remotes = 0;
mgr->in_band_queue = -1;
size_t i;
if (handle_openflow && mgr->in_band) {
- if (time_msec() >= mgr->next_in_band_update) {
- update_in_band_remotes(mgr);
+ if (!in_band_run(mgr->in_band)) {
+ in_band_destroy(mgr->in_band);
+ mgr->in_band = NULL;
}
- in_band_run(mgr->in_band);
}
LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
ofconn_wait(ofconn, handling_openflow);
}
if (handling_openflow && mgr->in_band) {
- poll_timer_wait_until(mgr->next_in_band_update);
in_band_wait(mgr->in_band);
}
if (handling_openflow && mgr->fail_open) {
{
const struct ofconn *ofconn;
- shash_init(info);
-
HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
const struct rconn *rconn = ofconn->rconn;
- time_t now = time_now();
- time_t last_connection = rconn_get_last_connection(rconn);
- time_t last_disconnect = rconn_get_last_disconnect(rconn);
- int last_error = rconn_get_last_error(rconn);
- struct ofproto_controller_info *cinfo = xmalloc(sizeof *cinfo);
+ const char *target = rconn_get_target(rconn);
- shash_add(info, rconn_get_target(rconn), cinfo);
+ if (!shash_find(info, target)) {
+ struct ofproto_controller_info *cinfo = xmalloc(sizeof *cinfo);
+ time_t now = time_now();
+ time_t last_connection = rconn_get_last_connection(rconn);
+ time_t last_disconnect = rconn_get_last_disconnect(rconn);
+ int last_error = rconn_get_last_error(rconn);
- cinfo->is_connected = rconn_is_connected(rconn);
- cinfo->role = ofconn->role;
+ shash_add(info, target, cinfo);
- cinfo->pairs.n = 0;
+ cinfo->is_connected = rconn_is_connected(rconn);
+ cinfo->role = ofconn->role;
- if (last_error) {
- cinfo->pairs.keys[cinfo->pairs.n] = "last_error";
- cinfo->pairs.values[cinfo->pairs.n++] =
- xstrdup(ovs_retval_to_string(last_error));
- }
+ cinfo->pairs.n = 0;
- cinfo->pairs.keys[cinfo->pairs.n] = "state";
- cinfo->pairs.values[cinfo->pairs.n++] =
- xstrdup(rconn_get_state(rconn));
+ if (last_error) {
+ cinfo->pairs.keys[cinfo->pairs.n] = "last_error";
+ cinfo->pairs.values[cinfo->pairs.n++]
+ = xstrdup(ovs_retval_to_string(last_error));
+ }
- if (last_connection != TIME_MIN) {
- cinfo->pairs.keys[cinfo->pairs.n] = "sec_since_connect";
+ cinfo->pairs.keys[cinfo->pairs.n] = "state";
cinfo->pairs.values[cinfo->pairs.n++]
- = xasprintf("%ld", (long int) (now - last_connection));
+ = xstrdup(rconn_get_state(rconn));
+
+ if (last_connection != TIME_MIN) {
+ cinfo->pairs.keys[cinfo->pairs.n] = "sec_since_connect";
+ cinfo->pairs.values[cinfo->pairs.n++]
+ = xasprintf("%ld", (long int) (now - last_connection));
+ }
+
+ if (last_disconnect != TIME_MIN) {
+ cinfo->pairs.keys[cinfo->pairs.n] = "sec_since_disconnect";
+ cinfo->pairs.values[cinfo->pairs.n++]
+ = xasprintf("%ld", (long int) (now - last_disconnect));
+ }
}
+ }
+}
- if (last_disconnect != TIME_MIN) {
- cinfo->pairs.keys[cinfo->pairs.n] = "sec_since_disconnect";
- cinfo->pairs.values[cinfo->pairs.n++]
- = xasprintf("%ld", (long int) (now - last_disconnect));
+void
+connmgr_free_controller_info(struct shash *info)
+{
+ struct shash_node *node;
+
+ SHASH_FOR_EACH (node, info) {
+ struct ofproto_controller_info *cinfo = node->data;
+ while (cinfo->pairs.n) {
+ free((char *) cinfo->pairs.values[--cinfo->pairs.n]);
}
+ free(cinfo);
}
+ shash_destroy(info);
}
/* Changes 'mgr''s set of controllers to the 'n_controllers' controllers in
if (!mgr->in_band) {
in_band_create(mgr->ofproto, mgr->local_port_name, &mgr->in_band);
}
- if (mgr->in_band) {
- in_band_set_remotes(mgr->in_band, addrs, n_addrs);
- }
in_band_set_queue(mgr->in_band, mgr->in_band_queue);
- mgr->next_in_band_update = time_msec() + 1000;
} else {
- in_band_destroy(mgr->in_band);
- mgr->in_band = NULL;
+ /* in_band_run() needs a chance to delete any existing in-band flows.
+ * We will destroy mgr->in_band after it's done with that. */
+ }
+ if (mgr->in_band) {
+ in_band_set_remotes(mgr->in_band, addrs, n_addrs);
}
/* Clean up. */