}
struct ofpbuf *
-make_unbuffered_packet_out(const struct ofpbuf *packet,
- uint16_t in_port, uint16_t out_port)
+make_packet_out(const struct ofpbuf *packet, uint32_t buffer_id,
+ uint16_t in_port,
+ const struct ofp_action_header *actions, size_t n_actions)
{
+ size_t actions_len = n_actions * sizeof *actions;
struct ofp_packet_out *opo;
- struct ofp_action_output *oao;
- size_t size = sizeof *opo + sizeof *oao;
- struct ofpbuf *out = ofpbuf_new(size + packet->size);
+ size_t size = sizeof *opo + actions_len + (packet ? packet->size : 0);
+ struct ofpbuf *out = ofpbuf_new(size);
- opo = ofpbuf_put_zeros(out, size);
+ opo = ofpbuf_put_uninit(out, sizeof *opo);
opo->header.version = OFP_VERSION;
opo->header.type = OFPT_PACKET_OUT;
- opo->buffer_id = htonl(UINT32_MAX);
+ opo->header.length = htons(size);
+ opo->header.xid = htonl(0);
+ opo->buffer_id = htonl(buffer_id);
opo->in_port = htons(in_port);
-
- oao = (struct ofp_action_output *)&opo->actions[0];
- oao->type = htons(OFPAT_OUTPUT);
- oao->len = htons(sizeof *oao);
- oao->port = htons(out_port);
-
- opo->actions_len = htons(sizeof *oao);
-
- ofpbuf_put(out, packet->data, packet->size);
- update_openflow_length(out);
+ opo->actions_len = htons(actions_len);
+ ofpbuf_put(out, actions, actions_len);
+ if (packet) {
+ ofpbuf_put(out, packet->data, packet->size);
+ }
return out;
}
+struct ofpbuf *
+make_unbuffered_packet_out(const struct ofpbuf *packet,
+ uint16_t in_port, uint16_t out_port)
+{
+ struct ofp_action_output action;
+ action.type = htons(OFPAT_OUTPUT);
+ action.len = htons(sizeof action);
+ action.port = htons(out_port);
+ return make_packet_out(packet, UINT32_MAX, in_port,
+ (struct ofp_action_header *) &action, 1);
+}
+
struct ofpbuf *
make_buffered_packet_out(uint32_t buffer_id,
uint16_t in_port, uint16_t out_port)
{
- struct ofp_packet_out *opo;
- struct ofp_action_output *oao;
- size_t size = sizeof *opo + sizeof *oao;
- struct ofpbuf *out = ofpbuf_new(size);
- opo = ofpbuf_put_zeros(out, size);
- opo->header.version = OFP_VERSION;
- opo->header.type = OFPT_PACKET_OUT;
- opo->header.length = htons(size);
- opo->buffer_id = htonl(buffer_id);
- opo->in_port = htons(in_port);
-
- oao = (struct ofp_action_output *)&opo->actions[0];
- oao->type = htons(OFPAT_OUTPUT);
- oao->len = htons(sizeof *oao);
- oao->port = htons(out_port);
-
- opo->actions_len = htons(sizeof *oao);
- return out;
+ struct ofp_action_output action;
+ action.type = htons(OFPAT_OUTPUT);
+ action.len = htons(sizeof action);
+ action.port = htons(out_port);
+ return make_packet_out(NULL, buffer_id, in_port,
+ (struct ofp_action_header *) &action, 1);
}
/* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */