X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=164d0830f6b2803ce048ad5d8542fd819a8ebe6d;hb=8ba31bf16d03c449fbf40ec00d9a816b4ec05018;hp=5fa11dba43eb97224fe50c166b450d922471cf13;hpb=007948177581f3b3dad188221593d0e4bdca6ba0;p=openvswitch diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 5fa11dba..164d0830 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -55,6 +55,10 @@ VLOG_DEFINE_THIS_MODULE(ofctl); /* --strict: Use strict matching for flow mod commands? */ static bool strict; +/* --readd: If ture, on replace-flows, re-add even flows that have not changed + * (to reset flow counters). */ +static bool readd; + /* -F, --flow-format: Flow format to use. Either one of NXFF_* to force a * particular flow format or -1 to let ovs-ofctl choose intelligently. */ static int preferred_flow_format = -1; @@ -82,18 +86,20 @@ parse_options(int argc, char *argv[]) { enum { OPT_STRICT = UCHAR_MAX + 1, + OPT_READD, 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}, + {"readd", no_argument, NULL, OPT_READD}, + {"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}, + {NULL, 0, NULL, 0}, }; char *short_options = long_options_to_short_options(long_options); @@ -132,13 +138,17 @@ parse_options(int argc, char *argv[]) usage(); case 'V': - OVS_PRINT_VERSION(OFP_VERSION, OFP_VERSION); + ovs_print_version(OFP_VERSION, OFP_VERSION); exit(EXIT_SUCCESS); case OPT_STRICT: strict = true; break; + case OPT_READD: + readd = true; + break; + VLOG_OPTION_HANDLERS STREAM_SSL_OPTION_HANDLERS @@ -172,6 +182,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" @@ -183,6 +194,7 @@ usage(void) vlog_usage(); printf("\nOther options:\n" " --strict use strict match for flow commands\n" + " --readd replace flows that haven't changed\n" " -F, --flow-format=FORMAT force particular flow format\n" " -m, --more be more verbose printing OpenFlow\n" " -t, --timeout=SECS give up after SECS seconds\n" @@ -232,7 +244,7 @@ open_vconn__(const char *name, const char *default_suffix, free(datapath_name); free(datapath_type); - if (strstr(name, ":")) { + if (strchr(name, ':')) { run(vconn_open_block(name, OFP_VERSION, vconnp), "connecting to %s", name); } else if (!stat(name, &s) && S_ISSOCK(s.st_mode)) { @@ -246,7 +258,7 @@ open_vconn__(const char *name, const char *default_suffix, } open_vconn_socket(socket_name, vconnp); } else { - ovs_fatal(0, "%s is not a valid connection method", name); + ovs_fatal(0, "%s is not a bridge or a socket", name); } free(bridge_path); @@ -260,14 +272,14 @@ open_vconn(const char *name, struct vconn **vconnp) } static void * -alloc_stats_request(size_t body_len, uint16_t type, struct ofpbuf **bufferp) +alloc_stats_request(size_t rq_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(rq_len, OFPT_STATS_REQUEST, bufferp); rq->type = htons(type); rq->flags = htons(0); - return rq->body; + return rq; } static void @@ -314,12 +326,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); @@ -333,7 +345,7 @@ static void dump_trivial_stats_transaction(const char *vconn_name, uint8_t stats_type) { struct ofpbuf *request; - alloc_stats_request(0, stats_type, &request); + alloc_stats_request(sizeof(struct ofp_stats_msg), stats_type, &request); dump_stats_transaction(vconn_name, request); } @@ -522,7 +534,7 @@ static void do_dump_flows__(int argc, char *argv[], bool aggregate) { enum nx_flow_format min_flow_format, flow_format; - struct flow_stats_request fsr; + struct ofputil_flow_stats_request fsr; struct ofpbuf *request; struct vconn *vconn; @@ -658,7 +670,7 @@ do_flow_mod__(int argc, char *argv[], uint16_t command) flow_mod_table_id = false; parse_ofp_flow_mod_str(&requests, &flow_format, &flow_mod_table_id, - argc > 2 ? argv[2] : "", command); + argc > 2 ? argv[2] : "", command, false); check_final_format_for_flow_mod(flow_format); open_vconn(argv[1], &vconn); @@ -951,8 +963,7 @@ fte_version_print(const struct fte_version *version) } ds_init(&s); - ofp_print_actions(&s, (const struct ofp_action_header *) version->actions, - version->n_actions * sizeof *version->actions); + ofp_print_actions(&s, version->actions, version->n_actions); printf(" %s\n", ds_cstr(&s)); ds_destroy(&s); } @@ -1030,20 +1041,18 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index) min_flow_format = NXFF_OPENFLOW10; while (!ds_get_preprocessed_line(&s, file)) { struct fte_version *version; + struct ofputil_flow_mod fm; enum nx_flow_format min_ff; - struct ofpbuf actions; - struct flow_mod fm; - ofpbuf_init(&actions, 64); - parse_ofp_str(&fm, &actions, ds_cstr(&s)); + parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), true); version = xmalloc(sizeof *version); version->cookie = fm.cookie; version->idle_timeout = fm.idle_timeout; version->hard_timeout = fm.hard_timeout; version->flags = fm.flags & (OFPFF_SEND_FLOW_REM | OFPFF_EMERG); - version->n_actions = actions.size / sizeof *version->actions; - version->actions = ofpbuf_steal_data(&actions); + version->actions = fm.actions; + version->n_actions = fm.n_actions; min_ff = ofputil_min_flow_format(&fm.cr); min_flow_format = MAX(min_flow_format, min_ff); @@ -1067,7 +1076,7 @@ static void read_flows_from_switch(struct vconn *vconn, enum nx_flow_format flow_format, struct classifier *cls, int index) { - struct flow_stats_request fsr; + struct ofputil_flow_stats_request fsr; struct ofpbuf *request; ovs_be32 send_xid; bool done; @@ -1089,7 +1098,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); @@ -1101,8 +1110,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; } @@ -1143,7 +1152,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, enum nx_flow_format flow_format, struct list *packets) { const struct fte_version *version = fte->versions[index]; - struct flow_mod fm; + struct ofputil_flow_mod fm; struct ofpbuf *ofm; fm.cr = fte->rule; @@ -1207,7 +1216,8 @@ do_replace_flows(int argc OVS_UNUSED, char *argv[]) struct fte_version *file_ver = fte->versions[FILE_IDX]; struct fte_version *sw_ver = fte->versions[SWITCH_IDX]; - if (file_ver && (!sw_ver || !fte_version_equals(sw_ver, file_ver))) { + if (file_ver + && (readd || !sw_ver || !fte_version_equals(sw_ver, file_ver))) { fte_make_flow_mod(fte, FILE_IDX, OFPFC_ADD, flow_format, &requests); } @@ -1308,7 +1318,7 @@ do_parse_flow(int argc OVS_UNUSED, char *argv[]) list_init(&packets); parse_ofp_flow_mod_str(&packets, &flow_format, &flow_mod_table_id, - argv[1], OFPFC_ADD); + argv[1], OFPFC_ADD, false); print_packet_list(&packets); } @@ -1390,7 +1400,8 @@ do_parse_nx_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) puts(out); free(out); } else { - printf("nx_pull_match() returned error %x\n", error); + printf("nx_pull_match() returned error %x (%s)\n", error, + ofputil_error_to_string(error)); } ofpbuf_uninit(&nx_match);