Signed-off-by: Simon Horman <ho...@verge.net.au> ---
v4 * Manual rebase v3 * Add protocol variable to do_probe(). Previously this was added by a separate patch. v2 * No change --- lib/learning-switch.c | 10 ++++++++-- lib/ofp-util.c | 30 ++++++++++++++++++------------ lib/ofp-util.h | 3 ++- utilities/ovs-ofctl.c | 5 +++-- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index ec0b64b..660fc20 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -463,6 +463,9 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, struct ofpbuf pkt; struct flow flow; + enum ofputil_protocol protocol; + int ofp_version; + error = ofputil_decode_packet_in(&pi, oh); if (error) { VLOG_WARN_RL(&rl, "failed to decode packet-in: %s", @@ -511,6 +514,9 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; + ofp_version = rconn_get_version(rconn); + protocol = ofputil_protocol_from_ofp_version(ofp_version); + /* Send the packet, and possibly the whole flow, to the output port. */ if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) { struct ofputil_flow_mod fm; @@ -533,13 +539,13 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, /* If the switch didn't buffer the packet, we need to send a copy. */ if (pi.buffer_id == UINT32_MAX && out_port != OFPP_NONE) { - queue_tx(sw, rconn, ofputil_encode_packet_out(&po)); + queue_tx(sw, rconn, ofputil_encode_packet_out(&po, protocol)); } } else { /* We don't know that MAC, or we don't set up flows. Send along the * packet without setting up a flow. */ if (pi.buffer_id != UINT32_MAX || out_port != OFPP_NONE) { - queue_tx(sw, rconn, ofputil_encode_packet_out(&po)); + queue_tx(sw, rconn, ofputil_encode_packet_out(&po, protocol)); } } } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index f4ade7d..42955e0 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -3326,25 +3326,31 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm, } struct ofpbuf * -ofputil_encode_packet_out(const struct ofputil_packet_out *po) +ofputil_encode_packet_out(const struct ofputil_packet_out *po, + enum ofputil_protocol protocol) { - struct ofp_packet_out *opo; + uint8_t ofp_version = ofputil_protocol_to_ofp_version(protocol); struct ofpbuf *msg; - size_t size; + size_t packet_len = 0; - size = sizeof *opo + po->ofpacts_len; if (po->buffer_id == UINT32_MAX) { - size += po->packet_len; + packet_len = po->packet_len; } - msg = ofpbuf_new(size); - put_openflow(sizeof *opo, OFP10_VERSION, OFPT10_PACKET_OUT, msg); - ofpacts_to_openflow10(po->ofpacts, msg); + if (ofp_version == OFP10_VERSION) { + struct ofp_packet_out *opo; + + msg = ofpbuf_new(packet_len + sizeof *opo); + put_openflow(sizeof *opo, ofp_version, OFPT10_PACKET_OUT, msg); + opo = msg->data; + opo->buffer_id = htonl(po->buffer_id); + opo->in_port = htons(po->in_port); + opo->actions_len = htons(msg->size - sizeof *opo); + } else { + NOT_REACHED(); + } - opo = msg->data; - opo->buffer_id = htonl(po->buffer_id); - opo->in_port = htons(po->in_port); - opo->actions_len = htons(msg->size - sizeof *opo); + ofpacts_to_openflow10(po->ofpacts, msg); if (po->buffer_id == UINT32_MAX) { ofpbuf_put(msg, po->packet, po->packet_len); diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 33e6a95..c0d5d6d 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -378,7 +378,8 @@ struct ofputil_packet_out { enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *, const struct ofp_header *, struct ofpbuf *ofpacts); -struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *); +struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *, + enum ofputil_protocol protocol); enum ofputil_port_config { /* OpenFlow 1.0 and 1.1 share these values for these port config bits. */ diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index ea58263..71d4ba3 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -1239,6 +1239,7 @@ do_probe(int argc OVS_UNUSED, char *argv[]) static void do_packet_out(int argc, char *argv[]) { + enum ofputil_protocol protocol; struct ofputil_packet_out po; struct ofpbuf ofpacts; struct vconn *vconn; @@ -1254,7 +1255,7 @@ do_packet_out(int argc, char *argv[]) po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; - open_vconn(argv[1], &vconn); + protocol = open_vconn(argv[1], &vconn); for (i = 4; i < argc; i++) { struct ofpbuf *packet, *opo; const char *error_msg; @@ -1266,7 +1267,7 @@ do_packet_out(int argc, char *argv[]) po.packet = packet->data; po.packet_len = packet->size; - opo = ofputil_encode_packet_out(&po); + opo = ofputil_encode_packet_out(&po, protocol); transact_noreply(vconn, opo); ofpbuf_delete(packet); } -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev