Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/net/npf/npf_tableset.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/net/npf/npf_tableset.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.23 retrieving revision 1.24 diff -u -p -r1.23 -r1.24 --- src/sys/net/npf/npf_tableset.c 2016/04/20 15:46:08 1.23 +++ src/sys/net/npf/npf_tableset.c 2016/12/09 02:40:38 1.24 @@ -1,7 +1,7 @@ -/* $NetBSD: npf_tableset.c,v 1.23 2016/04/20 15:46:08 christos Exp $ */ +/* $NetBSD: npf_tableset.c,v 1.24 2016/12/09 02:40:38 christos Exp $ */ /*- - * Copyright (c) 2009-2014 The NetBSD Foundation, Inc. + * Copyright (c) 2009-2016 The NetBSD Foundation, Inc. * All rights reserved. * * This material is based upon work partially supported by The @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.23 2016/04/20 15:46:08 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.24 2016/12/09 02:40:38 christos Exp $"); #include #include @@ -58,13 +58,12 @@ __KERNEL_RCSID(0, "$NetBSD: npf_tableset #include #include "npf_impl.h" +#include "lpm.h" typedef struct npf_tblent { - union { - LIST_ENTRY(npf_tblent) te_hashent; - pt_node_t te_node; - } /* C11 */; - int te_alen; + LIST_ENTRY(npf_tblent) te_listent; + uint16_t te_preflen; + uint16_t te_alen; npf_addr_t te_addr; } npf_tblent_t; @@ -81,7 +80,8 @@ struct npf_table { u_long t_hashmask; }; struct { - pt_tree_t t_tree[2]; + lpm_t * t_lpm; + LIST_HEAD(, npf_tblent) t_list; }; struct { void * t_blob; @@ -294,7 +294,7 @@ table_hash_lookup(const npf_table_t *t, * Lookup the hash table and check for duplicates. * Note: mask is ignored for the hash storage. */ - LIST_FOREACH(ent, htbl, te_hashent) { + LIST_FOREACH(ent, htbl, te_listent) { if (ent->te_alen != alen) { continue; } @@ -307,27 +307,28 @@ table_hash_lookup(const npf_table_t *t, } static void -table_hash_destroy(npf_table_t *t) +table_hash_flush(npf_table_t *t) { for (unsigned n = 0; n <= t->t_hashmask; n++) { npf_tblent_t *ent; while ((ent = LIST_FIRST(&t->t_hashl[n])) != NULL) { - LIST_REMOVE(ent, te_hashent); + LIST_REMOVE(ent, te_listent); pool_cache_put(tblent_cache, ent); } } } static void -table_tree_destroy(pt_tree_t *tree) +table_tree_flush(npf_table_t *t) { npf_tblent_t *ent; - while ((ent = ptree_iterate(tree, NULL, PT_ASCENDING)) != NULL) { - ptree_remove_node(tree, ent); + while ((ent = LIST_FIRST(&t->t_list)) != NULL) { + LIST_REMOVE(ent, te_listent); pool_cache_put(tblent_cache, ent); } + lpm_clear(t->t_lpm, NULL, NULL); } /* @@ -339,35 +340,27 @@ npf_table_create(const char *name, u_int { npf_table_t *t; - t = kmem_zalloc(sizeof(npf_table_t), KM_SLEEP); + t = kmem_zalloc(sizeof(*t), KM_SLEEP); strlcpy(t->t_name, name, NPF_TABLE_MAXNAMELEN); switch (type) { case NPF_TABLE_TREE: - ptree_init(&t->t_tree[0], &npf_table_ptree_ops, - (void *)(sizeof(struct in_addr) / sizeof(uint32_t)), - offsetof(npf_tblent_t, te_node), - offsetof(npf_tblent_t, te_addr)); - ptree_init(&t->t_tree[1], &npf_table_ptree_ops, - (void *)(sizeof(struct in6_addr) / sizeof(uint32_t)), - offsetof(npf_tblent_t, te_node), - offsetof(npf_tblent_t, te_addr)); + if ((t->t_lpm = lpm_create()) == NULL) + goto out; + LIST_INIT(&t->t_list); break; case NPF_TABLE_HASH: t->t_hashl = hashinit(1024, HASH_LIST, true, &t->t_hashmask); - if (t->t_hashl == NULL) { - kmem_free(t, sizeof(npf_table_t)); - return NULL; - } + if (t->t_hashl == NULL) + goto out; break; case NPF_TABLE_CDB: t->t_blob = blob; t->t_bsize = size; t->t_cdb = cdbr_open_mem(blob, size, CDBR_DEFAULT, NULL, NULL); if (t->t_cdb == NULL) { - kmem_free(t, sizeof(npf_table_t)); free(blob, M_TEMP); - return NULL; + goto out; } t->t_nitems = cdbr_entries(t->t_cdb); break; @@ -379,6 +372,10 @@ npf_table_create(const char *name, u_int t->t_id = tid; return t; +out: + kmem_free(t, sizeof(*t)); + return NULL; + } /* @@ -391,12 +388,12 @@ npf_table_destroy(npf_table_t *t) switch (t->t_type) { case NPF_TABLE_HASH: - table_hash_destroy(t); + table_hash_flush(t); hashdone(t->t_hashl, HASH_LIST, t->t_hashmask); break; case NPF_TABLE_TREE: - table_tree_destroy(&t->t_tree[0]); - table_tree_destroy(&t->t_tree[1]); + table_tree_flush(t); + lpm_destroy(t->t_lpm); break; case NPF_TABLE_CDB: cdbr_close(t->t_cdb); @@ -406,7 +403,7 @@ npf_table_destroy(npf_table_t *t) KASSERT(false); } rw_destroy(&t->t_lock); - kmem_free(t, sizeof(npf_table_t)); + kmem_free(t, sizeof(*t)); } /* @@ -494,7 +491,7 @@ npf_table_insert(npf_table_t *t, const i break; } if (!table_hash_lookup(t, addr, alen, &htbl)) { - LIST_INSERT_HEAD(htbl, ent, te_hashent); + LIST_INSERT_HEAD(htbl, ent, te_listent); t->t_nitems++; } else { error = EEXIST; @@ -502,16 +499,12 @@ npf_table_insert(npf_table_t *t, const i break; } case NPF_TABLE_TREE: { - pt_tree_t *tree = &t->t_tree[aidx]; - bool ok; - - /* - * If no mask specified, use maximum mask. - */ - ok = (mask != NPF_NO_NETMASK) ? - ptree_insert_mask_node(tree, ent, mask) : - ptree_insert_node(tree, ent); - if (ok) { + const unsigned preflen = + (mask == NPF_NO_NETMASK) ? (alen * 8) : mask; + if (lpm_lookup(t->t_lpm, addr, alen) == NULL && + lpm_insert(t->t_lpm, addr, alen, preflen, ent) == 0) { + LIST_INSERT_HEAD(&t->t_list, ent, te_listent); + ent->te_preflen = preflen; t->t_nitems++; error = 0; } else { @@ -556,17 +549,17 @@ npf_table_remove(npf_table_t *t, const i ent = table_hash_lookup(t, addr, alen, &htbl); if (__predict_true(ent != NULL)) { - LIST_REMOVE(ent, te_hashent); + LIST_REMOVE(ent, te_listent); t->t_nitems--; } break; } case NPF_TABLE_TREE: { - pt_tree_t *tree = &t->t_tree[aidx]; - - ent = ptree_find_node(tree, addr); + ent = lpm_lookup(t->t_lpm, addr, alen); if (__predict_true(ent != NULL)) { - ptree_remove_node(tree, ent); + LIST_REMOVE(ent, te_listent); + lpm_remove(t->t_lpm, &ent->te_addr, + ent->te_alen, ent->te_preflen); t->t_nitems--; } break; @@ -611,7 +604,7 @@ npf_table_lookup(npf_table_t *t, const i break; case NPF_TABLE_TREE: rw_enter(&t->t_lock, RW_READER); - found = ptree_find_node(&t->t_tree[aidx], addr) != NULL; + found = lpm_lookup(t->t_lpm, addr, alen) != NULL; rw_exit(&t->t_lock); break; case NPF_TABLE_CDB: @@ -655,7 +648,7 @@ table_hash_list(const npf_table_t *t, vo for (unsigned n = 0; n <= t->t_hashmask; n++) { npf_tblent_t *ent; - LIST_FOREACH(ent, &t->t_hashl[n], te_hashent) { + LIST_FOREACH(ent, &t->t_hashl[n], te_listent) { error = table_ent_copyout(&ent->te_addr, ent->te_alen, 0, ubuf, len, &off); if (error) @@ -666,20 +659,15 @@ table_hash_list(const npf_table_t *t, vo } static int -table_tree_list(pt_tree_t *tree, npf_netmask_t maxmask, void *ubuf, - size_t len, size_t *off) +table_tree_list(const npf_table_t *t, void *ubuf, size_t len) { - npf_tblent_t *ent = NULL; + npf_tblent_t *ent; + size_t off = 0; int error = 0; - while ((ent = ptree_iterate(tree, ent, PT_ASCENDING)) != NULL) { - pt_bitlen_t blen; - - if (!ptree_mask_node_p(tree, ent, &blen)) { - blen = maxmask; - } - error = table_ent_copyout(&ent->te_addr, ent->te_alen, - blen, ubuf, len, off); + LIST_FOREACH(ent, &t->t_list, te_listent) { + error = table_ent_copyout(&ent->te_addr, + ent->te_alen, 0, ubuf, len, &off); if (error) break; } @@ -710,7 +698,6 @@ table_cdb_list(npf_table_t *t, void *ubu int npf_table_list(npf_table_t *t, void *ubuf, size_t len) { - size_t off = 0; int error = 0; rw_enter(&t->t_lock, RW_READER); @@ -719,10 +706,7 @@ npf_table_list(npf_table_t *t, void *ubu error = table_hash_list(t, ubuf, len); break; case NPF_TABLE_TREE: - error = table_tree_list(&t->t_tree[0], 32, ubuf, len, &off); - if (error) - break; - error = table_tree_list(&t->t_tree[1], 128, ubuf, len, &off); + error = table_tree_list(t, ubuf, len); break; case NPF_TABLE_CDB: error = table_cdb_list(t, ubuf, len); @@ -746,12 +730,11 @@ npf_table_flush(npf_table_t *t) rw_enter(&t->t_lock, RW_WRITER); switch (t->t_type) { case NPF_TABLE_HASH: - table_hash_destroy(t); + table_hash_flush(t); t->t_nitems = 0; break; case NPF_TABLE_TREE: - table_tree_destroy(&t->t_tree[0]); - table_tree_destroy(&t->t_tree[1]); + table_tree_flush(t); t->t_nitems = 0; break; case NPF_TABLE_CDB: