diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2015-03-06 12:54:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-06 15:49:27 -0500 |
commit | 35c6edac197fcfb53cea9993d9b64386b15abf48 (patch) | |
tree | 805ed820e32fb1a5bd0abea40393d3bef8422c4e /net/ipv4/fib_trie.c | |
parent | 8d8e810ca8ec2541f30af916f0de1b41ac86ec4a (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.c | 247 |
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 | ||
97 | struct tnode { | 97 | struct 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 | ||
140 | struct trie { | 140 | struct 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 | ||
147 | static struct tnode **resize(struct trie *t, struct tnode *tn); | 147 | static struct key_vector **resize(struct trie *t, struct key_vector *tn); |
148 | static size_t tnode_free_size; | 148 | static 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 */ |
167 | static inline void node_set_parent(struct tnode *n, struct tnode *tp) | 167 | static 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 | */ |
178 | static inline unsigned long tnode_child_length(const struct tnode *tn) | 178 | static 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 */ |
184 | static inline struct tnode *tnode_get_child(const struct tnode *tn, | 184 | static 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 */ |
191 | static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, | 191 | static 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 | ||
284 | static void __node_free_rcu(struct rcu_head *head) | 284 | static 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 | ||
298 | static struct tnode *tnode_alloc(int bits) | 298 | static 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 | ||
315 | static inline void empty_child_inc(struct tnode *n) | 315 | static 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 | ||
320 | static inline void empty_child_dec(struct tnode *n) | 320 | static 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 | ||
325 | static struct tnode *leaf_new(t_key key, struct fib_alias *fa) | 325 | static 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 | ||
347 | static struct tnode *tnode_new(t_key key, int pos, int bits) | 347 | static 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 | */ |
375 | static inline int tnode_full(const struct tnode *tn, const struct tnode *n) | 375 | static 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 | */ |
383 | static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) | 383 | static 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 | ||
411 | static void update_children(struct tnode *tn) | 412 | static 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 | ||
433 | static inline void put_child_root(struct tnode *tp, struct trie *t, | 434 | static 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 | ||
442 | static inline void tnode_free_init(struct tnode *tn) | 443 | static 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 | ||
447 | static inline void tnode_free_append(struct tnode *tn, struct tnode *n) | 448 | static 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 | ||
453 | static void tnode_free(struct tnode *tn) | 455 | static 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 | ||
471 | static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, | 473 | static 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 | ||
503 | static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode) | 506 | static 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 | ||
598 | static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode) | 602 | static 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 | ||
652 | static void collapse(struct trie *t, struct tnode *oldtnode) | 657 | static 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 | ||
670 | static unsigned char update_suffix(struct tnode *tn) | 675 | static 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 | */ |
762 | static bool should_inflate(const struct tnode *tp, const struct tnode *tn) | 767 | static 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 | ||
777 | static bool should_halve(const struct tnode *tp, const struct tnode *tn) | 782 | static 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 | ||
791 | static bool should_collapse(const struct tnode *tn) | 796 | static 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 |
806 | static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) | 811 | static 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 | ||
886 | static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) | 892 | static 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 | ||
895 | static void leaf_push_suffix(struct tnode *tn, struct tnode *l) | 901 | static 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 */ |
907 | static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) | 913 | static 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 | ||
971 | static void trie_rebalance(struct trie *t, struct tnode *tn) | 978 | static 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 | ||
985 | static int fib_insert_node(struct trie *t, struct tnode *tp, | 992 | static 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 | ||
1037 | static int fib_insert_alias(struct trie *t, struct tnode *tp, | 1044 | static 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 | ||
1240 | static inline t_key prefix_mismatch(t_key key, struct tnode *n) | 1247 | static 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 | } |
1420 | EXPORT_SYMBOL_GPL(fib_table_lookup); | 1427 | EXPORT_SYMBOL_GPL(fib_table_lookup); |
1421 | 1428 | ||
1422 | static void fib_remove_alias(struct trie *t, struct tnode *tp, | 1429 | static 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 */ |
1523 | static struct tnode *leaf_walk_rcu(struct tnode **tn, t_key key) | 1530 | static 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: | |||
1642 | int fib_table_flush(struct fib_table *tb) | 1649 | int 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 | ||
1745 | static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, | 1753 | static 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) | |||
1860 | struct fib_trie_iter { | 1868 | struct 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 | ||
1868 | static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) | 1876 | static 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); |
1880 | rescan: | 1888 | rescan: |
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 | ||
1913 | static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter, | 1921 | static 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 | ||
1938 | static void trie_collect_stats(struct trie *t, struct trie_stat *s) | 1946 | static 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 | ||
2098 | static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos) | 2106 | static 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) | |||
2222 | static int fib_trie_seq_show(struct seq_file *seq, void *v) | 2230 | static 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 = { | |||
2284 | struct fib_route_iter { | 2292 | struct 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 | ||
2292 | static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) | 2300 | static 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) | |||
2358 | static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 2367 | static 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 | |||
2406 | static int fib_route_seq_show(struct seq_file *seq, void *v) | 2415 | static 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) { |