The second step of merging the two switches in in_ioctl() is to split
the six ioctls in this function into two families of three and to start
disentangling them. While it is not strictly needed, it seemed cleanest
to introduce a new function analogous to what was done in in6_ioctl().
This way we have a clear separation of the two families and we can
manipulate them independently. We can easily merge them back together
later on if that is desired.

The diff below copies the boiler plate from in_ioctl() to a new function
and moves SIOCAIFADDR, SIOCDIFADDR, and SIOCSIFADDR there. The next step
will then be to actually merge the two cases per ioctl.

Index: sys/netinet/in.c
===================================================================
RCS file: /var/cvs/src/sys/netinet/in.c,v
retrieving revision 1.152
diff -u -p -r1.152 in.c
--- sys/netinet/in.c    25 May 2018 06:05:08 -0000      1.152
+++ sys/netinet/in.c    25 May 2018 06:24:30 -0000
@@ -84,6 +84,7 @@
 
 void in_socktrim(struct sockaddr_in *);
 
+int in_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *, int);
 int in_ioctl_get(u_long, caddr_t, struct ifnet *);
 void in_purgeaddr(struct ifaddr *);
 int in_addhost(struct in_ifaddr *, struct sockaddr_in *);
@@ -216,7 +217,6 @@ in_ioctl(u_long cmd, caddr_t data, struc
        struct in_aliasreq *ifra = (struct in_aliasreq *)data;
        struct sockaddr_in oldaddr;
        int error = 0;
-       int newifaddr;
 
        if (ifp == NULL)
                return (ENXIO);
@@ -230,6 +230,7 @@ in_ioctl(u_long cmd, caddr_t data, struc
        case SIOCAIFADDR:
        case SIOCDIFADDR:
        case SIOCSIFADDR:
+               return in_ioctl_change_ifaddr(cmd, data, ifp, privileged);
        case SIOCSIFNETMASK:
        case SIOCSIFDSTADDR:
        case SIOCSIFBRDADDR:
@@ -248,47 +249,6 @@ in_ioctl(u_long cmd, caddr_t data, struc
        }
 
        switch (cmd) {
-       case SIOCAIFADDR:
-       case SIOCDIFADDR:
-               if (ifra->ifra_addr.sin_family == AF_INET) {
-                       for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
-                               if ((ifa->ifa_addr->sa_family == AF_INET) &&
-                                   ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
-                                   ifra->ifra_addr.sin_addr.s_addr)
-                                       break;
-                       }
-                       ia = ifatoia(ifa);
-               }
-               if (cmd == SIOCDIFADDR && ia == NULL) {
-                       error = EADDRNOTAVAIL;
-                       goto err;
-               }
-               /* FALLTHROUGH */
-       case SIOCSIFADDR:
-               if (!privileged) {
-                       error = EPERM;
-                       goto err;
-               }
-
-               if (ia == NULL) {
-                       ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
-                       ia->ia_addr.sin_family = AF_INET;
-                       ia->ia_addr.sin_len = sizeof(ia->ia_addr);
-                       ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
-                       ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
-                       ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
-                       ia->ia_sockmask.sin_len = 8;
-                       if (ifp->if_flags & IFF_BROADCAST) {
-                               ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
-                               ia->ia_broadaddr.sin_family = AF_INET;
-                       }
-                       ia->ia_ifp = ifp;
-
-                       newifaddr = 1;
-               } else
-                       newifaddr = 0;
-               break;
-
        case SIOCSIFNETMASK:
        case SIOCSIFDSTADDR:
        case SIOCSIFBRDADDR:
@@ -342,7 +302,76 @@ in_ioctl(u_long cmd, caddr_t data, struc
                ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
                    ifra->ifra_addr.sin_addr.s_addr;
                break;
+       }
+
+err:
+       NET_UNLOCK();
+       return (error);
+}
+
+int
+in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp,
+    int privileged)
+{
+       struct ifreq *ifr = (struct ifreq *)data;
+       struct ifaddr *ifa;
+       struct in_ifaddr *ia = NULL;
+       struct in_aliasreq *ifra = (struct in_aliasreq *)data;
+       int error = 0;
+       int newifaddr;
 
+       NET_LOCK();
+
+       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+               if (ifa->ifa_addr->sa_family == AF_INET) {
+                       ia = ifatoia(ifa);
+                       break;
+               }
+       }
+
+       switch (cmd) {
+       case SIOCAIFADDR:
+       case SIOCDIFADDR:
+               if (ifra->ifra_addr.sin_family == AF_INET) {
+                       for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
+                               if ((ifa->ifa_addr->sa_family == AF_INET) &&
+                                   ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
+                                   ifra->ifra_addr.sin_addr.s_addr)
+                                       break;
+                       }
+                       ia = ifatoia(ifa);
+               }
+               if (cmd == SIOCDIFADDR && ia == NULL) {
+                       error = EADDRNOTAVAIL;
+                       goto err;
+               }
+               /* FALLTHROUGH */
+       case SIOCSIFADDR:
+               if (!privileged) {
+                       error = EPERM;
+                       goto err;
+               }
+
+               if (ia == NULL) {
+                       ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
+                       ia->ia_addr.sin_family = AF_INET;
+                       ia->ia_addr.sin_len = sizeof(ia->ia_addr);
+                       ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+                       ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
+                       ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
+                       ia->ia_sockmask.sin_len = 8;
+                       if (ifp->if_flags & IFF_BROADCAST) {
+                               ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
+                               ia->ia_broadaddr.sin_family = AF_INET;
+                       }
+                       ia->ia_ifp = ifp;
+
+                       newifaddr = 1;
+               } else
+                       newifaddr = 0;
+               break;
+       }
+       switch(cmd) {
        case SIOCSIFADDR:
                in_ifscrub(ifp, ia);
                error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), newifaddr);
@@ -399,6 +428,9 @@ in_ioctl(u_long cmd, caddr_t data, struc
                in_purgeaddr(&ia->ia_ifa);
                dohooks(ifp->if_addrhooks, 0);
                break;
+
+       default:
+               panic("invalid ioctl %lu", cmd);
        }
 
 err:

Reply via email to