diff options
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r-- | net/tipc/port.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 2f5806410c64..2e0cff408ff9 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -211,15 +211,18 @@ exit: | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /** | 213 | /** |
214 | * tipc_createport_raw - create a native TIPC port | 214 | * tipc_createport_raw - create a generic TIPC port |
215 | * | 215 | * |
216 | * Returns local port reference | 216 | * Returns port reference, or 0 if unable to create it |
217 | * | ||
218 | * Note: The newly created port is returned in the locked state. | ||
217 | */ | 219 | */ |
218 | 220 | ||
219 | u32 tipc_createport_raw(void *usr_handle, | 221 | u32 tipc_createport_raw(void *usr_handle, |
220 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), | 222 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), |
221 | void (*wakeup)(struct tipc_port *), | 223 | void (*wakeup)(struct tipc_port *), |
222 | const u32 importance) | 224 | const u32 importance, |
225 | struct tipc_port **tp_ptr) | ||
223 | { | 226 | { |
224 | struct port *p_ptr; | 227 | struct port *p_ptr; |
225 | struct tipc_msg *msg; | 228 | struct tipc_msg *msg; |
@@ -237,17 +240,12 @@ u32 tipc_createport_raw(void *usr_handle, | |||
237 | return 0; | 240 | return 0; |
238 | } | 241 | } |
239 | 242 | ||
240 | tipc_port_lock(ref); | ||
241 | p_ptr->publ.usr_handle = usr_handle; | 243 | p_ptr->publ.usr_handle = usr_handle; |
242 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; | 244 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; |
243 | p_ptr->publ.ref = ref; | 245 | p_ptr->publ.ref = ref; |
244 | msg = &p_ptr->publ.phdr; | 246 | msg = &p_ptr->publ.phdr; |
245 | msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, | 247 | msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); |
246 | 0); | ||
247 | msg_set_orignode(msg, tipc_own_addr); | ||
248 | msg_set_prevnode(msg, tipc_own_addr); | ||
249 | msg_set_origport(msg, ref); | 248 | msg_set_origport(msg, ref); |
250 | msg_set_importance(msg,importance); | ||
251 | p_ptr->last_in_seqno = 41; | 249 | p_ptr->last_in_seqno = 41; |
252 | p_ptr->sent = 1; | 250 | p_ptr->sent = 1; |
253 | INIT_LIST_HEAD(&p_ptr->wait_list); | 251 | INIT_LIST_HEAD(&p_ptr->wait_list); |
@@ -262,7 +260,7 @@ u32 tipc_createport_raw(void *usr_handle, | |||
262 | INIT_LIST_HEAD(&p_ptr->port_list); | 260 | INIT_LIST_HEAD(&p_ptr->port_list); |
263 | list_add_tail(&p_ptr->port_list, &ports); | 261 | list_add_tail(&p_ptr->port_list, &ports); |
264 | spin_unlock_bh(&tipc_port_list_lock); | 262 | spin_unlock_bh(&tipc_port_list_lock); |
265 | tipc_port_unlock(p_ptr); | 263 | *tp_ptr = &p_ptr->publ; |
266 | return ref; | 264 | return ref; |
267 | } | 265 | } |
268 | 266 | ||
@@ -402,10 +400,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, | |||
402 | buf = buf_acquire(LONG_H_SIZE); | 400 | buf = buf_acquire(LONG_H_SIZE); |
403 | if (buf) { | 401 | if (buf) { |
404 | msg = buf_msg(buf); | 402 | msg = buf_msg(buf); |
405 | msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); | 403 | msg_init(msg, usr, type, LONG_H_SIZE, destnode); |
404 | msg_set_errcode(msg, err); | ||
406 | msg_set_destport(msg, destport); | 405 | msg_set_destport(msg, destport); |
407 | msg_set_origport(msg, origport); | 406 | msg_set_origport(msg, origport); |
408 | msg_set_destnode(msg, destnode); | ||
409 | msg_set_orignode(msg, orignode); | 407 | msg_set_orignode(msg, orignode); |
410 | msg_set_transp_seqno(msg, seqno); | 408 | msg_set_transp_seqno(msg, seqno); |
411 | msg_set_msgcnt(msg, ack); | 409 | msg_set_msgcnt(msg, ack); |
@@ -446,17 +444,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
446 | return data_sz; | 444 | return data_sz; |
447 | } | 445 | } |
448 | rmsg = buf_msg(rbuf); | 446 | rmsg = buf_msg(rbuf); |
449 | msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); | 447 | msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); |
448 | msg_set_errcode(rmsg, err); | ||
450 | msg_set_destport(rmsg, msg_origport(msg)); | 449 | msg_set_destport(rmsg, msg_origport(msg)); |
451 | msg_set_prevnode(rmsg, tipc_own_addr); | ||
452 | msg_set_origport(rmsg, msg_destport(msg)); | 450 | msg_set_origport(rmsg, msg_destport(msg)); |
453 | if (msg_short(msg)) | 451 | if (msg_short(msg)) { |
454 | msg_set_orignode(rmsg, tipc_own_addr); | 452 | msg_set_orignode(rmsg, tipc_own_addr); |
455 | else | 453 | /* leave name type & instance as zeroes */ |
454 | } else { | ||
456 | msg_set_orignode(rmsg, msg_destnode(msg)); | 455 | msg_set_orignode(rmsg, msg_destnode(msg)); |
456 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
457 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
458 | } | ||
457 | msg_set_size(rmsg, data_sz + hdr_sz); | 459 | msg_set_size(rmsg, data_sz + hdr_sz); |
458 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
459 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
460 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); | 460 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); |
461 | 461 | ||
462 | /* send self-abort message when rejecting on a connected port */ | 462 | /* send self-abort message when rejecting on a connected port */ |
@@ -778,6 +778,7 @@ void tipc_port_reinit(void) | |||
778 | msg = &p_ptr->publ.phdr; | 778 | msg = &p_ptr->publ.phdr; |
779 | if (msg_orignode(msg) == tipc_own_addr) | 779 | if (msg_orignode(msg) == tipc_own_addr) |
780 | break; | 780 | break; |
781 | msg_set_prevnode(msg, tipc_own_addr); | ||
781 | msg_set_orignode(msg, tipc_own_addr); | 782 | msg_set_orignode(msg, tipc_own_addr); |
782 | } | 783 | } |
783 | spin_unlock_bh(&tipc_port_list_lock); | 784 | spin_unlock_bh(&tipc_port_list_lock); |
@@ -838,16 +839,13 @@ static void port_dispatcher_sigh(void *dummy) | |||
838 | u32 peer_node = port_peernode(p_ptr); | 839 | u32 peer_node = port_peernode(p_ptr); |
839 | 840 | ||
840 | tipc_port_unlock(p_ptr); | 841 | tipc_port_unlock(p_ptr); |
842 | if (unlikely(!cb)) | ||
843 | goto reject; | ||
841 | if (unlikely(!connected)) { | 844 | if (unlikely(!connected)) { |
842 | if (unlikely(published)) | 845 | if (tipc_connect2port(dref, &orig)) |
843 | goto reject; | 846 | goto reject; |
844 | tipc_connect2port(dref,&orig); | 847 | } else if ((msg_origport(msg) != peer_port) || |
845 | } | 848 | (msg_orignode(msg) != peer_node)) |
846 | if (unlikely(msg_origport(msg) != peer_port)) | ||
847 | goto reject; | ||
848 | if (unlikely(msg_orignode(msg) != peer_node)) | ||
849 | goto reject; | ||
850 | if (unlikely(!cb)) | ||
851 | goto reject; | 849 | goto reject; |
852 | if (unlikely(++p_ptr->publ.conn_unacked >= | 850 | if (unlikely(++p_ptr->publ.conn_unacked >= |
853 | TIPC_FLOW_CONTROL_WIN)) | 851 | TIPC_FLOW_CONTROL_WIN)) |
@@ -862,9 +860,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
862 | tipc_msg_event cb = up_ptr->msg_cb; | 860 | tipc_msg_event cb = up_ptr->msg_cb; |
863 | 861 | ||
864 | tipc_port_unlock(p_ptr); | 862 | tipc_port_unlock(p_ptr); |
865 | if (unlikely(connected)) | 863 | if (unlikely(!cb || connected)) |
866 | goto reject; | ||
867 | if (unlikely(!cb)) | ||
868 | goto reject; | 864 | goto reject; |
869 | skb_pull(buf, msg_hdr_sz(msg)); | 865 | skb_pull(buf, msg_hdr_sz(msg)); |
870 | cb(usr_handle, dref, &buf, msg_data(msg), | 866 | cb(usr_handle, dref, &buf, msg_data(msg), |
@@ -877,11 +873,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
877 | tipc_named_msg_event cb = up_ptr->named_msg_cb; | 873 | tipc_named_msg_event cb = up_ptr->named_msg_cb; |
878 | 874 | ||
879 | tipc_port_unlock(p_ptr); | 875 | tipc_port_unlock(p_ptr); |
880 | if (unlikely(connected)) | 876 | if (unlikely(!cb || connected || !published)) |
881 | goto reject; | ||
882 | if (unlikely(!cb)) | ||
883 | goto reject; | ||
884 | if (unlikely(!published)) | ||
885 | goto reject; | 877 | goto reject; |
886 | dseq.type = msg_nametype(msg); | 878 | dseq.type = msg_nametype(msg); |
887 | dseq.lower = msg_nameinst(msg); | 879 | dseq.lower = msg_nameinst(msg); |
@@ -908,11 +900,10 @@ err: | |||
908 | u32 peer_node = port_peernode(p_ptr); | 900 | u32 peer_node = port_peernode(p_ptr); |
909 | 901 | ||
910 | tipc_port_unlock(p_ptr); | 902 | tipc_port_unlock(p_ptr); |
911 | if (!connected || !cb) | 903 | if (!cb || !connected) |
912 | break; | ||
913 | if (msg_origport(msg) != peer_port) | ||
914 | break; | 904 | break; |
915 | if (msg_orignode(msg) != peer_node) | 905 | if ((msg_origport(msg) != peer_port) || |
906 | (msg_orignode(msg) != peer_node)) | ||
916 | break; | 907 | break; |
917 | tipc_disconnect(dref); | 908 | tipc_disconnect(dref); |
918 | skb_pull(buf, msg_hdr_sz(msg)); | 909 | skb_pull(buf, msg_hdr_sz(msg)); |
@@ -924,7 +915,7 @@ err: | |||
924 | tipc_msg_err_event cb = up_ptr->err_cb; | 915 | tipc_msg_err_event cb = up_ptr->err_cb; |
925 | 916 | ||
926 | tipc_port_unlock(p_ptr); | 917 | tipc_port_unlock(p_ptr); |
927 | if (connected || !cb) | 918 | if (!cb || connected) |
928 | break; | 919 | break; |
929 | skb_pull(buf, msg_hdr_sz(msg)); | 920 | skb_pull(buf, msg_hdr_sz(msg)); |
930 | cb(usr_handle, dref, &buf, msg_data(msg), | 921 | cb(usr_handle, dref, &buf, msg_data(msg), |
@@ -937,7 +928,7 @@ err: | |||
937 | up_ptr->named_err_cb; | 928 | up_ptr->named_err_cb; |
938 | 929 | ||
939 | tipc_port_unlock(p_ptr); | 930 | tipc_port_unlock(p_ptr); |
940 | if (connected || !cb) | 931 | if (!cb || connected) |
941 | break; | 932 | break; |
942 | dseq.type = msg_nametype(msg); | 933 | dseq.type = msg_nametype(msg); |
943 | dseq.lower = msg_nameinst(msg); | 934 | dseq.lower = msg_nameinst(msg); |
@@ -1053,6 +1044,7 @@ int tipc_createport(u32 user_ref, | |||
1053 | { | 1044 | { |
1054 | struct user_port *up_ptr; | 1045 | struct user_port *up_ptr; |
1055 | struct port *p_ptr; | 1046 | struct port *p_ptr; |
1047 | struct tipc_port *tp_ptr; | ||
1056 | u32 ref; | 1048 | u32 ref; |
1057 | 1049 | ||
1058 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); | 1050 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); |
@@ -1060,12 +1052,13 @@ int tipc_createport(u32 user_ref, | |||
1060 | warn("Port creation failed, no memory\n"); | 1052 | warn("Port creation failed, no memory\n"); |
1061 | return -ENOMEM; | 1053 | return -ENOMEM; |
1062 | } | 1054 | } |
1063 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); | 1055 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, |
1064 | p_ptr = tipc_port_lock(ref); | 1056 | importance, &tp_ptr); |
1065 | if (!p_ptr) { | 1057 | if (ref == 0) { |
1066 | kfree(up_ptr); | 1058 | kfree(up_ptr); |
1067 | return -ENOMEM; | 1059 | return -ENOMEM; |
1068 | } | 1060 | } |
1061 | p_ptr = (struct port *)tp_ptr; | ||
1069 | 1062 | ||
1070 | p_ptr->user_port = up_ptr; | 1063 | p_ptr->user_port = up_ptr; |
1071 | up_ptr->user_ref = user_ref; | 1064 | up_ptr->user_ref = user_ref; |