unsigned int *checkbits);
static unsigned int trie_lookup_value(const struct trie_node *,
const ovs_be32 value[],
+ unsigned int value_bits,
unsigned int *checkbits);
static void trie_destroy(struct trie_node *);
static void trie_insert(struct cls_trie *, const struct cls_rule *, int mlen);
mask = MINIFLOW_GET_BE32(&subtable->mask.masks, tp_src);
value = ((OVS_FORCE ovs_be32 *)flow)[TP_PORTS_OFS32] & mask;
- trie_lookup_value(subtable->ports_trie, &value, &mbits);
+ trie_lookup_value(subtable->ports_trie, &value, 32, &mbits);
((OVS_FORCE ovs_be32 *)&wc->masks)[TP_PORTS_OFS32] |=
mask & htonl(~0 << (32 - mbits));
*/
static unsigned int
trie_lookup_value(const struct trie_node *node, const ovs_be32 value[],
- unsigned int *checkbits)
+ unsigned int n_bits, unsigned int *checkbits)
{
- unsigned int plen = 0, match_len = 0;
+ unsigned int ofs = 0, match_len = 0;
const struct trie_node *prev = NULL;
- for (; node; prev = node, node = trie_next_node(node, value, plen)) {
+ for (; node; prev = node, node = trie_next_node(node, value, ofs)) {
unsigned int eqbits;
/* Check if this edge can be followed. */
- eqbits = prefix_equal_bits(node->prefix, node->nbits, value, plen);
- plen += eqbits;
+ eqbits = prefix_equal_bits(node->prefix, node->nbits, value, ofs);
+ ofs += eqbits;
if (eqbits < node->nbits) { /* Mismatch, nothing more to be found. */
- /* Bit at offset 'plen' differed. */
- *checkbits = plen + 1; /* Includes the first mismatching bit. */
+ /* Bit at offset 'ofs' differed. */
+ *checkbits = ofs + 1; /* Includes the first mismatching bit. */
return match_len;
}
/* Full match, check if rules exist at this prefix length. */
if (node->n_rules > 0) {
- match_len = plen;
+ match_len = ofs;
+ }
+ if (ofs >= n_bits) {
+ *checkbits = n_bits; /* Full prefix. */
+ return match_len;
}
}
- /* Dead end, exclude the other branch if it exists. */
- *checkbits = !prev || trie_is_leaf(prev) ? plen : plen + 1;
+ /* node == NULL. Full match so far, but we came to a dead end.
+ * need to exclude the other branch if it exists. */
+ *checkbits = !prev || trie_is_leaf(prev) ? ofs : ofs + 1;
return match_len;
}
if (mf_are_prereqs_ok(mf, flow)) {
return trie_lookup_value(trie->root,
&((ovs_be32 *)flow)[mf->flow_be32ofs],
- checkbits);
+ mf->n_bits, checkbits);
}
*checkbits = 0; /* Value not used in this case. */
return UINT_MAX;