net: Support nuking IPv6 sockets as well as IPv4.
[firefly-linux-kernel-4.4.55.git] / net / ipv6 / af_inet6.c
index 2f421a4beca750781c5be967de6a41dd3013ca27..fa743e0d32074b8cb6c029946e36e620c335c339 100644 (file)
@@ -489,6 +489,21 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
 
 EXPORT_SYMBOL(inet6_getname);
 
+int inet6_killaddr_ioctl(struct net *net, void __user *arg) {
+       struct in6_ifreq ireq;
+       struct sockaddr_in6 sin6;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EACCES;
+
+       if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
+               return -EFAULT;
+
+       sin6.sin6_family = AF_INET6;
+       ipv6_addr_copy(&sin6.sin6_addr, &ireq.ifr6_addr);
+       return tcp_nuke_addr(net, (struct sockaddr *) &sin6);
+}
+
 int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
@@ -513,6 +528,8 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return addrconf_del_ifaddr(net, (void __user *) arg);
        case SIOCSIFDSTADDR:
                return addrconf_set_dstaddr(net, (void __user *) arg);
+       case SIOCKILLADDR:
+               return inet6_killaddr_ioctl(net, (void __user *) arg);
        default:
                if (!sk->sk_prot->ioctl)
                        return -ENOIOCTLCMD;