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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev