case OFPAT_SET_NW_SRC: {
struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
- ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(na->nw_addr));
+ ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(&na->nw_addr));
break;
}
case OFPAT_SET_NW_DST: {
struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
- ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(na->nw_addr));
+ ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(&na->nw_addr));
break;
}
size_t actions_len)
{
uint8_t *p = (uint8_t *)action;
- size_t len = 0;
+ int len = 0;
ds_put_cstr(string, "actions=");
while (actions_len > 0) {
print_wild(f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
"%u", om->nw_proto);
}
- print_wild(f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
- "%d", ntohs(om->tp_src));
- print_wild(f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
- "%d", ntohs(om->tp_dst));
+ if (om->nw_proto == IP_TYPE_ICMP) {
+ print_wild(f, "icmp_type=", w & OFPFW_ICMP_TYPE, verbosity,
+ "%d", ntohs(om->icmp_type));
+ print_wild(f, "icmp_code=", w & OFPFW_ICMP_CODE, verbosity,
+ "%d", ntohs(om->icmp_code));
+ } else {
+ print_wild(f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
+ "%d", ntohs(om->tp_src));
+ print_wild(f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
+ "%d", ntohs(om->tp_dst));
+ }
}
/* Pretty-print the OFPT_FLOW_MOD packet of 'len' bytes at 'oh' to 'string'
ntohl(ofe->duration), ntohll(ofe->packet_count),
ntohll(ofe->byte_count));
}
+/* Pretty-print the NXT_FLOW_EXPIRED packet of 'len' bytes at 'oh' to 'string'
+ * at the given 'verbosity' level. */
+static void
+nx_print_flow_end(struct ds *string, const void *oh, size_t len,
+ int verbosity)
+{
+ const struct nx_flow_end *nfe = oh;
+
+ ds_put_cstr(string, "nx_flow_end: ");
+
+ if (len < sizeof(*nfe)) {
+ ds_put_format(string, " (***length=%zu < min_size=%zu***)\n",
+ len, sizeof(*nfe));
+ return;
+ }
+
+ ofp_print_match(string, &nfe->match, verbosity);
+ ds_put_cstr(string, " reason=");
+ switch (nfe->reason) {
+ case NXFER_IDLE_TIMEOUT:
+ ds_put_cstr(string, "idle");
+ break;
+ case NXFER_HARD_TIMEOUT:
+ ds_put_cstr(string, "hard");
+ break;
+ case NXFER_DELETE:
+ ds_put_cstr(string, "delete");
+ break;
+ case NXFER_EJECT:
+ ds_put_cstr(string, "eject");
+ break;
+ default:
+ ds_put_format(string, "**%"PRIu8"**", nfe->reason);
+ break;
+ }
+ ds_put_format(string,
+ " pri=%"PRIu16" init=%"PRIu64" used=%"PRIu64" end=%"PRIu64,
+ nfe->match.wildcards ? ntohs(nfe->priority) : (uint16_t)-1,
+ ntohll(nfe->init_time), ntohll(nfe->used_time),
+ ntohll(nfe->end_time));
+ ds_put_format(string,
+ " tflags=0x%x tos=0x%x pkts=%"PRIu64" bytes=%"PRIu64"\n",
+ nfe->tcp_flags, nfe->ip_tos, ntohll(nfe->packet_count),
+ ntohll(nfe->byte_count));
+}
+
+static void
+nx_print_msg(struct ds *string, const void *oh, size_t len, int verbosity)
+{
+ const struct nicira_header *nh = oh;
+
+ switch(ntohl(nh->subtype))
+ {
+ case NXT_FLOW_END:
+ nx_print_flow_end(string, oh, len, verbosity);
+ return;
+ }
+}
+
static void
ofp_print_port_mod(struct ds *string, const void *oh, size_t len,
}
}
+static void
+ofp_vendor(struct ds *string, const void *oh, size_t len, int verbosity)
+{
+ const struct ofp_vendor_header *vh = oh;
+
+ switch(ntohl(vh->vendor))
+ {
+ case NX_VENDOR_ID:
+ return nx_print_msg(string, oh, len, verbosity);
+ break;
+ }
+}
+
struct openflow_packet {
uint8_t type;
const char *name;
sizeof (struct ofp_header),
ofp_echo,
},
+ {
+ OFPT_VENDOR,
+ "vendor",
+ sizeof (struct ofp_vendor_header),
+ ofp_vendor,
+ },
};
/* Composes and returns a string representing the OpenFlow packet of 'len'