ovs-ofctl: Use vconn as a parameter of dump_stats_transaction()
[sliver-openvswitch.git] / utilities / ovs-ofctl.c
index 61d0266..5d10b37 100644 (file)
@@ -424,7 +424,7 @@ dump_trivial_transaction(const char *vconn_name, enum ofpraw raw)
 }
 
 static void
-dump_stats_transaction__(struct vconn *vconn, struct ofpbuf *request)
+dump_stats_transaction(struct vconn *vconn, struct ofpbuf *request)
 {
     const struct ofp_header *request_oh = request->data;
     ovs_be32 send_xid = request_oh->xid;
@@ -467,24 +467,17 @@ dump_stats_transaction__(struct vconn *vconn, struct ofpbuf *request)
 }
 
 static void
-dump_stats_transaction(const char *vconn_name, struct ofpbuf *request)
+dump_trivial_stats_transaction(const char *vconn_name, enum ofpraw raw)
 {
+    struct ofpbuf *request;
     struct vconn *vconn;
 
     open_vconn(vconn_name, &vconn);
-    dump_stats_transaction__(vconn, request);
+    request = ofpraw_alloc(raw, vconn_get_version(vconn), 0);
+    dump_stats_transaction(vconn, request);
     vconn_close(vconn);
 }
 
-static void
-dump_trivial_stats_transaction(const char *vconn_name, enum ofpraw raw)
-{
-    struct ofpbuf *request;
-
-    request = ofpraw_alloc(raw, OFP10_VERSION, 0);
-    dump_stats_transaction(vconn_name, request);
-}
-
 /* Sends 'request', which should be a request that only has a reply if an error
  * occurs, and waits for it to succeed or fail.  If an error does occur, prints
  * it and exits with an error.
@@ -839,7 +832,7 @@ ofctl_dump_flows__(int argc, char *argv[], bool aggregate)
     struct vconn *vconn;
 
     vconn = prepare_dump_flows(argc, argv, aggregate, &request);
-    dump_stats_transaction__(vconn, request);
+    dump_stats_transaction(vconn, request);
     vconn_close(vconn);
 }
 
@@ -956,8 +949,11 @@ ofctl_queue_stats(int argc, char *argv[])
 {
     struct ofp10_queue_stats_request *req;
     struct ofpbuf *request;
+    struct vconn *vconn;
 
-    request = ofpraw_alloc(OFPRAW_OFPST_QUEUE_REQUEST, OFP10_VERSION, 0);
+    open_vconn(argv[1], &vconn);
+    request = ofpraw_alloc(OFPRAW_OFPST_QUEUE_REQUEST,
+                           vconn_get_version(vconn), 0);
     req = ofpbuf_put_zeros(request, sizeof *req);
 
     if (argc > 2 && argv[2][0] && strcasecmp(argv[2], "all")) {
@@ -973,7 +969,8 @@ ofctl_queue_stats(int argc, char *argv[])
 
     memset(req->pad, 0, sizeof req->pad);
 
-    dump_stats_transaction(argv[1], request);
+    dump_stats_transaction(vconn, request);
+    vconn_close(vconn);
 }
 
 static enum ofputil_protocol
@@ -1217,7 +1214,7 @@ ofctl_barrier(struct unixctl_conn *conn, int argc OVS_UNUSED,
         return;
     }
 
-    msg = ofputil_encode_barrier_request();
+    msg = ofputil_encode_barrier_request(vconn_get_version(aux->vconn));
     error = vconn_send_block(aux->vconn, msg);
     if (error) {
         ofpbuf_delete(msg);
@@ -1377,7 +1374,7 @@ ofctl_monitor(int argc, char *argv[])
 
             msg = ofpbuf_new(0);
             ofputil_append_flow_monitor_request(&fmr, msg);
-            dump_stats_transaction__(vconn, msg);
+            dump_stats_transaction(vconn, msg);
         } else {
             ovs_fatal(0, "%s: unsupported \"monitor\" argument", arg);
         }
@@ -1418,13 +1415,17 @@ ofctl_dump_ports(int argc, char *argv[])
 {
     struct ofp10_port_stats_request *req;
     struct ofpbuf *request;
+    struct vconn *vconn;
     uint16_t port;
 
-    request = ofpraw_alloc(OFPRAW_OFPST_PORT_REQUEST, OFP10_VERSION, 0);
+    open_vconn(argv[1], &vconn);
+    request = ofpraw_alloc(OFPRAW_OFPST_PORT_REQUEST,
+                           vconn_get_version(vconn), 0);
     req = ofpbuf_put_zeros(request, sizeof *req);
     port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_NONE;
     req->port_no = htons(port);
-    dump_stats_transaction(argv[1], request);
+    dump_stats_transaction(vconn, request);
+    vconn_close(vconn);
 }
 
 static void
@@ -1440,8 +1441,8 @@ ofctl_probe(int argc OVS_UNUSED, char *argv[])
     struct vconn *vconn;
     struct ofpbuf *reply;
 
-    request = make_echo_request();
     open_vconn(argv[1], &vconn);
+    request = make_echo_request(vconn_get_version(vconn));
     run(vconn_transact(vconn, request, &reply), "talking to %s", argv[1]);
     if (reply->size != sizeof(struct ofp_header)) {
         ovs_fatal(0, "reply does not match request");
@@ -1453,6 +1454,7 @@ ofctl_probe(int argc OVS_UNUSED, char *argv[])
 static void
 ofctl_packet_out(int argc, char *argv[])
 {
+    enum ofputil_protocol protocol;
     struct ofputil_packet_out po;
     struct ofpbuf ofpacts;
     struct vconn *vconn;
@@ -1468,7 +1470,7 @@ ofctl_packet_out(int argc, char *argv[])
     po.ofpacts = ofpacts.data;
     po.ofpacts_len = ofpacts.size;
 
-    open_vconn(argv[1], &vconn);
+    protocol = open_vconn(argv[1], &vconn);
     for (i = 4; i < argc; i++) {
         struct ofpbuf *packet, *opo;
         const char *error_msg;
@@ -1480,7 +1482,7 @@ ofctl_packet_out(int argc, char *argv[])
 
         po.packet = packet->data;
         po.packet_len = packet->size;
-        opo = ofputil_encode_packet_out(&po);
+        opo = ofputil_encode_packet_out(&po, protocol);
         transact_noreply(vconn, opo);
         ofpbuf_delete(packet);
     }
@@ -2334,20 +2336,50 @@ ofctl_parse_ofp10_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 /* "parse-ofp10-match": reads a series of ofp10_match specifications as hex
  * bytes from stdin, converts them to cls_rules, prints them as strings on
  * stdout, and then converts them back to hex bytes and prints any differences
- * from the input. */
+ * from the input.
+ *
+ * The input hex bytes may contain "x"s to represent "don't-cares", bytes whose
+ * values are ignored in the input and will be set to zero when OVS converts
+ * them back to hex bytes.  ovs-ofctl actually sets "x"s to random bits when
+ * it does the conversion to hex, to ensure that in fact they are ignored. */
 static void
 ofctl_parse_ofp10_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
+    struct ds expout;
     struct ds in;
 
     ds_init(&in);
+    ds_init(&expout);
     while (!ds_get_preprocessed_line(&in, stdin)) {
-        struct ofpbuf match_in;
+        struct ofpbuf match_in, match_expout;
         struct ofp10_match match_out;
         struct ofp10_match match_normal;
         struct cls_rule rule;
+        char *p;
+
+        /* Parse hex bytes to use for expected output. */
+        ds_clear(&expout);
+        ds_put_cstr(&expout, ds_cstr(&in));
+        for (p = ds_cstr(&expout); *p; p++) {
+            if (*p == 'x') {
+                *p = '0';
+            }
+        }
+        ofpbuf_init(&match_expout, 0);
+        if (ofpbuf_put_hex(&match_expout, ds_cstr(&expout), NULL)[0] != '\0') {
+            ovs_fatal(0, "Trailing garbage in hex data");
+        }
+        if (match_expout.size != sizeof(struct ofp10_match)) {
+            ovs_fatal(0, "Input is %zu bytes, expected %zu",
+                      match_expout.size, sizeof(struct ofp10_match));
+        }
 
-        /* Parse hex bytes. */
+        /* Parse hex bytes for input. */
+        for (p = ds_cstr(&in); *p; p++) {
+            if (*p == 'x') {
+                *p = "0123456789abcdef"[random_uint32() & 0xf];
+            }
+        }
         ofpbuf_init(&match_in, 0);
         if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
             ovs_fatal(0, "Trailing garbage in hex data");
@@ -2364,7 +2396,7 @@ ofctl_parse_ofp10_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 
         /* Convert back to ofp10_match and print differences from input. */
         ofputil_cls_rule_to_ofp10_match(&rule, &match_out);
-        print_differences("", match_in.data, match_in.size,
+        print_differences("", match_expout.data, match_expout.size,
                           &match_out, sizeof match_out);
 
         /* Normalize, then convert and compare again. */
@@ -2375,8 +2407,10 @@ ofctl_parse_ofp10_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         putchar('\n');
 
         ofpbuf_uninit(&match_in);
+        ofpbuf_uninit(&match_expout);
     }
     ds_destroy(&in);
+    ds_destroy(&expout);
 }
 
 /* "parse-ofp11-match": reads a series of ofp11_match specifications as hex
@@ -2582,6 +2616,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[])
     printf("%04"PRIx16"/%04"PRIx16"\n",
            ntohs(fm.cr.flow.vlan_tci),
            ntohs(fm.cr.wc.vlan_tci_mask));
+    free(string_s);
 
     /* Convert to and from NXM. */
     ofpbuf_init(&nxm, 0);
@@ -2660,17 +2695,14 @@ ofctl_print_error(int argc OVS_UNUSED, char *argv[])
     }
 
     for (version = 0; version <= UINT8_MAX; version++) {
-        const struct ofperr_domain *domain;
-
-        domain = ofperr_domain_from_version(version);
-        if (!domain) {
+        const char *name = ofperr_domain_get_name(version);
+        if (!name) {
             continue;
         }
-
         printf("%s: %d,%d\n",
-               ofperr_domain_get_name(domain),
-               ofperr_get_type(error, domain),
-               ofperr_get_code(error, domain));
+               ofperr_domain_get_name(version),
+               ofperr_get_type(error, version),
+               ofperr_get_code(error, version));
     }
 }