X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=363c0a3a3d44ad18be52c96a3c655216b585563d;hb=d6cedfd9d29df4f9e9b7575c03ffcd2d84588c62;hp=c7069c5bb565ed04351623418e83042d4728e889;hpb=81a76618be9ea195a1e4a881ba9591728891d10b;p=openvswitch diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index c7069c5b..363c0a3a 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -52,6 +52,7 @@ #include "poll-loop.h" #include "random.h" #include "stream-ssl.h" +#include "socket-util.h" #include "timeval.h" #include "unixctl.h" #include "util.h" @@ -319,7 +320,8 @@ ofctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED, static void run(int retval, const char *message, ...) PRINTF_FORMAT(2, 3); -static void run(int retval, const char *message, ...) +static void +run(int retval, const char *message, ...) { if (retval) { va_list args; @@ -331,14 +333,20 @@ static void run(int retval, const char *message, ...) /* Generic commands. */ -static void +static int open_vconn_socket(const char *name, struct vconn **vconnp) { char *vconn_name = xasprintf("unix:%s", name); - VLOG_DBG("connecting to %s", vconn_name); - run(vconn_open_block(vconn_name, OFP10_VERSION, vconnp), - "connecting to %s", vconn_name); + int error; + + error = vconn_open(vconn_name, 0, vconnp, DSCP_DEFAULT); + if (error && error != ENOENT) { + ovs_fatal(0, "%s: failed to open socket (%s)", name, + strerror(error)); + } free(vconn_name); + + return error; } static enum ofputil_protocol @@ -349,7 +357,7 @@ open_vconn__(const char *name, const char *default_suffix, enum ofputil_protocol protocol; char *bridge_path; int ofp_version; - struct stat s; + int error; bridge_path = xasprintf("%s/%s.%s", ovs_rundir(), name, default_suffix); @@ -360,18 +368,13 @@ open_vconn__(const char *name, const char *default_suffix, free(datapath_type); if (strchr(name, ':')) { - run(vconn_open_block(name, OFP10_VERSION, vconnp), - "connecting to %s", name); - } else if (!stat(name, &s) && S_ISSOCK(s.st_mode)) { - open_vconn_socket(name, vconnp); - } else if (!stat(bridge_path, &s) && S_ISSOCK(s.st_mode)) { - open_vconn_socket(bridge_path, vconnp); - } 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); + run(vconn_open_block(name, 0, vconnp), "connecting to %s", name); + } else if (!open_vconn_socket(name, vconnp)) { + /* Fall Through. */ + } else if (!open_vconn_socket(bridge_path, vconnp)) { + /* Fall Through. */ + } else if (!open_vconn_socket(socket_name, vconnp)) { + /* Fall Through. */ } else { ovs_fatal(0, "%s is not a bridge or a socket", name); } @@ -379,6 +382,13 @@ open_vconn__(const char *name, const char *default_suffix, free(bridge_path); free(socket_name); + VLOG_DBG("connecting to %s", vconn_get_name(*vconnp)); + error = vconn_connect_block(*vconnp); + if (error) { + ovs_fatal(0, "%s: failed to connect to socket (%s)", name, + strerror(error)); + } + ofp_version = vconn_get_version(*vconnp); protocol = ofputil_protocol_from_ofp_version(ofp_version); if (!protocol) { @@ -741,9 +751,9 @@ fetch_ofputil_phy_port(const char *vconn_name, const char *port_name, static uint16_t str_to_port_no(const char *vconn_name, const char *port_name) { - unsigned int port_no; + uint16_t port_no; - if (str_to_uint(port_name, 10, &port_no)) { + if (ofputil_port_from_string(port_name, &port_no)) { return port_no; } else { struct ofputil_phy_port pp; @@ -763,7 +773,7 @@ try_set_protocol(struct vconn *vconn, enum ofputil_protocol want, request = ofputil_encode_set_protocol(*cur, want, &next); if (!request) { - return true; + return *cur == want; } run(vconn_transact_noreply(vconn, request, &reply), @@ -949,28 +959,24 @@ ofctl_dump_aggregate(int argc, char *argv[]) static void ofctl_queue_stats(int argc, char *argv[]) { - struct ofp10_queue_stats_request *req; struct ofpbuf *request; struct vconn *vconn; + struct ofputil_queue_stats_request oqs; 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")) { - req->port_no = htons(str_to_port_no(argv[1], argv[2])); + oqs.port_no = str_to_port_no(argv[1], argv[2]); } else { - req->port_no = htons(OFPP_ALL); + oqs.port_no = OFPP_ALL; } if (argc > 3 && argv[3][0] && strcasecmp(argv[3], "all")) { - req->queue_id = htonl(atoi(argv[3])); + oqs.queue_id = atoi(argv[3]); } else { - req->queue_id = htonl(OFPQ_ALL); + oqs.queue_id = OFPQ_ALL; } - memset(req->pad, 0, sizeof req->pad); - + request = ofputil_encode_queue_stats_request(vconn_get_version(vconn), &oqs); dump_stats_transaction(vconn, request); vconn_close(vconn); } @@ -1086,7 +1092,10 @@ static void set_packet_in_format(struct vconn *vconn, enum nx_packet_in_format packet_in_format) { - struct ofpbuf *spif = ofputil_make_set_packet_in_format(packet_in_format); + struct ofpbuf *spif; + + spif = ofputil_make_set_packet_in_format(vconn_get_version(vconn), + packet_in_format); transact_noreply(vconn, spif); VLOG_DBG("%s: using user-specified packet in format %s", vconn_get_name(vconn), @@ -1387,7 +1396,8 @@ ofctl_monitor(int argc, char *argv[]) } else { struct ofpbuf *spif, *reply; - spif = ofputil_make_set_packet_in_format(NXPIF_NXM); + spif = ofputil_make_set_packet_in_format(vconn_get_version(vconn), + NXPIF_NXM); run(vconn_transact_noreply(vconn, spif, &reply), "talking to %s", vconn_get_name(vconn)); if (reply) { @@ -1415,17 +1425,13 @@ ofctl_snoop(int argc OVS_UNUSED, char *argv[]) static void ofctl_dump_ports(int argc, char *argv[]) { - struct ofp10_port_stats_request *req; struct ofpbuf *request; struct vconn *vconn; uint16_t port; 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); + request = ofputil_encode_dump_ports_request(vconn_get_version(vconn), port); dump_stats_transaction(vconn, request); vconn_close(vconn); } @@ -1466,9 +1472,7 @@ ofctl_packet_out(int argc, char *argv[]) parse_ofpacts(argv[3], &ofpacts); po.buffer_id = UINT32_MAX; - po.in_port = (!strcasecmp(argv[2], "none") ? OFPP_NONE - : !strcasecmp(argv[2], "local") ? OFPP_LOCAL - : str_to_port_no(argv[1], argv[2])); + po.in_port = str_to_port_no(argv[1], argv[2]); po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; @@ -1778,6 +1782,7 @@ fte_free(struct fte *fte) if (fte) { fte_version_free(fte->versions[0]); fte_version_free(fte->versions[1]); + cls_rule_destroy(&fte->rule); free(fte); } } @@ -1816,6 +1821,7 @@ fte_insert(struct classifier *cls, const struct match *match, if (old) { fte_version_free(old->versions[index]); fte->versions[!index] = old->versions[!index]; + cls_rule_destroy(&old->rule); free(old); } } @@ -1967,7 +1973,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, struct ofputil_flow_mod fm; struct ofpbuf *ofm; - fm.match = fte->rule.match; + minimatch_expand(&fte->rule.match, &fm.match); fm.priority = fte->rule.priority; fm.cookie = htonll(0); fm.cookie_mask = htonll(0); @@ -2723,6 +2729,20 @@ ofctl_ofp_print(int argc, char *argv[]) ofpbuf_uninit(&packet); } +/* "encode-hello BITMAP...": Encodes each BITMAP as an OpenFlow hello message + * and dumps each message in hex. */ +static void +ofctl_encode_hello(int argc OVS_UNUSED, char *argv[]) +{ + uint32_t bitmap = strtol(argv[1], NULL, 0); + struct ofpbuf *hello; + + hello = ofputil_encode_hello(bitmap); + ovs_hex_dump(stdout, hello->data, hello->size, 0, false); + ofp_print(stdout, hello->data, hello->size, verbosity); + ofpbuf_delete(hello); +} + static const struct command all_commands[] = { { "show", 1, 1, ofctl_show }, { "monitor", 1, 3, ofctl_monitor }, @@ -2763,6 +2783,7 @@ static const struct command all_commands[] = { { "check-vlan", 2, 2, ofctl_check_vlan }, { "print-error", 1, 1, ofctl_print_error }, { "ofp-print", 1, 2, ofctl_ofp_print }, + { "encode-hello", 1, 1, ofctl_encode_hello }, { NULL, 0, 0, NULL }, };