aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.c24
-rw-r--r--net/tipc/core.h4
-rw-r--r--net/tipc/server.c2
-rw-r--r--net/tipc/server.h4
-rw-r--r--net/tipc/socket.c4
-rw-r--r--net/tipc/socket.h2
-rw-r--r--net/tipc/subscr.c104
-rw-r--r--net/tipc/subscr.h7
8 files changed, 86 insertions, 65 deletions
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 7c09670120eb..4a8b7955e0e0 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -68,8 +68,14 @@ static int __net_init tipc_init_net(struct net *net)
68 err = tipc_nametbl_init(net); 68 err = tipc_nametbl_init(net);
69 if (err) 69 if (err)
70 goto out_nametbl; 70 goto out_nametbl;
71
72 err = tipc_subscr_start(net);
73 if (err)
74 goto out_subscr;
71 return 0; 75 return 0;
72 76
77out_subscr:
78 tipc_nametbl_stop(net);
73out_nametbl: 79out_nametbl:
74 tipc_sk_rht_destroy(net); 80 tipc_sk_rht_destroy(net);
75out_sk_rht: 81out_sk_rht:
@@ -78,6 +84,7 @@ out_sk_rht:
78 84
79static void __net_exit tipc_exit_net(struct net *net) 85static void __net_exit tipc_exit_net(struct net *net)
80{ 86{
87 tipc_subscr_stop(net);
81 tipc_net_stop(net); 88 tipc_net_stop(net);
82 tipc_nametbl_stop(net); 89 tipc_nametbl_stop(net);
83 tipc_sk_rht_destroy(net); 90 tipc_sk_rht_destroy(net);
@@ -104,10 +111,6 @@ static int __init tipc_init(void)
104 111
105 get_random_bytes(&tipc_random, sizeof(tipc_random)); 112 get_random_bytes(&tipc_random, sizeof(tipc_random));
106 113
107 err = register_pernet_subsys(&tipc_net_ops);
108 if (err)
109 goto out_pernet;
110
111 err = tipc_netlink_start(); 114 err = tipc_netlink_start();
112 if (err) 115 if (err)
113 goto out_netlink; 116 goto out_netlink;
@@ -120,9 +123,9 @@ static int __init tipc_init(void)
120 if (err) 123 if (err)
121 goto out_sysctl; 124 goto out_sysctl;
122 125
123 err = tipc_subscr_start(); 126 err = register_pernet_subsys(&tipc_net_ops);
124 if (err) 127 if (err)
125 goto out_subscr; 128 goto out_pernet;
126 129
127 err = tipc_bearer_setup(); 130 err = tipc_bearer_setup();
128 if (err) 131 if (err)
@@ -131,28 +134,25 @@ static int __init tipc_init(void)
131 pr_info("Started in single node mode\n"); 134 pr_info("Started in single node mode\n");
132 return 0; 135 return 0;
133out_bearer: 136out_bearer:
134 tipc_subscr_stop(); 137 unregister_pernet_subsys(&tipc_net_ops);
135out_subscr: 138out_pernet:
136 tipc_unregister_sysctl(); 139 tipc_unregister_sysctl();
137out_sysctl: 140out_sysctl:
138 tipc_socket_stop(); 141 tipc_socket_stop();
139out_socket: 142out_socket:
140 tipc_netlink_stop(); 143 tipc_netlink_stop();
141out_netlink: 144out_netlink:
142 unregister_pernet_subsys(&tipc_net_ops);
143out_pernet:
144 pr_err("Unable to start in single node mode\n"); 145 pr_err("Unable to start in single node mode\n");
145 return err; 146 return err;
146} 147}
147 148
148static void __exit tipc_exit(void) 149static void __exit tipc_exit(void)
149{ 150{
150 unregister_pernet_subsys(&tipc_net_ops);
151 tipc_bearer_cleanup(); 151 tipc_bearer_cleanup();
152 tipc_netlink_stop(); 152 tipc_netlink_stop();
153 tipc_subscr_stop();
154 tipc_socket_stop(); 153 tipc_socket_stop();
155 tipc_unregister_sysctl(); 154 tipc_unregister_sysctl();
155 unregister_pernet_subsys(&tipc_net_ops);
156 156
157 pr_info("Deactivated\n"); 157 pr_info("Deactivated\n");
158} 158}
diff --git a/net/tipc/core.h b/net/tipc/core.h
index afabf39e801c..639f562dddf3 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -106,6 +106,10 @@ struct tipc_net {
106 /* Name table */ 106 /* Name table */
107 spinlock_t nametbl_lock; 107 spinlock_t nametbl_lock;
108 struct name_table *nametbl; 108 struct name_table *nametbl;
109
110 /* Topology subscription server */
111 struct tipc_server *topsrv;
112 atomic_t subscription_count;
109}; 113};
110 114
111#ifdef CONFIG_SYSCTL 115#ifdef CONFIG_SYSCTL
diff --git a/net/tipc/server.c b/net/tipc/server.c
index b5bdaf721d70..eadd4ed45905 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -309,7 +309,7 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309 struct socket *sock = NULL; 309 struct socket *sock = NULL;
310 int ret; 310 int ret;
311 311
312 ret = tipc_sock_create_local(s->type, &sock); 312 ret = tipc_sock_create_local(s->net, s->type, &sock);
313 if (ret < 0) 313 if (ret < 0)
314 return NULL; 314 return NULL;
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
diff --git a/net/tipc/server.h b/net/tipc/server.h
index 9c979a01997c..9015faedb1b0 100644
--- a/net/tipc/server.h
+++ b/net/tipc/server.h
@@ -47,6 +47,7 @@
47 * @conn_idr: identifier set of connection 47 * @conn_idr: identifier set of connection
48 * @idr_lock: protect the connection identifier set 48 * @idr_lock: protect the connection identifier set
49 * @idr_in_use: amount of allocated identifier entry 49 * @idr_in_use: amount of allocated identifier entry
50 * @net: network namspace instance
50 * @rcvbuf_cache: memory cache of server receive buffer 51 * @rcvbuf_cache: memory cache of server receive buffer
51 * @rcv_wq: receive workqueue 52 * @rcv_wq: receive workqueue
52 * @send_wq: send workqueue 53 * @send_wq: send workqueue
@@ -63,6 +64,7 @@ struct tipc_server {
63 struct idr conn_idr; 64 struct idr conn_idr;
64 spinlock_t idr_lock; 65 spinlock_t idr_lock;
65 int idr_in_use; 66 int idr_in_use;
67 struct net *net;
66 struct kmem_cache *rcvbuf_cache; 68 struct kmem_cache *rcvbuf_cache;
67 struct workqueue_struct *rcv_wq; 69 struct workqueue_struct *rcv_wq;
68 struct workqueue_struct *send_wq; 70 struct workqueue_struct *send_wq;
@@ -73,7 +75,7 @@ struct tipc_server {
73 struct sockaddr_tipc *addr, void *usr_data, 75 struct sockaddr_tipc *addr, void *usr_data,
74 void *buf, size_t len); 76 void *buf, size_t len);
75 struct sockaddr_tipc *saddr; 77 struct sockaddr_tipc *saddr;
76 const char name[TIPC_SERVER_NAME_LEN]; 78 char name[TIPC_SERVER_NAME_LEN];
77 int imp; 79 int imp;
78 int type; 80 int type;
79}; 81};
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 9b8470edc783..2cec496ba691 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -388,7 +388,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
388 * 388 *
389 * Returns 0 on success, errno otherwise 389 * Returns 0 on success, errno otherwise
390 */ 390 */
391int tipc_sock_create_local(int type, struct socket **res) 391int tipc_sock_create_local(struct net *net, int type, struct socket **res)
392{ 392{
393 int rc; 393 int rc;
394 394
@@ -397,7 +397,7 @@ int tipc_sock_create_local(int type, struct socket **res)
397 pr_err("Failed to create kernel socket\n"); 397 pr_err("Failed to create kernel socket\n");
398 return rc; 398 return rc;
399 } 399 }
400 tipc_sk_create(&init_net, *res, 0, 1); 400 tipc_sk_create(net, *res, 0, 1);
401 401
402 return 0; 402 return 0;
403} 403}
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index c15c4e121fe3..f56c3fded51f 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -45,7 +45,7 @@
45 45
46int tipc_socket_init(void); 46int tipc_socket_init(void);
47void tipc_socket_stop(void); 47void tipc_socket_stop(void);
48int tipc_sock_create_local(int type, struct socket **res); 48int tipc_sock_create_local(struct net *net, int type, struct socket **res);
49void tipc_sock_release_local(struct socket *sock); 49void tipc_sock_release_local(struct socket *sock);
50int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, 50int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
51 int flags); 51 int flags);
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index b71dbc0ae8f9..72c339e432aa 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -50,34 +50,6 @@ struct tipc_subscriber {
50 struct list_head subscription_list; 50 struct list_head subscription_list;
51}; 51};
52 52
53static void subscr_conn_msg_event(struct net *net, int conid,
54 struct sockaddr_tipc *addr, void *usr_data,
55 void *buf, size_t len);
56static void *subscr_named_msg_event(int conid);
57static void subscr_conn_shutdown_event(int conid, void *usr_data);
58
59static atomic_t subscription_count = ATOMIC_INIT(0);
60
61static struct sockaddr_tipc topsrv_addr __read_mostly = {
62 .family = AF_TIPC,
63 .addrtype = TIPC_ADDR_NAMESEQ,
64 .addr.nameseq.type = TIPC_TOP_SRV,
65 .addr.nameseq.lower = TIPC_TOP_SRV,
66 .addr.nameseq.upper = TIPC_TOP_SRV,
67 .scope = TIPC_NODE_SCOPE
68};
69
70static struct tipc_server topsrv __read_mostly = {
71 .saddr = &topsrv_addr,
72 .imp = TIPC_CRITICAL_IMPORTANCE,
73 .type = SOCK_SEQPACKET,
74 .max_rcvbuf_size = sizeof(struct tipc_subscr),
75 .name = "topology_server",
76 .tipc_conn_recvmsg = subscr_conn_msg_event,
77 .tipc_conn_new = subscr_named_msg_event,
78 .tipc_conn_shutdown = subscr_conn_shutdown_event,
79};
80
81/** 53/**
82 * htohl - convert value to endianness used by destination 54 * htohl - convert value to endianness used by destination
83 * @in: value to convert 55 * @in: value to convert
@@ -94,6 +66,7 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
94 u32 found_upper, u32 event, u32 port_ref, 66 u32 found_upper, u32 event, u32 port_ref,
95 u32 node) 67 u32 node)
96{ 68{
69 struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
97 struct tipc_subscriber *subscriber = sub->subscriber; 70 struct tipc_subscriber *subscriber = sub->subscriber;
98 struct kvec msg_sect; 71 struct kvec msg_sect;
99 72
@@ -104,8 +77,8 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
104 sub->evt.found_upper = htohl(found_upper, sub->swap); 77 sub->evt.found_upper = htohl(found_upper, sub->swap);
105 sub->evt.port.ref = htohl(port_ref, sub->swap); 78 sub->evt.port.ref = htohl(port_ref, sub->swap);
106 sub->evt.port.node = htohl(node, sub->swap); 79 sub->evt.port.node = htohl(node, sub->swap);
107 tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base, 80 tipc_conn_sendmsg(tn->topsrv, subscriber->conid, NULL,
108 msg_sect.iov_len); 81 msg_sect.iov_base, msg_sect.iov_len);
109} 82}
110 83
111/** 84/**
@@ -146,6 +119,7 @@ static void subscr_timeout(unsigned long data)
146{ 119{
147 struct tipc_subscription *sub = (struct tipc_subscription *)data; 120 struct tipc_subscription *sub = (struct tipc_subscription *)data;
148 struct tipc_subscriber *subscriber = sub->subscriber; 121 struct tipc_subscriber *subscriber = sub->subscriber;
122 struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
149 123
150 /* The spin lock per subscriber is used to protect its members */ 124 /* The spin lock per subscriber is used to protect its members */
151 spin_lock_bh(&subscriber->lock); 125 spin_lock_bh(&subscriber->lock);
@@ -170,7 +144,7 @@ static void subscr_timeout(unsigned long data)
170 144
171 /* Now destroy subscription */ 145 /* Now destroy subscription */
172 kfree(sub); 146 kfree(sub);
173 atomic_dec(&subscription_count); 147 atomic_dec(&tn->subscription_count);
174} 148}
175 149
176/** 150/**
@@ -180,10 +154,12 @@ static void subscr_timeout(unsigned long data)
180 */ 154 */
181static void subscr_del(struct tipc_subscription *sub) 155static void subscr_del(struct tipc_subscription *sub)
182{ 156{
157 struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
158
183 tipc_nametbl_unsubscribe(sub); 159 tipc_nametbl_unsubscribe(sub);
184 list_del(&sub->subscription_list); 160 list_del(&sub->subscription_list);
185 kfree(sub); 161 kfree(sub);
186 atomic_dec(&subscription_count); 162 atomic_dec(&tn->subscription_count);
187} 163}
188 164
189/** 165/**
@@ -191,9 +167,12 @@ static void subscr_del(struct tipc_subscription *sub)
191 * 167 *
192 * Note: Must call it in process context since it might sleep. 168 * Note: Must call it in process context since it might sleep.
193 */ 169 */
194static void subscr_terminate(struct tipc_subscriber *subscriber) 170static void subscr_terminate(struct tipc_subscription *sub)
195{ 171{
196 tipc_conn_terminate(&topsrv, subscriber->conid); 172 struct tipc_subscriber *subscriber = sub->subscriber;
173 struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
174
175 tipc_conn_terminate(tn->topsrv, subscriber->conid);
197} 176}
198 177
199static void subscr_release(struct tipc_subscriber *subscriber) 178static void subscr_release(struct tipc_subscriber *subscriber)
@@ -263,7 +242,9 @@ static void subscr_cancel(struct tipc_subscr *s,
263 */ 242 */
264static int subscr_subscribe(struct net *net, struct tipc_subscr *s, 243static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
265 struct tipc_subscriber *subscriber, 244 struct tipc_subscriber *subscriber,
266 struct tipc_subscription **sub_p) { 245 struct tipc_subscription **sub_p)
246{
247 struct tipc_net *tn = net_generic(net, tipc_net_id);
267 struct tipc_subscription *sub; 248 struct tipc_subscription *sub;
268 int swap; 249 int swap;
269 250
@@ -278,7 +259,7 @@ static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
278 } 259 }
279 260
280 /* Refuse subscription if global limit exceeded */ 261 /* Refuse subscription if global limit exceeded */
281 if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { 262 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
282 pr_warn("Subscription rejected, limit reached (%u)\n", 263 pr_warn("Subscription rejected, limit reached (%u)\n",
283 TIPC_MAX_SUBSCRIPTIONS); 264 TIPC_MAX_SUBSCRIPTIONS);
284 return -EINVAL; 265 return -EINVAL;
@@ -309,7 +290,7 @@ static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
309 sub->subscriber = subscriber; 290 sub->subscriber = subscriber;
310 sub->swap = swap; 291 sub->swap = swap;
311 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 292 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
312 atomic_inc(&subscription_count); 293 atomic_inc(&tn->subscription_count);
313 if (sub->timeout != TIPC_WAIT_FOREVER) { 294 if (sub->timeout != TIPC_WAIT_FOREVER) {
314 setup_timer(&sub->timer, subscr_timeout, (unsigned long)sub); 295 setup_timer(&sub->timer, subscr_timeout, (unsigned long)sub);
315 mod_timer(&sub->timer, jiffies + sub->timeout); 296 mod_timer(&sub->timer, jiffies + sub->timeout);
@@ -336,7 +317,7 @@ static void subscr_conn_msg_event(struct net *net, int conid,
336 if (subscr_subscribe(net, (struct tipc_subscr *)buf, subscriber, 317 if (subscr_subscribe(net, (struct tipc_subscr *)buf, subscriber,
337 &sub) < 0) { 318 &sub) < 0) {
338 spin_unlock_bh(&subscriber->lock); 319 spin_unlock_bh(&subscriber->lock);
339 subscr_terminate(subscriber); 320 subscr_terminate(sub);
340 return; 321 return;
341 } 322 }
342 if (sub) 323 if (sub)
@@ -344,7 +325,6 @@ static void subscr_conn_msg_event(struct net *net, int conid,
344 spin_unlock_bh(&subscriber->lock); 325 spin_unlock_bh(&subscriber->lock);
345} 326}
346 327
347
348/* Handle one request to establish a new subscriber */ 328/* Handle one request to establish a new subscriber */
349static void *subscr_named_msg_event(int conid) 329static void *subscr_named_msg_event(int conid)
350{ 330{
@@ -363,12 +343,50 @@ static void *subscr_named_msg_event(int conid)
363 return (void *)subscriber; 343 return (void *)subscriber;
364} 344}
365 345
366int tipc_subscr_start(void) 346int tipc_subscr_start(struct net *net)
367{ 347{
368 return tipc_server_start(&topsrv); 348 struct tipc_net *tn = net_generic(net, tipc_net_id);
349 const char name[] = "topology_server";
350 struct tipc_server *topsrv;
351 struct sockaddr_tipc *saddr;
352
353 saddr = kzalloc(sizeof(*saddr), GFP_ATOMIC);
354 if (!saddr)
355 return -ENOMEM;
356 saddr->family = AF_TIPC;
357 saddr->addrtype = TIPC_ADDR_NAMESEQ;
358 saddr->addr.nameseq.type = TIPC_TOP_SRV;
359 saddr->addr.nameseq.lower = TIPC_TOP_SRV;
360 saddr->addr.nameseq.upper = TIPC_TOP_SRV;
361 saddr->scope = TIPC_NODE_SCOPE;
362
363 topsrv = kzalloc(sizeof(*topsrv), GFP_ATOMIC);
364 if (!topsrv) {
365 kfree(saddr);
366 return -ENOMEM;
367 }
368 topsrv->net = net;
369 topsrv->saddr = saddr;
370 topsrv->imp = TIPC_CRITICAL_IMPORTANCE;
371 topsrv->type = SOCK_SEQPACKET;
372 topsrv->max_rcvbuf_size = sizeof(struct tipc_subscr);
373 topsrv->tipc_conn_recvmsg = subscr_conn_msg_event;
374 topsrv->tipc_conn_new = subscr_named_msg_event;
375 topsrv->tipc_conn_shutdown = subscr_conn_shutdown_event;
376
377 strncpy(topsrv->name, name, strlen(name) + 1);
378 tn->topsrv = topsrv;
379 atomic_set(&tn->subscription_count, 0);
380
381 return tipc_server_start(topsrv);
369} 382}
370 383
371void tipc_subscr_stop(void) 384void tipc_subscr_stop(struct net *net)
372{ 385{
373 tipc_server_stop(&topsrv); 386 struct tipc_net *tn = net_generic(net, tipc_net_id);
387 struct tipc_server *topsrv = tn->topsrv;
388
389 tipc_server_stop(topsrv);
390 kfree(topsrv->saddr);
391 kfree(topsrv);
374} 392}
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 670f57096635..33488bd9fe3c 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -74,13 +74,10 @@ struct tipc_subscription {
74 74
75int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower, 75int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
76 u32 found_upper); 76 u32 found_upper);
77
78void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower, 77void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
79 u32 found_upper, u32 event, u32 port_ref, 78 u32 found_upper, u32 event, u32 port_ref,
80 u32 node, int must); 79 u32 node, int must);
81 80int tipc_subscr_start(struct net *net);
82int tipc_subscr_start(void); 81void tipc_subscr_stop(struct net *net);
83
84void tipc_subscr_stop(void);
85 82
86#endif 83#endif