Skip to content

Commit

Permalink
[NET]: Support multiple network namespaces with netlink
Browse files Browse the repository at this point in the history
Each netlink socket will live in exactly one network namespace,
this includes the controlling kernel sockets.

This patch updates all of the existing netlink protocols
to only support the initial network namespace.  Request
by clients in other namespaces will get -ECONREFUSED.
As they would if the kernel did not have the support for
that netlink protocol compiled in.

As each netlink protocol is updated to be multiple network
namespace safe it can register multiple kernel sockets
to acquire a presence in the rest of the network namespaces.

The implementation in af_netlink is a simple filter implementation
at hash table insertion and hash table look up time.

Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ebiederm authored and David S. Miller committed Oct 10, 2007
1 parent e9dc865 commit b4b5102
Show file tree
Hide file tree
Showing 22 changed files with 121 additions and 60 deletions.
2 changes: 1 addition & 1 deletion drivers/connector/connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ static int __devinit cn_init(void)
dev->id.idx = cn_idx;
dev->id.val = cn_val;

dev->nls = netlink_kernel_create(NETLINK_CONNECTOR,
dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
CN_NETLINK_USERS + 0xf,
dev->input, NULL, THIS_MODULE);
if (!dev->nls)
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/scsi_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ scsi_netlink_init(void)
return;
}

scsi_nl_sock = netlink_kernel_create(NETLINK_SCSITRANSPORT,
scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL,
THIS_MODULE);
if (!scsi_nl_sock) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_conn_class;

nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
THIS_MODULE);
if (!nls) {
err = -ENOBUFS;
Expand Down
2 changes: 1 addition & 1 deletion fs/ecryptfs/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ int ecryptfs_init_netlink(void)
{
int rc;

ecryptfs_nl_sock = netlink_kernel_create(NETLINK_ECRYPTFS, 0,
ecryptfs_nl_sock = netlink_kernel_create(&init_net, NETLINK_ECRYPTFS, 0,
ecryptfs_receive_nl_message,
NULL, THIS_MODULE);
if (!ecryptfs_nl_sock) {
Expand Down
6 changes: 5 additions & 1 deletion include/linux/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#define MAX_LINKS 32

struct net;

struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK */
Expand Down Expand Up @@ -157,7 +159,8 @@ struct netlink_skb_parms
#define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)


extern struct sock *netlink_kernel_create(int unit, unsigned int groups,
extern struct sock *netlink_kernel_create(struct net *net,
int unit,unsigned int groups,
void (*input)(struct sock *sk, int len),
struct mutex *cb_mutex,
struct module *module);
Expand Down Expand Up @@ -206,6 +209,7 @@ struct netlink_callback

struct netlink_notify
{
struct net *net;
int pid;
int protocol;
};
Expand Down
4 changes: 2 additions & 2 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,8 +876,8 @@ static int __init audit_init(void)

printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
audit_default ? "enabled" : "disabled");
audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
NULL, THIS_MODULE);
audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
audit_receive, NULL, THIS_MODULE);
if (!audit_sock)
audit_panic("cannot initialize netlink socket");
else
Expand Down
5 changes: 2 additions & 3 deletions lib/kobject_uevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,8 @@ EXPORT_SYMBOL_GPL(add_uevent_var);
#if defined(CONFIG_NET)
static int __init kobject_uevent_init(void)
{
uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
NULL, THIS_MODULE);

uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT,
1, NULL, NULL, THIS_MODULE);
if (!uevent_sock) {
printk(KERN_ERR
"kobject_uevent: unable to create netlink socket!\n");
Expand Down
5 changes: 3 additions & 2 deletions net/bridge/netfilter/ebt_ulog.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,9 @@ static int __init ebt_ulog_init(void)
spin_lock_init(&ulog_buffers[i].lock);
}

ebtulognl = netlink_kernel_create(NETLINK_NFLOG, EBT_ULOG_MAXNLGROUPS,
NULL, NULL, THIS_MODULE);
ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
EBT_ULOG_MAXNLGROUPS, NULL, NULL,
THIS_MODULE);
if (!ebtulognl)
ret = -ENOMEM;
else if ((ret = ebt_register_watcher(&ulog)))
Expand Down
4 changes: 2 additions & 2 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,8 +1327,8 @@ void __init rtnetlink_init(void)
if (!rta_buf)
panic("rtnetlink_init: cannot allocate rta_buf\n");

rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv,
&rtnl_mutex, THIS_MODULE);
rtnl = netlink_kernel_create(&init_net, NETLINK_ROUTE, RTNLGRP_MAX,
rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
if (rtnl == NULL)
panic("rtnetlink_init: cannot initialize rtnetlink\n");
netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
Expand Down
3 changes: 2 additions & 1 deletion net/decnet/netfilter/dn_rtmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ static int __init dn_rtmsg_init(void)
{
int rv = 0;

dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
dnrmg = netlink_kernel_create(&init_net,
NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
dnrmg_receive_user_sk, NULL, THIS_MODULE);
if (dnrmg == NULL) {
printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/fib_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,8 @@ static void nl_fib_input(struct sock *sk, int len)

static void nl_fib_lookup_init(void)
{
netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, NULL,
THIS_MODULE);
netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0, nl_fib_input,
NULL, THIS_MODULE);
}

static void fib_disable_ip(struct net_device *dev, int force)
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/inet_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,8 @@ static int __init inet_diag_init(void)
if (!inet_diag_table)
goto out;

idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv,
NULL, THIS_MODULE);
idiagnl = netlink_kernel_create(&init_net, NETLINK_INET_DIAG, 0,
inet_diag_rcv, NULL, THIS_MODULE);
if (idiagnl == NULL)
goto out_free_table;
err = 0;
Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/netfilter/ip_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ ipq_rcv_nl_event(struct notifier_block *this,
if (event == NETLINK_URELEASE &&
n->protocol == NETLINK_FIREWALL && n->pid) {
write_lock_bh(&queue_lock);
if (n->pid == peer_pid)
if ((n->net == &init_net) && (n->pid == peer_pid))
__ipq_reset();
write_unlock_bh(&queue_lock);
}
Expand Down Expand Up @@ -671,8 +671,8 @@ static int __init ip_queue_init(void)
struct proc_dir_entry *proc;

netlink_register_notifier(&ipq_nl_notifier);
ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk,
NULL, THIS_MODULE);
ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0,
ipq_rcv_sk, NULL, THIS_MODULE);
if (ipqnl == NULL) {
printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
goto cleanup_netlink_notifier;
Expand Down
3 changes: 2 additions & 1 deletion net/ipv4/netfilter/ipt_ULOG.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ static int __init ipt_ulog_init(void)
for (i = 0; i < ULOG_MAXNLGROUPS; i++)
setup_timer(&ulog_buffers[i].timer, ulog_timer, i);

nflognl = netlink_kernel_create(NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
nflognl = netlink_kernel_create(&init_net,
NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
NULL, THIS_MODULE);
if (!nflognl)
return -ENOMEM;
Expand Down
6 changes: 3 additions & 3 deletions net/ipv6/netfilter/ip6_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ ipq_rcv_nl_event(struct notifier_block *this,
if (event == NETLINK_URELEASE &&
n->protocol == NETLINK_IP6_FW && n->pid) {
write_lock_bh(&queue_lock);
if (n->pid == peer_pid)
if ((n->net == &init_net) && (n->pid == peer_pid))
__ipq_reset();
write_unlock_bh(&queue_lock);
}
Expand Down Expand Up @@ -661,8 +661,8 @@ static int __init ip6_queue_init(void)
struct proc_dir_entry *proc;

netlink_register_notifier(&ipq_nl_notifier);
ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, NULL,
THIS_MODULE);
ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, ipq_rcv_sk,
NULL, THIS_MODULE);
if (ipqnl == NULL) {
printk(KERN_ERR "ip6_queue: failed to create netlink socket\n");
goto cleanup_netlink_notifier;
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nfnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ static int __init nfnetlink_init(void)
{
printk("Netfilter messages via NETLINK v%s.\n", nfversion);

nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX,
nfnl = netlink_kernel_create(&init_net, NETLINK_NETFILTER, NFNLGRP_MAX,
nfnetlink_rcv, NULL, THIS_MODULE);
if (!nfnl) {
printk(KERN_ERR "cannot initialize nfnetlink!\n");
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/nfnetlink_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,8 @@ nfulnl_rcv_nl_event(struct notifier_block *this,

hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
UDEBUG("node = %p\n", inst);
if (n->pid == inst->peer_pid)
if ((n->net == &init_net) &&
(n->pid == inst->peer_pid))
__instance_destroy(inst);
}
}
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/nfnetlink_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,8 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
struct hlist_head *head = &instance_table[i];

hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
if (n->pid == inst->peer_pid)
if ((n->net == &init_net) &&
(n->pid == inst->peer_pid))
__instance_destroy(inst);
}
}
Expand Down
Loading

0 comments on commit b4b5102

Please sign in to comment.