diff options
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r-- | net/ipv4/fib_trie.c | 287 |
1 files changed, 121 insertions, 166 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0f280348e0fd..5fe9b8b41df3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | * Hans Liss <hans.liss@its.uu.se> Uppsala Universitet | 13 | * Hans Liss <hans.liss@its.uu.se> Uppsala Universitet |
14 | * | 14 | * |
15 | * This work is based on the LPC-trie which is originally descibed in: | 15 | * This work is based on the LPC-trie which is originally described in: |
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. |
@@ -95,7 +95,7 @@ typedef unsigned int t_key; | |||
95 | #define IS_TNODE(n) (!(n->parent & T_LEAF)) | 95 | #define IS_TNODE(n) (!(n->parent & T_LEAF)) |
96 | #define IS_LEAF(n) (n->parent & T_LEAF) | 96 | #define IS_LEAF(n) (n->parent & T_LEAF) |
97 | 97 | ||
98 | struct node { | 98 | struct rt_trie_node { |
99 | unsigned long parent; | 99 | unsigned long parent; |
100 | t_key key; | 100 | t_key key; |
101 | }; | 101 | }; |
@@ -126,7 +126,7 @@ struct tnode { | |||
126 | struct work_struct work; | 126 | struct work_struct work; |
127 | struct tnode *tnode_free; | 127 | struct tnode *tnode_free; |
128 | }; | 128 | }; |
129 | struct node *child[0]; | 129 | struct rt_trie_node *child[0]; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 132 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
@@ -151,16 +151,16 @@ struct trie_stat { | |||
151 | }; | 151 | }; |
152 | 152 | ||
153 | struct trie { | 153 | struct trie { |
154 | struct node *trie; | 154 | struct rt_trie_node *trie; |
155 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 155 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
156 | struct trie_use_stats stats; | 156 | struct trie_use_stats stats; |
157 | #endif | 157 | #endif |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n); | 160 | static void put_child(struct trie *t, struct tnode *tn, int i, struct rt_trie_node *n); |
161 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, | 161 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n, |
162 | int wasfull); | 162 | int wasfull); |
163 | static struct node *resize(struct trie *t, struct tnode *tn); | 163 | static struct rt_trie_node *resize(struct trie *t, struct tnode *tn); |
164 | static struct tnode *inflate(struct trie *t, struct tnode *tn); | 164 | static struct tnode *inflate(struct trie *t, struct tnode *tn); |
165 | static struct tnode *halve(struct trie *t, struct tnode *tn); | 165 | static struct tnode *halve(struct trie *t, struct tnode *tn); |
166 | /* tnodes to free after resize(); protected by RTNL */ | 166 | /* tnodes to free after resize(); protected by RTNL */ |
@@ -177,12 +177,12 @@ static const int sync_pages = 128; | |||
177 | static struct kmem_cache *fn_alias_kmem __read_mostly; | 177 | static struct kmem_cache *fn_alias_kmem __read_mostly; |
178 | static struct kmem_cache *trie_leaf_kmem __read_mostly; | 178 | static struct kmem_cache *trie_leaf_kmem __read_mostly; |
179 | 179 | ||
180 | static inline struct tnode *node_parent(struct node *node) | 180 | static inline struct tnode *node_parent(struct rt_trie_node *node) |
181 | { | 181 | { |
182 | return (struct tnode *)(node->parent & ~NODE_TYPE_MASK); | 182 | return (struct tnode *)(node->parent & ~NODE_TYPE_MASK); |
183 | } | 183 | } |
184 | 184 | ||
185 | static inline struct tnode *node_parent_rcu(struct node *node) | 185 | static inline struct tnode *node_parent_rcu(struct rt_trie_node *node) |
186 | { | 186 | { |
187 | struct tnode *ret = node_parent(node); | 187 | struct tnode *ret = node_parent(node); |
188 | 188 | ||
@@ -192,22 +192,22 @@ static inline struct tnode *node_parent_rcu(struct node *node) | |||
192 | /* Same as rcu_assign_pointer | 192 | /* Same as rcu_assign_pointer |
193 | * but that macro() assumes that value is a pointer. | 193 | * but that macro() assumes that value is a pointer. |
194 | */ | 194 | */ |
195 | static inline void node_set_parent(struct node *node, struct tnode *ptr) | 195 | static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr) |
196 | { | 196 | { |
197 | smp_wmb(); | 197 | smp_wmb(); |
198 | node->parent = (unsigned long)ptr | NODE_TYPE(node); | 198 | node->parent = (unsigned long)ptr | NODE_TYPE(node); |
199 | } | 199 | } |
200 | 200 | ||
201 | static inline struct node *tnode_get_child(struct tnode *tn, unsigned int i) | 201 | static inline struct rt_trie_node *tnode_get_child(struct tnode *tn, unsigned int i) |
202 | { | 202 | { |
203 | BUG_ON(i >= 1U << tn->bits); | 203 | BUG_ON(i >= 1U << tn->bits); |
204 | 204 | ||
205 | return tn->child[i]; | 205 | return tn->child[i]; |
206 | } | 206 | } |
207 | 207 | ||
208 | static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) | 208 | static inline struct rt_trie_node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) |
209 | { | 209 | { |
210 | struct node *ret = tnode_get_child(tn, i); | 210 | struct rt_trie_node *ret = tnode_get_child(tn, i); |
211 | 211 | ||
212 | return rcu_dereference_rtnl(ret); | 212 | return rcu_dereference_rtnl(ret); |
213 | } | 213 | } |
@@ -217,12 +217,12 @@ static inline int tnode_child_length(const struct tnode *tn) | |||
217 | return 1 << tn->bits; | 217 | return 1 << tn->bits; |
218 | } | 218 | } |
219 | 219 | ||
220 | static inline t_key mask_pfx(t_key k, unsigned short l) | 220 | static inline t_key mask_pfx(t_key k, unsigned int l) |
221 | { | 221 | { |
222 | return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l); | 222 | return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l); |
223 | } | 223 | } |
224 | 224 | ||
225 | static inline t_key tkey_extract_bits(t_key a, int offset, int bits) | 225 | static inline t_key tkey_extract_bits(t_key a, unsigned int offset, unsigned int bits) |
226 | { | 226 | { |
227 | if (offset < KEYLENGTH) | 227 | if (offset < KEYLENGTH) |
228 | return ((t_key)(a << offset)) >> (KEYLENGTH - bits); | 228 | return ((t_key)(a << offset)) >> (KEYLENGTH - bits); |
@@ -378,7 +378,7 @@ static void __tnode_free_rcu(struct rcu_head *head) | |||
378 | { | 378 | { |
379 | struct tnode *tn = container_of(head, struct tnode, rcu); | 379 | struct tnode *tn = container_of(head, struct tnode, rcu); |
380 | size_t size = sizeof(struct tnode) + | 380 | size_t size = sizeof(struct tnode) + |
381 | (sizeof(struct node *) << tn->bits); | 381 | (sizeof(struct rt_trie_node *) << tn->bits); |
382 | 382 | ||
383 | if (size <= PAGE_SIZE) | 383 | if (size <= PAGE_SIZE) |
384 | kfree(tn); | 384 | kfree(tn); |
@@ -402,7 +402,7 @@ static void tnode_free_safe(struct tnode *tn) | |||
402 | tn->tnode_free = tnode_free_head; | 402 | tn->tnode_free = tnode_free_head; |
403 | tnode_free_head = tn; | 403 | tnode_free_head = tn; |
404 | tnode_free_size += sizeof(struct tnode) + | 404 | tnode_free_size += sizeof(struct tnode) + |
405 | (sizeof(struct node *) << tn->bits); | 405 | (sizeof(struct rt_trie_node *) << tn->bits); |
406 | } | 406 | } |
407 | 407 | ||
408 | static void tnode_free_flush(void) | 408 | static void tnode_free_flush(void) |
@@ -443,7 +443,7 @@ static struct leaf_info *leaf_info_new(int plen) | |||
443 | 443 | ||
444 | static struct tnode *tnode_new(t_key key, int pos, int bits) | 444 | static struct tnode *tnode_new(t_key key, int pos, int bits) |
445 | { | 445 | { |
446 | size_t sz = sizeof(struct tnode) + (sizeof(struct node *) << bits); | 446 | size_t sz = sizeof(struct tnode) + (sizeof(struct rt_trie_node *) << bits); |
447 | struct tnode *tn = tnode_alloc(sz); | 447 | struct tnode *tn = tnode_alloc(sz); |
448 | 448 | ||
449 | if (tn) { | 449 | if (tn) { |
@@ -456,7 +456,7 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) | |||
456 | } | 456 | } |
457 | 457 | ||
458 | pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), | 458 | pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), |
459 | sizeof(struct node) << bits); | 459 | sizeof(struct rt_trie_node) << bits); |
460 | return tn; | 460 | return tn; |
461 | } | 461 | } |
462 | 462 | ||
@@ -465,7 +465,7 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) | |||
465 | * and no bits are skipped. See discussion in dyntree paper p. 6 | 465 | * and no bits are skipped. See discussion in dyntree paper p. 6 |
466 | */ | 466 | */ |
467 | 467 | ||
468 | static inline int tnode_full(const struct tnode *tn, const struct node *n) | 468 | static inline int tnode_full(const struct tnode *tn, const struct rt_trie_node *n) |
469 | { | 469 | { |
470 | if (n == NULL || IS_LEAF(n)) | 470 | if (n == NULL || IS_LEAF(n)) |
471 | return 0; | 471 | return 0; |
@@ -474,7 +474,7 @@ static inline int tnode_full(const struct tnode *tn, const struct node *n) | |||
474 | } | 474 | } |
475 | 475 | ||
476 | static inline void put_child(struct trie *t, struct tnode *tn, int i, | 476 | static inline void put_child(struct trie *t, struct tnode *tn, int i, |
477 | struct node *n) | 477 | struct rt_trie_node *n) |
478 | { | 478 | { |
479 | tnode_put_child_reorg(tn, i, n, -1); | 479 | tnode_put_child_reorg(tn, i, n, -1); |
480 | } | 480 | } |
@@ -484,10 +484,10 @@ static inline void put_child(struct trie *t, struct tnode *tn, int i, | |||
484 | * Update the value of full_children and empty_children. | 484 | * Update the value of full_children and empty_children. |
485 | */ | 485 | */ |
486 | 486 | ||
487 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, | 487 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n, |
488 | int wasfull) | 488 | int wasfull) |
489 | { | 489 | { |
490 | struct node *chi = tn->child[i]; | 490 | struct rt_trie_node *chi = tn->child[i]; |
491 | int isfull; | 491 | int isfull; |
492 | 492 | ||
493 | BUG_ON(i >= 1<<tn->bits); | 493 | BUG_ON(i >= 1<<tn->bits); |
@@ -515,7 +515,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, | |||
515 | } | 515 | } |
516 | 516 | ||
517 | #define MAX_WORK 10 | 517 | #define MAX_WORK 10 |
518 | static struct node *resize(struct trie *t, struct tnode *tn) | 518 | static struct rt_trie_node *resize(struct trie *t, struct tnode *tn) |
519 | { | 519 | { |
520 | int i; | 520 | int i; |
521 | struct tnode *old_tn; | 521 | struct tnode *old_tn; |
@@ -605,7 +605,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
605 | 605 | ||
606 | /* Keep root node larger */ | 606 | /* Keep root node larger */ |
607 | 607 | ||
608 | if (!node_parent((struct node *)tn)) { | 608 | if (!node_parent((struct rt_trie_node *)tn)) { |
609 | inflate_threshold_use = inflate_threshold_root; | 609 | inflate_threshold_use = inflate_threshold_root; |
610 | halve_threshold_use = halve_threshold_root; | 610 | halve_threshold_use = halve_threshold_root; |
611 | } else { | 611 | } else { |
@@ -635,7 +635,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
635 | 635 | ||
636 | /* Return if at least one inflate is run */ | 636 | /* Return if at least one inflate is run */ |
637 | if (max_work != MAX_WORK) | 637 | if (max_work != MAX_WORK) |
638 | return (struct node *) tn; | 638 | return (struct rt_trie_node *) tn; |
639 | 639 | ||
640 | /* | 640 | /* |
641 | * Halve as long as the number of empty children in this | 641 | * Halve as long as the number of empty children in this |
@@ -663,7 +663,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
663 | if (tn->empty_children == tnode_child_length(tn) - 1) { | 663 | if (tn->empty_children == tnode_child_length(tn) - 1) { |
664 | one_child: | 664 | one_child: |
665 | for (i = 0; i < tnode_child_length(tn); i++) { | 665 | for (i = 0; i < tnode_child_length(tn); i++) { |
666 | struct node *n; | 666 | struct rt_trie_node *n; |
667 | 667 | ||
668 | n = tn->child[i]; | 668 | n = tn->child[i]; |
669 | if (!n) | 669 | if (!n) |
@@ -676,7 +676,7 @@ one_child: | |||
676 | return n; | 676 | return n; |
677 | } | 677 | } |
678 | } | 678 | } |
679 | return (struct node *) tn; | 679 | return (struct rt_trie_node *) tn; |
680 | } | 680 | } |
681 | 681 | ||
682 | static struct tnode *inflate(struct trie *t, struct tnode *tn) | 682 | static struct tnode *inflate(struct trie *t, struct tnode *tn) |
@@ -723,14 +723,14 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) | |||
723 | goto nomem; | 723 | goto nomem; |
724 | } | 724 | } |
725 | 725 | ||
726 | put_child(t, tn, 2*i, (struct node *) left); | 726 | put_child(t, tn, 2*i, (struct rt_trie_node *) left); |
727 | put_child(t, tn, 2*i+1, (struct node *) right); | 727 | put_child(t, tn, 2*i+1, (struct rt_trie_node *) right); |
728 | } | 728 | } |
729 | } | 729 | } |
730 | 730 | ||
731 | for (i = 0; i < olen; i++) { | 731 | for (i = 0; i < olen; i++) { |
732 | struct tnode *inode; | 732 | struct tnode *inode; |
733 | struct node *node = tnode_get_child(oldtnode, i); | 733 | struct rt_trie_node *node = tnode_get_child(oldtnode, i); |
734 | struct tnode *left, *right; | 734 | struct tnode *left, *right; |
735 | int size, j; | 735 | int size, j; |
736 | 736 | ||
@@ -825,7 +825,7 @@ nomem: | |||
825 | static struct tnode *halve(struct trie *t, struct tnode *tn) | 825 | static struct tnode *halve(struct trie *t, struct tnode *tn) |
826 | { | 826 | { |
827 | struct tnode *oldtnode = tn; | 827 | struct tnode *oldtnode = tn; |
828 | struct node *left, *right; | 828 | struct rt_trie_node *left, *right; |
829 | int i; | 829 | int i; |
830 | int olen = tnode_child_length(tn); | 830 | int olen = tnode_child_length(tn); |
831 | 831 | ||
@@ -856,7 +856,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) | |||
856 | if (!newn) | 856 | if (!newn) |
857 | goto nomem; | 857 | goto nomem; |
858 | 858 | ||
859 | put_child(t, tn, i/2, (struct node *)newn); | 859 | put_child(t, tn, i/2, (struct rt_trie_node *)newn); |
860 | } | 860 | } |
861 | 861 | ||
862 | } | 862 | } |
@@ -958,7 +958,7 @@ fib_find_node(struct trie *t, u32 key) | |||
958 | { | 958 | { |
959 | int pos; | 959 | int pos; |
960 | struct tnode *tn; | 960 | struct tnode *tn; |
961 | struct node *n; | 961 | struct rt_trie_node *n; |
962 | 962 | ||
963 | pos = 0; | 963 | pos = 0; |
964 | n = rcu_dereference_rtnl(t->trie); | 964 | n = rcu_dereference_rtnl(t->trie); |
@@ -993,17 +993,17 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) | |||
993 | 993 | ||
994 | key = tn->key; | 994 | key = tn->key; |
995 | 995 | ||
996 | while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) { | 996 | while (tn != NULL && (tp = node_parent((struct rt_trie_node *)tn)) != NULL) { |
997 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); | 997 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); |
998 | wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); | 998 | wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); |
999 | tn = (struct tnode *) resize(t, (struct tnode *)tn); | 999 | tn = (struct tnode *) resize(t, (struct tnode *)tn); |
1000 | 1000 | ||
1001 | tnode_put_child_reorg((struct tnode *)tp, cindex, | 1001 | tnode_put_child_reorg((struct tnode *)tp, cindex, |
1002 | (struct node *)tn, wasfull); | 1002 | (struct rt_trie_node *)tn, wasfull); |
1003 | 1003 | ||
1004 | tp = node_parent((struct node *) tn); | 1004 | tp = node_parent((struct rt_trie_node *) tn); |
1005 | if (!tp) | 1005 | if (!tp) |
1006 | rcu_assign_pointer(t->trie, (struct node *)tn); | 1006 | rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); |
1007 | 1007 | ||
1008 | tnode_free_flush(); | 1008 | tnode_free_flush(); |
1009 | if (!tp) | 1009 | if (!tp) |
@@ -1015,7 +1015,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) | |||
1015 | if (IS_TNODE(tn)) | 1015 | if (IS_TNODE(tn)) |
1016 | tn = (struct tnode *)resize(t, (struct tnode *)tn); | 1016 | tn = (struct tnode *)resize(t, (struct tnode *)tn); |
1017 | 1017 | ||
1018 | rcu_assign_pointer(t->trie, (struct node *)tn); | 1018 | rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); |
1019 | tnode_free_flush(); | 1019 | tnode_free_flush(); |
1020 | } | 1020 | } |
1021 | 1021 | ||
@@ -1025,7 +1025,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
1025 | { | 1025 | { |
1026 | int pos, newpos; | 1026 | int pos, newpos; |
1027 | struct tnode *tp = NULL, *tn = NULL; | 1027 | struct tnode *tp = NULL, *tn = NULL; |
1028 | struct node *n; | 1028 | struct rt_trie_node *n; |
1029 | struct leaf *l; | 1029 | struct leaf *l; |
1030 | int missbit; | 1030 | int missbit; |
1031 | struct list_head *fa_head = NULL; | 1031 | struct list_head *fa_head = NULL; |
@@ -1111,10 +1111,10 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
1111 | if (t->trie && n == NULL) { | 1111 | if (t->trie && n == NULL) { |
1112 | /* Case 2: n is NULL, and will just insert a new leaf */ | 1112 | /* Case 2: n is NULL, and will just insert a new leaf */ |
1113 | 1113 | ||
1114 | node_set_parent((struct node *)l, tp); | 1114 | node_set_parent((struct rt_trie_node *)l, tp); |
1115 | 1115 | ||
1116 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); | 1116 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); |
1117 | put_child(t, (struct tnode *)tp, cindex, (struct node *)l); | 1117 | put_child(t, (struct tnode *)tp, cindex, (struct rt_trie_node *)l); |
1118 | } else { | 1118 | } else { |
1119 | /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ | 1119 | /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ |
1120 | /* | 1120 | /* |
@@ -1141,18 +1141,18 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
1141 | return NULL; | 1141 | return NULL; |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | node_set_parent((struct node *)tn, tp); | 1144 | node_set_parent((struct rt_trie_node *)tn, tp); |
1145 | 1145 | ||
1146 | missbit = tkey_extract_bits(key, newpos, 1); | 1146 | missbit = tkey_extract_bits(key, newpos, 1); |
1147 | put_child(t, tn, missbit, (struct node *)l); | 1147 | put_child(t, tn, missbit, (struct rt_trie_node *)l); |
1148 | put_child(t, tn, 1-missbit, n); | 1148 | put_child(t, tn, 1-missbit, n); |
1149 | 1149 | ||
1150 | if (tp) { | 1150 | if (tp) { |
1151 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); | 1151 | cindex = tkey_extract_bits(key, tp->pos, tp->bits); |
1152 | put_child(t, (struct tnode *)tp, cindex, | 1152 | put_child(t, (struct tnode *)tp, cindex, |
1153 | (struct node *)tn); | 1153 | (struct rt_trie_node *)tn); |
1154 | } else { | 1154 | } else { |
1155 | rcu_assign_pointer(t->trie, (struct node *)tn); | 1155 | rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); |
1156 | tp = tn; | 1156 | tp = tn; |
1157 | } | 1157 | } |
1158 | } | 1158 | } |
@@ -1245,7 +1245,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1245 | if (fa->fa_info->fib_priority != fi->fib_priority) | 1245 | if (fa->fa_info->fib_priority != fi->fib_priority) |
1246 | break; | 1246 | break; |
1247 | if (fa->fa_type == cfg->fc_type && | 1247 | if (fa->fa_type == cfg->fc_type && |
1248 | fa->fa_scope == cfg->fc_scope && | ||
1249 | fa->fa_info == fi) { | 1248 | fa->fa_info == fi) { |
1250 | fa_match = fa; | 1249 | fa_match = fa; |
1251 | break; | 1250 | break; |
@@ -1271,7 +1270,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1271 | new_fa->fa_tos = fa->fa_tos; | 1270 | new_fa->fa_tos = fa->fa_tos; |
1272 | new_fa->fa_info = fi; | 1271 | new_fa->fa_info = fi; |
1273 | new_fa->fa_type = cfg->fc_type; | 1272 | new_fa->fa_type = cfg->fc_type; |
1274 | new_fa->fa_scope = cfg->fc_scope; | ||
1275 | state = fa->fa_state; | 1273 | state = fa->fa_state; |
1276 | new_fa->fa_state = state & ~FA_S_ACCESSED; | 1274 | new_fa->fa_state = state & ~FA_S_ACCESSED; |
1277 | 1275 | ||
@@ -1308,7 +1306,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1308 | new_fa->fa_info = fi; | 1306 | new_fa->fa_info = fi; |
1309 | new_fa->fa_tos = tos; | 1307 | new_fa->fa_tos = tos; |
1310 | new_fa->fa_type = cfg->fc_type; | 1308 | new_fa->fa_type = cfg->fc_type; |
1311 | new_fa->fa_scope = cfg->fc_scope; | ||
1312 | new_fa->fa_state = 0; | 1309 | new_fa->fa_state = 0; |
1313 | /* | 1310 | /* |
1314 | * Insert new entry to the list. | 1311 | * Insert new entry to the list. |
@@ -1340,8 +1337,8 @@ err: | |||
1340 | } | 1337 | } |
1341 | 1338 | ||
1342 | /* should be called with rcu_read_lock */ | 1339 | /* should be called with rcu_read_lock */ |
1343 | static int check_leaf(struct trie *t, struct leaf *l, | 1340 | static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, |
1344 | t_key key, const struct flowi *flp, | 1341 | t_key key, const struct flowi4 *flp, |
1345 | struct fib_result *res, int fib_flags) | 1342 | struct fib_result *res, int fib_flags) |
1346 | { | 1343 | { |
1347 | struct leaf_info *li; | 1344 | struct leaf_info *li; |
@@ -1349,40 +1346,75 @@ static int check_leaf(struct trie *t, struct leaf *l, | |||
1349 | struct hlist_node *node; | 1346 | struct hlist_node *node; |
1350 | 1347 | ||
1351 | hlist_for_each_entry_rcu(li, node, hhead, hlist) { | 1348 | hlist_for_each_entry_rcu(li, node, hhead, hlist) { |
1352 | int err; | 1349 | struct fib_alias *fa; |
1353 | int plen = li->plen; | 1350 | int plen = li->plen; |
1354 | __be32 mask = inet_make_mask(plen); | 1351 | __be32 mask = inet_make_mask(plen); |
1355 | 1352 | ||
1356 | if (l->key != (key & ntohl(mask))) | 1353 | if (l->key != (key & ntohl(mask))) |
1357 | continue; | 1354 | continue; |
1358 | 1355 | ||
1359 | err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags); | 1356 | list_for_each_entry_rcu(fa, &li->falh, fa_list) { |
1357 | struct fib_info *fi = fa->fa_info; | ||
1358 | int nhsel, err; | ||
1360 | 1359 | ||
1360 | if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) | ||
1361 | continue; | ||
1362 | if (fa->fa_info->fib_scope < flp->flowi4_scope) | ||
1363 | continue; | ||
1364 | fib_alias_accessed(fa); | ||
1365 | err = fib_props[fa->fa_type].error; | ||
1366 | if (err) { | ||
1361 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 1367 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
1362 | if (err <= 0) | 1368 | t->stats.semantic_match_passed++; |
1363 | t->stats.semantic_match_passed++; | 1369 | #endif |
1364 | else | 1370 | return err; |
1365 | t->stats.semantic_match_miss++; | 1371 | } |
1372 | if (fi->fib_flags & RTNH_F_DEAD) | ||
1373 | continue; | ||
1374 | for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { | ||
1375 | const struct fib_nh *nh = &fi->fib_nh[nhsel]; | ||
1376 | |||
1377 | if (nh->nh_flags & RTNH_F_DEAD) | ||
1378 | continue; | ||
1379 | if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif) | ||
1380 | continue; | ||
1381 | |||
1382 | #ifdef CONFIG_IP_FIB_TRIE_STATS | ||
1383 | t->stats.semantic_match_passed++; | ||
1384 | #endif | ||
1385 | res->prefixlen = plen; | ||
1386 | res->nh_sel = nhsel; | ||
1387 | res->type = fa->fa_type; | ||
1388 | res->scope = fa->fa_info->fib_scope; | ||
1389 | res->fi = fi; | ||
1390 | res->table = tb; | ||
1391 | res->fa_head = &li->falh; | ||
1392 | if (!(fib_flags & FIB_LOOKUP_NOREF)) | ||
1393 | atomic_inc(&res->fi->fib_clntref); | ||
1394 | return 0; | ||
1395 | } | ||
1396 | } | ||
1397 | |||
1398 | #ifdef CONFIG_IP_FIB_TRIE_STATS | ||
1399 | t->stats.semantic_match_miss++; | ||
1366 | #endif | 1400 | #endif |
1367 | if (err <= 0) | ||
1368 | return err; | ||
1369 | } | 1401 | } |
1370 | 1402 | ||
1371 | return 1; | 1403 | return 1; |
1372 | } | 1404 | } |
1373 | 1405 | ||
1374 | int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, | 1406 | int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, |
1375 | struct fib_result *res, int fib_flags) | 1407 | struct fib_result *res, int fib_flags) |
1376 | { | 1408 | { |
1377 | struct trie *t = (struct trie *) tb->tb_data; | 1409 | struct trie *t = (struct trie *) tb->tb_data; |
1378 | int ret; | 1410 | int ret; |
1379 | struct node *n; | 1411 | struct rt_trie_node *n; |
1380 | struct tnode *pn; | 1412 | struct tnode *pn; |
1381 | int pos, bits; | 1413 | unsigned int pos, bits; |
1382 | t_key key = ntohl(flp->fl4_dst); | 1414 | t_key key = ntohl(flp->daddr); |
1383 | int chopped_off; | 1415 | unsigned int chopped_off; |
1384 | t_key cindex = 0; | 1416 | t_key cindex = 0; |
1385 | int current_prefix_length = KEYLENGTH; | 1417 | unsigned int current_prefix_length = KEYLENGTH; |
1386 | struct tnode *cn; | 1418 | struct tnode *cn; |
1387 | t_key pref_mismatch; | 1419 | t_key pref_mismatch; |
1388 | 1420 | ||
@@ -1398,7 +1430,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, | |||
1398 | 1430 | ||
1399 | /* Just a leaf? */ | 1431 | /* Just a leaf? */ |
1400 | if (IS_LEAF(n)) { | 1432 | if (IS_LEAF(n)) { |
1401 | ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); | 1433 | ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags); |
1402 | goto found; | 1434 | goto found; |
1403 | } | 1435 | } |
1404 | 1436 | ||
@@ -1423,7 +1455,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, | |||
1423 | } | 1455 | } |
1424 | 1456 | ||
1425 | if (IS_LEAF(n)) { | 1457 | if (IS_LEAF(n)) { |
1426 | ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); | 1458 | ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags); |
1427 | if (ret > 0) | 1459 | if (ret > 0) |
1428 | goto backtrace; | 1460 | goto backtrace; |
1429 | goto found; | 1461 | goto found; |
@@ -1541,7 +1573,7 @@ backtrace: | |||
1541 | if (chopped_off <= pn->bits) { | 1573 | if (chopped_off <= pn->bits) { |
1542 | cindex &= ~(1 << (chopped_off-1)); | 1574 | cindex &= ~(1 << (chopped_off-1)); |
1543 | } else { | 1575 | } else { |
1544 | struct tnode *parent = node_parent_rcu((struct node *) pn); | 1576 | struct tnode *parent = node_parent_rcu((struct rt_trie_node *) pn); |
1545 | if (!parent) | 1577 | if (!parent) |
1546 | goto failed; | 1578 | goto failed; |
1547 | 1579 | ||
@@ -1568,7 +1600,7 @@ found: | |||
1568 | */ | 1600 | */ |
1569 | static void trie_leaf_remove(struct trie *t, struct leaf *l) | 1601 | static void trie_leaf_remove(struct trie *t, struct leaf *l) |
1570 | { | 1602 | { |
1571 | struct tnode *tp = node_parent((struct node *) l); | 1603 | struct tnode *tp = node_parent((struct rt_trie_node *) l); |
1572 | 1604 | ||
1573 | pr_debug("entering trie_leaf_remove(%p)\n", l); | 1605 | pr_debug("entering trie_leaf_remove(%p)\n", l); |
1574 | 1606 | ||
@@ -1629,7 +1661,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) | |||
1629 | 1661 | ||
1630 | if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) && | 1662 | if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) && |
1631 | (cfg->fc_scope == RT_SCOPE_NOWHERE || | 1663 | (cfg->fc_scope == RT_SCOPE_NOWHERE || |
1632 | fa->fa_scope == cfg->fc_scope) && | 1664 | fa->fa_info->fib_scope == cfg->fc_scope) && |
1665 | (!cfg->fc_prefsrc || | ||
1666 | fi->fib_prefsrc == cfg->fc_prefsrc) && | ||
1633 | (!cfg->fc_protocol || | 1667 | (!cfg->fc_protocol || |
1634 | fi->fib_protocol == cfg->fc_protocol) && | 1668 | fi->fib_protocol == cfg->fc_protocol) && |
1635 | fib_nh_match(cfg, fi) == 0) { | 1669 | fib_nh_match(cfg, fi) == 0) { |
@@ -1706,7 +1740,7 @@ static int trie_flush_leaf(struct leaf *l) | |||
1706 | * Scan for the next right leaf starting at node p->child[idx] | 1740 | * Scan for the next right leaf starting at node p->child[idx] |
1707 | * Since we have back pointer, no recursion necessary. | 1741 | * Since we have back pointer, no recursion necessary. |
1708 | */ | 1742 | */ |
1709 | static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) | 1743 | static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c) |
1710 | { | 1744 | { |
1711 | do { | 1745 | do { |
1712 | t_key idx; | 1746 | t_key idx; |
@@ -1732,7 +1766,7 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) | |||
1732 | } | 1766 | } |
1733 | 1767 | ||
1734 | /* Node empty, walk back up to parent */ | 1768 | /* Node empty, walk back up to parent */ |
1735 | c = (struct node *) p; | 1769 | c = (struct rt_trie_node *) p; |
1736 | } while ((p = node_parent_rcu(c)) != NULL); | 1770 | } while ((p = node_parent_rcu(c)) != NULL); |
1737 | 1771 | ||
1738 | return NULL; /* Root of trie */ | 1772 | return NULL; /* Root of trie */ |
@@ -1753,7 +1787,7 @@ static struct leaf *trie_firstleaf(struct trie *t) | |||
1753 | 1787 | ||
1754 | static struct leaf *trie_nextleaf(struct leaf *l) | 1788 | static struct leaf *trie_nextleaf(struct leaf *l) |
1755 | { | 1789 | { |
1756 | struct node *c = (struct node *) l; | 1790 | struct rt_trie_node *c = (struct rt_trie_node *) l; |
1757 | struct tnode *p = node_parent_rcu(c); | 1791 | struct tnode *p = node_parent_rcu(c); |
1758 | 1792 | ||
1759 | if (!p) | 1793 | if (!p) |
@@ -1802,80 +1836,6 @@ void fib_free_table(struct fib_table *tb) | |||
1802 | kfree(tb); | 1836 | kfree(tb); |
1803 | } | 1837 | } |
1804 | 1838 | ||
1805 | void fib_table_select_default(struct fib_table *tb, | ||
1806 | const struct flowi *flp, | ||
1807 | struct fib_result *res) | ||
1808 | { | ||
1809 | struct trie *t = (struct trie *) tb->tb_data; | ||
1810 | int order, last_idx; | ||
1811 | struct fib_info *fi = NULL; | ||
1812 | struct fib_info *last_resort; | ||
1813 | struct fib_alias *fa = NULL; | ||
1814 | struct list_head *fa_head; | ||
1815 | struct leaf *l; | ||
1816 | |||
1817 | last_idx = -1; | ||
1818 | last_resort = NULL; | ||
1819 | order = -1; | ||
1820 | |||
1821 | rcu_read_lock(); | ||
1822 | |||
1823 | l = fib_find_node(t, 0); | ||
1824 | if (!l) | ||
1825 | goto out; | ||
1826 | |||
1827 | fa_head = get_fa_head(l, 0); | ||
1828 | if (!fa_head) | ||
1829 | goto out; | ||
1830 | |||
1831 | if (list_empty(fa_head)) | ||
1832 | goto out; | ||
1833 | |||
1834 | list_for_each_entry_rcu(fa, fa_head, fa_list) { | ||
1835 | struct fib_info *next_fi = fa->fa_info; | ||
1836 | |||
1837 | if (fa->fa_scope != res->scope || | ||
1838 | fa->fa_type != RTN_UNICAST) | ||
1839 | continue; | ||
1840 | |||
1841 | if (next_fi->fib_priority > res->fi->fib_priority) | ||
1842 | break; | ||
1843 | if (!next_fi->fib_nh[0].nh_gw || | ||
1844 | next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) | ||
1845 | continue; | ||
1846 | |||
1847 | fib_alias_accessed(fa); | ||
1848 | |||
1849 | if (fi == NULL) { | ||
1850 | if (next_fi != res->fi) | ||
1851 | break; | ||
1852 | } else if (!fib_detect_death(fi, order, &last_resort, | ||
1853 | &last_idx, tb->tb_default)) { | ||
1854 | fib_result_assign(res, fi); | ||
1855 | tb->tb_default = order; | ||
1856 | goto out; | ||
1857 | } | ||
1858 | fi = next_fi; | ||
1859 | order++; | ||
1860 | } | ||
1861 | if (order <= 0 || fi == NULL) { | ||
1862 | tb->tb_default = -1; | ||
1863 | goto out; | ||
1864 | } | ||
1865 | |||
1866 | if (!fib_detect_death(fi, order, &last_resort, &last_idx, | ||
1867 | tb->tb_default)) { | ||
1868 | fib_result_assign(res, fi); | ||
1869 | tb->tb_default = order; | ||
1870 | goto out; | ||
1871 | } | ||
1872 | if (last_idx >= 0) | ||
1873 | fib_result_assign(res, last_resort); | ||
1874 | tb->tb_default = last_idx; | ||
1875 | out: | ||
1876 | rcu_read_unlock(); | ||
1877 | } | ||
1878 | |||
1879 | static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, | 1839 | static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, |
1880 | struct fib_table *tb, | 1840 | struct fib_table *tb, |
1881 | struct sk_buff *skb, struct netlink_callback *cb) | 1841 | struct sk_buff *skb, struct netlink_callback *cb) |
@@ -1900,7 +1860,6 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, | |||
1900 | RTM_NEWROUTE, | 1860 | RTM_NEWROUTE, |
1901 | tb->tb_id, | 1861 | tb->tb_id, |
1902 | fa->fa_type, | 1862 | fa->fa_type, |
1903 | fa->fa_scope, | ||
1904 | xkey, | 1863 | xkey, |
1905 | plen, | 1864 | plen, |
1906 | fa->fa_tos, | 1865 | fa->fa_tos, |
@@ -1990,7 +1949,7 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, | |||
1990 | return skb->len; | 1949 | return skb->len; |
1991 | } | 1950 | } |
1992 | 1951 | ||
1993 | void __init fib_hash_init(void) | 1952 | void __init fib_trie_init(void) |
1994 | { | 1953 | { |
1995 | fn_alias_kmem = kmem_cache_create("ip_fib_alias", | 1954 | fn_alias_kmem = kmem_cache_create("ip_fib_alias", |
1996 | sizeof(struct fib_alias), | 1955 | sizeof(struct fib_alias), |
@@ -2003,8 +1962,7 @@ void __init fib_hash_init(void) | |||
2003 | } | 1962 | } |
2004 | 1963 | ||
2005 | 1964 | ||
2006 | /* Fix more generic FIB names for init later */ | 1965 | struct fib_table *fib_trie_table(u32 id) |
2007 | struct fib_table *fib_hash_table(u32 id) | ||
2008 | { | 1966 | { |
2009 | struct fib_table *tb; | 1967 | struct fib_table *tb; |
2010 | struct trie *t; | 1968 | struct trie *t; |
@@ -2020,9 +1978,6 @@ struct fib_table *fib_hash_table(u32 id) | |||
2020 | t = (struct trie *) tb->tb_data; | 1978 | t = (struct trie *) tb->tb_data; |
2021 | memset(t, 0, sizeof(*t)); | 1979 | memset(t, 0, sizeof(*t)); |
2022 | 1980 | ||
2023 | if (id == RT_TABLE_LOCAL) | ||
2024 | pr_info("IPv4 FIB: Using LC-trie version %s\n", VERSION); | ||
2025 | |||
2026 | return tb; | 1981 | return tb; |
2027 | } | 1982 | } |
2028 | 1983 | ||
@@ -2036,7 +1991,7 @@ struct fib_trie_iter { | |||
2036 | unsigned int depth; | 1991 | unsigned int depth; |
2037 | }; | 1992 | }; |
2038 | 1993 | ||
2039 | static struct node *fib_trie_get_next(struct fib_trie_iter *iter) | 1994 | static struct rt_trie_node *fib_trie_get_next(struct fib_trie_iter *iter) |
2040 | { | 1995 | { |
2041 | struct tnode *tn = iter->tnode; | 1996 | struct tnode *tn = iter->tnode; |
2042 | unsigned int cindex = iter->index; | 1997 | unsigned int cindex = iter->index; |
@@ -2050,7 +2005,7 @@ static struct node *fib_trie_get_next(struct fib_trie_iter *iter) | |||
2050 | iter->tnode, iter->index, iter->depth); | 2005 | iter->tnode, iter->index, iter->depth); |
2051 | rescan: | 2006 | rescan: |
2052 | while (cindex < (1<<tn->bits)) { | 2007 | while (cindex < (1<<tn->bits)) { |
2053 | struct node *n = tnode_get_child_rcu(tn, cindex); | 2008 | struct rt_trie_node *n = tnode_get_child_rcu(tn, cindex); |
2054 | 2009 | ||
2055 | if (n) { | 2010 | if (n) { |
2056 | if (IS_LEAF(n)) { | 2011 | if (IS_LEAF(n)) { |
@@ -2069,7 +2024,7 @@ rescan: | |||
2069 | } | 2024 | } |
2070 | 2025 | ||
2071 | /* Current node exhausted, pop back up */ | 2026 | /* Current node exhausted, pop back up */ |
2072 | p = node_parent_rcu((struct node *)tn); | 2027 | p = node_parent_rcu((struct rt_trie_node *)tn); |
2073 | if (p) { | 2028 | if (p) { |
2074 | cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1; | 2029 | cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1; |
2075 | tn = p; | 2030 | tn = p; |
@@ -2081,10 +2036,10 @@ rescan: | |||
2081 | return NULL; | 2036 | return NULL; |
2082 | } | 2037 | } |
2083 | 2038 | ||
2084 | static struct node *fib_trie_get_first(struct fib_trie_iter *iter, | 2039 | static struct rt_trie_node *fib_trie_get_first(struct fib_trie_iter *iter, |
2085 | struct trie *t) | 2040 | struct trie *t) |
2086 | { | 2041 | { |
2087 | struct node *n; | 2042 | struct rt_trie_node *n; |
2088 | 2043 | ||
2089 | if (!t) | 2044 | if (!t) |
2090 | return NULL; | 2045 | return NULL; |
@@ -2108,7 +2063,7 @@ static struct node *fib_trie_get_first(struct fib_trie_iter *iter, | |||
2108 | 2063 | ||
2109 | static void trie_collect_stats(struct trie *t, struct trie_stat *s) | 2064 | static void trie_collect_stats(struct trie *t, struct trie_stat *s) |
2110 | { | 2065 | { |
2111 | struct node *n; | 2066 | struct rt_trie_node *n; |
2112 | struct fib_trie_iter iter; | 2067 | struct fib_trie_iter iter; |
2113 | 2068 | ||
2114 | memset(s, 0, sizeof(*s)); | 2069 | memset(s, 0, sizeof(*s)); |
@@ -2181,7 +2136,7 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) | |||
2181 | seq_putc(seq, '\n'); | 2136 | seq_putc(seq, '\n'); |
2182 | seq_printf(seq, "\tPointers: %u\n", pointers); | 2137 | seq_printf(seq, "\tPointers: %u\n", pointers); |
2183 | 2138 | ||
2184 | bytes += sizeof(struct node *) * pointers; | 2139 | bytes += sizeof(struct rt_trie_node *) * pointers; |
2185 | seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers); | 2140 | seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers); |
2186 | seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024); | 2141 | seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024); |
2187 | } | 2142 | } |
@@ -2262,7 +2217,7 @@ static const struct file_operations fib_triestat_fops = { | |||
2262 | .release = single_release_net, | 2217 | .release = single_release_net, |
2263 | }; | 2218 | }; |
2264 | 2219 | ||
2265 | static struct node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) | 2220 | static struct rt_trie_node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) |
2266 | { | 2221 | { |
2267 | struct fib_trie_iter *iter = seq->private; | 2222 | struct fib_trie_iter *iter = seq->private; |
2268 | struct net *net = seq_file_net(seq); | 2223 | struct net *net = seq_file_net(seq); |
@@ -2275,7 +2230,7 @@ static struct node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) | |||
2275 | struct fib_table *tb; | 2230 | struct fib_table *tb; |
2276 | 2231 | ||
2277 | hlist_for_each_entry_rcu(tb, node, head, tb_hlist) { | 2232 | hlist_for_each_entry_rcu(tb, node, head, tb_hlist) { |
2278 | struct node *n; | 2233 | struct rt_trie_node *n; |
2279 | 2234 | ||
2280 | for (n = fib_trie_get_first(iter, | 2235 | for (n = fib_trie_get_first(iter, |
2281 | (struct trie *) tb->tb_data); | 2236 | (struct trie *) tb->tb_data); |
@@ -2304,7 +2259,7 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
2304 | struct fib_table *tb = iter->tb; | 2259 | struct fib_table *tb = iter->tb; |
2305 | struct hlist_node *tb_node; | 2260 | struct hlist_node *tb_node; |
2306 | unsigned int h; | 2261 | unsigned int h; |
2307 | struct node *n; | 2262 | struct rt_trie_node *n; |
2308 | 2263 | ||
2309 | ++*pos; | 2264 | ++*pos; |
2310 | /* next node in same table */ | 2265 | /* next node in same table */ |
@@ -2390,7 +2345,7 @@ static inline const char *rtn_type(char *buf, size_t len, unsigned int t) | |||
2390 | static int fib_trie_seq_show(struct seq_file *seq, void *v) | 2345 | static int fib_trie_seq_show(struct seq_file *seq, void *v) |
2391 | { | 2346 | { |
2392 | const struct fib_trie_iter *iter = seq->private; | 2347 | const struct fib_trie_iter *iter = seq->private; |
2393 | struct node *n = v; | 2348 | struct rt_trie_node *n = v; |
2394 | 2349 | ||
2395 | if (!node_parent_rcu(n)) | 2350 | if (!node_parent_rcu(n)) |
2396 | fib_table_print(seq, iter->tb); | 2351 | fib_table_print(seq, iter->tb); |
@@ -2422,7 +2377,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) | |||
2422 | seq_indent(seq, iter->depth+1); | 2377 | seq_indent(seq, iter->depth+1); |
2423 | seq_printf(seq, " /%d %s %s", li->plen, | 2378 | seq_printf(seq, " /%d %s %s", li->plen, |
2424 | rtn_scope(buf1, sizeof(buf1), | 2379 | rtn_scope(buf1, sizeof(buf1), |
2425 | fa->fa_scope), | 2380 | fa->fa_info->fib_scope), |
2426 | rtn_type(buf2, sizeof(buf2), | 2381 | rtn_type(buf2, sizeof(buf2), |
2427 | fa->fa_type)); | 2382 | fa->fa_type)); |
2428 | if (fa->fa_tos) | 2383 | if (fa->fa_tos) |