Author: markj
Date: Fri Dec 20 20:15:34 2019
New Revision: 355942
URL: https://svnweb.freebsd.org/changeset/base/355942

Log:
  Deduplicate code between if_delgroup() and if_delgroups().
  
  Fix some style in if_addgroup().  No functional change intended.
  
  Reviewed by:  hselasky
  MFC after:    2 weeks
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D22892

Modified:
  head/sys/net/if.c

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c   Fri Dec 20 20:10:26 2019        (r355941)
+++ head/sys/net/if.c   Fri Dec 20 20:15:34 2019        (r355942)
@@ -1455,14 +1455,12 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
                        return (EEXIST);
                }
 
-       if ((ifgl = (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP,
-           M_NOWAIT)) == NULL) {
+       if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL) {
                IFNET_WUNLOCK();
                return (ENOMEM);
        }
 
-       if ((ifgm = (struct ifg_member *)malloc(sizeof(struct ifg_member),
-           M_TEMP, M_NOWAIT)) == NULL) {
+       if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
                free(ifgl, M_TEMP);
                IFNET_WUNLOCK();
                return (ENOMEM);
@@ -1473,8 +1471,7 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
                        break;
 
        if (ifg == NULL) {
-               if ((ifg = (struct ifg_group *)malloc(sizeof(struct ifg_group),
-                   M_TEMP, M_NOWAIT)) == NULL) {
+               if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL) {
                        free(ifgl, M_TEMP);
                        free(ifgm, M_TEMP);
                        IFNET_WUNLOCK();
@@ -1506,39 +1503,36 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
 }
 
 /*
- * Remove a group from an interface
+ * Helper function to remove a group out of an interface.  Expects the global
+ * ifnet lock to be write-locked, and drops it before returning.
  */
-int
-if_delgroup(struct ifnet *ifp, const char *groupname)
+static void
+_if_delgroup_locked(struct ifnet *ifp, struct ifg_list *ifgl,
+    const char *groupname)
 {
-       struct ifg_list         *ifgl;
-       struct ifg_member       *ifgm;
-       int freeifgl;
+       struct ifg_member *ifgm;
+       bool freeifgl;
 
-       IFNET_WLOCK();
-       CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
-               if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
-                       break;
-       if (ifgl == NULL) {
-               IFNET_WUNLOCK();
-               return (ENOENT);
-       }
+       IFNET_WLOCK_ASSERT();
 
-       freeifgl = 0;
        IF_ADDR_WLOCK(ifp);
        CK_STAILQ_REMOVE(&ifp->if_groups, ifgl, ifg_list, ifgl_next);
        IF_ADDR_WUNLOCK(ifp);
 
-       CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
-               if (ifgm->ifgm_ifp == ifp)
+       CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) {
+               if (ifgm->ifgm_ifp == ifp) {
+                       CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm,
+                           ifg_member, ifgm_next);
                        break;
+               }
+       }
 
-       if (ifgm != NULL)
-               CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, 
ifg_member, ifgm_next);
-
        if (--ifgl->ifgl_group->ifg_refcnt == 0) {
-               CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_group, 
ifg_next);
-               freeifgl = 1;
+               CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_group,
+                   ifg_next);
+               freeifgl = true;
+       } else {
+               freeifgl = false;
        }
        IFNET_WUNLOCK();
 
@@ -1551,7 +1545,27 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
        free(ifgl, M_TEMP);
 
        EVENTHANDLER_INVOKE(group_change_event, groupname);
+}
 
+/*
+ * Remove a group from an interface
+ */
+int
+if_delgroup(struct ifnet *ifp, const char *groupname)
+{
+       struct ifg_list *ifgl;
+
+       IFNET_WLOCK();
+       CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
+               if (strcmp(ifgl->ifgl_group->ifg_group, groupname) == 0)
+                       break;
+       if (ifgl == NULL) {
+               IFNET_WUNLOCK();
+               return (ENOENT);
+       }
+
+       _if_delgroup_locked(ifp, ifgl, groupname);
+
        return (0);
 }
 
@@ -1561,45 +1575,13 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
 static void
 if_delgroups(struct ifnet *ifp)
 {
-       struct ifg_list         *ifgl;
-       struct ifg_member       *ifgm;
+       struct ifg_list *ifgl;
        char groupname[IFNAMSIZ];
-       int ifglfree;
 
        IFNET_WLOCK();
-       while (!CK_STAILQ_EMPTY(&ifp->if_groups)) {
-               ifgl = CK_STAILQ_FIRST(&ifp->if_groups);
-
+       while ((ifgl = CK_STAILQ_FIRST(&ifp->if_groups)) != NULL) {
                strlcpy(groupname, ifgl->ifgl_group->ifg_group, IFNAMSIZ);
-
-               IF_ADDR_WLOCK(ifp);
-               CK_STAILQ_REMOVE(&ifp->if_groups, ifgl, ifg_list, ifgl_next);
-               IF_ADDR_WUNLOCK(ifp);
-
-               CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, 
ifgm_next)
-                       if (ifgm->ifgm_ifp == ifp)
-                               break;
-
-               if (ifgm != NULL)
-                       CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, 
ifg_member,
-                           ifgm_next);
-               ifglfree = 0;
-               if (--ifgl->ifgl_group->ifg_refcnt == 0) {
-                       CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, 
ifg_group, ifg_next);
-                       ifglfree = 1;
-               }
-
-               IFNET_WUNLOCK();
-               epoch_wait_preempt(net_epoch_preempt);
-               free(ifgm, M_TEMP);
-               if (ifglfree) {
-                       EVENTHANDLER_INVOKE(group_detach_event,
-                                                               
ifgl->ifgl_group);
-                       free(ifgl->ifgl_group, M_TEMP);
-               }
-               free(ifgl, M_TEMP);
-               EVENTHANDLER_INVOKE(group_change_event, groupname);
-
+               _if_delgroup_locked(ifp, ifgl, groupname);
                IFNET_WLOCK();
        }
        IFNET_WUNLOCK();
@@ -1681,7 +1663,7 @@ if_getgroupmembers(struct ifgroupreq *ifgr)
 
        IFNET_RLOCK();
        CK_STAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
-               if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
+               if (strcmp(ifg->ifg_group, ifgr->ifgr_name) == 0)
                        break;
        if (ifg == NULL) {
                IFNET_RUNLOCK();
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to