command-line: Add function to print command usage.
[cascardo/ovs.git] / tests / test-classifier.c
1 /*
2  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* "White box" tests for classifier.
18  *
19  * With very few exceptions, these tests obtain complete coverage of every
20  * basic block and every branch in the classifier implementation, e.g. a clean
21  * report from "gcov -b".  (Covering the exceptions would require finding
22  * collisions in the hash function used for flow data, etc.)
23  *
24  * This test should receive a clean report from "valgrind --leak-check=full":
25  * it frees every heap block that it allocates.
26  */
27
28 #include <config.h>
29 #undef NDEBUG
30 #include <assert.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include "byte-order.h"
34 #include "classifier.h"
35 #include "classifier-private.h"
36 #include "command-line.h"
37 #include "flow.h"
38 #include "ofp-util.h"
39 #include "packets.h"
40 #include "random.h"
41 #include "unaligned.h"
42 #include "util.h"
43 #include "ovstest.h"
44
45 /* Fields in a rule. */
46 #define CLS_FIELDS                        \
47     /*        struct flow    all-caps */  \
48     /*        member name    name     */  \
49     /*        -----------    -------- */  \
50     CLS_FIELD(tunnel.tun_id, TUN_ID)      \
51     CLS_FIELD(metadata,      METADATA)    \
52     CLS_FIELD(nw_src,        NW_SRC)      \
53     CLS_FIELD(nw_dst,        NW_DST)      \
54     CLS_FIELD(in_port,       IN_PORT)     \
55     CLS_FIELD(vlan_tci,      VLAN_TCI)    \
56     CLS_FIELD(dl_type,       DL_TYPE)     \
57     CLS_FIELD(tp_src,        TP_SRC)      \
58     CLS_FIELD(tp_dst,        TP_DST)      \
59     CLS_FIELD(dl_src,        DL_SRC)      \
60     CLS_FIELD(dl_dst,        DL_DST)      \
61     CLS_FIELD(nw_proto,      NW_PROTO)    \
62     CLS_FIELD(nw_tos,        NW_DSCP)
63
64 /* Field indexes.
65  *
66  * (These are also indexed into struct classifier's 'tables' array.) */
67 enum {
68 #define CLS_FIELD(MEMBER, NAME) CLS_F_IDX_##NAME,
69     CLS_FIELDS
70 #undef CLS_FIELD
71     CLS_N_FIELDS
72 };
73
74 /* Field information. */
75 struct cls_field {
76     int ofs;                    /* Offset in struct flow. */
77     int len;                    /* Length in bytes. */
78     const char *name;           /* Name (for debugging). */
79 };
80
81 static const struct cls_field cls_fields[CLS_N_FIELDS] = {
82 #define CLS_FIELD(MEMBER, NAME)                 \
83     { offsetof(struct flow, MEMBER),            \
84       sizeof ((struct flow *)0)->MEMBER,        \
85       #NAME },
86     CLS_FIELDS
87 #undef CLS_FIELD
88 };
89
90 struct test_rule {
91     int aux;                    /* Auxiliary data. */
92     struct cls_rule cls_rule;   /* Classifier rule data. */
93 };
94
95 static struct test_rule *
96 test_rule_from_cls_rule(const struct cls_rule *rule)
97 {
98     return rule ? CONTAINER_OF(rule, struct test_rule, cls_rule) : NULL;
99 }
100
101 static void
102 test_rule_destroy(struct test_rule *rule)
103 {
104     if (rule) {
105         cls_rule_destroy(&rule->cls_rule);
106         free(rule);
107     }
108 }
109
110 static struct test_rule *make_rule(int wc_fields, unsigned int priority,
111                                    int value_pat);
112 static void free_rule(struct test_rule *);
113 static struct test_rule *clone_rule(const struct test_rule *);
114
115 /* Trivial (linear) classifier. */
116 struct tcls {
117     size_t n_rules;
118     size_t allocated_rules;
119     struct test_rule **rules;
120 };
121
122 static void
123 tcls_init(struct tcls *tcls)
124 {
125     tcls->n_rules = 0;
126     tcls->allocated_rules = 0;
127     tcls->rules = NULL;
128 }
129
130 static void
131 tcls_destroy(struct tcls *tcls)
132 {
133     if (tcls) {
134         size_t i;
135
136         for (i = 0; i < tcls->n_rules; i++) {
137             test_rule_destroy(tcls->rules[i]);
138         }
139         free(tcls->rules);
140     }
141 }
142
143 static bool
144 tcls_is_empty(const struct tcls *tcls)
145 {
146     return tcls->n_rules == 0;
147 }
148
149 static struct test_rule *
150 tcls_insert(struct tcls *tcls, const struct test_rule *rule)
151 {
152     size_t i;
153
154     for (i = 0; i < tcls->n_rules; i++) {
155         const struct cls_rule *pos = &tcls->rules[i]->cls_rule;
156         if (cls_rule_equal(pos, &rule->cls_rule)) {
157             /* Exact match. */
158             free_rule(tcls->rules[i]);
159             tcls->rules[i] = clone_rule(rule);
160             return tcls->rules[i];
161         } else if (pos->priority < rule->cls_rule.priority) {
162             break;
163         }
164     }
165
166     if (tcls->n_rules >= tcls->allocated_rules) {
167         tcls->rules = x2nrealloc(tcls->rules, &tcls->allocated_rules,
168                                  sizeof *tcls->rules);
169     }
170     if (i != tcls->n_rules) {
171         memmove(&tcls->rules[i + 1], &tcls->rules[i],
172                 sizeof *tcls->rules * (tcls->n_rules - i));
173     }
174     tcls->rules[i] = clone_rule(rule);
175     tcls->n_rules++;
176     return tcls->rules[i];
177 }
178
179 static void
180 tcls_remove(struct tcls *cls, const struct test_rule *rule)
181 {
182     size_t i;
183
184     for (i = 0; i < cls->n_rules; i++) {
185         struct test_rule *pos = cls->rules[i];
186         if (pos == rule) {
187             test_rule_destroy(pos);
188
189             memmove(&cls->rules[i], &cls->rules[i + 1],
190                     sizeof *cls->rules * (cls->n_rules - i - 1));
191
192             cls->n_rules--;
193             return;
194         }
195     }
196     OVS_NOT_REACHED();
197 }
198
199 static bool
200 match(const struct cls_rule *wild_, const struct flow *fixed)
201 {
202     struct match wild;
203     int f_idx;
204
205     minimatch_expand(&wild_->match, &wild);
206     for (f_idx = 0; f_idx < CLS_N_FIELDS; f_idx++) {
207         bool eq;
208
209         if (f_idx == CLS_F_IDX_NW_SRC) {
210             eq = !((fixed->nw_src ^ wild.flow.nw_src)
211                    & wild.wc.masks.nw_src);
212         } else if (f_idx == CLS_F_IDX_NW_DST) {
213             eq = !((fixed->nw_dst ^ wild.flow.nw_dst)
214                    & wild.wc.masks.nw_dst);
215         } else if (f_idx == CLS_F_IDX_TP_SRC) {
216             eq = !((fixed->tp_src ^ wild.flow.tp_src)
217                    & wild.wc.masks.tp_src);
218         } else if (f_idx == CLS_F_IDX_TP_DST) {
219             eq = !((fixed->tp_dst ^ wild.flow.tp_dst)
220                    & wild.wc.masks.tp_dst);
221         } else if (f_idx == CLS_F_IDX_DL_SRC) {
222             eq = eth_addr_equal_except(fixed->dl_src, wild.flow.dl_src,
223                                        wild.wc.masks.dl_src);
224         } else if (f_idx == CLS_F_IDX_DL_DST) {
225             eq = eth_addr_equal_except(fixed->dl_dst, wild.flow.dl_dst,
226                                        wild.wc.masks.dl_dst);
227         } else if (f_idx == CLS_F_IDX_VLAN_TCI) {
228             eq = !((fixed->vlan_tci ^ wild.flow.vlan_tci)
229                    & wild.wc.masks.vlan_tci);
230         } else if (f_idx == CLS_F_IDX_TUN_ID) {
231             eq = !((fixed->tunnel.tun_id ^ wild.flow.tunnel.tun_id)
232                    & wild.wc.masks.tunnel.tun_id);
233         } else if (f_idx == CLS_F_IDX_METADATA) {
234             eq = !((fixed->metadata ^ wild.flow.metadata)
235                    & wild.wc.masks.metadata);
236         } else if (f_idx == CLS_F_IDX_NW_DSCP) {
237             eq = !((fixed->nw_tos ^ wild.flow.nw_tos) &
238                    (wild.wc.masks.nw_tos & IP_DSCP_MASK));
239         } else if (f_idx == CLS_F_IDX_NW_PROTO) {
240             eq = !((fixed->nw_proto ^ wild.flow.nw_proto)
241                    & wild.wc.masks.nw_proto);
242         } else if (f_idx == CLS_F_IDX_DL_TYPE) {
243             eq = !((fixed->dl_type ^ wild.flow.dl_type)
244                    & wild.wc.masks.dl_type);
245         } else if (f_idx == CLS_F_IDX_IN_PORT) {
246             eq = !((fixed->in_port.ofp_port
247                     ^ wild.flow.in_port.ofp_port)
248                    & wild.wc.masks.in_port.ofp_port);
249         } else {
250             OVS_NOT_REACHED();
251         }
252
253         if (!eq) {
254             return false;
255         }
256     }
257     return true;
258 }
259
260 static struct cls_rule *
261 tcls_lookup(const struct tcls *cls, const struct flow *flow)
262 {
263     size_t i;
264
265     for (i = 0; i < cls->n_rules; i++) {
266         struct test_rule *pos = cls->rules[i];
267         if (match(&pos->cls_rule, flow)) {
268             return &pos->cls_rule;
269         }
270     }
271     return NULL;
272 }
273
274 static void
275 tcls_delete_matches(struct tcls *cls, const struct cls_rule *target)
276 {
277     size_t i;
278
279     for (i = 0; i < cls->n_rules; ) {
280         struct test_rule *pos = cls->rules[i];
281         if (!minimask_has_extra(&pos->cls_rule.match.mask,
282                                 &target->match.mask)) {
283             struct flow flow;
284
285             miniflow_expand(&pos->cls_rule.match.flow, &flow);
286             if (match(target, &flow)) {
287                 tcls_remove(cls, pos);
288                 continue;
289             }
290         }
291         i++;
292     }
293 }
294 \f
295 static ovs_be32 nw_src_values[] = { CONSTANT_HTONL(0xc0a80001),
296                                     CONSTANT_HTONL(0xc0a04455) };
297 static ovs_be32 nw_dst_values[] = { CONSTANT_HTONL(0xc0a80002),
298                                     CONSTANT_HTONL(0xc0a04455) };
299 static ovs_be64 tun_id_values[] = {
300     0,
301     CONSTANT_HTONLL(UINT64_C(0xfedcba9876543210)) };
302 static ovs_be64 metadata_values[] = {
303     0,
304     CONSTANT_HTONLL(UINT64_C(0xfedcba9876543210)) };
305 static ofp_port_t in_port_values[] = { OFP_PORT_C(1), OFPP_LOCAL };
306 static ovs_be16 vlan_tci_values[] = { CONSTANT_HTONS(101), CONSTANT_HTONS(0) };
307 static ovs_be16 dl_type_values[]
308             = { CONSTANT_HTONS(ETH_TYPE_IP), CONSTANT_HTONS(ETH_TYPE_ARP) };
309 static ovs_be16 tp_src_values[] = { CONSTANT_HTONS(49362),
310                                     CONSTANT_HTONS(80) };
311 static ovs_be16 tp_dst_values[] = { CONSTANT_HTONS(6667), CONSTANT_HTONS(22) };
312 static uint8_t dl_src_values[][ETH_ADDR_LEN] = {
313                                       { 0x00, 0x02, 0xe3, 0x0f, 0x80, 0xa4 },
314                                       { 0x5e, 0x33, 0x7f, 0x5f, 0x1e, 0x99 } };
315 static uint8_t dl_dst_values[][ETH_ADDR_LEN] = {
316                                       { 0x4a, 0x27, 0x71, 0xae, 0x64, 0xc1 },
317                                       { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
318 static uint8_t nw_proto_values[] = { IPPROTO_TCP, IPPROTO_ICMP };
319 static uint8_t nw_dscp_values[] = { 48, 0 };
320
321 static void *values[CLS_N_FIELDS][2];
322
323 static void
324 init_values(void)
325 {
326     values[CLS_F_IDX_TUN_ID][0] = &tun_id_values[0];
327     values[CLS_F_IDX_TUN_ID][1] = &tun_id_values[1];
328
329     values[CLS_F_IDX_METADATA][0] = &metadata_values[0];
330     values[CLS_F_IDX_METADATA][1] = &metadata_values[1];
331
332     values[CLS_F_IDX_IN_PORT][0] = &in_port_values[0];
333     values[CLS_F_IDX_IN_PORT][1] = &in_port_values[1];
334
335     values[CLS_F_IDX_VLAN_TCI][0] = &vlan_tci_values[0];
336     values[CLS_F_IDX_VLAN_TCI][1] = &vlan_tci_values[1];
337
338     values[CLS_F_IDX_DL_SRC][0] = dl_src_values[0];
339     values[CLS_F_IDX_DL_SRC][1] = dl_src_values[1];
340
341     values[CLS_F_IDX_DL_DST][0] = dl_dst_values[0];
342     values[CLS_F_IDX_DL_DST][1] = dl_dst_values[1];
343
344     values[CLS_F_IDX_DL_TYPE][0] = &dl_type_values[0];
345     values[CLS_F_IDX_DL_TYPE][1] = &dl_type_values[1];
346
347     values[CLS_F_IDX_NW_SRC][0] = &nw_src_values[0];
348     values[CLS_F_IDX_NW_SRC][1] = &nw_src_values[1];
349
350     values[CLS_F_IDX_NW_DST][0] = &nw_dst_values[0];
351     values[CLS_F_IDX_NW_DST][1] = &nw_dst_values[1];
352
353     values[CLS_F_IDX_NW_PROTO][0] = &nw_proto_values[0];
354     values[CLS_F_IDX_NW_PROTO][1] = &nw_proto_values[1];
355
356     values[CLS_F_IDX_NW_DSCP][0] = &nw_dscp_values[0];
357     values[CLS_F_IDX_NW_DSCP][1] = &nw_dscp_values[1];
358
359     values[CLS_F_IDX_TP_SRC][0] = &tp_src_values[0];
360     values[CLS_F_IDX_TP_SRC][1] = &tp_src_values[1];
361
362     values[CLS_F_IDX_TP_DST][0] = &tp_dst_values[0];
363     values[CLS_F_IDX_TP_DST][1] = &tp_dst_values[1];
364 }
365
366 #define N_NW_SRC_VALUES ARRAY_SIZE(nw_src_values)
367 #define N_NW_DST_VALUES ARRAY_SIZE(nw_dst_values)
368 #define N_TUN_ID_VALUES ARRAY_SIZE(tun_id_values)
369 #define N_METADATA_VALUES ARRAY_SIZE(metadata_values)
370 #define N_IN_PORT_VALUES ARRAY_SIZE(in_port_values)
371 #define N_VLAN_TCI_VALUES ARRAY_SIZE(vlan_tci_values)
372 #define N_DL_TYPE_VALUES ARRAY_SIZE(dl_type_values)
373 #define N_TP_SRC_VALUES ARRAY_SIZE(tp_src_values)
374 #define N_TP_DST_VALUES ARRAY_SIZE(tp_dst_values)
375 #define N_DL_SRC_VALUES ARRAY_SIZE(dl_src_values)
376 #define N_DL_DST_VALUES ARRAY_SIZE(dl_dst_values)
377 #define N_NW_PROTO_VALUES ARRAY_SIZE(nw_proto_values)
378 #define N_NW_DSCP_VALUES ARRAY_SIZE(nw_dscp_values)
379
380 #define N_FLOW_VALUES (N_NW_SRC_VALUES *        \
381                        N_NW_DST_VALUES *        \
382                        N_TUN_ID_VALUES *        \
383                        N_IN_PORT_VALUES *       \
384                        N_VLAN_TCI_VALUES *       \
385                        N_DL_TYPE_VALUES *       \
386                        N_TP_SRC_VALUES *        \
387                        N_TP_DST_VALUES *        \
388                        N_DL_SRC_VALUES *        \
389                        N_DL_DST_VALUES *        \
390                        N_NW_PROTO_VALUES *      \
391                        N_NW_DSCP_VALUES)
392
393 static unsigned int
394 get_value(unsigned int *x, unsigned n_values)
395 {
396     unsigned int rem = *x % n_values;
397     *x /= n_values;
398     return rem;
399 }
400
401 static void
402 compare_classifiers(struct classifier *cls, struct tcls *tcls)
403 {
404     static const int confidence = 500;
405     unsigned int i;
406
407     assert(classifier_count(cls) == tcls->n_rules);
408     for (i = 0; i < confidence; i++) {
409         struct cls_rule *cr0, *cr1, *cr2;
410         struct flow flow;
411         struct flow_wildcards wc;
412         unsigned int x;
413
414         flow_wildcards_init_catchall(&wc);
415         x = random_range(N_FLOW_VALUES);
416         memset(&flow, 0, sizeof flow);
417         flow.nw_src = nw_src_values[get_value(&x, N_NW_SRC_VALUES)];
418         flow.nw_dst = nw_dst_values[get_value(&x, N_NW_DST_VALUES)];
419         flow.tunnel.tun_id = tun_id_values[get_value(&x, N_TUN_ID_VALUES)];
420         flow.metadata = metadata_values[get_value(&x, N_METADATA_VALUES)];
421         flow.in_port.ofp_port = in_port_values[get_value(&x,
422                                                    N_IN_PORT_VALUES)];
423         flow.vlan_tci = vlan_tci_values[get_value(&x, N_VLAN_TCI_VALUES)];
424         flow.dl_type = dl_type_values[get_value(&x, N_DL_TYPE_VALUES)];
425         flow.tp_src = tp_src_values[get_value(&x, N_TP_SRC_VALUES)];
426         flow.tp_dst = tp_dst_values[get_value(&x, N_TP_DST_VALUES)];
427         memcpy(flow.dl_src, dl_src_values[get_value(&x, N_DL_SRC_VALUES)],
428                ETH_ADDR_LEN);
429         memcpy(flow.dl_dst, dl_dst_values[get_value(&x, N_DL_DST_VALUES)],
430                ETH_ADDR_LEN);
431         flow.nw_proto = nw_proto_values[get_value(&x, N_NW_PROTO_VALUES)];
432         flow.nw_tos = nw_dscp_values[get_value(&x, N_NW_DSCP_VALUES)];
433
434         /* This assertion is here to suppress a GCC 4.9 array-bounds warning */
435         ovs_assert(cls->n_tries <= CLS_MAX_TRIES);
436
437         cr0 = classifier_lookup(cls, &flow, &wc);
438         cr1 = tcls_lookup(tcls, &flow);
439         assert((cr0 == NULL) == (cr1 == NULL));
440         if (cr0 != NULL) {
441             const struct test_rule *tr0 = test_rule_from_cls_rule(cr0);
442             const struct test_rule *tr1 = test_rule_from_cls_rule(cr1);
443
444             assert(cls_rule_equal(cr0, cr1));
445             assert(tr0->aux == tr1->aux);
446         }
447         cr2 = classifier_lookup(cls, &flow, NULL);
448         assert(cr2 == cr0);
449     }
450 }
451
452 static void
453 destroy_classifier(struct classifier *cls)
454 {
455     struct test_rule *rule;
456
457     CLS_FOR_EACH_SAFE (rule, cls_rule, cls) {
458         classifier_remove(cls, &rule->cls_rule);
459         free_rule(rule);
460     }
461     classifier_destroy(cls);
462 }
463
464 static void
465 pvector_verify(const struct pvector *pvec)
466 {
467     void *ptr OVS_UNUSED;
468     unsigned int priority, prev_priority = UINT_MAX;
469
470     PVECTOR_FOR_EACH (ptr, pvec) {
471         priority = cursor__.vector[cursor__.entry_idx].priority;
472         if (priority > prev_priority) {
473             ovs_abort(0, "Priority vector is out of order (%u > %u)",
474                       priority, prev_priority);
475         }
476         prev_priority = priority;
477     }
478 }
479
480 static unsigned int
481 trie_verify(const rcu_trie_ptr *trie, unsigned int ofs, unsigned int n_bits)
482 {
483     const struct trie_node *node = ovsrcu_get(struct trie_node *, trie);
484
485     if (node) {
486         assert(node->n_rules == 0 || node->n_bits > 0);
487         ofs += node->n_bits;
488         assert((ofs > 0 || (ofs == 0 && node->n_bits == 0)) && ofs <= n_bits);
489
490         return node->n_rules
491             + trie_verify(&node->edges[0], ofs, n_bits)
492             + trie_verify(&node->edges[1], ofs, n_bits);
493     }
494     return 0;
495 }
496
497 static void
498 verify_tries(struct classifier *cls)
499 {
500     unsigned int n_rules = 0;
501     int i;
502
503     for (i = 0; i < cls->n_tries; i++) {
504         n_rules += trie_verify(&cls->tries[i].root, 0,
505                                cls->tries[i].field->n_bits);
506     }
507     ovs_mutex_lock(&cls->mutex);
508     assert(n_rules <= cls->n_rules);
509     ovs_mutex_unlock(&cls->mutex);
510 }
511
512 static void
513 check_tables(const struct classifier *cls, int n_tables, int n_rules,
514              int n_dups)
515 {
516     const struct cls_subtable *table;
517     struct test_rule *test_rule;
518     int found_tables = 0;
519     int found_rules = 0;
520     int found_dups = 0;
521     int found_rules2 = 0;
522
523     pvector_verify(&cls->subtables);
524     CMAP_FOR_EACH (table, cmap_node, &cls->subtables_map) {
525         const struct cls_match *head;
526         unsigned int max_priority = 0;
527         unsigned int max_count = 0;
528         bool found = false;
529         const struct cls_subtable *iter;
530
531         /* Locate the subtable from 'subtables'. */
532         PVECTOR_FOR_EACH (iter, &cls->subtables) {
533             if (iter == table) {
534                 if (found) {
535                     ovs_abort(0, "Subtable %p duplicated in 'subtables'.",
536                               table);
537                 }
538                 found = true;
539             }
540         }
541         if (!found) {
542             ovs_abort(0, "Subtable %p not found from 'subtables'.", table);
543         }
544
545         assert(!cmap_is_empty(&table->rules));
546
547         ovs_mutex_lock(&cls->mutex);
548         assert(trie_verify(&table->ports_trie, 0, table->ports_mask_len)
549                == (table->ports_mask_len ? table->n_rules : 0));
550         ovs_mutex_unlock(&cls->mutex);
551
552         found_tables++;
553         CMAP_FOR_EACH (head, cmap_node, &table->rules) {
554             unsigned int prev_priority = UINT_MAX;
555             const struct cls_match *rule;
556
557             if (head->priority > max_priority) {
558                 max_priority = head->priority;
559                 max_count = 1;
560             } else if (head->priority == max_priority) {
561                 ++max_count;
562             }
563
564             found_rules++;
565             ovs_mutex_lock(&cls->mutex);
566             LIST_FOR_EACH (rule, list, &head->list) {
567                 assert(rule->priority < prev_priority);
568                 assert(rule->priority <= table->max_priority);
569
570                 prev_priority = rule->priority;
571                 found_rules++;
572                 found_dups++;
573                 ovs_mutex_unlock(&cls->mutex);
574                 assert(classifier_find_rule_exactly(cls, rule->cls_rule)
575                        == rule->cls_rule);
576                 ovs_mutex_lock(&cls->mutex);
577             }
578             ovs_mutex_unlock(&cls->mutex);
579         }
580         ovs_mutex_lock(&cls->mutex);
581         assert(table->max_priority == max_priority);
582         assert(table->max_count == max_count);
583         ovs_mutex_unlock(&cls->mutex);
584     }
585
586     assert(found_tables == cmap_count(&cls->subtables_map));
587     assert(found_tables == pvector_count(&cls->subtables));
588     assert(n_tables == -1 || n_tables == cmap_count(&cls->subtables_map));
589     assert(n_rules == -1 || found_rules == n_rules);
590     assert(n_dups == -1 || found_dups == n_dups);
591
592     CLS_FOR_EACH (test_rule, cls_rule, cls) {
593         found_rules2++;
594     }
595     assert(found_rules == found_rules2);
596 }
597
598 static struct test_rule *
599 make_rule(int wc_fields, unsigned int priority, int value_pat)
600 {
601     const struct cls_field *f;
602     struct test_rule *rule;
603     struct match match;
604
605     match_init_catchall(&match);
606     for (f = &cls_fields[0]; f < &cls_fields[CLS_N_FIELDS]; f++) {
607         int f_idx = f - cls_fields;
608         int value_idx = (value_pat & (1u << f_idx)) != 0;
609         memcpy((char *) &match.flow + f->ofs,
610                values[f_idx][value_idx], f->len);
611
612         if (f_idx == CLS_F_IDX_NW_SRC) {
613             match.wc.masks.nw_src = OVS_BE32_MAX;
614         } else if (f_idx == CLS_F_IDX_NW_DST) {
615             match.wc.masks.nw_dst = OVS_BE32_MAX;
616         } else if (f_idx == CLS_F_IDX_TP_SRC) {
617             match.wc.masks.tp_src = OVS_BE16_MAX;
618         } else if (f_idx == CLS_F_IDX_TP_DST) {
619             match.wc.masks.tp_dst = OVS_BE16_MAX;
620         } else if (f_idx == CLS_F_IDX_DL_SRC) {
621             memset(match.wc.masks.dl_src, 0xff, ETH_ADDR_LEN);
622         } else if (f_idx == CLS_F_IDX_DL_DST) {
623             memset(match.wc.masks.dl_dst, 0xff, ETH_ADDR_LEN);
624         } else if (f_idx == CLS_F_IDX_VLAN_TCI) {
625             match.wc.masks.vlan_tci = OVS_BE16_MAX;
626         } else if (f_idx == CLS_F_IDX_TUN_ID) {
627             match.wc.masks.tunnel.tun_id = OVS_BE64_MAX;
628         } else if (f_idx == CLS_F_IDX_METADATA) {
629             match.wc.masks.metadata = OVS_BE64_MAX;
630         } else if (f_idx == CLS_F_IDX_NW_DSCP) {
631             match.wc.masks.nw_tos |= IP_DSCP_MASK;
632         } else if (f_idx == CLS_F_IDX_NW_PROTO) {
633             match.wc.masks.nw_proto = UINT8_MAX;
634         } else if (f_idx == CLS_F_IDX_DL_TYPE) {
635             match.wc.masks.dl_type = OVS_BE16_MAX;
636         } else if (f_idx == CLS_F_IDX_IN_PORT) {
637             match.wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
638         } else {
639             OVS_NOT_REACHED();
640         }
641     }
642
643     rule = xzalloc(sizeof *rule);
644     cls_rule_init(&rule->cls_rule, &match, wc_fields ? priority : UINT_MAX);
645     return rule;
646 }
647
648 static struct test_rule *
649 clone_rule(const struct test_rule *src)
650 {
651     struct test_rule *dst;
652
653     dst = xmalloc(sizeof *dst);
654     dst->aux = src->aux;
655     cls_rule_clone(&dst->cls_rule, &src->cls_rule);
656     return dst;
657 }
658
659 static void
660 free_rule(struct test_rule *rule)
661 {
662     cls_rule_destroy(&rule->cls_rule);
663     free(rule);
664 }
665
666 static void
667 shuffle(unsigned int *p, size_t n)
668 {
669     for (; n > 1; n--, p++) {
670         unsigned int *q = &p[random_range(n)];
671         unsigned int tmp = *p;
672         *p = *q;
673         *q = tmp;
674     }
675 }
676
677 static void
678 shuffle_u32s(uint32_t *p, size_t n)
679 {
680     for (; n > 1; n--, p++) {
681         uint32_t *q = &p[random_range(n)];
682         uint32_t tmp = *p;
683         *p = *q;
684         *q = tmp;
685     }
686 }
687 \f
688 /* Classifier tests. */
689
690 static enum mf_field_id trie_fields[2] = {
691     MFF_IPV4_DST, MFF_IPV4_SRC
692 };
693
694 static void
695 set_prefix_fields(struct classifier *cls)
696 {
697     verify_tries(cls);
698     classifier_set_prefix_fields(cls, trie_fields, ARRAY_SIZE(trie_fields));
699     verify_tries(cls);
700 }
701
702 /* Tests an empty classifier. */
703 static void
704 test_empty(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
705 {
706     struct classifier cls;
707     struct tcls tcls;
708
709     classifier_init(&cls, flow_segment_u32s);
710     set_prefix_fields(&cls);
711     tcls_init(&tcls);
712     assert(classifier_is_empty(&cls));
713     assert(tcls_is_empty(&tcls));
714     compare_classifiers(&cls, &tcls);
715     classifier_destroy(&cls);
716     tcls_destroy(&tcls);
717 }
718
719 /* Destroys a null classifier. */
720 static void
721 test_destroy_null(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
722 {
723     classifier_destroy(NULL);
724 }
725
726 /* Tests classification with one rule at a time. */
727 static void
728 test_single_rule(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
729 {
730     unsigned int wc_fields;     /* Hilarious. */
731
732     for (wc_fields = 0; wc_fields < (1u << CLS_N_FIELDS); wc_fields++) {
733         struct classifier cls;
734         struct test_rule *rule, *tcls_rule;
735         struct tcls tcls;
736
737         rule = make_rule(wc_fields,
738                          hash_bytes(&wc_fields, sizeof wc_fields, 0), 0);
739
740         classifier_init(&cls, flow_segment_u32s);
741         set_prefix_fields(&cls);
742         tcls_init(&tcls);
743
744         tcls_rule = tcls_insert(&tcls, rule);
745         classifier_insert(&cls, &rule->cls_rule);
746         compare_classifiers(&cls, &tcls);
747         check_tables(&cls, 1, 1, 0);
748
749         classifier_remove(&cls, &rule->cls_rule);
750         tcls_remove(&tcls, tcls_rule);
751         assert(classifier_is_empty(&cls));
752         assert(tcls_is_empty(&tcls));
753         compare_classifiers(&cls, &tcls);
754
755         free_rule(rule);
756         classifier_destroy(&cls);
757         tcls_destroy(&tcls);
758     }
759 }
760
761 /* Tests replacing one rule by another. */
762 static void
763 test_rule_replacement(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
764 {
765     unsigned int wc_fields;
766
767     for (wc_fields = 0; wc_fields < (1u << CLS_N_FIELDS); wc_fields++) {
768         struct classifier cls;
769         struct test_rule *rule1;
770         struct test_rule *rule2;
771         struct tcls tcls;
772
773         rule1 = make_rule(wc_fields, OFP_DEFAULT_PRIORITY, UINT_MAX);
774         rule2 = make_rule(wc_fields, OFP_DEFAULT_PRIORITY, UINT_MAX);
775         rule2->aux += 5;
776         rule2->aux += 5;
777
778         classifier_init(&cls, flow_segment_u32s);
779         set_prefix_fields(&cls);
780         tcls_init(&tcls);
781         tcls_insert(&tcls, rule1);
782         classifier_insert(&cls, &rule1->cls_rule);
783         compare_classifiers(&cls, &tcls);
784         check_tables(&cls, 1, 1, 0);
785         tcls_destroy(&tcls);
786
787         tcls_init(&tcls);
788         tcls_insert(&tcls, rule2);
789
790         assert(test_rule_from_cls_rule(
791                    classifier_replace(&cls, &rule2->cls_rule)) == rule1);
792         free_rule(rule1);
793         compare_classifiers(&cls, &tcls);
794         check_tables(&cls, 1, 1, 0);
795
796         tcls_destroy(&tcls);
797         destroy_classifier(&cls);
798     }
799 }
800
801 static int
802 factorial(int n_items)
803 {
804     int n, i;
805
806     n = 1;
807     for (i = 2; i <= n_items; i++) {
808         n *= i;
809     }
810     return n;
811 }
812
813 static void
814 swap(int *a, int *b)
815 {
816     int tmp = *a;
817     *a = *b;
818     *b = tmp;
819 }
820
821 static void
822 reverse(int *a, int n)
823 {
824     int i;
825
826     for (i = 0; i < n / 2; i++) {
827         int j = n - (i + 1);
828         swap(&a[i], &a[j]);
829     }
830 }
831
832 static bool
833 next_permutation(int *a, int n)
834 {
835     int k;
836
837     for (k = n - 2; k >= 0; k--) {
838         if (a[k] < a[k + 1]) {
839             int l;
840
841             for (l = n - 1; ; l--) {
842                 if (a[l] > a[k]) {
843                     swap(&a[k], &a[l]);
844                     reverse(a + (k + 1), n - (k + 1));
845                     return true;
846                 }
847             }
848         }
849     }
850     return false;
851 }
852
853 /* Tests classification with rules that have the same matching criteria. */
854 static void
855 test_many_rules_in_one_list (int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
856 {
857     enum { N_RULES = 3 };
858     int n_pris;
859
860     for (n_pris = N_RULES; n_pris >= 1; n_pris--) {
861         int ops[N_RULES * 2];
862         int pris[N_RULES];
863         int n_permutations;
864         int i;
865
866         pris[0] = 0;
867         for (i = 1; i < N_RULES; i++) {
868             pris[i] = pris[i - 1] + (n_pris > i);
869         }
870
871         for (i = 0; i < N_RULES * 2; i++) {
872             ops[i] = i / 2;
873         }
874
875         n_permutations = 0;
876         do {
877             struct test_rule *rules[N_RULES];
878             struct test_rule *tcls_rules[N_RULES];
879             int pri_rules[N_RULES];
880             struct classifier cls;
881             struct tcls tcls;
882
883             n_permutations++;
884
885             for (i = 0; i < N_RULES; i++) {
886                 rules[i] = make_rule(456, pris[i], 0);
887                 tcls_rules[i] = NULL;
888                 pri_rules[i] = -1;
889             }
890
891             classifier_init(&cls, flow_segment_u32s);
892             set_prefix_fields(&cls);
893             tcls_init(&tcls);
894
895             for (i = 0; i < ARRAY_SIZE(ops); i++) {
896                 int j = ops[i];
897                 int m, n;
898
899                 if (!tcls_rules[j]) {
900                     struct test_rule *displaced_rule;
901
902                     tcls_rules[j] = tcls_insert(&tcls, rules[j]);
903                     displaced_rule = test_rule_from_cls_rule(
904                         classifier_replace(&cls, &rules[j]->cls_rule));
905                     if (pri_rules[pris[j]] >= 0) {
906                         int k = pri_rules[pris[j]];
907                         assert(displaced_rule != NULL);
908                         assert(displaced_rule != rules[j]);
909                         assert(pris[j] == displaced_rule->cls_rule.priority);
910                         tcls_rules[k] = NULL;
911                     } else {
912                         assert(displaced_rule == NULL);
913                     }
914                     pri_rules[pris[j]] = j;
915                 } else {
916                     classifier_remove(&cls, &rules[j]->cls_rule);
917                     tcls_remove(&tcls, tcls_rules[j]);
918                     tcls_rules[j] = NULL;
919                     pri_rules[pris[j]] = -1;
920                 }
921                 compare_classifiers(&cls, &tcls);
922
923                 n = 0;
924                 for (m = 0; m < N_RULES; m++) {
925                     n += tcls_rules[m] != NULL;
926                 }
927                 check_tables(&cls, n > 0, n, n - 1);
928             }
929
930             for (i = 0; i < N_RULES; i++) {
931                 if (rules[i]->cls_rule.cls_match) {
932                     classifier_remove(&cls, &rules[i]->cls_rule);
933                 }
934                 free_rule(rules[i]);
935             }
936             classifier_destroy(&cls);
937             tcls_destroy(&tcls);
938         } while (next_permutation(ops, ARRAY_SIZE(ops)));
939         assert(n_permutations == (factorial(N_RULES * 2) >> N_RULES));
940     }
941 }
942
943 static int
944 count_ones(unsigned long int x)
945 {
946     int n = 0;
947
948     while (x) {
949         x = zero_rightmost_1bit(x);
950         n++;
951     }
952
953     return n;
954 }
955
956 static bool
957 array_contains(int *array, int n, int value)
958 {
959     int i;
960
961     for (i = 0; i < n; i++) {
962         if (array[i] == value) {
963             return true;
964         }
965     }
966
967     return false;
968 }
969
970 /* Tests classification with two rules at a time that fall into the same
971  * table but different lists. */
972 static void
973 test_many_rules_in_one_table(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
974 {
975     int iteration;
976
977     for (iteration = 0; iteration < 50; iteration++) {
978         enum { N_RULES = 20 };
979         struct test_rule *rules[N_RULES];
980         struct test_rule *tcls_rules[N_RULES];
981         struct classifier cls;
982         struct tcls tcls;
983         int value_pats[N_RULES];
984         int value_mask;
985         int wcf;
986         int i;
987
988         do {
989             wcf = random_uint32() & ((1u << CLS_N_FIELDS) - 1);
990             value_mask = ~wcf & ((1u << CLS_N_FIELDS) - 1);
991         } while ((1 << count_ones(value_mask)) < N_RULES);
992
993         classifier_init(&cls, flow_segment_u32s);
994         set_prefix_fields(&cls);
995         tcls_init(&tcls);
996
997         for (i = 0; i < N_RULES; i++) {
998             unsigned int priority = random_uint32();
999
1000             do {
1001                 value_pats[i] = random_uint32() & value_mask;
1002             } while (array_contains(value_pats, i, value_pats[i]));
1003
1004             rules[i] = make_rule(wcf, priority, value_pats[i]);
1005             tcls_rules[i] = tcls_insert(&tcls, rules[i]);
1006
1007             classifier_insert(&cls, &rules[i]->cls_rule);
1008             compare_classifiers(&cls, &tcls);
1009
1010             check_tables(&cls, 1, i + 1, 0);
1011         }
1012
1013         for (i = 0; i < N_RULES; i++) {
1014             tcls_remove(&tcls, tcls_rules[i]);
1015             classifier_remove(&cls, &rules[i]->cls_rule);
1016             compare_classifiers(&cls, &tcls);
1017             free_rule(rules[i]);
1018
1019             check_tables(&cls, i < N_RULES - 1, N_RULES - (i + 1), 0);
1020         }
1021
1022         classifier_destroy(&cls);
1023         tcls_destroy(&tcls);
1024     }
1025 }
1026
1027 /* Tests classification with many rules at a time that fall into random lists
1028  * in 'n' tables. */
1029 static void
1030 test_many_rules_in_n_tables(int n_tables)
1031 {
1032     enum { MAX_RULES = 50 };
1033     int wcfs[10];
1034     int iteration;
1035     int i;
1036
1037     assert(n_tables < 10);
1038     for (i = 0; i < n_tables; i++) {
1039         do {
1040             wcfs[i] = random_uint32() & ((1u << CLS_N_FIELDS) - 1);
1041         } while (array_contains(wcfs, i, wcfs[i]));
1042     }
1043
1044     for (iteration = 0; iteration < 30; iteration++) {
1045         unsigned int priorities[MAX_RULES];
1046         struct classifier cls;
1047         struct tcls tcls;
1048
1049         random_set_seed(iteration + 1);
1050         for (i = 0; i < MAX_RULES; i++) {
1051             priorities[i] = i * 129;
1052         }
1053         shuffle(priorities, ARRAY_SIZE(priorities));
1054
1055         classifier_init(&cls, flow_segment_u32s);
1056         set_prefix_fields(&cls);
1057         tcls_init(&tcls);
1058
1059         for (i = 0; i < MAX_RULES; i++) {
1060             struct test_rule *rule;
1061             unsigned int priority = priorities[i];
1062             int wcf = wcfs[random_range(n_tables)];
1063             int value_pat = random_uint32() & ((1u << CLS_N_FIELDS) - 1);
1064             rule = make_rule(wcf, priority, value_pat);
1065             tcls_insert(&tcls, rule);
1066             classifier_insert(&cls, &rule->cls_rule);
1067             compare_classifiers(&cls, &tcls);
1068             check_tables(&cls, -1, i + 1, -1);
1069         }
1070
1071         while (!classifier_is_empty(&cls)) {
1072             struct test_rule *target;
1073             struct test_rule *rule;
1074
1075             target = clone_rule(tcls.rules[random_range(tcls.n_rules)]);
1076
1077             CLS_FOR_EACH_TARGET_SAFE (rule, cls_rule, &cls,
1078                                       &target->cls_rule) {
1079                 classifier_remove(&cls, &rule->cls_rule);
1080                 free_rule(rule);
1081             }
1082
1083             tcls_delete_matches(&tcls, &target->cls_rule);
1084             compare_classifiers(&cls, &tcls);
1085             check_tables(&cls, -1, -1, -1);
1086             free_rule(target);
1087         }
1088
1089         destroy_classifier(&cls);
1090         tcls_destroy(&tcls);
1091     }
1092 }
1093
1094 static void
1095 test_many_rules_in_two_tables(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1096 {
1097     test_many_rules_in_n_tables(2);
1098 }
1099
1100 static void
1101 test_many_rules_in_five_tables(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1102 {
1103     test_many_rules_in_n_tables(5);
1104 }
1105 \f
1106 /* Miniflow tests. */
1107
1108 static uint32_t
1109 random_value(void)
1110 {
1111     static const uint32_t values[] =
1112         { 0xffffffff, 0xaaaaaaaa, 0x55555555, 0x80000000,
1113           0x00000001, 0xface0000, 0x00d00d1e, 0xdeadbeef };
1114
1115     return values[random_range(ARRAY_SIZE(values))];
1116 }
1117
1118 static bool
1119 choose(unsigned int n, unsigned int *idxp)
1120 {
1121     if (*idxp < n) {
1122         return true;
1123     } else {
1124         *idxp -= n;
1125         return false;
1126     }
1127 }
1128
1129 static bool
1130 init_consecutive_values(int n_consecutive, struct flow *flow,
1131                         unsigned int *idxp)
1132 {
1133     uint32_t *flow_u32 = (uint32_t *) flow;
1134
1135     if (choose(FLOW_U32S - n_consecutive + 1, idxp)) {
1136         int i;
1137
1138         for (i = 0; i < n_consecutive; i++) {
1139             flow_u32[*idxp + i] = random_value();
1140         }
1141         return true;
1142     } else {
1143         return false;
1144     }
1145 }
1146
1147 static bool
1148 next_random_flow(struct flow *flow, unsigned int idx)
1149 {
1150     uint32_t *flow_u32 = (uint32_t *) flow;
1151     int i;
1152
1153     memset(flow, 0, sizeof *flow);
1154
1155     /* Empty flow. */
1156     if (choose(1, &idx)) {
1157         return true;
1158     }
1159
1160     /* All flows with a small number of consecutive nonzero values. */
1161     for (i = 1; i <= 4; i++) {
1162         if (init_consecutive_values(i, flow, &idx)) {
1163             return true;
1164         }
1165     }
1166
1167     /* All flows with a large number of consecutive nonzero values. */
1168     for (i = FLOW_U32S - 4; i <= FLOW_U32S; i++) {
1169         if (init_consecutive_values(i, flow, &idx)) {
1170             return true;
1171         }
1172     }
1173
1174     /* All flows with exactly two nonconsecutive nonzero values. */
1175     if (choose((FLOW_U32S - 1) * (FLOW_U32S - 2) / 2, &idx)) {
1176         int ofs1;
1177
1178         for (ofs1 = 0; ofs1 < FLOW_U32S - 2; ofs1++) {
1179             int ofs2;
1180
1181             for (ofs2 = ofs1 + 2; ofs2 < FLOW_U32S; ofs2++) {
1182                 if (choose(1, &idx)) {
1183                     flow_u32[ofs1] = random_value();
1184                     flow_u32[ofs2] = random_value();
1185                     return true;
1186                 }
1187             }
1188         }
1189         OVS_NOT_REACHED();
1190     }
1191
1192     /* 16 randomly chosen flows with N >= 3 nonzero values. */
1193     if (choose(16 * (FLOW_U32S - 4), &idx)) {
1194         int n = idx / 16 + 3;
1195         int i;
1196
1197         for (i = 0; i < n; i++) {
1198             flow_u32[i] = random_value();
1199         }
1200         shuffle_u32s(flow_u32, FLOW_U32S);
1201
1202         return true;
1203     }
1204
1205     return false;
1206 }
1207
1208 static void
1209 any_random_flow(struct flow *flow)
1210 {
1211     static unsigned int max;
1212     if (!max) {
1213         while (next_random_flow(flow, max)) {
1214             max++;
1215         }
1216     }
1217
1218     next_random_flow(flow, random_range(max));
1219 }
1220
1221 static void
1222 toggle_masked_flow_bits(struct flow *flow, const struct flow_wildcards *mask)
1223 {
1224     const uint32_t *mask_u32 = (const uint32_t *) &mask->masks;
1225     uint32_t *flow_u32 = (uint32_t *) flow;
1226     int i;
1227
1228     for (i = 0; i < FLOW_U32S; i++) {
1229         if (mask_u32[i] != 0) {
1230             uint32_t bit;
1231
1232             do {
1233                 bit = 1u << random_range(32);
1234             } while (!(bit & mask_u32[i]));
1235             flow_u32[i] ^= bit;
1236         }
1237     }
1238 }
1239
1240 static void
1241 wildcard_extra_bits(struct flow_wildcards *mask)
1242 {
1243     uint32_t *mask_u32 = (uint32_t *) &mask->masks;
1244     int i;
1245
1246     for (i = 0; i < FLOW_U32S; i++) {
1247         if (mask_u32[i] != 0) {
1248             uint32_t bit;
1249
1250             do {
1251                 bit = 1u << random_range(32);
1252             } while (!(bit & mask_u32[i]));
1253             mask_u32[i] &= ~bit;
1254         }
1255     }
1256 }
1257
1258 static void
1259 test_miniflow(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1260 {
1261     struct flow flow;
1262     unsigned int idx;
1263
1264     random_set_seed(0xb3faca38);
1265     for (idx = 0; next_random_flow(&flow, idx); idx++) {
1266         const uint32_t *flow_u32 = (const uint32_t *) &flow;
1267         struct miniflow miniflow, miniflow2, miniflow3;
1268         struct flow flow2, flow3;
1269         struct flow_wildcards mask;
1270         struct minimask minimask;
1271         int i;
1272
1273         /* Convert flow to miniflow. */
1274         miniflow_init(&miniflow, &flow);
1275
1276         /* Check that the flow equals its miniflow. */
1277         assert(miniflow_get_vid(&miniflow) == vlan_tci_to_vid(flow.vlan_tci));
1278         for (i = 0; i < FLOW_U32S; i++) {
1279             assert(MINIFLOW_GET_TYPE(&miniflow, uint32_t, i * 4)
1280                    == flow_u32[i]);
1281         }
1282
1283         /* Check that the miniflow equals itself. */
1284         assert(miniflow_equal(&miniflow, &miniflow));
1285
1286         /* Convert miniflow back to flow and verify that it's the same. */
1287         miniflow_expand(&miniflow, &flow2);
1288         assert(flow_equal(&flow, &flow2));
1289
1290         /* Check that copying a miniflow works properly. */
1291         miniflow_clone(&miniflow2, &miniflow);
1292         assert(miniflow_equal(&miniflow, &miniflow2));
1293         assert(miniflow_hash(&miniflow, 0) == miniflow_hash(&miniflow2, 0));
1294         miniflow_expand(&miniflow2, &flow3);
1295         assert(flow_equal(&flow, &flow3));
1296
1297         /* Check that masked matches work as expected for identical flows and
1298          * miniflows. */
1299         do {
1300             next_random_flow(&mask.masks, 1);
1301         } while (flow_wildcards_is_catchall(&mask));
1302         minimask_init(&minimask, &mask);
1303         assert(minimask_is_catchall(&minimask)
1304                == flow_wildcards_is_catchall(&mask));
1305         assert(miniflow_equal_in_minimask(&miniflow, &miniflow2, &minimask));
1306         assert(miniflow_equal_flow_in_minimask(&miniflow, &flow2, &minimask));
1307         assert(miniflow_hash_in_minimask(&miniflow, &minimask, 0x12345678) ==
1308                flow_hash_in_minimask(&flow, &minimask, 0x12345678));
1309
1310         /* Check that masked matches work as expected for differing flows and
1311          * miniflows. */
1312         toggle_masked_flow_bits(&flow2, &mask);
1313         assert(!miniflow_equal_flow_in_minimask(&miniflow, &flow2, &minimask));
1314         miniflow_init(&miniflow3, &flow2);
1315         assert(!miniflow_equal_in_minimask(&miniflow, &miniflow3, &minimask));
1316
1317         /* Clean up. */
1318         miniflow_destroy(&miniflow);
1319         miniflow_destroy(&miniflow2);
1320         miniflow_destroy(&miniflow3);
1321         minimask_destroy(&minimask);
1322     }
1323 }
1324
1325 static void
1326 test_minimask_has_extra(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1327 {
1328     struct flow_wildcards catchall;
1329     struct minimask minicatchall;
1330     struct flow flow;
1331     unsigned int idx;
1332
1333     flow_wildcards_init_catchall(&catchall);
1334     minimask_init(&minicatchall, &catchall);
1335     assert(minimask_is_catchall(&minicatchall));
1336
1337     random_set_seed(0x2ec7905b);
1338     for (idx = 0; next_random_flow(&flow, idx); idx++) {
1339         struct flow_wildcards mask;
1340         struct minimask minimask;
1341
1342         mask.masks = flow;
1343         minimask_init(&minimask, &mask);
1344         assert(!minimask_has_extra(&minimask, &minimask));
1345         assert(minimask_has_extra(&minicatchall, &minimask)
1346                == !minimask_is_catchall(&minimask));
1347         if (!minimask_is_catchall(&minimask)) {
1348             struct minimask minimask2;
1349
1350             wildcard_extra_bits(&mask);
1351             minimask_init(&minimask2, &mask);
1352             assert(minimask_has_extra(&minimask2, &minimask));
1353             assert(!minimask_has_extra(&minimask, &minimask2));
1354             minimask_destroy(&minimask2);
1355         }
1356
1357         minimask_destroy(&minimask);
1358     }
1359
1360     minimask_destroy(&minicatchall);
1361 }
1362
1363 static void
1364 test_minimask_combine(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1365 {
1366     struct flow_wildcards catchall;
1367     struct minimask minicatchall;
1368     struct flow flow;
1369     unsigned int idx;
1370
1371     flow_wildcards_init_catchall(&catchall);
1372     minimask_init(&minicatchall, &catchall);
1373     assert(minimask_is_catchall(&minicatchall));
1374
1375     random_set_seed(0x181bf0cd);
1376     for (idx = 0; next_random_flow(&flow, idx); idx++) {
1377         struct minimask minimask, minimask2, minicombined;
1378         struct flow_wildcards mask, mask2, combined, combined2;
1379         uint32_t storage[FLOW_U32S];
1380         struct flow flow2;
1381
1382         mask.masks = flow;
1383         minimask_init(&minimask, &mask);
1384
1385         minimask_combine(&minicombined, &minimask, &minicatchall, storage);
1386         assert(minimask_is_catchall(&minicombined));
1387
1388         any_random_flow(&flow2);
1389         mask2.masks = flow2;
1390         minimask_init(&minimask2, &mask2);
1391
1392         minimask_combine(&minicombined, &minimask, &minimask2, storage);
1393         flow_wildcards_and(&combined, &mask, &mask2);
1394         minimask_expand(&minicombined, &combined2);
1395         assert(flow_wildcards_equal(&combined, &combined2));
1396
1397         minimask_destroy(&minimask);
1398         minimask_destroy(&minimask2);
1399     }
1400
1401     minimask_destroy(&minicatchall);
1402 }
1403 \f
1404 static const struct command commands[] = {
1405     /* Classifier tests. */
1406     {"empty", NULL, 0, 0, test_empty},
1407     {"destroy-null", NULL, 0, 0, test_destroy_null},
1408     {"single-rule", NULL, 0, 0, test_single_rule},
1409     {"rule-replacement", NULL, 0, 0, test_rule_replacement},
1410     {"many-rules-in-one-list", NULL, 0, 0, test_many_rules_in_one_list},
1411     {"many-rules-in-one-table", NULL, 0, 0, test_many_rules_in_one_table},
1412     {"many-rules-in-two-tables", NULL, 0, 0, test_many_rules_in_two_tables},
1413     {"many-rules-in-five-tables", NULL, 0, 0, test_many_rules_in_five_tables},
1414
1415     /* Miniflow and minimask tests. */
1416     {"miniflow", NULL, 0, 0, test_miniflow},
1417     {"minimask_has_extra", NULL, 0, 0, test_minimask_has_extra},
1418     {"minimask_combine", NULL, 0, 0, test_minimask_combine},
1419
1420     {NULL, NULL, 0, 0, NULL},
1421 };
1422
1423 static void
1424 test_classifier_main(int argc, char *argv[])
1425 {
1426     set_program_name(argv[0]);
1427     init_values();
1428     run_command(argc - 1, argv + 1, commands);
1429 }
1430
1431 OVSTEST_REGISTER("test-classifier", test_classifier_main);