~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to utilities/ovs-ofctl.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
98
98
static struct sort_criterion *criteria;
99
99
static size_t n_criteria, allocated_criteria;
100
100
 
101
 
static const struct command all_commands[];
 
101
static const struct command *get_all_commands(void);
102
102
 
103
103
static void usage(void) NO_RETURN;
104
104
static void parse_options(int argc, char *argv[]);
113
113
    set_program_name(argv[0]);
114
114
    parse_options(argc, argv);
115
115
    signal(SIGPIPE, SIG_IGN);
116
 
    run_command(argc - optind, argv + optind, all_commands);
 
116
    run_command(argc - optind, argv + optind, get_all_commands());
117
117
    return 0;
118
118
}
119
119
 
151
151
        OFP_VERSION_OPTION_ENUMS,
152
152
        VLOG_OPTION_ENUMS
153
153
    };
154
 
    static struct option long_options[] = {
 
154
    static const struct option long_options[] = {
155
155
        {"timeout", required_argument, NULL, 't'},
156
156
        {"strict", no_argument, NULL, OPT_STRICT},
157
157
        {"readd", no_argument, NULL, OPT_READD},
361
361
                       vconnp);
362
362
    if (error && error != ENOENT) {
363
363
        ovs_fatal(0, "%s: failed to open socket (%s)", name,
364
 
                  strerror(error));
 
364
                  ovs_strerror(error));
365
365
    }
366
366
    free(vconn_name);
367
367
 
412
412
    error = vconn_connect_block(*vconnp);
413
413
    if (error) {
414
414
        ovs_fatal(0, "%s: failed to connect to socket (%s)", name,
415
 
                  strerror(error));
 
415
                  ovs_strerror(error));
416
416
    }
417
417
 
418
418
    ofp_version = vconn_get_version(*vconnp);
516
516
    vconn_close(vconn);
517
517
}
518
518
 
519
 
/* Sends 'request', which should be a request that only has a reply if an error
520
 
 * occurs, and waits for it to succeed or fail.  If an error does occur, prints
521
 
 * it and exits with an error.
 
519
/* Sends all of the 'requests', which should be requests that only have replies
 
520
 * if an error occurs, and waits for them to succeed or fail.  If an error does
 
521
 * occur, prints it and exits with an error.
522
522
 *
523
523
 * Destroys all of the 'requests'. */
524
524
static void
632
632
 
633
633
static bool
634
634
fetch_port_by_features(const char *vconn_name,
635
 
                       const char *port_name, unsigned int port_no,
 
635
                       const char *port_name, ofp_port_t port_no,
636
636
                       struct ofputil_phy_port *pp, bool *trunc)
637
637
{
638
638
    struct ofputil_switch_features features;
670
670
    }
671
671
 
672
672
    while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
673
 
        if (port_no != UINT_MAX
 
673
        if (port_no != OFPP_NONE
674
674
            ? port_no == pp->port_no
675
675
            : !strcmp(pp->name, port_name)) {
676
676
            found = true;
685
685
 
686
686
static bool
687
687
fetch_port_by_stats(const char *vconn_name,
688
 
                    const char *port_name, unsigned int port_no,
 
688
                    const char *port_name, ofp_port_t port_no,
689
689
                    struct ofputil_phy_port *pp)
690
690
{
691
691
    struct ofpbuf *request;
729
729
            }
730
730
 
731
731
            while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
732
 
                if (port_no != UINT_MAX ? port_no == pp->port_no
733
 
                                        : !strcmp(pp->name, port_name)) {
 
732
                if (port_no != OFPP_NONE ? port_no == pp->port_no
 
733
                                         : !strcmp(pp->name, port_name)) {
734
734
                    found = true;
735
735
                    break;
736
736
                }
746
746
    return found;
747
747
}
748
748
 
 
749
static bool
 
750
str_to_ofp(const char *s, ofp_port_t *ofp_port)
 
751
{
 
752
    bool ret;
 
753
    uint32_t port_;
 
754
 
 
755
    ret = str_to_uint(s, 10, &port_);
 
756
    *ofp_port = u16_to_ofp(port_);
 
757
    return ret;
 
758
}
749
759
 
750
760
/* Opens a connection to 'vconn_name', fetches the port structure for
751
761
 * 'port_name' (which may be a port name or number), and copies it into
754
764
fetch_ofputil_phy_port(const char *vconn_name, const char *port_name,
755
765
                       struct ofputil_phy_port *pp)
756
766
{
757
 
    unsigned int port_no;
 
767
    ofp_port_t port_no;
758
768
    bool found;
759
769
    bool trunc;
760
770
 
761
771
    /* Try to interpret the argument as a port number. */
762
 
    if (!str_to_uint(port_name, 10, &port_no)) {
763
 
        port_no = UINT_MAX;
 
772
    if (!str_to_ofp(port_name, &port_no)) {
 
773
        port_no = OFPP_NONE;
764
774
    }
765
775
 
766
776
    /* Try to find the port based on the Features Reply.  If it looks
779
789
 
780
790
/* Returns the port number corresponding to 'port_name' (which may be a port
781
791
 * name or number) within the switch 'vconn_name'. */
782
 
static uint16_t
 
792
static ofp_port_t
783
793
str_to_port_no(const char *vconn_name, const char *port_name)
784
794
{
785
 
    uint16_t port_no;
 
795
    ofp_port_t port_no;
786
796
 
787
797
    if (ofputil_port_from_string(port_name, &port_no)) {
788
798
        return port_no;
856
866
    enum ofputil_protocol usable_protocols, protocol;
857
867
    struct ofputil_flow_stats_request fsr;
858
868
    struct vconn *vconn;
859
 
 
860
 
    parse_ofp_flow_stats_request_str(&fsr, aggregate, argc > 2 ? argv[2] : "");
 
869
    char *error;
 
870
 
 
871
    error = parse_ofp_flow_stats_request_str(&fsr, aggregate,
 
872
                                             argc > 2 ? argv[2] : "");
 
873
    if (error) {
 
874
        ovs_fatal(0, "%s", error);
 
875
    }
 
876
 
861
877
    usable_protocols = ofputil_flow_stats_request_usable_protocols(&fsr);
862
878
 
863
879
    protocol = open_vconn(argv[1], &vconn);
1077
1093
{
1078
1094
    struct ofputil_flow_mod *fms = NULL;
1079
1095
    size_t n_fms = 0;
 
1096
    char *error;
1080
1097
 
1081
 
    parse_ofp_flow_mod_file(argv[2], command, &fms, &n_fms);
 
1098
    error = parse_ofp_flow_mod_file(argv[2], command, &fms, &n_fms);
 
1099
    if (error) {
 
1100
        ovs_fatal(0, "%s", error);
 
1101
    }
1082
1102
    ofctl_flow_mod__(argv[1], fms, n_fms);
1083
1103
    free(fms);
1084
1104
}
1090
1110
        ofctl_flow_mod_file(argc, argv, command);
1091
1111
    } else {
1092
1112
        struct ofputil_flow_mod fm;
1093
 
        parse_ofp_flow_mod_str(&fm, argc > 2 ? argv[2] : "", command, false);
 
1113
        char *error;
 
1114
 
 
1115
        error = parse_ofp_flow_mod_str(&fm, argc > 2 ? argv[2] : "", command);
 
1116
        if (error) {
 
1117
            ovs_fatal(0, "%s", error);
 
1118
        }
1094
1119
        ofctl_flow_mod__(argv[1], &fm, 1);
1095
1120
    }
1096
1121
}
1223
1248
        error = vconn_send_block(vconn, msg);
1224
1249
        if (error) {
1225
1250
            ofpbuf_delete(msg);
1226
 
            ds_put_format(&reply, "%s\n", strerror(error));
 
1251
            ds_put_format(&reply, "%s\n", ovs_strerror(error));
1227
1252
            ok = false;
1228
1253
        } else {
1229
1254
            ds_put_cstr(&reply, "sent\n");
1260
1285
    error = vconn_send_block(aux->vconn, msg);
1261
1286
    if (error) {
1262
1287
        ofpbuf_delete(msg);
1263
 
        unixctl_command_reply_error(conn, strerror(error));
 
1288
        unixctl_command_reply_error(conn, ovs_strerror(error));
1264
1289
    } else {
1265
1290
        aux->conn = conn;
1266
1291
    }
1274
1299
 
1275
1300
    fd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0666);
1276
1301
    if (fd < 0) {
1277
 
        unixctl_command_reply_error(conn, strerror(errno));
 
1302
        unixctl_command_reply_error(conn, ovs_strerror(errno));
1278
1303
        return;
1279
1304
    }
1280
1305
 
1312
1337
    }
1313
1338
}
1314
1339
 
 
1340
/* Prints to stdout all of the messages received on 'vconn'.
 
1341
 *
 
1342
 * Iff 'reply_to_echo_requests' is true, sends a reply to any echo request
 
1343
 * received on 'vconn'. */
1315
1344
static void
1316
 
monitor_vconn(struct vconn *vconn)
 
1345
monitor_vconn(struct vconn *vconn, bool reply_to_echo_requests)
1317
1346
{
1318
1347
    struct barrier_aux barrier_aux = { vconn, NULL };
1319
1348
    struct unixctl_server *server;
1357
1386
            run(retval, "vconn_recv");
1358
1387
 
1359
1388
            if (timestamp) {
1360
 
                time_t now = time_wall();
1361
 
                char s[32];
1362
 
 
1363
 
                strftime(s, sizeof s, "%Y-%m-%d %H:%M:%S: ", gmtime(&now));
 
1389
                char *s = xastrftime("%Y-%m-%d %H:%M:%S: ", time_wall(), true);
1364
1390
                fputs(s, stderr);
 
1391
                free(s);
1365
1392
            }
1366
1393
 
1367
1394
            ofptype_decode(&type, b->data);
1368
1395
            ofp_print(stderr, b->data, b->size, verbosity + 2);
 
1396
 
 
1397
            switch ((int) type) {
 
1398
            case OFPTYPE_BARRIER_REPLY:
 
1399
                if (barrier_aux.conn) {
 
1400
                    unixctl_command_reply(barrier_aux.conn, NULL);
 
1401
                    barrier_aux.conn = NULL;
 
1402
                }
 
1403
                break;
 
1404
 
 
1405
            case OFPTYPE_ECHO_REQUEST:
 
1406
                if (reply_to_echo_requests) {
 
1407
                    struct ofpbuf *reply;
 
1408
 
 
1409
                    reply = make_echo_reply(b->data);
 
1410
                    retval = vconn_send_block(vconn, reply);
 
1411
                    if (retval) {
 
1412
                        ovs_fatal(retval, "failed to send echo reply");
 
1413
                    }
 
1414
                }
 
1415
                break;
 
1416
            }
1369
1417
            ofpbuf_delete(b);
1370
 
 
1371
 
            if (barrier_aux.conn && type == OFPTYPE_BARRIER_REPLY) {
1372
 
                unixctl_command_reply(barrier_aux.conn, NULL);
1373
 
                barrier_aux.conn = NULL;
1374
 
            }
1375
1418
        }
1376
1419
 
1377
1420
        if (exiting) {
1411
1454
        } else if (!strncmp(arg, "watch:", 6)) {
1412
1455
            struct ofputil_flow_monitor_request fmr;
1413
1456
            struct ofpbuf *msg;
 
1457
            char *error;
1414
1458
 
1415
 
            parse_flow_monitor_request(&fmr, arg + 6);
 
1459
            error = parse_flow_monitor_request(&fmr, arg + 6);
 
1460
            if (error) {
 
1461
                ovs_fatal(0, "%s", error);
 
1462
            }
1416
1463
 
1417
1464
            msg = ofpbuf_new(0);
1418
1465
            ofputil_append_flow_monitor_request(&fmr, msg);
1454
1501
        }
1455
1502
    }
1456
1503
 
1457
 
    monitor_vconn(vconn);
 
1504
    monitor_vconn(vconn, true);
1458
1505
}
1459
1506
 
1460
1507
static void
1463
1510
    struct vconn *vconn;
1464
1511
 
1465
1512
    open_vconn__(argv[1], SNOOP, &vconn);
1466
 
    monitor_vconn(vconn);
 
1513
    monitor_vconn(vconn, false);
1467
1514
}
1468
1515
 
1469
1516
static void
1471
1518
{
1472
1519
    struct ofpbuf *request;
1473
1520
    struct vconn *vconn;
1474
 
    uint16_t port;
 
1521
    ofp_port_t port;
1475
1522
 
1476
1523
    open_vconn(argv[1], &vconn);
1477
1524
    port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_ANY;
1510
1557
    struct ofputil_packet_out po;
1511
1558
    struct ofpbuf ofpacts;
1512
1559
    struct vconn *vconn;
 
1560
    char *error;
1513
1561
    int i;
1514
1562
 
1515
1563
    ofpbuf_init(&ofpacts, 64);
1516
 
    parse_ofpacts(argv[3], &ofpacts);
 
1564
    error = parse_ofpacts(argv[3], &ofpacts);
 
1565
    if (error) {
 
1566
        ovs_fatal(0, "%s", error);
 
1567
    }
1517
1568
 
1518
1569
    po.buffer_id = UINT32_MAX;
1519
1570
    po.in_port = str_to_port_no(argv[1], argv[2]);
1877
1928
read_flows_from_file(const char *filename, struct classifier *cls, int index)
1878
1929
{
1879
1930
    enum ofputil_protocol usable_protocols;
 
1931
    int line_number;
1880
1932
    struct ds s;
1881
1933
    FILE *file;
1882
1934
 
1887
1939
 
1888
1940
    ds_init(&s);
1889
1941
    usable_protocols = OFPUTIL_P_ANY;
1890
 
    while (!ds_get_preprocessed_line(&s, file)) {
 
1942
    line_number = 0;
 
1943
    while (!ds_get_preprocessed_line(&s, file, &line_number)) {
1891
1944
        struct fte_version *version;
1892
1945
        struct ofputil_flow_mod fm;
 
1946
        char *error;
1893
1947
 
1894
 
        parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), true);
 
1948
        error = parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s));
 
1949
        if (error) {
 
1950
            ovs_fatal(0, "%s:%d: %s", filename, line_number, error);
 
1951
        }
1895
1952
 
1896
1953
        version = xmalloc(sizeof *version);
1897
1954
        version->cookie = fm.new_cookie;
2022
2079
    fm.cookie = htonll(0);
2023
2080
    fm.cookie_mask = htonll(0);
2024
2081
    fm.new_cookie = version->cookie;
 
2082
    fm.modify_cookie = true;
2025
2083
    fm.table_id = 0xff;
2026
2084
    fm.command = command;
2027
2085
    fm.idle_timeout = version->idle_timeout;
2204
2262
ofctl_parse_flow(int argc OVS_UNUSED, char *argv[])
2205
2263
{
2206
2264
    struct ofputil_flow_mod fm;
 
2265
    char *error;
2207
2266
 
2208
 
    parse_ofp_flow_mod_str(&fm, argv[1], OFPFC_ADD, false);
 
2267
    error = parse_ofp_flow_mod_str(&fm, argv[1], OFPFC_ADD);
 
2268
    if (error) {
 
2269
        ovs_fatal(0, "%s", error);
 
2270
    }
2209
2271
    ofctl_parse_flows__(&fm, 1);
2210
2272
}
2211
2273
 
2216
2278
{
2217
2279
    struct ofputil_flow_mod *fms = NULL;
2218
2280
    size_t n_fms = 0;
 
2281
    char *error;
2219
2282
 
2220
 
    parse_ofp_flow_mod_file(argv[1], OFPFC_ADD, &fms, &n_fms);
 
2283
    error = parse_ofp_flow_mod_file(argv[1], OFPFC_ADD, &fms, &n_fms);
 
2284
    if (error) {
 
2285
        ovs_fatal(0, "%s", error);
 
2286
    }
2221
2287
    ofctl_parse_flows__(fms, n_fms);
2222
2288
    free(fms);
2223
2289
}
2269
2335
            ofpbuf_init(&nx_match, 0);
2270
2336
            if (oxm) {
2271
2337
                match_len = oxm_put_match(&nx_match, &match);
2272
 
                out = oxm_match_to_string(nx_match.data, match_len);
 
2338
                out = oxm_match_to_string(&nx_match, match_len);
2273
2339
            } else {
2274
2340
                match_len = nx_put_match(&nx_match, &match,
2275
2341
                                         cookie, cookie_mask);
2339
2405
    struct ds in;
2340
2406
 
2341
2407
    ds_init(&in);
2342
 
    while (!ds_get_preprocessed_line(&in, stdin)) {
 
2408
    while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
2343
2409
        struct ofpbuf of10_out;
2344
2410
        struct ofpbuf of10_in;
2345
2411
        struct ofpbuf ofpacts;
2403
2469
 
2404
2470
    ds_init(&in);
2405
2471
    ds_init(&expout);
2406
 
    while (!ds_get_preprocessed_line(&in, stdin)) {
 
2472
    while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
2407
2473
        struct ofpbuf match_in, match_expout;
2408
2474
        struct ofp10_match match_out;
2409
2475
        struct ofp10_match match_normal;
2475
2541
    struct ds in;
2476
2542
 
2477
2543
    ds_init(&in);
2478
 
    while (!ds_get_preprocessed_line(&in, stdin)) {
 
2544
    while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
2479
2545
        struct ofpbuf match_in;
2480
2546
        struct ofp11_match match_out;
2481
2547
        struct match match;
2524
2590
    struct ds in;
2525
2591
 
2526
2592
    ds_init(&in);
2527
 
    while (!ds_get_preprocessed_line(&in, stdin)) {
 
2593
    while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
2528
2594
        struct ofpbuf of11_out;
2529
2595
        struct ofpbuf of11_in;
2530
2596
        struct ofpbuf ofpacts;
2582
2648
    struct ds in;
2583
2649
 
2584
2650
    ds_init(&in);
2585
 
    while (!ds_get_preprocessed_line(&in, stdin)) {
 
2651
    while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
2586
2652
        struct ofpbuf of11_out;
2587
2653
        struct ofpbuf of11_in;
2588
2654
        struct ofpbuf ofpacts;
2589
2655
        enum ofperr error;
2590
2656
        size_t size;
2591
2657
        struct ds s;
 
2658
        const char *table_id;
 
2659
        char *instructions;
 
2660
 
 
2661
        /* Parse table_id separated with the follow-up instructions by ",", if
 
2662
         * any. */
 
2663
        instructions = ds_cstr(&in);
 
2664
        table_id = NULL;
 
2665
        if (strstr(instructions, ",")) {
 
2666
            table_id = strsep(&instructions, ",");
 
2667
        }
2592
2668
 
2593
2669
        /* Parse hex bytes. */
2594
2670
        ofpbuf_init(&of11_in, 0);
2595
 
        if (ofpbuf_put_hex(&of11_in, ds_cstr(&in), NULL)[0] != '\0') {
 
2671
        if (ofpbuf_put_hex(&of11_in, instructions, NULL)[0] != '\0') {
2596
2672
            ovs_fatal(0, "Trailing garbage in hex data");
2597
2673
        }
2598
2674
 
2601
2677
        size = of11_in.size;
2602
2678
        error = ofpacts_pull_openflow11_instructions(&of11_in, of11_in.size,
2603
2679
                                                     &ofpacts);
 
2680
        if (!error) {
 
2681
            /* Verify actions. */
 
2682
            struct flow flow;
 
2683
            memset(&flow, 0, sizeof flow);
 
2684
            error = ofpacts_check(ofpacts.data, ofpacts.size, &flow, OFPP_MAX,
 
2685
                                  table_id ? atoi(table_id) : 0);
 
2686
        }
2604
2687
        if (error) {
2605
2688
            printf("bad OF1.1 instructions: %s\n\n", ofperr_get_name(error));
2606
2689
            ofpbuf_uninit(&ofpacts);
2654
2737
    struct match of11_match;
2655
2738
 
2656
2739
    enum ofperr error;
 
2740
    char *error_s;
2657
2741
 
2658
2742
    match_init_catchall(&match);
2659
2743
    match.flow.vlan_tci = htons(strtoul(argv[1], NULL, 16));
2663
2747
    string_s = match_to_string(&match, OFP_DEFAULT_PRIORITY);
2664
2748
    printf("%s -> ", string_s);
2665
2749
    fflush(stdout);
2666
 
    parse_ofp_str(&fm, -1, string_s, false);
 
2750
    error_s = parse_ofp_str(&fm, -1, string_s);
 
2751
    if (error_s) {
 
2752
        ovs_fatal(0, "%s", error_s);
 
2753
    }
2667
2754
    printf("%04"PRIx16"/%04"PRIx16"\n",
2668
2755
           ntohs(fm.match.flow.vlan_tci),
2669
2756
           ntohs(fm.match.wc.masks.vlan_tci));
2688
2775
    /* Convert to and from OXM. */
2689
2776
    ofpbuf_init(&nxm, 0);
2690
2777
    nxm_match_len = oxm_put_match(&nxm, &match);
2691
 
    nxm_s = oxm_match_to_string(nxm.data, nxm_match_len);
 
2778
    nxm_s = oxm_match_to_string(&nxm, nxm_match_len);
2692
2779
    error = oxm_pull_match(&nxm, &nxm_match);
2693
2780
    printf("OXM: %s -> ", nxm_s);
2694
2781
    if (error) {
2747
2834
 
2748
2835
    for (version = 0; version <= UINT8_MAX; version++) {
2749
2836
        const char *name = ofperr_domain_get_name(version);
2750
 
        if (!name) {
2751
 
            continue;
 
2837
        if (name) {
 
2838
            int vendor = ofperr_get_vendor(error, version);
 
2839
            int type = ofperr_get_type(error, version);
 
2840
            int code = ofperr_get_code(error, version);
 
2841
 
 
2842
            if (vendor != -1 || type != -1 || code != -1) {
 
2843
                printf("%s: vendor %#x, type %d, code %d\n",
 
2844
                       name, vendor, type, code);
 
2845
            }
2752
2846
        }
2753
 
        printf("%s: %d,%d\n",
2754
 
               ofperr_domain_get_name(version),
2755
 
               ofperr_get_type(error, version),
2756
 
               ofperr_get_code(error, version));
2757
2847
    }
2758
2848
}
2759
2849
 
2866
2956
 
2867
2957
    { NULL, 0, 0, NULL },
2868
2958
};
 
2959
 
 
2960
static const struct command *get_all_commands(void)
 
2961
{
 
2962
    return all_commands;
 
2963
}