X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=tests%2Ftest-odp.c;h=30cdbbf2eab77ad54a1b94d601441db58fbcc80e;hb=c5cf10598f8c9f4428291e9df3ecd72a05fb1ccf;hp=29732eb58baf77863142f90d7bfcfab11b755d82;hpb=06d7ae7d9ba1c09c3ce5ad805a89ea564449795d;p=sliver-openvswitch.git diff --git a/tests/test-odp.c b/tests/test-odp.c index 29732eb58..30cdbbf2e 100644 --- a/tests/test-odp.c +++ b/tests/test-odp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Nicira, Inc. + * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,66 +20,222 @@ #include "dynamic-string.h" #include "flow.h" +#include "match.h" #include "odp-util.h" +#include "ofp-parse.h" #include "ofpbuf.h" +#include "util.h" #include "vlog.h" +#include "ovstest.h" -int -main(void) +static int +parse_keys(bool wc_keys) { + int exit_code = 0; struct ds in; ds_init(&in); - vlog_set_levels_from_string("odp_util:console:dbg"); + vlog_set_levels_from_string_assert("odp_util:console:dbg"); while (!ds_get_test_line(&in, stdin)) { enum odp_key_fitness fitness; struct ofpbuf odp_key; + struct ofpbuf odp_mask; struct flow flow; struct ds out; int error; /* Convert string to OVS DP key. */ ofpbuf_init(&odp_key, 0); - error = odp_flow_key_from_string(ds_cstr(&in), NULL, &odp_key); + ofpbuf_init(&odp_mask, 0); + error = odp_flow_from_string(ds_cstr(&in), NULL, + &odp_key, &odp_mask); if (error) { - printf("odp_flow_key_from_string: error\n"); + printf("odp_flow_from_string: error\n"); goto next; } - /* Convert odp_key to flow. */ - fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow); - switch (fitness) { - case ODP_FIT_PERFECT: - break; + if (!wc_keys) { + /* Convert odp_key to flow. */ + fitness = odp_flow_key_to_flow(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), &flow); + switch (fitness) { + case ODP_FIT_PERFECT: + break; - case ODP_FIT_TOO_LITTLE: - printf("ODP_FIT_TOO_LITTLE: "); - break; + case ODP_FIT_TOO_LITTLE: + printf("ODP_FIT_TOO_LITTLE: "); + break; - case ODP_FIT_TOO_MUCH: - printf("ODP_FIT_TOO_MUCH: "); - break; + case ODP_FIT_TOO_MUCH: + printf("ODP_FIT_TOO_MUCH: "); + break; - case ODP_FIT_ERROR: - printf("odp_flow_key_to_flow: error\n"); - goto next; + case ODP_FIT_ERROR: + printf("odp_flow_key_to_flow: error\n"); + goto next; + } + /* Convert cls_rule back to odp_key. */ + ofpbuf_uninit(&odp_key); + ofpbuf_init(&odp_key, 0); + odp_flow_key_from_flow(&odp_key, &flow, NULL, + flow.in_port.odp_port); + + if (ofpbuf_size(&odp_key) > ODPUTIL_FLOW_KEY_BYTES) { + printf ("too long: %"PRIu32" > %d\n", + ofpbuf_size(&odp_key), ODPUTIL_FLOW_KEY_BYTES); + exit_code = 1; + } } - /* Convert cls_rule back to odp_key. */ + /* Convert odp_key to string. */ + ds_init(&out); + if (wc_keys) { + odp_flow_format(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), + ofpbuf_data(&odp_mask), ofpbuf_size(&odp_mask), NULL, &out, false); + } else { + odp_flow_key_format(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), &out); + } + puts(ds_cstr(&out)); + ds_destroy(&out); + + next: ofpbuf_uninit(&odp_key); + } + ds_destroy(&in); + + return exit_code; +} + +static int +parse_actions(void) +{ + struct ds in; + + ds_init(&in); + vlog_set_levels_from_string_assert("odp_util:console:dbg"); + while (!ds_get_test_line(&in, stdin)) { + struct ofpbuf odp_actions; + struct ds out; + int error; + + /* Convert string to OVS DP actions. */ + ofpbuf_init(&odp_actions, 0); + error = odp_actions_from_string(ds_cstr(&in), NULL, &odp_actions); + if (error) { + printf("odp_actions_from_string: error\n"); + goto next; + } + + /* Convert odp_actions back to string. */ + ds_init(&out); + format_odp_actions(&out, ofpbuf_data(&odp_actions), ofpbuf_size(&odp_actions)); + puts(ds_cstr(&out)); + ds_destroy(&out); + + next: + ofpbuf_uninit(&odp_actions); + } + ds_destroy(&in); + + return 0; +} + +static int +parse_filter(char *filter_parse) +{ + struct ds in; + struct flow flow_filter; + struct flow_wildcards wc_filter; + char *error, *filter = NULL; + + vlog_set_levels_from_string_assert("odp_util:console:dbg"); + if (filter_parse && !strncmp(filter_parse, "filter=", 7)) { + filter = strdup(filter_parse+7); + memset(&flow_filter, 0, sizeof(flow_filter)); + memset(&wc_filter, 0, sizeof(wc_filter)); + + error = parse_ofp_exact_flow(&flow_filter, &wc_filter.masks, filter, + NULL); + if (error) { + ovs_fatal(0, "Failed to parse filter (%s)", error); + } + } else { + ovs_fatal(0, "No filter to parse."); + } + + ds_init(&in); + while (!ds_get_test_line(&in, stdin)) { + struct ofpbuf odp_key; + struct ofpbuf odp_mask; + struct ds out; + int error; + + /* Convert string to OVS DP key. */ ofpbuf_init(&odp_key, 0); - odp_flow_key_from_flow(&odp_key, &flow); + ofpbuf_init(&odp_mask, 0); + error = odp_flow_from_string(ds_cstr(&in), NULL, + &odp_key, &odp_mask); + if (error) { + printf("odp_flow_from_string: error\n"); + goto next; + } + + if (filter) { + struct flow flow; + struct flow_wildcards wc; + struct match match, match_filter; + struct minimatch minimatch; + + odp_flow_key_to_flow(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), &flow); + odp_flow_key_to_mask(ofpbuf_data(&odp_mask), ofpbuf_size(&odp_mask), &wc.masks, + &flow); + match_init(&match, &flow, &wc); + + match_init(&match_filter, &flow_filter, &wc); + match_init(&match_filter, &match_filter.flow, &wc_filter); + minimatch_init(&minimatch, &match_filter); + if (!minimatch_matches_flow(&minimatch, &match.flow)) { + minimatch_destroy(&minimatch); + goto next; + } + minimatch_destroy(&minimatch); + } /* Convert odp_key to string. */ ds_init(&out); - odp_flow_key_format(odp_key.data, odp_key.size, &out); + odp_flow_format(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), + ofpbuf_data(&odp_mask), ofpbuf_size(&odp_mask), NULL, &out, false); puts(ds_cstr(&out)); ds_destroy(&out); next: ofpbuf_uninit(&odp_key); + ofpbuf_uninit(&odp_mask); } ds_destroy(&in); + free(filter); return 0; } + +static void +test_odp_main(int argc, char *argv[]) +{ + int exit_code = 0; + + set_program_name(argv[0]); + if (argc == 2 &&!strcmp(argv[1], "parse-keys")) { + exit_code =parse_keys(false); + } else if (argc == 2 &&!strcmp(argv[1], "parse-wc-keys")) { + exit_code =parse_keys(true); + } else if (argc == 2 && !strcmp(argv[1], "parse-actions")) { + exit_code = parse_actions(); + } else if (argc == 3 && !strcmp(argv[1], "parse-filter")) { + exit_code =parse_filter(argv[2]); + } else { + ovs_fatal(0, "usage: %s parse-keys | parse-wc-keys | parse-actions", argv[0]); + } + + exit(exit_code); +} + +OVSTEST_REGISTER("test-odp", test_odp_main);