-
-/* 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)
-{
- struct connmgr *mgr = ofconn->connmgr;
- uint16_t controller_max_len;
- struct 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 (mgr->fail_open && fail_open_is_active(mgr->fail_open)) {
- pin.up.buffer_id = pktbuf_get_null();
- } 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.fmd.in_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.fmd.in_port,
- ofputil_encode_packet_in(&pin.up,
- ofconn_get_protocol(ofconn),
- ofconn->packet_in_format),
- &txq);
- do_send_packet_ins(ofconn, &txq);
-}