diff --git a/sbin/route/route.c b/sbin/route/route.c index 975d392cbfe1..fef8a2205d3a 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.41 2001/01/27 04:26:49 itojun Exp $ */ +/* $NetBSD: route.c,v 1.42 2001/01/27 04:49:34 itojun Exp $ */ /* * Copyright (c) 1983, 1989, 1991, 1993 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\n\ #if 0 static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: route.c,v 1.41 2001/01/27 04:26:49 itojun Exp $"); +__RCSID("$NetBSD: route.c,v 1.42 2001/01/27 04:49:34 itojun Exp $"); #endif #endif /* not lint */ @@ -1452,7 +1452,7 @@ char *msgtypes[] = { char metricnames[] = "\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu"; char routeflags[] = -"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\017PROTO2\020PROTO1"; +"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016CLONED\017PROTO2\020PROTO1"; char ifnetflags[] = "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST"; char addrnames[] = diff --git a/sbin/route/show.c b/sbin/route/show.c index c91e3c6483de..f7ac61acb206 100644 --- a/sbin/route/show.c +++ b/sbin/route/show.c @@ -1,4 +1,4 @@ -/* $NetBSD: show.c,v 1.16 2001/01/27 04:26:49 itojun Exp $ */ +/* $NetBSD: show.c,v 1.17 2001/01/27 04:49:35 itojun Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -__RCSID("$NetBSD: show.c,v 1.16 2001/01/27 04:26:49 itojun Exp $"); +__RCSID("$NetBSD: show.c,v 1.17 2001/01/27 04:49:35 itojun Exp $"); #endif #endif /* not lint */ @@ -90,6 +90,7 @@ static const struct bits bits[] = { { RTF_LLINFO, 'L' }, { RTF_STATIC, 'S' }, { RTF_BLACKHOLE, 'B' }, + { RTF_CLONED, 'c' }, { RTF_PROTO1, '1' }, { RTF_PROTO2, '2' }, { 0 } diff --git a/share/man/man4/route.4 b/share/man/man4/route.4 index e9463edba44d..5f636f5c61a5 100644 --- a/share/man/man4/route.4 +++ b/share/man/man4/route.4 @@ -1,4 +1,4 @@ -.\" $NetBSD: route.4,v 1.8 2000/10/10 14:11:26 itojun Exp $ +.\" $NetBSD: route.4,v 1.9 2001/01/27 04:49:35 itojun Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -299,6 +299,7 @@ Flags include the values: #define RTF_LLINFO 0x400 /* generated by ARP or ESIS */ #define RTF_STATIC 0x800 /* manually added */ #define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ +#define RTF_CLONED 0x2000 /* this is a cloned route */ #define RTF_PROTO2 0x4000 /* protocol specific routing flag */ #define RTF_PROTO1 0x8000 /* protocol specific routing flag */ .Ed diff --git a/sys/net/route.c b/sys/net/route.c index 15adb99ffded..a41b4566b139 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.39 2001/01/17 04:05:42 itojun Exp $ */ +/* $NetBSD: route.c,v 1.40 2001/01/27 04:49:31 itojun Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -137,6 +137,8 @@ struct pool rttimer_pool; /* pool for rttimer structures */ struct callout rt_timer_ch; /* callout for rt_timer_timer() */ +static int rtdeletemsg __P((struct rtentry *)); + void rtable_init(table) void **table; @@ -369,6 +371,38 @@ out: rt_missmsg(RTM_REDIRECT, &info, flags, error); } +/* + * Delete a route and generate a message + */ +static int +rtdeletemsg(rt) + struct rtentry *rt; +{ + int error; + struct rt_addrinfo info; + + /* + * Request the new route so that the entry is not actually + * deleted. That will allow the information being reported to + * be accurate (and consistent with route_output()). + */ + bzero((caddr_t)&info, sizeof(info)); + info.rti_info[RTAX_DST] = rt_key(rt); + info.rti_info[RTAX_NETMASK] = rt_mask(rt); + info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; + info.rti_flags = rt->rt_flags; + error = rtrequest1(RTM_DELETE, &info, &rt); + + rt_missmsg(RTM_DELETE, &info, info.rti_flags, error); + + /* Adjust the refcount */ + if (error == 0 && rt->rt_refcnt <= 0) { + rt->rt_refcnt++; + rtfree(rt); + } + return (error); +} + /* * Routing table ioctl interface. */ @@ -500,7 +534,7 @@ rtrequest1(req, info, ret_nrt) struct rtentry **ret_nrt; { int s = splsoftnet(); int error = 0; - struct rtentry *rt; + struct rtentry *rt, *crt; struct radix_node *rn; struct radix_node_head *rnh; struct ifaddr *ifa; @@ -537,8 +571,11 @@ rtrequest1(req, info, ret_nrt) case RTM_RESOLVE: if (ret_nrt == 0 || (rt = *ret_nrt) == 0) senderr(EINVAL); + if ((rt->rt_flags & RTF_CLONING) == 0) + senderr(EINVAL); ifa = rt->rt_ifa; - flags = rt->rt_flags & ~RTF_CLONING; + flags = rt->rt_flags & ~(RTF_CLONING | RTF_STATIC); + flags |= RTF_CLONED; gateway = rt->rt_gateway; if ((netmask = rt->rt_genmask) == 0) flags |= RTF_HOST; @@ -564,15 +601,6 @@ rtrequest1(req, info, ret_nrt) rt_maskedcopy(dst, ndst, netmask); } else Bcopy(dst, ndst, dst->sa_len); - rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask, - rnh, rt->rt_nodes); - if (rn == 0) { - if (rt->rt_gwroute) - rtfree(rt->rt_gwroute); - Free(rt_key(rt)); - pool_put(&rtentry_pool, rt); - senderr(EEXIST); - } IFAREF(ifa); rt->rt_ifa = ifa; rt->rt_ifp = ifa->ifa_ifp; @@ -586,6 +614,25 @@ rtrequest1(req, info, ret_nrt) rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; } } + rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask, + rnh, rt->rt_nodes); + if (rn == NULL && (crt = rtalloc1(ndst, 0)) != NULL) { + /* overwrite cloned route */ + if ((crt->rt_flags & RTF_CLONED) != 0) { + rtdeletemsg(crt); + rn = rnh->rnh_addaddr((caddr_t)ndst, + (caddr_t)netmask, rnh, rt->rt_nodes); + } + RTFREE(crt); + } + if (rn == 0) { + IFAFREE(ifa); + if (rt->rt_gwroute) + rtfree(rt->rt_gwroute); + Free(rt_key(rt)); + pool_put(&rtentry_pool, rt); + senderr(EEXIST); + } if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(req, rt, info); if (ret_nrt) { diff --git a/sys/net/route.h b/sys/net/route.h index a4d15357b11b..59e911796e29 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $NetBSD: route.h,v 1.24 2001/01/17 04:05:42 itojun Exp $ */ +/* $NetBSD: route.h,v 1.25 2001/01/27 04:49:34 itojun Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -138,6 +138,7 @@ struct ortentry { #define RTF_LLINFO 0x400 /* generated by ARP or ESIS */ #define RTF_STATIC 0x800 /* manually added */ #define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ +#define RTF_CLONED 0x2000 /* this is a cloned route */ #define RTF_PROTO2 0x4000 /* protocol specific routing flag */ #define RTF_PROTO1 0x8000 /* protocol specific routing flag */ diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index ee3413b67d1b..3a569f0eed71 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: netstat.1,v 1.27 2000/08/15 20:24:58 jhawk Exp $ +.\" $NetBSD: netstat.1,v 1.28 2001/01/27 04:49:35 itojun Exp $ .\" .\" Copyright (c) 1983, 1990, 1992, 1993 .\" The Regents of the University of California. All rights reserved. @@ -289,6 +289,7 @@ The mapping between letters and flags is: 2 RTF_PROTO1 Protocol specific routing flag #2 B RTF_BLACKHOLE Just discard pkts (during updates) C RTF_CLONING Generate new routes on use +c RTF_CLONED Cloned routes (generated from RTF_CLONING) D RTF_DYNAMIC Created dynamically (by redirect) G RTF_GATEWAY Destination requires forwarding by intermediary H RTF_HOST Host entry (net otherwise) diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 43213cf9e785..7e3ec41f2bd3 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.51 2000/11/14 23:07:40 matt Exp $ */ +/* $NetBSD: route.c,v 1.52 2001/01/27 04:49:35 itojun Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -__RCSID("$NetBSD: route.c,v 1.51 2000/11/14 23:07:40 matt Exp $"); +__RCSID("$NetBSD: route.c,v 1.52 2001/01/27 04:49:35 itojun Exp $"); #endif #endif /* not lint */ @@ -91,7 +91,6 @@ struct bits { { RTF_GATEWAY, 'G' }, { RTF_HOST, 'H' }, { RTF_REJECT, 'R' }, - { RTF_BLACKHOLE,'B' }, { RTF_DYNAMIC, 'D' }, { RTF_MODIFIED, 'M' }, { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ @@ -100,6 +99,8 @@ struct bits { { RTF_XRESOLVE, 'X' }, { RTF_LLINFO, 'L' }, { RTF_STATIC, 'S' }, + { RTF_BLACKHOLE,'B' }, + { RTF_CLONED, 'c' }, { RTF_PROTO1, '1' }, { RTF_PROTO2, '2' }, { 0 }