ifioctl() contains two fallthrough paths that end up in ifp->if_ioctl().
The diff below merges them.

But instead of calling ifp->if_ioctl() from inside in{,6}_ioctl(), I
changed the logic to return EOPNOTSUPP.  The idea is that if_ioctl()
is part of the driver and will need a different lock than the address
layers.

Along the way I unified the error codes returned when `ifp' is NULL.
Note that this should never happen in in{,6}_ioctl(), but that's a
different crusade.

Comments, oks?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.521
diff -u -p -r1.521 if.c
--- net/if.c    31 Oct 2017 22:05:12 -0000      1.521
+++ net/if.c    1 Nov 2017 17:13:26 -0000
@@ -1985,30 +1985,6 @@ ifioctl(struct socket *so, u_long cmd, c
                        rtm_ifchg(ifp);
                break;
 
-       case SIOCDIFPHYADDR:
-       case SIOCSLIFPHYADDR:
-       case SIOCSLIFPHYRTABLE:
-       case SIOCSLIFPHYTTL:
-       case SIOCADDMULTI:
-       case SIOCDELMULTI:
-       case SIOCSIFMEDIA:
-       case SIOCSVNETID:
-       case SIOCSIFPAIR:
-       case SIOCSIFPARENT:
-       case SIOCDIFPARENT:
-               if ((error = suser(p, 0)) != 0)
-                       break;
-               /* FALLTHROUGH */
-       case SIOCGLIFPHYADDR:
-       case SIOCGLIFPHYRTABLE:
-       case SIOCGLIFPHYTTL:
-       case SIOCGIFMEDIA:
-       case SIOCGVNETID:
-       case SIOCGIFPAIR:
-       case SIOCGIFPARENT:
-               error = (*ifp->if_ioctl)(ifp, cmd, data);
-               break;
-
        case SIOCGIFDESCR:
                strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
                error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
@@ -2138,10 +2114,26 @@ ifioctl(struct socket *so, u_long cmd, c
                ifp->if_llprio = ifr->ifr_llprio;
                break;
 
+       case SIOCDIFPHYADDR:
+       case SIOCSLIFPHYADDR:
+       case SIOCSLIFPHYRTABLE:
+       case SIOCSLIFPHYTTL:
+       case SIOCADDMULTI:
+       case SIOCDELMULTI:
+       case SIOCSIFMEDIA:
+       case SIOCSVNETID:
+       case SIOCSIFPAIR:
+       case SIOCSIFPARENT:
+       case SIOCDIFPARENT:
+               if ((error = suser(p, 0)) != 0)
+                       break;
+               /* FALLTHROUGH */
        default:
                error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
                        (struct mbuf *) cmd, (struct mbuf *) data,
                        (struct mbuf *) ifp, p));
+               if (error == EOPNOTSUPP)
+                       error = ((*ifp->if_ioctl)(ifp, cmd, data));
                break;
        }
 
Index: netinet/in.c
===================================================================
RCS file: /cvs/src/sys/netinet/in.c,v
retrieving revision 1.143
diff -u -p -r1.143 in.c
--- netinet/in.c        24 Oct 2017 09:30:15 -0000      1.143
+++ netinet/in.c        1 Nov 2017 17:13:26 -0000
@@ -213,7 +213,7 @@ in_ioctl(u_long cmd, caddr_t data, struc
        int newifaddr;
 
        if (ifp == NULL)
-               return (EOPNOTSUPP);
+               return (ENXIO);
 
        NET_ASSERT_LOCKED();
 
@@ -393,8 +393,7 @@ in_ioctl(u_long cmd, caddr_t data, struc
                break;
 
        default:
-               error = ((*ifp->if_ioctl)(ifp, cmd, data));
-               return (error);
+               return (EOPNOTSUPP);
        }
        return (0);
 }
Index: netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.216
diff -u -p -r1.216 in6.c
--- netinet6/in6.c      26 Oct 2017 15:05:41 -0000      1.216
+++ netinet6/in6.c      1 Nov 2017 17:13:26 -0000
@@ -207,10 +207,11 @@ in6_ioctl(u_long cmd, caddr_t data, stru
        struct  in6_ifaddr *ia6 = NULL;
        struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
        struct sockaddr_in6 *sa6;
-       int error;
 
        if (ifp == NULL)
-               return (EOPNOTSUPP);
+               return (ENXIO);
+
+       NET_ASSERT_LOCKED();
 
        switch (cmd) {
        case SIOCGIFINFO_IN6:
@@ -249,7 +250,7 @@ in6_ioctl(u_long cmd, caddr_t data, stru
                 * Do not pass those ioctl to driver handler since they are not
                 * properly setup. Instead just error out.
                 */
-               return (EOPNOTSUPP);
+               return (EINVAL);
        default:
                sa6 = NULL;
                break;
@@ -311,7 +312,6 @@ in6_ioctl(u_long cmd, caddr_t data, stru
        }
 
        switch (cmd) {
-
        case SIOCGIFDSTADDR_IN6:
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                        return (EINVAL);
@@ -454,8 +454,7 @@ in6_ioctl(u_long cmd, caddr_t data, stru
                break;
 
        default:
-               error = ((*ifp->if_ioctl)(ifp, cmd, data));
-               return (error);
+               return (EOPNOTSUPP);
        }
 
        return (0);

Reply via email to