Signed-off-by: Simon Horman <ho...@verge.net.au> ---
v4 * No change v3 * Add OF1.2 entry to to ofputil_msg_types * Make OF1.2 the first option in the if statement in ofputil_decode_packet_in() * Rename o11pi as opi, which is consistent with the style used elsewhere * Rebase v2 * No change --- lib/ofp-util.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 1b15c11..cdbb303 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -824,6 +824,8 @@ static const struct ofputil_msg_type ofputil_msg_types[] = { sizeof(struct ofp_switch_features), sizeof(struct ofp11_port)), OFPT12(OFPT_FLOW_REMOVED, OFPT_FLOW_REMOVED, sizeof(struct ofp12_flow_removed), 0), + OFPT12(OFPT_PACKET_IN, OFPT_PACKET_IN, + offsetof(struct ofp_packet_in, data), 1), OFPT12(OFPT11_FLOW_MOD, OFPT11_FLOW_MOD, sizeof(struct ofp11_flow_mod), 1), OFPT12(OFPT_PORT_MOD, OFPT11_PORT_MOD, @@ -2459,6 +2461,24 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr, return msg; } +static void +ofputil_decode_packet_in_finish(struct ofputil_packet_in *pin, + struct cls_rule *rule, + struct ofpbuf *b) +{ + pin->packet = b->data; + pin->packet_len = b->size; + + pin->fmd.in_port = rule->flow.in_port; + + pin->fmd.tun_id = rule->flow.tun_id; + pin->fmd.tun_id_mask = rule->wc.tun_id_mask; + + memcpy(pin->fmd.regs, rule->flow.regs, sizeof pin->fmd.regs); + memcpy(pin->fmd.reg_masks, rule->wc.reg_masks, + sizeof pin->fmd.reg_masks); +} + enum ofperr ofputil_decode_packet_in(struct ofputil_packet_in *pin, const struct ofp_header *oh) @@ -2470,7 +2490,32 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin, code = ofputil_msg_type_code(type); memset(pin, 0, sizeof *pin); - if (code == OFPUTIL_OFPT_PACKET_IN) { + if (code == OFPUTIL_OFPT_PACKET_IN && oh->version == OFP12_VERSION) { + const struct ofp11_packet_in *opi; + struct cls_rule rule; + struct ofpbuf b; + int error; + + ofpbuf_use_const(&b, oh, ntohs(oh->length)); + + opi = ofpbuf_pull(&b, sizeof *opi); + error = ofputil_pull_ofp12_match(&b, 0, &rule, NULL, NULL); + if (error) { + return error; + } + + if (!ofpbuf_try_pull(&b, 2)) { + return OFPERR_OFPBRC_BAD_LEN; + } + + pin->reason = opi->reason; + pin->table_id = opi->table_id; + + pin->buffer_id = ntohl(opi->buffer_id); + pin->total_len = ntohs(opi->total_len); + + ofputil_decode_packet_in_finish(pin, &rule, &b); + } else if (code == OFPUTIL_OFPT_PACKET_IN && oh->version == OFP10_VERSION) { const struct ofp_packet_in *opi = (const struct ofp_packet_in *) oh; pin->packet = opi->data; @@ -2500,23 +2545,14 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin, return OFPERR_OFPBRC_BAD_LEN; } - pin->packet = b.data; - pin->packet_len = b.size; pin->reason = npi->reason; pin->table_id = npi->table_id; pin->cookie = npi->cookie; - pin->fmd.in_port = rule.flow.in_port; - - pin->fmd.tun_id = rule.flow.tun_id; - pin->fmd.tun_id_mask = rule.wc.tun_id_mask; - - memcpy(pin->fmd.regs, rule.flow.regs, sizeof pin->fmd.regs); - memcpy(pin->fmd.reg_masks, rule.wc.reg_masks, - sizeof pin->fmd.reg_masks); - pin->buffer_id = ntohl(npi->buffer_id); pin->total_len = ntohs(npi->total_len); + + ofputil_decode_packet_in_finish(pin, &rule, &b); } else { NOT_REACHED(); } -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev