From: Ben Pfaff Date: Wed, 10 Sep 2008 22:00:47 +0000 (-0700) Subject: Delete OFPST_SWITCH and make it available as a Nicira vendor extension. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0fb7347b9029284128b0ceb433c586dfd43dc62;p=openvswitch Delete OFPST_SWITCH and make it available as a Nicira vendor extension. --- diff --git a/ext b/ext index 4cf18a51..15707fb5 160000 --- 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 index 00000000..6e16fafc --- /dev/null +++ b/include/nicira-ext.h @@ -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 */ diff --git a/include/openflow.h b/include/openflow.h index 0309b4c4..e77dd714 100644 --- a/include/openflow.h +++ b/include/openflow.h @@ -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 diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 4bbcda23..c6076478 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -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 }, }, }; diff --git a/secchan/secchan.c b/secchan/secchan.c index 190fb28d..0aaa7cb1 100644 --- a/secchan/secchan.c +++ b/secchan/secchan.c @@ -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)); diff --git a/utilities/dpctl.c b/utilities/dpctl.c index a008e3ca..33a51f85 100644 --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@ -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