summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2011-03-10 20:24:12 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:38:31 -0800
commitc0b779e1c5220b812c5690727fb646b731101fff (patch)
tree626e2c338338d797854490a35f646b29b421b477 /net/ipv6
parentfafc4cc382454fbf40af9263e64473ae4d955b0c (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 4eb4d74d0a96..4252b3cc183d 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;