summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/route/route.c6
-rw-r--r--sbin/route/show.c8
-rw-r--r--share/man/man4/route.43
-rw-r--r--sys/net/route.c119
-rw-r--r--sys/net/route.h3
-rw-r--r--usr.bin/netstat/netstat.13
-rw-r--r--usr.bin/netstat/route.c7
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 }
};