Skip to content

Commit a62fbcc

Browse files
ying-xuedavem330
authored andcommitted
tipc: make subscriber server support net namespace
TIPC establishes one subscriber server which allows users to subscribe their interesting name service status. After tipc supports namespace, one dedicated tipc stack instance is created for each namespace, and each instance can be deemed as one independent TIPC node. As a result, subscriber server must be built for each namespace. Signed-off-by: Ying Xue <[email protected]> Tested-by: Tero Aho <[email protected]> Reviewed-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3474753 commit a62fbcc

File tree

8 files changed

+86
-65
lines changed

8 files changed

+86
-65
lines changed

net/tipc/core.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,14 @@ static int __net_init tipc_init_net(struct net *net)
6868
err = tipc_nametbl_init(net);
6969
if (err)
7070
goto out_nametbl;
71+
72+
err = tipc_subscr_start(net);
73+
if (err)
74+
goto out_subscr;
7175
return 0;
7276

77+
out_subscr:
78+
tipc_nametbl_stop(net);
7379
out_nametbl:
7480
tipc_sk_rht_destroy(net);
7581
out_sk_rht:
@@ -78,6 +84,7 @@ static int __net_init tipc_init_net(struct net *net)
7884

7985
static void __net_exit tipc_exit_net(struct net *net)
8086
{
87+
tipc_subscr_stop(net);
8188
tipc_net_stop(net);
8289
tipc_nametbl_stop(net);
8390
tipc_sk_rht_destroy(net);
@@ -104,10 +111,6 @@ static int __init tipc_init(void)
104111

105112
get_random_bytes(&tipc_random, sizeof(tipc_random));
106113

107-
err = register_pernet_subsys(&tipc_net_ops);
108-
if (err)
109-
goto out_pernet;
110-
111114
err = tipc_netlink_start();
112115
if (err)
113116
goto out_netlink;
@@ -120,9 +123,9 @@ static int __init tipc_init(void)
120123
if (err)
121124
goto out_sysctl;
122125

123-
err = tipc_subscr_start();
126+
err = register_pernet_subsys(&tipc_net_ops);
124127
if (err)
125-
goto out_subscr;
128+
goto out_pernet;
126129

127130
err = tipc_bearer_setup();
128131
if (err)
@@ -131,28 +134,25 @@ static int __init tipc_init(void)
131134
pr_info("Started in single node mode\n");
132135
return 0;
133136
out_bearer:
134-
tipc_subscr_stop();
135-
out_subscr:
137+
unregister_pernet_subsys(&tipc_net_ops);
138+
out_pernet:
136139
tipc_unregister_sysctl();
137140
out_sysctl:
138141
tipc_socket_stop();
139142
out_socket:
140143
tipc_netlink_stop();
141144
out_netlink:
142-
unregister_pernet_subsys(&tipc_net_ops);
143-
out_pernet:
144145
pr_err("Unable to start in single node mode\n");
145146
return err;
146147
}
147148

148149
static void __exit tipc_exit(void)
149150
{
150-
unregister_pernet_subsys(&tipc_net_ops);
151151
tipc_bearer_cleanup();
152152
tipc_netlink_stop();
153-
tipc_subscr_stop();
154153
tipc_socket_stop();
155154
tipc_unregister_sysctl();
155+
unregister_pernet_subsys(&tipc_net_ops);
156156

157157
pr_info("Deactivated\n");
158158
}

net/tipc/core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ struct tipc_net {
106106
/* Name table */
107107
spinlock_t nametbl_lock;
108108
struct name_table *nametbl;
109+
110+
/* Topology subscription server */
111+
struct tipc_server *topsrv;
112+
atomic_t subscription_count;
109113
};
110114

111115
#ifdef CONFIG_SYSCTL

net/tipc/server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309309
struct socket *sock = NULL;
310310
int ret;
311311

312-
ret = tipc_sock_create_local(s->type, &sock);
312+
ret = tipc_sock_create_local(s->net, s->type, &sock);
313313
if (ret < 0)
314314
return NULL;
315315
ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,

net/tipc/server.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* @conn_idr: identifier set of connection
4848
* @idr_lock: protect the connection identifier set
4949
* @idr_in_use: amount of allocated identifier entry
50+
* @net: network namspace instance
5051
* @rcvbuf_cache: memory cache of server receive buffer
5152
* @rcv_wq: receive workqueue
5253
* @send_wq: send workqueue
@@ -63,6 +64,7 @@ struct tipc_server {
6364
struct idr conn_idr;
6465
spinlock_t idr_lock;
6566
int idr_in_use;
67+
struct net *net;
6668
struct kmem_cache *rcvbuf_cache;
6769
struct workqueue_struct *rcv_wq;
6870
struct workqueue_struct *send_wq;
@@ -73,7 +75,7 @@ struct tipc_server {
7375
struct sockaddr_tipc *addr, void *usr_data,
7476
void *buf, size_t len);
7577
struct sockaddr_tipc *saddr;
76-
const char name[TIPC_SERVER_NAME_LEN];
78+
char name[TIPC_SERVER_NAME_LEN];
7779
int imp;
7880
int type;
7981
};

net/tipc/socket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
388388
*
389389
* Returns 0 on success, errno otherwise
390390
*/
391-
int tipc_sock_create_local(int type, struct socket **res)
391+
int tipc_sock_create_local(struct net *net, int type, struct socket **res)
392392
{
393393
int rc;
394394

@@ -397,7 +397,7 @@ int tipc_sock_create_local(int type, struct socket **res)
397397
pr_err("Failed to create kernel socket\n");
398398
return rc;
399399
}
400-
tipc_sk_create(&init_net, *res, 0, 1);
400+
tipc_sk_create(net, *res, 0, 1);
401401

402402
return 0;
403403
}

net/tipc/socket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
int tipc_socket_init(void);
4747
void tipc_socket_stop(void);
48-
int tipc_sock_create_local(int type, struct socket **res);
48+
int tipc_sock_create_local(struct net *net, int type, struct socket **res);
4949
void tipc_sock_release_local(struct socket *sock);
5050
int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
5151
int flags);

net/tipc/subscr.c

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,6 @@ struct tipc_subscriber {
5050
struct list_head subscription_list;
5151
};
5252

53-
static void subscr_conn_msg_event(struct net *net, int conid,
54-
struct sockaddr_tipc *addr, void *usr_data,
55-
void *buf, size_t len);
56-
static void *subscr_named_msg_event(int conid);
57-
static void subscr_conn_shutdown_event(int conid, void *usr_data);
58-
59-
static atomic_t subscription_count = ATOMIC_INIT(0);
60-
61-
static 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-
70-
static 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-
8153
/**
8254
* htohl - convert value to endianness used by destination
8355
* @in: value to convert
@@ -94,6 +66,7 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
9466
u32 found_upper, u32 event, u32 port_ref,
9567
u32 node)
9668
{
69+
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
9770
struct tipc_subscriber *subscriber = sub->subscriber;
9871
struct kvec msg_sect;
9972

@@ -104,8 +77,8 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
10477
sub->evt.found_upper = htohl(found_upper, sub->swap);
10578
sub->evt.port.ref = htohl(port_ref, sub->swap);
10679
sub->evt.port.node = htohl(node, sub->swap);
107-
tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base,
108-
msg_sect.iov_len);
80+
tipc_conn_sendmsg(tn->topsrv, subscriber->conid, NULL,
81+
msg_sect.iov_base, msg_sect.iov_len);
10982
}
11083

11184
/**
@@ -146,6 +119,7 @@ static void subscr_timeout(unsigned long data)
146119
{
147120
struct tipc_subscription *sub = (struct tipc_subscription *)data;
148121
struct tipc_subscriber *subscriber = sub->subscriber;
122+
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
149123

150124
/* The spin lock per subscriber is used to protect its members */
151125
spin_lock_bh(&subscriber->lock);
@@ -170,7 +144,7 @@ static void subscr_timeout(unsigned long data)
170144

171145
/* Now destroy subscription */
172146
kfree(sub);
173-
atomic_dec(&subscription_count);
147+
atomic_dec(&tn->subscription_count);
174148
}
175149

176150
/**
@@ -180,20 +154,25 @@ static void subscr_timeout(unsigned long data)
180154
*/
181155
static void subscr_del(struct tipc_subscription *sub)
182156
{
157+
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
158+
183159
tipc_nametbl_unsubscribe(sub);
184160
list_del(&sub->subscription_list);
185161
kfree(sub);
186-
atomic_dec(&subscription_count);
162+
atomic_dec(&tn->subscription_count);
187163
}
188164

189165
/**
190166
* subscr_terminate - terminate communication with a subscriber
191167
*
192168
* Note: Must call it in process context since it might sleep.
193169
*/
194-
static void subscr_terminate(struct tipc_subscriber *subscriber)
170+
static void subscr_terminate(struct tipc_subscription *sub)
195171
{
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);
197176
}
198177

199178
static void subscr_release(struct tipc_subscriber *subscriber)
@@ -263,7 +242,9 @@ static void subscr_cancel(struct tipc_subscr *s,
263242
*/
264243
static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
265244
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);
267248
struct tipc_subscription *sub;
268249
int swap;
269250

@@ -278,7 +259,7 @@ static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
278259
}
279260

280261
/* 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) {
282263
pr_warn("Subscription rejected, limit reached (%u)\n",
283264
TIPC_MAX_SUBSCRIPTIONS);
284265
return -EINVAL;
@@ -309,7 +290,7 @@ static int subscr_subscribe(struct net *net, struct tipc_subscr *s,
309290
sub->subscriber = subscriber;
310291
sub->swap = swap;
311292
memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
312-
atomic_inc(&subscription_count);
293+
atomic_inc(&tn->subscription_count);
313294
if (sub->timeout != TIPC_WAIT_FOREVER) {
314295
setup_timer(&sub->timer, subscr_timeout, (unsigned long)sub);
315296
mod_timer(&sub->timer, jiffies + sub->timeout);
@@ -336,15 +317,14 @@ static void subscr_conn_msg_event(struct net *net, int conid,
336317
if (subscr_subscribe(net, (struct tipc_subscr *)buf, subscriber,
337318
&sub) < 0) {
338319
spin_unlock_bh(&subscriber->lock);
339-
subscr_terminate(subscriber);
320+
subscr_terminate(sub);
340321
return;
341322
}
342323
if (sub)
343324
tipc_nametbl_subscribe(sub);
344325
spin_unlock_bh(&subscriber->lock);
345326
}
346327

347-
348328
/* Handle one request to establish a new subscriber */
349329
static void *subscr_named_msg_event(int conid)
350330
{
@@ -363,12 +343,50 @@ static void *subscr_named_msg_event(int conid)
363343
return (void *)subscriber;
364344
}
365345

366-
int tipc_subscr_start(void)
346+
int tipc_subscr_start(struct net *net)
367347
{
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);
369382
}
370383

371-
void tipc_subscr_stop(void)
384+
void tipc_subscr_stop(struct net *net)
372385
{
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);
374392
}

net/tipc/subscr.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,10 @@ struct tipc_subscription {
7474

7575
int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
7676
u32 found_upper);
77-
7877
void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
7978
u32 found_upper, u32 event, u32 port_ref,
8079
u32 node, int must);
81-
82-
int tipc_subscr_start(void);
83-
84-
void tipc_subscr_stop(void);
80+
int tipc_subscr_start(struct net *net);
81+
void tipc_subscr_stop(struct net *net);
8582

8683
#endif

0 commit comments

Comments
 (0)