aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c100
1 files changed, 35 insertions, 65 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 7b7b45a19597..c41a88100fea 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -73,8 +73,12 @@ struct netlink_sock {
73 struct netlink_callback *cb; 73 struct netlink_callback *cb;
74 spinlock_t cb_lock; 74 spinlock_t cb_lock;
75 void (*data_ready)(struct sock *sk, int bytes); 75 void (*data_ready)(struct sock *sk, int bytes);
76 struct module *module;
77 u32 flags;
76}; 78};
77 79
80#define NETLINK_KERNEL_SOCKET 0x1
81
78static inline struct netlink_sock *nlk_sk(struct sock *sk) 82static inline struct netlink_sock *nlk_sk(struct sock *sk)
79{ 83{
80 return (struct netlink_sock *)sk; 84 return (struct netlink_sock *)sk;
@@ -97,7 +101,7 @@ struct netlink_table {
97 struct nl_pid_hash hash; 101 struct nl_pid_hash hash;
98 struct hlist_head mc_list; 102 struct hlist_head mc_list;
99 unsigned int nl_nonroot; 103 unsigned int nl_nonroot;
100 struct proto_ops *p_ops; 104 struct module *module;
101}; 105};
102 106
103static struct netlink_table *nl_table; 107static struct netlink_table *nl_table;
@@ -338,6 +342,7 @@ static int netlink_create(struct socket *sock, int protocol)
338{ 342{
339 struct sock *sk; 343 struct sock *sk;
340 struct netlink_sock *nlk; 344 struct netlink_sock *nlk;
345 struct module *module;
341 346
342 sock->state = SS_UNCONNECTED; 347 sock->state = SS_UNCONNECTED;
343 348
@@ -347,30 +352,36 @@ static int netlink_create(struct socket *sock, int protocol)
347 if (protocol<0 || protocol >= MAX_LINKS) 352 if (protocol<0 || protocol >= MAX_LINKS)
348 return -EPROTONOSUPPORT; 353 return -EPROTONOSUPPORT;
349 354
350 netlink_table_grab(); 355 netlink_lock_table();
351 if (!nl_table[protocol].hash.entries) { 356 if (!nl_table[protocol].hash.entries) {
352#ifdef CONFIG_KMOD 357#ifdef CONFIG_KMOD
353 /* We do 'best effort'. If we find a matching module, 358 /* We do 'best effort'. If we find a matching module,
354 * it is loaded. If not, we don't return an error to 359 * it is loaded. If not, we don't return an error to
355 * allow pure userspace<->userspace communication. -HW 360 * allow pure userspace<->userspace communication. -HW
356 */ 361 */
357 netlink_table_ungrab(); 362 netlink_unlock_table();
358 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); 363 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
359 netlink_table_grab(); 364 netlink_lock_table();
360#endif 365#endif
361 } 366 }
362 netlink_table_ungrab(); 367 module = nl_table[protocol].module;
368 if (!try_module_get(module))
369 module = NULL;
370 netlink_unlock_table();
363 371
364 sock->ops = nl_table[protocol].p_ops; 372 sock->ops = &netlink_ops;
365 373
366 sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); 374 sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
367 if (!sk) 375 if (!sk) {
376 module_put(module);
368 return -ENOMEM; 377 return -ENOMEM;
378 }
369 379
370 sock_init_data(sock, sk); 380 sock_init_data(sock, sk);
371 381
372 nlk = nlk_sk(sk); 382 nlk = nlk_sk(sk);
373 383
384 nlk->module = module;
374 spin_lock_init(&nlk->cb_lock); 385 spin_lock_init(&nlk->cb_lock);
375 init_waitqueue_head(&nlk->wait); 386 init_waitqueue_head(&nlk->wait);
376 sk->sk_destruct = netlink_sock_destruct; 387 sk->sk_destruct = netlink_sock_destruct;
@@ -415,22 +426,15 @@ static int netlink_release(struct socket *sock)
415 notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); 426 notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n);
416 } 427 }
417 428
418 /* When this is a kernel socket, we need to remove the owner pointer, 429 if (nlk->module)
419 * since we don't know whether the module will be dying at any given 430 module_put(nlk->module);
420 * point - HW
421 */
422 if (!nlk->pid) {
423 struct proto_ops *p_tmp;
424 431
432 if (nlk->flags & NETLINK_KERNEL_SOCKET) {
425 netlink_table_grab(); 433 netlink_table_grab();
426 p_tmp = nl_table[sk->sk_protocol].p_ops; 434 nl_table[sk->sk_protocol].module = NULL;
427 if (p_tmp != &netlink_ops) {
428 nl_table[sk->sk_protocol].p_ops = &netlink_ops;
429 kfree(p_tmp);
430 }
431 netlink_table_ungrab(); 435 netlink_table_ungrab();
432 } 436 }
433 437
434 sock_put(sk); 438 sock_put(sk);
435 return 0; 439 return 0;
436} 440}
@@ -1060,9 +1064,9 @@ static void netlink_data_ready(struct sock *sk, int len)
1060struct sock * 1064struct sock *
1061netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct module *module) 1065netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct module *module)
1062{ 1066{
1063 struct proto_ops *p_ops;
1064 struct socket *sock; 1067 struct socket *sock;
1065 struct sock *sk; 1068 struct sock *sk;
1069 struct netlink_sock *nlk;
1066 1070
1067 if (!nl_table) 1071 if (!nl_table)
1068 return NULL; 1072 return NULL;
@@ -1070,64 +1074,32 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct
1070 if (unit<0 || unit>=MAX_LINKS) 1074 if (unit<0 || unit>=MAX_LINKS)
1071 return NULL; 1075 return NULL;
1072 1076
1073 /* Do a quick check, to make us not go down to netlink_insert()
1074 * if protocol already has kernel socket.
1075 */
1076 sk = netlink_lookup(unit, 0);
1077 if (unlikely(sk)) {
1078 sock_put(sk);
1079 return NULL;
1080 }
1081
1082 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) 1077 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
1083 return NULL; 1078 return NULL;
1084 1079
1085 sk = NULL; 1080 if (netlink_create(sock, unit) < 0)
1086 if (module) { 1081 goto out_sock_release;
1087 /* Every registering protocol implemented in a module needs
1088 * it's own p_ops, since the socket code cannot deal with
1089 * module refcounting otherwise. -HW
1090 */
1091 p_ops = kmalloc(sizeof(*p_ops), GFP_KERNEL);
1092 if (!p_ops)
1093 goto out_sock_release;
1094
1095 memcpy(p_ops, &netlink_ops, sizeof(*p_ops));
1096 p_ops->owner = module;
1097 } else
1098 p_ops = &netlink_ops;
1099
1100 netlink_table_grab();
1101 nl_table[unit].p_ops = p_ops;
1102 netlink_table_ungrab();
1103
1104 if (netlink_create(sock, unit) < 0) {
1105 sk = NULL;
1106 goto out_kfree_p_ops;
1107 }
1108 1082
1109 sk = sock->sk; 1083 sk = sock->sk;
1110 sk->sk_data_ready = netlink_data_ready; 1084 sk->sk_data_ready = netlink_data_ready;
1111 if (input) 1085 if (input)
1112 nlk_sk(sk)->data_ready = input; 1086 nlk_sk(sk)->data_ready = input;
1113 1087
1114 if (netlink_insert(sk, 0)) { 1088 if (netlink_insert(sk, 0))
1115 sk = NULL; 1089 goto out_sock_release;
1116 goto out_kfree_p_ops;
1117 }
1118 1090
1119 return sk; 1091 nlk = nlk_sk(sk);
1092 nlk->flags |= NETLINK_KERNEL_SOCKET;
1120 1093
1121out_kfree_p_ops:
1122 netlink_table_grab(); 1094 netlink_table_grab();
1123 if (nl_table[unit].p_ops != &netlink_ops) { 1095 nl_table[unit].module = module;
1124 kfree(nl_table[unit].p_ops);
1125 nl_table[unit].p_ops = &netlink_ops;
1126 }
1127 netlink_table_ungrab(); 1096 netlink_table_ungrab();
1097
1098 return sk;
1099
1128out_sock_release: 1100out_sock_release:
1129 sock_release(sock); 1101 sock_release(sock);
1130 return sk; 1102 return NULL;
1131} 1103}
1132 1104
1133void netlink_set_nonroot(int protocol, unsigned int flags) 1105void netlink_set_nonroot(int protocol, unsigned int flags)
@@ -1490,8 +1462,6 @@ enomem:
1490 for (i = 0; i < MAX_LINKS; i++) { 1462 for (i = 0; i < MAX_LINKS; i++) {
1491 struct nl_pid_hash *hash = &nl_table[i].hash; 1463 struct nl_pid_hash *hash = &nl_table[i].hash;
1492 1464
1493 nl_table[i].p_ops = &netlink_ops;
1494
1495 hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table)); 1465 hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table));
1496 if (!hash->table) { 1466 if (!hash->table) {
1497 while (i-- > 0) 1467 while (i-- > 0)