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.c115
1 files changed, 50 insertions, 65 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 2f5806410c64..e70d27ea6578 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -2,7 +2,7 @@
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2008, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -211,12 +211,12 @@ 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 pointer to (locked) TIPC port, or NULL if unable to create it
217 */ 217 */
218 218
219u32 tipc_createport_raw(void *usr_handle, 219struct tipc_port *tipc_createport_raw(void *usr_handle,
220 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 220 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
221 void (*wakeup)(struct tipc_port *), 221 void (*wakeup)(struct tipc_port *),
222 const u32 importance) 222 const u32 importance)
@@ -228,26 +228,21 @@ u32 tipc_createport_raw(void *usr_handle,
228 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); 228 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC);
229 if (!p_ptr) { 229 if (!p_ptr) {
230 warn("Port creation failed, no memory\n"); 230 warn("Port creation failed, no memory\n");
231 return 0; 231 return NULL;
232 } 232 }
233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock);
234 if (!ref) { 234 if (!ref) {
235 warn("Port creation failed, reference table exhausted\n"); 235 warn("Port creation failed, reference table exhausted\n");
236 kfree(p_ptr); 236 kfree(p_ptr);
237 return 0; 237 return NULL;
238 } 238 }
239 239
240 tipc_port_lock(ref);
241 p_ptr->publ.usr_handle = usr_handle; 240 p_ptr->publ.usr_handle = usr_handle;
242 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 241 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
243 p_ptr->publ.ref = ref; 242 p_ptr->publ.ref = ref;
244 msg = &p_ptr->publ.phdr; 243 msg = &p_ptr->publ.phdr;
245 msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 244 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); 245 msg_set_origport(msg, ref);
250 msg_set_importance(msg,importance);
251 p_ptr->last_in_seqno = 41; 246 p_ptr->last_in_seqno = 41;
252 p_ptr->sent = 1; 247 p_ptr->sent = 1;
253 INIT_LIST_HEAD(&p_ptr->wait_list); 248 INIT_LIST_HEAD(&p_ptr->wait_list);
@@ -262,8 +257,7 @@ u32 tipc_createport_raw(void *usr_handle,
262 INIT_LIST_HEAD(&p_ptr->port_list); 257 INIT_LIST_HEAD(&p_ptr->port_list);
263 list_add_tail(&p_ptr->port_list, &ports); 258 list_add_tail(&p_ptr->port_list, &ports);
264 spin_unlock_bh(&tipc_port_list_lock); 259 spin_unlock_bh(&tipc_port_list_lock);
265 tipc_port_unlock(p_ptr); 260 return &(p_ptr->publ);
266 return ref;
267} 261}
268 262
269int tipc_deleteport(u32 ref) 263int tipc_deleteport(u32 ref)
@@ -297,7 +291,7 @@ int tipc_deleteport(u32 ref)
297 kfree(p_ptr); 291 kfree(p_ptr);
298 dbg("Deleted port %u\n", ref); 292 dbg("Deleted port %u\n", ref);
299 tipc_net_route_msg(buf); 293 tipc_net_route_msg(buf);
300 return TIPC_OK; 294 return 0;
301} 295}
302 296
303/** 297/**
@@ -342,7 +336,7 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
342 return -EINVAL; 336 return -EINVAL;
343 *isunreliable = port_unreliable(p_ptr); 337 *isunreliable = port_unreliable(p_ptr);
344 tipc_port_unlock(p_ptr); 338 tipc_port_unlock(p_ptr);
345 return TIPC_OK; 339 return 0;
346} 340}
347 341
348int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 342int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
@@ -354,7 +348,7 @@ int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
354 return -EINVAL; 348 return -EINVAL;
355 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 349 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0));
356 tipc_port_unlock(p_ptr); 350 tipc_port_unlock(p_ptr);
357 return TIPC_OK; 351 return 0;
358} 352}
359 353
360static int port_unreturnable(struct port *p_ptr) 354static int port_unreturnable(struct port *p_ptr)
@@ -371,7 +365,7 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
371 return -EINVAL; 365 return -EINVAL;
372 *isunrejectable = port_unreturnable(p_ptr); 366 *isunrejectable = port_unreturnable(p_ptr);
373 tipc_port_unlock(p_ptr); 367 tipc_port_unlock(p_ptr);
374 return TIPC_OK; 368 return 0;
375} 369}
376 370
377int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 371int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
@@ -383,7 +377,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
383 return -EINVAL; 377 return -EINVAL;
384 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 378 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0));
385 tipc_port_unlock(p_ptr); 379 tipc_port_unlock(p_ptr);
386 return TIPC_OK; 380 return 0;
387} 381}
388 382
389/* 383/*
@@ -402,10 +396,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
402 buf = buf_acquire(LONG_H_SIZE); 396 buf = buf_acquire(LONG_H_SIZE);
403 if (buf) { 397 if (buf) {
404 msg = buf_msg(buf); 398 msg = buf_msg(buf);
405 msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); 399 msg_init(msg, usr, type, LONG_H_SIZE, destnode);
400 msg_set_errcode(msg, err);
406 msg_set_destport(msg, destport); 401 msg_set_destport(msg, destport);
407 msg_set_origport(msg, origport); 402 msg_set_origport(msg, origport);
408 msg_set_destnode(msg, destnode);
409 msg_set_orignode(msg, orignode); 403 msg_set_orignode(msg, orignode);
410 msg_set_transp_seqno(msg, seqno); 404 msg_set_transp_seqno(msg, seqno);
411 msg_set_msgcnt(msg, ack); 405 msg_set_msgcnt(msg, ack);
@@ -446,17 +440,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
446 return data_sz; 440 return data_sz;
447 } 441 }
448 rmsg = buf_msg(rbuf); 442 rmsg = buf_msg(rbuf);
449 msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); 443 msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg));
444 msg_set_errcode(rmsg, err);
450 msg_set_destport(rmsg, msg_origport(msg)); 445 msg_set_destport(rmsg, msg_origport(msg));
451 msg_set_prevnode(rmsg, tipc_own_addr);
452 msg_set_origport(rmsg, msg_destport(msg)); 446 msg_set_origport(rmsg, msg_destport(msg));
453 if (msg_short(msg)) 447 if (msg_short(msg)) {
454 msg_set_orignode(rmsg, tipc_own_addr); 448 msg_set_orignode(rmsg, tipc_own_addr);
455 else 449 /* leave name type & instance as zeroes */
450 } else {
456 msg_set_orignode(rmsg, msg_destnode(msg)); 451 msg_set_orignode(rmsg, msg_destnode(msg));
452 msg_set_nametype(rmsg, msg_nametype(msg));
453 msg_set_nameinst(rmsg, msg_nameinst(msg));
454 }
457 msg_set_size(rmsg, data_sz + hdr_sz); 455 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); 456 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz);
461 457
462 /* send self-abort message when rejecting on a connected port */ 458 /* send self-abort message when rejecting on a connected port */
@@ -778,6 +774,7 @@ void tipc_port_reinit(void)
778 msg = &p_ptr->publ.phdr; 774 msg = &p_ptr->publ.phdr;
779 if (msg_orignode(msg) == tipc_own_addr) 775 if (msg_orignode(msg) == tipc_own_addr)
780 break; 776 break;
777 msg_set_prevnode(msg, tipc_own_addr);
781 msg_set_orignode(msg, tipc_own_addr); 778 msg_set_orignode(msg, tipc_own_addr);
782 } 779 }
783 spin_unlock_bh(&tipc_port_list_lock); 780 spin_unlock_bh(&tipc_port_list_lock);
@@ -838,16 +835,13 @@ static void port_dispatcher_sigh(void *dummy)
838 u32 peer_node = port_peernode(p_ptr); 835 u32 peer_node = port_peernode(p_ptr);
839 836
840 tipc_port_unlock(p_ptr); 837 tipc_port_unlock(p_ptr);
838 if (unlikely(!cb))
839 goto reject;
841 if (unlikely(!connected)) { 840 if (unlikely(!connected)) {
842 if (unlikely(published)) 841 if (tipc_connect2port(dref, &orig))
843 goto reject; 842 goto reject;
844 tipc_connect2port(dref,&orig); 843 } else if ((msg_origport(msg) != peer_port) ||
845 } 844 (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; 845 goto reject;
852 if (unlikely(++p_ptr->publ.conn_unacked >= 846 if (unlikely(++p_ptr->publ.conn_unacked >=
853 TIPC_FLOW_CONTROL_WIN)) 847 TIPC_FLOW_CONTROL_WIN))
@@ -862,9 +856,7 @@ static void port_dispatcher_sigh(void *dummy)
862 tipc_msg_event cb = up_ptr->msg_cb; 856 tipc_msg_event cb = up_ptr->msg_cb;
863 857
864 tipc_port_unlock(p_ptr); 858 tipc_port_unlock(p_ptr);
865 if (unlikely(connected)) 859 if (unlikely(!cb || connected))
866 goto reject;
867 if (unlikely(!cb))
868 goto reject; 860 goto reject;
869 skb_pull(buf, msg_hdr_sz(msg)); 861 skb_pull(buf, msg_hdr_sz(msg));
870 cb(usr_handle, dref, &buf, msg_data(msg), 862 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -877,11 +869,7 @@ static void port_dispatcher_sigh(void *dummy)
877 tipc_named_msg_event cb = up_ptr->named_msg_cb; 869 tipc_named_msg_event cb = up_ptr->named_msg_cb;
878 870
879 tipc_port_unlock(p_ptr); 871 tipc_port_unlock(p_ptr);
880 if (unlikely(connected)) 872 if (unlikely(!cb || connected || !published))
881 goto reject;
882 if (unlikely(!cb))
883 goto reject;
884 if (unlikely(!published))
885 goto reject; 873 goto reject;
886 dseq.type = msg_nametype(msg); 874 dseq.type = msg_nametype(msg);
887 dseq.lower = msg_nameinst(msg); 875 dseq.lower = msg_nameinst(msg);
@@ -908,11 +896,10 @@ err:
908 u32 peer_node = port_peernode(p_ptr); 896 u32 peer_node = port_peernode(p_ptr);
909 897
910 tipc_port_unlock(p_ptr); 898 tipc_port_unlock(p_ptr);
911 if (!connected || !cb) 899 if (!cb || !connected)
912 break;
913 if (msg_origport(msg) != peer_port)
914 break; 900 break;
915 if (msg_orignode(msg) != peer_node) 901 if ((msg_origport(msg) != peer_port) ||
902 (msg_orignode(msg) != peer_node))
916 break; 903 break;
917 tipc_disconnect(dref); 904 tipc_disconnect(dref);
918 skb_pull(buf, msg_hdr_sz(msg)); 905 skb_pull(buf, msg_hdr_sz(msg));
@@ -924,7 +911,7 @@ err:
924 tipc_msg_err_event cb = up_ptr->err_cb; 911 tipc_msg_err_event cb = up_ptr->err_cb;
925 912
926 tipc_port_unlock(p_ptr); 913 tipc_port_unlock(p_ptr);
927 if (connected || !cb) 914 if (!cb || connected)
928 break; 915 break;
929 skb_pull(buf, msg_hdr_sz(msg)); 916 skb_pull(buf, msg_hdr_sz(msg));
930 cb(usr_handle, dref, &buf, msg_data(msg), 917 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -937,7 +924,7 @@ err:
937 up_ptr->named_err_cb; 924 up_ptr->named_err_cb;
938 925
939 tipc_port_unlock(p_ptr); 926 tipc_port_unlock(p_ptr);
940 if (connected || !cb) 927 if (!cb || connected)
941 break; 928 break;
942 dseq.type = msg_nametype(msg); 929 dseq.type = msg_nametype(msg);
943 dseq.lower = msg_nameinst(msg); 930 dseq.lower = msg_nameinst(msg);
@@ -976,7 +963,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
976 tipc_k_signal((Handler)port_dispatcher_sigh, 0); 963 tipc_k_signal((Handler)port_dispatcher_sigh, 0);
977 } 964 }
978 spin_unlock_bh(&queue_lock); 965 spin_unlock_bh(&queue_lock);
979 return TIPC_OK; 966 return 0;
980} 967}
981 968
982/* 969/*
@@ -1053,15 +1040,14 @@ int tipc_createport(u32 user_ref,
1053{ 1040{
1054 struct user_port *up_ptr; 1041 struct user_port *up_ptr;
1055 struct port *p_ptr; 1042 struct port *p_ptr;
1056 u32 ref;
1057 1043
1058 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 1044 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
1059 if (!up_ptr) { 1045 if (!up_ptr) {
1060 warn("Port creation failed, no memory\n"); 1046 warn("Port creation failed, no memory\n");
1061 return -ENOMEM; 1047 return -ENOMEM;
1062 } 1048 }
1063 ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); 1049 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher,
1064 p_ptr = tipc_port_lock(ref); 1050 port_wakeup, importance);
1065 if (!p_ptr) { 1051 if (!p_ptr) {
1066 kfree(up_ptr); 1052 kfree(up_ptr);
1067 return -ENOMEM; 1053 return -ENOMEM;
@@ -1081,16 +1067,15 @@ int tipc_createport(u32 user_ref,
1081 INIT_LIST_HEAD(&up_ptr->uport_list); 1067 INIT_LIST_HEAD(&up_ptr->uport_list);
1082 tipc_reg_add_port(up_ptr); 1068 tipc_reg_add_port(up_ptr);
1083 *portref = p_ptr->publ.ref; 1069 *portref = p_ptr->publ.ref;
1084 dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref);
1085 tipc_port_unlock(p_ptr); 1070 tipc_port_unlock(p_ptr);
1086 return TIPC_OK; 1071 return 0;
1087} 1072}
1088 1073
1089int tipc_ownidentity(u32 ref, struct tipc_portid *id) 1074int tipc_ownidentity(u32 ref, struct tipc_portid *id)
1090{ 1075{
1091 id->ref = ref; 1076 id->ref = ref;
1092 id->node = tipc_own_addr; 1077 id->node = tipc_own_addr;
1093 return TIPC_OK; 1078 return 0;
1094} 1079}
1095 1080
1096int tipc_portimportance(u32 ref, unsigned int *importance) 1081int tipc_portimportance(u32 ref, unsigned int *importance)
@@ -1102,7 +1087,7 @@ int tipc_portimportance(u32 ref, unsigned int *importance)
1102 return -EINVAL; 1087 return -EINVAL;
1103 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 1088 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr);
1104 tipc_port_unlock(p_ptr); 1089 tipc_port_unlock(p_ptr);
1105 return TIPC_OK; 1090 return 0;
1106} 1091}
1107 1092
1108int tipc_set_portimportance(u32 ref, unsigned int imp) 1093int tipc_set_portimportance(u32 ref, unsigned int imp)
@@ -1117,7 +1102,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1117 return -EINVAL; 1102 return -EINVAL;
1118 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 1103 msg_set_importance(&p_ptr->publ.phdr, (u32)imp);
1119 tipc_port_unlock(p_ptr); 1104 tipc_port_unlock(p_ptr);
1120 return TIPC_OK; 1105 return 0;
1121} 1106}
1122 1107
1123 1108
@@ -1152,7 +1137,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1152 list_add(&publ->pport_list, &p_ptr->publications); 1137 list_add(&publ->pport_list, &p_ptr->publications);
1153 p_ptr->pub_count++; 1138 p_ptr->pub_count++;
1154 p_ptr->publ.published = 1; 1139 p_ptr->publ.published = 1;
1155 res = TIPC_OK; 1140 res = 0;
1156 } 1141 }
1157exit: 1142exit:
1158 tipc_port_unlock(p_ptr); 1143 tipc_port_unlock(p_ptr);
@@ -1175,7 +1160,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1175 tipc_nametbl_withdraw(publ->type, publ->lower, 1160 tipc_nametbl_withdraw(publ->type, publ->lower,
1176 publ->ref, publ->key); 1161 publ->ref, publ->key);
1177 } 1162 }
1178 res = TIPC_OK; 1163 res = 0;
1179 } else { 1164 } else {
1180 list_for_each_entry_safe(publ, tpubl, 1165 list_for_each_entry_safe(publ, tpubl,
1181 &p_ptr->publications, pport_list) { 1166 &p_ptr->publications, pport_list) {
@@ -1189,7 +1174,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1189 break; 1174 break;
1190 tipc_nametbl_withdraw(publ->type, publ->lower, 1175 tipc_nametbl_withdraw(publ->type, publ->lower,
1191 publ->ref, publ->key); 1176 publ->ref, publ->key);
1192 res = TIPC_OK; 1177 res = 0;
1193 break; 1178 break;
1194 } 1179 }
1195 } 1180 }
@@ -1233,7 +1218,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1233 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1218 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,
1234 (void *)(unsigned long)ref, 1219 (void *)(unsigned long)ref,
1235 (net_ev_handler)port_handle_node_down); 1220 (net_ev_handler)port_handle_node_down);
1236 res = TIPC_OK; 1221 res = 0;
1237exit: 1222exit:
1238 tipc_port_unlock(p_ptr); 1223 tipc_port_unlock(p_ptr);
1239 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1224 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
@@ -1255,7 +1240,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1255 /* let timer expire on it's own to avoid deadlock! */ 1240 /* let timer expire on it's own to avoid deadlock! */
1256 tipc_nodesub_unsubscribe( 1241 tipc_nodesub_unsubscribe(
1257 &((struct port *)tp_ptr)->subscription); 1242 &((struct port *)tp_ptr)->subscription);
1258 res = TIPC_OK; 1243 res = 0;
1259 } else { 1244 } else {
1260 res = -ENOTCONN; 1245 res = -ENOTCONN;
1261 } 1246 }
@@ -1320,7 +1305,7 @@ int tipc_isconnected(u32 ref, int *isconnected)
1320 return -EINVAL; 1305 return -EINVAL;
1321 *isconnected = p_ptr->publ.connected; 1306 *isconnected = p_ptr->publ.connected;
1322 tipc_port_unlock(p_ptr); 1307 tipc_port_unlock(p_ptr);
1323 return TIPC_OK; 1308 return 0;
1324} 1309}
1325 1310
1326int tipc_peer(u32 ref, struct tipc_portid *peer) 1311int tipc_peer(u32 ref, struct tipc_portid *peer)
@@ -1334,7 +1319,7 @@ int tipc_peer(u32 ref, struct tipc_portid *peer)
1334 if (p_ptr->publ.connected) { 1319 if (p_ptr->publ.connected) {
1335 peer->ref = port_peerport(p_ptr); 1320 peer->ref = port_peerport(p_ptr);
1336 peer->node = port_peernode(p_ptr); 1321 peer->node = port_peernode(p_ptr);
1337 res = TIPC_OK; 1322 res = 0;
1338 } else 1323 } else
1339 res = -ENOTCONN; 1324 res = -ENOTCONN;
1340 tipc_port_unlock(p_ptr); 1325 tipc_port_unlock(p_ptr);