All interfaces define an `if_ioctl' function pointer. So do not check for it.
Change the remaining 'return' into 'break'. In SIOCSIFLLADDR change the address *after* querying the driver. This make the logic in vlan(4) work as intended. ok? Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.517 diff -u -p -r1.517 if.c --- net/if.c 16 Oct 2017 08:19:15 -0000 1.517 +++ net/if.c 16 Oct 2017 10:09:37 -0000 @@ -556,6 +556,8 @@ if_attach_queues(struct ifnet *ifp, unsi void if_attach_common(struct ifnet *ifp) { + KASSERT(ifp->if_ioctl != NULL); + TAILQ_INIT(&ifp->if_addrlist); TAILQ_INIT(&ifp->if_maddrlist); @@ -1524,11 +1526,8 @@ if_downall(void) if ((ifp->if_flags & IFF_UP) == 0) continue; if_down(ifp); - if (ifp->if_ioctl) { - ifrq.ifr_flags = ifp->if_flags; - (void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, - (caddr_t)&ifrq); - } + ifrq.ifr_flags = ifp->if_flags; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); } NET_UNLOCK(); } @@ -1913,12 +1912,10 @@ ifioctl(struct socket *so, u_long cmd, c ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (ifr->ifr_flags & ~IFF_CANTCHANGE); - if (ifp->if_ioctl != NULL) { - error = (*ifp->if_ioctl)(ifp, cmd, data); - if (error != 0) { - ifp->if_flags = oif_flags; - break; - } + error = (*ifp->if_ioctl)(ifp, cmd, data); + if (error != 0) { + ifp->if_flags = oif_flags; + break; } if (ISSET(oif_flags ^ ifp->if_flags, IFF_UP)) { @@ -2001,8 +1998,6 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFMTU: if ((error = suser(p, 0)) != 0) break; - if (ifp->if_ioctl == NULL) - return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); if (!error) rtm_ifchg(ifp); @@ -2024,7 +2019,7 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFPARENT: case SIOCDIFPARENT: if ((error = suser(p, 0)) != 0) - return (error); + break; /* FALLTHROUGH */ case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: @@ -2035,8 +2030,6 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCGVNETID: case SIOCGIFPAIR: case SIOCGIFPARENT: - if (ifp->if_ioctl == 0) - return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); break; @@ -2085,8 +2078,10 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFPRIORITY: if ((error = suser(p, 0)) != 0) break; - if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) - return (EINVAL); + if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) { + error = EINVAL; + break; + } ifp->if_priority = ifr->ifr_metric; break; @@ -2126,28 +2121,31 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFLLADDR: if ((error = suser(p, 0))) - return (error); - if (ifp->if_sadl == NULL) - return (EINVAL); - if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) - return (EINVAL); - if (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data)) - return (EINVAL); + break; + if ((ifp->if_sadl == NULL) || + (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) || + (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data))) { + error = EINVAL; + break; + } switch (ifp->if_type) { case IFT_ETHER: case IFT_CARP: case IFT_XETHER: case IFT_ISO88025: - if_setlladdr(ifp, ifr->ifr_addr.sa_data); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == ENOTTY) error = 0; + if (error == 0) + error = if_setlladdr(ifp, + ifr->ifr_addr.sa_data); break; default: - return (ENODEV); + error = ENODEV; } - ifnewlladdr(ifp); + if (error == 0) + ifnewlladdr(ifp); break; case SIOCGIFLLPRIO: @@ -2157,8 +2155,10 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFLLPRIO: if ((error = suser(p, 0))) break; - if (ifr->ifr_llprio > UCHAR_MAX) - return (EINVAL); + if (ifr->ifr_llprio > UCHAR_MAX) { + error = EINVAL; + break; + } ifp->if_llprio = ifr->ifr_llprio; break; @@ -2539,9 +2539,8 @@ if_setgroupattribs(caddr_t data) ifg->ifg_carp_demoted += demote; TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) - if (ifgm->ifgm_ifp->if_ioctl) - ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, - SIOCSIFGATTR, data); + ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, SIOCSIFGATTR, data); + return (0); }