- switch (ofconn->role) {
- case NX_ROLE_MASTER:
- return 3;
- case NX_ROLE_OTHER:
- return 2;
- case NX_ROLE_SLAVE:
- return 1;
- default:
- /* Shouldn't happen. */
- return 0;
- }
-}
-
-/* One of ofproto's "snoop" pvconns has accepted a new connection on 'vconn'.
- * Connects this vconn to a controller. */
-static void
-add_snooper(struct ofproto *ofproto, struct vconn *vconn)
-{
- struct ofconn *ofconn, *best;
-
- /* Pick a controller for monitoring. */
- best = NULL;
- LIST_FOR_EACH (ofconn, node, &ofproto->all_conns) {
- if (ofconn->type == OFCONN_PRIMARY
- && (!best || snoop_preference(ofconn) > snoop_preference(best))) {
- best = ofconn;
- }
- }
-
- if (best) {
- rconn_add_monitor(best->rconn, vconn);
- } else {
- VLOG_INFO_RL(&rl, "no controller connection to snoop");
- vconn_close(vconn);
- }
-}
-
-int
-ofproto_run1(struct ofproto *p)
-{
- struct ofconn *ofconn, *next_ofconn;
- struct ofservice *ofservice;
- char *devname;
- int error;
- int i;
-
- if (shash_is_empty(&p->port_by_name)) {
- init_ports(p);
- }
-
- for (i = 0; i < 50; i++) {
- struct ofpbuf *buf;
-
- error = dpif_recv(p->dpif, &buf);
- if (error) {
- if (error == ENODEV) {
- /* Someone destroyed the datapath behind our back. The caller
- * better destroy us and give up, because we're just going to
- * spin from here on out. */
- static struct vlog_rate_limit rl2 = VLOG_RATE_LIMIT_INIT(1, 5);
- VLOG_ERR_RL(&rl2, "%s: datapath was destroyed externally",
- dpif_name(p->dpif));
- return ENODEV;
- }
- break;
- }
-
- handle_odp_msg(p, buf);
- }
-
- while ((error = dpif_port_poll(p->dpif, &devname)) != EAGAIN) {
- process_port_change(p, error, devname);
- }
- while ((error = netdev_monitor_poll(p->netdev_monitor,
- &devname)) != EAGAIN) {
- process_port_change(p, error, devname);
- }
-
- if (p->in_band) {
- if (time_msec() >= p->next_in_band_update) {
- update_in_band_remotes(p);
- }
- in_band_run(p->in_band);
- }
-
- LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &p->all_conns) {
- ofconn_run(ofconn, p);
- }
-
- /* Fail-open maintenance. Do this after processing the ofconns since
- * fail-open checks the status of the controller rconn. */
- if (p->fail_open) {
- fail_open_run(p->fail_open);
- }
-
- HMAP_FOR_EACH (ofservice, node, &p->services) {
- struct vconn *vconn;
- int retval;
-
- retval = pvconn_accept(ofservice->pvconn, OFP_VERSION, &vconn);
- if (!retval) {
- struct rconn *rconn;
- char *name;
-
- rconn = rconn_create(ofservice->probe_interval, 0);
- name = ofconn_make_name(p, vconn_get_name(vconn));
- rconn_connect_unreliably(rconn, vconn, name);
- free(name);
-
- ofconn = ofconn_create(p, rconn, OFCONN_SERVICE);
- ofconn_set_rate_limit(ofconn, ofservice->rate_limit,
- ofservice->burst_limit);
- } else if (retval != EAGAIN) {
- VLOG_WARN_RL(&rl, "accept failed (%s)", strerror(retval));
- }
- }
-
- for (i = 0; i < p->n_snoops; i++) {
- struct vconn *vconn;
- int retval;
-
- retval = pvconn_accept(p->snoops[i], OFP_VERSION, &vconn);
- if (!retval) {
- add_snooper(p, vconn);
- } else if (retval != EAGAIN) {
- VLOG_WARN_RL(&rl, "accept failed (%s)", strerror(retval));
- }
- }
-
- if (time_msec() >= p->next_expiration) {
- int delay = ofproto_expire(p);
- p->next_expiration = time_msec() + delay;
- COVERAGE_INC(ofproto_expiration);
- }
-
- if (p->netflow) {
- netflow_run(p->netflow);
- }
- if (p->sflow) {
- ofproto_sflow_run(p->sflow);
- }
-
- return 0;
-}
-
-struct revalidate_cbdata {
- struct ofproto *ofproto;
- bool revalidate_all; /* Revalidate all exact-match rules? */
- bool revalidate_subrules; /* Revalidate all exact-match subrules? */
- struct tag_set revalidate_set; /* Set of tags to revalidate. */
-};
-
-int
-ofproto_run2(struct ofproto *p, bool revalidate_all)
-{
- if (p->need_revalidate || revalidate_all
- || !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;
- cbdata.revalidate_set = p->revalidate_set;
- tag_set_init(&p->revalidate_set);
- COVERAGE_INC(ofproto_revalidate);
- classifier_for_each(&p->cls, CLS_INC_EXACT, revalidate_cb, &cbdata);
- p->need_revalidate = false;
- }
-
- return 0;
-}
-
-void
-ofproto_wait(struct ofproto *p)
-{
- struct ofservice *ofservice;
- struct ofconn *ofconn;
- size_t i;
-
- dpif_recv_wait(p->dpif);
- dpif_port_poll_wait(p->dpif);
- netdev_monitor_poll_wait(p->netdev_monitor);
- LIST_FOR_EACH (ofconn, node, &p->all_conns) {
- ofconn_wait(ofconn);
- }
- if (p->in_band) {
- poll_timer_wait_until(p->next_in_band_update);
- in_band_wait(p->in_band);
- }
- if (p->fail_open) {
- fail_open_wait(p->fail_open);
- }
- if (p->sflow) {
- ofproto_sflow_wait(p->sflow);
- }
- 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()");
- poll_immediate_wake();
- } else if (p->next_expiration != LLONG_MAX) {
- poll_timer_wait_until(p->next_expiration);
- }
- HMAP_FOR_EACH (ofservice, node, &p->services) {
- pvconn_wait(ofservice->pvconn);
- }
- for (i = 0; i < p->n_snoops; i++) {
- pvconn_wait(p->snoops[i]);
- }
-}
-
-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)
-{
- return !hmap_is_empty(&p->controllers);