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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 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.2 (Berkeley) 11/15/93 34 * $FreeBSD$ 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> 43 #include <sys/mbuf.h> 44 #include <sys/socket.h> 45 #include <sys/domain.h> 46 #include <sys/kernel.h> 47 48 #include <net/if.h> 49 #include <net/route.h> 50 51 #include <netinet/in.h> 52 #include <netinet/ip_mroute.h> 53 54 #define SA(p) ((struct sockaddr *)(p)) 55 56 struct route_cb route_cb; 57 static struct rtstat rtstat; 58 struct radix_node_head *rt_tables[AF_MAX+1]; 59 60 static int rttrash; /* routes not in table but not freed */ 61 62 static void rt_maskedcopy __P((struct sockaddr *, 63 struct sockaddr *, struct sockaddr *)); 64 static void rtable_init __P((void **)); 65 66 static void 67 rtable_init(table) 68 void **table; 69 { 70 struct domain *dom; 71 for (dom = domains; dom; dom = dom->dom_next) 72 if (dom->dom_rtattach) 73 dom->dom_rtattach(&table[dom->dom_family], 74 dom->dom_rtoffset); 75 } 76 77 void 78 route_init() 79 { 80 rn_init(); /* initialize all zeroes, all ones, mask table */ 81 rtable_init((void **)rt_tables); 82 } 83 84 /* 85 * Packet routing routines. 86 */ 87 void 88 rtalloc(ro) 89 register struct route *ro; 90 { 91 rtalloc_ign(ro, 0UL); 92 } 93 94 void 95 rtalloc_ign(ro, ignore) 96 register struct route *ro; 97 u_long ignore; 98 { 99 struct rtentry *rt; 100 int s; 101 102 if ((rt = ro->ro_rt) != NULL) { 103 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP) 104 return; 105 /* XXX - We are probably always at splnet here already. */ 106 s = splnet(); 107 RTFREE(rt); 108 ro->ro_rt = NULL; 109 splx(s); 110 } 111 ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore); 112 } 113 114 /* 115 * Look up the route that matches the address given 116 * Or, at least try.. Create a cloned route if needed. 117 */ 118 struct rtentry * 119 rtalloc1(dst, report, ignflags) 120 register struct sockaddr *dst; 121 int report; 122 u_long ignflags; 123 { 124 register struct radix_node_head *rnh = rt_tables[dst->sa_family]; 125 register struct rtentry *rt; 126 register struct radix_node *rn; 127 struct rtentry *newrt = 0; 128 struct rt_addrinfo info; 129 u_long nflags; 130 int s = splnet(), err = 0, msgtype = RTM_MISS; 131 132 /* 133 * Look up the address in the table for that Address Family 134 */ 135 if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) && 136 ((rn->rn_flags & RNF_ROOT) == 0)) { 137 /* 138 * If we find it and it's not the root node, then 139 * get a refernce on the rtentry associated. 140 */ 141 newrt = rt = (struct rtentry *)rn; 142 nflags = rt->rt_flags & ~ignflags; 143 if (report && (nflags & (RTF_CLONING | RTF_PRCLONING))) { 144 /* 145 * We are apparently adding (report = 0 in delete). 146 * If it requires that it be cloned, do so. 147 * (This implies it wasn't a HOST route.) 148 */ 149 err = rtrequest(RTM_RESOLVE, dst, SA(0), 150 SA(0), 0, &newrt); 151 if (err) { 152 /* 153 * If the cloning didn't succeed, maybe 154 * what we have will do. Return that. 155 */ 156 newrt = rt; 157 rt->rt_refcnt++; 158 goto miss; 159 } 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 } 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 */ 176 rtstat.rts_unreach++; 177 miss: if (report) { 178 /* 179 * If required, report the failure to the supervising 180 * Authorities. 181 * For a delete, this is not an error. (report == 0) 182 */ 183 bzero((caddr_t)&info, sizeof(info)); 184 info.rti_info[RTAX_DST] = dst; 185 rt_missmsg(msgtype, &info, 0, err); 186 } 187 } 188 splx(s); 189 return (newrt); 190 } 191 192 /* 193 * Remove a reference count from an rtentry. 194 * If the count gets low enough, take it out of the routing table 195 */ 196 void 197 rtfree(rt) 198 register struct rtentry *rt; 199 { 200 /* 201 * find the tree for that address family 202 */ 203 register struct radix_node_head *rnh = 204 rt_tables[rt_key(rt)->sa_family]; 205 register struct ifaddr *ifa; 206 207 if (rt == 0 || rnh == 0) 208 panic("rtfree"); 209 210 /* 211 * decrement the reference count by one and if it reaches 0, 212 * and there is a close function defined, call the close function 213 */ 214 rt->rt_refcnt--; 215 if(rnh->rnh_close && rt->rt_refcnt == 0) { 216 rnh->rnh_close((struct radix_node *)rt, rnh); 217 } 218 219 /* 220 * If we are no longer "up" (and ref == 0) 221 * then we can free the resources associated 222 * with the route. 223 */ 224 if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) { 225 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) 226 panic ("rtfree 2"); 227 /* 228 * the rtentry must have been removed from the routing table 229 * so it is represented in rttrash.. remove that now. 230 */ 231 rttrash--; 232 233 #ifdef DIAGNOSTIC 234 if (rt->rt_refcnt < 0) { 235 printf("rtfree: %p not freed (neg refs)\n", rt); 236 return; 237 } 238 #endif 239 240 /* 241 * release references on items we hold them on.. 242 * e.g other routes and ifaddrs. 243 */ 244 if((ifa = rt->rt_ifa)) 245 IFAFREE(ifa); 246 if (rt->rt_parent) { 247 RTFREE(rt->rt_parent); 248 } 249 250 /* 251 * The key is separatly alloc'd so free it (see rt_setgate()). 252 * This also frees the gateway, as they are always malloc'd 253 * together. 254 */ 255 Free(rt_key(rt)); 256 257 /* 258 * and the rtentry itself of course 259 */ 260 Free(rt); 261 } 262 } 263 264 void 265 ifafree(ifa) 266 register struct ifaddr *ifa; 267 { 268 if (ifa == NULL) 269 panic("ifafree"); 270 if (ifa->ifa_refcnt == 0) 271 free(ifa, M_IFADDR); 272 else 273 ifa->ifa_refcnt--; 274 } 275 276 /* 277 * Force a routing table entry to the specified 278 * destination to go through the given gateway. 279 * Normally called as a result of a routing redirect 280 * message from the network layer. 281 * 282 * N.B.: must be called at splnet 283 * 284 */ 285 void 286 rtredirect(dst, gateway, netmask, flags, src, rtp) 287 struct sockaddr *dst, *gateway, *netmask, *src; 288 int flags; 289 struct rtentry **rtp; 290 { 291 register 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; 300 goto out; 301 } 302 rt = rtalloc1(dst, 0, 0UL); 303 /* 304 * If the redirect isn't from our current router for this dst, 305 * it's either old or wrong. If it redirects us to ourselves, 306 * we have a routing loop, perhaps as a result of an interface 307 * going down recently. 308 */ 309 #define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0) 310 if (!(flags & RTF_DONE) && rt && 311 (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa)) 312 error = EINVAL; 313 else if (ifa_ifwithaddr(gateway)) 314 error = EHOSTUNREACH; 315 if (error) 316 goto done; 317 /* 318 * Create a new entry if we just got back a wildcard entry 319 * or the the lookup failed. This is necessary for hosts 320 * which use routing redirects generated by smart gateways 321 * to dynamically build the routing tables. 322 */ 323 if ((rt == 0) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2)) 324 goto create; 325 /* 326 * Don't listen to the redirect if it's 327 * for a route to an interface. 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: 336 flags |= RTF_GATEWAY | RTF_DYNAMIC; 337 error = rtrequest((int)RTM_ADD, dst, gateway, 338 netmask, flags, 339 (struct rtentry **)0); 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; 348 stat = &rtstat.rts_newgateway; 349 /* 350 * add the key and gateway (in one malloc'd chunk). 351 */ 352 rt_setgate(rt, rt_key(rt), gateway); 353 } 354 } else 355 error = EHOSTUNREACH; 356 done: 357 if (rt) { 358 if (rtp && !error) 359 *rtp = rt; 360 else 361 rtfree(rt); 362 } 363 out: 364 if (error) 365 rtstat.rts_badredirect++; 366 else if (stat != NULL) 367 (*stat)++; 368 bzero((caddr_t)&info, sizeof(info)); 369 info.rti_info[RTAX_DST] = dst; 370 info.rti_info[RTAX_GATEWAY] = gateway; 371 info.rti_info[RTAX_NETMASK] = netmask; 372 info.rti_info[RTAX_AUTHOR] = src; 373 rt_missmsg(RTM_REDIRECT, &info, flags, error); 374 } 375 376 /* 377 * Routing table ioctl interface. 378 */ 379 int 380 rtioctl(req, data, p) 381 int req; 382 caddr_t data; 383 struct proc *p; 384 { 385 #ifdef INET 386 /* Multicast goop, grrr... */ 387 #ifdef MROUTING 388 return mrt_ioctl(req, data); 389 #else 390 return mrt_ioctl(req, data, p); 391 #endif 392 #else /* INET */ 393 return ENXIO; 394 #endif /* INET */ 395 } 396 397 struct ifaddr * 398 ifa_ifwithroute(flags, dst, gateway) 399 int flags; 400 struct sockaddr *dst, *gateway; 401 { 402 register struct ifaddr *ifa; 403 if ((flags & RTF_GATEWAY) == 0) { 404 /* 405 * If we are adding a route to an interface, 406 * and the interface is a pt to pt link 407 * we should search for the destination 408 * as our clue to the interface. Otherwise 409 * we can use the local address. 410 */ 411 ifa = 0; 412 if (flags & RTF_HOST) { 413 ifa = ifa_ifwithdstaddr(dst); 414 } 415 if (ifa == 0) 416 ifa = ifa_ifwithaddr(gateway); 417 } else { 418 /* 419 * If we are adding a route to a remote net 420 * or host, the gateway may still be on the 421 * other end of a pt to pt link. 422 */ 423 ifa = ifa_ifwithdstaddr(gateway); 424 } 425 if (ifa == 0) 426 ifa = ifa_ifwithnet(gateway); 427 if (ifa == 0) { 428 struct rtentry *rt = rtalloc1(dst, 0, 0UL); 429 if (rt == 0) 430 return (0); 431 rt->rt_refcnt--; 432 if ((ifa = rt->rt_ifa) == 0) 433 return (0); 434 } 435 if (ifa->ifa_addr->sa_family != dst->sa_family) { 436 struct ifaddr *oifa = ifa; 437 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 438 if (ifa == 0) 439 ifa = oifa; 440 } 441 return (ifa); 442 } 443 444 #define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 445 446 static int rt_fixdelete __P((struct radix_node *, void *)); 447 static int rt_fixchange __P((struct radix_node *, void *)); 448 449 struct rtfc_arg { 450 struct rtentry *rt0; 451 struct radix_node_head *rnh; 452 }; 453 454 /* 455 * Do appropriate manipulations of a routing tree given 456 * all the bits of info needed 457 */ 458 int 459 rtrequest(req, dst, gateway, netmask, flags, ret_nrt) 460 int req, flags; 461 struct sockaddr *dst, *gateway, *netmask; 462 struct rtentry **ret_nrt; 463 { 464 int s = splnet(); int error = 0; 465 register struct rtentry *rt; 466 register struct radix_node *rn; 467 register struct radix_node_head *rnh; 468 struct ifaddr *ifa; 469 struct sockaddr *ndst; 470 #define senderr(x) { error = x ; goto bad; } 471 472 /* 473 * Find the correct routing tree to use for this Address Family 474 */ 475 if ((rnh = rt_tables[dst->sa_family]) == 0) 476 senderr(ESRCH); 477 /* 478 * If we are adding a host route then we don't want to put 479 * a netmask in the tree 480 */ 481 if (flags & RTF_HOST) 482 netmask = 0; 483 switch (req) { 484 case RTM_DELETE: 485 /* 486 * Remove the item from the tree and return it. 487 * Complain if it is not there and do no more processing. 488 */ 489 if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0) 490 senderr(ESRCH); 491 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) 492 panic ("rtrequest delete"); 493 rt = (struct rtentry *)rn; 494 495 /* 496 * Now search what's left of the subtree for any cloned 497 * routes which might have been formed from this node. 498 */ 499 if ((rt->rt_flags & RTF_PRCLONING) && netmask) { 500 rnh->rnh_walktree_from(rnh, dst, netmask, 501 rt_fixdelete, rt); 502 } 503 504 /* 505 * Remove any external references we may have. 506 * This might result in another rtentry being freed if 507 * we held its last reference. 508 */ 509 if (rt->rt_gwroute) { 510 rt = rt->rt_gwroute; 511 RTFREE(rt); 512 (rt = (struct rtentry *)rn)->rt_gwroute = 0; 513 } 514 515 /* 516 * NB: RTF_UP must be set during the search above, 517 * because we might delete the last ref, causing 518 * rt to get freed prematurely. 519 * eh? then why not just add a reference? 520 * I'm not sure how RTF_UP helps matters. (JRE) 521 */ 522 rt->rt_flags &= ~RTF_UP; 523 524 /* 525 * give the protocol a chance to keep things in sync. 526 */ 527 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) 528 ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); 529 530 /* 531 * one more rtentry floating around that is not 532 * linked to the routing table. 533 */ 534 rttrash++; 535 536 /* 537 * If the caller wants it, then it can have it, 538 * but it's up to it to free the rtentry as we won't be 539 * doing it. 540 */ 541 if (ret_nrt) 542 *ret_nrt = rt; 543 else if (rt->rt_refcnt <= 0) { 544 rt->rt_refcnt++; /* make a 1->0 transition */ 545 rtfree(rt); 546 } 547 break; 548 549 case RTM_RESOLVE: 550 if (ret_nrt == 0 || (rt = *ret_nrt) == 0) 551 senderr(EINVAL); 552 ifa = rt->rt_ifa; 553 flags = rt->rt_flags & 554 ~(RTF_CLONING | RTF_PRCLONING | RTF_STATIC); 555 flags |= RTF_WASCLONED; 556 gateway = rt->rt_gateway; 557 if ((netmask = rt->rt_genmask) == 0) 558 flags |= RTF_HOST; 559 goto makeroute; 560 561 case RTM_ADD: 562 if ((flags & RTF_GATEWAY) && !gateway) 563 panic("rtrequest: GATEWAY but no gateway"); 564 565 if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0) 566 senderr(ENETUNREACH); 567 568 makeroute: 569 R_Malloc(rt, struct rtentry *, sizeof(*rt)); 570 if (rt == 0) 571 senderr(ENOBUFS); 572 Bzero(rt, sizeof(*rt)); 573 rt->rt_flags = RTF_UP | flags; 574 /* 575 * Add the gateway. Possibly re-malloc-ing the storage for it 576 * also add the rt_gwroute if possible. 577 */ 578 if ((error = rt_setgate(rt, dst, gateway)) != 0) { 579 Free(rt); 580 senderr(error); 581 } 582 583 /* 584 * point to the (possibly newly malloc'd) dest address. 585 */ 586 ndst = rt_key(rt); 587 588 /* 589 * make sure it contains the value we want (masked if needed). 590 */ 591 if (netmask) { 592 rt_maskedcopy(dst, ndst, netmask); 593 } else 594 Bcopy(dst, ndst, dst->sa_len); 595 596 /* 597 * Note that we now have a reference to the ifa. 598 * This moved from below so that rnh->rnh_addaddr() can 599 * examine the ifa and ifa->ifa_ifp if it so desires. 600 */ 601 ifa->ifa_refcnt++; 602 rt->rt_ifa = ifa; 603 rt->rt_ifp = ifa->ifa_ifp; 604 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ 605 606 rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask, 607 rnh, rt->rt_nodes); 608 if (rn == 0) { 609 struct rtentry *rt2; 610 /* 611 * Uh-oh, we already have one of these in the tree. 612 * We do a special hack: if the route that's already 613 * there was generated by the protocol-cloning 614 * mechanism, then we just blow it away and retry 615 * the insertion of the new one. 616 */ 617 rt2 = rtalloc1(dst, 0, RTF_PRCLONING); 618 if (rt2 && rt2->rt_parent) { 619 rtrequest(RTM_DELETE, 620 (struct sockaddr *)rt_key(rt2), 621 rt2->rt_gateway, 622 rt_mask(rt2), rt2->rt_flags, 0); 623 RTFREE(rt2); 624 rn = rnh->rnh_addaddr((caddr_t)ndst, 625 (caddr_t)netmask, 626 rnh, rt->rt_nodes); 627 } else if (rt2) { 628 /* undo the extra ref we got */ 629 RTFREE(rt2); 630 } 631 } 632 633 /* 634 * If it still failed to go into the tree, 635 * then un-make it (this should be a function) 636 */ 637 if (rn == 0) { 638 if (rt->rt_gwroute) 639 rtfree(rt->rt_gwroute); 640 if (rt->rt_ifa) { 641 IFAFREE(rt->rt_ifa); 642 } 643 Free(rt_key(rt)); 644 Free(rt); 645 senderr(EEXIST); 646 } 647 648 rt->rt_parent = 0; 649 650 /* 651 * If we got here from RESOLVE, then we are cloning 652 * so clone the rest, and note that we 653 * are a clone (and increment the parent's references) 654 */ 655 if (req == RTM_RESOLVE) { 656 rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ 657 if ((*ret_nrt)->rt_flags & RTF_PRCLONING) { 658 rt->rt_parent = (*ret_nrt); 659 (*ret_nrt)->rt_refcnt++; 660 } 661 } 662 663 /* 664 * if this protocol has something to add to this then 665 * allow it to do that as well. 666 */ 667 if (ifa->ifa_rtrequest) 668 ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); 669 670 /* 671 * We repeat the same procedure from rt_setgate() here because 672 * it doesn't fire when we call it there because the node 673 * hasn't been added to the tree yet. 674 */ 675 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) { 676 struct rtfc_arg arg; 677 arg.rnh = rnh; 678 arg.rt0 = rt; 679 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt), 680 rt_fixchange, &arg); 681 } 682 683 /* 684 * actually return a resultant rtentry and 685 * give the caller a single reference. 686 */ 687 if (ret_nrt) { 688 *ret_nrt = rt; 689 rt->rt_refcnt++; 690 } 691 break; 692 } 693 bad: 694 splx(s); 695 return (error); 696 } 697 698 /* 699 * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' 700 * (i.e., the routes related to it by the operation of cloning). This 701 * routine is iterated over all potential former-child-routes by way of 702 * rnh->rnh_walktree_from() above, and those that actually are children of 703 * the late parent (passed in as VP here) are themselves deleted. 704 */ 705 static int 706 rt_fixdelete(rn, vp) 707 struct radix_node *rn; 708 void *vp; 709 { 710 struct rtentry *rt = (struct rtentry *)rn; 711 struct rtentry *rt0 = vp; 712 713 if (rt->rt_parent == rt0 && !(rt->rt_flags & RTF_PINNED)) { 714 return rtrequest(RTM_DELETE, rt_key(rt), 715 (struct sockaddr *)0, rt_mask(rt), 716 rt->rt_flags, (struct rtentry **)0); 717 } 718 return 0; 719 } 720 721 /* 722 * This routine is called from rt_setgate() to do the analogous thing for 723 * adds and changes. There is the added complication in this case of a 724 * middle insert; i.e., insertion of a new network route between an older 725 * network route and (cloned) host routes. For this reason, a simple check 726 * of rt->rt_parent is insufficient; each candidate route must be tested 727 * against the (mask, value) of the new route (passed as before in vp) 728 * to see if the new route matches it. Unfortunately, this has the obnoxious 729 * property of also triggering for insertion /above/ a pre-existing network 730 * route and clones. Sigh. This may be fixed some day. 731 * 732 * XXX - it may be possible to do fixdelete() for changes and reserve this 733 * routine just for adds. I'm not sure why I thought it was necessary to do 734 * changes this way. 735 */ 736 #ifdef DEBUG 737 static int rtfcdebug = 0; 738 #endif 739 740 static int 741 rt_fixchange(rn, vp) 742 struct radix_node *rn; 743 void *vp; 744 { 745 struct rtentry *rt = (struct rtentry *)rn; 746 struct rtfc_arg *ap = vp; 747 struct rtentry *rt0 = ap->rt0; 748 struct radix_node_head *rnh = ap->rnh; 749 u_char *xk1, *xm1, *xk2; 750 int i, len; 751 752 #ifdef DEBUG 753 if (rtfcdebug) 754 printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0); 755 #endif 756 757 if (!rt->rt_parent || (rt->rt_flags & RTF_PINNED)) { 758 #ifdef DEBUG 759 if(rtfcdebug) printf("no parent or pinned\n"); 760 #endif 761 return 0; 762 } 763 764 if (rt->rt_parent == rt0) { 765 #ifdef DEBUG 766 if(rtfcdebug) printf("parent match\n"); 767 #endif 768 return rtrequest(RTM_DELETE, rt_key(rt), 769 (struct sockaddr *)0, rt_mask(rt), 770 rt->rt_flags, (struct rtentry **)0); 771 } 772 773 /* 774 * There probably is a function somewhere which does this... 775 * if not, there should be. 776 */ 777 len = imin(((struct sockaddr *)rt_key(rt0))->sa_len, 778 ((struct sockaddr *)rt_key(rt))->sa_len); 779 780 xk1 = (u_char *)rt_key(rt0); 781 xm1 = (u_char *)rt_mask(rt0); 782 xk2 = (u_char *)rt_key(rt); 783 784 for (i = rnh->rnh_treetop->rn_offset; i < len; i++) { 785 if ((xk2[i] & xm1[i]) != xk1[i]) { 786 #ifdef DEBUG 787 if(rtfcdebug) printf("no match\n"); 788 #endif 789 return 0; 790 } 791 } 792 793 /* 794 * OK, this node is a clone, and matches the node currently being 795 * changed/added under the node's mask. So, get rid of it. 796 */ 797 #ifdef DEBUG 798 if(rtfcdebug) printf("deleting\n"); 799 #endif 800 return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, 801 rt_mask(rt), rt->rt_flags, (struct rtentry **)0); 802 } 803 804 int 805 rt_setgate(rt0, dst, gate) 806 struct rtentry *rt0; 807 struct sockaddr *dst, *gate; 808 { 809 caddr_t new, old; 810 int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len); 811 register struct rtentry *rt = rt0; 812 struct radix_node_head *rnh = rt_tables[dst->sa_family]; 813 814 /* 815 * A host route with the destination equal to the gateway 816 * will interfere with keeping LLINFO in the routing 817 * table, so disallow it. 818 */ 819 if (((rt0->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) == 820 (RTF_HOST|RTF_GATEWAY)) && 821 (dst->sa_len == gate->sa_len) && 822 (bcmp(dst, gate, dst->sa_len) == 0)) { 823 /* 824 * The route might already exist if this is an RTM_CHANGE 825 * or a routing redirect, so try to delete it. 826 */ 827 if (rt_key(rt0)) 828 rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt0), 829 rt0->rt_gateway, rt_mask(rt0), rt0->rt_flags, 0); 830 return EADDRNOTAVAIL; 831 } 832 833 /* 834 * Both dst and gateway are stored in the same malloc'd chunk 835 * (If I ever get my hands on....) 836 * if we need to malloc a new chunk, then keep the old one around 837 * till we don't need it any more. 838 */ 839 if (rt->rt_gateway == 0 || glen > ROUNDUP(rt->rt_gateway->sa_len)) { 840 old = (caddr_t)rt_key(rt); 841 R_Malloc(new, caddr_t, dlen + glen); 842 if (new == 0) 843 return ENOBUFS; 844 rt->rt_nodes->rn_key = new; 845 } else { 846 /* 847 * otherwise just overwrite the old one 848 */ 849 new = rt->rt_nodes->rn_key; 850 old = 0; 851 } 852 853 /* 854 * copy the new gateway value into the memory chunk 855 */ 856 Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen); 857 858 /* 859 * if we are replacing the chunk (or it's new) we need to 860 * replace the dst as well 861 */ 862 if (old) { 863 Bcopy(dst, new, dlen); 864 Free(old); 865 } 866 867 /* 868 * If there is already a gwroute, it's now almost definitly wrong 869 * so drop it. 870 */ 871 if (rt->rt_gwroute) { 872 rt = rt->rt_gwroute; RTFREE(rt); 873 rt = rt0; rt->rt_gwroute = 0; 874 } 875 /* 876 * Cloning loop avoidance: 877 * In the presence of protocol-cloning and bad configuration, 878 * it is possible to get stuck in bottomless mutual recursion 879 * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing 880 * protocol-cloning to operate for gateways (which is probably the 881 * correct choice anyway), and avoid the resulting reference loops 882 * by disallowing any route to run through itself as a gateway. 883 * This is obviously mandatory when we get rt->rt_output(). 884 */ 885 if (rt->rt_flags & RTF_GATEWAY) { 886 rt->rt_gwroute = rtalloc1(gate, 1, RTF_PRCLONING); 887 if (rt->rt_gwroute == rt) { 888 RTFREE(rt->rt_gwroute); 889 rt->rt_gwroute = 0; 890 return EDQUOT; /* failure */ 891 } 892 } 893 894 /* 895 * This isn't going to do anything useful for host routes, so 896 * don't bother. Also make sure we have a reasonable mask 897 * (we don't yet have one during adds). 898 */ 899 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) { 900 struct rtfc_arg arg; 901 arg.rnh = rnh; 902 arg.rt0 = rt; 903 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt), 904 rt_fixchange, &arg); 905 } 906 907 return 0; 908 } 909 910 static void 911 rt_maskedcopy(src, dst, netmask) 912 struct sockaddr *src, *dst, *netmask; 913 { 914 register u_char *cp1 = (u_char *)src; 915 register u_char *cp2 = (u_char *)dst; 916 register u_char *cp3 = (u_char *)netmask; 917 u_char *cplim = cp2 + *cp3; 918 u_char *cplim2 = cp2 + *cp1; 919 920 *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */ 921 cp3 += 2; 922 if (cplim > cplim2) 923 cplim = cplim2; 924 while (cp2 < cplim) 925 *cp2++ = *cp1++ & *cp3++; 926 if (cp2 < cplim2) 927 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2)); 928 } 929 930 /* 931 * Set up a routing table entry, normally 932 * for an interface. 933 */ 934 int 935 rtinit(ifa, cmd, flags) 936 register struct ifaddr *ifa; 937 int cmd, flags; 938 { 939 register struct rtentry *rt; 940 register struct sockaddr *dst; 941 register struct sockaddr *deldst; 942 struct mbuf *m = 0; 943 struct rtentry *nrt = 0; 944 int error; 945 946 dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr; 947 /* 948 * If it's a delete, check that if it exists, it's on the correct 949 * interface or we might scrub a route to another ifa which would 950 * be confusing at best and possibly worse. 951 */ 952 if (cmd == RTM_DELETE) { 953 /* 954 * It's a delete, so it should already exist.. 955 * If it's a net, mask off the host bits 956 * (Assuming we have a mask) 957 */ 958 if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { 959 m = m_get(M_DONTWAIT, MT_SONAME); 960 if (m == NULL) 961 return(ENOBUFS); 962 deldst = mtod(m, struct sockaddr *); 963 rt_maskedcopy(dst, deldst, ifa->ifa_netmask); 964 dst = deldst; 965 } 966 /* 967 * Get an rtentry that is in the routing tree and 968 * contains the correct info. (if this fails, can't get there). 969 * We set "report" to FALSE so that if it doesn't exist, 970 * it doesn't report an error or clone a route, etc. etc. 971 */ 972 rt = rtalloc1(dst, 0, 0UL); 973 if (rt) { 974 /* 975 * Ok so we found the rtentry. it has an extra reference 976 * for us at this stage. we won't need that so 977 * lop that off now. 978 */ 979 rt->rt_refcnt--; 980 if (rt->rt_ifa != ifa) { 981 /* 982 * If the interface in the rtentry doesn't match 983 * the interface we are using, then we don't 984 * want to delete it, so return an error. 985 * This seems to be the only point of 986 * this whole RTM_DELETE clause. 987 */ 988 if (m) 989 (void) m_free(m); 990 return (flags & RTF_HOST ? EHOSTUNREACH 991 : ENETUNREACH); 992 } 993 } 994 /* XXX */ 995 #if 0 996 else { 997 /* 998 * One would think that as we are deleting, and we know 999 * it doesn't exist, we could just return at this point 1000 * with an "ELSE" clause, but apparently not.. 1001 */ 1002 return (flags & RTF_HOST ? EHOSTUNREACH 1003 : ENETUNREACH); 1004 } 1005 #endif 1006 } 1007 /* 1008 * Do the actual request 1009 */ 1010 error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask, 1011 flags | ifa->ifa_flags, &nrt); 1012 if (m) 1013 (void) m_free(m); 1014 /* 1015 * If we are deleting, and we found an entry, then 1016 * it's been removed from the tree.. now throw it away. 1017 */ 1018 if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) { 1019 /* 1020 * notify any listenning routing agents of the change 1021 */ 1022 rt_newaddrmsg(cmd, ifa, error, nrt); 1023 if (rt->rt_refcnt <= 0) { 1024 rt->rt_refcnt++; /* need a 1->0 transition to free */ 1025 rtfree(rt); 1026 } 1027 } 1028 1029 /* 1030 * We are adding, and we have a returned routing entry. 1031 * We need to sanity check the result. 1032 */ 1033 if (cmd == RTM_ADD && error == 0 && (rt = nrt)) { 1034 /* 1035 * We just wanted to add it.. we don't actually need a reference 1036 */ 1037 rt->rt_refcnt--; 1038 /* 1039 * If it came back with an unexpected interface, then it must 1040 * have already existed or something. (XXX) 1041 */ 1042 if (rt->rt_ifa != ifa) { 1043 if (!(rt->rt_ifa->ifa_ifp->if_flags & 1044 (IFF_POINTOPOINT|IFF_LOOPBACK))) 1045 printf("rtinit: wrong ifa (%p) was (%p)\n", 1046 ifa, rt->rt_ifa); 1047 /* 1048 * Ask that the protocol in question 1049 * remove anything it has associated with 1050 * this route and ifaddr. 1051 */ 1052 if (rt->rt_ifa->ifa_rtrequest) 1053 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); 1054 /* 1055 * Remove the reference to its ifaddr. 1056 */ 1057 IFAFREE(rt->rt_ifa); 1058 /* 1059 * And substitute in references to the ifaddr 1060 * we are adding. 1061 */ 1062 rt->rt_ifa = ifa; 1063 rt->rt_ifp = ifa->ifa_ifp; 1064 rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/ 1065 ifa->ifa_refcnt++; 1066 /* 1067 * Now ask the protocol to check if it needs 1068 * any special processing in its new form. 1069 */ 1070 if (ifa->ifa_rtrequest) 1071 ifa->ifa_rtrequest(RTM_ADD, rt, SA(0)); 1072 } 1073 /* 1074 * notify any listenning routing agents of the change 1075 */ 1076 rt_newaddrmsg(cmd, ifa, error, nrt); 1077 } 1078 return (error); 1079 } 1080 1081 /* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */ 1082 SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); 1083