aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r--net/tipc/port.c79
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
219u32 tipc_createport_raw(void *usr_handle, 221u32 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;