ip6_fib.c (1da177e4c3f41524e886b7f1b8a0c1fc7321cac2) ip6_fib.c (0d51aa80a9b1db43920c0770c3bb842dd823c005)
1/*
2 * Linux INET6 implementation
3 * Forwarding Information Database
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $

--- 380 unchanged lines hidden (view full) ---

389 return ln;
390}
391
392/*
393 * Insert routing information in a node.
394 */
395
396static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
1/*
2 * Linux INET6 implementation
3 * Forwarding Information Database
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $

--- 380 unchanged lines hidden (view full) ---

389 return ln;
390}
391
392/*
393 * Insert routing information in a node.
394 */
395
396static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
397 struct nlmsghdr *nlh)
397 struct nlmsghdr *nlh, struct netlink_skb_parms *req)
398{
399 struct rt6_info *iter = NULL;
400 struct rt6_info **ins;
401
402 ins = &fn->leaf;
403
404 if (fn->fn_flags&RTN_TL_ROOT &&
405 fn->leaf == &ip6_null_entry &&

--- 38 unchanged lines hidden (view full) ---

444 * insert node
445 */
446
447out:
448 rt->u.next = iter;
449 *ins = rt;
450 rt->rt6i_node = fn;
451 atomic_inc(&rt->rt6i_ref);
398{
399 struct rt6_info *iter = NULL;
400 struct rt6_info **ins;
401
402 ins = &fn->leaf;
403
404 if (fn->fn_flags&RTN_TL_ROOT &&
405 fn->leaf == &ip6_null_entry &&

--- 38 unchanged lines hidden (view full) ---

444 * insert node
445 */
446
447out:
448 rt->u.next = iter;
449 *ins = rt;
450 rt->rt6i_node = fn;
451 atomic_inc(&rt->rt6i_ref);
452 inet6_rt_notify(RTM_NEWROUTE, rt, nlh);
452 inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req);
453 rt6_stats.fib_rt_entries++;
454
455 if ((fn->fn_flags & RTN_RTINFO) == 0) {
456 rt6_stats.fib_route_nodes++;
457 fn->fn_flags |= RTN_RTINFO;
458 }
459
460 return 0;

--- 13 unchanged lines hidden (view full) ---

474}
475
476/*
477 * Add routing information to the routing tree.
478 * <destination addr>/<source addr>
479 * with source addr info in sub-trees
480 */
481
453 rt6_stats.fib_rt_entries++;
454
455 if ((fn->fn_flags & RTN_RTINFO) == 0) {
456 rt6_stats.fib_route_nodes++;
457 fn->fn_flags |= RTN_RTINFO;
458 }
459
460 return 0;

--- 13 unchanged lines hidden (view full) ---

474}
475
476/*
477 * Add routing information to the routing tree.
478 * <destination addr>/<source addr>
479 * with source addr info in sub-trees
480 */
481
482int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
482int fib6_add(struct fib6_node *root, struct rt6_info *rt,
483 struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
483{
484 struct fib6_node *fn;
485 int err = -ENOMEM;
486
487 fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
488 rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst));
489
490 if (fn == NULL)

--- 56 unchanged lines hidden (view full) ---

547 if (sn == NULL)
548 goto st_failure;
549 }
550
551 fn = sn;
552 }
553#endif
554
484{
485 struct fib6_node *fn;
486 int err = -ENOMEM;
487
488 fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
489 rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst));
490
491 if (fn == NULL)

--- 56 unchanged lines hidden (view full) ---

548 if (sn == NULL)
549 goto st_failure;
550 }
551
552 fn = sn;
553 }
554#endif
555
555 err = fib6_add_rt2node(fn, rt, nlh);
556 err = fib6_add_rt2node(fn, rt, nlh, req);
556
557 if (err == 0) {
558 fib6_start_gc(rt);
559 if (!(rt->rt6i_flags&RTF_CACHE))
560 fib6_prune_clones(fn, rt);
561 }
562
563out:

--- 290 unchanged lines hidden (view full) ---

854
855 rt6_release(pn->leaf);
856 pn->leaf = NULL;
857 fn = pn;
858 }
859}
860
861static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
557
558 if (err == 0) {
559 fib6_start_gc(rt);
560 if (!(rt->rt6i_flags&RTF_CACHE))
561 fib6_prune_clones(fn, rt);
562 }
563
564out:

--- 290 unchanged lines hidden (view full) ---

855
856 rt6_release(pn->leaf);
857 pn->leaf = NULL;
858 fn = pn;
859 }
860}
861
862static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
862 struct nlmsghdr *nlh, void *_rtattr)
863 struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
863{
864 struct fib6_walker_t *w;
865 struct rt6_info *rt = *rtp;
866
867 RT6_TRACE("fib6_del_route\n");
868
869 /* Unlink it */
870 *rtp = rt->u.next;

--- 39 unchanged lines hidden (view full) ---

910 rt6_release(rt);
911 }
912 fn = fn->parent;
913 }
914 /* No more references are possible at this point. */
915 if (atomic_read(&rt->rt6i_ref) != 1) BUG();
916 }
917
864{
865 struct fib6_walker_t *w;
866 struct rt6_info *rt = *rtp;
867
868 RT6_TRACE("fib6_del_route\n");
869
870 /* Unlink it */
871 *rtp = rt->u.next;

--- 39 unchanged lines hidden (view full) ---

911 rt6_release(rt);
912 }
913 fn = fn->parent;
914 }
915 /* No more references are possible at this point. */
916 if (atomic_read(&rt->rt6i_ref) != 1) BUG();
917 }
918
918 inet6_rt_notify(RTM_DELROUTE, rt, nlh);
919 inet6_rt_notify(RTM_DELROUTE, rt, nlh, req);
919 rt6_release(rt);
920}
921
920 rt6_release(rt);
921}
922
922int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
923int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
923{
924 struct fib6_node *fn = rt->rt6i_node;
925 struct rt6_info **rtp;
926
927#if RT6_DEBUG >= 2
928 if (rt->u.dst.obsolete>0) {
929 BUG_TRAP(fn==NULL);
930 return -ENOENT;

--- 8 unchanged lines hidden (view full) ---

939 fib6_prune_clones(fn, rt);
940
941 /*
942 * Walk the leaf entries looking for ourself
943 */
944
945 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
946 if (*rtp == rt) {
924{
925 struct fib6_node *fn = rt->rt6i_node;
926 struct rt6_info **rtp;
927
928#if RT6_DEBUG >= 2
929 if (rt->u.dst.obsolete>0) {
930 BUG_TRAP(fn==NULL);
931 return -ENOENT;

--- 8 unchanged lines hidden (view full) ---

940 fib6_prune_clones(fn, rt);
941
942 /*
943 * Walk the leaf entries looking for ourself
944 */
945
946 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
947 if (*rtp == rt) {
947 fib6_del_route(fn, rtp, nlh, _rtattr);
948 fib6_del_route(fn, rtp, nlh, _rtattr, req);
948 return 0;
949 }
950 }
951 return -ENOENT;
952}
953
954/*
955 * Tree traversal function.

--- 112 unchanged lines hidden (view full) ---

1068 int res;
1069 struct rt6_info *rt;
1070 struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w;
1071
1072 for (rt = w->leaf; rt; rt = rt->u.next) {
1073 res = c->func(rt, c->arg);
1074 if (res < 0) {
1075 w->leaf = rt;
949 return 0;
950 }
951 }
952 return -ENOENT;
953}
954
955/*
956 * Tree traversal function.

--- 112 unchanged lines hidden (view full) ---

1069 int res;
1070 struct rt6_info *rt;
1071 struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w;
1072
1073 for (rt = w->leaf; rt; rt = rt->u.next) {
1074 res = c->func(rt, c->arg);
1075 if (res < 0) {
1076 w->leaf = rt;
1076 res = fib6_del(rt, NULL, NULL);
1077 res = fib6_del(rt, NULL, NULL, NULL);
1077 if (res) {
1078#if RT6_DEBUG >= 2
1079 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
1080#endif
1081 continue;
1082 }
1083 return 0;
1084 }

--- 141 unchanged lines hidden ---
1078 if (res) {
1079#if RT6_DEBUG >= 2
1080 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
1081#endif
1082 continue;
1083 }
1084 return 0;
1085 }

--- 141 unchanged lines hidden ---