diff options
| author | Jon Maloy <jon.maloy@ericsson.com> | 2018-02-15 04:40:49 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-02-16 15:26:34 -0500 |
| commit | 5c45ab24ac77ea32eae7d3576cf37c3ddb259f80 (patch) | |
| tree | d8a46d20cdeb90d3a625eaa71d1a71293635e0d4 | |
| parent | da0a75e86ae230f92743c073843d3ea35bd061af (diff) | |
tipc: make struct tipc_server private for server.c
In order to narrow the interface and dependencies between the topology
server and the subscription/binding table functionality we move struct
tipc_server inside the file server.c. This requires some code
adaptations in other files, but those are mostly minor.
The most important change is that we have to move the start/stop
functions for the topology server to server.c, where they logically
belong anyway.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/tipc/name_table.c | 10 | ||||
| -rw-r--r-- | net/tipc/server.c | 124 | ||||
| -rw-r--r-- | net/tipc/server.h | 36 | ||||
| -rw-r--r-- | net/tipc/subscr.c | 64 | ||||
| -rw-r--r-- | net/tipc/subscr.h | 4 |
5 files changed, 110 insertions, 128 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index b234b7ee0b84..e01c9c691ba2 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -813,8 +813,7 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref, | |||
| 813 | */ | 813 | */ |
| 814 | void tipc_nametbl_subscribe(struct tipc_subscription *sub) | 814 | void tipc_nametbl_subscribe(struct tipc_subscription *sub) |
| 815 | { | 815 | { |
| 816 | struct tipc_server *srv = sub->server; | 816 | struct tipc_net *tn = tipc_net(sub->net); |
| 817 | struct tipc_net *tn = tipc_net(srv->net); | ||
| 818 | struct tipc_subscr *s = &sub->evt.s; | 817 | struct tipc_subscr *s = &sub->evt.s; |
| 819 | u32 type = tipc_sub_read(s, seq.type); | 818 | u32 type = tipc_sub_read(s, seq.type); |
| 820 | int index = hash(type); | 819 | int index = hash(type); |
| @@ -822,7 +821,7 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub) | |||
| 822 | struct tipc_name_seq ns; | 821 | struct tipc_name_seq ns; |
| 823 | 822 | ||
| 824 | spin_lock_bh(&tn->nametbl_lock); | 823 | spin_lock_bh(&tn->nametbl_lock); |
| 825 | seq = nametbl_find_seq(srv->net, type); | 824 | seq = nametbl_find_seq(sub->net, type); |
| 826 | if (!seq) | 825 | if (!seq) |
| 827 | seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); | 826 | seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); |
| 828 | if (seq) { | 827 | if (seq) { |
| @@ -844,14 +843,13 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub) | |||
| 844 | */ | 843 | */ |
| 845 | void tipc_nametbl_unsubscribe(struct tipc_subscription *sub) | 844 | void tipc_nametbl_unsubscribe(struct tipc_subscription *sub) |
| 846 | { | 845 | { |
| 847 | struct tipc_server *srv = sub->server; | ||
| 848 | struct tipc_subscr *s = &sub->evt.s; | 846 | struct tipc_subscr *s = &sub->evt.s; |
| 849 | struct tipc_net *tn = tipc_net(srv->net); | 847 | struct tipc_net *tn = tipc_net(sub->net); |
| 850 | struct name_seq *seq; | 848 | struct name_seq *seq; |
| 851 | u32 type = tipc_sub_read(s, seq.type); | 849 | u32 type = tipc_sub_read(s, seq.type); |
| 852 | 850 | ||
| 853 | spin_lock_bh(&tn->nametbl_lock); | 851 | spin_lock_bh(&tn->nametbl_lock); |
| 854 | seq = nametbl_find_seq(srv->net, type); | 852 | seq = nametbl_find_seq(sub->net, type); |
| 855 | if (seq != NULL) { | 853 | if (seq != NULL) { |
| 856 | spin_lock_bh(&seq->lock); | 854 | spin_lock_bh(&seq->lock); |
| 857 | list_del_init(&sub->nameseq_list); | 855 | list_del_init(&sub->nameseq_list); |
diff --git a/net/tipc/server.c b/net/tipc/server.c index a5c112ed3bbe..0abbdd698662 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
| @@ -49,7 +49,37 @@ | |||
| 49 | #define CF_CONNECTED 1 | 49 | #define CF_CONNECTED 1 |
| 50 | #define CF_SERVER 2 | 50 | #define CF_SERVER 2 |
| 51 | 51 | ||
| 52 | #define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data) | 52 | #define TIPC_SERVER_NAME_LEN 32 |
| 53 | |||
| 54 | /** | ||
| 55 | * struct tipc_server - TIPC server structure | ||
| 56 | * @conn_idr: identifier set of connection | ||
| 57 | * @idr_lock: protect the connection identifier set | ||
| 58 | * @idr_in_use: amount of allocated identifier entry | ||
| 59 | * @net: network namspace instance | ||
| 60 | * @rcvbuf_cache: memory cache of server receive buffer | ||
| 61 | * @rcv_wq: receive workqueue | ||
| 62 | * @send_wq: send workqueue | ||
| 63 | * @max_rcvbuf_size: maximum permitted receive message length | ||
| 64 | * @tipc_conn_new: callback will be called when new connection is incoming | ||
| 65 | * @tipc_conn_release: callback will be called before releasing the connection | ||
| 66 | * @tipc_conn_recvmsg: callback will be called when message arrives | ||
| 67 | * @saddr: TIPC server address | ||
| 68 | * @name: server name | ||
| 69 | * @imp: message importance | ||
| 70 | * @type: socket type | ||
| 71 | */ | ||
| 72 | struct tipc_server { | ||
| 73 | struct idr conn_idr; | ||
| 74 | spinlock_t idr_lock; /* for idr list */ | ||
| 75 | int idr_in_use; | ||
| 76 | struct net *net; | ||
| 77 | struct workqueue_struct *rcv_wq; | ||
| 78 | struct workqueue_struct *send_wq; | ||
| 79 | int max_rcvbuf_size; | ||
| 80 | struct sockaddr_tipc *saddr; | ||
| 81 | char name[TIPC_SERVER_NAME_LEN]; | ||
| 82 | }; | ||
| 53 | 83 | ||
| 54 | /** | 84 | /** |
| 55 | * struct tipc_conn - TIPC connection structure | 85 | * struct tipc_conn - TIPC connection structure |
| @@ -93,6 +123,11 @@ static void tipc_recv_work(struct work_struct *work); | |||
| 93 | static void tipc_send_work(struct work_struct *work); | 123 | static void tipc_send_work(struct work_struct *work); |
| 94 | static void tipc_clean_outqueues(struct tipc_conn *con); | 124 | static void tipc_clean_outqueues(struct tipc_conn *con); |
| 95 | 125 | ||
| 126 | static struct tipc_conn *sock2con(struct sock *sk) | ||
| 127 | { | ||
| 128 | return sk->sk_user_data; | ||
| 129 | } | ||
| 130 | |||
| 96 | static bool connected(struct tipc_conn *con) | 131 | static bool connected(struct tipc_conn *con) |
| 97 | { | 132 | { |
| 98 | return con && test_bit(CF_CONNECTED, &con->flags); | 133 | return con && test_bit(CF_CONNECTED, &con->flags); |
| @@ -198,14 +233,17 @@ static void tipc_register_callbacks(struct socket *sock, struct tipc_conn *con) | |||
| 198 | static void tipc_con_delete_sub(struct tipc_conn *con, struct tipc_subscr *s) | 233 | static void tipc_con_delete_sub(struct tipc_conn *con, struct tipc_subscr *s) |
| 199 | { | 234 | { |
| 200 | struct list_head *sub_list = &con->sub_list; | 235 | struct list_head *sub_list = &con->sub_list; |
| 236 | struct tipc_net *tn = tipc_net(con->server->net); | ||
| 201 | struct tipc_subscription *sub, *tmp; | 237 | struct tipc_subscription *sub, *tmp; |
| 202 | 238 | ||
| 203 | spin_lock_bh(&con->sub_lock); | 239 | spin_lock_bh(&con->sub_lock); |
| 204 | list_for_each_entry_safe(sub, tmp, sub_list, sub_list) { | 240 | list_for_each_entry_safe(sub, tmp, sub_list, sub_list) { |
| 205 | if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) | 241 | if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) { |
| 206 | tipc_sub_unsubscribe(sub); | 242 | tipc_sub_unsubscribe(sub); |
| 207 | else if (s) | 243 | atomic_dec(&tn->subscription_count); |
| 244 | } else if (s) { | ||
| 208 | break; | 245 | break; |
| 246 | } | ||
| 209 | } | 247 | } |
| 210 | spin_unlock_bh(&con->sub_lock); | 248 | spin_unlock_bh(&con->sub_lock); |
| 211 | } | 249 | } |
| @@ -220,8 +258,7 @@ static void tipc_close_conn(struct tipc_conn *con) | |||
| 220 | 258 | ||
| 221 | if (disconnect) { | 259 | if (disconnect) { |
| 222 | sk->sk_user_data = NULL; | 260 | sk->sk_user_data = NULL; |
| 223 | if (con->conid) | 261 | tipc_con_delete_sub(con, NULL); |
| 224 | tipc_con_delete_sub(con, NULL); | ||
| 225 | } | 262 | } |
| 226 | write_unlock_bh(&sk->sk_callback_lock); | 263 | write_unlock_bh(&sk->sk_callback_lock); |
| 227 | 264 | ||
| @@ -272,15 +309,21 @@ static int tipc_con_rcv_sub(struct tipc_server *srv, | |||
| 272 | struct tipc_conn *con, | 309 | struct tipc_conn *con, |
| 273 | struct tipc_subscr *s) | 310 | struct tipc_subscr *s) |
| 274 | { | 311 | { |
| 312 | struct tipc_net *tn = tipc_net(srv->net); | ||
| 275 | struct tipc_subscription *sub; | 313 | struct tipc_subscription *sub; |
| 276 | 314 | ||
| 277 | if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) { | 315 | if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) { |
| 278 | tipc_con_delete_sub(con, s); | 316 | tipc_con_delete_sub(con, s); |
| 279 | return 0; | 317 | return 0; |
| 280 | } | 318 | } |
| 281 | sub = tipc_sub_subscribe(srv, s, con->conid); | 319 | if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCR) { |
| 320 | pr_warn("Subscription rejected, max (%u)\n", TIPC_MAX_SUBSCR); | ||
| 321 | return -1; | ||
| 322 | } | ||
| 323 | sub = tipc_sub_subscribe(srv->net, s, con->conid); | ||
| 282 | if (!sub) | 324 | if (!sub) |
| 283 | return -1; | 325 | return -1; |
| 326 | atomic_inc(&tn->subscription_count); | ||
| 284 | spin_lock_bh(&con->sub_lock); | 327 | spin_lock_bh(&con->sub_lock); |
| 285 | list_add(&sub->sub_list, &con->sub_list); | 328 | list_add(&sub->sub_list, &con->sub_list); |
| 286 | spin_unlock_bh(&con->sub_lock); | 329 | spin_unlock_bh(&con->sub_lock); |
| @@ -426,13 +469,14 @@ static void tipc_clean_outqueues(struct tipc_conn *con) | |||
| 426 | /* tipc_conn_queue_evt - interrupt level call from a subscription instance | 469 | /* tipc_conn_queue_evt - interrupt level call from a subscription instance |
| 427 | * The queued job is launched in tipc_send_to_sock() | 470 | * The queued job is launched in tipc_send_to_sock() |
| 428 | */ | 471 | */ |
| 429 | void tipc_conn_queue_evt(struct tipc_server *s, int conid, | 472 | void tipc_conn_queue_evt(struct net *net, int conid, |
| 430 | u32 event, struct tipc_event *evt) | 473 | u32 event, struct tipc_event *evt) |
| 431 | { | 474 | { |
| 475 | struct tipc_server *srv = tipc_topsrv(net); | ||
| 432 | struct outqueue_entry *e; | 476 | struct outqueue_entry *e; |
| 433 | struct tipc_conn *con; | 477 | struct tipc_conn *con; |
| 434 | 478 | ||
| 435 | con = tipc_conn_lookup(s, conid); | 479 | con = tipc_conn_lookup(srv, conid); |
| 436 | if (!con) | 480 | if (!con) |
| 437 | return; | 481 | return; |
| 438 | 482 | ||
| @@ -448,7 +492,7 @@ void tipc_conn_queue_evt(struct tipc_server *s, int conid, | |||
| 448 | list_add_tail(&e->list, &con->outqueue); | 492 | list_add_tail(&e->list, &con->outqueue); |
| 449 | spin_unlock_bh(&con->outqueue_lock); | 493 | spin_unlock_bh(&con->outqueue_lock); |
| 450 | 494 | ||
| 451 | if (queue_work(s->send_wq, &con->swork)) | 495 | if (queue_work(srv->send_wq, &con->swork)) |
| 452 | return; | 496 | return; |
| 453 | err: | 497 | err: |
| 454 | conn_put(con); | 498 | conn_put(con); |
| @@ -620,41 +664,71 @@ static int tipc_work_start(struct tipc_server *s) | |||
| 620 | return 0; | 664 | return 0; |
| 621 | } | 665 | } |
| 622 | 666 | ||
| 623 | int tipc_server_start(struct tipc_server *s) | 667 | int tipc_topsrv_start(struct net *net) |
| 624 | { | 668 | { |
| 669 | struct tipc_net *tn = tipc_net(net); | ||
| 670 | const char name[] = "topology_server"; | ||
| 671 | struct sockaddr_tipc *saddr; | ||
| 672 | struct tipc_server *srv; | ||
| 625 | int ret; | 673 | int ret; |
| 626 | 674 | ||
| 627 | spin_lock_init(&s->idr_lock); | 675 | saddr = kzalloc(sizeof(*saddr), GFP_ATOMIC); |
| 628 | idr_init(&s->conn_idr); | 676 | if (!saddr) |
| 629 | s->idr_in_use = 0; | 677 | return -ENOMEM; |
| 678 | saddr->family = AF_TIPC; | ||
| 679 | saddr->addrtype = TIPC_ADDR_NAMESEQ; | ||
| 680 | saddr->addr.nameseq.type = TIPC_TOP_SRV; | ||
| 681 | saddr->addr.nameseq.lower = TIPC_TOP_SRV; | ||
| 682 | saddr->addr.nameseq.upper = TIPC_TOP_SRV; | ||
| 683 | saddr->scope = TIPC_NODE_SCOPE; | ||
| 684 | |||
| 685 | srv = kzalloc(sizeof(*srv), GFP_ATOMIC); | ||
| 686 | if (!srv) { | ||
| 687 | kfree(saddr); | ||
| 688 | return -ENOMEM; | ||
| 689 | } | ||
| 690 | srv->net = net; | ||
| 691 | srv->saddr = saddr; | ||
| 692 | srv->max_rcvbuf_size = sizeof(struct tipc_subscr); | ||
| 693 | |||
| 694 | strncpy(srv->name, name, strlen(name) + 1); | ||
| 695 | tn->topsrv = srv; | ||
| 696 | atomic_set(&tn->subscription_count, 0); | ||
| 697 | |||
| 698 | spin_lock_init(&srv->idr_lock); | ||
| 699 | idr_init(&srv->conn_idr); | ||
| 700 | srv->idr_in_use = 0; | ||
| 630 | 701 | ||
| 631 | ret = tipc_work_start(s); | 702 | ret = tipc_work_start(srv); |
| 632 | if (ret < 0) | 703 | if (ret < 0) |
| 633 | return ret; | 704 | return ret; |
| 634 | 705 | ||
| 635 | ret = tipc_open_listening_sock(s); | 706 | ret = tipc_open_listening_sock(srv); |
| 636 | if (ret < 0) | 707 | if (ret < 0) |
| 637 | tipc_work_stop(s); | 708 | tipc_work_stop(srv); |
| 638 | 709 | ||
| 639 | return ret; | 710 | return ret; |
| 640 | } | 711 | } |
| 641 | 712 | ||
| 642 | void tipc_server_stop(struct tipc_server *s) | 713 | void tipc_topsrv_stop(struct net *net) |
| 643 | { | 714 | { |
| 715 | struct tipc_server *srv = tipc_topsrv(net); | ||
| 644 | struct tipc_conn *con; | 716 | struct tipc_conn *con; |
| 645 | int id; | 717 | int id; |
| 646 | 718 | ||
| 647 | spin_lock_bh(&s->idr_lock); | 719 | spin_lock_bh(&srv->idr_lock); |
| 648 | for (id = 0; s->idr_in_use; id++) { | 720 | for (id = 0; srv->idr_in_use; id++) { |
| 649 | con = idr_find(&s->conn_idr, id); | 721 | con = idr_find(&srv->conn_idr, id); |
| 650 | if (con) { | 722 | if (con) { |
| 651 | spin_unlock_bh(&s->idr_lock); | 723 | spin_unlock_bh(&srv->idr_lock); |
| 652 | tipc_close_conn(con); | 724 | tipc_close_conn(con); |
| 653 | spin_lock_bh(&s->idr_lock); | 725 | spin_lock_bh(&srv->idr_lock); |
| 654 | } | 726 | } |
| 655 | } | 727 | } |
| 656 | spin_unlock_bh(&s->idr_lock); | 728 | spin_unlock_bh(&srv->idr_lock); |
| 657 | 729 | ||
| 658 | tipc_work_stop(s); | 730 | tipc_work_stop(srv); |
| 659 | idr_destroy(&s->conn_idr); | 731 | idr_destroy(&srv->conn_idr); |
| 732 | kfree(srv->saddr); | ||
| 733 | kfree(srv); | ||
| 660 | } | 734 | } |
diff --git a/net/tipc/server.h b/net/tipc/server.h index 995b79591ffe..ce93b6d68e41 100644 --- a/net/tipc/server.h +++ b/net/tipc/server.h | |||
| @@ -47,45 +47,11 @@ | |||
| 47 | #define TIPC_SUB_NODE_SCOPE 0x40 | 47 | #define TIPC_SUB_NODE_SCOPE 0x40 |
| 48 | #define TIPC_SUB_NO_STATUS 0x80 | 48 | #define TIPC_SUB_NO_STATUS 0x80 |
| 49 | 49 | ||
| 50 | /** | 50 | void tipc_conn_queue_evt(struct net *net, int conid, |
| 51 | * struct tipc_server - TIPC server structure | ||
| 52 | * @conn_idr: identifier set of connection | ||
| 53 | * @idr_lock: protect the connection identifier set | ||
| 54 | * @idr_in_use: amount of allocated identifier entry | ||
| 55 | * @net: network namspace instance | ||
| 56 | * @rcvbuf_cache: memory cache of server receive buffer | ||
| 57 | * @rcv_wq: receive workqueue | ||
| 58 | * @send_wq: send workqueue | ||
| 59 | * @max_rcvbuf_size: maximum permitted receive message length | ||
| 60 | * @tipc_conn_new: callback will be called when new connection is incoming | ||
| 61 | * @tipc_conn_release: callback will be called before releasing the connection | ||
| 62 | * @tipc_conn_recvmsg: callback will be called when message arrives | ||
| 63 | * @saddr: TIPC server address | ||
| 64 | * @name: server name | ||
| 65 | * @imp: message importance | ||
| 66 | * @type: socket type | ||
| 67 | */ | ||
| 68 | struct tipc_server { | ||
| 69 | struct idr conn_idr; | ||
| 70 | spinlock_t idr_lock; | ||
| 71 | int idr_in_use; | ||
| 72 | struct net *net; | ||
| 73 | struct workqueue_struct *rcv_wq; | ||
| 74 | struct workqueue_struct *send_wq; | ||
| 75 | int max_rcvbuf_size; | ||
| 76 | struct sockaddr_tipc *saddr; | ||
| 77 | char name[TIPC_SERVER_NAME_LEN]; | ||
| 78 | }; | ||
| 79 | |||
| 80 | void tipc_conn_queue_evt(struct tipc_server *s, int conid, | ||
| 81 | u32 event, struct tipc_event *evt); | 51 | u32 event, struct tipc_event *evt); |
| 82 | 52 | ||
| 83 | bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, | 53 | bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, |
| 84 | u32 upper, u32 filter, int *conid); | 54 | u32 upper, u32 filter, int *conid); |
| 85 | void tipc_topsrv_kern_unsubscr(struct net *net, int conid); | 55 | void tipc_topsrv_kern_unsubscr(struct net *net, int conid); |
| 86 | 56 | ||
| 87 | int tipc_server_start(struct tipc_server *s); | ||
| 88 | |||
| 89 | void tipc_server_stop(struct tipc_server *s); | ||
| 90 | |||
| 91 | #endif | 57 | #endif |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 3be1e4b6cbfa..c8146568d04e 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -51,7 +51,7 @@ static void tipc_sub_send_event(struct tipc_subscription *sub, | |||
| 51 | tipc_evt_write(evt, found_upper, found_upper); | 51 | tipc_evt_write(evt, found_upper, found_upper); |
| 52 | tipc_evt_write(evt, port.ref, port); | 52 | tipc_evt_write(evt, port.ref, port); |
| 53 | tipc_evt_write(evt, port.node, node); | 53 | tipc_evt_write(evt, port.node, node); |
| 54 | tipc_conn_queue_evt(sub->server, sub->conid, event, evt); | 54 | tipc_conn_queue_evt(sub->net, sub->conid, event, evt); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| @@ -114,14 +114,7 @@ static void tipc_sub_timeout(struct timer_list *t) | |||
| 114 | 114 | ||
| 115 | static void tipc_sub_kref_release(struct kref *kref) | 115 | static void tipc_sub_kref_release(struct kref *kref) |
| 116 | { | 116 | { |
| 117 | struct tipc_subscription *sub; | 117 | kfree(container_of(kref, struct tipc_subscription, kref)); |
| 118 | struct tipc_net *tn; | ||
| 119 | |||
| 120 | sub = container_of(kref, struct tipc_subscription, kref); | ||
| 121 | tn = tipc_net(sub->server->net); | ||
| 122 | |||
| 123 | atomic_dec(&tn->subscription_count); | ||
| 124 | kfree(sub); | ||
| 125 | } | 118 | } |
| 126 | 119 | ||
| 127 | void tipc_sub_put(struct tipc_subscription *subscription) | 120 | void tipc_sub_put(struct tipc_subscription *subscription) |
| @@ -134,19 +127,14 @@ void tipc_sub_get(struct tipc_subscription *subscription) | |||
| 134 | kref_get(&subscription->kref); | 127 | kref_get(&subscription->kref); |
| 135 | } | 128 | } |
| 136 | 129 | ||
| 137 | struct tipc_subscription *tipc_sub_subscribe(struct tipc_server *srv, | 130 | struct tipc_subscription *tipc_sub_subscribe(struct net *net, |
| 138 | struct tipc_subscr *s, | 131 | struct tipc_subscr *s, |
| 139 | int conid) | 132 | int conid) |
| 140 | { | 133 | { |
| 141 | struct tipc_net *tn = tipc_net(srv->net); | ||
| 142 | u32 filter = tipc_sub_read(s, filter); | 134 | u32 filter = tipc_sub_read(s, filter); |
| 143 | struct tipc_subscription *sub; | 135 | struct tipc_subscription *sub; |
| 144 | u32 timeout; | 136 | u32 timeout; |
| 145 | 137 | ||
| 146 | if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCR) { | ||
| 147 | pr_warn("Subscription rejected, max (%u)\n", TIPC_MAX_SUBSCR); | ||
| 148 | return NULL; | ||
| 149 | } | ||
| 150 | if ((filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE) || | 138 | if ((filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE) || |
| 151 | (tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))) { | 139 | (tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))) { |
| 152 | pr_warn("Subscription rejected, illegal request\n"); | 140 | pr_warn("Subscription rejected, illegal request\n"); |
| @@ -157,12 +145,11 @@ struct tipc_subscription *tipc_sub_subscribe(struct tipc_server *srv, | |||
| 157 | pr_warn("Subscription rejected, no memory\n"); | 145 | pr_warn("Subscription rejected, no memory\n"); |
| 158 | return NULL; | 146 | return NULL; |
| 159 | } | 147 | } |
| 160 | sub->server = srv; | 148 | sub->net = net; |
| 161 | sub->conid = conid; | 149 | sub->conid = conid; |
| 162 | sub->inactive = false; | 150 | sub->inactive = false; |
| 163 | memcpy(&sub->evt.s, s, sizeof(*s)); | 151 | memcpy(&sub->evt.s, s, sizeof(*s)); |
| 164 | spin_lock_init(&sub->lock); | 152 | spin_lock_init(&sub->lock); |
| 165 | atomic_inc(&tn->subscription_count); | ||
| 166 | kref_init(&sub->kref); | 153 | kref_init(&sub->kref); |
| 167 | tipc_nametbl_subscribe(sub); | 154 | tipc_nametbl_subscribe(sub); |
| 168 | timer_setup(&sub->timer, tipc_sub_timeout, 0); | 155 | timer_setup(&sub->timer, tipc_sub_timeout, 0); |
| @@ -180,46 +167,3 @@ void tipc_sub_unsubscribe(struct tipc_subscription *sub) | |||
| 180 | list_del(&sub->sub_list); | 167 | list_del(&sub->sub_list); |
| 181 | tipc_sub_put(sub); | 168 | tipc_sub_put(sub); |
| 182 | } | 169 | } |
| 183 | |||
| 184 | int tipc_topsrv_start(struct net *net) | ||
| 185 | { | ||
| 186 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 187 | const char name[] = "topology_server"; | ||
| 188 | struct sockaddr_tipc *saddr; | ||
| 189 | struct tipc_server *topsrv; | ||
| 190 | |||
| 191 | saddr = kzalloc(sizeof(*saddr), GFP_ATOMIC); | ||
| 192 | if (!saddr) | ||
| 193 | return -ENOMEM; | ||
| 194 | saddr->family = AF_TIPC; | ||
| 195 | saddr->addrtype = TIPC_ADDR_NAMESEQ; | ||
| 196 | saddr->addr.nameseq.type = TIPC_TOP_SRV; | ||
| 197 | saddr->addr.nameseq.lower = TIPC_TOP_SRV; | ||
| 198 | saddr->addr.nameseq.upper = TIPC_TOP_SRV; | ||
| 199 | saddr->scope = TIPC_NODE_SCOPE; | ||
| 200 | |||
| 201 | topsrv = kzalloc(sizeof(*topsrv), GFP_ATOMIC); | ||
| 202 | if (!topsrv) { | ||
| 203 | kfree(saddr); | ||
| 204 | return -ENOMEM; | ||
| 205 | } | ||
| 206 | topsrv->net = net; | ||
| 207 | topsrv->saddr = saddr; | ||
| 208 | topsrv->max_rcvbuf_size = sizeof(struct tipc_subscr); | ||
| 209 | |||
| 210 | strncpy(topsrv->name, name, strlen(name) + 1); | ||
| 211 | tn->topsrv = topsrv; | ||
| 212 | atomic_set(&tn->subscription_count, 0); | ||
| 213 | |||
| 214 | return tipc_server_start(topsrv); | ||
| 215 | } | ||
| 216 | |||
| 217 | void tipc_topsrv_stop(struct net *net) | ||
| 218 | { | ||
| 219 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 220 | struct tipc_server *topsrv = tn->topsrv; | ||
| 221 | |||
| 222 | tipc_server_stop(topsrv); | ||
| 223 | kfree(topsrv->saddr); | ||
| 224 | kfree(topsrv); | ||
| 225 | } | ||
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index 720932896ba6..82ba61afe638 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h | |||
| @@ -56,7 +56,7 @@ struct tipc_conn; | |||
| 56 | */ | 56 | */ |
| 57 | struct tipc_subscription { | 57 | struct tipc_subscription { |
| 58 | struct kref kref; | 58 | struct kref kref; |
| 59 | struct tipc_server *server; | 59 | struct net *net; |
| 60 | struct timer_list timer; | 60 | struct timer_list timer; |
| 61 | struct list_head nameseq_list; | 61 | struct list_head nameseq_list; |
| 62 | struct list_head sub_list; | 62 | struct list_head sub_list; |
| @@ -66,7 +66,7 @@ struct tipc_subscription { | |||
| 66 | spinlock_t lock; /* serialize up/down and timer events */ | 66 | spinlock_t lock; /* serialize up/down and timer events */ |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | struct tipc_subscription *tipc_sub_subscribe(struct tipc_server *srv, | 69 | struct tipc_subscription *tipc_sub_subscribe(struct net *net, |
| 70 | struct tipc_subscr *s, | 70 | struct tipc_subscr *s, |
| 71 | int conid); | 71 | int conid); |
| 72 | void tipc_sub_unsubscribe(struct tipc_subscription *sub); | 72 | void tipc_sub_unsubscribe(struct tipc_subscription *sub); |
