X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tests%2Ftest-classifier.c;h=57a1e2c2cc60d2817053df546fb23c217c9e589c;hb=d1b680c61626595b2777f4bf25997a9178acb60c;hp=0307e48f540c39676c5175bf66b96bb9e5651209;hpb=e8b52a913a8fc3d2ef0dae82eda5905668ebfae1;p=openvswitch diff --git a/tests/test-classifier.c b/tests/test-classifier.c index 0307e48f..57a1e2c2 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Nicira Networks. + * Copyright (c) 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,12 +26,11 @@ */ #include -#include #include "classifier.h" #include #include +#include "command-line.h" #include "flow.h" -#include #include "packets.h" #undef NDEBUG @@ -111,7 +110,7 @@ tcls_insert(struct tcls *tcls, const struct test_rule *rule) free(tcls->rules[i]); tcls->rules[i] = xmemdup(rule, sizeof *rule); return tcls->rules[i]; - } else if (pos->priority <= rule->cls_rule.priority) { + } else if (pos->priority < rule->cls_rule.priority) { break; } } @@ -238,8 +237,10 @@ static uint32_t nw_src_values[] = { T_HTONL(0xc0a80001), T_HTONL(0xc0a04455) }; static uint32_t nw_dst_values[] = { T_HTONL(0xc0a80002), T_HTONL(0xc0a04455) }; +static uint32_t tun_id_values[] = { 0, 0xffff0000 }; static uint16_t in_port_values[] = { T_HTONS(1), T_HTONS(OFPP_LOCAL) }; static uint16_t dl_vlan_values[] = { T_HTONS(101), T_HTONS(0) }; +static uint8_t dl_vlan_pcp_values[] = { 7, 0 }; static uint16_t dl_type_values[] = { T_HTONS(ETH_TYPE_IP), T_HTONS(ETH_TYPE_ARP) }; static uint16_t tp_src_values[] = { T_HTONS(49362), T_HTONS(80) }; @@ -249,18 +250,25 @@ static uint8_t dl_src_values[][6] = { { 0x00, 0x02, 0xe3, 0x0f, 0x80, 0xa4 }, static uint8_t dl_dst_values[][6] = { { 0x4a, 0x27, 0x71, 0xae, 0x64, 0xc1 }, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; static uint8_t nw_proto_values[] = { IP_TYPE_TCP, IP_TYPE_ICMP }; +static uint8_t nw_tos_values[] = { 49, 0 }; static void *values[CLS_N_FIELDS][2]; static void init_values(void) { + values[CLS_F_IDX_TUN_ID][0] = &tun_id_values[0]; + values[CLS_F_IDX_TUN_ID][1] = &tun_id_values[1]; + values[CLS_F_IDX_IN_PORT][0] = &in_port_values[0]; values[CLS_F_IDX_IN_PORT][1] = &in_port_values[1]; values[CLS_F_IDX_DL_VLAN][0] = &dl_vlan_values[0]; values[CLS_F_IDX_DL_VLAN][1] = &dl_vlan_values[1]; + values[CLS_F_IDX_DL_VLAN_PCP][0] = &dl_vlan_pcp_values[0]; + values[CLS_F_IDX_DL_VLAN_PCP][1] = &dl_vlan_pcp_values[1]; + values[CLS_F_IDX_DL_SRC][0] = dl_src_values[0]; values[CLS_F_IDX_DL_SRC][1] = dl_src_values[1]; @@ -279,6 +287,9 @@ init_values(void) values[CLS_F_IDX_NW_PROTO][0] = &nw_proto_values[0]; values[CLS_F_IDX_NW_PROTO][1] = &nw_proto_values[1]; + values[CLS_F_IDX_NW_TOS][0] = &nw_tos_values[0]; + values[CLS_F_IDX_NW_TOS][1] = &nw_tos_values[1]; + values[CLS_F_IDX_TP_SRC][0] = &tp_src_values[0]; values[CLS_F_IDX_TP_SRC][1] = &tp_src_values[1]; @@ -288,25 +299,31 @@ init_values(void) #define N_NW_SRC_VALUES ARRAY_SIZE(nw_src_values) #define N_NW_DST_VALUES ARRAY_SIZE(nw_dst_values) +#define N_TUN_ID_VALUES ARRAY_SIZE(tun_id_values) #define N_IN_PORT_VALUES ARRAY_SIZE(in_port_values) #define N_DL_VLAN_VALUES ARRAY_SIZE(dl_vlan_values) +#define N_DL_VLAN_PCP_VALUES ARRAY_SIZE(dl_vlan_pcp_values) #define N_DL_TYPE_VALUES ARRAY_SIZE(dl_type_values) #define N_TP_SRC_VALUES ARRAY_SIZE(tp_src_values) #define N_TP_DST_VALUES ARRAY_SIZE(tp_dst_values) #define N_DL_SRC_VALUES ARRAY_SIZE(dl_src_values) #define N_DL_DST_VALUES ARRAY_SIZE(dl_dst_values) #define N_NW_PROTO_VALUES ARRAY_SIZE(nw_proto_values) +#define N_NW_TOS_VALUES ARRAY_SIZE(nw_tos_values) #define N_FLOW_VALUES (N_NW_SRC_VALUES * \ N_NW_DST_VALUES * \ + N_TUN_ID_VALUES * \ N_IN_PORT_VALUES * \ N_DL_VLAN_VALUES * \ + N_DL_VLAN_PCP_VALUES * \ N_DL_TYPE_VALUES * \ N_TP_SRC_VALUES * \ N_TP_DST_VALUES * \ N_DL_SRC_VALUES * \ N_DL_DST_VALUES * \ - N_NW_PROTO_VALUES) + N_NW_PROTO_VALUES * \ + N_NW_TOS_VALUES) static unsigned int get_value(unsigned int *x, unsigned n_values) @@ -335,21 +352,25 @@ lookup_with_include_bits(const struct classifier *cls, static void compare_classifiers(struct classifier *cls, struct tcls *tcls) { + static const int confidence = 500; unsigned int i; assert(classifier_count(cls) == tcls->n_rules); assert(classifier_count_exact(cls) == tcls_count_exact(tcls)); - for (i = 0; i < N_FLOW_VALUES; i++) { + for (i = 0; i < confidence; i++) { struct cls_rule *cr0, *cr1; flow_t flow; unsigned int x; int include; - x = i; + x = rand () % N_FLOW_VALUES; flow.nw_src = nw_src_values[get_value(&x, N_NW_SRC_VALUES)]; flow.nw_dst = nw_dst_values[get_value(&x, N_NW_DST_VALUES)]; + flow.tun_id = tun_id_values[get_value(&x, N_TUN_ID_VALUES)]; flow.in_port = in_port_values[get_value(&x, N_IN_PORT_VALUES)]; flow.dl_vlan = dl_vlan_values[get_value(&x, N_DL_VLAN_VALUES)]; + flow.dl_vlan_pcp = dl_vlan_pcp_values[get_value(&x, + N_DL_VLAN_PCP_VALUES)]; flow.dl_type = dl_type_values[get_value(&x, N_DL_TYPE_VALUES)]; flow.tp_src = tp_src_values[get_value(&x, N_TP_SRC_VALUES)]; flow.tp_dst = tp_dst_values[get_value(&x, N_TP_DST_VALUES)]; @@ -358,7 +379,8 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls) memcpy(flow.dl_dst, dl_dst_values[get_value(&x, N_DL_DST_VALUES)], ETH_ADDR_LEN); flow.nw_proto = nw_proto_values[get_value(&x, N_NW_PROTO_VALUES)]; - flow.reserved = 0; + flow.nw_tos = nw_tos_values[get_value(&x, N_NW_TOS_VALUES)]; + memset(flow.reserved, 0, sizeof flow.reserved); for (include = 1; include <= 3; include++) { cr0 = lookup_with_include_bits(cls, &flow, include); @@ -446,9 +468,9 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) } } - rule = xcalloc(1, sizeof *rule); - cls_rule_from_flow(&rule->cls_rule, &flow, wildcards, - !wildcards ? UINT_MAX : priority); + rule = xzalloc(sizeof *rule); + cls_rule_from_flow(&flow, wildcards, !wildcards ? UINT_MAX : priority, + &rule->cls_rule); return rule; } @@ -465,7 +487,7 @@ shuffle(unsigned int *p, size_t n) /* Tests an empty classifier. */ static void -test_empty(void) +test_empty(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { struct classifier cls; struct tcls tcls; @@ -481,14 +503,14 @@ test_empty(void) /* Destroys a null classifier. */ static void -test_destroy_null(void) +test_destroy_null(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { classifier_destroy(NULL); } /* Tests classification with one rule at a time. */ static void -test_single_rule(void) +test_single_rule(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { unsigned int wc_fields; /* Hilarious. */ @@ -526,14 +548,14 @@ test_single_rule(void) /* Tests replacing one rule by another. */ static void -test_rule_replacement(void) +test_rule_replacement(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { unsigned int wc_fields; for (wc_fields = 0; wc_fields < (1u << CLS_N_FIELDS); wc_fields++) { struct classifier cls; - struct test_rule *rule1, *tcls_rule1; - struct test_rule *rule2, *tcls_rule2; + struct test_rule *rule1; + struct test_rule *rule2; struct tcls tcls; rule1 = make_rule(wc_fields, OFP_DEFAULT_PRIORITY, UINT_MAX); @@ -543,14 +565,14 @@ test_rule_replacement(void) classifier_init(&cls); tcls_init(&tcls); - tcls_rule1 = tcls_insert(&tcls, rule1); + tcls_insert(&tcls, rule1); assert(!classifier_insert(&cls, &rule1->cls_rule)); check_tables(&cls, 1, 1, 1); compare_classifiers(&cls, &tcls); tcls_destroy(&tcls); tcls_init(&tcls); - tcls_rule2 = tcls_insert(&tcls, rule2); + tcls_insert(&tcls, rule2); assert(test_rule_from_cls_rule( classifier_insert(&cls, &rule2->cls_rule)) == rule1); free(rule1); @@ -577,7 +599,7 @@ random_wcf_in_table(int table, int seed) /* Tests classification with two rules at a time that fall into the same * bucket. */ static void -test_two_rules_in_one_bucket(void) +test_two_rules_in_one_bucket(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { int table, rel_pri, wcf_pat, value_pat; @@ -666,7 +688,7 @@ test_two_rules_in_one_bucket(void) /* Tests classification with two rules at a time that fall into the same * table but different buckets. */ static void -test_two_rules_in_one_table(void) +test_two_rules_in_one_table(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { int table, rel_pri, wcf_pat; @@ -742,7 +764,8 @@ test_two_rules_in_one_table(void) /* Tests classification with two rules at a time that fall into different * tables. */ static void -test_two_rules_in_different_tables(void) +test_two_rules_in_different_tables(int argc OVS_UNUSED, + char *argv[] OVS_UNUSED) { int table1, table2, rel_pri, wcf_pat; @@ -811,7 +834,7 @@ test_two_rules_in_different_tables(void) /* Tests classification with many rules at a time that fall into the same * bucket but have unique priorities (and various wildcards). */ static void -test_many_rules_in_one_bucket(void) +test_many_rules_in_one_bucket(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { enum { MAX_RULES = 50 }; int iteration, table; @@ -855,7 +878,7 @@ test_many_rules_in_one_bucket(void) /* Tests classification with many rules at a time that fall into the same * table but random buckets. */ static void -test_many_rules_in_one_table(void) +test_many_rules_in_one_table(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { enum { MAX_RULES = 50 }; int iteration, table; @@ -898,7 +921,8 @@ test_many_rules_in_one_table(void) /* Tests classification with many rules at a time that fall into random buckets * in random tables. */ static void -test_many_rules_in_different_tables(void) +test_many_rules_in_different_tables(int argc OVS_UNUSED, + char *argv[] OVS_UNUSED) { enum { MAX_RULES = 50 }; int iteration; @@ -943,36 +967,32 @@ test_many_rules_in_different_tables(void) compare_classifiers(&cls, &tcls); free(rule); } - putchar('.'); - fflush(stdout); destroy_classifier(&cls); tcls_destroy(&tcls); } } -static void -run_test(void (*function)(void)) -{ - function(); - putchar('.'); - fflush(stdout); -} +static const struct command commands[] = { + {"empty", 0, 0, test_empty}, + {"destroy-null", 0, 0, test_destroy_null}, + {"single-rule", 0, 0, test_single_rule}, + {"rule-replacement", 0, 0, test_rule_replacement}, + {"two-rules-in-one-bucket", 0, 0, test_two_rules_in_one_bucket}, + {"two-rules-in-one-table", 0, 0, test_two_rules_in_one_table}, + {"two-rules-in-different-tables", 0, 0, + test_two_rules_in_different_tables}, + {"many-rules-in-one-bucket", 0, 0, test_many_rules_in_one_bucket}, + {"many-rules-in-one-table", 0, 0, test_many_rules_in_one_table}, + {"many-rules-in-different-tables", 0, 0, + test_many_rules_in_different_tables}, + {NULL, 0, 0, NULL}, +}; int -main(void) +main(int argc, char *argv[]) { init_values(); - run_test(test_empty); - run_test(test_destroy_null); - run_test(test_single_rule); - run_test(test_rule_replacement); - run_test(test_two_rules_in_one_bucket); - run_test(test_two_rules_in_one_table); - run_test(test_two_rules_in_different_tables); - run_test(test_many_rules_in_one_bucket); - run_test(test_many_rules_in_one_table); - run_test(test_many_rules_in_different_tables); - putchar('\n'); + run_command(argc - 1, argv + 1, commands); return 0; }