aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@redhat.com>2015-03-06 12:54:08 -0500
committerDavid S. Miller <davem@davemloft.net>2015-03-06 15:49:27 -0500
commit35c6edac197fcfb53cea9993d9b64386b15abf48 (patch)
tree805ed820e32fb1a5bd0abea40393d3bef8422c4e /net/ipv4/fib_trie.c
parent8d8e810ca8ec2541f30af916f0de1b41ac86ec4a (diff)
fib_trie: Rename tnode to key_vector
Rename the tnode to key_vector. The key_vector will be the eventual container for all of the information needed by either a leaf or a tnode. The final result should be much smaller than the 40 bytes currently needed for either one. This also updates the trie struct so that it contains an array of size 1 of tnode pointers. This is to bring the structure more inline with how an actual tnode itself is configured. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c247
1 files changed, 128 insertions, 119 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 752520747056..8b21fc3da43e 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -94,12 +94,12 @@ typedef unsigned int t_key;
94 94
95#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos) 95#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos)
96 96
97struct tnode { 97struct key_vector {
98 struct rcu_head rcu; 98 struct rcu_head rcu;
99 99
100 t_key empty_children; /* KEYLENGTH bits needed */ 100 t_key empty_children; /* KEYLENGTH bits needed */
101 t_key full_children; /* KEYLENGTH bits needed */ 101 t_key full_children; /* KEYLENGTH bits needed */
102 struct tnode __rcu *parent; 102 struct key_vector __rcu *parent;
103 103
104 t_key key; 104 t_key key;
105 unsigned char pos; /* 2log(KEYLENGTH) bits needed */ 105 unsigned char pos; /* 2log(KEYLENGTH) bits needed */
@@ -109,11 +109,11 @@ struct tnode {
109 /* This list pointer if valid if (pos | bits) == 0 (LEAF) */ 109 /* This list pointer if valid if (pos | bits) == 0 (LEAF) */
110 struct hlist_head leaf; 110 struct hlist_head leaf;
111 /* This array is valid if (pos | bits) > 0 (TNODE) */ 111 /* This array is valid if (pos | bits) > 0 (TNODE) */
112 struct tnode __rcu *tnode[0]; 112 struct key_vector __rcu *tnode[0];
113 }; 113 };
114}; 114};
115 115
116#define TNODE_SIZE(n) offsetof(struct tnode, tnode[n]) 116#define TNODE_SIZE(n) offsetof(struct key_vector, tnode[n])
117#define LEAF_SIZE TNODE_SIZE(1) 117#define LEAF_SIZE TNODE_SIZE(1)
118 118
119#ifdef CONFIG_IP_FIB_TRIE_STATS 119#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -138,13 +138,13 @@ struct trie_stat {
138}; 138};
139 139
140struct trie { 140struct trie {
141 struct tnode __rcu *trie; 141 struct key_vector __rcu *tnode[1];
142#ifdef CONFIG_IP_FIB_TRIE_STATS 142#ifdef CONFIG_IP_FIB_TRIE_STATS
143 struct trie_use_stats __percpu *stats; 143 struct trie_use_stats __percpu *stats;
144#endif 144#endif
145}; 145};
146 146
147static struct tnode **resize(struct trie *t, struct tnode *tn); 147static struct key_vector **resize(struct trie *t, struct key_vector *tn);
148static size_t tnode_free_size; 148static size_t tnode_free_size;
149 149
150/* 150/*
@@ -164,7 +164,7 @@ static struct kmem_cache *trie_leaf_kmem __read_mostly;
164#define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) 164#define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent)
165 165
166/* wrapper for rcu_assign_pointer */ 166/* wrapper for rcu_assign_pointer */
167static inline void node_set_parent(struct tnode *n, struct tnode *tp) 167static inline void node_set_parent(struct key_vector *n, struct key_vector *tp)
168{ 168{
169 if (n) 169 if (n)
170 rcu_assign_pointer(n->parent, tp); 170 rcu_assign_pointer(n->parent, tp);
@@ -175,21 +175,21 @@ static inline void node_set_parent(struct tnode *n, struct tnode *tp)
175/* This provides us with the number of children in this node, in the case of a 175/* This provides us with the number of children in this node, in the case of a
176 * leaf this will return 0 meaning none of the children are accessible. 176 * leaf this will return 0 meaning none of the children are accessible.
177 */ 177 */
178static inline unsigned long tnode_child_length(const struct tnode *tn) 178static inline unsigned long tnode_child_length(const struct key_vector *tn)
179{ 179{
180 return (1ul << tn->bits) & ~(1ul); 180 return (1ul << tn->bits) & ~(1ul);
181} 181}
182 182
183/* caller must hold RTNL */ 183/* caller must hold RTNL */
184static inline struct tnode *tnode_get_child(const struct tnode *tn, 184static inline struct key_vector *tnode_get_child(struct key_vector *tn,
185 unsigned long i) 185 unsigned long i)
186{ 186{
187 return rtnl_dereference(tn->tnode[i]); 187 return rtnl_dereference(tn->tnode[i]);
188} 188}
189 189
190/* caller must hold RCU read lock or RTNL */ 190/* caller must hold RCU read lock or RTNL */
191static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, 191static inline struct key_vector *tnode_get_child_rcu(struct key_vector *tn,
192 unsigned long i) 192 unsigned long i)
193{ 193{
194 return rcu_dereference_rtnl(tn->tnode[i]); 194 return rcu_dereference_rtnl(tn->tnode[i]);
195} 195}
@@ -277,13 +277,13 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa)
277} 277}
278 278
279#define TNODE_KMALLOC_MAX \ 279#define TNODE_KMALLOC_MAX \
280 ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct tnode *)) 280 ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct key_vector *))
281#define TNODE_VMALLOC_MAX \ 281#define TNODE_VMALLOC_MAX \
282 ilog2((SIZE_MAX - TNODE_SIZE(0)) / sizeof(struct tnode *)) 282 ilog2((SIZE_MAX - TNODE_SIZE(0)) / sizeof(struct key_vector *))
283 283
284static void __node_free_rcu(struct rcu_head *head) 284static void __node_free_rcu(struct rcu_head *head)
285{ 285{
286 struct tnode *n = container_of(head, struct tnode, rcu); 286 struct key_vector *n = container_of(head, struct key_vector, rcu);
287 287
288 if (IS_LEAF(n)) 288 if (IS_LEAF(n))
289 kmem_cache_free(trie_leaf_kmem, n); 289 kmem_cache_free(trie_leaf_kmem, n);
@@ -295,7 +295,7 @@ static void __node_free_rcu(struct rcu_head *head)
295 295
296#define node_free(n) call_rcu(&n->rcu, __node_free_rcu) 296#define node_free(n) call_rcu(&n->rcu, __node_free_rcu)
297 297
298static struct tnode *tnode_alloc(int bits) 298static struct key_vector *tnode_alloc(int bits)
299{ 299{
300 size_t size; 300 size_t size;
301 301
@@ -312,19 +312,19 @@ static struct tnode *tnode_alloc(int bits)
312 return vzalloc(size); 312 return vzalloc(size);
313} 313}
314 314
315static inline void empty_child_inc(struct tnode *n) 315static inline void empty_child_inc(struct key_vector *n)
316{ 316{
317 ++n->empty_children ? : ++n->full_children; 317 ++n->empty_children ? : ++n->full_children;
318} 318}
319 319
320static inline void empty_child_dec(struct tnode *n) 320static inline void empty_child_dec(struct key_vector *n)
321{ 321{
322 n->empty_children-- ? : n->full_children--; 322 n->empty_children-- ? : n->full_children--;
323} 323}
324 324
325static struct tnode *leaf_new(t_key key, struct fib_alias *fa) 325static struct key_vector *leaf_new(t_key key, struct fib_alias *fa)
326{ 326{
327 struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); 327 struct key_vector *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
328 if (l) { 328 if (l) {
329 l->parent = NULL; 329 l->parent = NULL;
330 /* set key and pos to reflect full key value 330 /* set key and pos to reflect full key value
@@ -344,9 +344,9 @@ static struct tnode *leaf_new(t_key key, struct fib_alias *fa)
344 return l; 344 return l;
345} 345}
346 346
347static struct tnode *tnode_new(t_key key, int pos, int bits) 347static struct key_vector *tnode_new(t_key key, int pos, int bits)
348{ 348{
349 struct tnode *tn = tnode_alloc(bits); 349 struct key_vector *tn = tnode_alloc(bits);
350 unsigned int shift = pos + bits; 350 unsigned int shift = pos + bits;
351 351
352 /* verify bits and pos their msb bits clear and values are valid */ 352 /* verify bits and pos their msb bits clear and values are valid */
@@ -365,14 +365,14 @@ static struct tnode *tnode_new(t_key key, int pos, int bits)
365 } 365 }
366 366
367 pr_debug("AT %p s=%zu %zu\n", tn, TNODE_SIZE(0), 367 pr_debug("AT %p s=%zu %zu\n", tn, TNODE_SIZE(0),
368 sizeof(struct tnode *) << bits); 368 sizeof(struct key_vector *) << bits);
369 return tn; 369 return tn;
370} 370}
371 371
372/* Check whether a tnode 'n' is "full", i.e. it is an internal node 372/* Check whether a tnode 'n' is "full", i.e. it is an internal node
373 * and no bits are skipped. See discussion in dyntree paper p. 6 373 * and no bits are skipped. See discussion in dyntree paper p. 6
374 */ 374 */
375static inline int tnode_full(const struct tnode *tn, const struct tnode *n) 375static inline int tnode_full(struct key_vector *tn, struct key_vector *n)
376{ 376{
377 return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); 377 return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n);
378} 378}
@@ -380,9 +380,10 @@ static inline int tnode_full(const struct tnode *tn, const struct tnode *n)
380/* Add a child at position i overwriting the old value. 380/* Add a child at position i overwriting the old value.
381 * Update the value of full_children and empty_children. 381 * Update the value of full_children and empty_children.
382 */ 382 */
383static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) 383static void put_child(struct key_vector *tn, unsigned long i,
384 struct key_vector *n)
384{ 385{
385 struct tnode *chi = tnode_get_child(tn, i); 386 struct key_vector *chi = tnode_get_child(tn, i);
386 int isfull, wasfull; 387 int isfull, wasfull;
387 388
388 BUG_ON(i >= tnode_child_length(tn)); 389 BUG_ON(i >= tnode_child_length(tn));
@@ -408,13 +409,13 @@ static void put_child(struct tnode *tn, unsigned long i, struct tnode *n)
408 rcu_assign_pointer(tn->tnode[i], n); 409 rcu_assign_pointer(tn->tnode[i], n);
409} 410}
410 411
411static void update_children(struct tnode *tn) 412static void update_children(struct key_vector *tn)
412{ 413{
413 unsigned long i; 414 unsigned long i;
414 415
415 /* update all of the child parent pointers */ 416 /* update all of the child parent pointers */
416 for (i = tnode_child_length(tn); i;) { 417 for (i = tnode_child_length(tn); i;) {
417 struct tnode *inode = tnode_get_child(tn, --i); 418 struct key_vector *inode = tnode_get_child(tn, --i);
418 419
419 if (!inode) 420 if (!inode)
420 continue; 421 continue;
@@ -430,27 +431,28 @@ static void update_children(struct tnode *tn)
430 } 431 }
431} 432}
432 433
433static inline void put_child_root(struct tnode *tp, struct trie *t, 434static inline void put_child_root(struct key_vector *tp, struct trie *t,
434 t_key key, struct tnode *n) 435 t_key key, struct key_vector *n)
435{ 436{
436 if (tp) 437 if (tp)
437 put_child(tp, get_index(key, tp), n); 438 put_child(tp, get_index(key, tp), n);
438 else 439 else
439 rcu_assign_pointer(t->trie, n); 440 rcu_assign_pointer(t->tnode[0], n);
440} 441}
441 442
442static inline void tnode_free_init(struct tnode *tn) 443static inline void tnode_free_init(struct key_vector *tn)
443{ 444{
444 tn->rcu.next = NULL; 445 tn->rcu.next = NULL;
445} 446}
446 447
447static inline void tnode_free_append(struct tnode *tn, struct tnode *n) 448static inline void tnode_free_append(struct key_vector *tn,
449 struct key_vector *n)
448{ 450{
449 n->rcu.next = tn->rcu.next; 451 n->rcu.next = tn->rcu.next;
450 tn->rcu.next = &n->rcu; 452 tn->rcu.next = &n->rcu;
451} 453}
452 454
453static void tnode_free(struct tnode *tn) 455static void tnode_free(struct key_vector *tn)
454{ 456{
455 struct callback_head *head = &tn->rcu; 457 struct callback_head *head = &tn->rcu;
456 458
@@ -459,7 +461,7 @@ static void tnode_free(struct tnode *tn)
459 tnode_free_size += TNODE_SIZE(1ul << tn->bits); 461 tnode_free_size += TNODE_SIZE(1ul << tn->bits);
460 node_free(tn); 462 node_free(tn);
461 463
462 tn = container_of(head, struct tnode, rcu); 464 tn = container_of(head, struct key_vector, rcu);
463 } 465 }
464 466
465 if (tnode_free_size >= PAGE_SIZE * sync_pages) { 467 if (tnode_free_size >= PAGE_SIZE * sync_pages) {
@@ -468,11 +470,12 @@ static void tnode_free(struct tnode *tn)
468 } 470 }
469} 471}
470 472
471static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, 473static struct key_vector __rcu **replace(struct trie *t,
472 struct tnode *tn) 474 struct key_vector *oldtnode,
475 struct key_vector *tn)
473{ 476{
474 struct tnode *tp = node_parent(oldtnode); 477 struct key_vector *tp = node_parent(oldtnode);
475 struct tnode **cptr; 478 struct key_vector **cptr;
476 unsigned long i; 479 unsigned long i;
477 480
478 /* setup the parent pointer out of and back into this node */ 481 /* setup the parent pointer out of and back into this node */
@@ -486,11 +489,11 @@ static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode,
486 tnode_free(oldtnode); 489 tnode_free(oldtnode);
487 490
488 /* record the pointer that is pointing to this node */ 491 /* record the pointer that is pointing to this node */
489 cptr = tp ? tp->tnode : &t->trie; 492 cptr = tp ? tp->tnode : t->tnode;
490 493
491 /* resize children now that oldtnode is freed */ 494 /* resize children now that oldtnode is freed */
492 for (i = tnode_child_length(tn); i;) { 495 for (i = tnode_child_length(tn); i;) {
493 struct tnode *inode = tnode_get_child(tn, --i); 496 struct key_vector *inode = tnode_get_child(tn, --i);
494 497
495 /* resize child node */ 498 /* resize child node */
496 if (tnode_full(tn, inode)) 499 if (tnode_full(tn, inode))
@@ -500,9 +503,10 @@ static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode,
500 return cptr; 503 return cptr;
501} 504}
502 505
503static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode) 506static struct key_vector __rcu **inflate(struct trie *t,
507 struct key_vector *oldtnode)
504{ 508{
505 struct tnode *tn; 509 struct key_vector *tn;
506 unsigned long i; 510 unsigned long i;
507 t_key m; 511 t_key m;
508 512
@@ -521,8 +525,8 @@ static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode)
521 * nodes. 525 * nodes.
522 */ 526 */
523 for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { 527 for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) {
524 struct tnode *inode = tnode_get_child(oldtnode, --i); 528 struct key_vector *inode = tnode_get_child(oldtnode, --i);
525 struct tnode *node0, *node1; 529 struct key_vector *node0, *node1;
526 unsigned long j, k; 530 unsigned long j, k;
527 531
528 /* An empty child */ 532 /* An empty child */
@@ -595,9 +599,10 @@ notnode:
595 return NULL; 599 return NULL;
596} 600}
597 601
598static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode) 602static struct key_vector __rcu **halve(struct trie *t,
603 struct key_vector *oldtnode)
599{ 604{
600 struct tnode *tn; 605 struct key_vector *tn;
601 unsigned long i; 606 unsigned long i;
602 607
603 pr_debug("In halve\n"); 608 pr_debug("In halve\n");
@@ -615,9 +620,9 @@ static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode)
615 * nodes. 620 * nodes.
616 */ 621 */
617 for (i = tnode_child_length(oldtnode); i;) { 622 for (i = tnode_child_length(oldtnode); i;) {
618 struct tnode *node1 = tnode_get_child(oldtnode, --i); 623 struct key_vector *node1 = tnode_get_child(oldtnode, --i);
619 struct tnode *node0 = tnode_get_child(oldtnode, --i); 624 struct key_vector *node0 = tnode_get_child(oldtnode, --i);
620 struct tnode *inode; 625 struct key_vector *inode;
621 626
622 /* At least one of the children is empty */ 627 /* At least one of the children is empty */
623 if (!node1 || !node0) { 628 if (!node1 || !node0) {
@@ -649,9 +654,9 @@ notnode:
649 return NULL; 654 return NULL;
650} 655}
651 656
652static void collapse(struct trie *t, struct tnode *oldtnode) 657static void collapse(struct trie *t, struct key_vector *oldtnode)
653{ 658{
654 struct tnode *n, *tp; 659 struct key_vector *n, *tp;
655 unsigned long i; 660 unsigned long i;
656 661
657 /* scan the tnode looking for that one child that might still exist */ 662 /* scan the tnode looking for that one child that might still exist */
@@ -667,7 +672,7 @@ static void collapse(struct trie *t, struct tnode *oldtnode)
667 node_free(oldtnode); 672 node_free(oldtnode);
668} 673}
669 674
670static unsigned char update_suffix(struct tnode *tn) 675static unsigned char update_suffix(struct key_vector *tn)
671{ 676{
672 unsigned char slen = tn->pos; 677 unsigned char slen = tn->pos;
673 unsigned long stride, i; 678 unsigned long stride, i;
@@ -678,7 +683,7 @@ static unsigned char update_suffix(struct tnode *tn)
678 * represent the nodes with suffix length equal to tn->pos 683 * represent the nodes with suffix length equal to tn->pos
679 */ 684 */
680 for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) { 685 for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) {
681 struct tnode *n = tnode_get_child(tn, i); 686 struct key_vector *n = tnode_get_child(tn, i);
682 687
683 if (!n || (n->slen <= slen)) 688 if (!n || (n->slen <= slen))
684 continue; 689 continue;
@@ -759,7 +764,7 @@ static unsigned char update_suffix(struct tnode *tn)
759 * tnode_child_length(tn) 764 * tnode_child_length(tn)
760 * 765 *
761 */ 766 */
762static bool should_inflate(const struct tnode *tp, const struct tnode *tn) 767static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn)
763{ 768{
764 unsigned long used = tnode_child_length(tn); 769 unsigned long used = tnode_child_length(tn);
765 unsigned long threshold = used; 770 unsigned long threshold = used;
@@ -774,7 +779,7 @@ static bool should_inflate(const struct tnode *tp, const struct tnode *tn)
774 return (used > 1) && tn->pos && ((50 * used) >= threshold); 779 return (used > 1) && tn->pos && ((50 * used) >= threshold);
775} 780}
776 781
777static bool should_halve(const struct tnode *tp, const struct tnode *tn) 782static inline bool should_halve(struct key_vector *tp, struct key_vector *tn)
778{ 783{
779 unsigned long used = tnode_child_length(tn); 784 unsigned long used = tnode_child_length(tn);
780 unsigned long threshold = used; 785 unsigned long threshold = used;
@@ -788,7 +793,7 @@ static bool should_halve(const struct tnode *tp, const struct tnode *tn)
788 return (used > 1) && (tn->bits > 1) && ((100 * used) < threshold); 793 return (used > 1) && (tn->bits > 1) && ((100 * used) < threshold);
789} 794}
790 795
791static bool should_collapse(const struct tnode *tn) 796static inline bool should_collapse(struct key_vector *tn)
792{ 797{
793 unsigned long used = tnode_child_length(tn); 798 unsigned long used = tnode_child_length(tn);
794 799
@@ -803,14 +808,15 @@ static bool should_collapse(const struct tnode *tn)
803} 808}
804 809
805#define MAX_WORK 10 810#define MAX_WORK 10
806static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) 811static struct key_vector __rcu **resize(struct trie *t,
812 struct key_vector *tn)
807{ 813{
808#ifdef CONFIG_IP_FIB_TRIE_STATS 814#ifdef CONFIG_IP_FIB_TRIE_STATS
809 struct trie_use_stats __percpu *stats = t->stats; 815 struct trie_use_stats __percpu *stats = t->stats;
810#endif 816#endif
811 struct tnode *tp = node_parent(tn); 817 struct key_vector *tp = node_parent(tn);
812 unsigned long cindex = tp ? get_index(tn->key, tp) : 0; 818 unsigned long cindex = tp ? get_index(tn->key, tp) : 0;
813 struct tnode __rcu **cptr = tp ? tp->tnode : &t->trie; 819 struct key_vector __rcu **cptr = tp ? tp->tnode : t->tnode;
814 int max_work = MAX_WORK; 820 int max_work = MAX_WORK;
815 821
816 pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", 822 pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
@@ -826,7 +832,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn)
826 * nonempty nodes that are above the threshold. 832 * nonempty nodes that are above the threshold.
827 */ 833 */
828 while (should_inflate(tp, tn) && max_work) { 834 while (should_inflate(tp, tn) && max_work) {
829 struct tnode __rcu **tcptr = inflate(t, tn); 835 struct key_vector __rcu **tcptr = inflate(t, tn);
830 836
831 if (!tcptr) { 837 if (!tcptr) {
832#ifdef CONFIG_IP_FIB_TRIE_STATS 838#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -848,7 +854,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn)
848 * node is above threshold. 854 * node is above threshold.
849 */ 855 */
850 while (should_halve(tp, tn) && max_work) { 856 while (should_halve(tp, tn) && max_work) {
851 struct tnode __rcu **tcptr = halve(t, tn); 857 struct key_vector __rcu **tcptr = halve(t, tn);
852 858
853 if (!tcptr) { 859 if (!tcptr) {
854#ifdef CONFIG_IP_FIB_TRIE_STATS 860#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -883,7 +889,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn)
883 return cptr; 889 return cptr;
884} 890}
885 891
886static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) 892static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l)
887{ 893{
888 while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) { 894 while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) {
889 if (update_suffix(tp) > l->slen) 895 if (update_suffix(tp) > l->slen)
@@ -892,7 +898,7 @@ static void leaf_pull_suffix(struct tnode *tp, struct tnode *l)
892 } 898 }
893} 899}
894 900
895static void leaf_push_suffix(struct tnode *tn, struct tnode *l) 901static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l)
896{ 902{
897 /* if this is a new leaf then tn will be NULL and we can sort 903 /* if this is a new leaf then tn will be NULL and we can sort
898 * out parent suffix lengths as a part of trie_rebalance 904 * out parent suffix lengths as a part of trie_rebalance
@@ -904,9 +910,10 @@ static void leaf_push_suffix(struct tnode *tn, struct tnode *l)
904} 910}
905 911
906/* rcu_read_lock needs to be hold by caller from readside */ 912/* rcu_read_lock needs to be hold by caller from readside */
907static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) 913static struct key_vector *fib_find_node(struct trie *t,
914 struct key_vector **tp, u32 key)
908{ 915{
909 struct tnode *pn = NULL, *n = rcu_dereference_rtnl(t->trie); 916 struct key_vector *pn = NULL, *n = rcu_dereference_rtnl(t->tnode[0]);
910 917
911 while (n) { 918 while (n) {
912 unsigned long index = get_index(key, n); 919 unsigned long index = get_index(key, n);
@@ -938,7 +945,7 @@ static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key)
938 n = tnode_get_child_rcu(n, index); 945 n = tnode_get_child_rcu(n, index);
939 } 946 }
940 947
941 *tn = pn; 948 *tp = pn;
942 949
943 return n; 950 return n;
944} 951}
@@ -968,24 +975,24 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen,
968 return NULL; 975 return NULL;
969} 976}
970 977
971static void trie_rebalance(struct trie *t, struct tnode *tn) 978static void trie_rebalance(struct trie *t, struct key_vector *tn)
972{ 979{
973 struct tnode __rcu **cptr = &t->trie; 980 struct key_vector __rcu **cptr = t->tnode;
974 981
975 while (tn) { 982 while (tn) {
976 struct tnode *tp = node_parent(tn); 983 struct key_vector *tp = node_parent(tn);
977 984
978 cptr = resize(t, tn); 985 cptr = resize(t, tn);
979 if (!tp) 986 if (!tp)
980 break; 987 break;
981 tn = container_of(cptr, struct tnode, tnode[0]); 988 tn = container_of(cptr, struct key_vector, tnode[0]);
982 } 989 }
983} 990}
984 991
985static int fib_insert_node(struct trie *t, struct tnode *tp, 992static int fib_insert_node(struct trie *t, struct key_vector *tp,
986 struct fib_alias *new, t_key key) 993 struct fib_alias *new, t_key key)
987{ 994{
988 struct tnode *n, *l; 995 struct key_vector *n, *l;
989 996
990 l = leaf_new(key, new); 997 l = leaf_new(key, new);
991 if (!l) 998 if (!l)
@@ -995,7 +1002,7 @@ static int fib_insert_node(struct trie *t, struct tnode *tp,
995 if (tp) 1002 if (tp)
996 n = tnode_get_child(tp, get_index(key, tp)); 1003 n = tnode_get_child(tp, get_index(key, tp));
997 else 1004 else
998 n = rcu_dereference_rtnl(t->trie); 1005 n = rcu_dereference_rtnl(t->tnode[0]);
999 1006
1000 /* Case 2: n is a LEAF or a TNODE and the key doesn't match. 1007 /* Case 2: n is a LEAF or a TNODE and the key doesn't match.
1001 * 1008 *
@@ -1004,7 +1011,7 @@ static int fib_insert_node(struct trie *t, struct tnode *tp,
1004 * leaves us in position for handling as case 3 1011 * leaves us in position for handling as case 3
1005 */ 1012 */
1006 if (n) { 1013 if (n) {
1007 struct tnode *tn; 1014 struct key_vector *tn;
1008 1015
1009 tn = tnode_new(key, __fls(key ^ n->key), 1); 1016 tn = tnode_new(key, __fls(key ^ n->key), 1);
1010 if (!tn) 1017 if (!tn)
@@ -1034,8 +1041,8 @@ noleaf:
1034 return -ENOMEM; 1041 return -ENOMEM;
1035} 1042}
1036 1043
1037static int fib_insert_alias(struct trie *t, struct tnode *tp, 1044static int fib_insert_alias(struct trie *t, struct key_vector *tp,
1038 struct tnode *l, struct fib_alias *new, 1045 struct key_vector *l, struct fib_alias *new,
1039 struct fib_alias *fa, t_key key) 1046 struct fib_alias *fa, t_key key)
1040{ 1047{
1041 if (!l) 1048 if (!l)
@@ -1072,7 +1079,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1072{ 1079{
1073 struct trie *t = (struct trie *)tb->tb_data; 1080 struct trie *t = (struct trie *)tb->tb_data;
1074 struct fib_alias *fa, *new_fa; 1081 struct fib_alias *fa, *new_fa;
1075 struct tnode *l, *tp; 1082 struct key_vector *l, *tp;
1076 struct fib_info *fi; 1083 struct fib_info *fi;
1077 u8 plen = cfg->fc_dst_len; 1084 u8 plen = cfg->fc_dst_len;
1078 u8 slen = KEYLENGTH - plen; 1085 u8 slen = KEYLENGTH - plen;
@@ -1237,7 +1244,7 @@ err:
1237 return err; 1244 return err;
1238} 1245}
1239 1246
1240static inline t_key prefix_mismatch(t_key key, struct tnode *n) 1247static inline t_key prefix_mismatch(t_key key, struct key_vector *n)
1241{ 1248{
1242 t_key prefix = n->key; 1249 t_key prefix = n->key;
1243 1250
@@ -1253,12 +1260,12 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
1253 struct trie_use_stats __percpu *stats = t->stats; 1260 struct trie_use_stats __percpu *stats = t->stats;
1254#endif 1261#endif
1255 const t_key key = ntohl(flp->daddr); 1262 const t_key key = ntohl(flp->daddr);
1256 struct tnode *n, *pn; 1263 struct key_vector *n, *pn;
1257 struct fib_alias *fa; 1264 struct fib_alias *fa;
1258 unsigned long index; 1265 unsigned long index;
1259 t_key cindex; 1266 t_key cindex;
1260 1267
1261 n = rcu_dereference(t->trie); 1268 n = rcu_dereference(t->tnode[0]);
1262 if (!n) 1269 if (!n)
1263 return -EAGAIN; 1270 return -EAGAIN;
1264 1271
@@ -1310,7 +1317,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
1310 /* Step 2: Sort out leaves and begin backtracing for longest prefix */ 1317 /* Step 2: Sort out leaves and begin backtracing for longest prefix */
1311 for (;;) { 1318 for (;;) {
1312 /* record the pointer where our next node pointer is stored */ 1319 /* record the pointer where our next node pointer is stored */
1313 struct tnode __rcu **cptr = n->tnode; 1320 struct key_vector __rcu **cptr = n->tnode;
1314 1321
1315 /* This test verifies that none of the bits that differ 1322 /* This test verifies that none of the bits that differ
1316 * between the key and the prefix exist in the region of 1323 * between the key and the prefix exist in the region of
@@ -1419,8 +1426,8 @@ found:
1419} 1426}
1420EXPORT_SYMBOL_GPL(fib_table_lookup); 1427EXPORT_SYMBOL_GPL(fib_table_lookup);
1421 1428
1422static void fib_remove_alias(struct trie *t, struct tnode *tp, 1429static void fib_remove_alias(struct trie *t, struct key_vector *tp,
1423 struct tnode *l, struct fib_alias *old) 1430 struct key_vector *l, struct fib_alias *old)
1424{ 1431{
1425 /* record the location of the previous list_info entry */ 1432 /* record the location of the previous list_info entry */
1426 struct hlist_node **pprev = old->fa_list.pprev; 1433 struct hlist_node **pprev = old->fa_list.pprev;
@@ -1453,7 +1460,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1453{ 1460{
1454 struct trie *t = (struct trie *) tb->tb_data; 1461 struct trie *t = (struct trie *) tb->tb_data;
1455 struct fib_alias *fa, *fa_to_delete; 1462 struct fib_alias *fa, *fa_to_delete;
1456 struct tnode *l, *tp; 1463 struct key_vector *l, *tp;
1457 u8 plen = cfg->fc_dst_len; 1464 u8 plen = cfg->fc_dst_len;
1458 u8 slen = KEYLENGTH - plen; 1465 u8 slen = KEYLENGTH - plen;
1459 u8 tos = cfg->fc_tos; 1466 u8 tos = cfg->fc_tos;
@@ -1520,9 +1527,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1520} 1527}
1521 1528
1522/* Scan for the next leaf starting at the provided key value */ 1529/* Scan for the next leaf starting at the provided key value */
1523static struct tnode *leaf_walk_rcu(struct tnode **tn, t_key key) 1530static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key)
1524{ 1531{
1525 struct tnode *pn, *n = *tn; 1532 struct key_vector *pn, *n = *tn;
1526 unsigned long cindex; 1533 unsigned long cindex;
1527 1534
1528 /* record parent node for backtracing */ 1535 /* record parent node for backtracing */
@@ -1588,10 +1595,10 @@ void fib_table_flush_external(struct fib_table *tb)
1588{ 1595{
1589 struct trie *t = (struct trie *)tb->tb_data; 1596 struct trie *t = (struct trie *)tb->tb_data;
1590 struct fib_alias *fa; 1597 struct fib_alias *fa;
1591 struct tnode *n, *pn; 1598 struct key_vector *n, *pn;
1592 unsigned long cindex; 1599 unsigned long cindex;
1593 1600
1594 n = rcu_dereference(t->trie); 1601 n = rcu_dereference(t->tnode[0]);
1595 if (!n) 1602 if (!n)
1596 return; 1603 return;
1597 1604
@@ -1642,14 +1649,14 @@ backtrace:
1642int fib_table_flush(struct fib_table *tb) 1649int fib_table_flush(struct fib_table *tb)
1643{ 1650{
1644 struct trie *t = (struct trie *)tb->tb_data; 1651 struct trie *t = (struct trie *)tb->tb_data;
1652 struct key_vector *n, *pn;
1645 struct hlist_node *tmp; 1653 struct hlist_node *tmp;
1646 struct fib_alias *fa; 1654 struct fib_alias *fa;
1647 struct tnode *n, *pn;
1648 unsigned long cindex; 1655 unsigned long cindex;
1649 unsigned char slen; 1656 unsigned char slen;
1650 int found = 0; 1657 int found = 0;
1651 1658
1652 n = rcu_dereference(t->trie); 1659 n = rcu_dereference(t->tnode[0]);
1653 if (!n) 1660 if (!n)
1654 goto flush_complete; 1661 goto flush_complete;
1655 1662
@@ -1664,7 +1671,7 @@ backtrace:
1664 /* walk trie in reverse order */ 1671 /* walk trie in reverse order */
1665 do { 1672 do {
1666 while (!(cindex--)) { 1673 while (!(cindex--)) {
1667 struct tnode __rcu **cptr; 1674 struct key_vector __rcu **cptr;
1668 t_key pkey = pn->key; 1675 t_key pkey = pn->key;
1669 1676
1670 n = pn; 1677 n = pn;
@@ -1677,7 +1684,8 @@ backtrace:
1677 if (!pn) 1684 if (!pn)
1678 goto flush_complete; 1685 goto flush_complete;
1679 1686
1680 pn = container_of(cptr, struct tnode, tnode[0]); 1687 pn = container_of(cptr, struct key_vector,
1688 tnode[0]);
1681 cindex = get_index(pkey, pn); 1689 cindex = get_index(pkey, pn);
1682 } 1690 }
1683 1691
@@ -1742,7 +1750,7 @@ void fib_free_table(struct fib_table *tb)
1742 call_rcu(&tb->rcu, __trie_free_rcu); 1750 call_rcu(&tb->rcu, __trie_free_rcu);
1743} 1751}
1744 1752
1745static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, 1753static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
1746 struct sk_buff *skb, struct netlink_callback *cb) 1754 struct sk_buff *skb, struct netlink_callback *cb)
1747{ 1755{
1748 __be32 xkey = htonl(l->key); 1756 __be32 xkey = htonl(l->key);
@@ -1783,14 +1791,14 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
1783 struct netlink_callback *cb) 1791 struct netlink_callback *cb)
1784{ 1792{
1785 struct trie *t = (struct trie *)tb->tb_data; 1793 struct trie *t = (struct trie *)tb->tb_data;
1786 struct tnode *l, *tp; 1794 struct key_vector *l, *tp;
1787 /* Dump starting at last key. 1795 /* Dump starting at last key.
1788 * Note: 0.0.0.0/0 (ie default) is first key. 1796 * Note: 0.0.0.0/0 (ie default) is first key.
1789 */ 1797 */
1790 int count = cb->args[2]; 1798 int count = cb->args[2];
1791 t_key key = cb->args[3]; 1799 t_key key = cb->args[3];
1792 1800
1793 tp = rcu_dereference_rtnl(t->trie); 1801 tp = rcu_dereference_rtnl(t->tnode[0]);
1794 1802
1795 while ((l = leaf_walk_rcu(&tp, key)) != NULL) { 1803 while ((l = leaf_walk_rcu(&tp, key)) != NULL) {
1796 if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { 1804 if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
@@ -1843,7 +1851,7 @@ struct fib_table *fib_trie_table(u32 id)
1843 tb->tb_num_default = 0; 1851 tb->tb_num_default = 0;
1844 1852
1845 t = (struct trie *) tb->tb_data; 1853 t = (struct trie *) tb->tb_data;
1846 RCU_INIT_POINTER(t->trie, NULL); 1854 RCU_INIT_POINTER(t->tnode[0], NULL);
1847#ifdef CONFIG_IP_FIB_TRIE_STATS 1855#ifdef CONFIG_IP_FIB_TRIE_STATS
1848 t->stats = alloc_percpu(struct trie_use_stats); 1856 t->stats = alloc_percpu(struct trie_use_stats);
1849 if (!t->stats) { 1857 if (!t->stats) {
@@ -1860,16 +1868,16 @@ struct fib_table *fib_trie_table(u32 id)
1860struct fib_trie_iter { 1868struct fib_trie_iter {
1861 struct seq_net_private p; 1869 struct seq_net_private p;
1862 struct fib_table *tb; 1870 struct fib_table *tb;
1863 struct tnode *tnode; 1871 struct key_vector *tnode;
1864 unsigned int index; 1872 unsigned int index;
1865 unsigned int depth; 1873 unsigned int depth;
1866}; 1874};
1867 1875
1868static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) 1876static struct key_vector *fib_trie_get_next(struct fib_trie_iter *iter)
1869{ 1877{
1870 unsigned long cindex = iter->index; 1878 unsigned long cindex = iter->index;
1871 struct tnode *tn = iter->tnode; 1879 struct key_vector *tn = iter->tnode;
1872 struct tnode *p; 1880 struct key_vector *p;
1873 1881
1874 /* A single entry routing table */ 1882 /* A single entry routing table */
1875 if (!tn) 1883 if (!tn)
@@ -1879,7 +1887,7 @@ static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter)
1879 iter->tnode, iter->index, iter->depth); 1887 iter->tnode, iter->index, iter->depth);
1880rescan: 1888rescan:
1881 while (cindex < tnode_child_length(tn)) { 1889 while (cindex < tnode_child_length(tn)) {
1882 struct tnode *n = tnode_get_child_rcu(tn, cindex); 1890 struct key_vector *n = tnode_get_child_rcu(tn, cindex);
1883 1891
1884 if (n) { 1892 if (n) {
1885 if (IS_LEAF(n)) { 1893 if (IS_LEAF(n)) {
@@ -1910,15 +1918,15 @@ rescan:
1910 return NULL; 1918 return NULL;
1911} 1919}
1912 1920
1913static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter, 1921static struct key_vector *fib_trie_get_first(struct fib_trie_iter *iter,
1914 struct trie *t) 1922 struct trie *t)
1915{ 1923{
1916 struct tnode *n; 1924 struct key_vector *n;
1917 1925
1918 if (!t) 1926 if (!t)
1919 return NULL; 1927 return NULL;
1920 1928
1921 n = rcu_dereference(t->trie); 1929 n = rcu_dereference(t->tnode[0]);
1922 if (!n) 1930 if (!n)
1923 return NULL; 1931 return NULL;
1924 1932
@@ -1937,7 +1945,7 @@ static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter,
1937 1945
1938static void trie_collect_stats(struct trie *t, struct trie_stat *s) 1946static void trie_collect_stats(struct trie *t, struct trie_stat *s)
1939{ 1947{
1940 struct tnode *n; 1948 struct key_vector *n;
1941 struct fib_trie_iter iter; 1949 struct fib_trie_iter iter;
1942 1950
1943 memset(s, 0, sizeof(*s)); 1951 memset(s, 0, sizeof(*s));
@@ -2002,7 +2010,7 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
2002 seq_putc(seq, '\n'); 2010 seq_putc(seq, '\n');
2003 seq_printf(seq, "\tPointers: %u\n", pointers); 2011 seq_printf(seq, "\tPointers: %u\n", pointers);
2004 2012
2005 bytes += sizeof(struct tnode *) * pointers; 2013 bytes += sizeof(struct key_vector *) * pointers;
2006 seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers); 2014 seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers);
2007 seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024); 2015 seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024);
2008} 2016}
@@ -2095,7 +2103,7 @@ static const struct file_operations fib_triestat_fops = {
2095 .release = single_release_net, 2103 .release = single_release_net,
2096}; 2104};
2097 2105
2098static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos) 2106static struct key_vector *fib_trie_get_idx(struct seq_file *seq, loff_t pos)
2099{ 2107{
2100 struct fib_trie_iter *iter = seq->private; 2108 struct fib_trie_iter *iter = seq->private;
2101 struct net *net = seq_file_net(seq); 2109 struct net *net = seq_file_net(seq);
@@ -2107,7 +2115,7 @@ static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos)
2107 struct fib_table *tb; 2115 struct fib_table *tb;
2108 2116
2109 hlist_for_each_entry_rcu(tb, head, tb_hlist) { 2117 hlist_for_each_entry_rcu(tb, head, tb_hlist) {
2110 struct tnode *n; 2118 struct key_vector *n;
2111 2119
2112 for (n = fib_trie_get_first(iter, 2120 for (n = fib_trie_get_first(iter,
2113 (struct trie *) tb->tb_data); 2121 (struct trie *) tb->tb_data);
@@ -2136,7 +2144,7 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2136 struct fib_table *tb = iter->tb; 2144 struct fib_table *tb = iter->tb;
2137 struct hlist_node *tb_node; 2145 struct hlist_node *tb_node;
2138 unsigned int h; 2146 unsigned int h;
2139 struct tnode *n; 2147 struct key_vector *n;
2140 2148
2141 ++*pos; 2149 ++*pos;
2142 /* next node in same table */ 2150 /* next node in same table */
@@ -2222,7 +2230,7 @@ static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
2222static int fib_trie_seq_show(struct seq_file *seq, void *v) 2230static int fib_trie_seq_show(struct seq_file *seq, void *v)
2223{ 2231{
2224 const struct fib_trie_iter *iter = seq->private; 2232 const struct fib_trie_iter *iter = seq->private;
2225 struct tnode *n = v; 2233 struct key_vector *n = v;
2226 2234
2227 if (!node_parent_rcu(n)) 2235 if (!node_parent_rcu(n))
2228 fib_table_print(seq, iter->tb); 2236 fib_table_print(seq, iter->tb);
@@ -2284,15 +2292,16 @@ static const struct file_operations fib_trie_fops = {
2284struct fib_route_iter { 2292struct fib_route_iter {
2285 struct seq_net_private p; 2293 struct seq_net_private p;
2286 struct fib_table *main_tb; 2294 struct fib_table *main_tb;
2287 struct tnode *tnode; 2295 struct key_vector *tnode;
2288 loff_t pos; 2296 loff_t pos;
2289 t_key key; 2297 t_key key;
2290}; 2298};
2291 2299
2292static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) 2300static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
2301 loff_t pos)
2293{ 2302{
2294 struct fib_table *tb = iter->main_tb; 2303 struct fib_table *tb = iter->main_tb;
2295 struct tnode *l, **tp = &iter->tnode; 2304 struct key_vector *l, **tp = &iter->tnode;
2296 struct trie *t; 2305 struct trie *t;
2297 t_key key; 2306 t_key key;
2298 2307
@@ -2302,7 +2311,7 @@ static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos)
2302 key = iter->key; 2311 key = iter->key;
2303 } else { 2312 } else {
2304 t = (struct trie *)tb->tb_data; 2313 t = (struct trie *)tb->tb_data;
2305 iter->tnode = rcu_dereference_rtnl(t->trie); 2314 iter->tnode = rcu_dereference_rtnl(t->tnode[0]);
2306 iter->pos = 0; 2315 iter->pos = 0;
2307 key = 0; 2316 key = 0;
2308 } 2317 }
@@ -2348,7 +2357,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
2348 return fib_route_get_idx(iter, *pos); 2357 return fib_route_get_idx(iter, *pos);
2349 2358
2350 t = (struct trie *)tb->tb_data; 2359 t = (struct trie *)tb->tb_data;
2351 iter->tnode = rcu_dereference_rtnl(t->trie); 2360 iter->tnode = rcu_dereference_rtnl(t->tnode[0]);
2352 iter->pos = 0; 2361 iter->pos = 0;
2353 iter->key = 0; 2362 iter->key = 0;
2354 2363
@@ -2358,7 +2367,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
2358static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2367static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2359{ 2368{
2360 struct fib_route_iter *iter = seq->private; 2369 struct fib_route_iter *iter = seq->private;
2361 struct tnode *l = NULL; 2370 struct key_vector *l = NULL;
2362 t_key key = iter->key; 2371 t_key key = iter->key;
2363 2372
2364 ++*pos; 2373 ++*pos;
@@ -2406,7 +2415,7 @@ static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info
2406static int fib_route_seq_show(struct seq_file *seq, void *v) 2415static int fib_route_seq_show(struct seq_file *seq, void *v)
2407{ 2416{
2408 struct fib_alias *fa; 2417 struct fib_alias *fa;
2409 struct tnode *l = v; 2418 struct key_vector *l = v;
2410 __be32 prefix; 2419 __be32 prefix;
2411 2420
2412 if (v == SEQ_START_TOKEN) { 2421 if (v == SEQ_START_TOKEN) {