X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=f757b58094019d6aed244014a0c71f4b4be01fe9;hb=1ce0a5fa82f1a0013dd62713d16fde973b029eb7;hp=796aa292356c8a4953cdd8fd229cb49545064183;hpb=64ff1d96389aaa326154060326efc00093bb9f70;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 796aa292..f757b580 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -350,6 +350,17 @@ static void ofconn_set_rate_limit(struct ofconn *, int rate, int burst); static struct ofproto *ofconn_get_ofproto(struct ofconn *); +static enum nx_flow_format ofconn_get_flow_format(struct ofconn *); +static void ofconn_set_flow_format(struct ofconn *, enum nx_flow_format); + +static int ofconn_get_miss_send_len(const struct ofconn *); +static void ofconn_set_miss_send_len(struct ofconn *, int miss_send_len); + +static enum ofconn_type ofconn_get_type(const struct ofconn *); + +static enum nx_role ofconn_get_role(const struct ofconn *); +static void ofconn_set_role(struct ofconn *, enum nx_role); + static void queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn, struct rconn_packet_counter *counter); @@ -1137,7 +1148,7 @@ process_port_change(struct ofproto *ofproto, int error, char *devname) static int snoop_preference(const struct ofconn *ofconn) { - switch (ofconn->role) { + switch (ofconn_get_role(ofconn)) { case NX_ROLE_MASTER: return 3; case NX_ROLE_OTHER: @@ -1160,7 +1171,7 @@ add_snooper(struct ofproto *ofproto, struct vconn *vconn) /* Pick a controller for monitoring. */ best = NULL; LIST_FOR_EACH (ofconn, node, &ofproto->all_conns) { - if (ofconn->type == OFCONN_PRIMARY + if (ofconn_get_type(ofconn) == OFCONN_PRIMARY && (!best || snoop_preference(ofconn) > snoop_preference(best))) { best = ofconn; } @@ -1397,7 +1408,7 @@ ofproto_get_ofproto_controller_info(const struct ofproto *ofproto, shash_add(info, rconn_get_target(rconn), cinfo); cinfo->is_connected = rconn_is_connected(rconn); - cinfo->role = ofconn->role; + cinfo->role = ofconn_get_role(ofconn); cinfo->pairs.n = 0; @@ -1688,7 +1699,7 @@ send_port_status(struct ofproto *p, const struct ofport *ofport, /* Primary controllers, even slaves, should always get port status updates. Otherwise obey ofconn_receives_async_msgs(). */ - if (ofconn->type != OFCONN_PRIMARY + if (ofconn_get_type(ofconn) != OFCONN_PRIMARY && !ofconn_receives_async_msgs(ofconn)) { continue; } @@ -1890,7 +1901,7 @@ ofconn_destroy(struct ofconn *ofconn) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); - if (ofconn->type == OFCONN_PRIMARY) { + if (ofconn_get_type(ofconn) == OFCONN_PRIMARY) { hmap_remove(&ofproto->controllers, &ofconn->hmap_node); } @@ -1956,10 +1967,10 @@ ofconn_wait(struct ofconn *ofconn) static bool ofconn_receives_async_msgs(const struct ofconn *ofconn) { - if (ofconn->type == OFCONN_PRIMARY) { + if (ofconn_get_type(ofconn) == OFCONN_PRIMARY) { /* Primary controllers always get asynchronous messages unless they * have configured themselves as "slaves". */ - return ofconn->role != NX_ROLE_SLAVE; + return ofconn_get_role(ofconn) != NX_ROLE_SLAVE; } else { /* Service connections don't get asynchronous messages unless they have * explicitly asked for them by setting a nonzero miss send length. */ @@ -2005,6 +2016,48 @@ ofconn_get_ofproto(struct ofconn *ofconn) { return ofconn->ofproto; } + +static enum nx_flow_format +ofconn_get_flow_format(struct ofconn *ofconn) +{ + return ofconn->flow_format; +} + +static void +ofconn_set_flow_format(struct ofconn *ofconn, enum nx_flow_format flow_format) +{ + ofconn->flow_format = flow_format; +} + +static int +ofconn_get_miss_send_len(const struct ofconn *ofconn) +{ + return ofconn->miss_send_len; +} + +static void +ofconn_set_miss_send_len(struct ofconn *ofconn, int miss_send_len) +{ + ofconn->miss_send_len = miss_send_len; +} + +static enum ofconn_type +ofconn_get_type(const struct ofconn *ofconn) +{ + return ofconn->type; +} + +static enum nx_role +ofconn_get_role(const struct ofconn *ofconn) +{ + return ofconn->role; +} + +static void +ofconn_set_role(struct ofconn *ofconn, enum nx_role role) +{ + ofconn->role = role; +} static void ofservice_reconfigure(struct ofservice *ofservice, @@ -2632,6 +2685,12 @@ queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn, } } +static void +ofconn_send_reply(const struct ofconn *ofconn, struct ofpbuf *msg) +{ + queue_tx(msg, ofconn, ofconn->reply_counter); +} + static void send_error_oh(const struct ofconn *ofconn, const struct ofp_header *oh, int error) @@ -2639,14 +2698,14 @@ send_error_oh(const struct ofconn *ofconn, const struct ofp_header *oh, struct ofpbuf *buf = ofputil_encode_error_msg(error, oh); if (buf) { COVERAGE_INC(ofproto_error); - queue_tx(buf, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, buf); } } static int handle_echo_request(struct ofconn *ofconn, const struct ofp_header *oh) { - queue_tx(make_echo_reply(oh), ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, make_echo_reply(oh)); return 0; } @@ -2681,7 +2740,7 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh) hton_ofp_phy_port(ofpbuf_put(buf, &port->opp, sizeof port->opp)); } - queue_tx(buf, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, buf); return 0; } @@ -2701,8 +2760,8 @@ handle_get_config_request(struct ofconn *ofconn, const struct ofp_header *oh) /* Send reply. */ osc = make_openflow_xid(sizeof *osc, OFPT_GET_CONFIG_REPLY, oh->xid, &buf); osc->flags = htons(flags); - osc->miss_send_len = htons(ofconn->miss_send_len); - queue_tx(buf, ofconn, ofconn->reply_counter); + osc->miss_send_len = htons(ofconn_get_miss_send_len(ofconn)); + ofconn_send_reply(ofconn, buf); return 0; } @@ -2713,7 +2772,8 @@ handle_set_config(struct ofconn *ofconn, const struct ofp_switch_config *osc) struct ofproto *ofproto = ofconn_get_ofproto(ofconn); uint16_t flags = ntohs(osc->flags); - if (ofconn->type == OFCONN_PRIMARY && ofconn->role != NX_ROLE_SLAVE) { + if (ofconn_get_type(ofconn) == OFCONN_PRIMARY + && ofconn_get_role(ofconn) != NX_ROLE_SLAVE) { switch (flags & OFPC_FRAG_MASK) { case OFPC_FRAG_NORMAL: dpif_set_drop_frags(ofproto->dpif, false); @@ -2728,7 +2788,7 @@ handle_set_config(struct ofconn *ofconn, const struct ofp_switch_config *osc) } } - ofconn->miss_send_len = ntohs(osc->miss_send_len); + ofconn_set_miss_send_len(ofconn, ntohs(osc->miss_send_len)); return 0; } @@ -3246,7 +3306,8 @@ xlate_actions(struct action_xlate_ctx *ctx, static int reject_slave_controller(struct ofconn *ofconn, const const char *msg_type) { - if (ofconn->type == OFCONN_PRIMARY && ofconn->role == NX_ROLE_SLAVE) { + if (ofconn_get_type(ofconn) == OFCONN_PRIMARY + && ofconn_get_role(ofconn) == NX_ROLE_SLAVE) { static struct vlog_rate_limit perm_rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_WARN_RL(&perm_rl, "rejecting %s message from slave controller", msg_type); @@ -3405,7 +3466,7 @@ append_ofp_stats_reply(size_t nbytes, struct ofconn *ofconn, struct ofp_stats_reply *reply = msg->data; reply->flags = htons(OFPSF_REPLY_MORE); *msgp = make_ofp_stats_reply(reply->header.xid, reply->type, nbytes); - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); } return ofpbuf_put_uninit(*msgp, nbytes); } @@ -3441,7 +3502,7 @@ append_nxstats_reply(size_t nbytes, struct ofconn *ofconn, struct nicira_stats_msg *reply = msg->data; reply->flags = htons(OFPSF_REPLY_MORE); *msgp = make_nxstats_reply(reply->header.xid, reply->subtype, nbytes); - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); } ofpbuf_prealloc_tailroom(*msgp, nbytes); } @@ -3462,7 +3523,7 @@ handle_desc_stats_request(struct ofconn *ofconn, ovs_strlcpy(ods->sw_desc, p->sw_desc, sizeof ods->sw_desc); ovs_strlcpy(ods->serial_num, p->serial_desc, sizeof ods->serial_num); ovs_strlcpy(ods->dp_desc, p->dp_desc, sizeof ods->dp_desc); - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); return 0; } @@ -3481,14 +3542,14 @@ handle_table_stats_request(struct ofconn *ofconn, ots = append_ofp_stats_reply(sizeof *ots, ofconn, &msg); memset(ots, 0, sizeof *ots); strcpy(ots->name, "classifier"); - ots->wildcards = (ofconn->flow_format == NXFF_OPENFLOW10 + ots->wildcards = (ofconn_get_flow_format(ofconn) == NXFF_OPENFLOW10 ? htonl(OFPFW_ALL) : htonl(OVSFW_ALL)); ots->max_entries = htonl(1024 * 1024); /* An arbitrary big number. */ ots->active_count = htonl(classifier_count(&p->cls)); put_32aligned_be64(&ots->lookup_count, htonll(0)); /* XXX */ put_32aligned_be64(&ots->matched_count, htonll(0)); /* XXX */ - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); return 0; } @@ -3542,7 +3603,7 @@ handle_port_stats_request(struct ofconn *ofconn, const struct ofp_header *oh) } } - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); return 0; } @@ -3586,8 +3647,8 @@ put_ofp_flow_stats(struct ofconn *ofconn, struct rule *rule, ofs->length = htons(len); ofs->table_id = 0; ofs->pad = 0; - ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match, - rule->flow_cookie, &cookie); + ofputil_cls_rule_to_match(&rule->cr, ofconn_get_flow_format(ofconn), + &ofs->match, rule->flow_cookie, &cookie); put_32aligned_be64(&ofs->cookie, cookie); calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec); ofs->priority = htons(rule->cr.priority); @@ -3637,7 +3698,7 @@ handle_flow_stats_request(struct ofconn *ofconn, const struct ofp_header *oh) put_ofp_flow_stats(ofconn, rule, fsr->out_port, &reply); } } - queue_tx(reply, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, reply); return 0; } @@ -3714,7 +3775,7 @@ handle_nxst_flow(struct ofconn *ofconn, const struct ofp_header *oh) put_nx_flow_stats(ofconn, rule, nfsr->out_port, &reply); } } - queue_tx(reply, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, reply); return 0; } @@ -3810,7 +3871,7 @@ handle_aggregate_stats_request(struct ofconn *ofconn, reply = append_ofp_stats_reply(sizeof *reply, ofconn, &msg); query_aggregate_stats(ofproto, &target, request->out_port, request->table_id, reply); - queue_tx(msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, msg); return 0; } @@ -3843,7 +3904,7 @@ handle_nxst_aggregate(struct ofconn *ofconn, const struct ofp_header *oh) reply = ofpbuf_put_uninit(buf, sizeof *reply); query_aggregate_stats(ofproto, &target, request->out_port, request->table_id, reply); - queue_tx(buf, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, buf); return 0; } @@ -3931,7 +3992,7 @@ handle_queue_stats_request(struct ofconn *ofconn, const struct ofp_header *oh) ofpbuf_delete(cbdata.msg); return ofp_mkerr(OFPET_QUEUE_OP_FAILED, OFPQOFC_BAD_PORT); } - queue_tx(cbdata.msg, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, cbdata.msg); return 0; } @@ -4251,7 +4312,7 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) return error; } - error = ofputil_decode_flow_mod(&fm, oh, ofconn->flow_format); + error = ofputil_decode_flow_mod(&fm, oh, ofconn_get_flow_format(ofconn)); if (error) { return error; } @@ -4298,8 +4359,11 @@ handle_tun_id_from_cookie(struct ofconn *ofconn, const struct ofp_header *oh) { const struct nxt_tun_id_cookie *msg = (const struct nxt_tun_id_cookie *) oh; + enum nx_flow_format flow_format; + + flow_format = msg->set ? NXFF_TUN_ID_FROM_COOKIE : NXFF_OPENFLOW10; + ofconn_set_flow_format(ofconn, flow_format); - ofconn->flow_format = msg->set ? NXFF_TUN_ID_FROM_COOKIE : NXFF_OPENFLOW10; return 0; } @@ -4311,7 +4375,7 @@ handle_role_request(struct ofconn *ofconn, const struct ofp_header *oh) struct ofpbuf *buf; uint32_t role; - if (ofconn->type != OFCONN_PRIMARY) { + if (ofconn_get_type(ofconn) != OFCONN_PRIMARY) { VLOG_WARN_RL(&rl, "ignoring role request on non-controller " "connection"); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_EPERM); @@ -4331,16 +4395,16 @@ handle_role_request(struct ofconn *ofconn, const struct ofp_header *oh) struct ofconn *other; HMAP_FOR_EACH (other, hmap_node, &ofproto->controllers) { - if (other->role == NX_ROLE_MASTER) { - other->role = NX_ROLE_SLAVE; + if (ofconn_get_role(other) == NX_ROLE_MASTER) { + ofconn_set_role(other, NX_ROLE_SLAVE); } } } - ofconn->role = role; + ofconn_set_role(ofconn, role); reply = make_nxmsg_xid(sizeof *reply, NXT_ROLE_REPLY, oh->xid, &buf); reply->role = htonl(role); - queue_tx(buf, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, buf); return 0; } @@ -4356,7 +4420,7 @@ handle_nxt_set_flow_format(struct ofconn *ofconn, const struct ofp_header *oh) if (format == NXFF_OPENFLOW10 || format == NXFF_TUN_ID_FROM_COOKIE || format == NXFF_NXM) { - ofconn->flow_format = format; + ofconn_set_flow_format(ofconn, format); return 0; } else { return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_EPERM); @@ -4372,7 +4436,7 @@ handle_barrier_request(struct ofconn *ofconn, const struct ofp_header *oh) /* Currently, everything executes synchronously, so we can just * immediately send the barrier reply. */ ob = make_openflow_xid(sizeof *ob, OFPT_BARRIER_REPLY, oh->xid, &buf); - queue_tx(buf, ofconn, ofconn->reply_counter); + ofconn_send_reply(ofconn, buf); return 0; } @@ -4902,18 +4966,20 @@ rule_send_removed(struct ofproto *p, struct rule *rule, uint8_t reason) fr.byte_count = rule->byte_count; LIST_FOR_EACH (ofconn, node, &p->all_conns) { + struct ofpbuf *msg; + if (!rconn_is_connected(ofconn->rconn) || !ofconn_receives_async_msgs(ofconn)) { continue; } - /* Account flow expirations under ofconn->reply_counter, the counter - * for replies to OpenFlow requests. That works because preventing - * OpenFlow requests from being processed also prevents new flows from - * being added (and expiring). (It also prevents processing OpenFlow - * requests that would not add new flows, so it is imperfect.) */ - queue_tx(ofputil_encode_flow_removed(&fr, ofconn->flow_format), - ofconn, ofconn->reply_counter); + /* This accounts flow expirations as if they were replies to OpenFlow + * requests. That works because preventing OpenFlow requests from + * being processed also prevents new flows from being added (and + * expiring). (It also prevents processing OpenFlow requests that + * would not add new flows, so it is imperfect.) */ + msg = ofputil_encode_flow_removed(&fr, ofconn_get_flow_format(ofconn)); + ofconn_send_reply(ofconn, msg); } }