Deleted Added
full compact
route.c (122334) route.c (122921)
1/*
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
1/*
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
34 * $FreeBSD: head/sys/net/route.c 122334 2003-11-08 23:36:32Z sam $
34 * $FreeBSD: head/sys/net/route.c 122921 2003-11-20 19:47:31Z andre $
35 */
36
37#include "opt_inet.h"
38#include "opt_mrouting.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/malloc.h>

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

134 if ((rn = rnh->rnh_matchaddr(dst, rnh)) &&
135 (rn->rn_flags & RNF_ROOT) == 0) {
136 /*
137 * If we find it and it's not the root node, then
138 * get a refernce on the rtentry associated.
139 */
140 newrt = rt = (struct rtentry *)rn;
141 nflags = rt->rt_flags & ~ignflags;
35 */
36
37#include "opt_inet.h"
38#include "opt_mrouting.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/malloc.h>

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

134 if ((rn = rnh->rnh_matchaddr(dst, rnh)) &&
135 (rn->rn_flags & RNF_ROOT) == 0) {
136 /*
137 * If we find it and it's not the root node, then
138 * get a refernce on the rtentry associated.
139 */
140 newrt = rt = (struct rtentry *)rn;
141 nflags = rt->rt_flags & ~ignflags;
142 if (report && (nflags & (RTF_CLONING | RTF_PRCLONING))) {
142 if (report && (nflags & RTF_CLONING)) {
143 /*
144 * We are apparently adding (report = 0 in delete).
145 * If it requires that it be cloned, do so.
146 * (This implies it wasn't a HOST route.)
147 */
148 err = rtrequest(RTM_RESOLVE, dst, SA(0),
149 SA(0), 0, &newrt);
150 if (err) {

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

579 ("lookup mismatch, rt %p rn %p", rt, rn));
580
581 rt->rt_flags &= ~RTF_UP;
582
583 /*
584 * Now search what's left of the subtree for any cloned
585 * routes which might have been formed from this node.
586 */
143 /*
144 * We are apparently adding (report = 0 in delete).
145 * If it requires that it be cloned, do so.
146 * (This implies it wasn't a HOST route.)
147 */
148 err = rtrequest(RTM_RESOLVE, dst, SA(0),
149 SA(0), 0, &newrt);
150 if (err) {

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

579 ("lookup mismatch, rt %p rn %p", rt, rn));
580
581 rt->rt_flags &= ~RTF_UP;
582
583 /*
584 * Now search what's left of the subtree for any cloned
585 * routes which might have been formed from this node.
586 */
587 if ((rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) && rt_mask(rt))
587 if ((rt->rt_flags & RTF_CLONING) && rt_mask(rt))
588 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
589 rt_fixdelete, rt);
590
591 /*
592 * Remove any external references we may have.
593 * This might result in another rtentry being freed if
594 * we held its last reference.
595 */

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

642 return (EAFNOSUPPORT);
643 RADIX_NODE_HEAD_LOCK(rnh);
644 /*
645 * If we are adding a host route then we don't want to put
646 * a netmask in the tree, nor do we want to clone it.
647 */
648 if (flags & RTF_HOST) {
649 netmask = 0;
588 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
589 rt_fixdelete, rt);
590
591 /*
592 * Remove any external references we may have.
593 * This might result in another rtentry being freed if
594 * we held its last reference.
595 */

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

642 return (EAFNOSUPPORT);
643 RADIX_NODE_HEAD_LOCK(rnh);
644 /*
645 * If we are adding a host route then we don't want to put
646 * a netmask in the tree, nor do we want to clone it.
647 */
648 if (flags & RTF_HOST) {
649 netmask = 0;
650 flags &= ~(RTF_CLONING | RTF_PRCLONING);
650 flags &= ~RTF_CLONING;
651 }
652 switch (req) {
653 case RTM_DELETE:
654 /*
655 * Remove the item from the tree and return it.
656 * Complain if it is not there and do no more processing.
657 */
658 rn = rnh->rnh_deladdr(dst, netmask, rnh);

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

664 RT_LOCK(rt);
665 RT_ADDREF(rt);
666 rt->rt_flags &= ~RTF_UP;
667
668 /*
669 * Now search what's left of the subtree for any cloned
670 * routes which might have been formed from this node.
671 */
651 }
652 switch (req) {
653 case RTM_DELETE:
654 /*
655 * Remove the item from the tree and return it.
656 * Complain if it is not there and do no more processing.
657 */
658 rn = rnh->rnh_deladdr(dst, netmask, rnh);

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

664 RT_LOCK(rt);
665 RT_ADDREF(rt);
666 rt->rt_flags &= ~RTF_UP;
667
668 /*
669 * Now search what's left of the subtree for any cloned
670 * routes which might have been formed from this node.
671 */
672 if ((rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) &&
672 if ((rt->rt_flags & RTF_CLONING) &&
673 rt_mask(rt)) {
674 rnh->rnh_walktree_from(rnh, dst, rt_mask(rt),
675 rt_fixdelete, rt);
676 }
677
678 /*
679 * Remove any external references we may have.
680 * This might result in another rtentry being freed if

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

711 break;
712
713 case RTM_RESOLVE:
714 if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
715 senderr(EINVAL);
716 ifa = rt->rt_ifa;
717 /* XXX locking? */
718 flags = rt->rt_flags &
673 rt_mask(rt)) {
674 rnh->rnh_walktree_from(rnh, dst, rt_mask(rt),
675 rt_fixdelete, rt);
676 }
677
678 /*
679 * Remove any external references we may have.
680 * This might result in another rtentry being freed if

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

711 break;
712
713 case RTM_RESOLVE:
714 if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
715 senderr(EINVAL);
716 ifa = rt->rt_ifa;
717 /* XXX locking? */
718 flags = rt->rt_flags &
719 ~(RTF_CLONING | RTF_PRCLONING | RTF_STATIC);
719 ~(RTF_CLONING | RTF_STATIC);
720 flags |= RTF_WASCLONED;
721 gateway = rt->rt_gateway;
722 if ((netmask = rt->rt_genmask) == 0)
723 flags |= RTF_HOST;
724 goto makeroute;
725
726 case RTM_ADD:
727 if ((flags & RTF_GATEWAY) && !gateway)

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

772
773 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
774 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
775 if (rn == 0) {
776 struct rtentry *rt2;
777 /*
778 * Uh-oh, we already have one of these in the tree.
779 * We do a special hack: if the route that's already
720 flags |= RTF_WASCLONED;
721 gateway = rt->rt_gateway;
722 if ((netmask = rt->rt_genmask) == 0)
723 flags |= RTF_HOST;
724 goto makeroute;
725
726 case RTM_ADD:
727 if ((flags & RTF_GATEWAY) && !gateway)

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

772
773 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
774 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
775 if (rn == 0) {
776 struct rtentry *rt2;
777 /*
778 * Uh-oh, we already have one of these in the tree.
779 * We do a special hack: if the route that's already
780 * there was generated by the protocol-cloning
781 * mechanism, then we just blow it away and retry
782 * the insertion of the new one.
780 * there was generated by the cloning mechanism
781 * then we just blow it away and retry the insertion
782 * of the new one.
783 */
783 */
784 rt2 = rtalloc1(dst, 0, RTF_PRCLONING);
784 rt2 = rtalloc1(dst, 0, 0);
785 if (rt2 && rt2->rt_parent) {
786 rtexpunge(rt2);
787 RT_UNLOCK(rt2);
788 rn = rnh->rnh_addaddr(ndst, netmask,
789 rnh, rt->rt_nodes);
790 } else if (rt2) {
791 /* undo the extra ref we got */
792 RTFREE_LOCKED(rt2);

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

815 * so clone the rest, and note that we
816 * are a clone (and increment the parent's references)
817 */
818 if (req == RTM_RESOLVE) {
819 KASSERT(ret_nrt && *ret_nrt,
820 ("no route to clone from"));
821 rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
822 rt->rt_rmx.rmx_pksent = 0; /* reset packet counter */
785 if (rt2 && rt2->rt_parent) {
786 rtexpunge(rt2);
787 RT_UNLOCK(rt2);
788 rn = rnh->rnh_addaddr(ndst, netmask,
789 rnh, rt->rt_nodes);
790 } else if (rt2) {
791 /* undo the extra ref we got */
792 RTFREE_LOCKED(rt2);

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

815 * so clone the rest, and note that we
816 * are a clone (and increment the parent's references)
817 */
818 if (req == RTM_RESOLVE) {
819 KASSERT(ret_nrt && *ret_nrt,
820 ("no route to clone from"));
821 rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
822 rt->rt_rmx.rmx_pksent = 0; /* reset packet counter */
823 if ((*ret_nrt)->rt_flags & (RTF_CLONING | RTF_PRCLONING)) {
823 if ((*ret_nrt)->rt_flags & RTF_CLONING) {
824 /*
825 * NB: We do not bump the refcnt on the parent
826 * entry under the assumption that it will
827 * remain so long as we do. This is
828 * important when deleting the parent route
829 * as this operation requires traversing
830 * the tree to delete all clones and futzing
831 * with refcnts requires us to double-lock

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

891 */
892static int
893rt_fixdelete(struct radix_node *rn, void *vp)
894{
895 struct rtentry *rt = (struct rtentry *)rn;
896 struct rtentry *rt0 = vp;
897
898 if (rt->rt_parent == rt0 &&
824 /*
825 * NB: We do not bump the refcnt on the parent
826 * entry under the assumption that it will
827 * remain so long as we do. This is
828 * important when deleting the parent route
829 * as this operation requires traversing
830 * the tree to delete all clones and futzing
831 * with refcnts requires us to double-lock

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

891 */
892static int
893rt_fixdelete(struct radix_node *rn, void *vp)
894{
895 struct rtentry *rt = (struct rtentry *)rn;
896 struct rtentry *rt0 = vp;
897
898 if (rt->rt_parent == rt0 &&
899 !(rt->rt_flags & (RTF_PINNED | RTF_CLONING | RTF_PRCLONING))) {
899 !(rt->rt_flags & (RTF_PINNED | RTF_CLONING))) {
900 return rtrequest(RTM_DELETE, rt_key(rt),
901 (struct sockaddr *)0, rt_mask(rt),
902 rt->rt_flags, (struct rtentry **)0);
903 }
904 return 0;
905}
906
907/*

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

932 int i, len, mlen;
933
934#ifdef DEBUG
935 if (rtfcdebug)
936 printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0);
937#endif
938
939 if (!rt->rt_parent ||
900 return rtrequest(RTM_DELETE, rt_key(rt),
901 (struct sockaddr *)0, rt_mask(rt),
902 rt->rt_flags, (struct rtentry **)0);
903 }
904 return 0;
905}
906
907/*

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

932 int i, len, mlen;
933
934#ifdef DEBUG
935 if (rtfcdebug)
936 printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0);
937#endif
938
939 if (!rt->rt_parent ||
940 (rt->rt_flags & (RTF_PINNED | RTF_CLONING | RTF_PRCLONING))) {
940 (rt->rt_flags & (RTF_PINNED | RTF_CLONING))) {
941#ifdef DEBUG
942 if(rtfcdebug) printf("no parent, pinned or cloning\n");
943#endif
944 return 0;
945 }
946
947 if (rt->rt_parent == rt0) {
948#ifdef DEBUG

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

1082 * Cloning loop avoidance:
1083 * In the presence of protocol-cloning and bad configuration,
1084 * it is possible to get stuck in bottomless mutual recursion
1085 * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing
1086 * protocol-cloning to operate for gateways (which is probably the
1087 * correct choice anyway), and avoid the resulting reference loops
1088 * by disallowing any route to run through itself as a gateway.
1089 * This is obviously mandatory when we get rt->rt_output().
941#ifdef DEBUG
942 if(rtfcdebug) printf("no parent, pinned or cloning\n");
943#endif
944 return 0;
945 }
946
947 if (rt->rt_parent == rt0) {
948#ifdef DEBUG

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

1082 * Cloning loop avoidance:
1083 * In the presence of protocol-cloning and bad configuration,
1084 * it is possible to get stuck in bottomless mutual recursion
1085 * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing
1086 * protocol-cloning to operate for gateways (which is probably the
1087 * correct choice anyway), and avoid the resulting reference loops
1088 * by disallowing any route to run through itself as a gateway.
1089 * This is obviously mandatory when we get rt->rt_output().
1090 * XXX: After removal of PRCLONING this is probably not needed anymore.
1090 */
1091 if (rt->rt_flags & RTF_GATEWAY) {
1092 /* XXX LOR here */
1091 */
1092 if (rt->rt_flags & RTF_GATEWAY) {
1093 /* XXX LOR here */
1093 rt->rt_gwroute = rtalloc1(gate, 1, RTF_PRCLONING);
1094 rt->rt_gwroute = rtalloc1(gate, 1, 0);
1094 if (rt->rt_gwroute == rt) {
1095 RTFREE_LOCKED(rt->rt_gwroute);
1096 rt->rt_gwroute = 0;
1097 return EDQUOT; /* failure */
1098 }
1099 if (rt->rt_gwroute != NULL)
1100 RT_UNLOCK(rt->rt_gwroute);
1101 }

--- 217 unchanged lines hidden ---
1095 if (rt->rt_gwroute == rt) {
1096 RTFREE_LOCKED(rt->rt_gwroute);
1097 rt->rt_gwroute = 0;
1098 return EDQUOT; /* failure */
1099 }
1100 if (rt->rt_gwroute != NULL)
1101 RT_UNLOCK(rt->rt_gwroute);
1102 }

--- 217 unchanged lines hidden ---