X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ofproto%2Fconnmgr.c;h=cdd7a695f31906f1720cb31253e5f19b7860062e;hb=77ab5fd2a95ba2fef5bbe25aaa429776b9e29ea3;hp=c3e486c2e56e624033f38f63ba19ec9a6be2a4b5;hpb=99520767ca72b422d83c1357d8f876a7ed1bf0d2;p=cascardo%2Fovs.git diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index c3e486c2e..cdd7a695f 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -1002,7 +1002,7 @@ ofconn_set_protocol(struct ofconn *ofconn, enum ofputil_protocol protocol) /* Returns the currently configured packet in format for 'ofconn', one of * NXPIF_*. * - * The default, if no other format has been set, is NXPIF_OPENFLOW10. */ + * The default, if no other format has been set, is NXPIF_STANDARD. */ enum nx_packet_in_format ofconn_get_packet_in_format(struct ofconn *ofconn) { @@ -1250,7 +1250,7 @@ ofconn_flush(struct ofconn *ofconn) ofconn->role = OFPCR12_ROLE_EQUAL; ofconn_set_protocol(ofconn, OFPUTIL_P_NONE); - ofconn->packet_in_format = NXPIF_OPENFLOW10; + ofconn->packet_in_format = NXPIF_STANDARD; rconn_packet_counter_destroy(ofconn->packet_in_counter); ofconn->packet_in_counter = rconn_packet_counter_create(); @@ -1480,33 +1480,6 @@ ofconn_receives_async_msg(const struct ofconn *ofconn, return (masks[type] & (1u << reason)) != 0; } -/* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the - * packet rather than to send the packet to the controller. - * - * This function returns false to indicate the packet should be dropped if - * the controller action was the result of the default table-miss behaviour - * and the controller is using OpenFlow1.3+. - * - * Otherwise true is returned to indicate the packet should be forwarded to - * the controller */ -static bool -ofconn_wants_packet_in_on_miss(struct ofconn *ofconn, - const struct ofproto_packet_in *pin) -{ - if (pin->miss_type == OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW) { - enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); - - if (protocol != OFPUTIL_P_NONE - && ofputil_protocol_to_ofp_version(protocol) >= OFP13_VERSION - && (ofproto_table_get_miss_config(ofconn->connmgr->ofproto, - pin->up.table_id) - == OFPUTIL_TABLE_MISS_DEFAULT)) { - return false; - } - } - return true; -} - /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the * packet rather than to send the packet to the controller. * @@ -1582,9 +1555,6 @@ ofconn_send(const struct ofconn *ofconn, struct ofpbuf *msg, /* Sending asynchronous messages. */ -static void schedule_packet_in(struct ofconn *, struct ofproto_packet_in, - enum ofp_packet_in_reason wire_reason); - /* Sends an OFPT_PORT_STATUS message with 'opp' and 'reason' to appropriate * controllers managed by 'mgr'. For messages caused by a controller * OFPT_PORT_MOD, specify 'source' as the controller connection that sent the @@ -1678,59 +1648,36 @@ connmgr_send_flow_removed(struct connmgr *mgr, } } -/* Normally a send-to-controller action uses reason OFPR_ACTION. However, in - * OpenFlow 1.3 and later, packet_ins generated by a send-to-controller action - * in a "table-miss" flow (one with priority 0 and completely wildcarded) are - * sent as OFPR_NO_MATCH. This function returns the reason that should - * actually be sent on 'ofconn' for 'pin'. */ -static enum ofp_packet_in_reason -wire_reason(struct ofconn *ofconn, const struct ofproto_packet_in *pin) -{ - enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); - - if (pin->miss_type == OFPROTO_PACKET_IN_MISS_FLOW - && pin->up.reason == OFPR_ACTION - && protocol != OFPUTIL_P_NONE - && ofputil_protocol_to_ofp_version(protocol) >= OFP13_VERSION) { - return OFPR_NO_MATCH; - } - - switch (pin->up.reason) { - case OFPR_ACTION_SET: - case OFPR_GROUP: - case OFPR_PACKET_OUT: - if (!(protocol & OFPUTIL_P_OF14_UP)) { - /* Only supported in OF1.4+ */ - return OFPR_ACTION; - } - /* Fall through. */ - case OFPR_NO_MATCH: - case OFPR_ACTION: - case OFPR_INVALID_TTL: - case OFPR_N_REASONS: - default: - return pin->up.reason; - } -} - /* Given 'pin', sends an OFPT_PACKET_IN message to each OpenFlow controller as - * necessary according to their individual configurations. - * - * The caller doesn't need to fill in pin->buffer_id or pin->total_len. */ + * necessary according to their individual configurations. */ void -connmgr_send_packet_in(struct connmgr *mgr, - const struct ofproto_packet_in *pin) +connmgr_send_async_msg(struct connmgr *mgr, + const struct ofproto_async_msg *am) { struct ofconn *ofconn; LIST_FOR_EACH (ofconn, node, &mgr->all_conns) { - enum ofp_packet_in_reason reason = wire_reason(ofconn, pin); - - if (ofconn_wants_packet_in_on_miss(ofconn, pin) - && ofconn_receives_async_msg(ofconn, OAM_PACKET_IN, reason) - && ofconn->controller_id == pin->controller_id) { - schedule_packet_in(ofconn, *pin, reason); + enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); + if (protocol == OFPUTIL_P_NONE || !rconn_is_connected(ofconn->rconn) + || ofconn->controller_id != am->controller_id + || !ofconn_receives_async_msg(ofconn, am->oam, + am->pin.up.public.reason)) { + continue; } + + struct ofpbuf *msg = ofputil_encode_packet_in_private( + &am->pin.up, protocol, ofconn->packet_in_format, + am->pin.max_len >= 0 ? am->pin.max_len : ofconn->miss_send_len, + ofconn->pktbuf); + + struct ovs_list txq; + bool is_miss = (am->pin.up.public.reason == OFPR_NO_MATCH || + am->pin.up.public.reason == OFPR_EXPLICIT_MISS || + am->pin.up.public.reason == OFPR_IMPLICIT_MISS); + pinsched_send(ofconn->schedulers[is_miss], + am->pin.up.public.flow_metadata.flow.in_port.ofp_port, + msg, &txq); + do_send_packet_ins(ofconn, &txq); } } @@ -1749,55 +1696,6 @@ do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq) } } } - -/* Takes 'pin', composes an OpenFlow packet-in message from it, and passes it - * to 'ofconn''s packet scheduler for sending. */ -static void -schedule_packet_in(struct ofconn *ofconn, struct ofproto_packet_in pin, - enum ofp_packet_in_reason wire_reason) -{ - uint16_t controller_max_len; - struct ovs_list txq; - - pin.up.total_len = pin.up.packet_len; - - pin.up.reason = wire_reason; - if (pin.up.reason == OFPR_ACTION) { - controller_max_len = pin.send_len; /* max_len */ - } else { - controller_max_len = ofconn->miss_send_len; - } - - /* Get OpenFlow buffer_id. - * For OpenFlow 1.2+, OFPCML_NO_BUFFER (== UINT16_MAX) specifies - * unbuffered. This behaviour doesn't violate prior versions, too. */ - if (controller_max_len == UINT16_MAX) { - pin.up.buffer_id = UINT32_MAX; - } else if (!ofconn->pktbuf) { - pin.up.buffer_id = UINT32_MAX; - } else { - pin.up.buffer_id = pktbuf_save(ofconn->pktbuf, - pin.up.packet, pin.up.packet_len, - pin.up.flow_metadata.flow.in_port.ofp_port); - } - - /* Figure out how much of the packet to send. - * If not buffered, send the entire packet. Otherwise, depending on - * the reason of packet-in, send what requested by the controller. */ - if (pin.up.buffer_id != UINT32_MAX - && controller_max_len < pin.up.packet_len) { - pin.up.packet_len = controller_max_len; - } - - /* Make OFPT_PACKET_IN and hand over to packet scheduler. */ - pinsched_send(ofconn->schedulers[pin.up.reason == OFPR_NO_MATCH ? 0 : 1], - pin.up.flow_metadata.flow.in_port.ofp_port, - ofputil_encode_packet_in(&pin.up, - ofconn_get_protocol(ofconn), - ofconn->packet_in_format), - &txq); - do_send_packet_ins(ofconn, &txq); -} /* Fail-open settings. */ @@ -2343,3 +2241,14 @@ ofmonitor_wait(struct connmgr *mgr) } ovs_mutex_unlock(&ofproto_mutex); } + +void +ofproto_async_msg_free(struct ofproto_async_msg *am) +{ + free(am->pin.up.public.packet); + free(am->pin.up.public.userdata); + free(am->pin.up.stack); + free(am->pin.up.actions); + free(am->pin.up.action_set); + free(am); +}