This is a small refactoring of ifioctl() which moves the ioctls that
only need a read lock into a separate function. This will simplify an
upcoming diff.

Index: sys/net/if.c
===================================================================
RCS file: /var/cvs/src/sys/net/if.c,v
retrieving revision 1.522
diff -u -p -r1.522 if.c
--- sys/net/if.c        4 Nov 2017 13:11:54 -0000       1.522
+++ sys/net/if.c        4 Nov 2017 14:27:42 -0000
@@ -138,6 +138,8 @@ void        if_slowtimo(void *);
 void   if_detached_qstart(struct ifqueue *);
 int    if_detached_ioctl(struct ifnet *, u_long, caddr_t);
 
+int    ifioctl_get(u_long, caddr_t);
+
 int    if_getgroup(caddr_t, struct ifnet *);
 int    if_getgroupmembers(caddr_t);
 int    if_getgroupattribs(caddr_t);
@@ -1804,11 +1806,8 @@ ifioctl(struct socket *so, u_long cmd, c
        int s, error = 0, oif_xflags;
        size_t bytesdone;
        unsigned short oif_flags;
-       const char *label;
 
        switch (cmd) {
-       case SIOCGIFCONF:
-               return (ifconf(cmd, data));
        case SIOCIFCREATE:
        case SIOCIFDESTROY:
                if ((error = suser(p, 0)) != 0)
@@ -1816,16 +1815,26 @@ ifioctl(struct socket *so, u_long cmd, c
                return ((cmd == SIOCIFCREATE) ?
                    if_clone_create(ifr->ifr_name, 0) :
                    if_clone_destroy(ifr->ifr_name));
-       case SIOCIFGCLONERS:
-               return (if_clone_list((struct if_clonereq *)data));
-       case SIOCGIFGMEMB:
-               return (if_getgroupmembers(data));
-       case SIOCGIFGATTR:
-               return (if_getgroupattribs(data));
        case SIOCSIFGATTR:
                if ((error = suser(p, 0)) != 0)
                        return (error);
                return (if_setgroupattribs(data));
+       case SIOCGIFCONF:
+       case SIOCGIFGMEMB:
+       case SIOCGIFGATTR:
+       case SIOCGIFFLAGS:
+       case SIOCGIFXFLAGS:
+       case SIOCGIFMETRIC:
+       case SIOCGIFMTU:
+       case SIOCGIFHARDMTU:
+       case SIOCGIFDATA:
+       case SIOCGIFDESCR:
+       case SIOCGIFRTLABEL:
+       case SIOCGIFPRIORITY:
+       case SIOCGIFRDOMAIN:
+       case SIOCGIFGROUP:
+       case SIOCGIFLLPRIO:
+               return (ifioctl_get(cmd, data));
        }
 
        ifp = ifunit(ifr->ifr_name);
@@ -1858,35 +1867,6 @@ ifioctl(struct socket *so, u_long cmd, c
                }
                break;
 
-       case SIOCGIFFLAGS:
-               ifr->ifr_flags = ifp->if_flags;
-               if (ifq_is_oactive(&ifp->if_snd))
-                       ifr->ifr_flags |= IFF_OACTIVE;
-               break;
-
-       case SIOCGIFXFLAGS:
-               ifr->ifr_flags = ifp->if_xflags & ~(IFXF_MPSAFE|IFXF_CLONED);
-               break;
-
-       case SIOCGIFMETRIC:
-               ifr->ifr_metric = ifp->if_metric;
-               break;
-
-       case SIOCGIFMTU:
-               ifr->ifr_mtu = ifp->if_mtu;
-               break;
-
-       case SIOCGIFHARDMTU:
-               ifr->ifr_hardmtu = ifp->if_hardmtu;
-               break;
-
-       case SIOCGIFDATA: {
-               struct if_data ifdata;
-               if_getdata(ifp, &ifdata);
-               error = copyout(&ifdata, ifr->ifr_data, sizeof(ifdata));
-               break;
-       }
-
        case SIOCSIFFLAGS:
                if ((error = suser(p, 0)) != 0)
                        break;
@@ -1985,12 +1965,6 @@ ifioctl(struct socket *so, u_long cmd, c
                        rtm_ifchg(ifp);
                break;
 
-       case SIOCGIFDESCR:
-               strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
-               error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
-                   &bytesdone);
-               break;
-
        case SIOCSIFDESCR:
                if ((error = suser(p, 0)) != 0)
                        break;
@@ -2002,16 +1976,6 @@ ifioctl(struct socket *so, u_long cmd, c
                }
                break;
 
-       case SIOCGIFRTLABEL:
-               if (ifp->if_rtlabelid &&
-                   (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
-                       strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
-                       error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
-                           RTLABEL_LEN, &bytesdone);
-               } else
-                       error = ENOENT;
-               break;
-
        case SIOCSIFRTLABEL:
                if ((error = suser(p, 0)) != 0)
                        break;
@@ -2023,10 +1987,6 @@ ifioctl(struct socket *so, u_long cmd, c
                }
                break;
 
-       case SIOCGIFPRIORITY:
-               ifr->ifr_metric = ifp->if_priority;
-               break;
-
        case SIOCSIFPRIORITY:
                if ((error = suser(p, 0)) != 0)
                        break;
@@ -2037,10 +1997,6 @@ ifioctl(struct socket *so, u_long cmd, c
                ifp->if_priority = ifr->ifr_metric;
                break;
 
-       case SIOCGIFRDOMAIN:
-               ifr->ifr_rdomainid = ifp->if_rdomain;
-               break;
-
        case SIOCSIFRDOMAIN:
                if ((error = suser(p, 0)) != 0)
                        break;
@@ -2057,10 +2013,6 @@ ifioctl(struct socket *so, u_long cmd, c
                        error = 0;
                break;
 
-       case SIOCGIFGROUP:
-               error = if_getgroup(data, ifp);
-               break;
-
        case SIOCDIFGROUP:
                if ((error = suser(p, 0)))
                        break;
@@ -2100,10 +2052,6 @@ ifioctl(struct socket *so, u_long cmd, c
                        ifnewlladdr(ifp);
                break;
 
-       case SIOCGIFLLPRIO:
-               ifr->ifr_llprio = ifp->if_llprio;
-               break;
-
        case SIOCSIFLLPRIO:
                if ((error = suser(p, 0)))
                        break;
@@ -2142,6 +2090,101 @@ ifioctl(struct socket *so, u_long cmd, c
 
        if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
                getmicrotime(&ifp->if_lastchange);
+
+       return (error);
+}
+
+int
+ifioctl_get(u_long cmd, caddr_t data)
+{
+       struct ifnet *ifp;
+       struct ifreq *ifr = (struct ifreq *)data;
+       char ifdescrbuf[IFDESCRSIZE];
+       char ifrtlabelbuf[RTLABEL_LEN];
+       int error = 0;
+       size_t bytesdone;
+       const char *label;
+
+       switch(cmd) {
+       case SIOCGIFCONF:
+               return (ifconf(cmd, data));
+       case SIOCIFGCLONERS:
+               return (if_clone_list((struct if_clonereq *)data));
+       case SIOCGIFGMEMB:
+               return (if_getgroupmembers(data));
+       case SIOCGIFGATTR:
+               return (if_getgroupattribs(data));
+       }
+
+       ifp = ifunit(ifr->ifr_name);
+       if (ifp == NULL)
+               return (ENXIO);
+
+       switch(cmd) {
+       case SIOCGIFFLAGS:
+               ifr->ifr_flags = ifp->if_flags;
+               if (ifq_is_oactive(&ifp->if_snd))
+                       ifr->ifr_flags |= IFF_OACTIVE;
+               break;
+
+       case SIOCGIFXFLAGS:
+               ifr->ifr_flags = ifp->if_xflags & ~(IFXF_MPSAFE|IFXF_CLONED);
+               break;
+
+       case SIOCGIFMETRIC:
+               ifr->ifr_metric = ifp->if_metric;
+               break;
+
+       case SIOCGIFMTU:
+               ifr->ifr_mtu = ifp->if_mtu;
+               break;
+
+       case SIOCGIFHARDMTU:
+               ifr->ifr_hardmtu = ifp->if_hardmtu;
+               break;
+
+       case SIOCGIFDATA: {
+               struct if_data ifdata;
+               if_getdata(ifp, &ifdata);
+               error = copyout(&ifdata, ifr->ifr_data, sizeof(ifdata));
+               break;
+       }
+
+       case SIOCGIFDESCR:
+               strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
+               error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
+                   &bytesdone);
+               break;
+
+       case SIOCGIFRTLABEL:
+               if (ifp->if_rtlabelid &&
+                   (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
+                       strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
+                       error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
+                           RTLABEL_LEN, &bytesdone);
+               } else
+                       error = ENOENT;
+               break;
+
+       case SIOCGIFPRIORITY:
+               ifr->ifr_metric = ifp->if_priority;
+               break;
+
+       case SIOCGIFRDOMAIN:
+               ifr->ifr_rdomainid = ifp->if_rdomain;
+               break;
+
+       case SIOCGIFGROUP:
+               error = if_getgroup(data, ifp);
+               break;
+
+       case SIOCGIFLLPRIO:
+               ifr->ifr_llprio = ifp->if_llprio;
+               break;
+
+       default:
+               panic("invalid ioctl %lu", cmd);
+       }
 
        return (error);
 }

Reply via email to