bridge: Fix high cpu utilization.
[cascardo/ovs.git] / utilities / ovs-ofctl.c
index 3b78ca5..01b3f60 100644 (file)
@@ -91,6 +91,10 @@ static int verbosity;
  * "snoop" command? */
 static bool timestamp;
 
+/* --unixctl-path: Path to use for unixctl server, for "monitor" and "snoop"
+     commands. */
+static char *unixctl_path;
+
 /* --sort, --rsort: Sort order. */
 enum sort_order { SORT_ASC, SORT_DESC };
 struct sort_criterion {
@@ -149,6 +153,7 @@ parse_options(int argc, char *argv[])
         OPT_TIMESTAMP,
         OPT_SORT,
         OPT_RSORT,
+        OPT_UNIXCTL,
         DAEMON_OPTION_ENUMS,
         OFP_VERSION_OPTION_ENUMS,
         VLOG_OPTION_ENUMS
@@ -163,6 +168,7 @@ parse_options(int argc, char *argv[])
         {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
         {"sort", optional_argument, NULL, OPT_SORT},
         {"rsort", optional_argument, NULL, OPT_RSORT},
+        {"unixctl",     required_argument, NULL, OPT_UNIXCTL},
         {"help", no_argument, NULL, 'h'},
         DAEMON_LONG_OPTIONS,
         OFP_VERSION_LONG_OPTIONS,
@@ -253,6 +259,10 @@ parse_options(int argc, char *argv[])
             add_sort_criterion(SORT_DESC, optarg);
             break;
 
+        case OPT_UNIXCTL:
+            unixctl_path = optarg;
+            break;
+
         DAEMON_OPTION_HANDLERS
         OFP_VERSION_OPTION_HANDLERS
         VLOG_OPTION_HANDLERS
@@ -305,7 +315,7 @@ usage(void)
            "  get-frags SWITCH            print fragment handling behavior\n"
            "  set-frags SWITCH FRAG_MODE  set fragment handling behavior\n"
            "  dump-ports SWITCH [PORT]    print port statistics\n"
-           "  dump-ports-desc SWITCH      print port descriptions\n"
+           "  dump-ports-desc SWITCH [PORT]  print port descriptions\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"
@@ -361,6 +371,7 @@ usage(void)
            "  -t, --timeout=SECS          give up after SECS seconds\n"
            "  --sort[=field]              sort in ascending order\n"
            "  --rsort[=field]             sort in descending order\n"
+           "  --unixctl=SOCKET            set control socket name\n"
            "  -h, --help                  display this help message\n"
            "  -V, --version               display version information\n");
     exit(EXIT_SUCCESS);
@@ -648,7 +659,7 @@ ofctl_show(int argc OVS_UNUSED, char *argv[])
     ofpbuf_delete(reply);
 
     if (!has_ports) {
-        request = ofpraw_alloc(OFPRAW_OFPST_PORT_DESC_REQUEST, version, 0);
+        request = ofputil_encode_port_desc_stats_request(version, OFPP_ANY);
         dump_stats_transaction(vconn, request);
     }
     dump_trivial_transaction(vconn_name, OFPRAW_OFPT_GET_CONFIG_REQUEST);
@@ -761,8 +772,8 @@ fetch_port_by_stats(struct vconn *vconn,
     bool done = false;
     bool found = false;
 
-    request = ofpraw_alloc(OFPRAW_OFPST_PORT_DESC_REQUEST,
-                           vconn_get_version(vconn), 0);
+    request = ofputil_encode_port_desc_stats_request(vconn_get_version(vconn),
+                                                     port_no);
     send_xid = ((struct ofp_header *) ofpbuf_data(request))->xid;
 
     send_openflow_buffer(vconn, request);
@@ -1437,7 +1448,7 @@ monitor_vconn(struct vconn *vconn, bool reply_to_echo_requests)
 
     daemon_save_fd(STDERR_FILENO);
     daemonize_start();
-    error = unixctl_server_create(NULL, &server);
+    error = unixctl_server_create(unixctl_path, &server);
     if (error) {
         ovs_fatal(error, "failed to create unixctl server");
     }
@@ -1620,7 +1631,16 @@ ofctl_dump_ports(int argc, char *argv[])
 static void
 ofctl_dump_ports_desc(int argc OVS_UNUSED, char *argv[])
 {
-    dump_trivial_stats_transaction(argv[1], OFPRAW_OFPST_PORT_DESC_REQUEST);
+    struct ofpbuf *request;
+    struct vconn *vconn;
+    ofp_port_t port;
+
+    open_vconn(argv[1], &vconn);
+    port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_ANY;
+    request = ofputil_encode_port_desc_stats_request(vconn_get_version(vconn),
+                                                     port);
+    dump_stats_transaction(vconn, request);
+    vconn_close(vconn);
 }
 
 static void
@@ -2814,7 +2834,7 @@ ofctl_parse_flows(int argc OVS_UNUSED, char *argv[])
 }
 
 static void
-ofctl_parse_nxm__(bool oxm)
+ofctl_parse_nxm__(bool oxm, enum ofp_version version)
 {
     struct ds in;
 
@@ -2859,7 +2879,7 @@ ofctl_parse_nxm__(bool oxm)
             ofpbuf_uninit(&nx_match);
             ofpbuf_init(&nx_match, 0);
             if (oxm) {
-                match_len = oxm_put_match(&nx_match, &match);
+                match_len = oxm_put_match(&nx_match, &match, version);
                 out = oxm_match_to_string(&nx_match, match_len);
             } else {
                 match_len = nx_put_match(&nx_match, &match,
@@ -2885,16 +2905,22 @@ ofctl_parse_nxm__(bool oxm)
 static void
 ofctl_parse_nxm(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
-    return ofctl_parse_nxm__(false);
+    return ofctl_parse_nxm__(false, 0);
 }
 
-/* "parse-oxm": reads a series of OXM nx_match specifications as strings from
- * stdin, does some internal fussing with them, and then prints them back as
- * strings on stdout. */
+/* "parse-oxm VERSION": reads a series of OXM nx_match specifications as
+ * strings from stdin, does some internal fussing with them, and then prints
+ * them back as strings on stdout.  VERSION must specify an OpenFlow version,
+ * e.g. "OpenFlow12". */
 static void
-ofctl_parse_oxm(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
+ofctl_parse_oxm(int argc OVS_UNUSED, char *argv[])
 {
-    return ofctl_parse_nxm__(true);
+    enum ofp_version version = ofputil_version_from_string(argv[1]);
+    if (version < OFP12_VERSION) {
+        ovs_fatal(0, "%s: not a valid version for OXM", argv[1]);
+    }
+
+    return ofctl_parse_nxm__(true, version);
 }
 
 static void
@@ -3340,7 +3366,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[])
 
     /* Convert to and from OXM. */
     ofpbuf_init(&nxm, 0);
-    nxm_match_len = oxm_put_match(&nxm, &match);
+    nxm_match_len = oxm_put_match(&nxm, &match, OFP12_VERSION);
     nxm_s = oxm_match_to_string(&nxm, nxm_match_len);
     error = oxm_pull_match(&nxm, &nxm_match);
     printf("OXM: %s -> ", nxm_s);
@@ -3504,7 +3530,7 @@ static const struct command all_commands[] = {
     { "meter-features", 1, 1, ofctl_meter_features },
     { "packet-out", 4, INT_MAX, ofctl_packet_out },
     { "dump-ports", 1, 2, ofctl_dump_ports },
-    { "dump-ports-desc", 1, 1, ofctl_dump_ports_desc },
+    { "dump-ports-desc", 1, 2, ofctl_dump_ports_desc },
     { "mod-port", 3, 3, ofctl_mod_port },
     { "mod-table", 3, 3, ofctl_mod_table },
     { "get-frags", 1, 1, ofctl_get_frags },
@@ -3530,7 +3556,7 @@ static const struct command all_commands[] = {
     { "parse-flows", 1, 1, ofctl_parse_flows },
     { "parse-nx-match", 0, 0, ofctl_parse_nxm },
     { "parse-nxm", 0, 0, ofctl_parse_nxm },
-    { "parse-oxm", 0, 0, ofctl_parse_oxm },
+    { "parse-oxm", 1, 1, ofctl_parse_oxm },
     { "parse-ofp10-actions", 0, 0, ofctl_parse_ofp10_actions },
     { "parse-ofp10-match", 0, 0, ofctl_parse_ofp10_match },
     { "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match },