mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Gao feng <gaofeng@cn.fujitsu.com>
To: containers@lists.linux-foundation.org, linux-audit@redhat.com,
	linux-kernel@vger.kernel.org
Cc: eparis@redhat.com, serge.hallyn@ubuntu.com,
	ebiederm@xmission.com, sgrubb@redhat.com, aris@redhat.com,
	matthltc@linux.vnet.ibm.com, Gao feng <gaofeng@cn.fujitsu.com>
Subject: [PATCH 04/22] netlink: Add compare function for netlink_table
Date: Wed, 19 Jun 2013 09:53:36 +0800	[thread overview]
Message-ID: <1371606834-5802-5-git-send-email-gaofeng@cn.fujitsu.com> (raw)
In-Reply-To: <1371606834-5802-1-git-send-email-gaofeng@cn.fujitsu.com>

As we know, netlink sockets are private resource of
net namespace, they can communicate with each other
only when they in the same net namespace. this works
well until we try to add namespace support for other
subsystems which use netlink.

Don't like ipv4 and route table.., it is not suited to
make these subsytems belong to net namespace, Such as
audit and crypto subsystems,they are more suitable to
user namespace.

So we must have the ability to make the netlink sockets
in same user namespace can communicate with each other.

This patch adds a new function pointer "compare" for
netlink_table, we can decide if the netlink sockets can
communicate with each other through this netlink_table
self-defined compare function.

The behavior isn't changed if we don't provide the compare
function for netlink_table.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/linux/netlink.h  |  1 +
 net/netlink/af_netlink.c | 32 ++++++++++++++++++++++++--------
 net/netlink/af_netlink.h |  1 +
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 6358da5..f78b430 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -46,6 +46,7 @@ struct netlink_kernel_cfg {
 	void		(*input)(struct sk_buff *skb);
 	struct mutex	*cb_mutex;
 	void		(*bind)(int group);
+	bool		(*compare)(struct net *net, struct sock *sk);
 };
 
 extern struct sock *__netlink_kernel_create(struct net *net, int unit,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 57ee84d..942d429 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -854,16 +854,23 @@ netlink_unlock_table(void)
 		wake_up(&nl_table_wait);
 }
 
+static bool netlink_compare(struct net *net, struct sock *sk)
+{
+	return net_eq(sock_net(sk), net);
+}
+
 static struct sock *netlink_lookup(struct net *net, int protocol, u32 portid)
 {
-	struct nl_portid_hash *hash = &nl_table[protocol].hash;
+	struct netlink_table *table = &nl_table[protocol];
+	struct nl_portid_hash *hash = &table->hash;
 	struct hlist_head *head;
 	struct sock *sk;
 
 	read_lock(&nl_table_lock);
 	head = nl_portid_hashfn(hash, portid);
 	sk_for_each(sk, head) {
-		if (net_eq(sock_net(sk), net) && (nlk_sk(sk)->portid == portid)) {
+		if (table->compare(net, sk) &&
+		    (nlk_sk(sk)->portid == portid)) {
 			sock_hold(sk);
 			goto found;
 		}
@@ -976,7 +983,8 @@ netlink_update_listeners(struct sock *sk)
 
 static int netlink_insert(struct sock *sk, struct net *net, u32 portid)
 {
-	struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
+	struct netlink_table *table = &nl_table[sk->sk_protocol];
+	struct nl_portid_hash *hash = &table->hash;
 	struct hlist_head *head;
 	int err = -EADDRINUSE;
 	struct sock *osk;
@@ -986,7 +994,8 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 portid)
 	head = nl_portid_hashfn(hash, portid);
 	len = 0;
 	sk_for_each(osk, head) {
-		if (net_eq(sock_net(osk), net) && (nlk_sk(osk)->portid == portid))
+		if (table->compare(net, osk) &&
+		    (nlk_sk(osk)->portid == portid))
 			break;
 		len++;
 	}
@@ -1183,7 +1192,8 @@ static int netlink_autobind(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
 	struct net *net = sock_net(sk);
-	struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
+	struct netlink_table *table = &nl_table[sk->sk_protocol];
+	struct nl_portid_hash *hash = &table->hash;
 	struct hlist_head *head;
 	struct sock *osk;
 	s32 portid = task_tgid_vnr(current);
@@ -1195,7 +1205,7 @@ retry:
 	netlink_table_grab();
 	head = nl_portid_hashfn(hash, portid);
 	sk_for_each(osk, head) {
-		if (!net_eq(sock_net(osk), net))
+		if (!table->compare(net, osk))
 			continue;
 		if (nlk_sk(osk)->portid == portid) {
 			/* Bind collision, search negative portid values. */
@@ -2285,6 +2295,8 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
 		if (cfg) {
 			nl_table[unit].bind = cfg->bind;
 			nl_table[unit].flags = cfg->flags;
+			if (cfg->compare)
+				nl_table[unit].compare = cfg->compare;
 		}
 		nl_table[unit].registered = 1;
 	} else {
@@ -2707,6 +2719,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
 	struct sock *s;
 	struct nl_seq_iter *iter;
+	struct net *net;
 	int i, j;
 
 	++*pos;
@@ -2714,11 +2727,12 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 	if (v == SEQ_START_TOKEN)
 		return netlink_seq_socket_idx(seq, 0);
 
+	net = seq_file_net(seq);
 	iter = seq->private;
 	s = v;
 	do {
 		s = sk_next(s);
-	} while (s && sock_net(s) != seq_file_net(seq));
+	} while (s && !nl_table[s->sk_protocol].compare(net, s));
 	if (s)
 		return s;
 
@@ -2730,7 +2744,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 		for (; j <= hash->mask; j++) {
 			s = sk_head(&hash->table[j]);
-			while (s && sock_net(s) != seq_file_net(seq))
+			while (s && !nl_table[s->sk_protocol].compare(net, s))
 				s = sk_next(s);
 			if (s) {
 				iter->link = i;
@@ -2923,6 +2937,8 @@ static int __init netlink_proto_init(void)
 		hash->shift = 0;
 		hash->mask = 0;
 		hash->rehash_time = jiffies;
+
+		nl_table[i].compare = netlink_compare;
 	}
 
 	netlink_add_usersock_entry();
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index ed85222..eaa88d1 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -73,6 +73,7 @@ struct netlink_table {
 	struct mutex		*cb_mutex;
 	struct module		*module;
 	void			(*bind)(int group);
+	bool			(*compare)(struct net *net, struct sock *sock);
 	int			registered;
 };
 
-- 
1.8.1.4


  parent reply	other threads:[~2013-06-19  1:53 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-19  1:53 [Part1 PATCH 00/22] Add namespace support for audit Gao feng
2013-06-19  1:53 ` [PATCH 01/22] Audit: change type of audit_ever_enabled to bool Gao feng
2013-06-19  1:53 ` [PATCH 02/22] Audit: remove duplicate comments Gao feng
2013-06-19  1:53 ` [PATCH 03/22] Audit: make audit kernel side netlink sock per userns Gao feng
2013-06-19  1:53 ` Gao feng [this message]
2013-06-19  1:53 ` [PATCH 05/22] Audit: implement audit self-defined compare function Gao feng
2013-06-19  1:53 ` [PATCH 06/22] Audit: make audit_skb_queue per user namespace Gao feng
2013-06-19  1:53 ` [PATCH 07/22] Audit: make audit_skb_hold_queue " Gao feng
2013-06-19  1:53 ` [PATCH 08/22] Audit: make kauditd_task " Gao feng
2013-06-19  1:53 ` [PATCH 09/22] Audit: make audit_nlk_portid per user namesapce Gao feng
2013-06-19  1:53 ` [PATCH 10/22] Audit: make audit_enabled per user namespace Gao feng
2013-06-19  1:53 ` [PATCH 11/22] Audit: make audit_ever_enabled " Gao feng
2013-06-19  1:53 ` [PATCH 12/22] Audit: make audit_initialized " Gao feng
2013-06-19  1:53 ` [PATCH 13/22] Audit: only allow init user namespace to change rate limit Gao feng
2013-06-19  1:53 ` [PATCH 14/22] Audit: only allow init user namespace to change audit_failure Gao feng
2013-06-19  1:53 ` [PATCH 15/22] Audit: only allow init user namespace to change backlog_limit Gao feng
2013-06-19  1:53 ` [PATCH 16/22] Audit: make kauditd_wait per user namespace Gao feng
2013-06-19  1:53 ` [PATCH 17/22] Audit: make audit_backlog_wait " Gao feng
2013-06-19  1:53 ` [PATCH 18/22] Audit: introduce new audit logging interface for " Gao feng
2013-06-19  1:53 ` [PATCH 19/22] Audit: pass proper user namespace to audit_log_common_recv_msg Gao feng
2013-06-19  1:53 ` [PATCH 20/22] Audit: Log audit config change in uninit user namespace Gao feng
2013-06-19  1:53 ` [PATCH 21/22] Audit: send reply message to the auditd in proper " Gao feng
2013-06-19  1:53 ` [PATCH 22/22] Audit: Allow GET,SET,USER MSG operations in uninit " Gao feng
2013-06-19 20:49 ` [Part1 PATCH 00/22] Add namespace support for audit Aristeu Rozanski
2013-06-19 20:51   ` Eric Paris
2013-06-19 21:03     ` Eric W. Biederman
2013-06-20  5:21       ` Gao feng
2013-06-20  3:02     ` Gao feng
2013-06-20  3:09       ` Gao feng
2013-06-20 22:01         ` Eric W. Biederman
2013-06-21  5:15           ` Gao feng
2013-06-24 15:02           ` Aristeu Rozanski
2013-06-24 19:03             ` Eric W. Biederman
2013-06-20 13:02       ` Eric Paris
2013-06-20 20:45         ` Serge E. Hallyn
2013-06-21  3:48         ` Gao feng
2013-06-21  9:51           ` Daniel J Walsh
2013-06-21 10:49             ` Eric W. Biederman
2013-07-04  3:30           ` Gao feng

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=1371606834-5802-5-git-send-email-gaofeng@cn.fujitsu.com \
    --to=gaofeng@cn.fujitsu.com \
    --cc=aris@redhat.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=ebiederm@xmission.com \
    --cc=eparis@redhat.com \
    --cc=linux-audit@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthltc@linux.vnet.ibm.com \
    --cc=serge.hallyn@ubuntu.com \
    --cc=sgrubb@redhat.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

all inboxes | Powered by JetHome®