On Thu, Apr 21, 2022 at 03:25:03PM +0200, Alexander Bluhm wrote:
> 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?

I prefer the other diff, I don't like that other diff but this one is worse.
 
> 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;
> 

-- 
:wq Claudio

Reply via email to