X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=ce36d95691c786931f4fa19ce2880a99d5937208;hb=67e96a5dca90225358936b1392bba8b3207805b1;hp=fe3b6206cae20f373efe77cf5ef456c2c6c049b6;hpb=9aec6f5a52b1575a30264554736c1275442e3d80;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index fe3b6206..ce36d956 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1953,17 +1953,13 @@ reject_slave_controller(struct ofconn *ofconn) } static enum ofperr -handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) +handle_packet_out(struct ofconn *ofconn, const struct ofp_packet_out *opo) { struct ofproto *p = ofconn_get_ofproto(ofconn); - struct ofp_packet_out *opo; - struct ofpbuf payload, *buffer; - union ofp_action *ofp_actions; - struct ofpbuf request; + struct ofputil_packet_out po; + struct ofpbuf *payload; struct flow flow; - size_t n_ofp_actions; enum ofperr error; - uint16_t in_port; COVERAGE_INC(ofproto_packet_out); @@ -1972,45 +1968,28 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) return error; } - /* Get ofp_packet_out. */ - ofpbuf_use_const(&request, oh, ntohs(oh->length)); - opo = ofpbuf_pull(&request, offsetof(struct ofp_packet_out, actions)); - - /* Get actions. */ - error = ofputil_pull_actions(&request, ntohs(opo->actions_len), - &ofp_actions, &n_ofp_actions); + /* Decode message. */ + error = ofputil_decode_packet_out(&po, opo); if (error) { return error; } /* Get payload. */ - if (opo->buffer_id != htonl(UINT32_MAX)) { - error = ofconn_pktbuf_retrieve(ofconn, ntohl(opo->buffer_id), - &buffer, NULL); - if (error || !buffer) { + if (po.buffer_id != UINT32_MAX) { + error = ofconn_pktbuf_retrieve(ofconn, po.buffer_id, &payload, NULL); + if (error || !payload) { return error; } - payload = *buffer; } else { - payload = request; - buffer = NULL; - } - - /* Get in_port and partially validate it. - * - * We don't know what range of ports the ofproto actually implements, but - * we do know that only certain reserved ports (numbered OFPP_MAX and - * above) are valid. */ - in_port = ntohs(opo->in_port); - if (in_port >= OFPP_MAX && in_port != OFPP_LOCAL && in_port != OFPP_NONE) { - return OFPERR_NXBRC_BAD_IN_PORT; + payload = xmalloc(sizeof *payload); + ofpbuf_use_const(payload, po.packet, po.packet_len); } /* Send out packet. */ - flow_extract(&payload, 0, 0, in_port, &flow); - error = p->ofproto_class->packet_out(p, &payload, &flow, - ofp_actions, n_ofp_actions); - ofpbuf_delete(buffer); + flow_extract(payload, 0, 0, po.in_port, &flow); + error = p->ofproto_class->packet_out(p, payload, &flow, + po.actions, po.n_actions); + ofpbuf_delete(payload); return error; } @@ -3138,6 +3117,41 @@ handle_nxt_set_packet_in_format(struct ofconn *ofconn, return 0; } +static enum ofperr +handle_nxt_set_async_config(struct ofconn *ofconn, const struct ofp_header *oh) +{ + const struct nx_async_config *msg = (const struct nx_async_config *) oh; + uint32_t master[OAM_N_TYPES]; + uint32_t slave[OAM_N_TYPES]; + + master[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[0]); + master[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[0]); + master[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[0]); + + slave[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[1]); + slave[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[1]); + slave[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[1]); + + ofconn_set_async_config(ofconn, master, slave); + + return 0; +} + +static enum ofperr +handle_nxt_set_controller_id(struct ofconn *ofconn, + const struct ofp_header *oh) +{ + const struct nx_controller_id *nci; + + nci = (const struct nx_controller_id *) oh; + if (!is_all_zeros(nci->zero, sizeof nci->zero)) { + return OFPERR_NXBRC_MUST_BE_ZERO; + } + + ofconn_set_controller_id(ofconn, ntohs(nci->controller_id)); + return 0; +} + static enum ofperr handle_barrier_request(struct ofconn *ofconn, const struct ofp_header *oh) { @@ -3180,7 +3194,7 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) return handle_set_config(ofconn, msg->data); case OFPUTIL_OFPT_PACKET_OUT: - return handle_packet_out(ofconn, oh); + return handle_packet_out(ofconn, msg->data); case OFPUTIL_OFPT_PORT_MOD: return handle_port_mod(ofconn, oh); @@ -3208,6 +3222,9 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) case OFPUTIL_NXT_SET_PACKET_IN_FORMAT: return handle_nxt_set_packet_in_format(ofconn, oh); + case OFPUTIL_NXT_SET_CONTROLLER_ID: + return handle_nxt_set_controller_id(ofconn, oh); + case OFPUTIL_NXT_FLOW_MOD: return handle_flow_mod(ofconn, oh); @@ -3215,6 +3232,9 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) /* Nothing to do. */ return 0; + case OFPUTIL_NXT_SET_ASYNC_CONFIG: + return handle_nxt_set_async_config(ofconn, oh); + /* Statistics requests. */ case OFPUTIL_OFPST_DESC_REQUEST: return handle_desc_stats_request(ofconn, msg->data); @@ -3963,7 +3983,7 @@ ofproto_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED, HMAP_FOR_EACH (ofproto, hmap_node, &all_ofprotos) { ds_put_format(&results, "%s\n", ofproto->name); } - unixctl_command_reply(conn, 200, ds_cstr(&results)); + unixctl_command_reply(conn, ds_cstr(&results)); ds_destroy(&results); }