On Fri, Feb 15, 2019 at 06:06:05PM +0100, [email protected] wrote:
>
> Hello,
>
> the following change lead to a kernerl panic after running
> /usr/src/regress/usr.sbin/bgpd/integrationtests/network_statement.sh
>
> https://cvsweb.openbsd.org/src/sys/net/route.c?rev=1.381&content-type=text/x-cvsweb-markup
>
> > CVSROOT: /cvs
> > Module name: src
> > Changes by: [email protected] 2019/02/13 16:47:43
> >
> > Modified files:
> > sys/net : if_mpe.c if_mpw.c route.c route.h
> > sys/netinet : in.c ip_mroute.c
> > sys/netinet6 : in6.c in6_ifattach.c ip6_mroute.c
> > share/man/man9 : rt_ifa_add.9
> >
> > Log message:
> > change rt_ifa_add and rt_ifa_del so they take an rdomain argument.
> >
> > this allows mpls interfaces (mpe, mpw) to pass the rdomain they
> > wish the local label to be in, rather than have it implicitly forced
> > to 0 by these functions. right now they'll pass 0, but it will soon
> > be possible to have them rx packets in other rdomains.
> >
> > previously the functions used ifp->if_rdomain for the rdomain.
> > everything other than mpls still passes ifp->if_rdomain.
> >
> > ok mpi@
>
> the Panic:
>
> panic: kernel diagnostic assertion "rdomain == rtable_l2(rdomain)" fail
> ed: file "/sys/net/route.c", line 1116
> Stopped at db_enter+0x12: popq %r11
> TID PID UID PRFLAGS PFLAGS CPU COMMAND
> *316919 99618 0 0x3 0 1K ifconfig
> db_enter() at db_enter+0x12
> panic() at panic+0x128
> __assert(ffffffff81a98516,ffffffff81a9c30b,45c,ffffffff81a4b70b) at
> __assert+0x
> 28
> rt_ifa_del(ffff80000054f600,200004,ffff80000054f658,b) at rt_ifa_del+0x30b
> rt_ifa_dellocal(ffff80000054f600) at rt_ifa_dellocal+0xc7
> in_purgeaddr(ffff80000054f600) at in_purgeaddr+0xab
> in_ifdetach(ffff80000054a800) at in_ifdetach+0x42
> if_detach(ffff80000054a800) at if_detach+0x11e
> loop_clone_destroy(ffff80000054a800) at loop_clone_destroy+0xb8
> if_clone_destroy(ffff800021ee8c20) at if_clone_destroy+0x10c
> ifioctl(fffffd8279ccdac0,80206979,ffff800021ee8c20,ffff800021fc5540) at
> ifioctl
> +0x1f4
> sys_ioctl(ffff800021fc5540,ffff800021ee8d50,ffff800021ee8d40) at
> sys_ioctl+0x3d
> 5
> syscall(ffff800021ee8df0) at syscall+0x338
> Xsyscall(6,36,1,36,7f7ffffe4438,7281f765060) at Xsyscall+0x128
> end of kernel
> end trace frame: 0x7f7ffffe4340, count: 1
>
I removed the KASSERT() for now because destroying the lo(4) of a rdomain
triggers it (because until now the rdomain is switched to a rtable with
rdomain 0 as L2 before calling rt_ifa_del). A better fix is attached which
should result in a better order of operation.
Thanks for the heads up
--
:wq Claudio
Index: if_loop.c
===================================================================
RCS file: /cvs/src/sys/net/if_loop.c,v
retrieving revision 1.88
diff -u -p -r1.88 if_loop.c
--- if_loop.c 9 Sep 2018 10:11:41 -0000 1.88
+++ if_loop.c 15 Feb 2019 21:21:28 -0000
@@ -196,6 +196,7 @@ int
loop_clone_destroy(struct ifnet *ifp)
{
struct ifnet *p;
+ unsigned int rdomain = 0;
if (ifp->if_index == rtable_loindex(ifp->if_rdomain)) {
/* rdomain 0 always needs a loopback */
@@ -214,13 +215,16 @@ loop_clone_destroy(struct ifnet *ifp)
}
NET_UNLOCK();
- rtable_l2set(ifp->if_rdomain, 0, 0);
+ rdomain = ifp->if_rdomain;
}
if_ih_remove(ifp, loinput, NULL);
if_detach(ifp);
free(ifp, M_DEVBUF, sizeof(*ifp));
+
+ if (rdomain)
+ rtable_l2set(rdomain, 0, 0);
return (0);
}
Index: route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.382
diff -u -p -r1.382 route.c
--- route.c 15 Feb 2019 21:16:01 -0000 1.382
+++ route.c 15 Feb 2019 21:21:28 -0000
@@ -1040,6 +1040,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags
uint8_t prio = ifp->if_priority + RTP_STATIC;
int error;
+ KASSERT(rdomain == rtable_l2(rdomain));
+
memset(&info, 0, sizeof(info));
info.rti_ifa = ifa;
info.rti_flags = flags;
@@ -1048,12 +1050,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags
info.rti_info[RTAX_GATEWAY] = sdltosa(ifp->if_sadl);
else
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
-
- KASSERT(rdomain == rtable_l2(rdomain));
- if (rdomain == rtable_l2(ifp->if_rtlabelid)) {
- info.rti_info[RTAX_LABEL] =
- rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
- }
+ info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
#ifdef MPLS
if ((flags & RTF_MPLS) == RTF_MPLS)
@@ -1097,6 +1094,8 @@ rt_ifa_del(struct ifaddr *ifa, int flags
uint8_t prio = ifp->if_priority + RTP_STATIC;
int error;
+ KASSERT(rdomain == rtable_l2(rdomain));
+
if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
m = m_get(M_DONTWAIT, MT_SONAME);
if (m == NULL)
@@ -1112,11 +1111,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags
info.rti_info[RTAX_DST] = dst;
if ((flags & RTF_LLINFO) == 0)
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
-
- if (rdomain == rtable_l2(ifp->if_rtlabelid)) {
- info.rti_info[RTAX_LABEL] =
- rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
- }
+ info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
if ((flags & RTF_HOST) == 0)
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;