Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src/sys Pull up following revision(s) (requested by ozaki-r i...
details: https://anonhg.NetBSD.org/src/rev/fbf10164c195
branches: netbsd-8
changeset: 445623:fbf10164c195
user: martin <martin%NetBSD.org@localhost>
date: Tue Nov 06 14:38:58 2018 +0000
description:
Pull up following revision(s) (requested by ozaki-r in ticket #1080):
sys/netinet6/nd6.c: revision 1.251
sys/netinet/if_arp.c: revision 1.276
sys/net/if.c: revision 1.438
sys/net/if.c: revision 1.439
sys/net/route.c: revision 1.214
sys/net/route.c: revision 1.215
sys/net/route.c: revision 1.216
sys/netinet6/in6.c: revision 1.270
sys/net/route.h: revision 1.120
sys/net/if.c: revision 1.440
Remove a wrong assertion in ifaref
-
Doing ifref on an ifa with IFA_DESTROYING is not a problem; the reference should
be dropped during the destruction of the ifa.
-
Use atomic operations for ifa_refcnt
-
Avoid a dangling pointer during rt_replace_ifa
-
Avoid double rt_replace_ifa on rtrequest1(RTM_ADD)
Some callers of rtrequest1(RTM_ADD) adjust rt_ifa of an rtentry created by
rtrequest1 that may change rt_ifa (in ifa_rtrequest) with another ifa that is
different from requested one. It's wasteful and even worse introduces a race
condition. rtrequest1 should just use a passed ifa as is if a caller hopes so.
-
Use rt_update framework on updating a rtentry
diffstat:
sys/net/if.c | 16 +++++++----
sys/net/route.c | 70 ++++++++++++++++++++-------------------------------
sys/net/route.h | 7 ++++-
sys/netinet/if_arp.c | 9 +++++-
sys/netinet6/in6.c | 34 +++++++++++++++++++++++-
sys/netinet6/nd6.c | 7 ++--
6 files changed, 87 insertions(+), 56 deletions(-)
diffs (truncated from 346 to 300 lines):
diff -r 8f73f2431c24 -r fbf10164c195 sys/net/if.c
--- a/sys/net/if.c Sun Nov 04 11:15:10 2018 +0000
+++ b/sys/net/if.c Tue Nov 06 14:38:58 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.394.2.14 2018/08/27 07:49:11 martin Exp $ */
+/* $NetBSD: if.c,v 1.394.2.15 2018/11/06 14:38:58 martin Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.14 2018/08/27 07:49:11 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.15 2018/11/06 14:38:58 martin Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1777,8 +1777,8 @@
void
ifaref(struct ifaddr *ifa)
{
- KASSERT(!ISSET(ifa->ifa_flags, IFA_DESTROYING));
- ifa->ifa_refcnt++;
+
+ atomic_inc_uint(&ifa->ifa_refcnt);
}
void
@@ -1787,7 +1787,7 @@
KASSERT(ifa != NULL);
KASSERT(ifa->ifa_refcnt > 0);
- if (--ifa->ifa_refcnt == 0) {
+ if (atomic_dec_uint_nv(&ifa->ifa_refcnt) == 0) {
free(ifa, M_IFADDR);
}
}
@@ -2177,7 +2177,8 @@
struct psref psref;
if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL ||
- (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL)
+ (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL ||
+ ISSET(info->rti_flags, RTF_DONTCHANGEIFA))
return;
if ((ifa = ifaof_ifpforaddr_psref(dst, ifp, &psref)) != NULL) {
rt_replace_ifa(rt, ifa);
@@ -2431,6 +2432,9 @@
rt->rt_ifp = lo0ifp;
+ if (ISSET(info->rti_flags, RTF_DONTCHANGEIFA))
+ break;
+
IFADDR_READER_FOREACH(ifa, ifp) {
if (equal(rt_getkey(rt), ifa->ifa_addr))
break;
diff -r 8f73f2431c24 -r fbf10164c195 sys/net/route.c
--- a/sys/net/route.c Sun Nov 04 11:15:10 2018 +0000
+++ b/sys/net/route.c Tue Nov 06 14:38:58 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: route.c,v 1.194.6.11 2018/09/07 12:31:30 martin Exp $ */
+/* $NetBSD: route.c,v 1.194.6.12 2018/11/06 14:38:58 martin Exp $ */
/*-
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.11 2018/09/07 12:31:30 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.12 2018/11/06 14:38:58 martin Exp $");
#include <sys/param.h>
#ifdef RTFLUSH_DEBUG
@@ -406,6 +406,11 @@
void
rt_replace_ifa(struct rtentry *rt, struct ifaddr *ifa)
{
+ struct ifaddr *old;
+
+ if (rt->rt_ifa == ifa)
+ return;
+
if (rt->rt_ifa &&
rt->rt_ifa != ifa &&
rt->rt_ifa->ifa_flags & IFA_ROUTE &&
@@ -424,8 +429,9 @@
}
ifaref(ifa);
- ifafree(rt->rt_ifa);
+ old = rt->rt_ifa;
rt_set_ifa1(rt, ifa);
+ ifafree(old);
}
static void
@@ -1236,7 +1242,7 @@
if (rt == NULL)
senderr(ENOBUFS);
memset(rt, 0, sizeof(*rt));
- rt->rt_flags = RTF_UP | flags;
+ rt->rt_flags = RTF_UP | (flags & ~RTF_DONTCHANGEIFA);
LIST_INIT(&rt->rt_timer);
RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
@@ -1599,7 +1605,7 @@
}
memset(&info, 0, sizeof(info));
info.rti_ifa = ifa;
- info.rti_flags = flags | ifa->ifa_flags;
+ info.rti_flags = flags | ifa->ifa_flags | RTF_DONTCHANGEIFA;
info.rti_info[RTAX_DST] = dst;
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
@@ -1630,40 +1636,7 @@
rt_unref(rt);
break;
case RTM_ADD:
- /*
- * XXX it looks just reverting rt_ifa replaced by ifa_rtrequest
- * called via rtrequest1. Can we just prevent the replacement
- * somehow and remove the following code? And also doesn't
- * calling ifa_rtrequest(RTM_ADD) replace rt_ifa again?
- */
- if (rt->rt_ifa != ifa) {
- printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
- rt->rt_ifa);
-#ifdef NET_MPSAFE
- KASSERT(!cpu_softintr_p());
-
- error = rt_update_prepare(rt);
- if (error == 0) {
-#endif
- if (rt->rt_ifa->ifa_rtrequest != NULL) {
- rt->rt_ifa->ifa_rtrequest(RTM_DELETE,
- rt, &info);
- }
- rt_replace_ifa(rt, ifa);
- rt->rt_ifp = ifa->ifa_ifp;
- if (ifa->ifa_rtrequest != NULL)
- ifa->ifa_rtrequest(RTM_ADD, rt, &info);
-#ifdef NET_MPSAFE
- rt_update_finish(rt);
- } else {
- /*
- * If error != 0, the rtentry is being
- * destroyed, so doing nothing doesn't
- * matter.
- */
- }
-#endif
- }
+ KASSERT(rt->rt_ifa == ifa);
rt_newmsg(cmd, rt);
rt_unref(rt);
RT_REFCNT_TRACE(rt);
@@ -1695,17 +1668,16 @@
struct rtentry *nrt;
memset(&info, 0, sizeof(info));
- info.rti_flags = RTF_HOST | RTF_LOCAL;
+ info.rti_flags = RTF_HOST | RTF_LOCAL | RTF_DONTCHANGEIFA;
info.rti_info[RTAX_DST] = ifa->ifa_addr;
info.rti_info[RTAX_GATEWAY] =
(const struct sockaddr *)ifa->ifa_ifp->if_sadl;
info.rti_ifa = ifa;
nrt = NULL;
e = rtrequest1(RTM_ADD, &info, &nrt);
- if (nrt && ifa != nrt->rt_ifa)
- rt_replace_ifa(nrt, ifa);
rt_newaddrmsg(RTM_ADD, ifa, e, nrt);
if (nrt != NULL) {
+ KASSERT(nrt->rt_ifa == ifa);
#ifdef RT_DEBUG
dump_rt(nrt);
#endif
@@ -1758,7 +1730,21 @@
}
rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);
} else {
+#ifdef NET_MPSAFE
+ int error = rt_update_prepare(rt);
+ if (error == 0) {
+ rt_replace_ifa(rt, alt_ifa);
+ rt_update_finish(rt);
+ } else {
+ /*
+ * If error != 0, the rtentry is being
+ * destroyed, so doing nothing doesn't
+ * matter.
+ */
+ }
+#else
rt_replace_ifa(rt, alt_ifa);
+#endif
rt_newmsg(RTM_CHANGE, rt);
}
} else
diff -r 8f73f2431c24 -r fbf10164c195 sys/net/route.h
--- a/sys/net/route.h Sun Nov 04 11:15:10 2018 +0000
+++ b/sys/net/route.h Tue Nov 06 14:38:58 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: route.h,v 1.112.4.4 2018/04/14 10:16:19 martin Exp $ */
+/* $NetBSD: route.h,v 1.112.4.5 2018/11/06 14:38:58 martin Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@@ -172,6 +172,11 @@
#define RTF_LOCAL 0x40000 /* route represents a local address */
#define RTF_BROADCAST 0x80000 /* route represents a bcast address */
#define RTF_UPDATING 0x100000 /* route is updating */
+/*
+ * The flag is nevert set to rt_flags. It just tells rtrequest1 to set a passed
+ * ifa to rt_ifa (via rti_ifa) and not replace rt_ifa in ifa_rtrequest.
+ */
+#define RTF_DONTCHANGEIFA 0x200000 /* suppress rt_ifa replacement */
/*
* Routing statistics.
diff -r 8f73f2431c24 -r fbf10164c195 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c Sun Nov 04 11:15:10 2018 +0000
+++ b/sys/netinet/if_arp.c Tue Nov 06 14:38:58 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.250.2.8 2018/04/02 08:54:35 martin Exp $ */
+/* $NetBSD: if_arp.c,v 1.250.2.9 2018/11/06 14:38:58 martin Exp $ */
/*-
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.250.2.8 2018/04/02 08:54:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.250.2.9 2018/11/06 14:38:58 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -603,6 +603,11 @@
rt->rt_rmx.rmx_mtu = 0;
}
rt->rt_flags |= RTF_LOCAL;
+
+ if (ISSET(info->rti_flags, RTF_DONTCHANGEIFA)) {
+ pserialize_read_exit(s);
+ goto out;
+ }
/*
* make sure to set rt->rt_ifa to the interface
* address we are using, otherwise we will have trouble
diff -r 8f73f2431c24 -r fbf10164c195 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c Sun Nov 04 11:15:10 2018 +0000
+++ b/sys/netinet6/in6.c Tue Nov 06 14:38:58 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.245.2.11 2018/06/07 17:48:31 martin Exp $ */
+/* $NetBSD: in6.c,v 1.245.2.12 2018/11/06 14:38:58 martin Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.245.2.11 2018/06/07 17:48:31 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.245.2.12 2018/11/06 14:38:58 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -869,8 +869,23 @@
ntohs(mltaddr.sin6_addr.s6_addr16[1]),
satocsin6(rt_getkey(rt))->sin6_addr.s6_addr16[0],
satocsin6(rt_getkey(rt))->sin6_addr.s6_addr16[1]);
+#ifdef NET_MPSAFE
+ error = rt_update_prepare(rt);
+ if (error == 0) {
+ rt_replace_ifa(rt, &ia->ia_ifa);
+ rt->rt_ifp = ifp;
+ rt_update_finish(rt);
+ } else {
+ /*
+ * If error != 0, the rtentry is being
+ * destroyed, so doing nothing doesn't
+ * matter.
+ */
+ }
+#else
rt_replace_ifa(rt, &ia->ia_ifa);
rt->rt_ifp = ifp;
+#endif
}
}
if (!rt) {
@@ -953,8 +968,23 @@
ntohs(mltaddr.sin6_addr.s6_addr16[1]),
satocsin6(rt_getkey(rt))->sin6_addr.s6_addr16[0],
satocsin6(rt_getkey(rt))->sin6_addr.s6_addr16[1]);
+#ifdef NET_MPSAFE
+ error = rt_update_prepare(rt);
Home |
Main Index |
Thread Index |
Old Index