route.c (7090) | route.c (7197) |
---|---|
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.2 (Berkeley) 11/15/93 | 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.2 (Berkeley) 11/15/93 |
34 * $Id: route.c,v 1.15 1995/01/23 17:53:21 davidg Exp $ | 34 * $Id: route.c,v 1.16 1995/03/16 18:14:30 bde Exp $ |
35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/proc.h> 41#include <sys/mbuf.h> 42#include <sys/socket.h> --- 5 unchanged lines hidden (view full) --- 48#include <net/if.h> 49#include <net/route.h> 50#include <net/raw_cb.h> 51 52#include <netinet/in.h> 53#include <netinet/in_var.h> 54#include <netinet/ip_mroute.h> 55 | 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/proc.h> 41#include <sys/mbuf.h> 42#include <sys/socket.h> --- 5 unchanged lines hidden (view full) --- 48#include <net/if.h> 49#include <net/route.h> 50#include <net/raw_cb.h> 51 52#include <netinet/in.h> 53#include <netinet/in_var.h> 54#include <netinet/ip_mroute.h> 55 |
56#ifdef NS 57#include <netns/ns.h> 58#endif 59 | |
60#define SA(p) ((struct sockaddr *)(p)) 61 62int rttrash; /* routes not in table but not freed */ 63struct sockaddr wildcard; /* zero valued cookie for wildcard searches */ 64 65void 66rtable_init(table) 67 void **table; --- 277 unchanged lines hidden (view full) --- 345 if (ifa == 0) 346 ifa = oifa; 347 } 348 return (ifa); 349} 350 351#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 352 | 56#define SA(p) ((struct sockaddr *)(p)) 57 58int rttrash; /* routes not in table but not freed */ 59struct sockaddr wildcard; /* zero valued cookie for wildcard searches */ 60 61void 62rtable_init(table) 63 void **table; --- 277 unchanged lines hidden (view full) --- 341 if (ifa == 0) 342 ifa = oifa; 343 } 344 return (ifa); 345} 346 347#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 348 |
353static void rt_fixfamily(struct rtentry *rt); | 349static int rt_fixdelete(struct radix_node *, void *); |
354 355int 356rtrequest(req, dst, gateway, netmask, flags, ret_nrt) 357 int req, flags; 358 struct sockaddr *dst, *gateway, *netmask; 359 struct rtentry **ret_nrt; 360{ 361 int s = splnet(); int error = 0; --- 12 unchanged lines hidden (view full) --- 374 switch (req) { 375 case RTM_DELETE: 376 if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0) 377 senderr(ESRCH); 378 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) 379 panic ("rtrequest delete"); 380 rt = (struct rtentry *)rn; 381 rt->rt_flags &= ~RTF_UP; | 350 351int 352rtrequest(req, dst, gateway, netmask, flags, ret_nrt) 353 int req, flags; 354 struct sockaddr *dst, *gateway, *netmask; 355 struct rtentry **ret_nrt; 356{ 357 int s = splnet(); int error = 0; --- 12 unchanged lines hidden (view full) --- 370 switch (req) { 371 case RTM_DELETE: 372 if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0) 373 senderr(ESRCH); 374 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) 375 panic ("rtrequest delete"); 376 rt = (struct rtentry *)rn; 377 rt->rt_flags &= ~RTF_UP; |
382 rt_fixfamily(rt); | 378 379 /* 380 * Now search what's left of the subtree for any cloned 381 * routes which might have been formed from this node. 382 */ 383 if (rt->rt_flags & RTF_PRCLONING) { 384 rnh->rnh_walktree_from(rnh, dst, netmask, 385 rt_fixdelete, rt); 386 } |
383 if (rt->rt_gwroute) { 384 rt = rt->rt_gwroute; RTFREE(rt); 385 (rt = (struct rtentry *)rn)->rt_gwroute = 0; 386 } 387 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) 388 ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); 389 rttrash++; 390 if (ret_nrt) --- 48 unchanged lines hidden (view full) --- 439 rtfree(rt->rt_gwroute); 440 Free(rt_key(rt)); 441 Free(rt); 442 senderr(EEXIST); 443 } 444 ifa->ifa_refcnt++; 445 rt->rt_ifa = ifa; 446 rt->rt_ifp = ifa->ifa_ifp; | 387 if (rt->rt_gwroute) { 388 rt = rt->rt_gwroute; RTFREE(rt); 389 (rt = (struct rtentry *)rn)->rt_gwroute = 0; 390 } 391 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) 392 ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); 393 rttrash++; 394 if (ret_nrt) --- 48 unchanged lines hidden (view full) --- 443 rtfree(rt->rt_gwroute); 444 Free(rt_key(rt)); 445 Free(rt); 446 senderr(EEXIST); 447 } 448 ifa->ifa_refcnt++; 449 rt->rt_ifa = ifa; 450 rt->rt_ifp = ifa->ifa_ifp; |
447 if (req == RTM_RESOLVE) | 451 if (req == RTM_RESOLVE) { |
448 rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ | 452 rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ |
449 if ((req == RTM_RESOLVE) 450 && ((*ret_nrt)->rt_flags & RTF_PRCLONING)) { 451 rt->rt_parent = (*ret_nrt); 452 rt->rt_nextchild = (*ret_nrt)->rt_nextchild; 453 (*ret_nrt)->rt_nextchild = rt; | 453 if ((*ret_nrt)->rt_flags & RTF_PRCLONING) 454 rt->rt_parent = (*ret_nrt); |
454 } 455 if (ifa->ifa_rtrequest) 456 ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); 457 if (ret_nrt) { 458 *ret_nrt = rt; 459 rt->rt_refcnt++; 460 } 461 break; 462 } 463bad: 464 splx(s); 465 return (error); 466} 467 468/* 469 * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' 470 * (i.e., the routes related to it by the operation of cloning). This | 455 } 456 if (ifa->ifa_rtrequest) 457 ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); 458 if (ret_nrt) { 459 *ret_nrt = rt; 460 rt->rt_refcnt++; 461 } 462 break; 463 } 464bad: 465 splx(s); 466 return (error); 467} 468 469/* 470 * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' 471 * (i.e., the routes related to it by the operation of cloning). This |
471 * involves deleting the entire chain of descendants (in the case of a parent 472 * route being deleted), or removing this route from the chain (in the case 473 * of a child route being deleted). | 472 * routine is iterated over all potential former-child-routes by way of 473 * rnh->rnh_walktree_from() above, and those that actually are children of 474 * the late parent (passed in as VP here) are themselves deleted. |
474 */ | 475 */ |
475static void 476rt_fixfamily(struct rtentry *rt0) | 476static int 477rt_fixdelete(struct radix_node *rn, void *vp) |
477{ | 478{ |
478 struct rtentry *rt, *lrt, *nrt; | 479 struct rtentry *rt = (struct rtentry *)rn; 480 struct rtentry *rt0 = vp; |
479 | 481 |
480 if(rt = rt0->rt_parent) { 481 if(rt->rt_flags & RTF_CHAINDELETE) 482 return; /* relax, it will all be done for us */ 483 484 /* So what if it takes linear time? */ 485 do { 486 lrt = rt; 487 rt = rt->rt_nextchild; 488 } while(rt && rt != rt0); 489 lrt->rt_nextchild = rt0->rt_nextchild; 490 } else if((rt = rt0)->rt_nextchild) { 491 lrt = rt; 492 rt->rt_flags |= RTF_CHAINDELETE; 493 494 rt = rt->rt_nextchild; 495 496 while(rt) { 497 nrt = rt->rt_nextchild; 498 /* 499 * There might be some value to open-coding this 500 * rtrequest call, but I am not yet convinced of 501 * the value of this. 502 */ 503 rtrequest(RTM_DELETE, rt_key(rt), 504 (struct sockaddr *)0, rt_mask(rt), 505 rt->rt_flags, (struct rtentry **)0); 506 rt = nrt; 507 } 508 lrt->rt_flags &= ~RTF_CHAINDELETE; | 482 if (rt->rt_parent == rt0) { 483 return rtrequest(RTM_DELETE, rt_key(rt), 484 (struct sockaddr *)0, rt_mask(rt), 485 rt->rt_flags, (struct rtentry **)0); |
509 } | 486 } |
487 return 0; |
|
510} 511 512int 513rt_setgate(rt0, dst, gate) 514 struct rtentry *rt0; 515 struct sockaddr *dst, *gate; 516{ 517 caddr_t new, old; --- 112 unchanged lines hidden --- | 488} 489 490int 491rt_setgate(rt0, dst, gate) 492 struct rtentry *rt0; 493 struct sockaddr *dst, *gate; 494{ 495 caddr_t new, old; --- 112 unchanged lines hidden --- |