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); }