On Wed, Nov 23, 2022 at 03:39:54PM +0300, Vitaliy Makkoveev wrote:
> Could this be merged with the following non "Mechanical move" diff?

Here's a rebased and cleaned up diff.

Feedback? Objection? OK?

---
Neighbour Discovery information is protected by the net lock, as
documented in nd6.h struct nd_ifinfo.

ndp(8) is the only SIOCGIFINFO_IN6 and SIOCGNBRINFO_IN6 user in base.

nd6_lookup(), also used in ICMP6 input and IPv6 forwarding, only needs
the net lock.

diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 44dfa3488ef..ad680278210 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -205,48 +205,48 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, 
struct ifnet *ifp)
 
        switch (cmd) {
 #ifdef MROUTING
        case SIOCGETSGCNT_IN6:
        case SIOCGETMIFCNT_IN6:
                KERNEL_LOCK();
                error = mrt6_ioctl(so, cmd, data);
                KERNEL_UNLOCK();
-               break;
+               return (error);
 #endif /* MROUTING */
        default:
-               KERNEL_LOCK();
-               error = in6_ioctl(cmd, data, ifp, privileged);
-               KERNEL_UNLOCK();
-               break;
+               return (in6_ioctl(cmd, data, ifp, privileged));
        }
-
-       return error;
 }
 
 int
 in6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
 {
+       int error;
+
        if (ifp == NULL)
                return (ENXIO);
 
        switch (cmd) {
        case SIOCGIFINFO_IN6:
        case SIOCGNBRINFO_IN6:
                return (nd6_ioctl(cmd, data, ifp));
        case SIOCGIFDSTADDR_IN6:
        case SIOCGIFNETMASK_IN6:
        case SIOCGIFAFLAG_IN6:
        case SIOCGIFALIFETIME_IN6:
                return (in6_ioctl_get(cmd, data, ifp));
        case SIOCAIFADDR_IN6:
        case SIOCDIFADDR_IN6:
                if (!privileged)
                        return (EPERM);
-               return (in6_ioctl_change_ifaddr(cmd, data, ifp));
+               KERNEL_LOCK();
+               error = in6_ioctl_change_ifaddr(cmd, data, ifp);
+               KERNEL_UNLOCK();
+               return (error);
        case SIOCSIFADDR:
        case SIOCSIFDSTADDR:
        case SIOCSIFBRDADDR:
        case SIOCSIFNETMASK:
                /*
                 * Do not pass those ioctl to driver handler since they are not
                 * properly set up. Instead just error out.
                 */
@@ -417,16 +417,17 @@ in6_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
        sa = sin6tosa(&ifr->ifr_addr);
        if (sa->sa_family == AF_INET6) {
                sa->sa_len = sizeof(struct sockaddr_in6);
                error = in6_sa2sin6(sa, &sa6);
                if (error)
                        return (error);
        }
 
+       KERNEL_LOCK();
        NET_LOCK_SHARED();
 
        if (sa6 != NULL) {
                error = in6_check_embed_scope(sa6, ifp->if_index);
                if (error)
                        goto err;
                error = in6_clear_scope_id(sa6, ifp->if_index);
                if (error)
@@ -512,16 +513,17 @@ in6_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
                break;
 
        default:
                panic("%s: invalid ioctl %lu", __func__, cmd);
        }
 
 err:
        NET_UNLOCK_SHARED();
+       KERNEL_UNLOCK();
        return (error);
 }
 
 int
 in6_check_embed_scope(struct sockaddr_in6 *sa6, unsigned int ifidx)
 {
        if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
                if (sa6->sin6_addr.s6_addr16[1] == 0) {

Reply via email to