route.c (85052) | route.c (85074) |
---|---|
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 (Berkeley) 1/9/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 (Berkeley) 1/9/95 |
34 * $FreeBSD: head/sys/net/route.c 85052 2001-10-17 11:10:55Z ru $ | 34 * $FreeBSD: head/sys/net/route.c 85074 2001-10-17 18:07:05Z ru $ |
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> --- 117 unchanged lines hidden (view full) --- 160 if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) { 161 /* 162 * If the new route specifies it be 163 * externally resolved, then go do that. 164 */ 165 msgtype = RTM_RESOLVE; 166 goto miss; 167 } | 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> --- 117 unchanged lines hidden (view full) --- 160 if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) { 161 /* 162 * If the new route specifies it be 163 * externally resolved, then go do that. 164 */ 165 msgtype = RTM_RESOLVE; 166 goto miss; 167 } |
168 /* Inform listeners of the new route. */ 169 bzero(&info, sizeof(info)); 170 info.rti_info[RTAX_DST] = rt_key(rt); 171 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 172 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 173 if (rt->rt_ifp != NULL) { 174 info.rti_info[RTAX_IFP] = 175 TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr; 176 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 177 } 178 rt_missmsg(RTM_ADD, &info, rt->rt_flags, 0); |
|
168 } else 169 rt->rt_refcnt++; 170 } else { 171 /* 172 * Either we hit the root or couldn't find any match, 173 * Which basically means 174 * "caint get there frm here" 175 */ --- 107 unchanged lines hidden (view full) --- 283 * 284 */ 285void 286rtredirect(dst, gateway, netmask, flags, src, rtp) 287 struct sockaddr *dst, *gateway, *netmask, *src; 288 int flags; 289 struct rtentry **rtp; 290{ | 179 } else 180 rt->rt_refcnt++; 181 } else { 182 /* 183 * Either we hit the root or couldn't find any match, 184 * Which basically means 185 * "caint get there frm here" 186 */ --- 107 unchanged lines hidden (view full) --- 294 * 295 */ 296void 297rtredirect(dst, gateway, netmask, flags, src, rtp) 298 struct sockaddr *dst, *gateway, *netmask, *src; 299 int flags; 300 struct rtentry **rtp; 301{ |
291 register struct rtentry *rt; | 302 struct rtentry *rt; |
292 int error = 0; 293 short *stat = 0; 294 struct rt_addrinfo info; 295 struct ifaddr *ifa; 296 297 /* verify the gateway is directly reachable */ 298 if ((ifa = ifa_ifwithnet(gateway)) == 0) { 299 error = ENETUNREACH; --- 28 unchanged lines hidden (view full) --- 328 */ 329 if (rt->rt_flags & RTF_GATEWAY) { 330 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) { 331 /* 332 * Changing from route to net => route to host. 333 * Create new route, rather than smashing route to net. 334 */ 335 create: | 303 int error = 0; 304 short *stat = 0; 305 struct rt_addrinfo info; 306 struct ifaddr *ifa; 307 308 /* verify the gateway is directly reachable */ 309 if ((ifa = ifa_ifwithnet(gateway)) == 0) { 310 error = ENETUNREACH; --- 28 unchanged lines hidden (view full) --- 339 */ 340 if (rt->rt_flags & RTF_GATEWAY) { 341 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) { 342 /* 343 * Changing from route to net => route to host. 344 * Create new route, rather than smashing route to net. 345 */ 346 create: |
347 if (rt) 348 rtfree(rt); |
|
336 flags |= RTF_GATEWAY | RTF_DYNAMIC; | 349 flags |= RTF_GATEWAY | RTF_DYNAMIC; |
337 error = rtrequest((int)RTM_ADD, dst, gateway, 338 netmask, flags, 339 (struct rtentry **)0); | 350 bzero((caddr_t)&info, sizeof(info)); 351 info.rti_info[RTAX_DST] = dst; 352 info.rti_info[RTAX_GATEWAY] = gateway; 353 info.rti_info[RTAX_NETMASK] = netmask; 354 info.rti_ifa = ifa; 355 info.rti_flags = flags; 356 rt = NULL; 357 error = rtrequest1(RTM_ADD, &info, &rt); 358 if (rt != NULL) 359 flags = rt->rt_flags; |
340 stat = &rtstat.rts_dynamic; 341 } else { 342 /* 343 * Smash the current notion of the gateway to 344 * this destination. Should check about netmask!!! 345 */ 346 rt->rt_flags |= RTF_MODIFIED; 347 flags |= RTF_MODIFIED; --- 83 unchanged lines hidden (view full) --- 431 struct ifaddr *oifa = ifa; 432 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 433 if (ifa == 0) 434 ifa = oifa; 435 } 436 return (ifa); 437} 438 | 360 stat = &rtstat.rts_dynamic; 361 } else { 362 /* 363 * Smash the current notion of the gateway to 364 * this destination. Should check about netmask!!! 365 */ 366 rt->rt_flags |= RTF_MODIFIED; 367 flags |= RTF_MODIFIED; --- 83 unchanged lines hidden (view full) --- 451 struct ifaddr *oifa = ifa; 452 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 453 if (ifa == 0) 454 ifa = oifa; 455 } 456 return (ifa); 457} 458 |
439#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 440 | |
441static int rt_fixdelete __P((struct radix_node *, void *)); 442static int rt_fixchange __P((struct radix_node *, void *)); 443 444struct rtfc_arg { 445 struct rtentry *rt0; 446 struct radix_node_head *rnh; 447}; 448 449/* 450 * Do appropriate manipulations of a routing tree given 451 * all the bits of info needed 452 */ 453int 454rtrequest(req, dst, gateway, netmask, flags, ret_nrt) 455 int req, flags; 456 struct sockaddr *dst, *gateway, *netmask; 457 struct rtentry **ret_nrt; 458{ | 459static int rt_fixdelete __P((struct radix_node *, void *)); 460static int rt_fixchange __P((struct radix_node *, void *)); 461 462struct rtfc_arg { 463 struct rtentry *rt0; 464 struct radix_node_head *rnh; 465}; 466 467/* 468 * Do appropriate manipulations of a routing tree given 469 * all the bits of info needed 470 */ 471int 472rtrequest(req, dst, gateway, netmask, flags, ret_nrt) 473 int req, flags; 474 struct sockaddr *dst, *gateway, *netmask; 475 struct rtentry **ret_nrt; 476{ |
477 struct rt_addrinfo info; 478 479 bzero((caddr_t)&info, sizeof(info)); 480 info.rti_flags = flags; 481 info.rti_info[RTAX_DST] = dst; 482 info.rti_info[RTAX_GATEWAY] = gateway; 483 info.rti_info[RTAX_NETMASK] = netmask; 484 return rtrequest1(req, &info, ret_nrt); 485} 486 487/* 488 * These (questionable) definitions of apparent local variables apply 489 * to the next two functions. XXXXXX!!! 490 */ 491#define dst info->rti_info[RTAX_DST] 492#define gateway info->rti_info[RTAX_GATEWAY] 493#define netmask info->rti_info[RTAX_NETMASK] 494#define ifaaddr info->rti_info[RTAX_IFA] 495#define ifpaddr info->rti_info[RTAX_IFP] 496#define flags info->rti_flags 497 498int 499rt_getifa(info) 500 struct rt_addrinfo *info; 501{ 502 struct ifaddr *ifa; 503 int error = 0; 504 505 /* 506 * ifp may be specified by sockaddr_dl 507 * when protocol address is ambiguous. 508 */ 509 if (info->rti_ifp == NULL && ifpaddr != NULL && 510 ifpaddr->sa_family == AF_LINK && 511 (ifa = ifa_ifwithnet(ifpaddr)) != NULL) 512 info->rti_ifp = ifa->ifa_ifp; 513 if (info->rti_ifa == NULL && ifaaddr != NULL) 514 info->rti_ifa = ifa_ifwithaddr(ifaaddr); 515 if (info->rti_ifa == NULL) { 516 struct sockaddr *sa; 517 518 sa = ifaaddr != NULL ? ifaaddr : 519 (gateway != NULL ? gateway : dst); 520 if (sa != NULL && info->rti_ifp != NULL) 521 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp); 522 else if (dst != NULL && gateway != NULL) 523 info->rti_ifa = ifa_ifwithroute(flags, dst, gateway); 524 else if (sa != NULL) 525 info->rti_ifa = ifa_ifwithroute(flags, sa, sa); 526 } 527 if ((ifa = info->rti_ifa) != NULL) { 528 if (info->rti_ifp == NULL) 529 info->rti_ifp = ifa->ifa_ifp; 530 } else 531 error = ENETUNREACH; 532 return (error); 533} 534 535int 536rtrequest1(req, info, ret_nrt) 537 int req; 538 struct rt_addrinfo *info; 539 struct rtentry **ret_nrt; 540{ |
|
459 int s = splnet(); int error = 0; 460 register struct rtentry *rt; 461 register struct radix_node *rn; 462 register struct radix_node_head *rnh; 463 struct ifaddr *ifa; 464 struct sockaddr *ndst; 465#define senderr(x) { error = x ; goto bad; } 466 467 /* 468 * Find the correct routing tree to use for this Address Family 469 */ 470 if ((rnh = rt_tables[dst->sa_family]) == 0) | 541 int s = splnet(); int error = 0; 542 register struct rtentry *rt; 543 register struct radix_node *rn; 544 register struct radix_node_head *rnh; 545 struct ifaddr *ifa; 546 struct sockaddr *ndst; 547#define senderr(x) { error = x ; goto bad; } 548 549 /* 550 * Find the correct routing tree to use for this Address Family 551 */ 552 if ((rnh = rt_tables[dst->sa_family]) == 0) |
471 senderr(ESRCH); | 553 senderr(EAFNOSUPPORT); |
472 /* 473 * If we are adding a host route then we don't want to put 474 * a netmask in the tree, nor do we want to clone it. 475 */ 476 if (flags & RTF_HOST) { 477 netmask = 0; 478 flags &= ~(RTF_CLONING | RTF_PRCLONING); 479 } --- 38 unchanged lines hidden (view full) --- 518 * I'm not sure how RTF_UP helps matters. (JRE) 519 */ 520 rt->rt_flags &= ~RTF_UP; 521 522 /* 523 * give the protocol a chance to keep things in sync. 524 */ 525 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) | 554 /* 555 * If we are adding a host route then we don't want to put 556 * a netmask in the tree, nor do we want to clone it. 557 */ 558 if (flags & RTF_HOST) { 559 netmask = 0; 560 flags &= ~(RTF_CLONING | RTF_PRCLONING); 561 } --- 38 unchanged lines hidden (view full) --- 600 * I'm not sure how RTF_UP helps matters. (JRE) 601 */ 602 rt->rt_flags &= ~RTF_UP; 603 604 /* 605 * give the protocol a chance to keep things in sync. 606 */ 607 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) |
526 ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); | 608 ifa->ifa_rtrequest(RTM_DELETE, rt, info); |
527 528 /* 529 * one more rtentry floating around that is not 530 * linked to the routing table. 531 */ 532 rttrash++; 533 534 /* --- 20 unchanged lines hidden (view full) --- 555 if ((netmask = rt->rt_genmask) == 0) 556 flags |= RTF_HOST; 557 goto makeroute; 558 559 case RTM_ADD: 560 if ((flags & RTF_GATEWAY) && !gateway) 561 panic("rtrequest: GATEWAY but no gateway"); 562 | 609 610 /* 611 * one more rtentry floating around that is not 612 * linked to the routing table. 613 */ 614 rttrash++; 615 616 /* --- 20 unchanged lines hidden (view full) --- 637 if ((netmask = rt->rt_genmask) == 0) 638 flags |= RTF_HOST; 639 goto makeroute; 640 641 case RTM_ADD: 642 if ((flags & RTF_GATEWAY) && !gateway) 643 panic("rtrequest: GATEWAY but no gateway"); 644 |
563 if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0) 564 senderr(ENETUNREACH); | 645 if (info->rti_ifa == NULL && (error = rt_getifa(info))) 646 senderr(error); 647 ifa = info->rti_ifa; |
565 566 makeroute: 567 R_Malloc(rt, struct rtentry *, sizeof(*rt)); 568 if (rt == 0) 569 senderr(ENOBUFS); 570 Bzero(rt, sizeof(*rt)); 571 rt->rt_flags = RTF_UP | flags; 572 /* --- 85 unchanged lines hidden (view full) --- 658 } 659 } 660 661 /* 662 * if this protocol has something to add to this then 663 * allow it to do that as well. 664 */ 665 if (ifa->ifa_rtrequest) | 648 649 makeroute: 650 R_Malloc(rt, struct rtentry *, sizeof(*rt)); 651 if (rt == 0) 652 senderr(ENOBUFS); 653 Bzero(rt, sizeof(*rt)); 654 rt->rt_flags = RTF_UP | flags; 655 /* --- 85 unchanged lines hidden (view full) --- 741 } 742 } 743 744 /* 745 * if this protocol has something to add to this then 746 * allow it to do that as well. 747 */ 748 if (ifa->ifa_rtrequest) |
666 ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); | 749 ifa->ifa_rtrequest(req, rt, info); |
667 668 /* 669 * We repeat the same procedure from rt_setgate() here because 670 * it doesn't fire when we call it there because the node 671 * hasn't been added to the tree yet. 672 */ 673 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) { 674 struct rtfc_arg arg; --- 7 unchanged lines hidden (view full) --- 682 * actually return a resultant rtentry and 683 * give the caller a single reference. 684 */ 685 if (ret_nrt) { 686 *ret_nrt = rt; 687 rt->rt_refcnt++; 688 } 689 break; | 750 751 /* 752 * We repeat the same procedure from rt_setgate() here because 753 * it doesn't fire when we call it there because the node 754 * hasn't been added to the tree yet. 755 */ 756 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) { 757 struct rtfc_arg arg; --- 7 unchanged lines hidden (view full) --- 765 * actually return a resultant rtentry and 766 * give the caller a single reference. 767 */ 768 if (ret_nrt) { 769 *ret_nrt = rt; 770 rt->rt_refcnt++; 771 } 772 break; |
773 default: 774 error = EOPNOTSUPP; |
|
690 } 691bad: 692 splx(s); 693 return (error); | 775 } 776bad: 777 splx(s); 778 return (error); |
779#undef dst 780#undef gateway 781#undef netmask 782#undef ifaaddr 783#undef ifpaddr 784#undef flags |
|
694} 695 696/* 697 * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' 698 * (i.e., the routes related to it by the operation of cloning). This 699 * routine is iterated over all potential former-child-routes by way of 700 * rnh->rnh_walktree_from() above, and those that actually are children of 701 * the late parent (passed in as VP here) are themselves deleted. --- 112 unchanged lines hidden (view full) --- 814 */ 815#ifdef DEBUG 816 if(rtfcdebug) printf("deleting\n"); 817#endif 818 return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, 819 rt_mask(rt), rt->rt_flags, (struct rtentry **)0); 820} 821 | 785} 786 787/* 788 * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' 789 * (i.e., the routes related to it by the operation of cloning). This 790 * routine is iterated over all potential former-child-routes by way of 791 * rnh->rnh_walktree_from() above, and those that actually are children of 792 * the late parent (passed in as VP here) are themselves deleted. --- 112 unchanged lines hidden (view full) --- 905 */ 906#ifdef DEBUG 907 if(rtfcdebug) printf("deleting\n"); 908#endif 909 return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, 910 rt_mask(rt), rt->rt_flags, (struct rtentry **)0); 911} 912 |
913#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 914 |
|
822int 823rt_setgate(rt0, dst, gate) 824 struct rtentry *rt0; 825 struct sockaddr *dst, *gate; 826{ 827 caddr_t new, old; 828 int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len); 829 register struct rtentry *rt = rt0; --- 51 unchanged lines hidden (view full) --- 881 Bcopy(dst, new, dlen); 882 Free(old); 883 } 884 885 /* 886 * If there is already a gwroute, it's now almost definitly wrong 887 * so drop it. 888 */ | 915int 916rt_setgate(rt0, dst, gate) 917 struct rtentry *rt0; 918 struct sockaddr *dst, *gate; 919{ 920 caddr_t new, old; 921 int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len); 922 register struct rtentry *rt = rt0; --- 51 unchanged lines hidden (view full) --- 974 Bcopy(dst, new, dlen); 975 Free(old); 976 } 977 978 /* 979 * If there is already a gwroute, it's now almost definitly wrong 980 * so drop it. 981 */ |
889 if (rt->rt_gwroute) { 890 rt = rt->rt_gwroute; RTFREE(rt); 891 rt = rt0; rt->rt_gwroute = 0; | 982 if (rt->rt_gwroute != NULL) { 983 RTFREE(rt->rt_gwroute); 984 rt->rt_gwroute = NULL; |
892 } 893 /* 894 * Cloning loop avoidance: 895 * In the presence of protocol-cloning and bad configuration, 896 * it is possible to get stuck in bottomless mutual recursion 897 * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing 898 * protocol-cloning to operate for gateways (which is probably the 899 * correct choice anyway), and avoid the resulting reference loops --- 52 unchanged lines hidden (view full) --- 952int 953rtinit(ifa, cmd, flags) 954 register struct ifaddr *ifa; 955 int cmd, flags; 956{ 957 register struct rtentry *rt; 958 register struct sockaddr *dst; 959 register struct sockaddr *deldst; | 985 } 986 /* 987 * Cloning loop avoidance: 988 * In the presence of protocol-cloning and bad configuration, 989 * it is possible to get stuck in bottomless mutual recursion 990 * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing 991 * protocol-cloning to operate for gateways (which is probably the 992 * correct choice anyway), and avoid the resulting reference loops --- 52 unchanged lines hidden (view full) --- 1045int 1046rtinit(ifa, cmd, flags) 1047 register struct ifaddr *ifa; 1048 int cmd, flags; 1049{ 1050 register struct rtentry *rt; 1051 register struct sockaddr *dst; 1052 register struct sockaddr *deldst; |
1053 struct sockaddr *netmask; |
|
960 struct mbuf *m = 0; 961 struct rtentry *nrt = 0; | 1054 struct mbuf *m = 0; 1055 struct rtentry *nrt = 0; |
1056 struct radix_node_head *rnh; 1057 struct radix_node *rn; |
|
962 int error; | 1058 int error; |
1059 struct rt_addrinfo info; |
|
963 | 1060 |
964 dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr; | 1061 if (flags & RTF_HOST) { 1062 dst = ifa->ifa_dstaddr; 1063 netmask = NULL; 1064 } else { 1065 dst = ifa->ifa_addr; 1066 netmask = ifa->ifa_netmask; 1067 } |
965 /* 966 * If it's a delete, check that if it exists, it's on the correct 967 * interface or we might scrub a route to another ifa which would 968 * be confusing at best and possibly worse. 969 */ 970 if (cmd == RTM_DELETE) { 971 /* 972 * It's a delete, so it should already exist.. 973 * If it's a net, mask off the host bits 974 * (Assuming we have a mask) 975 */ | 1068 /* 1069 * If it's a delete, check that if it exists, it's on the correct 1070 * interface or we might scrub a route to another ifa which would 1071 * be confusing at best and possibly worse. 1072 */ 1073 if (cmd == RTM_DELETE) { 1074 /* 1075 * It's a delete, so it should already exist.. 1076 * If it's a net, mask off the host bits 1077 * (Assuming we have a mask) 1078 */ |
976 if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { | 1079 if (netmask != NULL) { |
977 m = m_get(M_DONTWAIT, MT_SONAME); 978 if (m == NULL) 979 return(ENOBUFS); 980 deldst = mtod(m, struct sockaddr *); | 1080 m = m_get(M_DONTWAIT, MT_SONAME); 1081 if (m == NULL) 1082 return(ENOBUFS); 1083 deldst = mtod(m, struct sockaddr *); |
981 rt_maskedcopy(dst, deldst, ifa->ifa_netmask); | 1084 rt_maskedcopy(dst, deldst, netmask); |
982 dst = deldst; 983 } 984 /* | 1085 dst = deldst; 1086 } 1087 /* |
985 * Get an rtentry that is in the routing tree and 986 * contains the correct info. (if this fails, can't get there). 987 * We set "report" to FALSE so that if it doesn't exist, 988 * it doesn't report an error or clone a route, etc. etc. | 1088 * Look up an rtentry that is in the routing tree and 1089 * contains the correct info. |
989 */ | 1090 */ |
990 rt = rtalloc1(dst, 0, 0UL); 991 if (rt) { 992 /* 993 * Ok so we found the rtentry. it has an extra reference 994 * for us at this stage. we won't need that so 995 * lop that off now. 996 */ 997 rt->rt_refcnt--; 998 if (rt->rt_ifa != ifa) { 999 /* 1000 * If the interface in the rtentry doesn't match 1001 * the interface we are using, then we don't 1002 * want to delete it, so return an error. 1003 * This seems to be the only point of 1004 * this whole RTM_DELETE clause. 1005 */ 1006 if (m) 1007 (void) m_free(m); 1008 return (flags & RTF_HOST ? EHOSTUNREACH 1009 : ENETUNREACH); 1010 } | 1091 if ((rnh = rt_tables[dst->sa_family]) == NULL || 1092 (rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL || 1093 (rn->rn_flags & RNF_ROOT) || 1094 ((struct rtentry *)rn)->rt_ifa != ifa || 1095 !equal(SA(rn->rn_key), dst)) { 1096 if (m) 1097 (void) m_free(m); 1098 return (flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); |
1011 } 1012 /* XXX */ 1013#if 0 1014 else { 1015 /* 1016 * One would think that as we are deleting, and we know 1017 * it doesn't exist, we could just return at this point 1018 * with an "ELSE" clause, but apparently not.. 1019 */ | 1099 } 1100 /* XXX */ 1101#if 0 1102 else { 1103 /* 1104 * One would think that as we are deleting, and we know 1105 * it doesn't exist, we could just return at this point 1106 * with an "ELSE" clause, but apparently not.. 1107 */ |
1020 return (flags & RTF_HOST ? EHOSTUNREACH 1021 : ENETUNREACH); | 1108 return (flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); |
1022 } 1023#endif 1024 } 1025 /* 1026 * Do the actual request 1027 */ | 1109 } 1110#endif 1111 } 1112 /* 1113 * Do the actual request 1114 */ |
1028 error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask, 1029 flags | ifa->ifa_flags, &nrt); 1030 if (m) 1031 (void) m_free(m); 1032 /* 1033 * If we are deleting, and we found an entry, then 1034 * it's been removed from the tree.. now throw it away. 1035 */ 1036 if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) { | 1115 bzero((caddr_t)&info, sizeof(info)); 1116 info.rti_ifa = ifa; 1117 info.rti_flags = flags | ifa->ifa_flags; 1118 info.rti_info[RTAX_DST] = dst; 1119 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; 1120 info.rti_info[RTAX_NETMASK] = netmask; 1121 error = rtrequest1(cmd, &info, &nrt); 1122 if (error == 0 && (rt = nrt) != NULL) { |
1037 /* 1038 * notify any listenning routing agents of the change 1039 */ | 1123 /* 1124 * notify any listenning routing agents of the change 1125 */ |
1040 rt_newaddrmsg(cmd, ifa, error, nrt); 1041 if (rt->rt_refcnt <= 0) { 1042 rt->rt_refcnt++; /* need a 1->0 transition to free */ 1043 rtfree(rt); 1044 } 1045 } 1046 1047 /* 1048 * We are adding, and we have a returned routing entry. 1049 * We need to sanity check the result. 1050 */ 1051 if (cmd == RTM_ADD && error == 0 && (rt = nrt)) { 1052 /* 1053 * We just wanted to add it.. we don't actually need a reference 1054 */ 1055 rt->rt_refcnt--; 1056 /* 1057 * If it came back with an unexpected interface, then it must 1058 * have already existed or something. (XXX) 1059 */ 1060 if (rt->rt_ifa != ifa) { 1061 if (!(rt->rt_ifa->ifa_ifp->if_flags & 1062 (IFF_POINTOPOINT|IFF_LOOPBACK))) 1063 printf("rtinit: wrong ifa (%p) was (%p)\n", 1064 ifa, rt->rt_ifa); | 1126 rt_newaddrmsg(cmd, ifa, error, rt); 1127 if (cmd == RTM_DELETE) { |
1065 /* | 1128 /* |
1066 * Ask that the protocol in question 1067 * remove anything it has associated with 1068 * this route and ifaddr. | 1129 * If we are deleting, and we found an entry, then 1130 * it's been removed from the tree.. now throw it away. |
1069 */ | 1131 */ |
1070 if (rt->rt_ifa->ifa_rtrequest) 1071 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); | 1132 if (rt->rt_refcnt <= 0) { 1133 rt->rt_refcnt++; /* make a 1->0 transition */ 1134 rtfree(rt); 1135 } 1136 } else if (cmd == RTM_ADD) { |
1072 /* | 1137 /* |
1073 * Remove the reference to its ifaddr. | 1138 * We just wanted to add it.. we don't actually 1139 * need a reference. |
1074 */ | 1140 */ |
1075 IFAFREE(rt->rt_ifa); 1076 /* 1077 * And substitute in references to the ifaddr 1078 * we are adding. 1079 */ 1080 rt->rt_ifa = ifa; 1081 rt->rt_ifp = ifa->ifa_ifp; 1082 rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/ 1083 ifa->ifa_refcnt++; 1084 /* 1085 * Now ask the protocol to check if it needs 1086 * any special processing in its new form. 1087 */ 1088 if (ifa->ifa_rtrequest) 1089 ifa->ifa_rtrequest(RTM_ADD, rt, SA(0)); | 1141 rt->rt_refcnt--; |
1090 } | 1142 } |
1091 /* 1092 * notify any listenning routing agents of the change 1093 */ 1094 rt_newaddrmsg(cmd, ifa, error, nrt); | |
1095 } | 1143 } |
1144 if (m) 1145 (void) m_free(m); |
|
1096 return (error); 1097} 1098 1099/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */ 1100SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); | 1146 return (error); 1147} 1148 1149/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */ 1150SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); |