X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=3d101789df92fb79499baa455f269ba7b5aaef90;hb=8c7ea6a0c0d44f707eef136b77ac0dd1c55509a4;hp=6c476951bde0238f9ed99716f3acfde3efc15ae2;hpb=02c5617b60e6dbd729c529629488bb7f812ca3d9;p=openvswitch diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 6c476951..3d101789 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,6 @@ #include "command-line.h" #include "compiler.h" #include "dirs.h" -#include "dpif.h" #include "dynamic-string.h" #include "netlink.h" #include "nx-match.h" @@ -40,6 +40,7 @@ #include "ofp-print.h" #include "ofp-util.h" #include "ofpbuf.h" +#include "ofproto/ofproto.h" #include "openflow/nicira-ext.h" #include "openflow/openflow.h" #include "random.h" @@ -84,15 +85,15 @@ parse_options(int argc, char *argv[]) VLOG_OPTION_ENUMS }; static struct option long_options[] = { - {"timeout", required_argument, 0, 't'}, - {"strict", no_argument, 0, OPT_STRICT}, - {"flow-format", required_argument, 0, 'F'}, - {"more", no_argument, 0, 'm'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, NULL, 't'}, + {"strict", no_argument, NULL, OPT_STRICT}, + {"flow-format", required_argument, NULL, 'F'}, + {"more", no_argument, NULL, 'm'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, VLOG_LONG_OPTIONS, - STREAM_SSL_LONG_OPTIONS - {0, 0, 0, 0}, + STREAM_SSL_LONG_OPTIONS, + {NULL, 0, NULL, 0}, }; char *short_options = long_options_to_short_options(long_options); @@ -171,6 +172,7 @@ usage(void) " add-flows SWITCH FILE add flows from FILE\n" " mod-flows SWITCH FLOW modify actions of matching FLOWs\n" " del-flows SWITCH [FLOW] delete matching FLOWs\n" + " replace-flows SWITCH FILE replace flows with those in FILE\n" " monitor SWITCH [MISSLEN] print packets received from SWITCH\n" "\nFor OpenFlow switches and controllers:\n" " probe VCONN probe whether VCONN is up\n" @@ -198,17 +200,8 @@ static void run(int retval, const char *message, ...) if (retval) { va_list args; - fprintf(stderr, "%s: ", program_name); va_start(args, message); - vfprintf(stderr, message, args); - va_end(args); - if (retval == EOF) { - fputs(": unexpected end of file\n", stderr); - } else { - fprintf(stderr, ": %s\n", strerror(retval)); - } - - exit(EXIT_FAILURE); + ovs_fatal_valist(retval, message, args); } } @@ -228,12 +221,17 @@ static void open_vconn__(const char *name, const char *default_suffix, struct vconn **vconnp) { - struct dpif *dpif; + char *datapath_name, *datapath_type, *socket_name; + char *bridge_path; struct stat s; - char *bridge_path, *datapath_name, *datapath_type; bridge_path = xasprintf("%s/%s.%s", ovs_rundir(), name, default_suffix); - dp_parse_name(name, &datapath_name, &datapath_type); + + ofproto_parse_name(name, &datapath_name, &datapath_type); + socket_name = xasprintf("%s/%s.%s", + ovs_rundir(), datapath_name, default_suffix); + free(datapath_name); + free(datapath_type); if (strstr(name, ":")) { run(vconn_open_block(name, OFP_VERSION, vconnp), @@ -242,36 +240,18 @@ open_vconn__(const char *name, const char *default_suffix, open_vconn_socket(name, vconnp); } else if (!stat(bridge_path, &s) && S_ISSOCK(s.st_mode)) { open_vconn_socket(bridge_path, vconnp); - } else if (!dpif_open(datapath_name, datapath_type, &dpif)) { - char dpif_name[IF_NAMESIZE + 1]; - char *socket_name; - - run(dpif_port_get_name(dpif, ODPP_LOCAL, dpif_name, sizeof dpif_name), - "obtaining name of %s", dpif_name); - dpif_close(dpif); - if (strcmp(dpif_name, name)) { - VLOG_DBG("datapath %s is named %s", name, dpif_name); - } - - socket_name = xasprintf("%s/%s.%s", - ovs_rundir(), dpif_name, default_suffix); - if (stat(socket_name, &s)) { - ovs_fatal(errno, "cannot connect to %s: stat failed on %s", - name, socket_name); - } else if (!S_ISSOCK(s.st_mode)) { + } 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); - free(socket_name); } else { ovs_fatal(0, "%s is not a valid connection method", name); } - free(datapath_name); - free(datapath_type); free(bridge_path); + free(socket_name); } static void @@ -283,12 +263,11 @@ open_vconn(const char *name, struct vconn **vconnp) static void * alloc_stats_request(size_t body_len, uint16_t type, struct ofpbuf **bufferp) { - struct ofp_stats_request *rq; - rq = make_openflow((offsetof(struct ofp_stats_request, body) - + body_len), OFPT_STATS_REQUEST, bufferp); + struct ofp_stats_msg *rq; + rq = make_openflow(sizeof *rq + body_len, OFPT_STATS_REQUEST, bufferp); rq->type = htons(type); rq->flags = htons(0); - return rq->body; + return rq + 1; } static void @@ -335,12 +314,12 @@ dump_stats_transaction(const char *vconn_name, struct ofpbuf *request) run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed"); recv_xid = ((struct ofp_header *) reply->data)->xid; if (send_xid == recv_xid) { - struct ofp_stats_reply *osr; + struct ofp_stats_msg *osm; ofp_print(stdout, reply->data, reply->size, verbosity + 1); - osr = ofpbuf_at(reply, 0, sizeof *osr); - done = !osr || !(ntohs(osr->flags) & OFPSF_REPLY_MORE); + osm = ofpbuf_at(reply, 0, sizeof *osm); + done = !osm || !(ntohs(osm->flags) & OFPSF_REPLY_MORE); } else { VLOG_DBG("received reply with xid %08"PRIx32" " "!= expected %08"PRIx32, recv_xid, send_xid); @@ -523,8 +502,6 @@ negotiate_highest_flow_format(struct vconn *vconn, 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; } @@ -552,7 +529,7 @@ do_dump_flows__(int argc, char *argv[], bool aggregate) parse_ofp_flow_stats_request_str(&fsr, aggregate, argc > 2 ? argv[2] : ""); open_vconn(argv[1], &vconn); - min_flow_format = ofputil_min_flow_format(&fsr.match, false, 0); + min_flow_format = ofputil_min_flow_format(&fsr.match); flow_format = negotiate_highest_flow_format(vconn, min_flow_format); request = ofputil_encode_flow_stats_request(&fsr, flow_format); dump_stats_transaction(argv[1], request); @@ -633,56 +610,72 @@ check_final_format_for_flow_mod(enum nx_flow_format flow_format) } static void -do_flow_mod__(int argc OVS_UNUSED, char *argv[], uint16_t command) +do_flow_mod_file__(int argc OVS_UNUSED, char *argv[], uint16_t command) { enum nx_flow_format flow_format; + bool flow_mod_table_id; struct list requests; struct vconn *vconn; + FILE *file; + + file = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"); + if (file == NULL) { + ovs_fatal(errno, "%s: open", argv[2]); + } list_init(&requests); 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); + flow_mod_table_id = false; open_vconn(argv[1], &vconn); - transact_multiple_noreply(vconn, &requests); + while (parse_ofp_flow_mod_file(&requests, &flow_format, &flow_mod_table_id, + file, command)) { + check_final_format_for_flow_mod(flow_format); + transact_multiple_noreply(vconn, &requests); + } vconn_close(vconn); -} -static void -do_add_flow(int argc, char *argv[]) -{ - do_flow_mod__(argc, argv, OFPFC_ADD); + if (file != stdin) { + fclose(file); + } } static void -do_add_flows(int argc OVS_UNUSED, char *argv[]) +do_flow_mod__(int argc, char *argv[], uint16_t command) { enum nx_flow_format flow_format; + bool flow_mod_table_id; struct list requests; struct vconn *vconn; - FILE *file; - file = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"); - if (file == NULL) { - ovs_fatal(errno, "%s: open", argv[2]); + if (argc > 2 && !strcmp(argv[2], "-")) { + do_flow_mod_file__(argc, argv, command); + return; } list_init(&requests); flow_format = set_initial_format_for_flow_mod(&requests); + flow_mod_table_id = false; + + parse_ofp_flow_mod_str(&requests, &flow_format, &flow_mod_table_id, + argc > 2 ? argv[2] : "", command, false); + check_final_format_for_flow_mod(flow_format); open_vconn(argv[1], &vconn); - while (parse_ofp_flow_mod_file(&requests, &flow_format, file, OFPFC_ADD)) { - check_final_format_for_flow_mod(flow_format); - transact_multiple_noreply(vconn, &requests); - } + transact_multiple_noreply(vconn, &requests); vconn_close(vconn); +} - if (file != stdin) { - fclose(file); - } +static void +do_add_flow(int argc, char *argv[]) +{ + do_flow_mod__(argc, argv, OFPFC_ADD); +} + +static void +do_add_flows(int argc, char *argv[]) +{ + do_flow_mod_file__(argc, argv, OFPFC_ADD); } static void @@ -824,9 +817,9 @@ do_ping(int argc, char *argv[]) OFPT_ECHO_REQUEST, &request); random_bytes(rq_hdr + 1, payload); - gettimeofday(&start, NULL); + xgettimeofday(&start); run(vconn_transact(vconn, ofpbuf_clone(request), &reply), "transact"); - gettimeofday(&end, NULL); + xgettimeofday(&end); rpy_hdr = reply->data; if (reply->size != request->size @@ -871,7 +864,7 @@ do_benchmark(int argc OVS_UNUSED, char *argv[]) count, message_size, count * message_size); open_vconn(argv[1], &vconn); - gettimeofday(&start, NULL); + xgettimeofday(&start); for (i = 0; i < count; i++) { struct ofpbuf *request, *reply; struct ofp_header *rq_hdr; @@ -881,7 +874,7 @@ do_benchmark(int argc OVS_UNUSED, char *argv[]) run(vconn_transact(vconn, request, &reply), "transact"); ofpbuf_delete(reply); } - gettimeofday(&end, NULL); + xgettimeofday(&end); vconn_close(vconn); duration = ((1000*(double)(end.tv_sec - start.tv_sec)) @@ -1010,7 +1003,7 @@ fte_insert(struct classifier *cls, const struct cls_rule *rule, fte->rule = *rule; fte->versions[index] = version; - old = fte_from_cls_rule(classifier_insert(cls, &fte->rule)); + old = fte_from_cls_rule(classifier_replace(cls, &fte->rule)); if (old) { fte_version_free(old->versions[index]); fte->versions[!index] = old->versions[!index]; @@ -1040,10 +1033,9 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index) enum nx_flow_format min_ff; struct ofpbuf actions; struct flow_mod fm; - uint8_t table_idx; ofpbuf_init(&actions, 64); - parse_ofp_str(&fm, &table_idx, &actions, ds_cstr(&s)); + parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), true); version = xmalloc(sizeof *version); version->cookie = fm.cookie; @@ -1053,7 +1045,7 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index) version->n_actions = actions.size / sizeof *version->actions; version->actions = ofpbuf_steal_data(&actions); - min_ff = ofputil_min_flow_format(&fm.cr, true, fm.cookie); + min_ff = ofputil_min_flow_format(&fm.cr); min_flow_format = MAX(min_flow_format, min_ff); check_final_format_for_flow_mod(min_flow_format); @@ -1097,7 +1089,7 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format, recv_xid = ((struct ofp_header *) reply->data)->xid; if (send_xid == recv_xid) { const struct ofputil_msg_type *type; - const struct ofp_stats_reply *osr; + const struct ofp_stats_msg *osm; enum ofputil_msg_code code; ofputil_decode_msg_type(reply->data, &type); @@ -1109,8 +1101,8 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format, verbosity + 1)); } - osr = reply->data; - if (!(osr->flags & htons(OFPSF_REPLY_MORE))) { + osm = reply->data; + if (!(osm->flags & htons(OFPSF_REPLY_MORE))) { done = true; } @@ -1119,8 +1111,7 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format, struct ofputil_flow_stats fs; int retval; - retval = ofputil_decode_flow_stats_reply(&fs, reply, - flow_format); + retval = ofputil_decode_flow_stats_reply(&fs, reply); if (retval) { if (retval != EOF) { ovs_fatal(0, "parse error in reply"); @@ -1139,8 +1130,6 @@ read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format, fte_insert(cls, &fs.rule, version, index); } - - osr = ofpbuf_at(reply, 0, sizeof *osr); } else { VLOG_DBG("received reply with xid %08"PRIx32" " "!= expected %08"PRIx32, recv_xid, send_xid); @@ -1159,6 +1148,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, fm.cr = fte->rule; fm.cookie = version->cookie; + fm.table_id = 0xff; fm.command = command; fm.idle_timeout = version->idle_timeout; fm.hard_timeout = version->hard_timeout; @@ -1174,7 +1164,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, fm.n_actions = 0; } - ofm = ofputil_encode_flow_mod(&fm, flow_format); + ofm = ofputil_encode_flow_mod(&fm, flow_format, false); list_push_back(packets, &ofm->list_node); } @@ -1307,15 +1297,18 @@ static void do_parse_flow(int argc OVS_UNUSED, char *argv[]) { enum nx_flow_format flow_format; + bool flow_mod_table_id; struct list packets; flow_format = NXFF_OPENFLOW10; if (preferred_flow_format > 0) { flow_format = preferred_flow_format; } + flow_mod_table_id = false; list_init(&packets); - parse_ofp_flow_mod_str(&packets, &flow_format, argv[1], OFPFC_ADD); + parse_ofp_flow_mod_str(&packets, &flow_format, &flow_mod_table_id, + argv[1], OFPFC_ADD, false); print_packet_list(&packets); } @@ -1325,6 +1318,7 @@ static void do_parse_flows(int argc OVS_UNUSED, char *argv[]) { enum nx_flow_format flow_format; + bool flow_mod_table_id; struct list packets; FILE *file; @@ -1337,9 +1331,11 @@ do_parse_flows(int argc OVS_UNUSED, char *argv[]) if (preferred_flow_format > 0) { flow_format = preferred_flow_format; } + flow_mod_table_id = false; list_init(&packets); - while (parse_ofp_flow_mod_file(&packets, &flow_format, file, OFPFC_ADD)) { + while (parse_ofp_flow_mod_file(&packets, &flow_format, &flow_mod_table_id, + file, OFPFC_ADD)) { print_packet_list(&packets); } fclose(file);