Delete OFPST_SWITCH and make it available as a Nicira vendor extension.
authorBen Pfaff <blp@nicira.com>
Wed, 10 Sep 2008 22:00:47 +0000 (15:00 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 10 Sep 2008 22:00:47 +0000 (15:00 -0700)
ext
include/nicira-ext.h [new file with mode: 0644]
include/openflow.h
lib/ofp-print.c
secchan/secchan.c
utilities/dpctl.c

diff --git a/ext b/ext
index 4cf18a517a2663e945529a16e5d18e3b676c2687..15707fb578371cdd0b7ee8c84758d78633e0177b 160000 (submodule)
--- a/ext
+++ b/ext
@@ -1 +1 @@
-Subproject commit 4cf18a517a2663e945529a16e5d18e3b676c2687
+Subproject commit 15707fb578371cdd0b7ee8c84758d78633e0177b
diff --git a/include/nicira-ext.h b/include/nicira-ext.h
new file mode 100644 (file)
index 0000000..6e16faf
--- /dev/null
@@ -0,0 +1,63 @@
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ *
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#ifndef NICIRA_EXT_H
+#define NICIRA_EXT_H 1
+
+#include "openflow.h"
+
+/* The following vendor extensions, proposed by Nicira Networks, are not yet
+ * ready for standardization (and may never be), so they are not included in
+ * openflow.h. */
+
+#define NX_VENDOR_ID 0x00002320
+
+enum nicira_type {
+    /* Switch status request.  The request body is an ASCII string that
+     * specifies a prefix of the key names to include in the output; if it is
+     * the null string, then all key-value pairs are included. */
+    NXT_STATUS_REQUEST,
+
+    /* Switch status reply.  The reply body is an ASCII string of key-value
+     * pairs in the form "key=value\n". */
+    NXT_STATUS_REPLY
+};
+
+struct nicira_header {
+    struct ofp_header header;
+    uint32_t vendor_id;         /* NX_VENDOR_ID. */
+    uint32_t subtype;           /* One of NXT_* above. */
+};
+OFP_ASSERT(sizeof(struct nicira_header) == sizeof(struct ofp_vendor) + 4);
+
+#endif /* nicira-ext.h */
index 0309b4c47722b7911067e0717d3a01b69e0d9c87..e77dd7149d98f34854b6a581e9a4fe907f9c7360 100644 (file)
@@ -500,14 +500,6 @@ enum ofp_stats_types {
      * The reply body is an array of struct ofp_port_stats. */
     OFPST_PORT,
 
-    /* Switch status.
-     * The request body is an ASCII string that specifies a prefix of the key
-     * names to include in the output; if it is the null string, then all
-     * key-value pairs are included.
-     * The reply body is an ASCII string of key-value pairs in the form
-     * "key=value\n". */
-    OFPST_SWITCH,
-
     /* Vendor extension.
      * The request and reply bodies begin with a 32-bit vendor ID, which takes
      * the same form as in "struct ofp_vendor".  The request and reply bodies
index 4bbcda2350c153a09c0944dffb380c134bdcfe0c..c60764787bb68ddecd47a12f4c114793416ac1b0 100644 (file)
@@ -814,19 +814,12 @@ ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
 }
 
 static void
-switch_status_reply(struct ds *string, const void *body, size_t len,
-                    int verbosity UNUSED)
+vendor_stat(struct ds *string, const void *body, size_t len,
+            int verbosity UNUSED)
 {
-    char *save_ptr = NULL;
-    char *s, *line;
-
-    s = xmemdup0(body, len);
-    for (line = strtok_r(s, "\n\n", &save_ptr); line != NULL;
-         line = strtok_r(NULL, "\n\n", &save_ptr)) {
-        ds_put_printable(string, line, strlen(line));
-        ds_put_char(string, '\n');
-    }
-    free(s);
+    ds_put_format(string, " vendor=%08"PRIx32, ntohl(*(uint32_t *) body));
+    ds_put_format(string, " %zu bytes additional data",
+                  len - sizeof(uint32_t));
 }
 
 enum stats_direction {
@@ -881,10 +874,10 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
             { 0, 0, NULL, },
             { 0, SIZE_MAX, ofp_port_stats_reply },
         },
-        [OFPST_SWITCH] = {
-            "switch status",
-            { 0, 0, NULL, },
-            { 0, SIZE_MAX, switch_status_reply },
+        [OFPST_VENDOR] = {
+            "vendor-specific",
+            { sizeof(uint32_t), SIZE_MAX, vendor_stat },
+            { sizeof(uint32_t), SIZE_MAX, vendor_stat },
         },
     };
 
index 190fb28defa34a85319203db83f6e6e09f4f1125..0aaa7cb1aca507cec701d7636399899e651ed58e 100644 (file)
@@ -58,6 +58,7 @@
 #include "list.h"
 #include "mac-learning.h"
 #include "netdev.h"
+#include "nicira-ext.h"
 #include "openflow.h"
 #include "packets.h"
 #include "poll-loop.h"
@@ -1657,30 +1658,24 @@ switch_status_remote_packet_cb(struct relay *r, void *ss_)
     struct rconn *rc = r->halves[HALF_REMOTE].rconn;
     struct buffer *msg = r->halves[HALF_REMOTE].rxbuf;
     struct switch_status_category *c;
-    struct ofp_stats_request *osr;
-    struct ofp_stats_reply *reply;
+    struct nicira_header *request;
+    struct nicira_header *reply;
     struct status_reply sr;
-    struct ofp_header *oh;
     struct buffer *b;
     int retval;
 
-    oh = msg->data;
-    if (oh->type != OFPT_STATS_REQUEST) {
+    if (msg->size < sizeof(struct nicira_header)) {
         return false;
     }
-    if (msg->size < sizeof(struct ofp_stats_request)) {
-        VLOG_WARN_RL(&vrl, "packet too short (%zu bytes) for stats_request",
-                     msg->size);
+    request = msg->data;
+    if (request->header.type != OFPT_VENDOR
+        || request->vendor_id != htonl(NX_VENDOR_ID)
+        || request->subtype != htonl(NXT_STATUS_REQUEST)) {
         return false;
     }
 
-    osr = msg->data;
-    if (osr->type != htons(OFPST_SWITCH)) {
-        return false;
-    }
-
-    sr.request.string = (void *) (osr + 1);
-    sr.request.length = msg->size - sizeof *osr;
+    sr.request.string = (void *) (request + 1);
+    sr.request.length = msg->size - sizeof *request;
     ds_init(&sr.output);
     for (c = ss->categories; c < &ss->categories[ss->n_categories]; c++) {
         if (!memcmp(c->name, sr.request.string,
@@ -1689,12 +1684,11 @@ switch_status_remote_packet_cb(struct relay *r, void *ss_)
             c->cb(&sr, c->aux);
         }
     }
-    reply = make_openflow_xid((offsetof(struct ofp_stats_reply, body)
-                               + sr.output.length),
-                              OFPT_STATS_REPLY, osr->header.xid, &b);
-    reply->type = htons(OFPST_SWITCH);
-    reply->flags = 0;
-    memcpy(reply->body, sr.output.string, sr.output.length);
+    reply = make_openflow_xid(sizeof *reply + sr.output.length,
+                              OFPT_VENDOR, request->header.xid, &b);
+    reply->vendor_id = htonl(NX_VENDOR_ID);
+    reply->subtype = htonl(NXT_STATUS_REPLY);
+    memcpy(reply + 1, sr.output.string, sr.output.length);
     retval = rconn_send(rc, b, NULL);
     if (retval && retval != EAGAIN) {
         VLOG_WARN("send failed (%s)", strerror(retval));
index a008e3cae89fcf3a1cebd58436500af7edeeef3e..33a51f856c2413e2efba907baf9007547270b5fe 100644 (file)
@@ -54,6 +54,7 @@
 #include "command-line.h"
 #include "compiler.h"
 #include "dpif.h"
+#include "nicira-ext.h"
 #include "ofp-print.h"
 #include "openflow.h"
 #include "packets.h"
@@ -415,12 +416,32 @@ do_show(int argc UNUSED, char *argv[])
 static void
 do_status(int argc, char *argv[])
 {
-    struct buffer *request;
-    alloc_stats_request(0, OFPST_SWITCH, &request);
+    struct nicira_header *request, *reply;
+    struct vconn *vconn;
+    struct buffer *b;
+
+    request = make_openflow(sizeof *request, OFPT_VENDOR, &b);
+    request->vendor_id = htonl(NX_VENDOR_ID);
+    request->subtype = htonl(NXT_STATUS_REQUEST);
     if (argc > 2) {
-        buffer_put(request, argv[2], strlen(argv[2]));
+        buffer_put(b, argv[2], strlen(argv[2]));
     }
-    dump_stats_transaction(argv[1], request);
+    run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
+    run(vconn_transact(vconn, b, &b), "talking to %s", argv[1]);
+    vconn_close(vconn);
+
+    if (b->size < sizeof *reply) {
+        fatal(0, "short reply (%zu bytes)", b->size);
+    }
+    reply = b->data;
+    if (reply->header.type != OFPT_VENDOR
+        || reply->vendor_id != ntohl(NX_VENDOR_ID)
+        || reply->subtype != ntohl(NXT_STATUS_REPLY)) {
+        ofp_print(stderr, b->data, b->size, 2);
+        fatal(0, "bad reply");
+    }
+
+    fwrite(reply + 1, b->size, 1, stdout);
 }
 
 static void