const struct ofp_header *oh,
struct ofpbuf *ofpacts)
{
- const struct ofp_packet_out *opo;
- enum ofperr error;
enum ofpraw raw;
struct ofpbuf b;
ofpbuf_use_const(&b, oh, ntohs(oh->length));
raw = ofpraw_pull_assert(&b);
- assert(raw == OFPRAW_OFPT10_PACKET_OUT);
- opo = ofpbuf_pull(&b, sizeof *opo);
- po->buffer_id = ntohl(opo->buffer_id);
- po->in_port = ntohs(opo->in_port);
+ if (raw == OFPRAW_OFPT10_PACKET_OUT) {
+ enum ofperr error;
+ const struct ofp_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
+
+ po->buffer_id = ntohl(opo->buffer_id);
+ po->in_port = ntohs(opo->in_port);
+
+ error = ofpacts_pull_openflow10(&b, ntohs(opo->actions_len), ofpacts);
+ if (error) {
+ return error;
+ }
+ } else {
+ NOT_REACHED();
+ }
+
if (po->in_port >= OFPP_MAX && po->in_port != OFPP_LOCAL
&& po->in_port != OFPP_NONE && po->in_port != OFPP_CONTROLLER) {
VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out has bad input port %#"PRIx16,
return OFPERR_NXBRC_BAD_IN_PORT;
}
- error = ofpacts_pull_openflow10(&b, ntohs(opo->actions_len), ofpacts);
- if (error) {
- return error;
- }
po->ofpacts = ofpacts->data;
po->ofpacts_len = ofpacts->size;
}
case OFP11_VERSION:
- case OFP12_VERSION:
+ case OFP12_VERSION: {
+ struct ofp11_packet_out *opo;
+ size_t len;
+
+ msg = ofpraw_alloc(OFPRAW_OFPT11_PACKET_OUT, ofp_version, size);
+ ofpbuf_put_zeros(msg, sizeof *opo);
+ len = ofpacts_put_openflow11_actions(po->ofpacts, po->ofpacts_len, msg);
+
+ opo = msg->l3;
+ opo->buffer_id = htonl(po->buffer_id);
+ opo->in_port = ofputil_port_to_ofp11(po->in_port);
+ opo->actions_len = htons(len);
+ break;
+ }
+
default:
NOT_REACHED();
}