}
static void
-ofp_print_packet_in(struct ds *string, const struct ofp_packet_in *op,
+ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
int verbosity)
{
- size_t len = ntohs(op->header.length);
- size_t data_len;
+ struct ofputil_packet_in pin;
+ int error;
- ds_put_format(string, " total_len=%"PRIu16" in_port=",
- ntohs(op->total_len));
- ofputil_format_port(ntohs(op->in_port), string);
+ error = ofputil_decode_packet_in(&pin, oh);
+ if (error) {
+ ofp_print_error(string, error);
+ return;
+ }
- if (op->reason == OFPR_ACTION)
+ ds_put_format(string, " total_len=%"PRIu16" in_port=", pin.total_len);
+ ofputil_format_port(pin.in_port, string);
+
+ if (pin.reason == OFPR_ACTION) {
ds_put_cstr(string, " (via action)");
- else if (op->reason != OFPR_NO_MATCH)
- ds_put_format(string, " (***reason %"PRIu8"***)", op->reason);
+ } else if (pin.reason != OFPR_NO_MATCH) {
+ ds_put_format(string, " (***reason %"PRIu8"***)", pin.reason);
+ }
- data_len = len - offsetof(struct ofp_packet_in, data);
- ds_put_format(string, " data_len=%zu", data_len);
- if (op->buffer_id == htonl(UINT32_MAX)) {
+ ds_put_format(string, " data_len=%zu", pin.packet_len);
+ if (pin.buffer_id == UINT32_MAX) {
ds_put_format(string, " (unbuffered)");
- if (ntohs(op->total_len) != data_len)
+ if (pin.total_len != pin.packet_len) {
ds_put_format(string, " (***total_len != data_len***)");
+ }
} else {
- ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(op->buffer_id));
- if (ntohs(op->total_len) < data_len)
+ ds_put_format(string, " buffer=0x%08"PRIx32, pin.buffer_id);
+ if (pin.total_len < pin.packet_len) {
ds_put_format(string, " (***total_len < data_len***)");
+ }
}
ds_put_char(string, '\n');
if (verbosity > 0) {
- char *packet = ofp_packet_to_string(op->data, data_len);
+ char *packet = ofp_packet_to_string(pin.packet, pin.packet_len);
ds_put_cstr(string, packet);
free(packet);
}
return msg;
}
+int
+ofputil_decode_packet_in(struct ofputil_packet_in *pin,
+ const struct ofp_header *oh)
+{
+ const struct ofputil_msg_type *type;
+ enum ofputil_msg_code code;
+
+ ofputil_decode_msg_type(oh, &type);
+ code = ofputil_msg_type_code(type);
+ memset(pin, 0, sizeof *pin);
+
+ if (code == OFPUTIL_OFPT_PACKET_IN) {
+ const struct ofp_packet_in *opi = (const struct ofp_packet_in *) oh;
+
+ pin->packet = opi->data;
+ pin->packet_len = ntohs(opi->header.length)
+ - offsetof(struct ofp_packet_in, data);
+
+ pin->in_port = ntohs(opi->in_port);
+ pin->reason = opi->reason;
+ pin->buffer_id = ntohl(opi->buffer_id);
+ pin->total_len = ntohs(opi->total_len);
+ } else {
+ NOT_REACHED();
+ }
+
+ return 0;
+}
+
/* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
* and returns the message. */
struct ofpbuf *
pin.packet = packet->data;
pin.packet_len = packet->size;
+ pin.total_len = packet->size;
pin.in_port = flow->in_port;
pin.reason = OFPR_NO_MATCH;
pin.buffer_id = 0; /* not yet known */
pin.packet = packet->data;
pin.packet_len = packet->size;
+ pin.total_len = packet->size;
pin.in_port = flow->in_port;
pin.reason = OFPR_ACTION;
pin.buffer_id = 0; /* not yet known */