diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bearer.c | 7 | ||||
-rw-r--r-- | net/tipc/config.c | 11 | ||||
-rw-r--r-- | net/tipc/core.c | 109 | ||||
-rw-r--r-- | net/tipc/core.h | 2 | ||||
-rw-r--r-- | net/tipc/handler.c | 1 | ||||
-rw-r--r-- | net/tipc/link.c | 7 | ||||
-rw-r--r-- | net/tipc/name_table.c | 40 | ||||
-rw-r--r-- | net/tipc/netlink.c | 8 | ||||
-rw-r--r-- | net/tipc/ref.c | 3 | ||||
-rw-r--r-- | net/tipc/server.c | 19 | ||||
-rw-r--r-- | net/tipc/server.h | 2 | ||||
-rw-r--r-- | net/tipc/socket.c | 12 | ||||
-rw-r--r-- | net/tipc/subscr.c | 48 |
13 files changed, 136 insertions, 133 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index a38c89969c68..574b86193b15 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -610,8 +610,13 @@ static struct notifier_block notifier = { | |||
610 | 610 | ||
611 | int tipc_bearer_setup(void) | 611 | int tipc_bearer_setup(void) |
612 | { | 612 | { |
613 | int err; | ||
614 | |||
615 | err = register_netdevice_notifier(¬ifier); | ||
616 | if (err) | ||
617 | return err; | ||
613 | dev_add_pack(&tipc_packet_type); | 618 | dev_add_pack(&tipc_packet_type); |
614 | return register_netdevice_notifier(¬ifier); | 619 | return 0; |
615 | } | 620 | } |
616 | 621 | ||
617 | void tipc_bearer_cleanup(void) | 622 | void tipc_bearer_cleanup(void) |
diff --git a/net/tipc/config.c b/net/tipc/config.c index c301a9a592d8..e6d721692ae0 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
@@ -181,7 +181,7 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
181 | if (tipc_own_addr) | 181 | if (tipc_own_addr) |
182 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 182 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
183 | " (cannot change node address once assigned)"); | 183 | " (cannot change node address once assigned)"); |
184 | tipc_core_start_net(addr); | 184 | tipc_net_start(addr); |
185 | return tipc_cfg_reply_none(); | 185 | return tipc_cfg_reply_none(); |
186 | } | 186 | } |
187 | 187 | ||
@@ -376,7 +376,6 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
376 | struct tipc_cfg_msg_hdr *req_hdr; | 376 | struct tipc_cfg_msg_hdr *req_hdr; |
377 | struct tipc_cfg_msg_hdr *rep_hdr; | 377 | struct tipc_cfg_msg_hdr *rep_hdr; |
378 | struct sk_buff *rep_buf; | 378 | struct sk_buff *rep_buf; |
379 | int ret; | ||
380 | 379 | ||
381 | /* Validate configuration message header (ignore invalid message) */ | 380 | /* Validate configuration message header (ignore invalid message) */ |
382 | req_hdr = (struct tipc_cfg_msg_hdr *)buf; | 381 | req_hdr = (struct tipc_cfg_msg_hdr *)buf; |
@@ -398,12 +397,8 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
398 | memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); | 397 | memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); |
399 | rep_hdr->tcm_len = htonl(rep_buf->len); | 398 | rep_hdr->tcm_len = htonl(rep_buf->len); |
400 | rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); | 399 | rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); |
401 | 400 | tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data, | |
402 | ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data, | 401 | rep_buf->len); |
403 | rep_buf->len); | ||
404 | if (ret < 0) | ||
405 | pr_err("Sending cfg reply message failed, no memory\n"); | ||
406 | |||
407 | kfree_skb(rep_buf); | 402 | kfree_skb(rep_buf); |
408 | } | 403 | } |
409 | } | 404 | } |
diff --git a/net/tipc/core.c b/net/tipc/core.c index f9e88d8b04ca..80c20647b3d2 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -77,37 +77,13 @@ struct sk_buff *tipc_buf_acquire(u32 size) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * tipc_core_stop_net - shut down TIPC networking sub-systems | ||
81 | */ | ||
82 | static void tipc_core_stop_net(void) | ||
83 | { | ||
84 | tipc_net_stop(); | ||
85 | tipc_bearer_cleanup(); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * start_net - start TIPC networking sub-systems | ||
90 | */ | ||
91 | int tipc_core_start_net(unsigned long addr) | ||
92 | { | ||
93 | int res; | ||
94 | |||
95 | tipc_net_start(addr); | ||
96 | res = tipc_bearer_setup(); | ||
97 | if (res < 0) | ||
98 | goto err; | ||
99 | return res; | ||
100 | |||
101 | err: | ||
102 | tipc_core_stop_net(); | ||
103 | return res; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode | 80 | * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode |
108 | */ | 81 | */ |
109 | static void tipc_core_stop(void) | 82 | static void tipc_core_stop(void) |
110 | { | 83 | { |
84 | tipc_handler_stop(); | ||
85 | tipc_net_stop(); | ||
86 | tipc_bearer_cleanup(); | ||
111 | tipc_netlink_stop(); | 87 | tipc_netlink_stop(); |
112 | tipc_cfg_stop(); | 88 | tipc_cfg_stop(); |
113 | tipc_subscr_stop(); | 89 | tipc_subscr_stop(); |
@@ -122,30 +98,65 @@ static void tipc_core_stop(void) | |||
122 | */ | 98 | */ |
123 | static int tipc_core_start(void) | 99 | static int tipc_core_start(void) |
124 | { | 100 | { |
125 | int res; | 101 | int err; |
126 | 102 | ||
127 | get_random_bytes(&tipc_random, sizeof(tipc_random)); | 103 | get_random_bytes(&tipc_random, sizeof(tipc_random)); |
128 | 104 | ||
129 | res = tipc_handler_start(); | 105 | err = tipc_handler_start(); |
130 | if (!res) | 106 | if (err) |
131 | res = tipc_ref_table_init(tipc_max_ports, tipc_random); | 107 | goto out_handler; |
132 | if (!res) | 108 | |
133 | res = tipc_nametbl_init(); | 109 | err = tipc_ref_table_init(tipc_max_ports, tipc_random); |
134 | if (!res) | 110 | if (err) |
135 | res = tipc_netlink_start(); | 111 | goto out_reftbl; |
136 | if (!res) | 112 | |
137 | res = tipc_socket_init(); | 113 | err = tipc_nametbl_init(); |
138 | if (!res) | 114 | if (err) |
139 | res = tipc_register_sysctl(); | 115 | goto out_nametbl; |
140 | if (!res) | 116 | |
141 | res = tipc_subscr_start(); | 117 | err = tipc_netlink_start(); |
142 | if (!res) | 118 | if (err) |
143 | res = tipc_cfg_init(); | 119 | goto out_netlink; |
144 | if (res) { | 120 | |
145 | tipc_handler_stop(); | 121 | err = tipc_socket_init(); |
146 | tipc_core_stop(); | 122 | if (err) |
147 | } | 123 | goto out_socket; |
148 | return res; | 124 | |
125 | err = tipc_register_sysctl(); | ||
126 | if (err) | ||
127 | goto out_sysctl; | ||
128 | |||
129 | err = tipc_subscr_start(); | ||
130 | if (err) | ||
131 | goto out_subscr; | ||
132 | |||
133 | err = tipc_cfg_init(); | ||
134 | if (err) | ||
135 | goto out_cfg; | ||
136 | |||
137 | err = tipc_bearer_setup(); | ||
138 | if (err) | ||
139 | goto out_bearer; | ||
140 | |||
141 | return 0; | ||
142 | out_bearer: | ||
143 | tipc_cfg_stop(); | ||
144 | out_cfg: | ||
145 | tipc_subscr_stop(); | ||
146 | out_subscr: | ||
147 | tipc_unregister_sysctl(); | ||
148 | out_sysctl: | ||
149 | tipc_socket_stop(); | ||
150 | out_socket: | ||
151 | tipc_netlink_stop(); | ||
152 | out_netlink: | ||
153 | tipc_nametbl_stop(); | ||
154 | out_nametbl: | ||
155 | tipc_ref_table_stop(); | ||
156 | out_reftbl: | ||
157 | tipc_handler_stop(); | ||
158 | out_handler: | ||
159 | return err; | ||
149 | } | 160 | } |
150 | 161 | ||
151 | static int __init tipc_init(void) | 162 | static int __init tipc_init(void) |
@@ -174,8 +185,6 @@ static int __init tipc_init(void) | |||
174 | 185 | ||
175 | static void __exit tipc_exit(void) | 186 | static void __exit tipc_exit(void) |
176 | { | 187 | { |
177 | tipc_handler_stop(); | ||
178 | tipc_core_stop_net(); | ||
179 | tipc_core_stop(); | 188 | tipc_core_stop(); |
180 | pr_info("Deactivated\n"); | 189 | pr_info("Deactivated\n"); |
181 | } | 190 | } |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 1ff477b0450d..4dfe137587bb 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -90,7 +90,6 @@ extern int tipc_random __read_mostly; | |||
90 | /* | 90 | /* |
91 | * Routines available to privileged subsystems | 91 | * Routines available to privileged subsystems |
92 | */ | 92 | */ |
93 | int tipc_core_start_net(unsigned long); | ||
94 | int tipc_handler_start(void); | 93 | int tipc_handler_start(void); |
95 | void tipc_handler_stop(void); | 94 | void tipc_handler_stop(void); |
96 | int tipc_netlink_start(void); | 95 | int tipc_netlink_start(void); |
@@ -192,6 +191,7 @@ static inline void k_term_timer(struct timer_list *timer) | |||
192 | 191 | ||
193 | struct tipc_skb_cb { | 192 | struct tipc_skb_cb { |
194 | void *handle; | 193 | void *handle; |
194 | bool deferred; | ||
195 | }; | 195 | }; |
196 | 196 | ||
197 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) | 197 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index e4bc8a296744..1fabf160501f 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
@@ -58,7 +58,6 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) | |||
58 | 58 | ||
59 | spin_lock_bh(&qitem_lock); | 59 | spin_lock_bh(&qitem_lock); |
60 | if (!handler_enabled) { | 60 | if (!handler_enabled) { |
61 | pr_err("Signal request ignored by handler\n"); | ||
62 | spin_unlock_bh(&qitem_lock); | 61 | spin_unlock_bh(&qitem_lock); |
63 | return -ENOPROTOOPT; | 62 | return -ENOPROTOOPT; |
64 | } | 63 | } |
diff --git a/net/tipc/link.c b/net/tipc/link.c index d4b5de41b682..da6018beb6eb 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1391,6 +1391,12 @@ static int link_recv_buf_validate(struct sk_buff *buf) | |||
1391 | u32 hdr_size; | 1391 | u32 hdr_size; |
1392 | u32 min_hdr_size; | 1392 | u32 min_hdr_size; |
1393 | 1393 | ||
1394 | /* If this packet comes from the defer queue, the skb has already | ||
1395 | * been validated | ||
1396 | */ | ||
1397 | if (unlikely(TIPC_SKB_CB(buf)->deferred)) | ||
1398 | return 1; | ||
1399 | |||
1394 | if (unlikely(buf->len < MIN_H_SIZE)) | 1400 | if (unlikely(buf->len < MIN_H_SIZE)) |
1395 | return 0; | 1401 | return 0; |
1396 | 1402 | ||
@@ -1703,6 +1709,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, | |||
1703 | &l_ptr->newest_deferred_in, buf)) { | 1709 | &l_ptr->newest_deferred_in, buf)) { |
1704 | l_ptr->deferred_inqueue_sz++; | 1710 | l_ptr->deferred_inqueue_sz++; |
1705 | l_ptr->stats.deferred_recv++; | 1711 | l_ptr->stats.deferred_recv++; |
1712 | TIPC_SKB_CB(buf)->deferred = true; | ||
1706 | if ((l_ptr->deferred_inqueue_sz % 16) == 1) | 1713 | if ((l_ptr->deferred_inqueue_sz % 16) == 1) |
1707 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); | 1714 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); |
1708 | } else | 1715 | } else |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 92a1533af4e0..042e8e3cabc0 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -941,20 +941,48 @@ int tipc_nametbl_init(void) | |||
941 | return 0; | 941 | return 0; |
942 | } | 942 | } |
943 | 943 | ||
944 | void tipc_nametbl_stop(void) | 944 | /** |
945 | * tipc_purge_publications - remove all publications for a given type | ||
946 | * | ||
947 | * tipc_nametbl_lock must be held when calling this function | ||
948 | */ | ||
949 | static void tipc_purge_publications(struct name_seq *seq) | ||
945 | { | 950 | { |
946 | u32 i; | 951 | struct publication *publ, *safe; |
952 | struct sub_seq *sseq; | ||
953 | struct name_info *info; | ||
947 | 954 | ||
948 | if (!table.types) | 955 | if (!seq->sseqs) { |
956 | nameseq_delete_empty(seq); | ||
949 | return; | 957 | return; |
958 | } | ||
959 | sseq = seq->sseqs; | ||
960 | info = sseq->info; | ||
961 | list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { | ||
962 | tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, | ||
963 | publ->ref, publ->key); | ||
964 | } | ||
965 | } | ||
966 | |||
967 | void tipc_nametbl_stop(void) | ||
968 | { | ||
969 | u32 i; | ||
970 | struct name_seq *seq; | ||
971 | struct hlist_head *seq_head; | ||
972 | struct hlist_node *safe; | ||
950 | 973 | ||
951 | /* Verify name table is empty, then release it */ | 974 | /* Verify name table is empty and purge any lingering |
975 | * publications, then release the name table | ||
976 | */ | ||
952 | write_lock_bh(&tipc_nametbl_lock); | 977 | write_lock_bh(&tipc_nametbl_lock); |
953 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 978 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
954 | if (hlist_empty(&table.types[i])) | 979 | if (hlist_empty(&table.types[i])) |
955 | continue; | 980 | continue; |
956 | pr_err("nametbl_stop(): orphaned hash chain detected\n"); | 981 | seq_head = &table.types[i]; |
957 | break; | 982 | hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) { |
983 | tipc_purge_publications(seq); | ||
984 | } | ||
985 | continue; | ||
958 | } | 986 | } |
959 | kfree(table.types); | 987 | kfree(table.types); |
960 | table.types = NULL; | 988 | table.types = NULL; |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 9f72a6376362..3aaf73de9e2d 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -83,8 +83,6 @@ static struct genl_ops tipc_genl_ops[] = { | |||
83 | }, | 83 | }, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static int tipc_genl_family_registered; | ||
87 | |||
88 | int tipc_netlink_start(void) | 86 | int tipc_netlink_start(void) |
89 | { | 87 | { |
90 | int res; | 88 | int res; |
@@ -94,16 +92,10 @@ int tipc_netlink_start(void) | |||
94 | pr_err("Failed to register netlink interface\n"); | 92 | pr_err("Failed to register netlink interface\n"); |
95 | return res; | 93 | return res; |
96 | } | 94 | } |
97 | |||
98 | tipc_genl_family_registered = 1; | ||
99 | return 0; | 95 | return 0; |
100 | } | 96 | } |
101 | 97 | ||
102 | void tipc_netlink_stop(void) | 98 | void tipc_netlink_stop(void) |
103 | { | 99 | { |
104 | if (!tipc_genl_family_registered) | ||
105 | return; | ||
106 | |||
107 | genl_unregister_family(&tipc_genl_family); | 100 | genl_unregister_family(&tipc_genl_family); |
108 | tipc_genl_family_registered = 0; | ||
109 | } | 101 | } |
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 2a2a938dc22c..de3d593e2fee 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
@@ -126,9 +126,6 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
126 | */ | 126 | */ |
127 | void tipc_ref_table_stop(void) | 127 | void tipc_ref_table_stop(void) |
128 | { | 128 | { |
129 | if (!tipc_ref_table.entries) | ||
130 | return; | ||
131 | |||
132 | vfree(tipc_ref_table.entries); | 129 | vfree(tipc_ref_table.entries); |
133 | tipc_ref_table.entries = NULL; | 130 | tipc_ref_table.entries = NULL; |
134 | } | 131 | } |
diff --git a/net/tipc/server.c b/net/tipc/server.c index b635ca347a87..646a930eefbf 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
@@ -87,7 +87,6 @@ static void tipc_clean_outqueues(struct tipc_conn *con); | |||
87 | static void tipc_conn_kref_release(struct kref *kref) | 87 | static void tipc_conn_kref_release(struct kref *kref) |
88 | { | 88 | { |
89 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); | 89 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); |
90 | struct tipc_server *s = con->server; | ||
91 | 90 | ||
92 | if (con->sock) { | 91 | if (con->sock) { |
93 | tipc_sock_release_local(con->sock); | 92 | tipc_sock_release_local(con->sock); |
@@ -95,10 +94,6 @@ static void tipc_conn_kref_release(struct kref *kref) | |||
95 | } | 94 | } |
96 | 95 | ||
97 | tipc_clean_outqueues(con); | 96 | tipc_clean_outqueues(con); |
98 | |||
99 | if (con->conid) | ||
100 | s->tipc_conn_shutdown(con->conid, con->usr_data); | ||
101 | |||
102 | kfree(con); | 97 | kfree(con); |
103 | } | 98 | } |
104 | 99 | ||
@@ -181,6 +176,9 @@ static void tipc_close_conn(struct tipc_conn *con) | |||
181 | struct tipc_server *s = con->server; | 176 | struct tipc_server *s = con->server; |
182 | 177 | ||
183 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { | 178 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { |
179 | if (con->conid) | ||
180 | s->tipc_conn_shutdown(con->conid, con->usr_data); | ||
181 | |||
184 | spin_lock_bh(&s->idr_lock); | 182 | spin_lock_bh(&s->idr_lock); |
185 | idr_remove(&s->conn_idr, con->conid); | 183 | idr_remove(&s->conn_idr, con->conid); |
186 | s->idr_in_use--; | 184 | s->idr_in_use--; |
@@ -429,10 +427,12 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, | |||
429 | list_add_tail(&e->list, &con->outqueue); | 427 | list_add_tail(&e->list, &con->outqueue); |
430 | spin_unlock_bh(&con->outqueue_lock); | 428 | spin_unlock_bh(&con->outqueue_lock); |
431 | 429 | ||
432 | if (test_bit(CF_CONNECTED, &con->flags)) | 430 | if (test_bit(CF_CONNECTED, &con->flags)) { |
433 | if (!queue_work(s->send_wq, &con->swork)) | 431 | if (!queue_work(s->send_wq, &con->swork)) |
434 | conn_put(con); | 432 | conn_put(con); |
435 | 433 | } else { | |
434 | conn_put(con); | ||
435 | } | ||
436 | return 0; | 436 | return 0; |
437 | } | 437 | } |
438 | 438 | ||
@@ -573,7 +573,6 @@ int tipc_server_start(struct tipc_server *s) | |||
573 | kmem_cache_destroy(s->rcvbuf_cache); | 573 | kmem_cache_destroy(s->rcvbuf_cache); |
574 | return ret; | 574 | return ret; |
575 | } | 575 | } |
576 | s->enabled = 1; | ||
577 | return ret; | 576 | return ret; |
578 | } | 577 | } |
579 | 578 | ||
@@ -583,10 +582,6 @@ void tipc_server_stop(struct tipc_server *s) | |||
583 | int total = 0; | 582 | int total = 0; |
584 | int id; | 583 | int id; |
585 | 584 | ||
586 | if (!s->enabled) | ||
587 | return; | ||
588 | |||
589 | s->enabled = 0; | ||
590 | spin_lock_bh(&s->idr_lock); | 585 | spin_lock_bh(&s->idr_lock); |
591 | for (id = 0; total < s->idr_in_use; id++) { | 586 | for (id = 0; total < s->idr_in_use; id++) { |
592 | con = idr_find(&s->conn_idr, id); | 587 | con = idr_find(&s->conn_idr, id); |
diff --git a/net/tipc/server.h b/net/tipc/server.h index 98b23f20bc0f..be817b0b547e 100644 --- a/net/tipc/server.h +++ b/net/tipc/server.h | |||
@@ -56,7 +56,6 @@ | |||
56 | * @name: server name | 56 | * @name: server name |
57 | * @imp: message importance | 57 | * @imp: message importance |
58 | * @type: socket type | 58 | * @type: socket type |
59 | * @enabled: identify whether server is launched or not | ||
60 | */ | 59 | */ |
61 | struct tipc_server { | 60 | struct tipc_server { |
62 | struct idr conn_idr; | 61 | struct idr conn_idr; |
@@ -74,7 +73,6 @@ struct tipc_server { | |||
74 | const char name[TIPC_SERVER_NAME_LEN]; | 73 | const char name[TIPC_SERVER_NAME_LEN]; |
75 | int imp; | 74 | int imp; |
76 | int type; | 75 | int type; |
77 | int enabled; | ||
78 | }; | 76 | }; |
79 | 77 | ||
80 | int tipc_conn_sendmsg(struct tipc_server *s, int conid, | 78 | int tipc_conn_sendmsg(struct tipc_server *s, int conid, |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index aab4948f0aff..0ed0eaa62f29 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -70,8 +70,6 @@ static const struct proto_ops msg_ops; | |||
70 | static struct proto tipc_proto; | 70 | static struct proto tipc_proto; |
71 | static struct proto tipc_proto_kern; | 71 | static struct proto tipc_proto_kern; |
72 | 72 | ||
73 | static int sockets_enabled; | ||
74 | |||
75 | /* | 73 | /* |
76 | * Revised TIPC socket locking policy: | 74 | * Revised TIPC socket locking policy: |
77 | * | 75 | * |
@@ -999,7 +997,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long timeo) | |||
999 | 997 | ||
1000 | for (;;) { | 998 | for (;;) { |
1001 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 999 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1002 | if (skb_queue_empty(&sk->sk_receive_queue)) { | 1000 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { |
1003 | if (sock->state == SS_DISCONNECTING) { | 1001 | if (sock->state == SS_DISCONNECTING) { |
1004 | err = -ENOTCONN; | 1002 | err = -ENOTCONN; |
1005 | break; | 1003 | break; |
@@ -1625,7 +1623,7 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
1625 | for (;;) { | 1623 | for (;;) { |
1626 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, | 1624 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
1627 | TASK_INTERRUPTIBLE); | 1625 | TASK_INTERRUPTIBLE); |
1628 | if (skb_queue_empty(&sk->sk_receive_queue)) { | 1626 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { |
1629 | release_sock(sk); | 1627 | release_sock(sk); |
1630 | timeo = schedule_timeout(timeo); | 1628 | timeo = schedule_timeout(timeo); |
1631 | lock_sock(sk); | 1629 | lock_sock(sk); |
@@ -2027,8 +2025,6 @@ int tipc_socket_init(void) | |||
2027 | proto_unregister(&tipc_proto); | 2025 | proto_unregister(&tipc_proto); |
2028 | goto out; | 2026 | goto out; |
2029 | } | 2027 | } |
2030 | |||
2031 | sockets_enabled = 1; | ||
2032 | out: | 2028 | out: |
2033 | return res; | 2029 | return res; |
2034 | } | 2030 | } |
@@ -2038,10 +2034,6 @@ int tipc_socket_init(void) | |||
2038 | */ | 2034 | */ |
2039 | void tipc_socket_stop(void) | 2035 | void tipc_socket_stop(void) |
2040 | { | 2036 | { |
2041 | if (!sockets_enabled) | ||
2042 | return; | ||
2043 | |||
2044 | sockets_enabled = 0; | ||
2045 | sock_unregister(tipc_family_ops.family); | 2037 | sock_unregister(tipc_family_ops.family); |
2046 | proto_unregister(&tipc_proto); | 2038 | proto_unregister(&tipc_proto); |
2047 | } | 2039 | } |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 7cb0bd5b1176..642437231ad5 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -96,20 +96,16 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower, | |||
96 | { | 96 | { |
97 | struct tipc_subscriber *subscriber = sub->subscriber; | 97 | struct tipc_subscriber *subscriber = sub->subscriber; |
98 | struct kvec msg_sect; | 98 | struct kvec msg_sect; |
99 | int ret; | ||
100 | 99 | ||
101 | msg_sect.iov_base = (void *)&sub->evt; | 100 | msg_sect.iov_base = (void *)&sub->evt; |
102 | msg_sect.iov_len = sizeof(struct tipc_event); | 101 | msg_sect.iov_len = sizeof(struct tipc_event); |
103 | |||
104 | sub->evt.event = htohl(event, sub->swap); | 102 | sub->evt.event = htohl(event, sub->swap); |
105 | sub->evt.found_lower = htohl(found_lower, sub->swap); | 103 | sub->evt.found_lower = htohl(found_lower, sub->swap); |
106 | sub->evt.found_upper = htohl(found_upper, sub->swap); | 104 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
107 | sub->evt.port.ref = htohl(port_ref, sub->swap); | 105 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
108 | sub->evt.port.node = htohl(node, sub->swap); | 106 | sub->evt.port.node = htohl(node, sub->swap); |
109 | ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, | 107 | tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base, |
110 | msg_sect.iov_base, msg_sect.iov_len); | 108 | msg_sect.iov_len); |
111 | if (ret < 0) | ||
112 | pr_err("Sending subscription event failed, no memory\n"); | ||
113 | } | 109 | } |
114 | 110 | ||
115 | /** | 111 | /** |
@@ -153,14 +149,6 @@ static void subscr_timeout(struct tipc_subscription *sub) | |||
153 | /* The spin lock per subscriber is used to protect its members */ | 149 | /* The spin lock per subscriber is used to protect its members */ |
154 | spin_lock_bh(&subscriber->lock); | 150 | spin_lock_bh(&subscriber->lock); |
155 | 151 | ||
156 | /* Validate if the connection related to the subscriber is | ||
157 | * closed (in case subscriber is terminating) | ||
158 | */ | ||
159 | if (subscriber->conid == 0) { | ||
160 | spin_unlock_bh(&subscriber->lock); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | /* Validate timeout (in case subscription is being cancelled) */ | 152 | /* Validate timeout (in case subscription is being cancelled) */ |
165 | if (sub->timeout == TIPC_WAIT_FOREVER) { | 153 | if (sub->timeout == TIPC_WAIT_FOREVER) { |
166 | spin_unlock_bh(&subscriber->lock); | 154 | spin_unlock_bh(&subscriber->lock); |
@@ -215,9 +203,6 @@ static void subscr_release(struct tipc_subscriber *subscriber) | |||
215 | 203 | ||
216 | spin_lock_bh(&subscriber->lock); | 204 | spin_lock_bh(&subscriber->lock); |
217 | 205 | ||
218 | /* Invalidate subscriber reference */ | ||
219 | subscriber->conid = 0; | ||
220 | |||
221 | /* Destroy any existing subscriptions for subscriber */ | 206 | /* Destroy any existing subscriptions for subscriber */ |
222 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | 207 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, |
223 | subscription_list) { | 208 | subscription_list) { |
@@ -278,9 +263,9 @@ static void subscr_cancel(struct tipc_subscr *s, | |||
278 | * | 263 | * |
279 | * Called with subscriber lock held. | 264 | * Called with subscriber lock held. |
280 | */ | 265 | */ |
281 | static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | 266 | static int subscr_subscribe(struct tipc_subscr *s, |
282 | struct tipc_subscriber *subscriber) | 267 | struct tipc_subscriber *subscriber, |
283 | { | 268 | struct tipc_subscription **sub_p) { |
284 | struct tipc_subscription *sub; | 269 | struct tipc_subscription *sub; |
285 | int swap; | 270 | int swap; |
286 | 271 | ||
@@ -291,23 +276,21 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
291 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { | 276 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
292 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); | 277 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
293 | subscr_cancel(s, subscriber); | 278 | subscr_cancel(s, subscriber); |
294 | return NULL; | 279 | return 0; |
295 | } | 280 | } |
296 | 281 | ||
297 | /* Refuse subscription if global limit exceeded */ | 282 | /* Refuse subscription if global limit exceeded */ |
298 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { | 283 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { |
299 | pr_warn("Subscription rejected, limit reached (%u)\n", | 284 | pr_warn("Subscription rejected, limit reached (%u)\n", |
300 | TIPC_MAX_SUBSCRIPTIONS); | 285 | TIPC_MAX_SUBSCRIPTIONS); |
301 | subscr_terminate(subscriber); | 286 | return -EINVAL; |
302 | return NULL; | ||
303 | } | 287 | } |
304 | 288 | ||
305 | /* Allocate subscription object */ | 289 | /* Allocate subscription object */ |
306 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); | 290 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
307 | if (!sub) { | 291 | if (!sub) { |
308 | pr_warn("Subscription rejected, no memory\n"); | 292 | pr_warn("Subscription rejected, no memory\n"); |
309 | subscr_terminate(subscriber); | 293 | return -ENOMEM; |
310 | return NULL; | ||
311 | } | 294 | } |
312 | 295 | ||
313 | /* Initialize subscription object */ | 296 | /* Initialize subscription object */ |
@@ -321,8 +304,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
321 | (sub->seq.lower > sub->seq.upper)) { | 304 | (sub->seq.lower > sub->seq.upper)) { |
322 | pr_warn("Subscription rejected, illegal request\n"); | 305 | pr_warn("Subscription rejected, illegal request\n"); |
323 | kfree(sub); | 306 | kfree(sub); |
324 | subscr_terminate(subscriber); | 307 | return -EINVAL; |
325 | return NULL; | ||
326 | } | 308 | } |
327 | INIT_LIST_HEAD(&sub->nameseq_list); | 309 | INIT_LIST_HEAD(&sub->nameseq_list); |
328 | list_add(&sub->subscription_list, &subscriber->subscription_list); | 310 | list_add(&sub->subscription_list, &subscriber->subscription_list); |
@@ -335,8 +317,8 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
335 | (Handler)subscr_timeout, (unsigned long)sub); | 317 | (Handler)subscr_timeout, (unsigned long)sub); |
336 | k_start_timer(&sub->timer, sub->timeout); | 318 | k_start_timer(&sub->timer, sub->timeout); |
337 | } | 319 | } |
338 | 320 | *sub_p = sub; | |
339 | return sub; | 321 | return 0; |
340 | } | 322 | } |
341 | 323 | ||
342 | /* Handle one termination request for the subscriber */ | 324 | /* Handle one termination request for the subscriber */ |
@@ -350,10 +332,14 @@ static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
350 | void *usr_data, void *buf, size_t len) | 332 | void *usr_data, void *buf, size_t len) |
351 | { | 333 | { |
352 | struct tipc_subscriber *subscriber = usr_data; | 334 | struct tipc_subscriber *subscriber = usr_data; |
353 | struct tipc_subscription *sub; | 335 | struct tipc_subscription *sub = NULL; |
354 | 336 | ||
355 | spin_lock_bh(&subscriber->lock); | 337 | spin_lock_bh(&subscriber->lock); |
356 | sub = subscr_subscribe((struct tipc_subscr *)buf, subscriber); | 338 | if (subscr_subscribe((struct tipc_subscr *)buf, subscriber, &sub) < 0) { |
339 | spin_unlock_bh(&subscriber->lock); | ||
340 | subscr_terminate(subscriber); | ||
341 | return; | ||
342 | } | ||
357 | if (sub) | 343 | if (sub) |
358 | tipc_nametbl_subscribe(sub); | 344 | tipc_nametbl_subscribe(sub); |
359 | spin_unlock_bh(&subscriber->lock); | 345 | spin_unlock_bh(&subscriber->lock); |