" dump-desc SWITCH print switch description\n"
" dump-tables SWITCH print table stats\n"
" mod-port SWITCH IFACE ACT modify port behavior\n"
- " dump-ports SWITCH print port statistics\n"
+ " dump-ports SWITCH [PORT] print port statistics\n"
" dump-flows SWITCH print all flow entries\n"
" dump-flows SWITCH FLOW print matching FLOWs\n"
" dump-aggregate SWITCH print aggregate flow statistics\n"
return n_wild;
}
+static uint16_t
+str_to_port_no(const char *vconn_name, const char *str)
+{
+ struct ofpbuf *request, *reply;
+ struct ofp_switch_features *osf;
+ struct vconn *vconn;
+ int n_ports;
+ int port_idx;
+ unsigned int port_no;
+
+
+ /* Check if the argument is a port index. Otherwise, treat it as
+ * the port name. */
+ if (str_to_uint(str, 10, &port_no)) {
+ return port_no;
+ }
+
+ /* Send a "Features Request" to resolve the name into a number. */
+ make_openflow(sizeof(struct ofp_header), OFPT_FEATURES_REQUEST, &request);
+ open_vconn(vconn_name, &vconn);
+ run(vconn_transact(vconn, request, &reply), "talking to %s", vconn_name);
+
+ osf = reply->data;
+ n_ports = (reply->size - sizeof *osf) / sizeof *osf->ports;
+
+ for (port_idx = 0; port_idx < n_ports; port_idx++) {
+ /* Check argument as an interface name */
+ if (!strncmp((char *)osf->ports[port_idx].name, str,
+ sizeof osf->ports[0].name)) {
+ break;
+ }
+ }
+ if (port_idx == n_ports) {
+ ovs_fatal(0, "couldn't find monitored port: %s", str);
+ }
+
+ ofpbuf_delete(reply);
+ vconn_close(vconn);
+
+ return port_idx;
+}
+
static void *
put_action(struct ofpbuf *b, size_t size, uint16_t type)
{
/* Unless a numeric argument is specified, we send the whole
* packet to the controller. */
- if (arg && (strspn(act, "0123456789") == strlen(act))) {
+ if (arg && (strspn(arg, "0123456789") == strlen(arg))) {
oao->max_len = htons(str_to_u32(arg));
} else {
oao->max_len = htons(UINT16_MAX);
{ "nw_dst", OFPFW_NW_DST_MASK, F_IP,
F_OFS(nw_dst), OFPFW_NW_DST_SHIFT },
{ "nw_proto", OFPFW_NW_PROTO, F_U8, F_OFS(nw_proto), 0 },
+ { "nw_tos", OFPFW_NW_TOS, F_U8, F_OFS(nw_tos), 0 },
{ "tp_src", OFPFW_TP_SRC, F_U16, F_OFS(tp_src), 0 },
{ "tp_dst", OFPFW_TP_DST, F_U16, F_OFS(tp_dst), 0 },
{ "icmp_type", OFPFW_ICMP_TYPE, F_U16, F_OFS(icmp_type), 0 },
}
static void
-do_dump_ports(int argc OVS_UNUSED, char *argv[])
+do_dump_ports(int argc, char *argv[])
{
- dump_trivial_stats_transaction(argv[1], OFPST_PORT);
+ struct ofp_port_stats_request *req;
+ struct ofpbuf *request;
+ uint16_t port;
+
+ req = alloc_stats_request(sizeof *req, OFPST_PORT, &request);
+ port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_NONE;
+ req->port_no = htons(port);
+ dump_stats_transaction(argv[1], request);
}
static void
{ "add-flows", 2, 2, do_add_flows },
{ "mod-flows", 2, 2, do_mod_flows },
{ "del-flows", 1, 2, do_del_flows },
- { "dump-ports", 1, 1, do_dump_ports },
+ { "dump-ports", 1, 2, do_dump_ports },
{ "mod-port", 3, 3, do_mod_port },
{ "probe", 1, 1, do_probe },
{ "ping", 1, 2, do_ping },