struct classifier cls;
bool need_revalidate;
long long int next_expiration;
+ struct tag_set revalidate_set;
/* OpenFlow connections. */
struct list all_conns;
classifier_init(&p->cls);
p->need_revalidate = false;
p->next_expiration = time_msec() + 1000;
+ tag_set_init(&p->revalidate_set);
/* Initialize OpenFlow connections. */
list_init(&p->all_conns);
{
int error = ofproto_run1(p);
if (!error) {
- error = ofproto_run2(p, false, NULL);
+ error = ofproto_run2(p, false);
}
return error;
}
};
int
-ofproto_run2(struct ofproto *p,
- bool revalidate_all, const struct tag_set *revalidate_set)
+ofproto_run2(struct ofproto *p, bool revalidate_all)
{
if (p->need_revalidate || revalidate_all
- || (revalidate_set && !tag_set_is_empty(revalidate_set))) {
+ || !tag_set_is_empty(&p->revalidate_set)) {
struct revalidate_cbdata cbdata;
cbdata.ofproto = p;
cbdata.revalidate_all = revalidate_all;
cbdata.revalidate_subrules = p->need_revalidate;
- if (revalidate_set) {
- cbdata.revalidate_set = *revalidate_set;
- } else {
- tag_set_init(&cbdata.revalidate_set);
- }
+ cbdata.revalidate_set = p->revalidate_set;
+ tag_set_init(&p->revalidate_set);
classifier_for_each(&p->cls, CLS_INC_EXACT, revalidate_cb, &cbdata);
p->need_revalidate = false;
}
if (p->executer) {
executer_wait(p->executer);
}
+ if (!tag_set_is_empty(&p->revalidate_set)) {
+ poll_immediate_wake();
+ }
if (p->need_revalidate) {
/* Shouldn't happen, but if it does just go around again. */
VLOG_DBG_RL(&rl, "need revalidate in ofproto_wait_cb()");
}
}
+void
+ofproto_revalidate(struct ofproto *ofproto, tag_type tag)
+{
+ tag_set_add(&ofproto->revalidate_set, tag);
+}
+
+struct tag_set *
+ofproto_get_revalidate_set(struct ofproto *ofproto)
+{
+ return &ofproto->revalidate_set;
+}
+
bool
ofproto_is_alive(const struct ofproto *p)
{
void ofproto_destroy(struct ofproto *);
int ofproto_run(struct ofproto *);
int ofproto_run1(struct ofproto *);
-int ofproto_run2(struct ofproto *,
- bool revalidate_all, const struct tag_set *revalidate_set);
+int ofproto_run2(struct ofproto *, bool revalidate_all);
void ofproto_wait(struct ofproto *);
bool ofproto_is_alive(const struct ofproto *);
void (*normal_cb)(const flow_t *, bool revalidating,
struct odp_actions *, tag_type *, void *aux);
};
+void ofproto_revalidate(struct ofproto *, tag_type);
+struct tag_set *ofproto_get_revalidate_set(struct ofproto *);
#endif /* ofproto.h */
size_t n_ports, allocated_ports;
/* Flow tracking. */
- struct tag_set revalidate_set;
bool flush;
/* Flow statistics gathering. */
}
bond_wait(br);
brstp_wait(br);
- if (!tag_set_is_empty(&br->revalidate_set)) {
- poll_immediate_wake();
- }
}
}
port_array_init(&br->ifaces);
- tag_set_init(&br->revalidate_set);
br->flush = false;
list_push_back(&all_bridges, &br->node);
}
if (br->ml) {
- mac_learning_run(br->ml, &br->revalidate_set);
+ mac_learning_run(br->ml, ofproto_get_revalidate_set(br->ofproto));
}
bond_run(br);
brstp_run(br);
- error = ofproto_run2(br->ofproto, br->flush, &br->revalidate_set);
- tag_set_init(&br->revalidate_set);
+ error = ofproto_run2(br->ofproto, br->flush);
br->flush = false;
return error;
iface->name,
iface->enabled ? "enable" : "disabled");
if (!iface->enabled) {
- tag_set_add(&br->revalidate_set, iface->tag);
+ ofproto_revalidate(br->ofproto, iface->tag);
if (iface->port_ifidx == port->active_iface) {
- tag_set_add(&br->revalidate_set,
- port->active_iface_tag);
+ ofproto_revalidate(br->ofproto,
+ port->active_iface_tag);
bond_choose_active_iface(port);
}
} else {
if (port->active_iface < 0) {
- tag_set_add(&br->revalidate_set, port->no_ifaces_tag);
+ ofproto_revalidate(br->ofproto, port->no_ifaces_tag);
bond_choose_active_iface(port);
}
iface->tag = tag_create_random();
"on port %s in VLAN %d",
br->name, ETH_ADDR_ARGS(flow->dl_src),
in_port->name, vlan);
- tag_set_add(&br->revalidate_set, rev_tag);
+ ofproto_revalidate(br->ofproto, rev_tag);
}
}
free(iface);
if (del_active) {
- tag_set_add(&port->bridge->revalidate_set, port->active_iface_tag);
+ ofproto_revalidate(port->bridge->ofproto, port->active_iface_tag);
bond_choose_active_iface(port);
}
if (p->stp_state == STP_DISABLED) {
bridge_flush(br);
} else {
- tag_set_add(&p->bridge->revalidate_set, p->stp_state_tag);
+ ofproto_revalidate(p->bridge->ofproto, p->stp_state_tag);
}
p->stp_state = state;
p->stp_state_tag = (p->stp_state == STP_DISABLED ? 0