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