+static void
+update_in_band_remotes(struct ofproto *ofproto)
+{
+ const struct ofconn *ofconn;
+ struct sockaddr_in *addrs;
+ size_t max_addrs, n_addrs;
+ bool discovery;
+ size_t i;
+
+ /* Allocate enough memory for as many remotes as we could possibly have. */
+ max_addrs = ofproto->n_extra_remotes + hmap_count(&ofproto->controllers);
+ addrs = xmalloc(max_addrs * sizeof *addrs);
+ n_addrs = 0;
+
+ /* Add all the remotes. */
+ discovery = false;
+ HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &ofproto->controllers) {
+ struct sockaddr_in *sin = &addrs[n_addrs];
+
+ sin->sin_addr.s_addr = rconn_get_remote_ip(ofconn->rconn);
+ if (sin->sin_addr.s_addr) {
+ sin->sin_port = rconn_get_remote_port(ofconn->rconn);
+ n_addrs++;
+ }
+ if (ofconn->discovery) {
+ discovery = true;
+ }
+ }
+ for (i = 0; i < ofproto->n_extra_remotes; i++) {
+ addrs[n_addrs++] = ofproto->extra_in_band_remotes[i];
+ }
+
+ /* Create or update or destroy in-band.
+ *
+ * Ordinarily we only enable in-band if there's at least one remote
+ * address, but discovery needs the in-band rules for DHCP to be installed
+ * even before we know any remote addresses. */
+ if (n_addrs || discovery) {
+ if (!ofproto->in_band) {
+ in_band_create(ofproto, ofproto->dpif, ofproto->switch_status,
+ &ofproto->in_band);
+ }
+ in_band_set_remotes(ofproto->in_band, addrs, n_addrs);
+ ofproto->next_in_band_update = time_msec() + 1000;
+ } else {
+ in_band_destroy(ofproto->in_band);
+ ofproto->in_band = NULL;
+ }
+
+ /* Clean up. */
+ free(addrs);
+}
+