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 <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
22 files changed:
dev->id.idx = cn_idx;
dev->id.val = cn_val;
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)
CN_NETLINK_USERS + 0xf,
dev->input, NULL, THIS_MODULE);
if (!dev->nls)
- 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) {
SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL,
THIS_MODULE);
if (!scsi_nl_sock) {
if (err)
goto unregister_conn_class;
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;
THIS_MODULE);
if (!nls) {
err = -ENOBUFS;
- 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) {
ecryptfs_receive_nl_message,
NULL, THIS_MODULE);
if (!ecryptfs_nl_sock) {
struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK */
struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK */
#define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)
#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);
void (*input)(struct sock *sk, int len),
struct mutex *cb_mutex,
struct module *module);
int pid;
int protocol;
};
int pid;
int protocol;
};
printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
audit_default ? "enabled" : "disabled");
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
if (!audit_sock)
audit_panic("cannot initialize netlink socket");
else
#if defined(CONFIG_NET)
static int __init kobject_uevent_init(void)
{
#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");
if (!uevent_sock) {
printk(KERN_ERR
"kobject_uevent: unable to create netlink socket!\n");
spin_lock_init(&ulog_buffers[i].lock);
}
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)))
if (!ebtulognl)
ret = -ENOMEM;
else if ((ret = ebt_register_watcher(&ulog)))
if (!rta_buf)
panic("rtnetlink_init: cannot allocate rta_buf\n");
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);
if (rtnl == NULL)
panic("rtnetlink_init: cannot initialize rtnetlink\n");
netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
- 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");
dnrmg_receive_user_sk, NULL, THIS_MODULE);
if (dnrmg == NULL) {
printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
static void nl_fib_lookup_init(void)
{
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)
}
static void fib_disable_ip(struct net_device *dev, int force)
if (!inet_diag_table)
goto out;
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;
if (idiagnl == NULL)
goto out_free_table;
err = 0;
if (event == NETLINK_URELEASE &&
n->protocol == NETLINK_FIREWALL && n->pid) {
write_lock_bh(&queue_lock);
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);
}
__ipq_reset();
write_unlock_bh(&queue_lock);
}
struct proc_dir_entry *proc;
netlink_register_notifier(&ipq_nl_notifier);
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;
if (ipqnl == NULL) {
printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
goto cleanup_netlink_notifier;
for (i = 0; i < ULOG_MAXNLGROUPS; i++)
setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
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;
NULL, THIS_MODULE);
if (!nflognl)
return -ENOMEM;
if (event == NETLINK_URELEASE &&
n->protocol == NETLINK_IP6_FW && n->pid) {
write_lock_bh(&queue_lock);
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);
}
__ipq_reset();
write_unlock_bh(&queue_lock);
}
struct proc_dir_entry *proc;
netlink_register_notifier(&ipq_nl_notifier);
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;
if (ipqnl == NULL) {
printk(KERN_ERR "ip6_queue: failed to create netlink socket\n");
goto cleanup_netlink_notifier;
{
printk("Netfilter messages via NETLINK v%s.\n", nfversion);
{
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");
nfnetlink_rcv, NULL, THIS_MODULE);
if (!nfnl) {
printk(KERN_ERR "cannot initialize nfnetlink!\n");
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
UDEBUG("node = %p\n", inst);
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);
}
}
__instance_destroy(inst);
}
}
struct hlist_head *head = &instance_table[i];
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
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);
}
}
__instance_destroy(inst);
}
}
wake_up(&nl_table_wait);
}
wake_up(&nl_table_wait);
}
-static __inline__ struct sock *netlink_lookup(int protocol, u32 pid)
+static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid)
{
struct nl_pid_hash *hash = &nl_table[protocol].hash;
struct hlist_head *head;
{
struct nl_pid_hash *hash = &nl_table[protocol].hash;
struct hlist_head *head;
read_lock(&nl_table_lock);
head = nl_pid_hashfn(hash, pid);
sk_for_each(sk, node, head) {
read_lock(&nl_table_lock);
head = nl_pid_hashfn(hash, pid);
sk_for_each(sk, node, head) {
- if (nlk_sk(sk)->pid == pid) {
+ if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) {
sock_hold(sk);
goto found;
}
sock_hold(sk);
goto found;
}
* makes sure updates are visible before bind or setsockopt return. */
}
* makes sure updates are visible before bind or setsockopt return. */
}
-static int netlink_insert(struct sock *sk, u32 pid)
+static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
{
struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
struct hlist_head *head;
{
struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
struct hlist_head *head;
head = nl_pid_hashfn(hash, pid);
len = 0;
sk_for_each(osk, node, head) {
head = nl_pid_hashfn(hash, pid);
len = 0;
sk_for_each(osk, node, head) {
- if (nlk_sk(osk)->pid == pid)
+ if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid))
struct netlink_sock *nlk;
int err = 0;
struct netlink_sock *nlk;
int err = 0;
- if (net != &init_net)
- return -EAFNOSUPPORT;
-
sock->state = SS_UNCONNECTED;
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
sock->state = SS_UNCONNECTED;
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
if (nlk->pid && !nlk->subscriptions) {
struct netlink_notify n = {
if (nlk->pid && !nlk->subscriptions) {
struct netlink_notify n = {
.protocol = sk->sk_protocol,
.pid = nlk->pid,
};
.protocol = sk->sk_protocol,
.pid = nlk->pid,
};
static int netlink_autobind(struct socket *sock)
{
struct sock *sk = sock->sk;
static int netlink_autobind(struct socket *sock)
{
struct sock *sk = sock->sk;
+ struct net *net = sk->sk_net;
struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
struct hlist_head *head;
struct sock *osk;
struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
struct hlist_head *head;
struct sock *osk;
netlink_table_grab();
head = nl_pid_hashfn(hash, pid);
sk_for_each(osk, node, head) {
netlink_table_grab();
head = nl_pid_hashfn(hash, pid);
sk_for_each(osk, node, head) {
+ if ((osk->sk_net != net))
+ continue;
if (nlk_sk(osk)->pid == pid) {
/* Bind collision, search negative pid values. */
pid = rover--;
if (nlk_sk(osk)->pid == pid) {
/* Bind collision, search negative pid values. */
pid = rover--;
}
netlink_table_ungrab();
}
netlink_table_ungrab();
- err = netlink_insert(sk, pid);
+ err = netlink_insert(sk, net, pid);
if (err == -EADDRINUSE)
goto retry;
if (err == -EADDRINUSE)
goto retry;
static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sock *sk = sock->sk;
static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sock *sk = sock->sk;
+ struct net *net = sk->sk_net;
struct netlink_sock *nlk = nlk_sk(sk);
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
int err;
struct netlink_sock *nlk = nlk_sk(sk);
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
int err;
return -EINVAL;
} else {
err = nladdr->nl_pid ?
return -EINVAL;
} else {
err = nladdr->nl_pid ?
- netlink_insert(sk, nladdr->nl_pid) :
+ netlink_insert(sk, net, nladdr->nl_pid) :
netlink_autobind(sock);
if (err)
return err;
netlink_autobind(sock);
if (err)
return err;
static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
{
int protocol = ssk->sk_protocol;
static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
{
int protocol = ssk->sk_protocol;
struct sock *sock;
struct netlink_sock *nlk;
struct sock *sock;
struct netlink_sock *nlk;
- sock = netlink_lookup(protocol, pid);
+ net = ssk->sk_net;
+ sock = netlink_lookup(net, protocol, pid);
if (!sock)
return ERR_PTR(-ECONNREFUSED);
if (!sock)
return ERR_PTR(-ECONNREFUSED);
struct netlink_broadcast_data {
struct sock *exclude_sk;
struct netlink_broadcast_data {
struct sock *exclude_sk;
u32 pid;
u32 group;
int failure;
u32 pid;
u32 group;
int failure;
!test_bit(p->group - 1, nlk->groups))
goto out;
!test_bit(p->group - 1, nlk->groups))
goto out;
+ if ((sk->sk_net != p->net))
+ goto out;
+
if (p->failure) {
netlink_overrun(sk);
goto out;
if (p->failure) {
netlink_overrun(sk);
goto out;
int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
u32 group, gfp_t allocation)
{
int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
u32 group, gfp_t allocation)
{
+ struct net *net = ssk->sk_net;
struct netlink_broadcast_data info;
struct hlist_node *node;
struct sock *sk;
struct netlink_broadcast_data info;
struct hlist_node *node;
struct sock *sk;
skb = netlink_trim(skb, allocation);
info.exclude_sk = ssk;
skb = netlink_trim(skb, allocation);
info.exclude_sk = ssk;
info.pid = pid;
info.group = group;
info.failure = 0;
info.pid = pid;
info.group = group;
info.failure = 0;
if (sk == p->exclude_sk)
goto out;
if (sk == p->exclude_sk)
goto out;
+ if (sk->sk_net != p->exclude_sk->sk_net)
+ goto out;
+
if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
!test_bit(p->group - 1, nlk->groups))
goto out;
if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
!test_bit(p->group - 1, nlk->groups))
goto out;
-netlink_kernel_create(int unit, unsigned int groups,
+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)
{
void (*input)(struct sock *sk, int len),
struct mutex *cb_mutex, struct module *module)
{
if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
return NULL;
if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
return NULL;
- if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
+ if (__netlink_create(net, sock, cb_mutex, unit) < 0)
goto out_sock_release;
if (groups < 32)
goto out_sock_release;
if (groups < 32)
if (input)
nlk_sk(sk)->data_ready = input;
if (input)
nlk_sk(sk)->data_ready = input;
- if (netlink_insert(sk, 0))
+ if (netlink_insert(sk, net, 0))
goto out_sock_release;
nlk = nlk_sk(sk);
nlk->flags |= NETLINK_KERNEL_SOCKET;
netlink_table_grab();
goto out_sock_release;
nlk = nlk_sk(sk);
nlk->flags |= NETLINK_KERNEL_SOCKET;
netlink_table_grab();
- nl_table[unit].groups = groups;
- nl_table[unit].listeners = listeners;
- nl_table[unit].cb_mutex = cb_mutex;
- nl_table[unit].module = module;
- nl_table[unit].registered = 1;
+ if (!nl_table[unit].registered) {
+ nl_table[unit].groups = groups;
+ nl_table[unit].listeners = listeners;
+ nl_table[unit].cb_mutex = cb_mutex;
+ nl_table[unit].module = module;
+ nl_table[unit].registered = 1;
+ }
netlink_table_ungrab();
return sk;
netlink_table_ungrab();
return sk;
atomic_inc(&skb->users);
cb->skb = skb;
atomic_inc(&skb->users);
cb->skb = skb;
- sk = netlink_lookup(ssk->sk_protocol, NETLINK_CB(skb).pid);
+ sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid);
if (sk == NULL) {
netlink_destroy_callback(cb);
return -ECONNREFUSED;
if (sk == NULL) {
netlink_destroy_callback(cb);
return -ECONNREFUSED;
if (!skb) {
struct sock *sk;
if (!skb) {
struct sock *sk;
- sk = netlink_lookup(in_skb->sk->sk_protocol,
+ sk = netlink_lookup(in_skb->sk->sk_net,
+ in_skb->sk->sk_protocol,
NETLINK_CB(in_skb).pid);
if (sk) {
sk->sk_err = ENOBUFS;
NETLINK_CB(in_skb).pid);
if (sk) {
sk->sk_err = ENOBUFS;
#ifdef CONFIG_PROC_FS
struct nl_seq_iter {
#ifdef CONFIG_PROC_FS
struct nl_seq_iter {
int link;
int hash_idx;
};
int link;
int hash_idx;
};
for (j = 0; j <= hash->mask; j++) {
sk_for_each(s, node, &hash->table[j]) {
for (j = 0; j <= hash->mask; j++) {
sk_for_each(s, node, &hash->table[j]) {
+ if (iter->net != s->sk_net)
+ continue;
if (off == pos) {
iter->link = i;
iter->hash_idx = j;
if (off == pos) {
iter->link = i;
iter->hash_idx = j;
if (v == SEQ_START_TOKEN)
return netlink_seq_socket_idx(seq, 0);
if (v == SEQ_START_TOKEN)
return netlink_seq_socket_idx(seq, 0);
+ iter = seq->private;
+ s = v;
+ do {
+ s = sk_next(s);
+ } while (s && (iter->net != s->sk_net));
i = iter->link;
j = iter->hash_idx + 1;
i = iter->link;
j = iter->hash_idx + 1;
for (; j <= hash->mask; j++) {
s = sk_head(&hash->table[j]);
for (; j <= hash->mask; j++) {
s = sk_head(&hash->table[j]);
+ while (s && (iter->net != s->sk_net))
+ s = sk_next(s);
if (s) {
iter->link = i;
iter->hash_idx = j;
if (s) {
iter->link = i;
iter->hash_idx = j;
seq = file->private_data;
seq->private = iter;
seq = file->private_data;
seq->private = iter;
+ iter->net = get_net(PROC_NET(inode));
+static int netlink_seq_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq = file->private_data;
+ struct nl_seq_iter *iter = seq->private;
+ put_net(iter->net);
+ return seq_release_private(inode, file);
+}
+
static const struct file_operations netlink_seq_fops = {
.owner = THIS_MODULE,
.open = netlink_seq_open,
.read = seq_read,
.llseek = seq_lseek,
static const struct file_operations netlink_seq_fops = {
.owner = THIS_MODULE,
.open = netlink_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release_private,
+ .release = netlink_seq_release,
.owner = THIS_MODULE, /* for consistency 8) */
};
.owner = THIS_MODULE, /* for consistency 8) */
};
+static int netlink_net_init(struct net *net)
+{
+#ifdef CONFIG_PROC_FS
+ if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
+ return -ENOMEM;
+#endif
+ return 0;
+}
+
+static void netlink_net_exit(struct net *net)
+{
+#ifdef CONFIG_PROC_FS
+ proc_net_remove(net, "netlink");
+#endif
+}
+
+static struct pernet_operations netlink_net_ops = {
+ .init = netlink_net_init,
+ .exit = netlink_net_exit,
+};
+
static int __init netlink_proto_init(void)
{
struct sk_buff *dummy_skb;
static int __init netlink_proto_init(void)
{
struct sk_buff *dummy_skb;
}
sock_register(&netlink_family_ops);
}
sock_register(&netlink_family_ops);
-#ifdef CONFIG_PROC_FS
- proc_net_fops_create(&init_net, "netlink", 0, &netlink_seq_fops);
-#endif
+ register_pernet_subsys(&netlink_net_ops);
/* The netlink device handler may be needed early. */
rtnetlink_init();
out:
/* The netlink device handler may be needed early. */
rtnetlink_init();
out:
netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
/* we'll bump the group number right afterwards */
netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
/* we'll bump the group number right afterwards */
- genl_sock = netlink_kernel_create(NETLINK_GENERIC, 0, genl_rcv,
- NULL, THIS_MODULE);
+ genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0,
+ genl_rcv, NULL, THIS_MODULE);
if (genl_sock == NULL)
panic("GENL: Cannot initialize generic netlink\n");
if (genl_sock == NULL)
panic("GENL: Cannot initialize generic netlink\n");
printk(KERN_INFO "Initializing XFRM netlink socket\n");
printk(KERN_INFO "Initializing XFRM netlink socket\n");
- nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
+ nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX,
xfrm_netlink_rcv, NULL, THIS_MODULE);
if (nlsk == NULL)
return -ENOMEM;
xfrm_netlink_rcv, NULL, THIS_MODULE);
if (nlsk == NULL)
return -ENOMEM;
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/selinux_netlink.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/selinux_netlink.h>
+#include <net/net_namespace.h>
static struct sock *selnl;
static struct sock *selnl;
static int __init selnl_init(void)
{
static int __init selnl_init(void)
{
- selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL, NULL,
- THIS_MODULE);
+ selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
+ SELNLGRP_MAX, NULL, NULL, THIS_MODULE);
if (selnl == NULL)
panic("SELinux: Cannot create netlink socket.");
netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
if (selnl == NULL)
panic("SELinux: Cannot create netlink socket.");
netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);