Merge 'master' into 'next'.
[sliver-openvswitch.git] / utilities / ovs-ofctl.c
index 81ce1f7..5fa11db 100644 (file)
@@ -32,7 +32,6 @@
 #include "command-line.h"
 #include "compiler.h"
 #include "dirs.h"
-#include "dpif.h"
 #include "dynamic-string.h"
 #include "netlink.h"
 #include "nx-match.h"
@@ -41,6 +40,7 @@
 #include "ofp-print.h"
 #include "ofp-util.h"
 #include "ofpbuf.h"
+#include "ofproto/ofproto.h"
 #include "openflow/nicira-ext.h"
 #include "openflow/openflow.h"
 #include "random.h"
@@ -92,7 +92,7 @@ parse_options(int argc, char *argv[])
         {"help", no_argument, 0, 'h'},
         {"version", no_argument, 0, 'V'},
         VLOG_LONG_OPTIONS,
-        STREAM_SSL_LONG_OPTIONS
+        STREAM_SSL_LONG_OPTIONS,
         {0, 0, 0, 0},
     };
     char *short_options = long_options_to_short_options(long_options);
@@ -199,17 +199,8 @@ static void run(int retval, const char *message, ...)
     if (retval) {
         va_list args;
 
-        fprintf(stderr, "%s: ", program_name);
         va_start(args, message);
-        vfprintf(stderr, message, args);
-        va_end(args);
-        if (retval == EOF) {
-            fputs(": unexpected end of file\n", stderr);
-        } else {
-            fprintf(stderr, ": %s\n", strerror(retval));
-        }
-
-        exit(EXIT_FAILURE);
+        ovs_fatal_valist(retval, message, args);
     }
 }
 \f
@@ -229,12 +220,17 @@ static void
 open_vconn__(const char *name, const char *default_suffix,
              struct vconn **vconnp)
 {
-    struct dpif *dpif;
+    char *datapath_name, *datapath_type, *socket_name;
+    char *bridge_path;
     struct stat s;
-    char *bridge_path, *datapath_name, *datapath_type;
 
     bridge_path = xasprintf("%s/%s.%s", ovs_rundir(), name, default_suffix);
-    dp_parse_name(name, &datapath_name, &datapath_type);
+
+    ofproto_parse_name(name, &datapath_name, &datapath_type);
+    socket_name = xasprintf("%s/%s.%s",
+                            ovs_rundir(), datapath_name, default_suffix);
+    free(datapath_name);
+    free(datapath_type);
 
     if (strstr(name, ":")) {
         run(vconn_open_block(name, OFP_VERSION, vconnp),
@@ -243,36 +239,18 @@ open_vconn__(const char *name, const char *default_suffix,
         open_vconn_socket(name, vconnp);
     } else if (!stat(bridge_path, &s) && S_ISSOCK(s.st_mode)) {
         open_vconn_socket(bridge_path, vconnp);
-    } else if (!dpif_open(datapath_name, datapath_type, &dpif)) {
-        char dpif_name[IF_NAMESIZE + 1];
-        char *socket_name;
-
-        run(dpif_port_get_name(dpif, ODPP_LOCAL, dpif_name, sizeof dpif_name),
-            "obtaining name of %s", dpif_name);
-        dpif_close(dpif);
-        if (strcmp(dpif_name, name)) {
-            VLOG_DBG("datapath %s is named %s", name, dpif_name);
-        }
-
-        socket_name = xasprintf("%s/%s.%s",
-                                ovs_rundir(), dpif_name, default_suffix);
-        if (stat(socket_name, &s)) {
-            ovs_fatal(errno, "cannot connect to %s: stat failed on %s",
-                      name, socket_name);
-        } else if (!S_ISSOCK(s.st_mode)) {
+    } else if (!stat(socket_name, &s)) {
+        if (!S_ISSOCK(s.st_mode)) {
             ovs_fatal(0, "cannot connect to %s: %s is not a socket",
                       name, socket_name);
         }
-
         open_vconn_socket(socket_name, vconnp);
-        free(socket_name);
     } else {
         ovs_fatal(0, "%s is not a valid connection method", name);
     }
 
-    free(datapath_name);
-    free(datapath_type);
     free(bridge_path);
+    free(socket_name);
 }
 
 static void
@@ -524,8 +502,6 @@ negotiate_highest_flow_format(struct vconn *vconn,
 
         if (try_set_flow_format(vconn, NXFF_NXM)) {
             flow_format = NXFF_NXM;
-        } else if (try_set_flow_format(vconn, NXFF_TUN_ID_FROM_COOKIE)) {
-            flow_format = NXFF_TUN_ID_FROM_COOKIE;
         } else {
             flow_format = NXFF_OPENFLOW10;
         }
@@ -553,7 +529,7 @@ do_dump_flows__(int argc, char *argv[], bool aggregate)
     parse_ofp_flow_stats_request_str(&fsr, aggregate, argc > 2 ? argv[2] : "");
 
     open_vconn(argv[1], &vconn);
-    min_flow_format = ofputil_min_flow_format(&fsr.match, false, 0);
+    min_flow_format = ofputil_min_flow_format(&fsr.match);
     flow_format = negotiate_highest_flow_format(vconn, min_flow_format);
     request = ofputil_encode_flow_stats_request(&fsr, flow_format);
     dump_stats_transaction(argv[1], request);
@@ -637,6 +613,7 @@ static void
 do_flow_mod_file__(int argc OVS_UNUSED, char *argv[], uint16_t command)
 {
     enum nx_flow_format flow_format;
+    bool flow_mod_table_id;
     struct list requests;
     struct vconn *vconn;
     FILE *file;
@@ -648,9 +625,11 @@ do_flow_mod_file__(int argc OVS_UNUSED, char *argv[], uint16_t command)
 
     list_init(&requests);
     flow_format = set_initial_format_for_flow_mod(&requests);
+    flow_mod_table_id = false;
 
     open_vconn(argv[1], &vconn);
-    while (parse_ofp_flow_mod_file(&requests, &flow_format, file, command)) {
+    while (parse_ofp_flow_mod_file(&requests, &flow_format, &flow_mod_table_id,
+                                   file, command)) {
         check_final_format_for_flow_mod(flow_format);
         transact_multiple_noreply(vconn, &requests);
     }
@@ -665,6 +644,7 @@ static void
 do_flow_mod__(int argc, char *argv[], uint16_t command)
 {
     enum nx_flow_format flow_format;
+    bool flow_mod_table_id;
     struct list requests;
     struct vconn *vconn;
 
@@ -675,9 +655,10 @@ do_flow_mod__(int argc, char *argv[], uint16_t command)
 
     list_init(&requests);
     flow_format = set_initial_format_for_flow_mod(&requests);
+    flow_mod_table_id = false;
 
-    parse_ofp_flow_mod_str(&requests, &flow_format, argc > 2 ? argv[2] : "",
-                           command);
+    parse_ofp_flow_mod_str(&requests, &flow_format, &flow_mod_table_id,
+                           argc > 2 ? argv[2] : "", command);
     check_final_format_for_flow_mod(flow_format);
 
     open_vconn(argv[1], &vconn);
@@ -836,9 +817,9 @@ do_ping(int argc, char *argv[])
                                OFPT_ECHO_REQUEST, &request);
         random_bytes(rq_hdr + 1, payload);
 
-        gettimeofday(&start, NULL);
+        xgettimeofday(&start);
         run(vconn_transact(vconn, ofpbuf_clone(request), &reply), "transact");
-        gettimeofday(&end, NULL);
+        xgettimeofday(&end);
 
         rpy_hdr = reply->data;
         if (reply->size != request->size
@@ -883,7 +864,7 @@ do_benchmark(int argc OVS_UNUSED, char *argv[])
            count, message_size, count * message_size);
 
     open_vconn(argv[1], &vconn);
-    gettimeofday(&start, NULL);
+    xgettimeofday(&start);
     for (i = 0; i < count; i++) {
         struct ofpbuf *request, *reply;
         struct ofp_header *rq_hdr;
@@ -893,7 +874,7 @@ do_benchmark(int argc OVS_UNUSED, char *argv[])
         run(vconn_transact(vconn, request, &reply), "transact");
         ofpbuf_delete(reply);
     }
-    gettimeofday(&end, NULL);
+    xgettimeofday(&end);
     vconn_close(vconn);
 
     duration = ((1000*(double)(end.tv_sec - start.tv_sec))
@@ -1022,7 +1003,7 @@ fte_insert(struct classifier *cls, const struct cls_rule *rule,
     fte->rule = *rule;
     fte->versions[index] = version;
 
-    old = fte_from_cls_rule(classifier_insert(cls, &fte->rule));
+    old = fte_from_cls_rule(classifier_replace(cls, &fte->rule));
     if (old) {
         fte_version_free(old->versions[index]);
         fte->versions[!index] = old->versions[!index];
@@ -1052,10 +1033,9 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index)
         enum nx_flow_format min_ff;
         struct ofpbuf actions;
         struct flow_mod fm;
-        uint8_t table_idx;
 
         ofpbuf_init(&actions, 64);
-        parse_ofp_str(&fm, &table_idx, &actions, ds_cstr(&s));
+        parse_ofp_str(&fm, &actions, ds_cstr(&s));
 
         version = xmalloc(sizeof *version);
         version->cookie = fm.cookie;
@@ -1065,7 +1045,7 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index)
         version->n_actions = actions.size / sizeof *version->actions;
         version->actions = ofpbuf_steal_data(&actions);
 
-        min_ff = ofputil_min_flow_format(&fm.cr, true, fm.cookie);
+        min_ff = ofputil_min_flow_format(&fm.cr);
         min_flow_format = MAX(min_flow_format, min_ff);
         check_final_format_for_flow_mod(min_flow_format);
 
@@ -1131,8 +1111,7 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format,
                 struct ofputil_flow_stats fs;
                 int retval;
 
-                retval = ofputil_decode_flow_stats_reply(&fs, reply,
-                                                         flow_format);
+                retval = ofputil_decode_flow_stats_reply(&fs, reply);
                 if (retval) {
                     if (retval != EOF) {
                         ovs_fatal(0, "parse error in reply");
@@ -1151,8 +1130,6 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format,
 
                 fte_insert(cls, &fs.rule, version, index);
             }
-
-            osr = ofpbuf_at(reply, 0, sizeof *osr);
         } else {
             VLOG_DBG("received reply with xid %08"PRIx32" "
                      "!= expected %08"PRIx32, recv_xid, send_xid);
@@ -1171,6 +1148,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command,
 
     fm.cr = fte->rule;
     fm.cookie = version->cookie;
+    fm.table_id = 0xff;
     fm.command = command;
     fm.idle_timeout = version->idle_timeout;
     fm.hard_timeout = version->hard_timeout;
@@ -1186,7 +1164,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command,
         fm.n_actions = 0;
     }
 
-    ofm = ofputil_encode_flow_mod(&fm, flow_format);
+    ofm = ofputil_encode_flow_mod(&fm, flow_format, false);
     list_push_back(packets, &ofm->list_node);
 }
 
@@ -1319,15 +1297,18 @@ static void
 do_parse_flow(int argc OVS_UNUSED, char *argv[])
 {
     enum nx_flow_format flow_format;
+    bool flow_mod_table_id;
     struct list packets;
 
     flow_format = NXFF_OPENFLOW10;
     if (preferred_flow_format > 0) {
         flow_format = preferred_flow_format;
     }
+    flow_mod_table_id = false;
 
     list_init(&packets);
-    parse_ofp_flow_mod_str(&packets, &flow_format, argv[1], OFPFC_ADD);
+    parse_ofp_flow_mod_str(&packets, &flow_format, &flow_mod_table_id,
+                           argv[1], OFPFC_ADD);
     print_packet_list(&packets);
 }
 
@@ -1337,6 +1318,7 @@ static void
 do_parse_flows(int argc OVS_UNUSED, char *argv[])
 {
     enum nx_flow_format flow_format;
+    bool flow_mod_table_id;
     struct list packets;
     FILE *file;
 
@@ -1349,9 +1331,11 @@ do_parse_flows(int argc OVS_UNUSED, char *argv[])
     if (preferred_flow_format > 0) {
         flow_format = preferred_flow_format;
     }
+    flow_mod_table_id = false;
 
     list_init(&packets);
-    while (parse_ofp_flow_mod_file(&packets, &flow_format, file, OFPFC_ADD)) {
+    while (parse_ofp_flow_mod_file(&packets, &flow_format, &flow_mod_table_id,
+                                   file, OFPFC_ADD)) {
         print_packet_list(&packets);
     }
     fclose(file);