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;
+
+ pin->fmd.metadata = rule->flow.metadata;
+ pin->fmd.metadata_mask = rule->wc.metadata_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)
ofpbuf_use_const(&b, oh, ntohs(oh->length));
raw = ofpraw_pull_assert(&b);
- if (raw == OFPRAW_OFPT10_PACKET_IN) {
+ if (raw == OFPRAW_OFPT12_PACKET_IN) {
+ const struct ofp12_packet_in *opi;
+ struct cls_rule rule;
+ int error;
+
+ opi = ofpbuf_pull(&b, sizeof *opi);
+ error = oxm_pull_match_loose(&b, 0, &rule);
+ 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 (raw == OFPRAW_OFPT10_PACKET_IN) {
const struct ofp_packet_in *opi;
opi = ofpbuf_pull(&b, offsetof(struct ofp_packet_in, data));
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;
-
- pin->fmd.metadata = rule.flow.metadata;
- pin->fmd.metadata_mask = rule.wc.metadata_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();
}
])
AT_CLEANUP
-AT_SETUP([OFPT_PACKET_IN])
+AT_SETUP([OFPT_PACKET_IN - OF1.0])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
01 0a 00 4e 00 00 00 00 00 00 01 11 00 3c 00 03 \
])
AT_CLEANUP
+AT_SETUP([OFPT_PACKET_IN - OF1.2])
+AT_KEYWORDS([ofp-print])
+AT_CHECK([ovs-ofctl ofp-print "\
+03 0a 00 4c 00 00 00 00 ff ff ff 00 00 2a 00 00 \
+00 01 00 0c 80 00 00 04 ff ff ff fe 00 00 00 00 \
+00 00 ff ff ff ff ff ff 00 23 20 83 c1 5f 80 35 \
+00 01 08 00 06 04 00 03 00 23 20 83 c1 5f 00 00 \
+00 00 00 23 20 83 c1 5f 00 00 00 00 \
+"], [0], [dnl
+OFPT_PACKET_IN (OF1.2) (xid=0x0): total_len=42 in_port=LOCAL (via no_match) data_len=42 buffer=0xffffff00
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(00:23:20:83:c1:5f->ff:ff:ff:ff:ff:ff) type:8035 proto:0 tos:0 ttl:0 ip(0.0.0.0->0.0.0.0)
+])
+AT_CLEANUP
+
AT_SETUP([OFPT_FLOW_REMOVED])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\