Hi,

As claudio@ wants to refactor router timer before making them MP
safe, I would like to protect them with kernel lock.  It should fix
this panic.

https://marc.info/?l=openbsd-tech&m=164038527425440&w=2

I hope this is the final step before running IP forwarding in
parallel.

ok?

bluhm

Index: netinet/ip_icmp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.188
diff -u -p -r1.188 ip_icmp.c
--- netinet/ip_icmp.c   20 Apr 2022 09:38:26 -0000      1.188
+++ netinet/ip_icmp.c   21 Apr 2022 12:45:40 -0000
@@ -634,8 +634,10 @@ reflect:
                rtredirect(sintosa(&sdst), sintosa(&sgw),
                    sintosa(&ssrc), &newrt, m->m_pkthdr.ph_rtableid);
                if (newrt != NULL && icmp_redirtimeout > 0) {
+                       KERNEL_LOCK();
                        rt_timer_add(newrt, icmp_redirect_timeout,
                            icmp_redirect_timeout_q, m->m_pkthdr.ph_rtableid);
+                       KERNEL_UNLOCK();
                }
                rtfree(newrt);
                pfctlinput(PRC_REDIRECT_HOST, sintosa(&sdst));
@@ -884,8 +886,10 @@ icmp_sysctl(int *name, u_int namelen, vo
                NET_LOCK();
                error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
                    &icmp_redirtimeout, 0, INT_MAX);
+               KERNEL_LOCK();
                rt_timer_queue_change(icmp_redirect_timeout_q,
                    icmp_redirtimeout);
+               KERNEL_UNLOCK();
                NET_UNLOCK();
                break;
 
@@ -975,8 +979,10 @@ icmp_mtudisc_clone(struct in_addr dst, u
                rt = nrt;
                rtm_send(rt, RTM_ADD, 0, rtableid);
        }
+       KERNEL_LOCK();
        error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q,
            rtableid);
+       KERNEL_UNLOCK();
        if (error)
                goto bad;
 
Index: netinet/ip_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.367
diff -u -p -r1.367 ip_input.c
--- netinet/ip_input.c  20 Apr 2022 09:38:26 -0000      1.367
+++ netinet/ip_input.c  21 Apr 2022 13:00:33 -0000
@@ -1616,9 +1616,11 @@ ip_sysctl(int *name, u_int namelen, void
                NET_LOCK();
                error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc);
                if (ip_mtudisc == 0) {
+                       KERNEL_LOCK();
                        rt_timer_queue_destroy(ip_mtudisc_timeout_q);
                        ip_mtudisc_timeout_q =
                            rt_timer_queue_create(ip_mtudisc_timeout);
+                       KERNEL_UNLOCK();
                }
                NET_UNLOCK();
                return error;
@@ -1626,8 +1628,10 @@ ip_sysctl(int *name, u_int namelen, void
                NET_LOCK();
                error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
                    &ip_mtudisc_timeout, 0, INT_MAX);
+               KERNEL_LOCK();
                rt_timer_queue_change(ip_mtudisc_timeout_q,
                    ip_mtudisc_timeout);
+               KERNEL_UNLOCK();
                NET_UNLOCK();
                return (error);
 #ifdef IPSEC
Index: netinet/ip_mroute.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.131
diff -u -p -r1.131 ip_mroute.c
--- netinet/ip_mroute.c 15 Dec 2021 17:21:08 -0000      1.131
+++ netinet/ip_mroute.c 21 Apr 2022 13:02:43 -0000
@@ -520,7 +520,9 @@ ip_mrouter_init(struct socket *so, struc
                return (EADDRINUSE);
 
        ip_mrouter[rtableid] = so;
+       KERNEL_LOCK();
        mrouterq[rtableid] = rt_timer_queue_create(MCAST_EXPIRE_FREQUENCY);
+       KERNEL_UNLOCK();
 
        return (0);
 }
@@ -572,7 +574,9 @@ ip_mrouter_done(struct socket *so)
 
        mrt_api_config = 0;
 
+       KERNEL_LOCK();
        rt_timer_queue_destroy(mrouterq[rtableid]);
+       KERNEL_UNLOCK();
        mrouterq[rtableid] = NULL;
        ip_mrouter[rtableid] = NULL;
        mrt_count[rtableid] = 0;
@@ -799,8 +803,10 @@ mfc_expire_route(struct rtentry *rt, str
        /* Not expired, add it back to the queue. */
        if (mfc->mfc_expire == 0) {
                mfc->mfc_expire = 1;
+               KERNEL_LOCK();
                rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid],
                    rtableid);
+               KERNEL_UNLOCK();
                return;
        }
 
@@ -834,8 +840,10 @@ mfc_add_route(struct ifnet *ifp, struct 
 
        rt->rt_llinfo = (caddr_t)mfc;
 
+       KERNEL_LOCK();
        rt_timer_add(rt, mfc_expire_route, mrouterq[rtableid],
            rtableid);
+       KERNEL_UNLOCK();
 
        mfc->mfc_parent = mfccp->mfcc_parent;
        mfc->mfc_pkt_cnt = 0;
@@ -1342,7 +1350,9 @@ mrt_mcast_del(struct rtentry *rt, unsign
        int                      error;
 
        /* Remove all timers related to this route. */
+       KERNEL_LOCK();
        rt_timer_remove_all(rt);
+       KERNEL_UNLOCK();
 
        free(rt->rt_llinfo, M_MRTABLE, sizeof(struct mfc));
        rt->rt_llinfo = NULL;
Index: netinet6/icmp6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/icmp6.c,v
retrieving revision 1.239
diff -u -p -r1.239 icmp6.c
--- netinet6/icmp6.c    20 Apr 2022 09:38:26 -0000      1.239
+++ netinet6/icmp6.c    21 Apr 2022 12:48:18 -0000
@@ -987,7 +987,9 @@ icmp6_mtudisc_update(struct ip6ctlparam 
         * allow non-validated cases if memory is plenty, to make traffic
         * from non-connected pcb happy.
         */
+       KERNEL_LOCK();
        rtcount = rt_timer_queue_count(icmp6_mtudisc_timeout_q);
+       KERNEL_UNLOCK();
        if (validated) {
                if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat)
                        return;
@@ -1383,7 +1385,9 @@ icmp6_redirect_input(struct mbuf *m, int
                 * work just fine even if we do not install redirect route
                 * (there will be additional hops, though).
                 */
+               KERNEL_LOCK();
                rtcount = rt_timer_queue_count(icmp6_redirect_timeout_q);
+               KERNEL_UNLOCK();
                if (0 <= ip6_maxdynroutes && rtcount >= ip6_maxdynroutes)
                        goto freeit;
                else if (0 <= icmp6_redirect_lowat &&
@@ -1405,8 +1409,10 @@ icmp6_redirect_input(struct mbuf *m, int
                rtredirect(sin6tosa(&sdst), sin6tosa(&sgw), sin6tosa(&ssrc),
                    &newrt, m->m_pkthdr.ph_rtableid);
                if (newrt != NULL && icmp6_redirtimeout > 0) {
+                       KERNEL_LOCK();
                        rt_timer_add(newrt, icmp6_redirect_timeout,
                            icmp6_redirect_timeout_q, m->m_pkthdr.ph_rtableid);
+                       KERNEL_UNLOCK();
                }
                rtfree(newrt);
        }
@@ -1829,8 +1835,10 @@ icmp6_mtudisc_clone(struct sockaddr_in6 
                rt = nrt;
                rtm_send(rt, RTM_ADD, 0, rtableid);
        }
+       KERNEL_LOCK();
        error = rt_timer_add(rt, icmp6_mtudisc_timeout, icmp6_mtudisc_timeout_q,
            rtableid);
+       KERNEL_UNLOCK();
        if (error)
                goto bad;
 
@@ -1921,8 +1929,10 @@ icmp6_sysctl(int *name, u_int namelen, v
                NET_LOCK();
                error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
                    &icmp6_redirtimeout, 0, INT_MAX);
+               KERNEL_LOCK();
                rt_timer_queue_change(icmp6_redirect_timeout_q,
                    icmp6_redirtimeout);
+               KERNEL_UNLOCK();
                NET_UNLOCK();
                break;
 
Index: netinet6/ip6_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.241
diff -u -p -r1.241 ip6_input.c
--- netinet6/ip6_input.c        20 Apr 2022 09:38:26 -0000      1.241
+++ netinet6/ip6_input.c        21 Apr 2022 12:48:51 -0000
@@ -1456,8 +1456,10 @@ ip6_sysctl(int *name, u_int namelen, voi
                NET_LOCK();
                error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
                    &ip6_mtudisc_timeout, 0, INT_MAX);
+               KERNEL_LOCK();
                rt_timer_queue_change(icmp6_mtudisc_timeout_q,
                    ip6_mtudisc_timeout);
+               KERNEL_UNLOCK();
                NET_UNLOCK();
                return (error);
        case IPV6CTL_IFQUEUE:
Index: netinet6/ip6_mroute.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_mroute.c,v
retrieving revision 1.127
diff -u -p -r1.127 ip6_mroute.c
--- netinet6/ip6_mroute.c       15 Dec 2021 17:21:08 -0000      1.127
+++ netinet6/ip6_mroute.c       21 Apr 2022 12:50:04 -0000
@@ -494,7 +494,9 @@ ip6_mrouter_init(struct socket *so, int 
 
        ip6_mrouter[rtableid] = so;
        ip6_mrouter_ver = cmd;
+       KERNEL_LOCK();
        mrouter6q[rtableid] = rt_timer_queue_create(MCAST_EXPIRE_TIMEOUT);
+       KERNEL_UNLOCK();
 
        return (0);
 }
@@ -544,7 +546,9 @@ ip6_mrouter_done(struct socket *so)
                ip6_mrouter_detach(ifp);
        }
 
+       KERNEL_LOCK();
        rt_timer_queue_destroy(mrouter6q[rtableid]);
+       KERNEL_UNLOCK();
        ip6_mrouter[inp->inp_rtableid] = NULL;
        ip6_mrouter_ver = 0;
        mrouter6q[rtableid] = NULL;
@@ -682,7 +686,9 @@ mf6c_add_route(struct ifnet *ifp, struct
        }
 
        rt->rt_llinfo = (caddr_t)mf6c;
+       KERNEL_LOCK();
        rt_timer_add(rt, mf6c_expire_route, mrouter6q[rtableid], rtableid);
+       KERNEL_UNLOCK();
        mf6c->mf6c_parent = mf6cc->mf6cc_parent;
        rtfree(rt);
 
@@ -1010,8 +1016,10 @@ mf6c_expire_route(struct rtentry *rt, st
 
        if (mf6c->mf6c_expire == 0) {
                mf6c->mf6c_expire = 1;
+               KERNEL_LOCK();
                rt_timer_add(rt, mf6c_expire_route, mrouter6q[rtableid],
                    rtableid);
+               KERNEL_UNLOCK();
                return;
        }
 
@@ -1272,7 +1280,9 @@ mrt6_mcast_del(struct rtentry *rt, unsig
        int error;
 
        /* Remove all timers related to this route. */
+       KERNEL_LOCK();
        rt_timer_remove_all(rt);
+       KERNEL_UNLOCK();
 
        free(rt->rt_llinfo, M_MRTABLE, sizeof(struct mf6c));
        rt->rt_llinfo = NULL;

Reply via email to