summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2011-03-10 20:24:12 -0800
committerColin Cross <ccross@android.com>2011-06-14 09:09:56 -0700
commit810bf5db1e7aa71994907e71d05abc6cd6a6f482 (patch)
tree33da05b442c257b7019a2d56f5bdfb6022d21588 /net/ipv6
parentd31005f0522b1d85cc96a39ea4c76e5f57399429 (diff)
net: Support nuking IPv6 sockets as well as IPv4.
On Linux, when an interface goes down all its IPv6 addresses are deleted, so relying on knowing the previous IPv6 addresses on the interface is brittle. Instead, support nuking all sockets that are bound to IP addresses that are not configured and up on the system. This behaviour is triggered by specifying the unspecified address (:: or 0.0.0.0). If an IP address is specified, the behaviour is unchanged, except the ioctl now supports IPv6 as well as IPv4. Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/af_inet6.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index cd436663f23..8221871ff5c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -494,6 +494,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;
@@ -518,6 +533,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;