- /* Update packet headers. */
- opi->buffer_id = htonl(buffer_id);
- update_openflow_length(packet);
-
- /* Hand over to packet scheduler. It might immediately call into
- * do_send_packet_in() or it might buffer it for a while (until a later
- * call to pinsched_run()). */
- pinsched_send(ofconn->schedulers[opi->reason], in_port,
- packet, do_send_packet_in, ofconn);
-}
-
-/* Replace struct odp_msg header in 'packet' by equivalent struct
- * ofp_packet_in. The odp_msg must have sufficient headroom to do so (e.g. as
- * returned by dpif_recv()).
- *
- * The conversion is not complete: the caller still needs to trim any unneeded
- * payload off the end of the buffer, set the length in the OpenFlow header,
- * and set buffer_id. Those require us to know the controller settings and so
- * must be done on a per-controller basis.
- *
- * Returns the maximum number of bytes of the packet that should be sent to
- * the controller (INT_MAX if no limit). */
-static int
-do_convert_to_packet_in(struct ofpbuf *packet)
-{
- struct odp_msg *msg = packet->data;
- struct ofp_packet_in *opi;
- uint8_t reason;
- uint16_t total_len;
- uint16_t in_port;
- int max_len;
-
- /* Extract relevant header fields */
- if (msg->type == _ODPL_ACTION_NR) {
- reason = OFPR_ACTION;
- max_len = msg->arg;
- } else {
- reason = OFPR_NO_MATCH;
- max_len = INT_MAX;
- }
- total_len = msg->length - sizeof *msg;
- in_port = odp_port_to_ofp_port(msg->port);
-
- /* Repurpose packet buffer by overwriting header. */
- ofpbuf_pull(packet, sizeof(struct odp_msg));
- opi = ofpbuf_push_zeros(packet, offsetof(struct ofp_packet_in, data));
- opi->header.version = OFP_VERSION;
- opi->header.type = OFPT_PACKET_IN;
- opi->total_len = htons(total_len);
- opi->in_port = htons(in_port);
- opi->reason = reason;
-
- return max_len;
+ /* Make OFPT_PACKET_IN and hand over to packet scheduler. It might
+ * immediately call into do_send_packet_in() or it might buffer it for a
+ * while (until a later call to pinsched_run()). */
+ msg = ofputil_encode_packet_in(&pin, clone ? NULL : upcall->packet);
+ pinsched_send(ofconn->schedulers[upcall->type == DPIF_UC_MISS ? 0 : 1],
+ flow->in_port, msg, do_send_packet_in, ofconn);