aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c91
1 files changed, 40 insertions, 51 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 4a8e370862bc..200eb538fbb3 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -16,7 +16,7 @@
16 * 16 *
17 * An experimental study of compression methods for dynamic tries 17 * An experimental study of compression methods for dynamic tries
18 * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. 18 * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
19 * http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/ 19 * http://www.csc.kth.se/~snilsson/software/dyntrie2/
20 * 20 *
21 * 21 *
22 * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson 22 * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
@@ -186,9 +186,7 @@ static inline struct tnode *node_parent_rcu(struct node *node)
186{ 186{
187 struct tnode *ret = node_parent(node); 187 struct tnode *ret = node_parent(node);
188 188
189 return rcu_dereference_check(ret, 189 return rcu_dereference_rtnl(ret);
190 rcu_read_lock_held() ||
191 lockdep_rtnl_is_held());
192} 190}
193 191
194/* Same as rcu_assign_pointer 192/* Same as rcu_assign_pointer
@@ -211,9 +209,7 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
211{ 209{
212 struct node *ret = tnode_get_child(tn, i); 210 struct node *ret = tnode_get_child(tn, i);
213 211
214 return rcu_dereference_check(ret, 212 return rcu_dereference_rtnl(ret);
215 rcu_read_lock_held() ||
216 lockdep_rtnl_is_held());
217} 213}
218 214
219static inline int tnode_child_length(const struct tnode *tn) 215static inline int tnode_child_length(const struct tnode *tn)
@@ -459,8 +455,8 @@ static struct tnode *tnode_new(t_key key, int pos, int bits)
459 tn->empty_children = 1<<bits; 455 tn->empty_children = 1<<bits;
460 } 456 }
461 457
462 pr_debug("AT %p s=%u %lu\n", tn, (unsigned int) sizeof(struct tnode), 458 pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode),
463 (unsigned long) (sizeof(struct node) << bits)); 459 sizeof(struct node) << bits);
464 return tn; 460 return tn;
465} 461}
466 462
@@ -609,11 +605,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
609 605
610 /* Keep root node larger */ 606 /* Keep root node larger */
611 607
612 if (!node_parent((struct node*) tn)) { 608 if (!node_parent((struct node *)tn)) {
613 inflate_threshold_use = inflate_threshold_root; 609 inflate_threshold_use = inflate_threshold_root;
614 halve_threshold_use = halve_threshold_root; 610 halve_threshold_use = halve_threshold_root;
615 } 611 } else {
616 else {
617 inflate_threshold_use = inflate_threshold; 612 inflate_threshold_use = inflate_threshold;
618 halve_threshold_use = halve_threshold; 613 halve_threshold_use = halve_threshold;
619 } 614 }
@@ -639,7 +634,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
639 check_tnode(tn); 634 check_tnode(tn);
640 635
641 /* Return if at least one inflate is run */ 636 /* Return if at least one inflate is run */
642 if( max_work != MAX_WORK) 637 if (max_work != MAX_WORK)
643 return (struct node *) tn; 638 return (struct node *) tn;
644 639
645 /* 640 /*
@@ -966,9 +961,7 @@ fib_find_node(struct trie *t, u32 key)
966 struct node *n; 961 struct node *n;
967 962
968 pos = 0; 963 pos = 0;
969 n = rcu_dereference_check(t->trie, 964 n = rcu_dereference_rtnl(t->trie);
970 rcu_read_lock_held() ||
971 lockdep_rtnl_is_held());
972 965
973 while (n != NULL && NODE_TYPE(n) == T_TNODE) { 966 while (n != NULL && NODE_TYPE(n) == T_TNODE) {
974 tn = (struct tnode *) n; 967 tn = (struct tnode *) n;
@@ -1349,7 +1342,7 @@ err:
1349/* should be called with rcu_read_lock */ 1342/* should be called with rcu_read_lock */
1350static int check_leaf(struct trie *t, struct leaf *l, 1343static int check_leaf(struct trie *t, struct leaf *l,
1351 t_key key, const struct flowi *flp, 1344 t_key key, const struct flowi *flp,
1352 struct fib_result *res) 1345 struct fib_result *res, int fib_flags)
1353{ 1346{
1354 struct leaf_info *li; 1347 struct leaf_info *li;
1355 struct hlist_head *hhead = &l->list; 1348 struct hlist_head *hhead = &l->list;
@@ -1363,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
1363 if (l->key != (key & ntohl(mask))) 1356 if (l->key != (key & ntohl(mask)))
1364 continue; 1357 continue;
1365 1358
1366 err = fib_semantic_match(&li->falh, flp, res, plen); 1359 err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags);
1367 1360
1368#ifdef CONFIG_IP_FIB_TRIE_STATS 1361#ifdef CONFIG_IP_FIB_TRIE_STATS
1369 if (err <= 0) 1362 if (err <= 0)
@@ -1379,7 +1372,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
1379} 1372}
1380 1373
1381int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, 1374int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1382 struct fib_result *res) 1375 struct fib_result *res, int fib_flags)
1383{ 1376{
1384 struct trie *t = (struct trie *) tb->tb_data; 1377 struct trie *t = (struct trie *) tb->tb_data;
1385 int ret; 1378 int ret;
@@ -1391,8 +1384,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1391 t_key cindex = 0; 1384 t_key cindex = 0;
1392 int current_prefix_length = KEYLENGTH; 1385 int current_prefix_length = KEYLENGTH;
1393 struct tnode *cn; 1386 struct tnode *cn;
1394 t_key node_prefix, key_prefix, pref_mismatch; 1387 t_key pref_mismatch;
1395 int mp;
1396 1388
1397 rcu_read_lock(); 1389 rcu_read_lock();
1398 1390
@@ -1406,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1406 1398
1407 /* Just a leaf? */ 1399 /* Just a leaf? */
1408 if (IS_LEAF(n)) { 1400 if (IS_LEAF(n)) {
1409 ret = check_leaf(t, (struct leaf *)n, key, flp, res); 1401 ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
1410 goto found; 1402 goto found;
1411 } 1403 }
1412 1404
@@ -1431,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1431 } 1423 }
1432 1424
1433 if (IS_LEAF(n)) { 1425 if (IS_LEAF(n)) {
1434 ret = check_leaf(t, (struct leaf *)n, key, flp, res); 1426 ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
1435 if (ret > 0) 1427 if (ret > 0)
1436 goto backtrace; 1428 goto backtrace;
1437 goto found; 1429 goto found;
@@ -1507,10 +1499,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1507 * matching prefix. 1499 * matching prefix.
1508 */ 1500 */
1509 1501
1510 node_prefix = mask_pfx(cn->key, cn->pos); 1502 pref_mismatch = mask_pfx(cn->key ^ key, cn->pos);
1511 key_prefix = mask_pfx(key, cn->pos);
1512 pref_mismatch = key_prefix^node_prefix;
1513 mp = 0;
1514 1503
1515 /* 1504 /*
1516 * In short: If skipped bits in this node do not match 1505 * In short: If skipped bits in this node do not match
@@ -1518,13 +1507,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1518 * state.directly. 1507 * state.directly.
1519 */ 1508 */
1520 if (pref_mismatch) { 1509 if (pref_mismatch) {
1521 while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) { 1510 int mp = KEYLENGTH - fls(pref_mismatch);
1522 mp++;
1523 pref_mismatch = pref_mismatch << 1;
1524 }
1525 key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
1526 1511
1527 if (key_prefix != 0) 1512 if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0)
1528 goto backtrace; 1513 goto backtrace;
1529 1514
1530 if (current_prefix_length >= cn->pos) 1515 if (current_prefix_length >= cn->pos)
@@ -1748,16 +1733,14 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c)
1748 1733
1749 /* Node empty, walk back up to parent */ 1734 /* Node empty, walk back up to parent */
1750 c = (struct node *) p; 1735 c = (struct node *) p;
1751 } while ( (p = node_parent_rcu(c)) != NULL); 1736 } while ((p = node_parent_rcu(c)) != NULL);
1752 1737
1753 return NULL; /* Root of trie */ 1738 return NULL; /* Root of trie */
1754} 1739}
1755 1740
1756static struct leaf *trie_firstleaf(struct trie *t) 1741static struct leaf *trie_firstleaf(struct trie *t)
1757{ 1742{
1758 struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, 1743 struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie);
1759 rcu_read_lock_held() ||
1760 lockdep_rtnl_is_held());
1761 1744
1762 if (!n) 1745 if (!n)
1763 return NULL; 1746 return NULL;
@@ -1814,6 +1797,11 @@ int fib_table_flush(struct fib_table *tb)
1814 return found; 1797 return found;
1815} 1798}
1816 1799
1800void fib_free_table(struct fib_table *tb)
1801{
1802 kfree(tb);
1803}
1804
1817void fib_table_select_default(struct fib_table *tb, 1805void fib_table_select_default(struct fib_table *tb,
1818 const struct flowi *flp, 1806 const struct flowi *flp,
1819 struct fib_result *res) 1807 struct fib_result *res)
@@ -1855,7 +1843,8 @@ void fib_table_select_default(struct fib_table *tb,
1855 if (!next_fi->fib_nh[0].nh_gw || 1843 if (!next_fi->fib_nh[0].nh_gw ||
1856 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) 1844 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
1857 continue; 1845 continue;
1858 fa->fa_state |= FA_S_ACCESSED; 1846
1847 fib_alias_accessed(fa);
1859 1848
1860 if (fi == NULL) { 1849 if (fi == NULL) {
1861 if (next_fi != res->fi) 1850 if (next_fi != res->fi)
@@ -2043,14 +2032,14 @@ struct fib_trie_iter {
2043 struct seq_net_private p; 2032 struct seq_net_private p;
2044 struct fib_table *tb; 2033 struct fib_table *tb;
2045 struct tnode *tnode; 2034 struct tnode *tnode;
2046 unsigned index; 2035 unsigned int index;
2047 unsigned depth; 2036 unsigned int depth;
2048}; 2037};
2049 2038
2050static struct node *fib_trie_get_next(struct fib_trie_iter *iter) 2039static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
2051{ 2040{
2052 struct tnode *tn = iter->tnode; 2041 struct tnode *tn = iter->tnode;
2053 unsigned cindex = iter->index; 2042 unsigned int cindex = iter->index;
2054 struct tnode *p; 2043 struct tnode *p;
2055 2044
2056 /* A single entry routing table */ 2045 /* A single entry routing table */
@@ -2159,7 +2148,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s)
2159 */ 2148 */
2160static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) 2149static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
2161{ 2150{
2162 unsigned i, max, pointers, bytes, avdepth; 2151 unsigned int i, max, pointers, bytes, avdepth;
2163 2152
2164 if (stat->leaves) 2153 if (stat->leaves)
2165 avdepth = stat->totdepth*100 / stat->leaves; 2154 avdepth = stat->totdepth*100 / stat->leaves;
@@ -2356,7 +2345,8 @@ static void fib_trie_seq_stop(struct seq_file *seq, void *v)
2356 2345
2357static void seq_indent(struct seq_file *seq, int n) 2346static void seq_indent(struct seq_file *seq, int n)
2358{ 2347{
2359 while (n-- > 0) seq_puts(seq, " "); 2348 while (n-- > 0)
2349 seq_puts(seq, " ");
2360} 2350}
2361 2351
2362static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s) 2352static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
@@ -2388,7 +2378,7 @@ static const char *const rtn_type_names[__RTN_MAX] = {
2388 [RTN_XRESOLVE] = "XRESOLVE", 2378 [RTN_XRESOLVE] = "XRESOLVE",
2389}; 2379};
2390 2380
2391static inline const char *rtn_type(char *buf, size_t len, unsigned t) 2381static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
2392{ 2382{
2393 if (t < __RTN_MAX && rtn_type_names[t]) 2383 if (t < __RTN_MAX && rtn_type_names[t])
2394 return rtn_type_names[t]; 2384 return rtn_type_names[t];
@@ -2544,13 +2534,12 @@ static void fib_route_seq_stop(struct seq_file *seq, void *v)
2544 rcu_read_unlock(); 2534 rcu_read_unlock();
2545} 2535}
2546 2536
2547static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) 2537static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
2548{ 2538{
2549 static unsigned type2flags[RTN_MAX + 1] = { 2539 unsigned int flags = 0;
2550 [7] = RTF_REJECT, [8] = RTF_REJECT,
2551 };
2552 unsigned flags = type2flags[type];
2553 2540
2541 if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT)
2542 flags = RTF_REJECT;
2554 if (fi && fi->fib_nh->nh_gw) 2543 if (fi && fi->fib_nh->nh_gw)
2555 flags |= RTF_GATEWAY; 2544 flags |= RTF_GATEWAY;
2556 if (mask == htonl(0xFFFFFFFF)) 2545 if (mask == htonl(0xFFFFFFFF))
@@ -2562,7 +2551,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
2562/* 2551/*
2563 * This outputs /proc/net/route. 2552 * This outputs /proc/net/route.
2564 * The format of the file is not supposed to be changed 2553 * The format of the file is not supposed to be changed
2565 * and needs to be same as fib_hash output to avoid breaking 2554 * and needs to be same as fib_hash output to avoid breaking
2566 * legacy utilities 2555 * legacy utilities
2567 */ 2556 */
2568static int fib_route_seq_show(struct seq_file *seq, void *v) 2557static int fib_route_seq_show(struct seq_file *seq, void *v)
@@ -2587,7 +2576,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2587 2576
2588 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2577 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2589 const struct fib_info *fi = fa->fa_info; 2578 const struct fib_info *fi = fa->fa_info;
2590 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); 2579 unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi);
2591 int len; 2580 int len;
2592 2581
2593 if (fa->fa_type == RTN_BROADCAST 2582 if (fa->fa_type == RTN_BROADCAST