The branch main has been updated by mjg:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3a01a97d23a27cb522b3e9de5d95b825f421cf9b

commit 3a01a97d23a27cb522b3e9de5d95b825f421cf9b
Author:     Mateusz Guzik <m...@freebsd.org>
AuthorDate: 2023-02-17 11:23:35 +0000
Commit:     Mateusz Guzik <m...@freebsd.org>
CommitDate: 2023-02-23 13:35:44 +0000

    mroute: partially sanitize the file
    
    There is rampant inconsistent formatting all around, make it mostly
    style(9)-conformant.
    
    While here:
    - drop malloc casts
    - rename a rw lock from mroute_mtx to mroute_lock
    - replace NOTREACHED comment with __assert_unreachable
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D38652
---
 sys/netinet/ip_mroute.c | 2783 +++++++++++++++++++++++------------------------
 1 file changed, 1387 insertions(+), 1396 deletions(-)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 6cabef8a1b16..15abe168e5c2 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -143,19 +143,19 @@ static MALLOC_DEFINE(M_MRTABLE, "mroutetbl", "multicast 
forwarding cache");
  * structures.
  */
 
-static struct rwlock mrouter_mtx;
-#define        MRW_RLOCK()             rw_rlock(&mrouter_mtx)
-#define        MRW_WLOCK()             rw_wlock(&mrouter_mtx)
-#define        MRW_RUNLOCK()   rw_runlock(&mrouter_mtx)
-#define        MRW_WUNLOCK()   rw_wunlock(&mrouter_mtx)
-#define        MRW_UNLOCK()    rw_unlock(&mrouter_mtx)
-#define        MRW_LOCK_ASSERT()       rw_assert(&mrouter_mtx, RA_LOCKED)
-#define        MRW_WLOCK_ASSERT()      rw_assert(&mrouter_mtx, RA_WLOCKED)
-#define        MRW_LOCK_TRY_UPGRADE()  rw_try_upgrade(&mrouter_mtx)
-#define        MRW_WOWNED()    rw_wowned(&mrouter_mtx)
+static struct rwlock mrouter_lock;
+#define        MRW_RLOCK()             rw_rlock(&mrouter_lock)
+#define        MRW_WLOCK()             rw_wlock(&mrouter_lock)
+#define        MRW_RUNLOCK()           rw_runlock(&mrouter_lock)
+#define        MRW_WUNLOCK()           rw_wunlock(&mrouter_lock)
+#define        MRW_UNLOCK()            rw_unlock(&mrouter_lock)
+#define        MRW_LOCK_ASSERT()       rw_assert(&mrouter_lock, RA_LOCKED)
+#define        MRW_WLOCK_ASSERT()      rw_assert(&mrouter_lock, RA_WLOCKED)
+#define        MRW_LOCK_TRY_UPGRADE()  rw_try_upgrade(&mrouter_lock)
+#define        MRW_WOWNED()            rw_wowned(&mrouter_lock)
 #define        MRW_LOCK_INIT()                                         \
-       rw_init(&mrouter_mtx, "IPv4 multicast forwarding")
-#define        MRW_LOCK_DESTROY()      rw_destroy(&mrouter_mtx)
+       rw_init(&mrouter_lock, "IPv4 multicast forwarding")
+#define        MRW_LOCK_DESTROY()      rw_destroy(&mrouter_lock)
 
 static int ip_mrouter_cnt;     /* # of vnets with active mrouters */
 static int ip_mrouter_unloading; /* Allow no more V_ip_mrouter sockets */
@@ -392,7 +392,7 @@ static __inline struct mfc *
 mfc_alloc(void)
 {
        struct mfc *rt;
-       rt = (struct mfc*) malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT | M_ZERO);
+       rt = malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT | M_ZERO);
        if (rt == NULL)
                return rt;
 
@@ -412,98 +412,94 @@ mfc_alloc(void)
 static int
 X_ip_mrouter_set(struct socket *so, struct sockopt *sopt)
 {
-    int        error, optval;
-    vifi_t     vifi;
-    struct     vifctl vifc;
-    struct     mfcctl2 mfc;
-    struct     bw_upcall bw_upcall;
-    uint32_t   i;
-
-    if (so != V_ip_mrouter && sopt->sopt_name != MRT_INIT)
-       return EPERM;
-
-    error = 0;
-    switch (sopt->sopt_name) {
-    case MRT_INIT:
-       error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
-       if (error)
-           break;
-       error = ip_mrouter_init(so, optval);
-       break;
+       int error, optval;
+       vifi_t vifi;
+       struct vifctl vifc;
+       struct mfcctl2 mfc;
+       struct bw_upcall bw_upcall;
+       uint32_t i;
+
+       if (so != V_ip_mrouter && sopt->sopt_name != MRT_INIT)
+               return EPERM;
+
+       error = 0;
+       switch (sopt->sopt_name) {
+       case MRT_INIT:
+               error = sooptcopyin(sopt, &optval, sizeof optval, sizeof 
optval);
+               if (error)
+                       break;
+               error = ip_mrouter_init(so, optval);
+               break;
+       case MRT_DONE:
+               error = ip_mrouter_done();
+               break;
+       case MRT_ADD_VIF:
+               error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
+               if (error)
+                       break;
+               error = add_vif(&vifc);
+               break;
+       case MRT_DEL_VIF:
+               error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
+               if (error)
+                       break;
+               error = del_vif(vifi);
+               break;
+       case MRT_ADD_MFC:
+       case MRT_DEL_MFC:
+               /*
+                * select data size depending on API version.
+                */
+               if (sopt->sopt_name == MRT_ADD_MFC &&
+                   V_mrt_api_config & MRT_API_FLAGS_ALL) {
+                       error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl2),
+                           sizeof(struct mfcctl2));
+               } else {
+                       error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl),
+                           sizeof(struct mfcctl));
+                       bzero((caddr_t)&mfc + sizeof(struct mfcctl),
+                           sizeof(mfc) - sizeof(struct mfcctl));
+               }
+               if (error)
+                       break;
+               if (sopt->sopt_name == MRT_ADD_MFC)
+                       error = add_mfc(&mfc);
+               else
+                       error = del_mfc(&mfc);
+               break;
 
-    case MRT_DONE:
-       error = ip_mrouter_done();
-       break;
+       case MRT_ASSERT:
+               error = sooptcopyin(sopt, &optval, sizeof optval, sizeof 
optval);
+               if (error)
+                       break;
+               set_assert(optval);
+               break;
 
-    case MRT_ADD_VIF:
-       error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
-       if (error)
-           break;
-       error = add_vif(&vifc);
-       break;
+       case MRT_API_CONFIG:
+               error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
+               if (!error)
+                       error = set_api_config(&i);
+               if (!error)
+                       error = sooptcopyout(sopt, &i, sizeof i);
+               break;
 
-    case MRT_DEL_VIF:
-       error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
-       if (error)
-           break;
-       error = del_vif(vifi);
-       break;
+       case MRT_ADD_BW_UPCALL:
+       case MRT_DEL_BW_UPCALL:
+               error = sooptcopyin(sopt, &bw_upcall, sizeof bw_upcall,
+                   sizeof bw_upcall);
+               if (error)
+                       break;
+               if (sopt->sopt_name == MRT_ADD_BW_UPCALL)
+                       error = add_bw_upcall(&bw_upcall);
+               else
+                       error = del_bw_upcall(&bw_upcall);
+               break;
 
-    case MRT_ADD_MFC:
-    case MRT_DEL_MFC:
-       /*
-        * select data size depending on API version.
-        */
-       if (sopt->sopt_name == MRT_ADD_MFC &&
-               V_mrt_api_config & MRT_API_FLAGS_ALL) {
-           error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl2),
-                               sizeof(struct mfcctl2));
-       } else {
-           error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl),
-                               sizeof(struct mfcctl));
-           bzero((caddr_t)&mfc + sizeof(struct mfcctl),
-                       sizeof(mfc) - sizeof(struct mfcctl));
+       default:
+               error = EOPNOTSUPP;
+               break;
        }
-       if (error)
-           break;
-       if (sopt->sopt_name == MRT_ADD_MFC)
-           error = add_mfc(&mfc);
-       else
-           error = del_mfc(&mfc);
-       break;
-
-    case MRT_ASSERT:
-       error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
-       if (error)
-           break;
-       set_assert(optval);
-       break;
-
-    case MRT_API_CONFIG:
-       error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
-       if (!error)
-           error = set_api_config(&i);
-       if (!error)
-           error = sooptcopyout(sopt, &i, sizeof i);
-       break;
-
-    case MRT_ADD_BW_UPCALL:
-    case MRT_DEL_BW_UPCALL:
-       error = sooptcopyin(sopt, &bw_upcall, sizeof bw_upcall,
-                               sizeof bw_upcall);
-       if (error)
-           break;
-       if (sopt->sopt_name == MRT_ADD_BW_UPCALL)
-           error = add_bw_upcall(&bw_upcall);
-       else
-           error = del_bw_upcall(&bw_upcall);
-       break;
-
-    default:
-       error = EOPNOTSUPP;
-       break;
-    }
-    return error;
+       return error;
 }
 
 /*
@@ -512,31 +508,30 @@ X_ip_mrouter_set(struct socket *so, struct sockopt *sopt)
 static int
 X_ip_mrouter_get(struct socket *so, struct sockopt *sopt)
 {
-    int error;
-
-    switch (sopt->sopt_name) {
-    case MRT_VERSION:
-       error = sooptcopyout(sopt, &mrt_api_version, sizeof mrt_api_version);
-       break;
-
-    case MRT_ASSERT:
-       error = sooptcopyout(sopt, &V_pim_assert_enabled,
-           sizeof V_pim_assert_enabled);
-       break;
-
-    case MRT_API_SUPPORT:
-       error = sooptcopyout(sopt, &mrt_api_support, sizeof mrt_api_support);
-       break;
-
-    case MRT_API_CONFIG:
-       error = sooptcopyout(sopt, &V_mrt_api_config, sizeof V_mrt_api_config);
-       break;
-
-    default:
-       error = EOPNOTSUPP;
-       break;
-    }
-    return error;
+       int error;
+
+       switch (sopt->sopt_name) {
+       case MRT_VERSION:
+               error = sooptcopyout(sopt, &mrt_api_version,
+                   sizeof mrt_api_version);
+               break;
+       case MRT_ASSERT:
+               error = sooptcopyout(sopt, &V_pim_assert_enabled,
+                   sizeof V_pim_assert_enabled);
+               break;
+       case MRT_API_SUPPORT:
+               error = sooptcopyout(sopt, &mrt_api_support,
+                   sizeof mrt_api_support);
+               break;
+       case MRT_API_CONFIG:
+               error = sooptcopyout(sopt, &V_mrt_api_config,
+                   sizeof V_mrt_api_config);
+               break;
+       default:
+               error = EOPNOTSUPP;
+               break;
+       }
+       return error;
 }
 
 /*
@@ -545,30 +540,30 @@ X_ip_mrouter_get(struct socket *so, struct sockopt *sopt)
 static int
 X_mrt_ioctl(u_long cmd, caddr_t data, int fibnum __unused)
 {
-    int error = 0;
-
-    /*
-     * Currently the only function calling this ioctl routine is rtioctl_fib().
-     * Typically, only root can create the raw socket in order to execute
-     * this ioctl method, however the request might be coming from a prison
-     */
-    error = priv_check(curthread, PRIV_NETINET_MROUTE);
-    if (error)
-       return (error);
-    switch (cmd) {
-    case (SIOCGETVIFCNT):
-       error = get_vif_cnt((struct sioc_vif_req *)data);
-       break;
-
-    case (SIOCGETSGCNT):
-       error = get_sg_cnt((struct sioc_sg_req *)data);
-       break;
-
-    default:
-       error = EINVAL;
-       break;
-    }
-    return error;
+       int error;
+
+       /*
+        * Currently the only function calling this ioctl routine is 
rtioctl_fib().
+        * Typically, only root can create the raw socket in order to execute
+        * this ioctl method, however the request might be coming from a prison
+        */
+       error = priv_check(curthread, PRIV_NETINET_MROUTE);
+       if (error)
+               return (error);
+       switch (cmd) {
+       case (SIOCGETVIFCNT):
+               error = get_vif_cnt((struct sioc_vif_req *)data);
+               break;
+
+       case (SIOCGETSGCNT):
+               error = get_sg_cnt((struct sioc_sg_req *)data);
+               break;
+
+       default:
+               error = EINVAL;
+               break;
+       }
+       return error;
 }
 
 /*
@@ -577,20 +572,20 @@ X_mrt_ioctl(u_long cmd, caddr_t data, int fibnum __unused)
 static int
 get_sg_cnt(struct sioc_sg_req *req)
 {
-    struct mfc *rt;
-
-    MRW_RLOCK();
-    rt = mfc_find(&req->src, &req->grp);
-    if (rt == NULL) {
-           MRW_RUNLOCK();
-       req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;
-       return EADDRNOTAVAIL;
-    }
-    req->pktcnt = rt->mfc_pkt_cnt;
-    req->bytecnt = rt->mfc_byte_cnt;
-    req->wrong_if = rt->mfc_wrong_if;
-    MRW_RUNLOCK();
-    return 0;
+       struct mfc *rt;
+
+       MRW_RLOCK();
+       rt = mfc_find(&req->src, &req->grp);
+       if (rt == NULL) {
+               MRW_RUNLOCK();
+               req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;
+               return EADDRNOTAVAIL;
+       }
+       req->pktcnt = rt->mfc_pkt_cnt;
+       req->bytecnt = rt->mfc_byte_cnt;
+       req->wrong_if = rt->mfc_wrong_if;
+       MRW_RUNLOCK();
+       return 0;
 }
 
 /*
@@ -599,73 +594,73 @@ get_sg_cnt(struct sioc_sg_req *req)
 static int
 get_vif_cnt(struct sioc_vif_req *req)
 {
-    vifi_t vifi = req->vifi;
+       vifi_t vifi = req->vifi;
 
-    MRW_RLOCK();
-    if (vifi >= V_numvifs) {
+       MRW_RLOCK();
+       if (vifi >= V_numvifs) {
+               MRW_RUNLOCK();
+               return EINVAL;
+       }
+
+       mtx_lock_spin(&V_viftable[vifi].v_spin);
+       req->icount = V_viftable[vifi].v_pkt_in;
+       req->ocount = V_viftable[vifi].v_pkt_out;
+       req->ibytes = V_viftable[vifi].v_bytes_in;
+       req->obytes = V_viftable[vifi].v_bytes_out;
+       mtx_unlock_spin(&V_viftable[vifi].v_spin);
        MRW_RUNLOCK();
-       return EINVAL;
-    }
-
-    mtx_lock_spin(&V_viftable[vifi].v_spin);
-    req->icount = V_viftable[vifi].v_pkt_in;
-    req->ocount = V_viftable[vifi].v_pkt_out;
-    req->ibytes = V_viftable[vifi].v_bytes_in;
-    req->obytes = V_viftable[vifi].v_bytes_out;
-    mtx_unlock_spin(&V_viftable[vifi].v_spin);
-    MRW_RUNLOCK();
-
-    return 0;
+
+       return 0;
 }
 
 static void
 if_detached_event(void *arg __unused, struct ifnet *ifp)
 {
-    vifi_t vifi;
-    u_long i, vifi_cnt = 0;
-    struct ifnet *free_ptr;
+       vifi_t vifi;
+       u_long i, vifi_cnt = 0;
+       struct ifnet *free_ptr;
 
-    MRW_WLOCK();
+       MRW_WLOCK();
 
-    if (V_ip_mrouter == NULL) {
-       MRW_WUNLOCK();
-       return;
-    }
-
-    /*
-     * Tear down multicast forwarder state associated with this ifnet.
-     * 1. Walk the vif list, matching vifs against this ifnet.
-     * 2. Walk the multicast forwarding cache (mfc) looking for
-     *    inner matches with this vif's index.
-     * 3. Expire any matching multicast forwarding cache entries.
-     * 4. Free vif state. This should disable ALLMULTI on the interface.
-     */
-    for (vifi = 0; vifi < V_numvifs; vifi++) {
-       if (V_viftable[vifi].v_ifp != ifp)
-               continue;
-       for (i = 0; i < mfchashsize; i++) {
-               struct mfc *rt, *nrt;
+       if (V_ip_mrouter == NULL) {
+               MRW_WUNLOCK();
+               return;
+       }
 
-               LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) {
-                       if (rt->mfc_parent == vifi) {
-                               expire_mfc(rt);
+       /*
+        * Tear down multicast forwarder state associated with this ifnet.
+        * 1. Walk the vif list, matching vifs against this ifnet.
+        * 2. Walk the multicast forwarding cache (mfc) looking for
+        *    inner matches with this vif's index.
+        * 3. Expire any matching multicast forwarding cache entries.
+        * 4. Free vif state. This should disable ALLMULTI on the interface.
+        */
+       for (vifi = 0; vifi < V_numvifs; vifi++) {
+               if (V_viftable[vifi].v_ifp != ifp)
+                       continue;
+               for (i = 0; i < mfchashsize; i++) {
+                       struct mfc *rt, *nrt;
+
+                       LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) {
+                               if (rt->mfc_parent == vifi) {
+                                       expire_mfc(rt);
+                               }
                        }
                }
+               del_vif_locked(vifi, &free_ptr);
+               if (free_ptr != NULL)
+                       vifi_cnt++;
        }
-       del_vif_locked(vifi, &free_ptr);
-       if (free_ptr != NULL)
-               vifi_cnt++;
-    }
 
-    MRW_WUNLOCK();
+       MRW_WUNLOCK();
 
-    /*
-     * Free IFP. We don't have to use free_ptr here as it is the same
-     * that ifp. Perform free as many times as required in case
-     * refcount is greater than 1.
-     */
-    for (i = 0; i < vifi_cnt; i++)
-           if_free(ifp);
+       /*
+        * Free IFP. We don't have to use free_ptr here as it is the same
+        * that ifp. Perform free as many times as required in case
+        * refcount is greater than 1.
+        */
+       for (i = 0; i < vifi_cnt; i++)
+               if_free(ifp);
 }
 
 static void
@@ -687,55 +682,55 @@ static int
 ip_mrouter_init(struct socket *so, int version)
 {
 
-    CTR2(KTR_IPMF, "%s: so %p", __func__, so);
+       CTR2(KTR_IPMF, "%s: so %p", __func__, so);
 
-    if (version != 1)
-       return ENOPROTOOPT;
+       if (version != 1)
+               return ENOPROTOOPT;
 
-    MRW_WLOCK();
+       MRW_WLOCK();
 
-    if (ip_mrouter_unloading) {
-       MRW_WUNLOCK();
-       return ENOPROTOOPT;
-    }
+       if (ip_mrouter_unloading) {
+               MRW_WUNLOCK();
+               return ENOPROTOOPT;
+       }
 
-    if (V_ip_mrouter != NULL) {
-       MRW_WUNLOCK();
-       return EADDRINUSE;
-    }
+       if (V_ip_mrouter != NULL) {
+               MRW_WUNLOCK();
+               return EADDRINUSE;
+       }
 
-    V_mfchashtbl = hashinit_flags(mfchashsize, M_MRTABLE, &V_mfchash,
-       HASH_NOWAIT);
+       V_mfchashtbl = hashinit_flags(mfchashsize, M_MRTABLE, &V_mfchash,
+           HASH_NOWAIT);
 
-    /* Create upcall ring */
-    mtx_init(&V_bw_upcalls_ring_mtx, "mroute upcall buf_ring mtx", NULL, 
MTX_DEF);
-    V_bw_upcalls_ring = buf_ring_alloc(BW_UPCALLS_MAX, M_MRTABLE,
-       M_NOWAIT, &V_bw_upcalls_ring_mtx);
-    if (!V_bw_upcalls_ring) {
-       MRW_WUNLOCK();
-       return (ENOMEM);
-    }
+       /* Create upcall ring */
+       mtx_init(&V_bw_upcalls_ring_mtx, "mroute upcall buf_ring mtx", NULL, 
MTX_DEF);
+       V_bw_upcalls_ring = buf_ring_alloc(BW_UPCALLS_MAX, M_MRTABLE,
+           M_NOWAIT, &V_bw_upcalls_ring_mtx);
+       if (!V_bw_upcalls_ring) {
+               MRW_WUNLOCK();
+               return (ENOMEM);
+       }
 
-    TASK_INIT(&V_task, 0, ip_mrouter_upcall_thread, curvnet);
-    taskqueue_cancel(V_task_queue, &V_task, NULL);
-    taskqueue_unblock(V_task_queue);
+       TASK_INIT(&V_task, 0, ip_mrouter_upcall_thread, curvnet);
+       taskqueue_cancel(V_task_queue, &V_task, NULL);
+       taskqueue_unblock(V_task_queue);
 
-    callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls,
-       curvnet);
-    callout_reset(&V_bw_upcalls_ch, BW_UPCALLS_PERIOD, expire_bw_upcalls_send,
-       curvnet);
+       callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls,
+           curvnet);
+       callout_reset(&V_bw_upcalls_ch, BW_UPCALLS_PERIOD, 
expire_bw_upcalls_send,
+           curvnet);
 
-    V_ip_mrouter = so;
-    atomic_add_int(&ip_mrouter_cnt, 1);
+       V_ip_mrouter = so;
+       atomic_add_int(&ip_mrouter_cnt, 1);
 
-    /* This is a mutex required by buf_ring init, but not used internally */
-    mtx_init(&V_buf_ring_mtx, "mroute buf_ring mtx", NULL, MTX_DEF);
+       /* This is a mutex required by buf_ring init, but not used internally */
+       mtx_init(&V_buf_ring_mtx, "mroute buf_ring mtx", NULL, MTX_DEF);
 
-    MRW_WUNLOCK();
+       MRW_WUNLOCK();
 
-    CTR1(KTR_IPMF, "%s: done", __func__);
+       CTR1(KTR_IPMF, "%s: done", __func__);
 
-    return 0;
+       return 0;
 }
 
 /*
@@ -744,100 +739,100 @@ ip_mrouter_init(struct socket *so, int version)
 static int
 X_ip_mrouter_done(void)
 {
-    struct ifnet **ifps;
-    int nifp;
-    u_long i;
-    vifi_t vifi;
-    struct bw_upcall *bu;
-
-    if (V_ip_mrouter == NULL)
-       return (EINVAL);
-
-    /*
-     * Detach/disable hooks to the reset of the system.
-     */
-    V_ip_mrouter = NULL;
-    atomic_subtract_int(&ip_mrouter_cnt, 1);
-    V_mrt_api_config = 0;
-
-    /*
-     * Wait for all epoch sections to complete to ensure
-     * V_ip_mrouter = NULL is visible to others.
-     */
-    epoch_wait_preempt(net_epoch_preempt);
-
-    /* Stop and drain task queue */
-    taskqueue_block(V_task_queue);
-    while (taskqueue_cancel(V_task_queue, &V_task, NULL)) {
-       taskqueue_drain(V_task_queue, &V_task);
-    }
-
-    ifps = malloc(MAXVIFS * sizeof(*ifps), M_TEMP, M_WAITOK);
-
-    MRW_WLOCK();
-    taskqueue_cancel(V_task_queue, &V_task, NULL);
-
-    /* Destroy upcall ring */
-    while ((bu = buf_ring_dequeue_mc(V_bw_upcalls_ring)) != NULL) {
-       free(bu, M_MRTABLE);
-    }
-    buf_ring_free(V_bw_upcalls_ring, M_MRTABLE);
-    mtx_destroy(&V_bw_upcalls_ring_mtx);
-
-    /*
-     * For each phyint in use, prepare to disable promiscuous reception
-     * of all IP multicasts.  Defer the actual call until the lock is released;
-     * just record the list of interfaces while locked.  Some interfaces use
-     * sx locks in their ioctl routines, which is not allowed while holding
-     * a non-sleepable lock.
-     */
-    KASSERT(V_numvifs <= MAXVIFS, ("More vifs than possible"));
-    for (vifi = 0, nifp = 0; vifi < V_numvifs; vifi++) {
-       if (!in_nullhost(V_viftable[vifi].v_lcl_addr) &&
-               !(V_viftable[vifi].v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) {
-           ifps[nifp++] = V_viftable[vifi].v_ifp;
-       }
-    }
-    bzero((caddr_t)V_viftable, sizeof(*V_viftable) * MAXVIFS);
-    V_numvifs = 0;
-    V_pim_assert_enabled = 0;
-
-    callout_stop(&V_expire_upcalls_ch);
-    callout_stop(&V_bw_upcalls_ch);
-
-    /*
-     * Free all multicast forwarding cache entries.
-     * Do not use hashdestroy(), as we must perform other cleanup.
-     */
-    for (i = 0; i < mfchashsize; i++) {
-       struct mfc *rt, *nrt;
-
-       LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) {
-               expire_mfc(rt);
-       }
-    }
-    free(V_mfchashtbl, M_MRTABLE);
-    V_mfchashtbl = NULL;
-
-    bzero(V_nexpire, sizeof(V_nexpire[0]) * mfchashsize);
-
-    V_reg_vif_num = VIFI_INVALID;
-
-    mtx_destroy(&V_buf_ring_mtx);
-
-    MRW_WUNLOCK();
-
-    /*
-     * Now drop our claim on promiscuous multicast on the interfaces recorded
-     * above.  This is safe to do now because ALLMULTI is reference counted.
-     */
-    for (vifi = 0; vifi < nifp; vifi++)
-           if_allmulti(ifps[vifi], 0);
-    free(ifps, M_TEMP);
-
-    CTR1(KTR_IPMF, "%s: done", __func__);
-
-    return 0;
+       struct ifnet **ifps;
+       int nifp;
+       u_long i;
+       vifi_t vifi;
+       struct bw_upcall *bu;
+
+       if (V_ip_mrouter == NULL)
+               return (EINVAL);
+
+       /*
+        * Detach/disable hooks to the reset of the system.
+        */
+       V_ip_mrouter = NULL;
+       atomic_subtract_int(&ip_mrouter_cnt, 1);
+       V_mrt_api_config = 0;
+
+       /*
+        * Wait for all epoch sections to complete to ensure
+        * V_ip_mrouter = NULL is visible to others.
+        */
+       epoch_wait_preempt(net_epoch_preempt);
+
+       /* Stop and drain task queue */
+       taskqueue_block(V_task_queue);
+       while (taskqueue_cancel(V_task_queue, &V_task, NULL)) {
+               taskqueue_drain(V_task_queue, &V_task);
+       }
+
+       ifps = malloc(MAXVIFS * sizeof(*ifps), M_TEMP, M_WAITOK);
+
+       MRW_WLOCK();
+       taskqueue_cancel(V_task_queue, &V_task, NULL);
+
+       /* Destroy upcall ring */
+       while ((bu = buf_ring_dequeue_mc(V_bw_upcalls_ring)) != NULL) {
+               free(bu, M_MRTABLE);
+       }
+       buf_ring_free(V_bw_upcalls_ring, M_MRTABLE);
+       mtx_destroy(&V_bw_upcalls_ring_mtx);
+
+       /*
+        * For each phyint in use, prepare to disable promiscuous reception
+        * of all IP multicasts.  Defer the actual call until the lock is 
released;
+        * just record the list of interfaces while locked.  Some interfaces use
+        * sx locks in their ioctl routines, which is not allowed while holding
+        * a non-sleepable lock.
+        */
+       KASSERT(V_numvifs <= MAXVIFS, ("More vifs than possible"));
+       for (vifi = 0, nifp = 0; vifi < V_numvifs; vifi++) {
+               if (!in_nullhost(V_viftable[vifi].v_lcl_addr) &&
+                   !(V_viftable[vifi].v_flags & (VIFF_TUNNEL | 
VIFF_REGISTER))) {
+                       ifps[nifp++] = V_viftable[vifi].v_ifp;
+               }
+       }
+       bzero((caddr_t)V_viftable, sizeof(*V_viftable) * MAXVIFS);
+       V_numvifs = 0;
+       V_pim_assert_enabled = 0;
+
+       callout_stop(&V_expire_upcalls_ch);
+       callout_stop(&V_bw_upcalls_ch);
+
+       /*
+        * Free all multicast forwarding cache entries.
+        * Do not use hashdestroy(), as we must perform other cleanup.
+        */
+       for (i = 0; i < mfchashsize; i++) {
+               struct mfc *rt, *nrt;
+
+               LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) {
+                       expire_mfc(rt);
+               }
+       }
+       free(V_mfchashtbl, M_MRTABLE);
+       V_mfchashtbl = NULL;
+
+       bzero(V_nexpire, sizeof(V_nexpire[0]) * mfchashsize);
+
+       V_reg_vif_num = VIFI_INVALID;
+
+       mtx_destroy(&V_buf_ring_mtx);
+
+       MRW_WUNLOCK();
+
+       /*
+        * Now drop our claim on promiscuous multicast on the interfaces 
recorded
+        * above.  This is safe to do now because ALLMULTI is reference counted.
+        */
+       for (vifi = 0; vifi < nifp; vifi++)
+               if_allmulti(ifps[vifi], 0);
+       free(ifps, M_TEMP);
+
+       CTR1(KTR_IPMF, "%s: done", __func__);
+
+       return 0;
 }
 
 /*
@@ -846,12 +841,12 @@ X_ip_mrouter_done(void)
 static int
 set_assert(int i)
 {
-    if ((i != 1) && (i != 0))
-       return EINVAL;
+       if ((i != 1) && (i != 0))
+               return EINVAL;
 
-    V_pim_assert_enabled = i;
+       V_pim_assert_enabled = i;
 
-    return 0;
+       return 0;
 }
 
 /*
@@ -860,40 +855,40 @@ set_assert(int i)
 int
 set_api_config(uint32_t *apival)
 {
-    u_long i;
-
-    /*
-     * We can set the API capabilities only if it is the first operation
-     * after MRT_INIT. I.e.:
-     *  - there are no vifs installed
-     *  - pim_assert is not enabled
-     *  - the MFC table is empty
-     */
-    if (V_numvifs > 0) {
-       *apival = 0;
-       return EPERM;
-    }
-    if (V_pim_assert_enabled) {
-       *apival = 0;
-       return EPERM;
-    }
-
-    MRW_RLOCK();
-
-    for (i = 0; i < mfchashsize; i++) {
-       if (LIST_FIRST(&V_mfchashtbl[i]) != NULL) {
-           MRW_RUNLOCK();
-           *apival = 0;
-           return EPERM;
-       }
-    }
-
-    MRW_RUNLOCK();
-
-    V_mrt_api_config = *apival & mrt_api_support;
-    *apival = V_mrt_api_config;
-
-    return 0;
+       u_long i;
+
+       /*
+        * We can set the API capabilities only if it is the first operation
+        * after MRT_INIT. I.e.:
+        *  - there are no vifs installed
+        *  - pim_assert is not enabled
+        *  - the MFC table is empty
+        */
+       if (V_numvifs > 0) {
+               *apival = 0;
+               return EPERM;
+       }
+       if (V_pim_assert_enabled) {
+               *apival = 0;
+               return EPERM;
+       }
+
+       MRW_RLOCK();
+
+       for (i = 0; i < mfchashsize; i++) {
+               if (LIST_FIRST(&V_mfchashtbl[i]) != NULL) {
+                       MRW_RUNLOCK();
+                       *apival = 0;
+                       return EPERM;
+               }
+       }
+
+       MRW_RUNLOCK();
+
+       V_mrt_api_config = *apival & mrt_api_support;
+       *apival = V_mrt_api_config;
+
+       return 0;
 }
 
 /*
@@ -902,102 +897,101 @@ set_api_config(uint32_t *apival)
 static int
 add_vif(struct vifctl *vifcp)
 {
-    struct vif *vifp = V_viftable + vifcp->vifc_vifi;
-    struct sockaddr_in sin = {sizeof sin, AF_INET};
-    struct ifaddr *ifa;
-    struct ifnet *ifp;
-    int error;
-
-
-    if (vifcp->vifc_vifi >= MAXVIFS)
-       return EINVAL;
-    /* rate limiting is no longer supported by this code */
-    if (vifcp->vifc_rate_limit != 0) {
-       log(LOG_ERR, "rate limiting is no longer supported\n");
-       return EINVAL;
-    }
-
-    if (in_nullhost(vifcp->vifc_lcl_addr))
-       return EADDRNOTAVAIL;
-
-    /* Find the interface with an address in AF_INET family */
-    if (vifcp->vifc_flags & VIFF_REGISTER) {
-       /*
-        * XXX: Because VIFF_REGISTER does not really need a valid
-        * local interface (e.g. it could be 127.0.0.2), we don't
-        * check its address.
-        */
-       ifp = NULL;
-    } else {
-       struct epoch_tracker et;
+       struct vif *vifp = V_viftable + vifcp->vifc_vifi;
+       struct sockaddr_in sin = {sizeof sin, AF_INET};
+       struct ifaddr *ifa;
+       struct ifnet *ifp;
+       int error;
 
-       sin.sin_addr = vifcp->vifc_lcl_addr;
-       NET_EPOCH_ENTER(et);
-       ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
-       if (ifa == NULL) {
-           NET_EPOCH_EXIT(et);
-           return EADDRNOTAVAIL;
+       if (vifcp->vifc_vifi >= MAXVIFS)
+               return EINVAL;
+       /* rate limiting is no longer supported by this code */
+       if (vifcp->vifc_rate_limit != 0) {
+               log(LOG_ERR, "rate limiting is no longer supported\n");
+               return EINVAL;
+       }
+
+       if (in_nullhost(vifcp->vifc_lcl_addr))
+               return EADDRNOTAVAIL;
+
+       /* Find the interface with an address in AF_INET family */
+       if (vifcp->vifc_flags & VIFF_REGISTER) {
+               /*
+                * XXX: Because VIFF_REGISTER does not really need a valid
+                * local interface (e.g. it could be 127.0.0.2), we don't
+                * check its address.
+                */
+               ifp = NULL;
+       } else {
+               struct epoch_tracker et;
+
+               sin.sin_addr = vifcp->vifc_lcl_addr;
+               NET_EPOCH_ENTER(et);
+               ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
+               if (ifa == NULL) {
+                       NET_EPOCH_EXIT(et);
+                       return EADDRNOTAVAIL;
+               }
+               ifp = ifa->ifa_ifp;
+               /* XXX FIXME we need to take a ref on ifp and cleanup properly! 
*/
+               NET_EPOCH_EXIT(et);
+       }
+
+       if ((vifcp->vifc_flags & VIFF_TUNNEL) != 0) {
+               CTR1(KTR_IPMF, "%s: tunnels are no longer supported", __func__);
+               return EOPNOTSUPP;
+       } else if (vifcp->vifc_flags & VIFF_REGISTER) {
+               ifp = V_multicast_register_if = if_alloc(IFT_LOOP);
*** 2270 LINES SKIPPED ***

Reply via email to