X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=0fd2fdfbee258e3d3469ef6aabfbb8099810940c;hb=9575eae3724fb437b2df9bfad02501325d3dcdaf;hp=0ee69effbe6f978a149582b01001f3587ccd6518;hpb=c91248b3ab3f75070c7985fe723f54437cb8848e;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 0ee69eff..0fd2fdfb 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -19,6 +19,7 @@ #include "ofproto.h" #include #include +#include #include #include #include @@ -545,6 +546,10 @@ update_in_band_remotes(struct ofproto *ofproto) HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &ofproto->controllers) { struct sockaddr_in *sin = &addrs[n_addrs]; + if (ofconn->band == OFPROTO_OUT_OF_BAND) { + continue; + } + 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); @@ -568,7 +573,9 @@ update_in_band_remotes(struct ofproto *ofproto) in_band_create(ofproto, ofproto->dpif, ofproto->switch_status, &ofproto->in_band); } - in_band_set_remotes(ofproto->in_band, addrs, n_addrs); + if (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); @@ -963,25 +970,47 @@ process_port_change(struct ofproto *ofproto, int error, char *devname) } } +/* Returns a "preference level" for snooping 'ofconn'. A higher return value + * means that 'ofconn' is more interesting for monitoring than a lower return + * value. */ +static int +snoop_preference(const struct ofconn *ofconn) +{ + 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; + struct ofconn *ofconn, *best; - /* Arbitrarily pick the first controller in the list for monitoring. We - * could do something smarter or more flexible later, if it ever proves - * useful. */ + /* Pick a controller for monitoring. */ + best = NULL; LIST_FOR_EACH (ofconn, struct ofconn, node, &ofproto->all_conns) { - if (ofconn->type == OFCONN_CONTROLLER) { - rconn_add_monitor(ofconn->rconn, vconn); - return; + if (ofconn->type == OFCONN_CONTROLLER + && (!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); } - VLOG_INFO_RL(&rl, "no controller connection to monitor"); - vconn_close(vconn); } int @@ -1133,7 +1162,7 @@ ofproto_wait(struct ofproto *p) ofconn_wait(ofconn); } if (p->in_band) { - poll_timer_wait(p->next_in_band_update - time_msec()); + poll_timer_wait_until(p->next_in_band_update); in_band_wait(p->in_band); } if (p->fail_open) { @@ -1150,7 +1179,7 @@ ofproto_wait(struct ofproto *p) VLOG_DBG_RL(&rl, "need revalidate in ofproto_wait_cb()"); poll_immediate_wake(); } else if (p->next_expiration != LLONG_MAX) { - poll_timer_wait(p->next_expiration - time_msec()); + poll_timer_wait_until(p->next_expiration); } for (i = 0; i < p->n_listeners; i++) { pvconn_wait(p->listeners[i]); @@ -1329,7 +1358,6 @@ make_ofport(const struct odp_port *odp_port) memset(&netdev_options, 0, sizeof netdev_options); netdev_options.name = odp_port->devname; netdev_options.ethertype = NETDEV_ETH_TYPE_NONE; - netdev_options.may_open = true; error = netdev_open(&netdev_options, &netdev); if (error) { @@ -3518,7 +3546,7 @@ handle_role_request(struct ofproto *ofproto, uint32_t role; if (ntohs(msg->header.length) != sizeof *nrr) { - VLOG_WARN_RL(&rl, "received role request of length %zu (expected %zu)", + VLOG_WARN_RL(&rl, "received role request of length %u (expected %zu)", ntohs(msg->header.length), sizeof *nrr); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } @@ -3568,7 +3596,7 @@ handle_vendor(struct ofproto *p, struct ofconn *ofconn, void *msg) struct nicira_header *nh; if (ntohs(ovh->header.length) < sizeof(struct ofp_vendor_header)) { - VLOG_WARN_RL(&rl, "received vendor message of length %zu " + VLOG_WARN_RL(&rl, "received vendor message of length %u " "(expected at least %zu)", ntohs(ovh->header.length), sizeof(struct ofp_vendor_header)); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); @@ -3577,7 +3605,7 @@ handle_vendor(struct ofproto *p, struct ofconn *ofconn, void *msg) return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR); } if (ntohs(ovh->header.length) < sizeof(struct nicira_header)) { - VLOG_WARN_RL(&rl, "received Nicira vendor message of length %zu " + VLOG_WARN_RL(&rl, "received Nicira vendor message of length %u " "(expected at least %zu)", ntohs(ovh->header.length), sizeof(struct nicira_header)); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); @@ -4202,7 +4230,8 @@ default_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet, /* Learn source MAC (but don't try to learn from revalidation). */ if (packet != NULL) { tag_type rev_tag = mac_learning_learn(ofproto->ml, flow->dl_src, - 0, flow->in_port); + 0, flow->in_port, + GRAT_ARP_LOCK_NONE); if (rev_tag) { /* The log messages here could actually be useful in debugging, * so keep the rate limit relatively high. */ @@ -4214,7 +4243,8 @@ default_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet, } /* Determine output port. */ - out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags); + out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags, + NULL); if (out_port < 0) { add_output_group_action(actions, DP_GROUP_FLOOD, nf_output_iface); } else if (out_port != flow->in_port) {