static void ofport_destroy__(struct ofport *);
static void ofport_destroy(struct ofport *);
-static int rule_create(struct ofproto *, const struct cls_rule *,
+static int rule_create(struct ofproto *,
+ const struct cls_rule *, uint8_t table_id,
const union ofp_action *, size_t n_actions,
uint16_t idle_timeout, uint16_t hard_timeout,
ovs_be64 flow_cookie, bool send_flow_removed,
ofproto->sw_desc = xstrdup(DEFAULT_SW_DESC);
ofproto->serial_desc = xstrdup(DEFAULT_SERIAL_DESC);
ofproto->dp_desc = xstrdup(DEFAULT_DP_DESC);
- ofproto->netdev_monitor = netdev_monitor_create();
hmap_init(&ofproto->ports);
shash_init(&ofproto->port_by_name);
ofproto->tables = NULL;
free(ofproto->sw_desc);
free(ofproto->serial_desc);
free(ofproto->dp_desc);
- netdev_monitor_destroy(ofproto->netdev_monitor);
hmap_destroy(&ofproto->ports);
shash_destroy(&ofproto->port_by_name);
int
ofproto_run(struct ofproto *p)
{
+ struct ofport *ofport;
char *devname;
int error;
process_port_change(p, error, devname);
}
}
- while ((error = netdev_monitor_poll(p->netdev_monitor,
- &devname)) != EAGAIN) {
- process_port_change(p, error, devname);
+
+ HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
+ unsigned int change_seq = netdev_change_seq(ofport->netdev);
+ if (ofport->change_seq != change_seq) {
+ ofport->change_seq = change_seq;
+ update_port(p, netdev_get_name(ofport->netdev));
+ }
}
connmgr_run(p->connmgr, handle_openflow);
void
ofproto_wait(struct ofproto *p)
{
+ struct ofport *ofport;
+
p->ofproto_class->wait(p);
if (p->ofproto_class->port_poll_wait) {
p->ofproto_class->port_poll_wait(p);
}
- netdev_monitor_poll_wait(p->netdev_monitor);
+
+ HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
+ if (ofport->change_seq != netdev_change_seq(ofport->netdev)) {
+ poll_immediate_wake();
+ }
+ }
connmgr_wait(p->connmgr);
}
const union ofp_action *actions, size_t n_actions)
{
struct rule *rule;
- rule_create(p, cls_rule, actions, n_actions, 0, 0, 0, false, &rule);
+ rule_create(p, cls_rule, 0, actions, n_actions, 0, 0, 0, false, &rule);
}
/* Searches for a rule with matching criteria exactly equal to 'target' in
}
ofport->ofproto = p;
ofport->netdev = netdev;
+ ofport->change_seq = netdev_change_seq(netdev);
ofport->opp = *opp;
ofport->ofp_port = ntohs(opp->port_no);
/* Add port to 'p'. */
- netdev_monitor_add(p->netdev_monitor, ofport->netdev);
hmap_insert(&p->ports, &ofport->hmap_node, hash_int(ofport->ofp_port, 0));
shash_add(&p->port_by_name, netdev_name, ofport);
struct ofproto *ofproto = port->ofproto;
const char *name = netdev_get_name(port->netdev);
- netdev_monitor_remove(ofproto->netdev_monitor, port->netdev);
hmap_remove(&ofproto->ports, &port->hmap_node);
shash_delete(&ofproto->port_by_name,
shash_find(&ofproto->port_by_name, name));
/* Install the newly opened netdev in case it has changed.
* Don't close the old netdev yet in case port_modified has to
* remove a retained reference to it.*/
- netdev_monitor_remove(ofproto->netdev_monitor, port->netdev);
- netdev_monitor_add(ofproto->netdev_monitor, netdev);
port->netdev = netdev;
+ port->change_seq = netdev_change_seq(netdev);
if (port->ofproto->ofproto_class->port_modified) {
port->ofproto->ofproto_class->port_modified(port);
* flow table, and stores the new rule into '*rulep'. Returns 0 on success,
* otherwise a positive errno value or OpenFlow error code. */
static int
-rule_create(struct ofproto *ofproto, const struct cls_rule *cls_rule,
+rule_create(struct ofproto *ofproto,
+ const struct cls_rule *cls_rule, uint8_t table_id,
const union ofp_action *actions, size_t n_actions,
uint16_t idle_timeout, uint16_t hard_timeout,
ovs_be64 flow_cookie, bool send_flow_removed,
struct rule *rule;
int error;
+ if (table_id == 0xff) {
+ if (ofproto->n_tables > 1) {
+ error = ofproto->ofproto_class->rule_choose_table(ofproto,
+ cls_rule,
+ &table_id);
+ if (error) {
+ return error;
+ }
+ assert(table_id < ofproto->n_tables);
+ } else {
+ table_id = 0;
+ }
+ }
+
rule = ofproto->ofproto_class->rule_alloc();
if (!rule) {
error = ENOMEM;
rule->ofproto = ofproto;
rule->cr = *cls_rule;
+ rule->table_id = table_id;
rule->flow_cookie = flow_cookie;
rule->created = time_msec();
rule->idle_timeout = idle_timeout;
}
buf_err = ofconn_pktbuf_retrieve(ofconn, fm->buffer_id, &packet, &in_port);
- error = rule_create(p, &fm->cr, fm->actions, fm->n_actions,
+ error = rule_create(p, &fm->cr, fm->table_id, fm->actions, fm->n_actions,
fm->idle_timeout, fm->hard_timeout, fm->cookie,
fm->flags & OFPFF_SEND_FLOW_REM, &rule);
if (error) {