{
struct in_band_remote *r;
bool any_changes;
- int min_refresh;
if (time_now() < ib->next_remote_refresh) {
return false;
}
any_changes = false;
- min_refresh = 10;
+ ib->next_remote_refresh = TIME_MAX;
for (r = ib->remotes; r < &ib->remotes[ib->n_remotes]; r++) {
uint8_t old_remote_mac[ETH_ADDR_LEN];
- int refresh_interval;
+ time_t next_refresh;
/* Save old MAC. */
memcpy(old_remote_mac, r->remote_mac, ETH_ADDR_LEN);
/* Refresh remote information. */
- refresh_interval = refresh_remote(ib, r);
- min_refresh = MIN(min_refresh, refresh_interval);
+ next_refresh = refresh_remote(ib, r) + time_now();
+ ib->next_remote_refresh = MIN(ib->next_remote_refresh, next_refresh);
/* If the MAC changed, log the changes. */
if (!eth_addr_equals(r->remote_mac, old_remote_mac)) {
}
}
}
- ib->next_remote_refresh = time_now() + min_refresh;
return any_changes;
}
}
}
-static void
-clear_rules(struct in_band *ib)
-{
- memset(ib->installed_local_mac, 0, sizeof ib->installed_local_mac);
-
- free(ib->remote_ips);
- ib->remote_ips = NULL;
- ib->n_remote_ips = 0;
-
- free(ib->remote_macs);
- ib->remote_macs = NULL;
- ib->n_remote_macs = 0;
-}
-
static void
drop_rule(struct in_band *ib, const struct in_band_rule *rule)
{
rule->wildcards, rule->priority);
}
+/* Drops from the flow table all of the flows set up by 'ib', then clears out
+ * the information about the installed flows so that they can be filled in
+ * again if necessary. */
static void
drop_rules(struct in_band *ib)
{
+ /* Drop rules. */
make_rules(ib, drop_rule);
- clear_rules(ib);
+
+ /* Clear out state. */
+ memset(ib->installed_local_mac, 0, sizeof ib->installed_local_mac);
+
+ free(ib->remote_ips);
+ ib->remote_ips = NULL;
+ ib->n_remote_ips = 0;
+
+ free(ib->remote_macs);
+ ib->remote_macs = NULL;
+ ib->n_remote_macs = 0;
}
static void
rule->priority, &action, 1, 0);
}
+/* Inserts flows into the flow table for the current state of 'ib'. */
static void
add_rules(struct in_band *ib)
{
}
}
+static bool
+any_rconns_changed(const struct in_band *ib, struct rconn **remotes, size_t n)
+{
+ size_t i;
+
+ if (n != ib->n_remotes) {
+ return true;
+ }
+
+ for (i = 0; i < n; i++) {
+ if (ib->remotes[i].rconn != remotes[i]) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
in_band_set_remotes(struct in_band *ib, struct rconn **remotes, size_t n)
{
size_t i;
/* Optimize the case where the rconns are the same as last time. */
- if (n == ib->n_remotes) {
- for (i = 0; i < n; i++) {
- if (ib->remotes[i].rconn != remotes[i]) {
- goto different;
- }
- }
+ if (!any_rconns_changed(ib, remotes, n)) {
return;
-
- different:;
}
+ /* Clear old remotes. */
for (i = 0; i < ib->n_remotes; i++) {
/* We don't own the rconn. */
netdev_close(ib->remotes[i].remote_netdev);
}
free(ib->remotes);
- ib->next_remote_refresh = TIME_MIN;
- ib->remotes = n ? xzalloc(n * sizeof *ib->remotes) : 0;
+ /* Set up new remotes. */
+ ib->remotes = n ? xzalloc(n * sizeof *ib->remotes) : NULL;
ib->n_remotes = n;
for (i = 0; i < n; i++) {
ib->remotes[i].rconn = remotes[i];
}
+
+ /* Force refresh in next call to in_band_run(). */
+ ib->next_remote_refresh = TIME_MIN;
}