diff options
-rw-r--r-- | sbin/route/route.c | 6 | ||||
-rw-r--r-- | sbin/route/show.c | 8 | ||||
-rw-r--r-- | share/man/man4/route.4 | 3 | ||||
-rw-r--r-- | sys/net/route.c | 119 | ||||
-rw-r--r-- | sys/net/route.h | 3 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.1 | 3 | ||||
-rw-r--r-- | usr.bin/netstat/route.c | 7 |
7 files changed, 125 insertions, 24 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c index 7a5ccba5184..159191250ce 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.59 2003/07/02 21:44:58 deraadt Exp $ */ +/* $OpenBSD: route.c,v 1.60 2003/08/26 08:33:12 itojun Exp $ */ /* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */ /* @@ -40,7 +40,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)route.c 8.3 (Berkeley) 3/19/94"; #else -static const char rcsid[] = "$OpenBSD: route.c,v 1.59 2003/07/02 21:44:58 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: route.c,v 1.60 2003/08/26 08:33:12 itojun Exp $"; #endif #endif /* not lint */ @@ -1461,7 +1461,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\017PROTO2\020PROTO1"; +"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\017PROTO2\020PROTO1\040CLONED"; 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 d325e49fe39..f0e20a63b89 100644 --- a/sbin/route/show.c +++ b/sbin/route/show.c @@ -1,4 +1,4 @@ -/* $OpenBSD: show.c,v 1.25 2003/07/02 21:44:58 deraadt Exp $ */ +/* $OpenBSD: show.c,v 1.26 2003/08/26 08:33:12 itojun Exp $ */ /* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -static char *rcsid = "$OpenBSD: show.c,v 1.25 2003/07/02 21:44:58 deraadt Exp $"; +static char *rcsid = "$OpenBSD: show.c,v 1.26 2003/08/26 08:33:12 itojun Exp $"; #endif #endif /* not lint */ @@ -76,7 +76,7 @@ extern int nflag; * Definitions for showing gateway flags. */ struct bits { - short b_mask; + int b_mask; char b_val; }; static const struct bits bits[] = { @@ -95,6 +95,8 @@ static const struct bits bits[] = { { RTF_STATIC, 'S' }, { RTF_PROTO1, '1' }, { RTF_PROTO2, '2' }, + { RTF_PROTO3, '3' }, + { RTF_CLONED, 'c' }, { 0 } }; diff --git a/share/man/man4/route.4 b/share/man/man4/route.4 index 28bad6a207b..bfb44ba6cd6 100644 --- a/share/man/man4/route.4 +++ b/share/man/man4/route.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: route.4,v 1.13 2003/06/02 23:30:12 millert Exp $ +.\" $OpenBSD: route.4,v 1.14 2003/08/26 08:33:12 itojun Exp $ .\" $NetBSD: route.4,v 1.3 1994/11/30 16:22:31 jtc Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 @@ -240,6 +240,7 @@ Flags include the values: #define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ #define RTF_PROTO2 0x4000 /* protocol specific routing flag #1 */ #define RTF_PROTO1 0x8000 /* protocol specific routing flag #2 */ +#define RTF_CLONED 0x10000 /* this is a cloned route */ .Ed .Pp Specifiers for metric values in rmx_locks and rtm_inits are: diff --git a/sys/net/route.c b/sys/net/route.c index d27bdabe4a9..1e7e2486b81 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.36 2003/06/02 23:28:12 millert Exp $ */ +/* $OpenBSD: route.c,v 1.37 2003/08/26 08:33:12 itojun Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -139,6 +139,9 @@ int rttrash; /* routes not in table but not freed */ struct sockaddr wildcard; /* zero valued cookie for wildcard searches */ static int okaytoclone(u_int, int); +static int rtdeletemsg(struct rtentry *); +static int rtflushclone1(struct radix_node *, void *); +static void rtflushclone(struct radix_node_head *, struct rtentry *); #ifdef IPSEC @@ -449,6 +452,67 @@ out: } /* + * 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); +} + +static int +rtflushclone1(rn, arg) + struct radix_node *rn; + void *arg; +{ + struct rtentry *rt, *parent; + + rt = (struct rtentry *)rn; + parent = (struct rtentry *)arg; + if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent == parent) + rtdeletemsg(rt); + return 0; +} + +static void +rtflushclone(rnh, parent) + struct radix_node_head *rnh; + struct rtentry *parent; +{ + +#ifdef DIAGNOSTIC + if (!parent || (parent->rt_flags & RTF_CLONING) == 0) + panic("rtflushclone: called with a non-cloning route"); + if (!rnh->rnh_walktree) + panic("rtflushclone: no rnh_walktree"); +#endif + rnh->rnh_walktree(rnh, rtflushclone1, (void *)parent); +} + +/* * Routing table ioctl interface. */ int @@ -595,7 +659,7 @@ rtrequest1(req, info, ret_nrt) struct rtentry **ret_nrt; { int s = splsoftnet(); int error = 0; - register struct rtentry *rt; + register struct rtentry *rt, *crt; register struct radix_node *rn; register struct radix_node_head *rnh; struct ifaddr *ifa; @@ -610,6 +674,13 @@ rtrequest1(req, info, ret_nrt) case RTM_DELETE: if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL) senderr(ESRCH); + rt = (struct rtentry *)rn; + if ((rt->rt_flags & RTF_CLONING) != 0) { + /* clean up any cloned children */ + rtflushclone(rnh, rt); + } + if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL) + senderr(ESRCH); if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) panic ("rtrequest delete"); rt = (struct rtentry *)rn; @@ -617,6 +688,10 @@ rtrequest1(req, info, ret_nrt) rt = rt->rt_gwroute; RTFREE(rt); (rt = (struct rtentry *)rn)->rt_gwroute = NULL; } + if (rt->rt_parent) { + rt->rt_parent->rt_refcnt--; + rt->rt_parent = NULL; + } rt->rt_flags &= ~RTF_UP; if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) ifa->ifa_rtrequest(RTM_DELETE, rt, info); @@ -632,8 +707,11 @@ rtrequest1(req, info, ret_nrt) case RTM_RESOLVE: if (ret_nrt == NULL || (rt = *ret_nrt) == NULL) 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) == NULL) flags |= RTF_HOST; @@ -659,15 +737,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 == NULL) { - if (rt->rt_gwroute) - rtfree(rt->rt_gwroute); - Free(rt_key(rt)); - Free(rt); - senderr(EEXIST); - } ifa->ifa_refcnt++; rt->rt_ifa = ifa; rt->rt_ifp = ifa->ifa_ifp; @@ -678,6 +747,28 @@ rtrequest1(req, info, ret_nrt) */ rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ rt->rt_parent = *ret_nrt; /* Back ptr. to parent. */ + rt->rt_parent->rt_refcnt++; + } + 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_flags & RTF_CLONED) != 0 && rt->rt_parent) + rtfree(rt->rt_parent); + if (rt->rt_gwroute) + rtfree(rt->rt_gwroute); + Free(rt_key(rt)); + Free(rt); + senderr(EEXIST); } if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(req, rt, info); @@ -685,6 +776,10 @@ rtrequest1(req, info, ret_nrt) *ret_nrt = rt; rt->rt_refcnt++; } + if ((rt->rt_flags & RTF_CLONING) != 0) { + /* clean up any cloned children */ + rtflushclone(rnh, rt); + } break; } bad: diff --git a/sys/net/route.h b/sys/net/route.h index 8c054fc5e7f..cf72b221581 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.17 2003/06/02 23:28:12 millert Exp $ */ +/* $OpenBSD: route.h,v 1.18 2003/08/26 08:33:12 itojun Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -139,6 +139,7 @@ struct ortentry { #define RTF_PROTO3 0x2000 /* protocol specific routing flag */ #define RTF_PROTO2 0x4000 /* protocol specific routing flag */ #define RTF_PROTO1 0x8000 /* protocol specific routing flag */ +#define RTF_CLONED 0x10000 /* this is a cloned route */ #ifndef _KERNEL /* obsoleted */ diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index 36947fcc829..ca504526e10 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: netstat.1,v 1.32 2003/07/14 12:38:30 jmc Exp $ +.\" $OpenBSD: netstat.1,v 1.33 2003/08/26 08:33:12 itojun Exp $ .\" $NetBSD: netstat.1,v 1.11 1995/10/03 21:42:43 thorpej Exp $ .\" .\" Copyright (c) 1983, 1990, 1992, 1993 @@ -283,6 +283,7 @@ The mapping between letters and flags is: 3 RTF_PROTO3 Protocol specific routing flag #3. 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 f2a207f2b5f..cecc34530eb 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.54 2003/06/26 21:59:11 deraadt Exp $ */ +/* $OpenBSD: route.c,v 1.55 2003/08/26 08:33:12 itojun Exp $ */ /* $NetBSD: route.c,v 1.15 1996/05/07 02:55:06 thorpej Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -static char *rcsid = "$OpenBSD: route.c,v 1.54 2003/06/26 21:59:11 deraadt Exp $"; +static char *rcsid = "$OpenBSD: route.c,v 1.55 2003/08/26 08:33:12 itojun Exp $"; #endif #endif /* not lint */ @@ -90,7 +90,7 @@ struct radix_node_head *rt_tables[AF_MAX+1]; * Definitions for showing gateway flags. */ struct bits { - short b_mask; + int b_mask; char b_val; } bits[] = { { RTF_UP, 'U' }, @@ -109,6 +109,7 @@ struct bits { { RTF_PROTO1, '1' }, { RTF_PROTO2, '2' }, { RTF_PROTO3, '3' }, + { RTF_CLONED, 'c' }, { 0 } }; |