aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_fib.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 14:38:13 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 14:38:13 -0500
commitcb18eccff48ef3986d1072964590bce6fec705fb (patch)
tree777fb1d15e0281341e1e02c9803d989538d346f2 /net/ipv6/ip6_fib.c
parentc827ba4cb49a30ce581201fd0ba2be77cde412c7 (diff)
parent5ef213f6842277ee1df5659f59fac0ffc9beb411 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (45 commits) [IPV4]: Restore multipath routing after rt_next changes. [XFRM] IPV6: Fix outbound RO transformation which is broken by IPsec tunnel patch. [NET]: Reorder fields of struct dst_entry [DECNET]: Convert decnet route to use the new dst_entry 'next' pointer [IPV6]: Convert ipv6 route to use the new dst_entry 'next' pointer [IPV4]: Convert ipv4 route to use the new dst_entry 'next' pointer [NET]: Introduce union in struct dst_entry to hold 'next' pointer [DECNET]: fix misannotation of linkinfo_dn [DECNET]: FRA_{DST,SRC} are le16 for decnet [UDP]: UDP can use sk_hash to speedup lookups [NET]: Fix whitespace errors. [NET] XFRM: Fix whitespace errors. [NET] X25: Fix whitespace errors. [NET] WANROUTER: Fix whitespace errors. [NET] UNIX: Fix whitespace errors. [NET] TIPC: Fix whitespace errors. [NET] SUNRPC: Fix whitespace errors. [NET] SCTP: Fix whitespace errors. [NET] SCHED: Fix whitespace errors. [NET] RXRPC: Fix whitespace errors. ...
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r--net/ipv6/ip6_fib.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 827f8842b578..f4d7be77eb0f 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Linux INET6 implementation 2 * Linux INET6 implementation
3 * Forwarding Information Database 3 * Forwarding Information Database
4 * 4 *
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $ 8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $
9 * 9 *
@@ -97,7 +97,7 @@ static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
97 97
98static struct fib6_walker_t fib6_walker_list = { 98static struct fib6_walker_t fib6_walker_list = {
99 .prev = &fib6_walker_list, 99 .prev = &fib6_walker_list,
100 .next = &fib6_walker_list, 100 .next = &fib6_walker_list,
101}; 101};
102 102
103#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next) 103#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next)
@@ -131,7 +131,7 @@ static __inline__ u32 fib6_new_sernum(void)
131/* 131/*
132 * Auxiliary address test functions for the radix tree. 132 * Auxiliary address test functions for the radix tree.
133 * 133 *
134 * These assume a 32bit processor (although it will work on 134 * These assume a 32bit processor (although it will work on
135 * 64bit processors) 135 * 64bit processors)
136 */ 136 */
137 137
@@ -297,7 +297,7 @@ static int fib6_dump_node(struct fib6_walker_t *w)
297 int res; 297 int res;
298 struct rt6_info *rt; 298 struct rt6_info *rt;
299 299
300 for (rt = w->leaf; rt; rt = rt->u.next) { 300 for (rt = w->leaf; rt; rt = rt->u.dst.rt6_next) {
301 res = rt6_dump_route(rt, w->args); 301 res = rt6_dump_route(rt, w->args);
302 if (res < 0) { 302 if (res < 0) {
303 /* Frame is full, suspend walking */ 303 /* Frame is full, suspend walking */
@@ -433,7 +433,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
433 struct fib6_node *pn = NULL; 433 struct fib6_node *pn = NULL;
434 struct rt6key *key; 434 struct rt6key *key;
435 int bit; 435 int bit;
436 __be32 dir = 0; 436 __be32 dir = 0;
437 __u32 sernum = fib6_new_sernum(); 437 __u32 sernum = fib6_new_sernum();
438 438
439 RT6_TRACE("fib6_add_1\n"); 439 RT6_TRACE("fib6_add_1\n");
@@ -451,27 +451,27 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
451 if (plen < fn->fn_bit || 451 if (plen < fn->fn_bit ||
452 !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) 452 !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
453 goto insert_above; 453 goto insert_above;
454 454
455 /* 455 /*
456 * Exact match ? 456 * Exact match ?
457 */ 457 */
458 458
459 if (plen == fn->fn_bit) { 459 if (plen == fn->fn_bit) {
460 /* clean up an intermediate node */ 460 /* clean up an intermediate node */
461 if ((fn->fn_flags & RTN_RTINFO) == 0) { 461 if ((fn->fn_flags & RTN_RTINFO) == 0) {
462 rt6_release(fn->leaf); 462 rt6_release(fn->leaf);
463 fn->leaf = NULL; 463 fn->leaf = NULL;
464 } 464 }
465 465
466 fn->fn_sernum = sernum; 466 fn->fn_sernum = sernum;
467 467
468 return fn; 468 return fn;
469 } 469 }
470 470
471 /* 471 /*
472 * We have more bits to go 472 * We have more bits to go
473 */ 473 */
474 474
475 /* Try to walk down on tree. */ 475 /* Try to walk down on tree. */
476 fn->fn_sernum = sernum; 476 fn->fn_sernum = sernum;
477 dir = addr_bit_set(addr, fn->fn_bit); 477 dir = addr_bit_set(addr, fn->fn_bit);
@@ -489,7 +489,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
489 if (ln == NULL) 489 if (ln == NULL)
490 return NULL; 490 return NULL;
491 ln->fn_bit = plen; 491 ln->fn_bit = plen;
492 492
493 ln->parent = pn; 493 ln->parent = pn;
494 ln->fn_sernum = sernum; 494 ln->fn_sernum = sernum;
495 495
@@ -503,7 +503,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
503 503
504insert_above: 504insert_above:
505 /* 505 /*
506 * split since we don't have a common prefix anymore or 506 * split since we don't have a common prefix anymore or
507 * we have a less significant route. 507 * we have a less significant route.
508 * we've to insert an intermediate node on the list 508 * we've to insert an intermediate node on the list
509 * this new node will point to the one we need to create 509 * this new node will point to the one we need to create
@@ -517,18 +517,18 @@ insert_above:
517 See comment in __ipv6_addr_diff: bit may be an invalid value, 517 See comment in __ipv6_addr_diff: bit may be an invalid value,
518 but if it is >= plen, the value is ignored in any case. 518 but if it is >= plen, the value is ignored in any case.
519 */ 519 */
520 520
521 bit = __ipv6_addr_diff(addr, &key->addr, addrlen); 521 bit = __ipv6_addr_diff(addr, &key->addr, addrlen);
522 522
523 /* 523 /*
524 * (intermediate)[in] 524 * (intermediate)[in]
525 * / \ 525 * / \
526 * (new leaf node)[ln] (old node)[fn] 526 * (new leaf node)[ln] (old node)[fn]
527 */ 527 */
528 if (plen > bit) { 528 if (plen > bit) {
529 in = node_alloc(); 529 in = node_alloc();
530 ln = node_alloc(); 530 ln = node_alloc();
531 531
532 if (in == NULL || ln == NULL) { 532 if (in == NULL || ln == NULL) {
533 if (in) 533 if (in)
534 node_free(in); 534 node_free(in);
@@ -537,8 +537,8 @@ insert_above:
537 return NULL; 537 return NULL;
538 } 538 }
539 539
540 /* 540 /*
541 * new intermediate node. 541 * new intermediate node.
542 * RTN_RTINFO will 542 * RTN_RTINFO will
543 * be off since that an address that chooses one of 543 * be off since that an address that chooses one of
544 * the branches would not match less specific routes 544 * the branches would not match less specific routes
@@ -575,7 +575,7 @@ insert_above:
575 } 575 }
576 } else { /* plen <= bit */ 576 } else { /* plen <= bit */
577 577
578 /* 578 /*
579 * (new leaf node)[ln] 579 * (new leaf node)[ln]
580 * / \ 580 * / \
581 * (old node)[fn] NULL 581 * (old node)[fn] NULL
@@ -591,7 +591,7 @@ insert_above:
591 ln->parent = pn; 591 ln->parent = pn;
592 592
593 ln->fn_sernum = sernum; 593 ln->fn_sernum = sernum;
594 594
595 if (dir) 595 if (dir)
596 pn->right = ln; 596 pn->right = ln;
597 else 597 else
@@ -623,11 +623,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
623 fn->leaf == &ip6_null_entry && 623 fn->leaf == &ip6_null_entry &&
624 !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){ 624 !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
625 fn->leaf = rt; 625 fn->leaf = rt;
626 rt->u.next = NULL; 626 rt->u.dst.rt6_next = NULL;
627 goto out; 627 goto out;
628 } 628 }
629 629
630 for (iter = fn->leaf; iter; iter=iter->u.next) { 630 for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) {
631 /* 631 /*
632 * Search for duplicates 632 * Search for duplicates
633 */ 633 */
@@ -655,7 +655,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
655 if (iter->rt6i_metric > rt->rt6i_metric) 655 if (iter->rt6i_metric > rt->rt6i_metric)
656 break; 656 break;
657 657
658 ins = &iter->u.next; 658 ins = &iter->u.dst.rt6_next;
659 } 659 }
660 660
661 /* 661 /*
@@ -663,7 +663,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
663 */ 663 */
664 664
665out: 665out:
666 rt->u.next = iter; 666 rt->u.dst.rt6_next = iter;
667 *ins = rt; 667 *ins = rt;
668 rt->rt6i_node = fn; 668 rt->rt6i_node = fn;
669 atomic_inc(&rt->rt6i_ref); 669 atomic_inc(&rt->rt6i_ref);
@@ -1104,7 +1104,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
1104 RT6_TRACE("fib6_del_route\n"); 1104 RT6_TRACE("fib6_del_route\n");
1105 1105
1106 /* Unlink it */ 1106 /* Unlink it */
1107 *rtp = rt->u.next; 1107 *rtp = rt->u.dst.rt6_next;
1108 rt->rt6i_node = NULL; 1108 rt->rt6i_node = NULL;
1109 rt6_stats.fib_rt_entries--; 1109 rt6_stats.fib_rt_entries--;
1110 rt6_stats.fib_discarded_routes++; 1110 rt6_stats.fib_discarded_routes++;
@@ -1114,14 +1114,14 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
1114 FOR_WALKERS(w) { 1114 FOR_WALKERS(w) {
1115 if (w->state == FWS_C && w->leaf == rt) { 1115 if (w->state == FWS_C && w->leaf == rt) {
1116 RT6_TRACE("walker %p adjusted by delroute\n", w); 1116 RT6_TRACE("walker %p adjusted by delroute\n", w);
1117 w->leaf = rt->u.next; 1117 w->leaf = rt->u.dst.rt6_next;
1118 if (w->leaf == NULL) 1118 if (w->leaf == NULL)
1119 w->state = FWS_U; 1119 w->state = FWS_U;
1120 } 1120 }
1121 } 1121 }
1122 read_unlock(&fib6_walker_lock); 1122 read_unlock(&fib6_walker_lock);
1123 1123
1124 rt->u.next = NULL; 1124 rt->u.dst.rt6_next = NULL;
1125 1125
1126 if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT) 1126 if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT)
1127 fn->leaf = &ip6_null_entry; 1127 fn->leaf = &ip6_null_entry;
@@ -1189,7 +1189,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
1189 * Walk the leaf entries looking for ourself 1189 * Walk the leaf entries looking for ourself
1190 */ 1190 */
1191 1191
1192 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { 1192 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.dst.rt6_next) {
1193 if (*rtp == rt) { 1193 if (*rtp == rt) {
1194 fib6_del_route(fn, rtp, info); 1194 fib6_del_route(fn, rtp, info);
1195 return 0; 1195 return 0;
@@ -1205,7 +1205,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
1205 * However, it is internally reenterable wrt itself and fib6_add/fib6_del. 1205 * However, it is internally reenterable wrt itself and fib6_add/fib6_del.
1206 * It means, that we can modify tree during walking 1206 * It means, that we can modify tree during walking
1207 * and use this function for garbage collection, clone pruning, 1207 * and use this function for garbage collection, clone pruning,
1208 * cleaning tree when a device goes down etc. etc. 1208 * cleaning tree when a device goes down etc. etc.
1209 * 1209 *
1210 * It guarantees that every node will be traversed, 1210 * It guarantees that every node will be traversed,
1211 * and that it will be traversed only once. 1211 * and that it will be traversed only once.
@@ -1244,7 +1244,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w)
1244 continue; 1244 continue;
1245 } 1245 }
1246 w->state = FWS_L; 1246 w->state = FWS_L;
1247#endif 1247#endif
1248 case FWS_L: 1248 case FWS_L:
1249 if (fn->left) { 1249 if (fn->left) {
1250 w->node = fn->left; 1250 w->node = fn->left;
@@ -1316,7 +1316,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
1316 struct rt6_info *rt; 1316 struct rt6_info *rt;
1317 struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w; 1317 struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w;
1318 1318
1319 for (rt = w->leaf; rt; rt = rt->u.next) { 1319 for (rt = w->leaf; rt; rt = rt->u.dst.rt6_next) {
1320 res = c->func(rt, c->arg); 1320 res = c->func(rt, c->arg);
1321 if (res < 0) { 1321 if (res < 0) {
1322 w->leaf = rt; 1322 w->leaf = rt;
@@ -1337,7 +1337,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
1337 1337
1338/* 1338/*
1339 * Convenient frontend to tree walker. 1339 * Convenient frontend to tree walker.
1340 * 1340 *
1341 * func is called on each route. 1341 * func is called on each route.
1342 * It may return -1 -> delete this route. 1342 * It may return -1 -> delete this route.
1343 * 0 -> continue walking 1343 * 0 -> continue walking