aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 3c56b96b4a4b..444ed223ee43 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -102,6 +102,7 @@ struct netlink_table {
102 struct hlist_head mc_list; 102 struct hlist_head mc_list;
103 unsigned int nl_nonroot; 103 unsigned int nl_nonroot;
104 struct module *module; 104 struct module *module;
105 int registered;
105}; 106};
106 107
107static struct netlink_table *nl_table; 108static struct netlink_table *nl_table;
@@ -343,11 +344,32 @@ static struct proto netlink_proto = {
343 .obj_size = sizeof(struct netlink_sock), 344 .obj_size = sizeof(struct netlink_sock),
344}; 345};
345 346
346static int netlink_create(struct socket *sock, int protocol) 347static int __netlink_create(struct socket *sock, int protocol)
347{ 348{
348 struct sock *sk; 349 struct sock *sk;
349 struct netlink_sock *nlk; 350 struct netlink_sock *nlk;
350 struct module *module; 351
352 sock->ops = &netlink_ops;
353
354 sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
355 if (!sk)
356 return -ENOMEM;
357
358 sock_init_data(sock, sk);
359
360 nlk = nlk_sk(sk);
361 spin_lock_init(&nlk->cb_lock);
362 init_waitqueue_head(&nlk->wait);
363
364 sk->sk_destruct = netlink_sock_destruct;
365 sk->sk_protocol = protocol;
366 return 0;
367}
368
369static int netlink_create(struct socket *sock, int protocol)
370{
371 struct module *module = NULL;
372 int err = 0;
351 373
352 sock->state = SS_UNCONNECTED; 374 sock->state = SS_UNCONNECTED;
353 375
@@ -358,41 +380,33 @@ static int netlink_create(struct socket *sock, int protocol)
358 return -EPROTONOSUPPORT; 380 return -EPROTONOSUPPORT;
359 381
360 netlink_lock_table(); 382 netlink_lock_table();
361 if (!nl_table[protocol].hash.entries) {
362#ifdef CONFIG_KMOD 383#ifdef CONFIG_KMOD
363 /* We do 'best effort'. If we find a matching module, 384 if (!nl_table[protocol].registered) {
364 * it is loaded. If not, we don't return an error to
365 * allow pure userspace<->userspace communication. -HW
366 */
367 netlink_unlock_table(); 385 netlink_unlock_table();
368 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); 386 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
369 netlink_lock_table(); 387 netlink_lock_table();
370#endif
371 } 388 }
372 module = nl_table[protocol].module; 389#endif
373 if (!try_module_get(module)) 390 if (nl_table[protocol].registered &&
374 module = NULL; 391 try_module_get(nl_table[protocol].module))
392 module = nl_table[protocol].module;
393 else
394 err = -EPROTONOSUPPORT;
375 netlink_unlock_table(); 395 netlink_unlock_table();
376 396
377 sock->ops = &netlink_ops; 397 if (err)
378 398 goto out;
379 sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
380 if (!sk) {
381 module_put(module);
382 return -ENOMEM;
383 }
384
385 sock_init_data(sock, sk);
386 399
387 nlk = nlk_sk(sk); 400 if ((err = __netlink_create(sock, protocol) < 0))
401 goto out_module;
388 402
389 nlk->module = module; 403 nlk_sk(sock->sk)->module = module;
390 spin_lock_init(&nlk->cb_lock); 404out:
391 init_waitqueue_head(&nlk->wait); 405 return err;
392 sk->sk_destruct = netlink_sock_destruct;
393 406
394 sk->sk_protocol = protocol; 407out_module:
395 return 0; 408 module_put(module);
409 goto out;
396} 410}
397 411
398static int netlink_release(struct socket *sock) 412static int netlink_release(struct socket *sock)
@@ -437,6 +451,7 @@ static int netlink_release(struct socket *sock)
437 if (nlk->flags & NETLINK_KERNEL_SOCKET) { 451 if (nlk->flags & NETLINK_KERNEL_SOCKET) {
438 netlink_table_grab(); 452 netlink_table_grab();
439 nl_table[sk->sk_protocol].module = NULL; 453 nl_table[sk->sk_protocol].module = NULL;
454 nl_table[sk->sk_protocol].registered = 0;
440 netlink_table_ungrab(); 455 netlink_table_ungrab();
441 } 456 }
442 457
@@ -1082,7 +1097,7 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct
1082 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) 1097 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
1083 return NULL; 1098 return NULL;
1084 1099
1085 if (netlink_create(sock, unit) < 0) 1100 if (__netlink_create(sock, unit) < 0)
1086 goto out_sock_release; 1101 goto out_sock_release;
1087 1102
1088 sk = sock->sk; 1103 sk = sock->sk;
@@ -1098,6 +1113,7 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct
1098 1113
1099 netlink_table_grab(); 1114 netlink_table_grab();
1100 nl_table[unit].module = module; 1115 nl_table[unit].module = module;
1116 nl_table[unit].registered = 1;
1101 netlink_table_ungrab(); 1117 netlink_table_ungrab();
1102 1118
1103 return sk; 1119 return sk;