X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=1901e242a2369c47fb4c59744a99d7487c50159b;hb=cd10ed7fb4fb5b1e3ed8e3fae1fd115c7ae96e77;hp=cf6a8a305c7280781101530a1c79a9c6ba7b6c07;hpb=10a24935c9d382e4d85b05d9616843f3d3bb4983;p=openvswitch diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index cf6a8a30..1901e242 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -27,11 +27,14 @@ #include #include "byte-order.h" +#include "classifier.h" #include "command-line.h" #include "compiler.h" #include "dirs.h" #include "dpif.h" +#include "dynamic-string.h" #include "netlink.h" +#include "nx-match.h" #include "odp-util.h" #include "ofp-parse.h" #include "ofp-print.h" @@ -46,7 +49,7 @@ #include "vconn.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(ofctl) +VLOG_DEFINE_THIS_MODULE(ofctl); #define MOD_PORT_CMD_UP "up" @@ -354,9 +357,7 @@ do_status(int argc, char *argv[]) struct vconn *vconn; struct ofpbuf *b; - request = make_openflow(sizeof *request, OFPT_VENDOR, &b); - request->vendor = htonl(NX_VENDOR_ID); - request->subtype = htonl(NXT_STATUS_REQUEST); + request = make_nxmsg(sizeof *request, NXT_STATUS_REQUEST, &b); if (argc > 2) { ofpbuf_put(b, argv[2], strlen(argv[2])); update_openflow_length(b); @@ -437,14 +438,15 @@ static void do_dump_flows(int argc, char *argv[]) { struct ofp_flow_stats_request *req; - uint16_t out_port; + struct parsed_flow pf; struct ofpbuf *request; req = alloc_stats_request(sizeof *req, OFPST_FLOW, &request); - parse_ofp_str(argc > 2 ? argv[2] : "", &req->match, NULL, - &req->table_id, &out_port, NULL, NULL, NULL, NULL); + parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : ""); + flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10, + &req->match); memset(&req->pad, 0, sizeof req->pad); - req->out_port = htons(out_port); + req->out_port = htons(pf.out_port); dump_stats_transaction(argv[1], request); } @@ -454,13 +456,14 @@ do_dump_aggregate(int argc, char *argv[]) { struct ofp_aggregate_stats_request *req; struct ofpbuf *request; - uint16_t out_port; + struct parsed_flow pf; req = alloc_stats_request(sizeof *req, OFPST_AGGREGATE, &request); - parse_ofp_str(argc > 2 ? argv[2] : "", &req->match, NULL, - &req->table_id, &out_port, NULL, NULL, NULL, NULL); + parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : ""); + flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10, + &req->match); memset(&req->pad, 0, sizeof req->pad); - req->out_port = htons(out_port); + req->out_port = htons(pf.out_port); dump_stats_transaction(argv[1], request); } @@ -494,26 +497,8 @@ do_add_flow(int argc OVS_UNUSED, char *argv[]) { struct vconn *vconn; struct ofpbuf *buffer; - struct ofp_flow_mod *ofm; - uint16_t priority, idle_timeout, hard_timeout; - uint64_t cookie; - struct ofp_match match; - - /* Parse and send. parse_ofp_str() will expand and reallocate the - * data in 'buffer', so we can't keep pointers to across the - * parse_ofp_str() call. */ - make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer); - parse_ofp_str(argv[2], &match, buffer, - NULL, NULL, &priority, &idle_timeout, &hard_timeout, - &cookie); - ofm = buffer->data; - ofm->match = match; - ofm->command = htons(OFPFC_ADD); - ofm->cookie = htonll(cookie); - ofm->idle_timeout = htons(idle_timeout); - ofm->hard_timeout = htons(hard_timeout); - ofm->buffer_id = htonl(UINT32_MAX); - ofm->priority = htons(priority); + + buffer = parse_ofp_flow_mod_str(argv[2], OFPFC_ADD); open_vconn(argv[1], &vconn); send_openflow_buffer(vconn, buffer); @@ -543,33 +528,12 @@ do_add_flows(int argc OVS_UNUSED, char *argv[]) static void do_mod_flows(int argc OVS_UNUSED, char *argv[]) { - uint16_t priority, idle_timeout, hard_timeout; - uint64_t cookie; struct vconn *vconn; struct ofpbuf *buffer; - struct ofp_flow_mod *ofm; - struct ofp_match match; - - /* Parse and send. parse_ofp_str() will expand and reallocate the - * data in 'buffer', so we can't keep pointers to across the - * parse_ofp_str() call. */ - make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer); - parse_ofp_str(argv[2], &match, buffer, - NULL, NULL, &priority, &idle_timeout, &hard_timeout, - &cookie); - ofm = buffer->data; - ofm->match = match; - if (strict) { - ofm->command = htons(OFPFC_MODIFY_STRICT); - } else { - ofm->command = htons(OFPFC_MODIFY); - } - ofm->idle_timeout = htons(idle_timeout); - ofm->hard_timeout = htons(hard_timeout); - ofm->cookie = htonll(cookie); - ofm->buffer_id = htonl(UINT32_MAX); - ofm->priority = htons(priority); + uint16_t command; + command = strict ? OFPFC_MODIFY_STRICT : OFPFC_MODIFY; + buffer = parse_ofp_flow_mod_str(argv[2], command); open_vconn(argv[1], &vconn); send_openflow_buffer(vconn, buffer); vconn_close(vconn); @@ -578,25 +542,11 @@ do_mod_flows(int argc OVS_UNUSED, char *argv[]) static void do_del_flows(int argc, char *argv[]) { struct vconn *vconn; - uint16_t priority; - uint16_t out_port; struct ofpbuf *buffer; - struct ofp_flow_mod *ofm; - - /* Parse and send. */ - ofm = make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer); - parse_ofp_str(argc > 2 ? argv[2] : "", &ofm->match, NULL, NULL, - &out_port, &priority, NULL, NULL, NULL); - if (strict) { - ofm->command = htons(OFPFC_DELETE_STRICT); - } else { - ofm->command = htons(OFPFC_DELETE); - } - ofm->idle_timeout = htons(0); - ofm->hard_timeout = htons(0); - ofm->buffer_id = htonl(UINT32_MAX); - ofm->out_port = htons(out_port); - ofm->priority = htons(priority); + uint16_t command; + + command = strict ? OFPFC_DELETE_STRICT : OFPFC_DELETE; + buffer = parse_ofp_flow_mod_str(argc > 2 ? argv[2] : "", command); open_vconn(argv[1], &vconn); send_openflow_buffer(vconn, buffer); @@ -610,10 +560,8 @@ do_tun_cookie(int argc OVS_UNUSED, char *argv[]) struct ofpbuf *buffer; struct vconn *vconn; - tun_id_cookie = make_openflow(sizeof *tun_id_cookie, OFPT_VENDOR, &buffer); - - tun_id_cookie->vendor = htonl(NX_VENDOR_ID); - tun_id_cookie->subtype = htonl(NXT_TUN_ID_FROM_COOKIE); + tun_id_cookie = make_nxmsg(sizeof *tun_id_cookie, NXT_TUN_ID_FROM_COOKIE, + &buffer); tun_id_cookie->set = !strcmp(argv[2], "true"); open_vconn(argv[1], &vconn); @@ -859,8 +807,14 @@ do_benchmark(int argc OVS_UNUSED, char *argv[]) count * message_size / (duration / 1000.0)); } -/* This command is really only useful for testing the flow parser (ofp_parse), - * so it is undocumented. */ +static void +do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +{ + usage(); +} + +/* Undocumented commands for unit testing. */ + static void do_parse_flows(int argc OVS_UNUSED, char *argv[]) { @@ -880,9 +834,57 @@ do_parse_flows(int argc OVS_UNUSED, char *argv[]) } static void -do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) -{ - usage(); +do_parse_nx_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +{ + struct ds in; + + ds_init(&in); + while (!ds_get_line(&in, stdin)) { + struct ofpbuf nx_match; + struct cls_rule rule; + int match_len; + int error; + char *s; + + /* Delete comments, skip blank lines. */ + s = ds_cstr(&in); + if (*s == '#') { + puts(s); + continue; + } + if (strchr(s, '#')) { + *strchr(s, '#') = '\0'; + } + if (s[strspn(s, " ")] == '\0') { + putchar('\n'); + continue; + } + + /* Convert string to nx_match. */ + ofpbuf_init(&nx_match, 0); + match_len = nx_match_from_string(ds_cstr(&in), &nx_match); + + /* Convert nx_match to cls_rule. */ + error = nx_pull_match(&nx_match, match_len, 0, &rule); + if (!error) { + char *out; + + /* Convert cls_rule back to nx_match. */ + ofpbuf_uninit(&nx_match); + ofpbuf_init(&nx_match, 0); + match_len = nx_put_match(&nx_match, &rule); + + /* Convert nx_match to string. */ + out = nx_match_to_string(nx_match.data, match_len); + puts(out); + free(out); + } else { + printf("nx_pull_match() returned error %x\n", error); + } + + ofpbuf_uninit(&nx_match); + } + ds_destroy(&in); } static const struct command all_commands[] = { @@ -905,7 +907,11 @@ static const struct command all_commands[] = { { "probe", 1, 1, do_probe }, { "ping", 1, 2, do_ping }, { "benchmark", 3, 3, do_benchmark }, - { "parse-flows", 1, 1, do_parse_flows }, { "help", 0, INT_MAX, do_help }, + + /* Undocumented commands for testing. */ + { "parse-flows", 1, 1, do_parse_flows }, + { "parse-nx-match", 0, 0, do_parse_nx_match }, + { NULL, 0, 0, NULL }, };