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);
|
return notsent_bytes < tcp_notsent_lowat(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int tcp_nuke_addr(struct net *net, struct sockaddr *addr);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
int tcp4_proc_init(void);
|
int tcp4_proc_init(void);
|
||||||
void tcp4_proc_exit(void);
|
void tcp4_proc_exit(void);
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
#define SIOCDIFADDR 0x8936 /* delete PA address */
|
#define SIOCDIFADDR 0x8936 /* delete PA address */
|
||||||
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
|
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
|
||||||
#define SIOCGIFCOUNT 0x8938 /* get number of devices */
|
#define SIOCGIFCOUNT 0x8938 /* get number of devices */
|
||||||
#define SIOCKILLADDR 0x8939 /* kill sockets with this local addr */
|
|
||||||
|
|
||||||
#define SIOCGIFBR 0x8940 /* Bridging support */
|
#define SIOCGIFBR 0x8940 /* Bridging support */
|
||||||
#define SIOCSIFBR 0x8941 /* Set bridging options */
|
#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 SIOCSIFPFLAGS:
|
||||||
case SIOCGIFPFLAGS:
|
case SIOCGIFPFLAGS:
|
||||||
case SIOCSIFFLAGS:
|
case SIOCSIFFLAGS:
|
||||||
case SIOCKILLADDR:
|
|
||||||
err = devinet_ioctl(net, cmd, (void __user *)arg);
|
err = devinet_ioctl(net, cmd, (void __user *)arg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
|
|
||||||
#include <net/arp.h>
|
#include <net/arp.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/tcp.h>
|
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <net/ip_fib.h>
|
#include <net/ip_fib.h>
|
||||||
#include <net/rtnetlink.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 SIOCSIFBRDADDR: /* Set the broadcast address */
|
||||||
case SIOCSIFDSTADDR: /* Set the destination address */
|
case SIOCSIFDSTADDR: /* Set the destination address */
|
||||||
case SIOCSIFNETMASK: /* Set the netmask for the interface */
|
case SIOCSIFNETMASK: /* Set the netmask for the interface */
|
||||||
case SIOCKILLADDR: /* Nuke all sockets on this address */
|
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1021,8 +1019,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = -EADDRNOTAVAIL;
|
ret = -EADDRNOTAVAIL;
|
||||||
if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS
|
if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
|
||||||
&& cmd != SIOCKILLADDR)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -1149,9 +1146,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
||||||
inet_insert_ifa(ifa);
|
inet_insert_ifa(ifa);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SIOCKILLADDR: /* Nuke all connections on this address */
|
|
||||||
ret = tcp_nuke_addr(net, (struct sockaddr *) sin);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
105
net/ipv4/tcp.c
105
net/ipv4/tcp.c
|
@ -276,9 +276,6 @@
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <net/xfrm.h>
|
#include <net/xfrm.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/ip6_route.h>
|
|
||||||
#include <net/ipv6.h>
|
|
||||||
#include <net/transp_v6.h>
|
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
@ -3254,105 +3251,3 @@ void __init tcp_init(void)
|
||||||
BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
|
BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
|
||||||
tcp_tasklet_init();
|
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);
|
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)
|
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
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);
|
return addrconf_del_ifaddr(net, (void __user *) arg);
|
||||||
case SIOCSIFDSTADDR:
|
case SIOCSIFDSTADDR:
|
||||||
return addrconf_set_dstaddr(net, (void __user *) arg);
|
return addrconf_set_dstaddr(net, (void __user *) arg);
|
||||||
case SIOCKILLADDR:
|
|
||||||
return inet6_killaddr_ioctl(net, (void __user *) arg);
|
|
||||||
default:
|
default:
|
||||||
if (!sk->sk_prot->ioctl)
|
if (!sk->sk_prot->ioctl)
|
||||||
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
||||||
|
|
Loading…
Add table
Reference in a new issue