Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/net Pull up revisions 1.40-1.41 (via patch, request...
details: https://anonhg.NetBSD.org/src/rev/46ac3ab69db3
branches: netbsd-1-5
changeset: 491133:46ac3ab69db3
user: he <he%NetBSD.org@localhost>
date: Thu Apr 05 12:43:22 2001 +0000
description:
Pull up revisions 1.40-1.41 (via patch, requested by itojun):
Mark cloned routes with RTF_CLONED. Present it in ``netstat -r''
output by ``c''.
Let static routes overwrite cloned routes, as cloned routes can
come back again if necessary. Should fix PR#11916 and maybe some
other PRs with ARP behavior.
Cleanup cloned route when parent route (RTF_CLONING) goes away.
Adds rt_parent to link parent from child (like NRL did, ours do
refcnt rt_refcnt properly).
diffstat:
sys/net/route.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 105 insertions(+), 12 deletions(-)
diffs (185 lines):
diff -r 92fad98897ea -r 46ac3ab69db3 sys/net/route.c
--- a/sys/net/route.c Thu Apr 05 12:42:59 2001 +0000
+++ b/sys/net/route.c Thu Apr 05 12:43:22 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: route.c,v 1.36 2000/03/30 09:45:40 augustss Exp $ */
+/* $NetBSD: route.c,v 1.36.4.1 2001/04/05 12:43:22 he Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -137,6 +137,10 @@
struct callout rt_timer_ch; /* callout for rt_timer_timer() */
+static int rtdeletemsg __P((struct rtentry *));
+static int rtflushclone1 __P((struct radix_node *, void *));
+static void rtflushclone __P((struct radix_node_head *, struct rtentry *));
+
void
rtable_init(table)
void **table;
@@ -351,6 +355,67 @@
}
/*
+ * 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;
+ error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
+ rt->rt_flags, &rt);
+
+ rt_missmsg(RTM_DELETE, &info, rt->rt_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
@@ -417,7 +482,7 @@
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;
@@ -430,6 +495,13 @@
netmask = 0;
switch (req) {
case RTM_DELETE:
+ if ((rn = rnh->rnh_lookup(dst, netmask, rnh)) == 0)
+ 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)) == 0)
senderr(ESRCH);
if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
@@ -454,8 +526,11 @@
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;
@@ -480,20 +555,13 @@
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;
if (req == RTM_RESOLVE) {
rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
+ rt->rt_parent = *ret_nrt;
+ rt->rt_parent->rt_refcnt++;
} else if (rt->rt_rmx.rmx_mtu == 0
&& !(rt->rt_rmx.rmx_locks & RTV_MTU)) { /* XXX */
if (rt->rt_gwroute != NULL) {
@@ -502,12 +570,37 @@
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_flags & RTF_CLONED) != 0 && rt->rt_parent)
+ rtfree(rt->rt_parent);
+ 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, SA(ret_nrt ? *ret_nrt : 0));
if (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:
Home |
Main Index |
Thread Index |
Old Index