diff options
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r-- | net/ipv6/ip6_fib.c | 66 |
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 | ||
98 | static struct fib6_walker_t fib6_walker_list = { | 98 | static 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 | ||
504 | insert_above: | 504 | insert_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 | ||
665 | out: | 665 | out: |
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 |