diff options
Diffstat (limited to 'net/tipc/port.c')
| -rw-r--r-- | net/tipc/port.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 67e96cb1e825..b9c8c6b9e94f 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
| @@ -57,8 +57,8 @@ | |||
| 57 | static struct sk_buff *msg_queue_head = NULL; | 57 | static struct sk_buff *msg_queue_head = NULL; |
| 58 | static struct sk_buff *msg_queue_tail = NULL; | 58 | static struct sk_buff *msg_queue_tail = NULL; |
| 59 | 59 | ||
| 60 | spinlock_t tipc_port_list_lock = SPIN_LOCK_UNLOCKED; | 60 | DEFINE_SPINLOCK(tipc_port_list_lock); |
| 61 | static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED; | 61 | static DEFINE_SPINLOCK(queue_lock); |
| 62 | 62 | ||
| 63 | static LIST_HEAD(ports); | 63 | static LIST_HEAD(ports); |
| 64 | static void port_handle_node_down(unsigned long ref); | 64 | static void port_handle_node_down(unsigned long ref); |
| @@ -168,7 +168,6 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) | |||
| 168 | struct port_list *item = dp; | 168 | struct port_list *item = dp; |
| 169 | int cnt = 0; | 169 | int cnt = 0; |
| 170 | 170 | ||
| 171 | assert(buf); | ||
| 172 | msg = buf_msg(buf); | 171 | msg = buf_msg(buf); |
| 173 | 172 | ||
| 174 | /* Create destination port list, if one wasn't supplied */ | 173 | /* Create destination port list, if one wasn't supplied */ |
| @@ -196,7 +195,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) | |||
| 196 | struct sk_buff *b = skb_clone(buf, GFP_ATOMIC); | 195 | struct sk_buff *b = skb_clone(buf, GFP_ATOMIC); |
| 197 | 196 | ||
| 198 | if (b == NULL) { | 197 | if (b == NULL) { |
| 199 | warn("Buffer allocation failure\n"); | 198 | warn("Unable to deliver multicast message(s)\n"); |
| 200 | msg_dbg(msg, "LOST:"); | 199 | msg_dbg(msg, "LOST:"); |
| 201 | goto exit; | 200 | goto exit; |
| 202 | } | 201 | } |
| @@ -227,15 +226,14 @@ u32 tipc_createport_raw(void *usr_handle, | |||
| 227 | struct tipc_msg *msg; | 226 | struct tipc_msg *msg; |
| 228 | u32 ref; | 227 | u32 ref; |
| 229 | 228 | ||
| 230 | p_ptr = kmalloc(sizeof(*p_ptr), GFP_ATOMIC); | 229 | p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); |
| 231 | if (p_ptr == NULL) { | 230 | if (!p_ptr) { |
| 232 | warn("Memory squeeze; failed to create port\n"); | 231 | warn("Port creation failed, no memory\n"); |
| 233 | return 0; | 232 | return 0; |
| 234 | } | 233 | } |
| 235 | memset(p_ptr, 0, sizeof(*p_ptr)); | ||
| 236 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); | 234 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); |
| 237 | if (!ref) { | 235 | if (!ref) { |
| 238 | warn("Reference Table Exhausted\n"); | 236 | warn("Port creation failed, reference table exhausted\n"); |
| 239 | kfree(p_ptr); | 237 | kfree(p_ptr); |
| 240 | return 0; | 238 | return 0; |
| 241 | } | 239 | } |
| @@ -810,18 +808,20 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 810 | void *usr_handle; | 808 | void *usr_handle; |
| 811 | int connected; | 809 | int connected; |
| 812 | int published; | 810 | int published; |
| 811 | u32 message_type; | ||
| 813 | 812 | ||
| 814 | struct sk_buff *next = buf->next; | 813 | struct sk_buff *next = buf->next; |
| 815 | struct tipc_msg *msg = buf_msg(buf); | 814 | struct tipc_msg *msg = buf_msg(buf); |
| 816 | u32 dref = msg_destport(msg); | 815 | u32 dref = msg_destport(msg); |
| 817 | 816 | ||
| 817 | message_type = msg_type(msg); | ||
| 818 | if (message_type > TIPC_DIRECT_MSG) | ||
| 819 | goto reject; /* Unsupported message type */ | ||
| 820 | |||
| 818 | p_ptr = tipc_port_lock(dref); | 821 | p_ptr = tipc_port_lock(dref); |
| 819 | if (!p_ptr) { | 822 | if (!p_ptr) |
| 820 | /* Port deleted while msg in queue */ | 823 | goto reject; /* Port deleted while msg in queue */ |
| 821 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 824 | |
| 822 | buf = next; | ||
| 823 | continue; | ||
| 824 | } | ||
| 825 | orig.ref = msg_origport(msg); | 825 | orig.ref = msg_origport(msg); |
| 826 | orig.node = msg_orignode(msg); | 826 | orig.node = msg_orignode(msg); |
| 827 | up_ptr = p_ptr->user_port; | 827 | up_ptr = p_ptr->user_port; |
| @@ -832,7 +832,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 832 | if (unlikely(msg_errcode(msg))) | 832 | if (unlikely(msg_errcode(msg))) |
| 833 | goto err; | 833 | goto err; |
| 834 | 834 | ||
| 835 | switch (msg_type(msg)) { | 835 | switch (message_type) { |
| 836 | 836 | ||
| 837 | case TIPC_CONN_MSG:{ | 837 | case TIPC_CONN_MSG:{ |
| 838 | tipc_conn_msg_event cb = up_ptr->conn_msg_cb; | 838 | tipc_conn_msg_event cb = up_ptr->conn_msg_cb; |
| @@ -874,6 +874,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 874 | &orig); | 874 | &orig); |
| 875 | break; | 875 | break; |
| 876 | } | 876 | } |
| 877 | case TIPC_MCAST_MSG: | ||
| 877 | case TIPC_NAMED_MSG:{ | 878 | case TIPC_NAMED_MSG:{ |
| 878 | tipc_named_msg_event cb = up_ptr->named_msg_cb; | 879 | tipc_named_msg_event cb = up_ptr->named_msg_cb; |
| 879 | 880 | ||
| @@ -886,7 +887,8 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 886 | goto reject; | 887 | goto reject; |
| 887 | dseq.type = msg_nametype(msg); | 888 | dseq.type = msg_nametype(msg); |
| 888 | dseq.lower = msg_nameinst(msg); | 889 | dseq.lower = msg_nameinst(msg); |
| 889 | dseq.upper = dseq.lower; | 890 | dseq.upper = (message_type == TIPC_NAMED_MSG) |
| 891 | ? dseq.lower : msg_nameupper(msg); | ||
| 890 | skb_pull(buf, msg_hdr_sz(msg)); | 892 | skb_pull(buf, msg_hdr_sz(msg)); |
| 891 | cb(usr_handle, dref, &buf, msg_data(msg), | 893 | cb(usr_handle, dref, &buf, msg_data(msg), |
| 892 | msg_data_sz(msg), msg_importance(msg), | 894 | msg_data_sz(msg), msg_importance(msg), |
| @@ -899,7 +901,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 899 | buf = next; | 901 | buf = next; |
| 900 | continue; | 902 | continue; |
| 901 | err: | 903 | err: |
| 902 | switch (msg_type(msg)) { | 904 | switch (message_type) { |
| 903 | 905 | ||
| 904 | case TIPC_CONN_MSG:{ | 906 | case TIPC_CONN_MSG:{ |
| 905 | tipc_conn_shutdown_event cb = | 907 | tipc_conn_shutdown_event cb = |
| @@ -931,6 +933,7 @@ err: | |||
| 931 | msg_data_sz(msg), msg_errcode(msg), &orig); | 933 | msg_data_sz(msg), msg_errcode(msg), &orig); |
| 932 | break; | 934 | break; |
| 933 | } | 935 | } |
| 936 | case TIPC_MCAST_MSG: | ||
| 934 | case TIPC_NAMED_MSG:{ | 937 | case TIPC_NAMED_MSG:{ |
| 935 | tipc_named_msg_err_event cb = | 938 | tipc_named_msg_err_event cb = |
| 936 | up_ptr->named_err_cb; | 939 | up_ptr->named_err_cb; |
| @@ -940,7 +943,8 @@ err: | |||
| 940 | break; | 943 | break; |
| 941 | dseq.type = msg_nametype(msg); | 944 | dseq.type = msg_nametype(msg); |
| 942 | dseq.lower = msg_nameinst(msg); | 945 | dseq.lower = msg_nameinst(msg); |
| 943 | dseq.upper = dseq.lower; | 946 | dseq.upper = (message_type == TIPC_NAMED_MSG) |
| 947 | ? dseq.lower : msg_nameupper(msg); | ||
| 944 | skb_pull(buf, msg_hdr_sz(msg)); | 948 | skb_pull(buf, msg_hdr_sz(msg)); |
| 945 | cb(usr_handle, dref, &buf, msg_data(msg), | 949 | cb(usr_handle, dref, &buf, msg_data(msg), |
| 946 | msg_data_sz(msg), msg_errcode(msg), &dseq); | 950 | msg_data_sz(msg), msg_errcode(msg), &dseq); |
| @@ -1053,8 +1057,9 @@ int tipc_createport(u32 user_ref, | |||
| 1053 | struct port *p_ptr; | 1057 | struct port *p_ptr; |
| 1054 | u32 ref; | 1058 | u32 ref; |
| 1055 | 1059 | ||
| 1056 | up_ptr = (struct user_port *)kmalloc(sizeof(*up_ptr), GFP_ATOMIC); | 1060 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); |
| 1057 | if (up_ptr == NULL) { | 1061 | if (!up_ptr) { |
| 1062 | warn("Port creation failed, no memory\n"); | ||
| 1058 | return -ENOMEM; | 1063 | return -ENOMEM; |
| 1059 | } | 1064 | } |
| 1060 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); | 1065 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); |
| @@ -1165,8 +1170,6 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
| 1165 | p_ptr = tipc_port_lock(ref); | 1170 | p_ptr = tipc_port_lock(ref); |
| 1166 | if (!p_ptr) | 1171 | if (!p_ptr) |
| 1167 | return -EINVAL; | 1172 | return -EINVAL; |
| 1168 | if (!p_ptr->publ.published) | ||
| 1169 | goto exit; | ||
| 1170 | if (!seq) { | 1173 | if (!seq) { |
| 1171 | list_for_each_entry_safe(publ, tpubl, | 1174 | list_for_each_entry_safe(publ, tpubl, |
| 1172 | &p_ptr->publications, pport_list) { | 1175 | &p_ptr->publications, pport_list) { |
| @@ -1193,7 +1196,6 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
| 1193 | } | 1196 | } |
| 1194 | if (list_empty(&p_ptr->publications)) | 1197 | if (list_empty(&p_ptr->publications)) |
| 1195 | p_ptr->publ.published = 0; | 1198 | p_ptr->publ.published = 0; |
| 1196 | exit: | ||
| 1197 | tipc_port_unlock(p_ptr); | 1199 | tipc_port_unlock(p_ptr); |
| 1198 | return res; | 1200 | return res; |
| 1199 | } | 1201 | } |
