Replace most uses of assert by ovs_assert.
[sliver-openvswitch.git] / utilities / ovs-ofctl.c
index df2c6aa..2ffe3d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -357,8 +357,8 @@ open_vconn_socket(const char *name, struct vconn **vconnp)
     char *vconn_name = xasprintf("unix:%s", name);
     int error;
 
-    error = vconn_open(vconn_name, get_allowed_ofp_versions(), vconnp,
-                       DSCP_DEFAULT);
+    error = vconn_open(vconn_name, get_allowed_ofp_versions(), DSCP_DEFAULT,
+                       vconnp);
     if (error && error != ENOENT) {
         ovs_fatal(0, "%s: failed to open socket (%s)", name,
                   strerror(error));
@@ -387,7 +387,8 @@ open_vconn__(const char *name, const char *default_suffix,
     free(datapath_type);
 
     if (strchr(name, ':')) {
-        run(vconn_open_block(name, get_allowed_ofp_versions(), vconnp),
+        run(vconn_open_block(name, get_allowed_ofp_versions(), DSCP_DEFAULT,
+                             vconnp),
             "connecting to %s", name);
     } else if (!open_vconn_socket(name, vconnp)) {
         /* Fall Through. */
@@ -2176,7 +2177,7 @@ ofctl_parse_flows__(struct ofputil_flow_mod *fms, size_t n_fms)
             break;
         }
     }
-    assert(IS_POW2(protocol));
+    ovs_assert(IS_POW2(protocol));
 
     printf("chosen protocol: %s\n", ofputil_protocol_to_string(protocol));
 
@@ -2751,6 +2752,40 @@ ofctl_print_error(int argc OVS_UNUSED, char *argv[])
     }
 }
 
+/* "encode-error-reply ENUM REQUEST": Encodes an error reply to REQUEST for the
+ * error named ENUM and prints the error reply in hex. */
+static void
+ofctl_encode_error_reply(int argc OVS_UNUSED, char *argv[])
+{
+    const struct ofp_header *oh;
+    struct ofpbuf request, *reply;
+    enum ofperr error;
+
+    error = ofperr_from_name(argv[1]);
+    if (!error) {
+        ovs_fatal(0, "unknown error \"%s\"", argv[1]);
+    }
+
+    ofpbuf_init(&request, 0);
+    if (ofpbuf_put_hex(&request, argv[2], NULL)[0] != '\0') {
+        ovs_fatal(0, "Trailing garbage in hex data");
+    }
+    if (request.size < sizeof(struct ofp_header)) {
+        ovs_fatal(0, "Request too short");
+    }
+
+    oh = request.data;
+    if (request.size != ntohs(oh->length)) {
+        ovs_fatal(0, "Request size inconsistent");
+    }
+
+    reply = ofperr_encode_reply(error, request.data);
+    ofpbuf_uninit(&request);
+
+    ovs_hex_dump(stdout, reply->data, reply->size, 0, false);
+    ofpbuf_delete(reply);
+}
+
 /* "ofp-print HEXSTRING [VERBOSITY]": Converts the hex digits in HEXSTRING into
  * binary data, interpreting them as an OpenFlow message, and prints the
  * OpenFlow message on stdout, at VERBOSITY (level 2 by default).  */
@@ -2820,6 +2855,7 @@ static const struct command all_commands[] = {
     { "parse-ofp11-instructions", 0, 0, ofctl_parse_ofp11_instructions },
     { "check-vlan", 2, 2, ofctl_check_vlan },
     { "print-error", 1, 1, ofctl_print_error },
+    { "encode-error-reply", 2, 2, ofctl_encode_error_reply },
     { "ofp-print", 1, 2, ofctl_ofp_print },
     { "encode-hello", 1, 1, ofctl_encode_hello },