From c77431ef47f542a6b2811e5cfb2832e09a108d3f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 28 Jan 2009 16:39:16 -0800 Subject: [PATCH] New function make_packet_out(), and reimplement helpers in terms of it. --- lib/vconn.c | 68 ++++++++++++++++++++++++++--------------------------- lib/vconn.h | 5 ++++ 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/lib/vconn.c b/lib/vconn.c index c9269b5f..bc01d4ac 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -920,54 +920,52 @@ make_add_simple_flow(const struct flow *flow, } 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. */ diff --git a/lib/vconn.h b/lib/vconn.h index fd384752..7916f86d 100644 --- a/lib/vconn.h +++ b/lib/vconn.h @@ -40,6 +40,7 @@ struct ofpbuf; struct flow; +struct ofp_action_header; struct ofp_header; struct ofp_stats_reply; struct pvconn; @@ -95,6 +96,10 @@ struct ofpbuf *make_del_flow(const struct flow *); struct ofpbuf *make_add_simple_flow(const struct flow *, uint32_t buffer_id, uint16_t out_port, uint16_t max_idle); +struct ofpbuf *make_packet_out(const struct ofpbuf *packet, uint32_t buffer_id, + uint16_t in_port, + const struct ofp_action_header *, + size_t n_actions); struct ofpbuf *make_buffered_packet_out(uint32_t buffer_id, uint16_t in_port, uint16_t out_port); struct ofpbuf *make_unbuffered_packet_out(const struct ofpbuf *packet, -- 2.30.2