On Fri, Feb 03, 2012 at 12:43:50PM -0800, Ben Pfaff wrote:
> OpenFlow actions have always been somewhat awkward to handle.
> Moreover, over time we've started creating actions that require more
> complicated parsing. When we maintain those actions internally in
> their wire format, we end up parsing them multiple times, whenever
> we have to look at the set of actions.
>
> When we add support for OpenFlow 1.1 or later protocols, the situation
> will get worse, because these newer protocols support many of the same
> actions but with different representations. It becomes unrealistic to
> handle each protocol in its wire format.
>
> This commit adopts a new strategy, by converting OpenFlow actions into
> an internal form from the wire format when they are read, and converting
> them back to the wire format when flows are dumped. I believe that this
> will be more maintainable over time.
>
> The following improvements are necessary before this commit is ready:
>
> - The current commit formats internal actions as Netlink. This is
> an imperfect choice because Netlink attributes are only 4-byte
> aligned, which makes it awkward to include 64-bit integers and
> pointers inside actions. It would be nice to figure out a way to
> do this, either by adding a way to 64-bit align Netlink attributes
> or to use a different framing format.
>
> - Add comments in various places.
>
> - The new functions in netlink, meta-flow, and ofp-util might be easier
> to review as separate commits.
>
> - A few minor points marked with XXX.
[snip]
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index f23b0dd..3b7eac1 100644
[snip]
> @@ -1953,17 +1944,14 @@ reject_slave_controller(struct ofconn *ofconn)
> }
>
> static enum ofperr
> -handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
> +handle_packet_out(struct ofconn *ofconn, const struct ofp_packet_out *opo)
> {
> struct ofproto *p = ofconn_get_ofproto(ofconn);
> - struct ofp_packet_out *opo;
> - struct ofpbuf payload, *buffer;
> - union ofp_action *ofp_actions;
> - struct ofpbuf request;
> + struct ofputil_packet_out po;
> + struct ofpbuf *payload;
> + struct nlattr *ofpacts;
> struct flow flow;
> - size_t n_ofp_actions;
> enum ofperr error;
> - uint16_t in_port;
>
> COVERAGE_INC(ofproto_packet_out);
>
> @@ -1972,28 +1960,21 @@ handle_packet_out(struct ofconn *ofconn, const struct
> ofp_header *oh)
> return error;
> }
>
> - /* Get ofp_packet_out. */
> - ofpbuf_use_const(&request, oh, ntohs(oh->length));
> - opo = ofpbuf_pull(&request, offsetof(struct ofp_packet_out, actions));
> -
> - /* Get actions. */
> - error = ofputil_pull_actions(&request, ntohs(opo->actions_len),
> - &ofp_actions, &n_ofp_actions);
> + /* Decode message. */
> + error = ofputil_decode_packet_out(&po, opo);
> if (error) {
> return error;
> }
>
> /* Get payload. */
> - if (opo->buffer_id != htonl(UINT32_MAX)) {
> - error = ofconn_pktbuf_retrieve(ofconn, ntohl(opo->buffer_id),
> - &buffer, NULL);
> - if (error || !buffer) {
> + if (po.buffer_id != UINT32_MAX) {
> + error = ofconn_pktbuf_retrieve(ofconn, po.buffer_id, &payload, NULL);
> + if (error || !payload) {
> return error;
> }
> - payload = *buffer;
> } else {
> - payload = request;
> - buffer = NULL;
> + payload = xmalloc(sizeof *payload);
> + ofpbuf_use_const(payload, po.packet, po.packet_len);
> }
>
> /* Get in_port and partially validate it.
> @@ -2001,16 +1982,15 @@ handle_packet_out(struct ofconn *ofconn, const struct
> ofp_header *oh)
> * We don't know what range of ports the ofproto actually implements, but
> * we do know that only certain reserved ports (numbered OFPP_MAX and
> * above) are valid. */
> - in_port = ntohs(opo->in_port);
> - if (in_port >= OFPP_MAX && in_port != OFPP_LOCAL && in_port !=
> OFPP_NONE) {
> + if (po.in_port >= OFPP_MAX && po.in_port != OFPP_LOCAL
> + && po.in_port != OFPP_NONE) {
> return OFPERR_NXBRC_BAD_IN_PORT;
> }
>
> /* Send out packet. */
> - flow_extract(&payload, 0, 0, in_port, &flow);
> - error = p->ofproto_class->packet_out(p, &payload, &flow,
> - ofp_actions, n_ofp_actions);
> - ofpbuf_delete(buffer);
> + flow_extract(payload, 0, 0, po.in_port, &flow);
> + error = p->ofproto_class->packet_out(p, payload, &flow, ofpacts);
> + ofpbuf_delete(payload);
>
> return error;
> }
ofpacts seems to be use uninitialised.
Is it necessary to some how initialise ofpacts from
po.actions and po.n_actions?
[snip]
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev