From: Lorenzo Colitti <lorenzo@google.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, hannes@stressinduktion.org,
eric.dumazet@gmail.com, ek@google.com, tom@herbertland.com,
zenczykowski@gmail.com, Lorenzo Colitti <lorenzo@google.com>
Subject: [PATCH v5 1/4] net: diag: Add the ability to destroy a socket.
Date: Tue, 15 Dec 2015 02:29:54 +0900 [thread overview]
Message-ID: <1450114197-73779-2-git-send-email-lorenzo@google.com> (raw)
In-Reply-To: <1450114197-73779-1-git-send-email-lorenzo@google.com>
This adds a diag_destroy pointer to struct proto that allows a
socket to be administratively closed without any action from the
process owning the socket or the socket protocol.
This allows a privileged userspace process, such as a connection
manager or system administration tool, to close sockets belonging
to other apps when the network they were established on has
disconnected. It is needed on laptops and mobile hosts to ensure
that network switches / disconnects do not result in applications
being blocked for long periods of time (minutes) in read or
connect calls on TCP sockets that will never succeed because the
IP address they are bound to is no longer on the system. Closing
the sockets causes these calls to fail fast and allows the apps
to reconnect on another network.
For many years Android kernels have supported this via an
out-of-tree SIOCKILLADDR ioctl that is called on every
RTM_DELADDR event, but this solution is cleaner, more robust and
more flexible: the connection manager can iterate over all
connections on the deleted IP address and close all of them. It
can also be used to close all sockets opened by a given app
process, for example if the user has restricted that app from
using the network.
It also allows in-kernel callers to perform the same sort of
operation by invoking sk->sk_prot->diag_destroy(sk) directly.
This patch adds a SOCK_DESTROY operation, a destroy function
pointer to sock_diag_handler, and a diag_destroy function
pointer. It does not include any implementation code.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/linux/sock_diag.h | 2 ++
include/net/sock.h | 1 +
include/uapi/linux/sock_diag.h | 1 +
net/core/sock_diag.c | 23 ++++++++++++++++++++---
4 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index fddebc6..15072fc 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -15,6 +15,7 @@ struct sock_diag_handler {
__u8 family;
int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh);
int (*get_info)(struct sk_buff *skb, struct sock *sk);
+ int (*destroy)(struct sk_buff *skb, struct nlmsghdr *nlh);
};
int sock_diag_register(const struct sock_diag_handler *h);
@@ -68,4 +69,5 @@ bool sock_diag_has_destroy_listeners(const struct sock *sk)
}
void sock_diag_broadcast_destroy(struct sock *sk);
+int sock_diag_destroy(struct sock *sk);
#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index 0ca22b0..a1b30d7f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1060,6 +1060,7 @@ struct proto {
void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
+ int (*diag_destroy)(struct sock *sk);
};
int proto_register(struct proto *prot, int alloc_slab);
diff --git a/include/uapi/linux/sock_diag.h b/include/uapi/linux/sock_diag.h
index 49230d3..bae2d80 100644
--- a/include/uapi/linux/sock_diag.h
+++ b/include/uapi/linux/sock_diag.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#define SOCK_DIAG_BY_FAMILY 20
+#define SOCK_DESTROY 21
struct sock_diag_req {
__u8 sdiag_family;
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index 0c1d58d..967d89f 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -214,7 +214,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld)
}
EXPORT_SYMBOL_GPL(sock_diag_unregister);
-static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
{
int err;
struct sock_diag_req *req = nlmsg_data(nlh);
@@ -234,8 +234,12 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
hndl = sock_diag_handlers[req->sdiag_family];
if (hndl == NULL)
err = -ENOENT;
- else
+ else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY)
err = hndl->dump(skb, nlh);
+ else if (nlh->nlmsg_type == SOCK_DESTROY && hndl->destroy)
+ err = hndl->destroy(skb, nlh);
+ else
+ err = -EOPNOTSUPP;
mutex_unlock(&sock_diag_table_mutex);
return err;
@@ -261,7 +265,8 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return ret;
case SOCK_DIAG_BY_FAMILY:
- return __sock_diag_rcv_msg(skb, nlh);
+ case SOCK_DESTROY:
+ return __sock_diag_cmd(skb, nlh);
default:
return -EINVAL;
}
@@ -295,6 +300,18 @@ static int sock_diag_bind(struct net *net, int group)
return 0;
}
+int sock_diag_destroy(struct sock *sk)
+{
+ if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (!sk->sk_prot->diag_destroy)
+ return -EOPNOTSUPP;
+
+ return sk->sk_prot->diag_destroy(sk);
+}
+EXPORT_SYMBOL_GPL(sock_diag_destroy);
+
static int __net_init diag_net_init(struct net *net)
{
struct netlink_kernel_cfg cfg = {
--
2.6.0.rc2.230.g3dd15c0
next prev parent reply other threads:[~2015-12-14 17:30 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-18 1:43 Add a SOCK_DESTROY operation to close sockets from userspace Lorenzo Colitti
2015-11-18 1:43 ` [PATCH 1/4] net: diag: split inet_diag_dump_one_icsk into two Lorenzo Colitti
2015-11-18 1:43 ` [PATCH 2/4] net: diag: Add the ability to destroy a socket from userspace Lorenzo Colitti
2015-11-18 1:43 ` [PATCH 3/4] net: diag: Support SOCK_DESTROY for inet sockets Lorenzo Colitti
2015-11-18 1:43 ` [PATCH 4/4] net: diag: Support destroying TCP sockets Lorenzo Colitti
2015-11-18 3:43 ` kbuild test robot
2015-11-18 4:46 ` Lorenzo Colitti
2015-11-18 4:25 ` kbuild test robot
2015-11-18 3:27 ` Add a SOCK_DESTROY operation to close sockets from userspace Stephen Hemminger
[not found] ` <CAAedzxqiXnKzCyevNipNnXEc_+TEjnVphLfseTo4ykZ8SAVt_w@mail.gmail.com>
2015-11-18 3:36 ` Erik Kline
2015-11-18 3:57 ` Maciej Żenczykowski
2015-11-18 11:56 ` David Laight
2015-11-18 4:04 ` Eric Dumazet
2015-11-18 10:19 ` Hannes Frederic Sowa
2015-11-18 10:47 ` Lorenzo Colitti
2015-11-18 11:19 ` Hannes Frederic Sowa
2015-11-18 12:54 ` Eric Dumazet
2015-11-18 13:04 ` Lorenzo Colitti
2015-11-18 13:31 ` Hannes Frederic Sowa
2015-11-18 14:45 ` Lorenzo Colitti
2015-11-18 14:56 ` Hannes Frederic Sowa
2015-11-18 15:16 ` Eric Dumazet
2015-11-18 15:32 ` Hannes Frederic Sowa
2015-11-18 15:33 ` Hannes Frederic Sowa
2015-11-18 20:35 ` David Miller
2015-11-18 20:43 ` Hannes Frederic Sowa
2015-11-19 3:49 ` David Miller
2015-11-19 5:12 ` Tom Herbert
2015-11-19 15:54 ` Hannes Frederic Sowa
2015-11-19 23:54 ` Maciej Żenczykowski
2015-11-19 5:13 ` Lorenzo Colitti
2015-11-19 5:53 ` David Miller
2015-11-19 7:19 ` Maciej Żenczykowski
2015-11-19 15:48 ` David Miller
2015-11-19 16:19 ` Eric Dumazet
2015-11-19 16:33 ` David Miller
2015-11-19 16:43 ` Eric Dumazet
2015-11-19 16:50 ` David Miller
2015-11-19 16:47 ` Eric Dumazet
2015-11-19 17:02 ` David Miller
2015-11-19 17:44 ` Eric Dumazet
2015-11-19 22:55 ` Lorenzo Colitti
2015-11-19 17:08 ` Hannes Frederic Sowa
2015-11-19 17:38 ` Tom Herbert
2015-11-19 18:09 ` David Miller
2015-11-19 18:27 ` Hannes Frederic Sowa
2015-11-19 23:02 ` Hannes Frederic Sowa
2015-11-19 23:47 ` Lorenzo Colitti
2015-11-19 22:33 ` Lorenzo Colitti
2015-11-19 22:38 ` Hannes Frederic Sowa
2015-11-19 23:24 ` Tom Herbert
2015-11-19 21:29 ` Tom Herbert
2015-11-19 21:41 ` Eric Dumazet
2015-11-19 21:53 ` Hannes Frederic Sowa
2015-11-19 22:04 ` Eric Dumazet
2015-11-19 22:09 ` Hannes Frederic Sowa
2015-11-19 22:15 ` Eric Dumazet
2015-11-19 22:31 ` Hannes Frederic Sowa
2015-11-19 22:36 ` Eric Dumazet
2015-11-19 21:53 ` Tom Herbert
2015-11-19 22:07 ` Eric Dumazet
2015-11-19 22:14 ` Tom Herbert
2015-11-19 22:33 ` Eric Dumazet
2015-11-20 0:04 ` Tom Herbert
2015-11-20 0:09 ` Lorenzo Colitti
2015-11-20 0:15 ` Tom Herbert
2015-11-20 2:25 ` Maciej Żenczykowski
2015-12-01 2:32 ` Lorenzo Colitti
2015-12-01 2:32 ` [PATCH v3 1/4] net: diag: split inet_diag_dump_one_icsk into two Lorenzo Colitti
2015-12-01 2:32 ` [PATCH v3 2/4] net: diag: Add the ability to destroy a socket from userspace Lorenzo Colitti
2015-12-01 2:32 ` [PATCH v3 3/4] net: diag: Support SOCK_DESTROY for inet sockets Lorenzo Colitti
2015-12-01 2:32 ` [PATCH v3 4/4] net: diag: Support destroying TCP sockets Lorenzo Colitti
2015-12-01 6:23 ` kbuild test robot
2015-12-01 7:12 ` Lorenzo Colitti
2015-12-01 2:53 ` Add a SOCK_DESTROY operation to close sockets from userspace Tom Herbert
2015-12-02 15:18 ` Lorenzo Colitti
2015-12-02 16:12 ` Tom Herbert
2015-12-02 16:30 ` Lorenzo Colitti
2015-12-02 17:09 ` Tom Herbert
2015-12-14 17:29 ` Lorenzo Colitti
2015-12-14 17:29 ` Lorenzo Colitti [this message]
2015-12-14 17:29 ` [PATCH v5 2/4] net: diag: split inet_diag_dump_one_icsk into two Lorenzo Colitti
2015-12-14 17:29 ` [PATCH v5 3/4] net: diag: Support SOCK_DESTROY for inet sockets Lorenzo Colitti
2015-12-14 17:29 ` [PATCH v5 4/4] net: diag: Support destroying TCP sockets Lorenzo Colitti
2015-12-14 17:51 ` kbuild test robot
2015-12-14 17:52 ` Tom Herbert
2015-12-14 18:03 ` Eric Dumazet
2015-12-14 19:37 ` David Miller
2015-12-15 17:17 ` [PATCH v5 4/4] net: diag: Support destroying TCP socketsr Lorenzo Colitti
2015-12-15 17:17 ` [PATCH v6 1/4] net: diag: split inet_diag_dump_one_icsk into two Lorenzo Colitti
2015-12-15 17:44 ` Eric Dumazet
2015-12-15 17:17 ` [PATCH v6 2/4] net: diag: Add the ability to destroy a socket Lorenzo Colitti
2015-12-15 17:44 ` Eric Dumazet
2015-12-15 17:17 ` [PATCH v6 3/4] net: diag: Support SOCK_DESTROY for inet sockets Lorenzo Colitti
2015-12-15 17:45 ` Eric Dumazet
2015-12-15 17:17 ` [PATCH v6 4/4] net: diag: Support destroying TCP sockets Lorenzo Colitti
2015-12-15 17:46 ` Eric Dumazet
2015-12-15 18:36 ` [PATCH v5 4/4] net: diag: Support destroying TCP socketsr Maciej Żenczykowski
2015-12-15 18:46 ` Rustad, Mark D
2015-12-15 18:38 ` David Miller
2015-11-20 0:12 ` Add a SOCK_DESTROY operation to close sockets from userspace Maciej Żenczykowski
2015-11-20 0:19 ` Lorenzo Colitti
2015-11-20 0:55 ` David Miller
2015-11-20 1:00 ` Maciej Żenczykowski
2015-11-20 1:55 ` Lorenzo Colitti
2015-11-20 16:51 ` David Ahern
2015-11-18 3:56 ` Tom Herbert
2015-11-18 4:23 ` Lorenzo Colitti
2015-11-18 4:31 ` Tom Herbert
2015-11-18 10:12 ` Hannes Frederic Sowa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1450114197-73779-2-git-send-email-lorenzo@google.com \
--to=lorenzo@google.com \
--cc=davem@davemloft.net \
--cc=ek@google.com \
--cc=eric.dumazet@gmail.com \
--cc=hannes@stressinduktion.org \
--cc=netdev@vger.kernel.org \
--cc=tom@herbertland.com \
--cc=zenczykowski@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).