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); |
