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 --- |