X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofp-print.c;h=79e23a933ef4e6bf65014f1a3e84d358f78f5ee1;hb=42c1353f46d59a5bc7b4012c7ab505cc14940f2d;hp=8df439de1af4124e4664e6dd48b74bb386c4be61;hpb=2953097759d3baaf22223b876d0028be8df78d3d;p=openvswitch diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 8df439de..79e23a93 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -34,6 +34,7 @@ #include "learn.h" #include "multipath.h" #include "meta-flow.h" +#include "netdev.h" #include "nx-match.h" #include "ofp-errors.h" #include "ofp-util.h" @@ -80,24 +81,6 @@ ofp_packet_to_string(const void *data, size_t len) return ds_cstr(&ds); } -static const char * -ofp_packet_in_reason_to_string(enum ofp_packet_in_reason reason) -{ - static char s[32]; - - switch (reason) { - case OFPR_NO_MATCH: - return "no_match"; - case OFPR_ACTION: - return "action"; - case OFPR_INVALID_TTL: - return "invalid_ttl"; - default: - sprintf(s, "%d", (int) reason); - return s; - } -} - static void ofp_print_packet_in(struct ds *string, const struct ofp_header *oh, int verbosity) @@ -140,7 +123,7 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh, } ds_put_format(string, " (via %s)", - ofp_packet_in_reason_to_string(pin.reason)); + ofputil_packet_in_reason_to_string(pin.reason)); ds_put_format(string, " data_len=%zu", pin.packet_len); if (pin.buffer_id == UINT32_MAX) { @@ -194,11 +177,13 @@ ofp_print_action(struct ds *s, const union ofp_action *a, const struct nx_action_multipath *nam; const struct nx_action_autopath *naa; const struct nx_action_output_reg *naor; + const struct nx_action_fin_timeout *naft; + const struct nx_action_controller *nac; struct mf_subfield subfield; uint16_t port; switch (code) { - case OFPUTIL_OFPAT_OUTPUT: + case OFPUTIL_OFPAT10_OUTPUT: port = ntohs(a->output.port); if (port < OFPP_MAX) { ds_put_format(s, "output:%"PRIu16, port); @@ -214,55 +199,55 @@ ofp_print_action(struct ds *s, const union ofp_action *a, } break; - case OFPUTIL_OFPAT_ENQUEUE: + case OFPUTIL_OFPAT10_ENQUEUE: oae = (const struct ofp_action_enqueue *) a; ds_put_format(s, "enqueue:"); ofputil_format_port(ntohs(oae->port), s); ds_put_format(s, "q%"PRIu32, ntohl(oae->queue_id)); break; - case OFPUTIL_OFPAT_SET_VLAN_VID: + case OFPUTIL_OFPAT10_SET_VLAN_VID: ds_put_format(s, "mod_vlan_vid:%"PRIu16, ntohs(a->vlan_vid.vlan_vid)); break; - case OFPUTIL_OFPAT_SET_VLAN_PCP: + case OFPUTIL_OFPAT10_SET_VLAN_PCP: ds_put_format(s, "mod_vlan_pcp:%"PRIu8, a->vlan_pcp.vlan_pcp); break; - case OFPUTIL_OFPAT_STRIP_VLAN: + case OFPUTIL_OFPAT10_STRIP_VLAN: ds_put_cstr(s, "strip_vlan"); break; - case OFPUTIL_OFPAT_SET_DL_SRC: + case OFPUTIL_OFPAT10_SET_DL_SRC: oada = (const struct ofp_action_dl_addr *) a; ds_put_format(s, "mod_dl_src:"ETH_ADDR_FMT, ETH_ADDR_ARGS(oada->dl_addr)); break; - case OFPUTIL_OFPAT_SET_DL_DST: + case OFPUTIL_OFPAT10_SET_DL_DST: oada = (const struct ofp_action_dl_addr *) a; ds_put_format(s, "mod_dl_dst:"ETH_ADDR_FMT, ETH_ADDR_ARGS(oada->dl_addr)); break; - case OFPUTIL_OFPAT_SET_NW_SRC: + case OFPUTIL_OFPAT10_SET_NW_SRC: ds_put_format(s, "mod_nw_src:"IP_FMT, IP_ARGS(&a->nw_addr.nw_addr)); break; - case OFPUTIL_OFPAT_SET_NW_DST: + case OFPUTIL_OFPAT10_SET_NW_DST: ds_put_format(s, "mod_nw_dst:"IP_FMT, IP_ARGS(&a->nw_addr.nw_addr)); break; - case OFPUTIL_OFPAT_SET_NW_TOS: + case OFPUTIL_OFPAT10_SET_NW_TOS: ds_put_format(s, "mod_nw_tos:%d", a->nw_tos.nw_tos); break; - case OFPUTIL_OFPAT_SET_TP_SRC: + case OFPUTIL_OFPAT10_SET_TP_SRC: ds_put_format(s, "mod_tp_src:%d", ntohs(a->tp_port.tp_port)); break; - case OFPUTIL_OFPAT_SET_TP_DST: + case OFPUTIL_OFPAT10_SET_TP_DST: ds_put_format(s, "mod_tp_dst:%d", ntohs(a->tp_port.tp_port)); break; @@ -356,6 +341,38 @@ ofp_print_action(struct ds *s, const union ofp_action *a, ds_put_cstr(s, "exit"); break; + case OFPUTIL_NXAST_FIN_TIMEOUT: + naft = (const struct nx_action_fin_timeout *) a; + ds_put_cstr(s, "fin_timeout("); + if (naft->fin_idle_timeout) { + ds_put_format(s, "idle_timeout=%"PRIu16",", + ntohs(naft->fin_idle_timeout)); + } + if (naft->fin_hard_timeout) { + ds_put_format(s, "hard_timeout=%"PRIu16",", + ntohs(naft->fin_hard_timeout)); + } + ds_chomp(s, ','); + ds_put_char(s, ')'); + break; + + case OFPUTIL_NXAST_CONTROLLER: + nac = (const struct nx_action_controller *) a; + ds_put_cstr(s, "controller("); + if (nac->reason != OFPR_ACTION) { + ds_put_format(s, "reason=%s,", + ofputil_packet_in_reason_to_string(nac->reason)); + } + if (nac->max_len != htons(UINT16_MAX)) { + ds_put_format(s, "max_len=%"PRIu16",", ntohs(nac->max_len)); + } + if (nac->controller_id != htons(0)) { + ds_put_format(s, "id=%"PRIu16",", ntohs(nac->controller_id)); + } + ds_chomp(s, ','); + ds_put_char(s, ')'); + break; + default: break; } @@ -427,37 +444,38 @@ ofp_print_packet_out(struct ds *string, const struct ofp_packet_out *opo, static int compare_ports(const void *a_, const void *b_) { - const struct ofp_phy_port *a = a_; - const struct ofp_phy_port *b = b_; - uint16_t ap = ntohs(a->port_no); - uint16_t bp = ntohs(b->port_no); + const struct ofputil_phy_port *a = a_; + const struct ofputil_phy_port *b = b_; + uint16_t ap = a->port_no; + uint16_t bp = b->port_no; return ap < bp ? -1 : ap > bp; } -struct bit_name { - uint32_t bit; - const char *name; -}; - static void ofp_print_bit_names(struct ds *string, uint32_t bits, - const struct bit_name bit_names[]) + const char *(*bit_to_name)(uint32_t bit)) { int n = 0; + int i; if (!bits) { ds_put_cstr(string, "0"); return; } - for (; bits && bit_names->name; bit_names++) { - if (bits & bit_names->bit) { - if (n++) { - ds_put_char(string, ' '); + for (i = 0; i < 32; i++) { + uint32_t bit = UINT32_C(1) << i; + + if (bits & bit) { + const char *name = bit_to_name(bit); + if (name) { + if (n++) { + ds_put_char(string, ' '); + } + ds_put_cstr(string, name); + bits &= ~bit; } - ds_put_cstr(string, bit_names->name); - bits &= ~bit_names->bit; } } @@ -469,55 +487,90 @@ ofp_print_bit_names(struct ds *string, uint32_t bits, } } +static const char * +netdev_feature_to_name(uint32_t bit) +{ + enum netdev_features f = bit; + + switch (f) { + case NETDEV_F_10MB_HD: return "10MB-HD"; + case NETDEV_F_10MB_FD: return "10MB-FD"; + case NETDEV_F_100MB_HD: return "100MB-HD"; + case NETDEV_F_100MB_FD: return "100MB-FD"; + case NETDEV_F_1GB_HD: return "1GB-HD"; + case NETDEV_F_1GB_FD: return "1GB-FD"; + case NETDEV_F_10GB_FD: return "10GB-FD"; + case NETDEV_F_40GB_FD: return "40GB-FD"; + case NETDEV_F_100GB_FD: return "100GB-FD"; + case NETDEV_F_1TB_FD: return "1TB-FD"; + case NETDEV_F_OTHER: return "OTHER"; + case NETDEV_F_COPPER: return "COPPER"; + case NETDEV_F_FIBER: return "FIBER"; + case NETDEV_F_AUTONEG: return "AUTO_NEG"; + case NETDEV_F_PAUSE: return "AUTO_PAUSE"; + case NETDEV_F_PAUSE_ASYM: return "AUTO_PAUSE_ASYM"; + } + + return NULL; +} + static void -ofp_print_port_features(struct ds *string, uint32_t features) +ofp_print_port_features(struct ds *string, enum netdev_features features) { - static const struct bit_name feature_bits[] = { - { OFPPF_10MB_HD, "10MB-HD" }, - { OFPPF_10MB_FD, "10MB-FD" }, - { OFPPF_100MB_HD, "100MB-HD" }, - { OFPPF_100MB_FD, "100MB-FD" }, - { OFPPF_1GB_HD, "1GB-HD" }, - { OFPPF_1GB_FD, "1GB-FD" }, - { OFPPF_10GB_FD, "10GB-FD" }, - { OFPPF_COPPER, "COPPER" }, - { OFPPF_FIBER, "FIBER" }, - { OFPPF_AUTONEG, "AUTO_NEG" }, - { OFPPF_PAUSE, "AUTO_PAUSE" }, - { OFPPF_PAUSE_ASYM, "AUTO_PAUSE_ASYM" }, - { 0, NULL }, - }; - - ofp_print_bit_names(string, features, feature_bits); + ofp_print_bit_names(string, features, netdev_feature_to_name); ds_put_char(string, '\n'); } +static const char * +ofputil_port_config_to_name(uint32_t bit) +{ + enum ofputil_port_config pc = bit; + + switch (pc) { + case OFPUTIL_PC_PORT_DOWN: return "PORT_DOWN"; + case OFPUTIL_PC_NO_STP: return "NO_STP"; + case OFPUTIL_PC_NO_RECV: return "NO_RECV"; + case OFPUTIL_PC_NO_RECV_STP: return "NO_RECV_STP"; + case OFPUTIL_PC_NO_FLOOD: return "NO_FLOOD"; + case OFPUTIL_PC_NO_FWD: return "NO_FWD"; + case OFPUTIL_PC_NO_PACKET_IN: return "NO_PACKET_IN"; + } + + return NULL; +} + static void -ofp_print_port_config(struct ds *string, uint32_t config) +ofp_print_port_config(struct ds *string, enum ofputil_port_config config) { - static const struct bit_name config_bits[] = { - { OFPPC_PORT_DOWN, "PORT_DOWN" }, - { OFPPC_NO_STP, "NO_STP" }, - { OFPPC_NO_RECV, "NO_RECV" }, - { OFPPC_NO_RECV_STP, "NO_RECV_STP" }, - { OFPPC_NO_FLOOD, "NO_FLOOD" }, - { OFPPC_NO_FWD, "NO_FWD" }, - { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" }, - { 0, NULL }, - }; - - ofp_print_bit_names(string, config, config_bits); + ofp_print_bit_names(string, config, ofputil_port_config_to_name); ds_put_char(string, '\n'); } +static const char * +ofputil_port_state_to_name(uint32_t bit) +{ + enum ofputil_port_state ps = bit; + + switch (ps) { + case OFPUTIL_PS_LINK_DOWN: return "LINK_DOWN"; + case OFPUTIL_PS_BLOCKED: return "BLOCKED"; + case OFPUTIL_PS_LIVE: return "LIVE"; + + case OFPUTIL_PS_STP_LISTEN: + case OFPUTIL_PS_STP_LEARN: + case OFPUTIL_PS_STP_FORWARD: + case OFPUTIL_PS_STP_BLOCK: + /* Handled elsewhere. */ + return NULL; + } + + return NULL; +} + static void -ofp_print_port_state(struct ds *string, uint32_t state) +ofp_print_port_state(struct ds *string, enum ofputil_port_state state) { - static const struct bit_name state_bits[] = { - { OFPPS_LINK_DOWN, "LINK_DOWN" }, - { 0, NULL }, - }; - uint32_t stp_state; + enum ofputil_port_state stp_state; /* The STP state is a 2-bit field so it doesn't fit in with the bitmask * pattern. We have to special case it. @@ -526,25 +579,26 @@ ofp_print_port_state(struct ds *string, uint32_t state) * talking to OVS, so we'd always print STP_LISTEN in that case. * Therefore, we don't print anything at all if the value is STP_LISTEN, to * avoid confusing users. */ - stp_state = state & OFPPS_STP_MASK; + stp_state = state & OFPUTIL_PS_STP_MASK; if (stp_state) { - ds_put_cstr(string, (stp_state == OFPPS_STP_LEARN ? "STP_LEARN" - : stp_state == OFPPS_STP_FORWARD ? "STP_FORWARD" - : "STP_BLOCK")); - state &= ~OFPPS_STP_MASK; + ds_put_cstr(string, + (stp_state == OFPUTIL_PS_STP_LEARN ? "STP_LEARN" + : stp_state == OFPUTIL_PS_STP_FORWARD ? "STP_FORWARD" + : "STP_BLOCK")); + state &= ~OFPUTIL_PS_STP_MASK; if (state) { - ofp_print_bit_names(string, state, state_bits); + ofp_print_bit_names(string, state, ofputil_port_state_to_name); } } else { - ofp_print_bit_names(string, state, state_bits); + ofp_print_bit_names(string, state, ofputil_port_state_to_name); } ds_put_char(string, '\n'); } static void -ofp_print_phy_port(struct ds *string, const struct ofp_phy_port *port) +ofp_print_phy_port(struct ds *string, const struct ofputil_phy_port *port) { - char name[OFP_MAX_PORT_NAME_LEN]; + char name[sizeof port->name]; int j; memcpy(name, port->name, sizeof name); @@ -556,58 +610,141 @@ ofp_print_phy_port(struct ds *string, const struct ofp_phy_port *port) name[j] = '\0'; ds_put_char(string, ' '); - ofputil_format_port(ntohs(port->port_no), string); + ofputil_format_port(port->port_no, string); ds_put_format(string, "(%s): addr:"ETH_ADDR_FMT"\n", name, ETH_ADDR_ARGS(port->hw_addr)); ds_put_cstr(string, " config: "); - ofp_print_port_config(string, ntohl(port->config)); + ofp_print_port_config(string, port->config); ds_put_cstr(string, " state: "); - ofp_print_port_state(string, ntohl(port->state)); + ofp_print_port_state(string, port->state); if (port->curr) { ds_put_format(string, " current: "); - ofp_print_port_features(string, ntohl(port->curr)); + ofp_print_port_features(string, port->curr); } if (port->advertised) { ds_put_format(string, " advertised: "); - ofp_print_port_features(string, ntohl(port->advertised)); + ofp_print_port_features(string, port->advertised); } if (port->supported) { ds_put_format(string, " supported: "); - ofp_print_port_features(string, ntohl(port->supported)); + ofp_print_port_features(string, port->supported); } if (port->peer) { ds_put_format(string, " peer: "); - ofp_print_port_features(string, ntohl(port->peer)); + ofp_print_port_features(string, port->peer); } + ds_put_format(string, " speed: %"PRIu32" Mbps now, " + "%"PRIu32" Mbps max\n", + port->curr_speed / UINT32_C(1000), + port->max_speed / UINT32_C(1000)); +} + +static const char * +ofputil_capabilities_to_name(uint32_t bit) +{ + enum ofputil_capabilities capabilities = bit; + + switch (capabilities) { + case OFPUTIL_C_FLOW_STATS: return "FLOW_STATS"; + case OFPUTIL_C_TABLE_STATS: return "TABLE_STATS"; + case OFPUTIL_C_PORT_STATS: return "PORT_STATS"; + case OFPUTIL_C_IP_REASM: return "IP_REASM"; + case OFPUTIL_C_QUEUE_STATS: return "QUEUE_STATS"; + case OFPUTIL_C_ARP_MATCH_IP: return "ARP_MATCH_IP"; + case OFPUTIL_C_STP: return "STP"; + case OFPUTIL_C_GROUP_STATS: return "GROUP_STATS"; + } + + return NULL; +} + +static const char * +ofputil_action_bitmap_to_name(uint32_t bit) +{ + enum ofputil_action_bitmap action = bit; + + switch (action) { + case OFPUTIL_A_OUTPUT: return "OUTPUT"; + case OFPUTIL_A_SET_VLAN_VID: return "SET_VLAN_VID"; + case OFPUTIL_A_SET_VLAN_PCP: return "SET_VLAN_PCP"; + case OFPUTIL_A_STRIP_VLAN: return "STRIP_VLAN"; + case OFPUTIL_A_SET_DL_SRC: return "SET_DL_SRC"; + case OFPUTIL_A_SET_DL_DST: return "SET_DL_DST"; + case OFPUTIL_A_SET_NW_SRC: return "SET_NW_SRC"; + case OFPUTIL_A_SET_NW_DST: return "SET_NW_DST"; + case OFPUTIL_A_SET_NW_ECN: return "SET_NW_ECN"; + case OFPUTIL_A_SET_NW_TOS: return "SET_NW_TOS"; + case OFPUTIL_A_SET_TP_SRC: return "SET_TP_SRC"; + case OFPUTIL_A_SET_TP_DST: return "SET_TP_DST"; + case OFPUTIL_A_ENQUEUE: return "ENQUEUE"; + case OFPUTIL_A_COPY_TTL_OUT: return "COPY_TTL_OUT"; + case OFPUTIL_A_COPY_TTL_IN: return "COPY_TTL_IN"; + case OFPUTIL_A_SET_MPLS_LABEL: return "SET_MPLS_LABEL"; + case OFPUTIL_A_SET_MPLS_TC: return "SET_MPLS_TC"; + case OFPUTIL_A_SET_MPLS_TTL: return "SET_MPLS_TTL"; + case OFPUTIL_A_DEC_MPLS_TTL: return "DEC_MPLS_TTL"; + case OFPUTIL_A_PUSH_VLAN: return "PUSH_VLAN"; + case OFPUTIL_A_POP_VLAN: return "POP_VLAN"; + case OFPUTIL_A_PUSH_MPLS: return "PUSH_MPLS"; + case OFPUTIL_A_POP_MPLS: return "POP_MPLS"; + case OFPUTIL_A_SET_QUEUE: return "SET_QUEUE"; + case OFPUTIL_A_GROUP: return "GROUP"; + case OFPUTIL_A_SET_NW_TTL: return "SET_NW_TTL"; + case OFPUTIL_A_DEC_NW_TTL: return "DEC_NW_TTL"; + } + + return NULL; } static void ofp_print_switch_features(struct ds *string, const struct ofp_switch_features *osf) { - size_t len = ntohs(osf->header.length); - struct ofp_phy_port *port_list; - int n_ports; - int i; + struct ofputil_switch_features features; + struct ofputil_phy_port *ports; + enum ofperr error; + struct ofpbuf b; + size_t n_ports; + size_t i; + + error = ofputil_decode_switch_features(osf, &features, &b); + if (error) { + ofp_print_error(string, error); + return; + } + + ds_put_format(string, " dpid:%016"PRIx64"\n", features.datapath_id); + ds_put_format(string, "n_tables:%"PRIu8", n_buffers:%"PRIu32"\n", + features.n_tables, features.n_buffers); - ds_put_format(string, " ver:0x%x, dpid:%016"PRIx64"\n", - osf->header.version, ntohll(osf->datapath_id)); - ds_put_format(string, "n_tables:%d, n_buffers:%d\n", osf->n_tables, - ntohl(osf->n_buffers)); - ds_put_format(string, "features: capabilities:%#x, actions:%#x\n", - ntohl(osf->capabilities), ntohl(osf->actions)); + ds_put_cstr(string, "capabilities: "); + ofp_print_bit_names(string, features.capabilities, + ofputil_capabilities_to_name); + ds_put_char(string, '\n'); + + ds_put_cstr(string, "actions: "); + ofp_print_bit_names(string, features.actions, + ofputil_action_bitmap_to_name); + ds_put_char(string, '\n'); - n_ports = (len - sizeof *osf) / sizeof *osf->ports; + n_ports = ofputil_count_phy_ports(osf); - port_list = xmemdup(osf->ports, len - sizeof *osf); - qsort(port_list, n_ports, sizeof *port_list, compare_ports); + ports = xmalloc(n_ports * sizeof *ports); for (i = 0; i < n_ports; i++) { - ofp_print_phy_port(string, &port_list[i]); + error = ofputil_pull_switch_features_port(&b, &ports[i]); + if (error) { + ofp_print_error(string, error); + return; + } } - free(port_list); + qsort(ports, n_ports, sizeof *ports, compare_ports); + for (i = 0; i < n_ports; i++) { + ofp_print_phy_port(string, &ports[i]); + } + free(ports); } static void @@ -768,7 +905,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh, bool need_priority; enum ofperr error; - error = ofputil_decode_flow_mod(&fm, oh, true); + error = ofputil_decode_flow_mod(&fm, oh, OFPUTIL_P_OF10_TID); if (error) { ofp_print_error(s, error); return; @@ -922,14 +1059,29 @@ ofp_print_flow_removed(struct ds *string, const struct ofp_header *oh) } static void -ofp_print_port_mod(struct ds *string, const struct ofp_port_mod *opm) +ofp_print_port_mod(struct ds *string, const struct ofp_header *oh) { - ds_put_format(string, "port: %d: addr:"ETH_ADDR_FMT", config: %#x, mask:%#x\n", - ntohs(opm->port_no), ETH_ADDR_ARGS(opm->hw_addr), - ntohl(opm->config), ntohl(opm->mask)); + struct ofputil_port_mod pm; + enum ofperr error; + + error = ofputil_decode_port_mod(oh, &pm); + if (error) { + ofp_print_error(string, error); + return; + } + + ds_put_format(string, "port: %"PRIu16": addr:"ETH_ADDR_FMT"\n", + pm.port_no, ETH_ADDR_ARGS(pm.hw_addr)); + + ds_put_format(string, " config: "); + ofp_print_port_config(string, pm.config); + + ds_put_format(string, " mask: "); + ofp_print_port_config(string, pm.mask); + ds_put_format(string, " advertise: "); - if (opm->advertise) { - ofp_print_port_features(string, ntohl(opm->advertise)); + if (pm.advertise) { + ofp_print_port_features(string, pm.advertise); } else { ds_put_format(string, "UNCHANGED\n"); } @@ -976,15 +1128,24 @@ ofp_print_error_msg(struct ds *string, const struct ofp_error_msg *oem) static void ofp_print_port_status(struct ds *string, const struct ofp_port_status *ops) { - if (ops->reason == OFPPR_ADD) { + struct ofputil_port_status ps; + enum ofperr error; + + error = ofputil_decode_port_status(ops, &ps); + if (error) { + ofp_print_error(string, error); + return; + } + + if (ps.reason == OFPPR_ADD) { ds_put_format(string, " ADD:"); - } else if (ops->reason == OFPPR_DELETE) { + } else if (ps.reason == OFPPR_DELETE) { ds_put_format(string, " DEL:"); - } else if (ops->reason == OFPPR_MODIFY) { + } else if (ps.reason == OFPPR_MODIFY) { ds_put_format(string, " MOD:"); } - ofp_print_phy_port(string, &ops->desc); + ofp_print_phy_port(string, &ps.desc); } static void @@ -1303,8 +1464,8 @@ ofp_print_nxt_set_flow_format(struct ds *string, uint32_t format = ntohl(nsff->format); ds_put_cstr(string, " format="); - if (ofputil_flow_format_is_valid(format)) { - ds_put_cstr(string, ofputil_flow_format_to_string(format)); + if (ofputil_nx_flow_format_is_valid(format)) { + ds_put_cstr(string, ofputil_nx_flow_format_to_string(format)); } else { ds_put_format(string, "%"PRIu32, format); } @@ -1360,7 +1521,7 @@ ofp_print_nxt_set_async_config(struct ds *string, for (j = 0; j < 32; j++) { if (nac->packet_in_mask[i] & htonl(1u << j)) { ds_put_format(string, " %s", - ofp_packet_in_reason_to_string(j)); + ofputil_packet_in_reason_to_string(j)); } } if (!nac->packet_in_mask[i]) { @@ -1393,6 +1554,13 @@ ofp_print_nxt_set_async_config(struct ds *string, } } +static void +ofp_print_nxt_set_controller_id(struct ds *string, + const struct nx_controller_id *nci) +{ + ds_put_format(string, " id=%"PRIu16, ntohs(nci->controller_id)); +} + static void ofp_to_string__(const struct ofp_header *oh, const struct ofputil_msg_type *type, struct ds *string, @@ -1401,8 +1569,18 @@ ofp_to_string__(const struct ofp_header *oh, enum ofputil_msg_code code; const void *msg = oh; - ds_put_format(string, "%s (xid=0x%"PRIx32"):", - ofputil_msg_type_name(type), ntohl(oh->xid)); + ds_put_cstr(string, ofputil_msg_type_name(type)); + switch (oh->version) { + case OFP10_VERSION: + break; + case OFP11_VERSION: + ds_put_cstr(string, " (OF1.1)"); + break; + default: + ds_put_format(string, " (OF 0x%02"PRIx8")", oh->version); + break; + } + ds_put_format(string, " (xid=0x%"PRIx32"):", ntohl(oh->xid)); code = ofputil_msg_type_code(type); switch (code) { @@ -1552,6 +1730,10 @@ ofp_to_string__(const struct ofp_header *oh, case OFPUTIL_NXT_FLOW_AGE: break; + case OFPUTIL_NXT_SET_CONTROLLER_ID: + ofp_print_nxt_set_controller_id(string, msg); + break; + case OFPUTIL_NXT_SET_ASYNC_CONFIG: ofp_print_nxt_set_async_config(string, msg); break; @@ -1610,91 +1792,6 @@ ofp_to_string(const void *oh_, size_t len, int verbosity) ds_put_hex_dump(&string, oh, len, 0, true); return ds_steal_cstr(&string); } - -/* Returns the name for the specified OpenFlow message type as a string, - * e.g. "OFPT_FEATURES_REPLY". If no name is known, the string returned is a - * hex number, e.g. "0x55". - * - * The caller must free the returned string when it is no longer needed. */ -char * -ofp_message_type_to_string(uint8_t type) -{ - const char *name; - - switch (type) { - case OFPT_HELLO: - name = "HELLO"; - break; - case OFPT_ERROR: - name = "ERROR"; - break; - case OFPT_ECHO_REQUEST: - name = "ECHO_REQUEST"; - break; - case OFPT_ECHO_REPLY: - name = "ECHO_REPLY"; - break; - case OFPT_VENDOR: - name = "VENDOR"; - break; - case OFPT_FEATURES_REQUEST: - name = "FEATURES_REQUEST"; - break; - case OFPT_FEATURES_REPLY: - name = "FEATURES_REPLY"; - break; - case OFPT_GET_CONFIG_REQUEST: - name = "GET_CONFIG_REQUEST"; - break; - case OFPT_GET_CONFIG_REPLY: - name = "GET_CONFIG_REPLY"; - break; - case OFPT_SET_CONFIG: - name = "SET_CONFIG"; - break; - case OFPT_PACKET_IN: - name = "PACKET_IN"; - break; - case OFPT_FLOW_REMOVED: - name = "FLOW_REMOVED"; - break; - case OFPT_PORT_STATUS: - name = "PORT_STATUS"; - break; - case OFPT_PACKET_OUT: - name = "PACKET_OUT"; - break; - case OFPT_FLOW_MOD: - name = "FLOW_MOD"; - break; - case OFPT_PORT_MOD: - name = "PORT_MOD"; - break; - case OFPT_STATS_REQUEST: - name = "STATS_REQUEST"; - break; - case OFPT_STATS_REPLY: - name = "STATS_REPLY"; - break; - case OFPT_BARRIER_REQUEST: - name = "BARRIER_REQUEST"; - break; - case OFPT_BARRIER_REPLY: - name = "BARRIER_REPLY"; - break; - case OFPT_QUEUE_GET_CONFIG_REQUEST: - name = "QUEUE_GET_CONFIG_REQUEST"; - break; - case OFPT_QUEUE_GET_CONFIG_REPLY: - name = "QUEUE_GET_CONFIG_REPLY"; - break; - default: - name = NULL; - break; - } - - return name ? xasprintf("OFPT_%s", name) : xasprintf("0x%02"PRIx8, type); -} static void print_and_free(FILE *stream, char *string)