Revert "net: socket ioctl to reset connections matching local address"
Use SOCK_DESTROY from now instead of SIOCKILLADDR
This reverts commit 38f0ec724f
.
Change-Id: I2dcd833b66c88a48de8978dce9d72ab78f9af549
This commit is contained in:
parent
d8c5b6f850
commit
3094efd84c
6 changed files with 1 additions and 133 deletions
|
@ -1681,8 +1681,6 @@ static inline bool tcp_stream_memory_free(const struct sock *sk)
|
|||
return notsent_bytes < tcp_notsent_lowat(tp);
|
||||
}
|
||||
|
||||
extern int tcp_nuke_addr(struct net *net, struct sockaddr *addr);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int tcp4_proc_init(void);
|
||||
void tcp4_proc_exit(void);
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
#define SIOCDIFADDR 0x8936 /* delete PA address */
|
||||
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
|
||||
#define SIOCGIFCOUNT 0x8938 /* get number of devices */
|
||||
#define SIOCKILLADDR 0x8939 /* kill sockets with this local addr */
|
||||
|
||||
#define SIOCGIFBR 0x8940 /* Bridging support */
|
||||
#define SIOCSIFBR 0x8941 /* Set bridging options */
|
||||
|
|
|
@ -886,7 +886,6 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||
case SIOCSIFPFLAGS:
|
||||
case SIOCGIFPFLAGS:
|
||||
case SIOCSIFFLAGS:
|
||||
case SIOCKILLADDR:
|
||||
err = devinet_ioctl(net, cmd, (void __user *)arg);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
|
||||
#include <net/arp.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/route.h>
|
||||
#include <net/ip_fib.h>
|
||||
#include <net/rtnetlink.h>
|
||||
|
@ -969,7 +968,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|||
case SIOCSIFBRDADDR: /* Set the broadcast address */
|
||||
case SIOCSIFDSTADDR: /* Set the destination address */
|
||||
case SIOCSIFNETMASK: /* Set the netmask for the interface */
|
||||
case SIOCKILLADDR: /* Nuke all sockets on this address */
|
||||
ret = -EPERM;
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
goto out;
|
||||
|
@ -1021,8 +1019,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|||
}
|
||||
|
||||
ret = -EADDRNOTAVAIL;
|
||||
if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS
|
||||
&& cmd != SIOCKILLADDR)
|
||||
if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
|
||||
goto done;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -1149,9 +1146,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|||
inet_insert_ifa(ifa);
|
||||
}
|
||||
break;
|
||||
case SIOCKILLADDR: /* Nuke all connections on this address */
|
||||
ret = tcp_nuke_addr(net, (struct sockaddr *) sin);
|
||||
break;
|
||||
}
|
||||
done:
|
||||
rtnl_unlock();
|
||||
|
|
105
net/ipv4/tcp.c
105
net/ipv4/tcp.c
|
@ -276,9 +276,6 @@
|
|||
#include <net/tcp.h>
|
||||
#include <net/xfrm.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ip6_route.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/transp_v6.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
@ -3254,105 +3251,3 @@ void __init tcp_init(void)
|
|||
BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
|
||||
tcp_tasklet_init();
|
||||
}
|
||||
|
||||
static int tcp_is_local(struct net *net, __be32 addr) {
|
||||
struct rtable *rt;
|
||||
struct flowi4 fl4 = { .daddr = addr };
|
||||
rt = ip_route_output_key(net, &fl4);
|
||||
if (IS_ERR_OR_NULL(rt))
|
||||
return 0;
|
||||
return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
static int tcp_is_local6(struct net *net, struct in6_addr *addr) {
|
||||
struct rt6_info *rt6 = rt6_lookup(net, addr, addr, 0, 0);
|
||||
return rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tcp_nuke_addr - destroy all sockets on the given local address
|
||||
* if local address is the unspecified address (0.0.0.0 or ::), destroy all
|
||||
* sockets with local addresses that are not configured.
|
||||
*/
|
||||
int tcp_nuke_addr(struct net *net, struct sockaddr *addr)
|
||||
{
|
||||
int family = addr->sa_family;
|
||||
unsigned int bucket;
|
||||
|
||||
struct in_addr *in;
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
struct in6_addr *in6 = NULL;
|
||||
#endif
|
||||
if (family == AF_INET) {
|
||||
in = &((struct sockaddr_in *)addr)->sin_addr;
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
} else if (family == AF_INET6) {
|
||||
in6 = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
||||
#endif
|
||||
} else {
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
for (bucket = 0; bucket < tcp_hashinfo.ehash_mask; bucket++) {
|
||||
struct hlist_nulls_node *node;
|
||||
struct sock *sk;
|
||||
spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket);
|
||||
|
||||
restart:
|
||||
spin_lock_bh(lock);
|
||||
sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) {
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT)
|
||||
continue;
|
||||
if (sock_flag(sk, SOCK_DEAD))
|
||||
continue;
|
||||
|
||||
if (family == AF_INET) {
|
||||
__be32 s4 = inet->inet_rcv_saddr;
|
||||
if (s4 == LOOPBACK4_IPV6)
|
||||
continue;
|
||||
|
||||
if (in->s_addr != s4 &&
|
||||
!(in->s_addr == INADDR_ANY &&
|
||||
!tcp_is_local(net, s4)))
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
if (family == AF_INET6) {
|
||||
struct in6_addr *s6;
|
||||
|
||||
s6 = &sk->sk_v6_rcv_saddr;
|
||||
if (ipv6_addr_type(s6) == IPV6_ADDR_MAPPED)
|
||||
continue;
|
||||
|
||||
if (!ipv6_addr_equal(in6, s6) &&
|
||||
!(ipv6_addr_equal(in6, &in6addr_any) &&
|
||||
!tcp_is_local6(net, s6)))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
sock_hold(sk);
|
||||
spin_unlock_bh(lock);
|
||||
|
||||
local_bh_disable();
|
||||
bh_lock_sock(sk);
|
||||
sk->sk_err = ETIMEDOUT;
|
||||
sk->sk_error_report(sk);
|
||||
|
||||
tcp_done(sk);
|
||||
bh_unlock_sock(sk);
|
||||
local_bh_enable();
|
||||
sock_put(sk);
|
||||
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock_bh(lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -495,21 +495,6 @@ 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;
|
||||
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;
|
||||
|
@ -533,8 +518,6 @@ 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue