X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=cd44cd8be8dcc3419057997a8c6c4ac9c2bc4f0e;hb=c7981f8ca285147fa315fde62d06107d54f4acac;hp=9f5a0a524f12640a06d930f74b7f3522a210d86c;hpb=770f1f66bb9dc4e784e6c2c5351089c62b9a5919;p=openvswitch diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 9f5a0a52..cd44cd8b 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -158,7 +158,6 @@ usage(void) "usage: %s [OPTIONS] COMMAND [ARG...]\n" "\nFor OpenFlow switches:\n" " show SWITCH show OpenFlow information\n" - " status SWITCH [KEY] report statistics (about KEY)\n" " dump-desc SWITCH print switch description\n" " dump-tables SWITCH print table stats\n" " mod-port SWITCH IFACE ACT modify port behavior\n" @@ -400,36 +399,6 @@ do_show(int argc OVS_UNUSED, char *argv[]) dump_trivial_transaction(argv[1], OFPT_GET_CONFIG_REQUEST); } -static void -do_status(int argc, char *argv[]) -{ - struct nicira_header *request, *reply; - struct vconn *vconn; - struct ofpbuf *b; - - request = make_nxmsg(sizeof *request, NXT_STATUS_REQUEST, &b); - if (argc > 2) { - ofpbuf_put(b, argv[2], strlen(argv[2])); - update_openflow_length(b); - } - open_vconn(argv[1], &vconn); - run(vconn_transact(vconn, b, &b), "talking to %s", argv[1]); - vconn_close(vconn); - - if (b->size < sizeof *reply) { - ovs_fatal(0, "short reply (%zu bytes)", b->size); - } - reply = b->data; - if (reply->header.type != OFPT_VENDOR - || reply->vendor != ntohl(NX_VENDOR_ID) - || reply->subtype != ntohl(NXT_STATUS_REPLY)) { - ofp_print(stderr, b->data, b->size, verbosity + 2); - ovs_fatal(0, "bad reply"); - } - - fwrite(reply + 1, b->size - sizeof *reply, 1, stdout); -} - static void do_dump_desc(int argc OVS_UNUSED, char *argv[]) { @@ -540,33 +509,39 @@ static enum nx_flow_format negotiate_highest_flow_format(struct vconn *vconn, const struct cls_rule *rule, bool cookie_support, ovs_be64 cookie) { - int flow_format; + enum nx_flow_format min_format; + min_format = ofputil_min_flow_format(rule, cookie_support, cookie); if (preferred_flow_format != -1) { - enum nx_flow_format min_format; + if (preferred_flow_format < min_format) { + ovs_fatal(0, "%s: cannot use requested flow format %s for " + "specified flow", vconn_get_name(vconn), + ofputil_flow_format_to_string(min_format)); + } - min_format = ofputil_min_flow_format(rule, cookie_support, cookie); - if (preferred_flow_format >= min_format) { - set_flow_format(vconn, preferred_flow_format); - return preferred_flow_format; + set_flow_format(vconn, preferred_flow_format); + return preferred_flow_format; + } else { + enum nx_flow_format flow_format; + + 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; } - VLOG_WARN("%s: cannot use requested flow format %s for " - "specified flow", vconn_get_name(vconn), - ofputil_flow_format_to_string(min_format)); - } + if (flow_format < min_format) { + ovs_fatal(0, "%s: cannot use switch's most advanced flow format " + "%s for specified flow", vconn_get_name(vconn), + ofputil_flow_format_to_string(min_format)); + } - 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; + VLOG_DBG("%s: negotiated flow format %s", vconn_get_name(vconn), + ofputil_flow_format_to_string(flow_format)); + return flow_format; } - - VLOG_DBG("%s: negotiated flow format %s", vconn_get_name(vconn), - ofputil_flow_format_to_string(flow_format)); - return flow_format; } static void @@ -622,6 +597,43 @@ do_queue_stats(int argc, char *argv[]) dump_stats_transaction(argv[1], request); } +/* Sets up the flow format for a vconn that will be used to modify the flow + * table. Returns the flow format used, after possibly adding an OpenFlow + * request to 'requests'. + * + * If 'preferred_flow_format' is -1, returns NXFF_OPENFLOW10 without modifying + * 'requests', since NXFF_OPENFLOW10 is the default flow format for any + * OpenFlow connection. + * + * If 'preferred_flow_format' is a specific format, adds a request to set that + * format to 'requests' and returns the format. */ +static enum nx_flow_format +set_initial_format_for_flow_mod(struct list *requests) +{ + if (preferred_flow_format < 0) { + return NXFF_OPENFLOW10; + } else { + struct ofpbuf *sff; + + sff = ofputil_make_set_flow_format(preferred_flow_format); + list_push_back(requests, &sff->list_node); + return preferred_flow_format; + } +} + +/* Checks that 'flow_format' is acceptable as a flow format after a flow_mod + * operation, given the global 'preferred_flow_format'. */ +static void +check_final_format_for_flow_mod(enum nx_flow_format flow_format) +{ + if (preferred_flow_format >= 0 && flow_format != preferred_flow_format) { + ovs_fatal(0, "flow cannot be expressed in flow format %s " + "(flow format %s or better is required)", + ofputil_flow_format_to_string(preferred_flow_format), + ofputil_flow_format_to_string(flow_format)); + } +} + static void do_flow_mod__(int argc OVS_UNUSED, char *argv[], uint16_t command) { @@ -630,9 +642,11 @@ do_flow_mod__(int argc OVS_UNUSED, char *argv[], uint16_t command) struct vconn *vconn; list_init(&requests); - flow_format = NXFF_OPENFLOW10; + flow_format = set_initial_format_for_flow_mod(&requests); + parse_ofp_flow_mod_str(&requests, &flow_format, argc > 2 ? argv[2] : "", command); + check_final_format_for_flow_mod(flow_format); open_vconn(argv[1], &vconn); transact_multiple_noreply(vconn, &requests); @@ -653,21 +667,24 @@ do_add_flows(int argc OVS_UNUSED, char *argv[]) struct vconn *vconn; FILE *file; - file = fopen(argv[2], "r"); + file = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"); if (file == NULL) { ovs_fatal(errno, "%s: open", argv[2]); } list_init(&requests); - flow_format = NXFF_OPENFLOW10; + flow_format = set_initial_format_for_flow_mod(&requests); open_vconn(argv[1], &vconn); while (parse_ofp_add_flow_file(&requests, &flow_format, file)) { + check_final_format_for_flow_mod(flow_format); transact_multiple_noreply(vconn, &requests); } vconn_close(vconn); - fclose(file); + if (file != stdin) { + fclose(file); + } } static void @@ -1015,7 +1032,6 @@ do_ofp_print(int argc, char *argv[]) static const struct command all_commands[] = { { "show", 1, 1, do_show }, - { "status", 1, 2, do_status }, { "monitor", 1, 2, do_monitor }, { "snoop", 1, 1, do_snoop }, { "dump-desc", 1, 1, do_dump_desc },