aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c6
-rw-r--r--net/tipc/bearer.c1
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/core.h6
-rw-r--r--net/tipc/link.c6
-rw-r--r--net/tipc/msg.c6
-rw-r--r--net/tipc/msg.h34
-rw-r--r--net/tipc/name_distr.c6
-rw-r--r--net/tipc/name_table.c289
-rw-r--r--net/tipc/name_table.h14
-rw-r--r--net/tipc/port.c284
-rw-r--r--net/tipc/socket.c3
12 files changed, 276 insertions, 381 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index fa68d1e9ff4b..759b318b5ffb 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -552,12 +552,16 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
552 if (likely(!msg_non_seq(buf_msg(buf)))) { 552 if (likely(!msg_non_seq(buf_msg(buf)))) {
553 struct tipc_msg *msg; 553 struct tipc_msg *msg;
554 554
555 assert(tipc_bcast_nmap.count != 0);
556 bcbuf_set_acks(buf, tipc_bcast_nmap.count); 555 bcbuf_set_acks(buf, tipc_bcast_nmap.count);
557 msg = buf_msg(buf); 556 msg = buf_msg(buf);
558 msg_set_non_seq(msg, 1); 557 msg_set_non_seq(msg, 1);
559 msg_set_mc_netid(msg, tipc_net_id); 558 msg_set_mc_netid(msg, tipc_net_id);
560 bcl->stats.sent_info++; 559 bcl->stats.sent_info++;
560
561 if (WARN_ON(!tipc_bcast_nmap.count)) {
562 dump_stack();
563 return 0;
564 }
561 } 565 }
562 566
563 /* Send buffer over bearers until all targets reached */ 567 /* Send buffer over bearers until all targets reached */
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 85209eadfae6..85eba9c08ee9 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -402,7 +402,6 @@ void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
402void tipc_continue(struct tipc_bearer *b_ptr) 402void tipc_continue(struct tipc_bearer *b_ptr)
403{ 403{
404 spin_lock_bh(&b_ptr->lock); 404 spin_lock_bh(&b_ptr->lock);
405 b_ptr->continue_count++;
406 if (!list_empty(&b_ptr->cong_links)) 405 if (!list_empty(&b_ptr->cong_links))
407 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr); 406 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
408 b_ptr->blocked = 0; 407 b_ptr->blocked = 0;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 31d6172b20fd..5ad70eff1ebf 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -107,7 +107,6 @@ struct media {
107 * @link_req: ptr to (optional) structure making periodic link setup requests 107 * @link_req: ptr to (optional) structure making periodic link setup requests
108 * @links: list of non-congested links associated with bearer 108 * @links: list of non-congested links associated with bearer
109 * @cong_links: list of congested links associated with bearer 109 * @cong_links: list of congested links associated with bearer
110 * @continue_count: # of times bearer has resumed after congestion or blocking
111 * @active: non-zero if bearer structure is represents a bearer 110 * @active: non-zero if bearer structure is represents a bearer
112 * @net_plane: network plane ('A' through 'H') currently associated with bearer 111 * @net_plane: network plane ('A' through 'H') currently associated with bearer
113 * @nodes: indicates which nodes in cluster can be reached through bearer 112 * @nodes: indicates which nodes in cluster can be reached through bearer
@@ -129,7 +128,6 @@ struct tipc_bearer {
129 struct link_req *link_req; 128 struct link_req *link_req;
130 struct list_head links; 129 struct list_head links;
131 struct list_head cong_links; 130 struct list_head cong_links;
132 u32 continue_count;
133 int active; 131 int active;
134 char net_plane; 132 char net_plane;
135 struct tipc_node_map nodes; 133 struct tipc_node_map nodes;
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 436dda1159d2..d234a98a460a 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -62,12 +62,6 @@ struct tipc_msg; /* msg.h */
62struct print_buf; /* log.h */ 62struct print_buf; /* log.h */
63 63
64/* 64/*
65 * TIPC sanity test macros
66 */
67
68#define assert(i) BUG_ON(!(i))
69
70/*
71 * TIPC system monitoring code 65 * TIPC system monitoring code
72 */ 66 */
73 67
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 5ed4b4f7452d..f89570c54f54 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1572,7 +1572,7 @@ static struct sk_buff *link_insert_deferred_queue(struct link *l_ptr,
1572static int link_recv_buf_validate(struct sk_buff *buf) 1572static int link_recv_buf_validate(struct sk_buff *buf)
1573{ 1573{
1574 static u32 min_data_hdr_size[8] = { 1574 static u32 min_data_hdr_size[8] = {
1575 SHORT_H_SIZE, MCAST_H_SIZE, LONG_H_SIZE, DIR_MSG_H_SIZE, 1575 SHORT_H_SIZE, MCAST_H_SIZE, NAMED_H_SIZE, BASIC_H_SIZE,
1576 MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE 1576 MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE
1577 }; 1577 };
1578 1578
@@ -2553,7 +2553,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2553 u32 msg_sz = msg_size(imsg); 2553 u32 msg_sz = msg_size(imsg);
2554 u32 fragm_sz = msg_data_sz(fragm); 2554 u32 fragm_sz = msg_data_sz(fragm);
2555 u32 exp_fragm_cnt = msg_sz/fragm_sz + !!(msg_sz % fragm_sz); 2555 u32 exp_fragm_cnt = msg_sz/fragm_sz + !!(msg_sz % fragm_sz);
2556 u32 max = TIPC_MAX_USER_MSG_SIZE + LONG_H_SIZE; 2556 u32 max = TIPC_MAX_USER_MSG_SIZE + NAMED_H_SIZE;
2557 if (msg_type(imsg) == TIPC_MCAST_MSG) 2557 if (msg_type(imsg) == TIPC_MCAST_MSG)
2558 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; 2558 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2559 if (msg_size(imsg) > max) { 2559 if (msg_size(imsg) > max) {
@@ -2882,7 +2882,7 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
2882 profile_total = 1; 2882 profile_total = 1;
2883 tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" 2883 tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n"
2884 " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " 2884 " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
2885 "-16354:%u%% -32768:%u%% -66000:%u%%\n", 2885 "-16384:%u%% -32768:%u%% -66000:%u%%\n",
2886 l_ptr->stats.msg_length_counts, 2886 l_ptr->stats.msg_length_counts,
2887 l_ptr->stats.msg_lengths_total / profile_total, 2887 l_ptr->stats.msg_lengths_total / profile_total,
2888 percent(l_ptr->stats.msg_length_profile[0], profile_total), 2888 percent(l_ptr->stats.msg_length_profile[0], profile_total),
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 03e57bf92c73..83d50967910c 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -61,10 +61,8 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
61 msg_set_size(m, hsize); 61 msg_set_size(m, hsize);
62 msg_set_prevnode(m, tipc_own_addr); 62 msg_set_prevnode(m, tipc_own_addr);
63 msg_set_type(m, type); 63 msg_set_type(m, type);
64 if (!msg_short(m)) { 64 msg_set_orignode(m, tipc_own_addr);
65 msg_set_orignode(m, tipc_own_addr); 65 msg_set_destnode(m, destnode);
66 msg_set_destnode(m, destnode);
67 }
68} 66}
69 67
70/** 68/**
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 8452454731fa..d93178f2e852 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -68,10 +68,10 @@
68 * Message header sizes 68 * Message header sizes
69 */ 69 */
70 70
71#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ 71#define SHORT_H_SIZE 24 /* In-cluster basic payload message */
72#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ 72#define BASIC_H_SIZE 32 /* Basic payload message */
73#define LONG_H_SIZE 40 /* Named messages */ 73#define NAMED_H_SIZE 40 /* Named payload message */
74#define MCAST_H_SIZE 44 /* Multicast messages */ 74#define MCAST_H_SIZE 44 /* Multicast payload message */
75#define INT_H_SIZE 40 /* Internal messages */ 75#define INT_H_SIZE 40 /* Internal messages */
76#define MIN_H_SIZE 24 /* Smallest legal TIPC header size */ 76#define MIN_H_SIZE 24 /* Smallest legal TIPC header size */
77#define MAX_H_SIZE 60 /* Largest possible TIPC header size */ 77#define MAX_H_SIZE 60 /* Largest possible TIPC header size */
@@ -311,26 +311,6 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
311} 311}
312 312
313/* 313/*
314 * TIPC may utilize the "link ack #" and "link seq #" fields of a short
315 * message header to hold the destination node for the message, since the
316 * normal "dest node" field isn't present. This cache is only referenced
317 * when required, so populating the cache of a longer message header is
318 * harmless (as long as the header has the two link sequence fields present).
319 *
320 * Note: Host byte order is OK here, since the info never goes off-card.
321 */
322
323static inline u32 msg_destnode_cache(struct tipc_msg *m)
324{
325 return m->hdr[2];
326}
327
328static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
329{
330 m->hdr[2] = dnode;
331}
332
333/*
334 * Words 3-10 314 * Words 3-10
335 */ 315 */
336 316
@@ -377,7 +357,7 @@ static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
377 357
378static inline int msg_short(struct tipc_msg *m) 358static inline int msg_short(struct tipc_msg *m)
379{ 359{
380 return msg_hdr_sz(m) == 24; 360 return msg_hdr_sz(m) == SHORT_H_SIZE;
381} 361}
382 362
383static inline u32 msg_orignode(struct tipc_msg *m) 363static inline u32 msg_orignode(struct tipc_msg *m)
@@ -635,7 +615,7 @@ static inline u32 msg_link_selector(struct tipc_msg *m)
635 615
636static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) 616static inline void msg_set_link_selector(struct tipc_msg *m, u32 n)
637{ 617{
638 msg_set_bits(m, 4, 0, 1, (n & 1)); 618 msg_set_bits(m, 4, 0, 1, n);
639} 619}
640 620
641/* 621/*
@@ -659,7 +639,7 @@ static inline u32 msg_probe(struct tipc_msg *m)
659 639
660static inline void msg_set_probe(struct tipc_msg *m, u32 val) 640static inline void msg_set_probe(struct tipc_msg *m, u32 val)
661{ 641{
662 msg_set_bits(m, 5, 0, 1, (val & 1)); 642 msg_set_bits(m, 5, 0, 1, val);
663} 643}
664 644
665static inline char msg_net_plane(struct tipc_msg *m) 645static inline char msg_net_plane(struct tipc_msg *m)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 80025a1b3bfd..cd356e504332 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -94,13 +94,13 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
94 94
95static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) 95static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
96{ 96{
97 struct sk_buff *buf = tipc_buf_acquire(LONG_H_SIZE + size); 97 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size);
98 struct tipc_msg *msg; 98 struct tipc_msg *msg;
99 99
100 if (buf != NULL) { 100 if (buf != NULL) {
101 msg = buf_msg(buf); 101 msg = buf_msg(buf);
102 tipc_msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest); 102 tipc_msg_init(msg, NAME_DISTRIBUTOR, type, INT_H_SIZE, dest);
103 msg_set_size(msg, LONG_H_SIZE + size); 103 msg_set_size(msg, INT_H_SIZE + size);
104 } 104 }
105 return buf; 105 return buf;
106} 106}
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 205ed4a4e186..46e6b6c2ecc9 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_table.c: TIPC name table code 2 * net/tipc/name_table.c: TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, 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
@@ -44,9 +44,7 @@
44static int tipc_nametbl_size = 1024; /* must be a power of 2 */ 44static int tipc_nametbl_size = 1024; /* must be a power of 2 */
45 45
46/** 46/**
47 * struct sub_seq - container for all published instances of a name sequence 47 * struct name_info - name sequence publication info
48 * @lower: name sequence lower bound
49 * @upper: name sequence upper bound
50 * @node_list: circular list of publications made by own node 48 * @node_list: circular list of publications made by own node
51 * @cluster_list: circular list of publications made by own cluster 49 * @cluster_list: circular list of publications made by own cluster
52 * @zone_list: circular list of publications made by own zone 50 * @zone_list: circular list of publications made by own zone
@@ -59,18 +57,29 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */
59 * (The cluster and node lists may be empty.) 57 * (The cluster and node lists may be empty.)
60 */ 58 */
61 59
62struct sub_seq { 60struct name_info {
63 u32 lower; 61 struct list_head node_list;
64 u32 upper; 62 struct list_head cluster_list;
65 struct publication *node_list; 63 struct list_head zone_list;
66 struct publication *cluster_list;
67 struct publication *zone_list;
68 u32 node_list_size; 64 u32 node_list_size;
69 u32 cluster_list_size; 65 u32 cluster_list_size;
70 u32 zone_list_size; 66 u32 zone_list_size;
71}; 67};
72 68
73/** 69/**
70 * struct sub_seq - container for all published instances of a name sequence
71 * @lower: name sequence lower bound
72 * @upper: name sequence upper bound
73 * @info: pointer to name sequence publication info
74 */
75
76struct sub_seq {
77 u32 lower;
78 u32 upper;
79 struct name_info *info;
80};
81
82/**
74 * struct name_seq - container for all published instances of a name type 83 * struct name_seq - container for all published instances of a name type
75 * @type: 32 bit 'type' value for name sequence 84 * @type: 32 bit 'type' value for name sequence
76 * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; 85 * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type';
@@ -246,6 +255,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
246 struct subscription *st; 255 struct subscription *st;
247 struct publication *publ; 256 struct publication *publ;
248 struct sub_seq *sseq; 257 struct sub_seq *sseq;
258 struct name_info *info;
249 int created_subseq = 0; 259 int created_subseq = 0;
250 260
251 sseq = nameseq_find_subseq(nseq, lower); 261 sseq = nameseq_find_subseq(nseq, lower);
@@ -258,6 +268,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
258 type, lower, upper); 268 type, lower, upper);
259 return NULL; 269 return NULL;
260 } 270 }
271
272 info = sseq->info;
261 } else { 273 } else {
262 u32 inspos; 274 u32 inspos;
263 struct sub_seq *freesseq; 275 struct sub_seq *freesseq;
@@ -292,6 +304,17 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
292 nseq->alloc *= 2; 304 nseq->alloc *= 2;
293 } 305 }
294 306
307 info = kzalloc(sizeof(*info), GFP_ATOMIC);
308 if (!info) {
309 warn("Cannot publish {%u,%u,%u}, no memory\n",
310 type, lower, upper);
311 return NULL;
312 }
313
314 INIT_LIST_HEAD(&info->node_list);
315 INIT_LIST_HEAD(&info->cluster_list);
316 INIT_LIST_HEAD(&info->zone_list);
317
295 /* Insert new sub-sequence */ 318 /* Insert new sub-sequence */
296 319
297 sseq = &nseq->sseqs[inspos]; 320 sseq = &nseq->sseqs[inspos];
@@ -301,6 +324,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
301 nseq->first_free++; 324 nseq->first_free++;
302 sseq->lower = lower; 325 sseq->lower = lower;
303 sseq->upper = upper; 326 sseq->upper = upper;
327 sseq->info = info;
304 created_subseq = 1; 328 created_subseq = 1;
305 } 329 }
306 330
@@ -310,33 +334,17 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
310 if (!publ) 334 if (!publ)
311 return NULL; 335 return NULL;
312 336
313 sseq->zone_list_size++; 337 list_add(&publ->zone_list, &info->zone_list);
314 if (!sseq->zone_list) 338 info->zone_list_size++;
315 sseq->zone_list = publ->zone_list_next = publ;
316 else {
317 publ->zone_list_next = sseq->zone_list->zone_list_next;
318 sseq->zone_list->zone_list_next = publ;
319 }
320 339
321 if (in_own_cluster(node)) { 340 if (in_own_cluster(node)) {
322 sseq->cluster_list_size++; 341 list_add(&publ->cluster_list, &info->cluster_list);
323 if (!sseq->cluster_list) 342 info->cluster_list_size++;
324 sseq->cluster_list = publ->cluster_list_next = publ;
325 else {
326 publ->cluster_list_next =
327 sseq->cluster_list->cluster_list_next;
328 sseq->cluster_list->cluster_list_next = publ;
329 }
330 } 343 }
331 344
332 if (node == tipc_own_addr) { 345 if (node == tipc_own_addr) {
333 sseq->node_list_size++; 346 list_add(&publ->node_list, &info->node_list);
334 if (!sseq->node_list) 347 info->node_list_size++;
335 sseq->node_list = publ->node_list_next = publ;
336 else {
337 publ->node_list_next = sseq->node_list->node_list_next;
338 sseq->node_list->node_list_next = publ;
339 }
340 } 348 }
341 349
342 /* 350 /*
@@ -370,9 +378,8 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
370 u32 node, u32 ref, u32 key) 378 u32 node, u32 ref, u32 key)
371{ 379{
372 struct publication *publ; 380 struct publication *publ;
373 struct publication *curr;
374 struct publication *prev;
375 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); 381 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
382 struct name_info *info;
376 struct sub_seq *free; 383 struct sub_seq *free;
377 struct subscription *s, *st; 384 struct subscription *s, *st;
378 int removed_subseq = 0; 385 int removed_subseq = 0;
@@ -380,96 +387,41 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
380 if (!sseq) 387 if (!sseq)
381 return NULL; 388 return NULL;
382 389
383 /* Remove publication from zone scope list */ 390 info = sseq->info;
384 391
385 prev = sseq->zone_list; 392 /* Locate publication, if it exists */
386 publ = sseq->zone_list->zone_list_next;
387 while ((publ->key != key) || (publ->ref != ref) ||
388 (publ->node && (publ->node != node))) {
389 prev = publ;
390 publ = publ->zone_list_next;
391 if (prev == sseq->zone_list) {
392 393
393 /* Prevent endless loop if publication not found */ 394 list_for_each_entry(publ, &info->zone_list, zone_list) {
394 395 if ((publ->key == key) && (publ->ref == ref) &&
395 return NULL; 396 (!publ->node || (publ->node == node)))
396 } 397 goto found;
397 }
398 if (publ != sseq->zone_list)
399 prev->zone_list_next = publ->zone_list_next;
400 else if (publ->zone_list_next != publ) {
401 prev->zone_list_next = publ->zone_list_next;
402 sseq->zone_list = publ->zone_list_next;
403 } else {
404 sseq->zone_list = NULL;
405 } 398 }
406 sseq->zone_list_size--; 399 return NULL;
400
401found:
402 /* Remove publication from zone scope list */
403
404 list_del(&publ->zone_list);
405 info->zone_list_size--;
407 406
408 /* Remove publication from cluster scope list, if present */ 407 /* Remove publication from cluster scope list, if present */
409 408
410 if (in_own_cluster(node)) { 409 if (in_own_cluster(node)) {
411 prev = sseq->cluster_list; 410 list_del(&publ->cluster_list);
412 curr = sseq->cluster_list->cluster_list_next; 411 info->cluster_list_size--;
413 while (curr != publ) {
414 prev = curr;
415 curr = curr->cluster_list_next;
416 if (prev == sseq->cluster_list) {
417
418 /* Prevent endless loop for malformed list */
419
420 err("Unable to de-list cluster publication\n"
421 "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
422 publ->type, publ->lower, publ->node,
423 publ->ref, publ->key);
424 goto end_cluster;
425 }
426 }
427 if (publ != sseq->cluster_list)
428 prev->cluster_list_next = publ->cluster_list_next;
429 else if (publ->cluster_list_next != publ) {
430 prev->cluster_list_next = publ->cluster_list_next;
431 sseq->cluster_list = publ->cluster_list_next;
432 } else {
433 sseq->cluster_list = NULL;
434 }
435 sseq->cluster_list_size--;
436 } 412 }
437end_cluster:
438 413
439 /* Remove publication from node scope list, if present */ 414 /* Remove publication from node scope list, if present */
440 415
441 if (node == tipc_own_addr) { 416 if (node == tipc_own_addr) {
442 prev = sseq->node_list; 417 list_del(&publ->node_list);
443 curr = sseq->node_list->node_list_next; 418 info->node_list_size--;
444 while (curr != publ) {
445 prev = curr;
446 curr = curr->node_list_next;
447 if (prev == sseq->node_list) {
448
449 /* Prevent endless loop for malformed list */
450
451 err("Unable to de-list node publication\n"
452 "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
453 publ->type, publ->lower, publ->node,
454 publ->ref, publ->key);
455 goto end_node;
456 }
457 }
458 if (publ != sseq->node_list)
459 prev->node_list_next = publ->node_list_next;
460 else if (publ->node_list_next != publ) {
461 prev->node_list_next = publ->node_list_next;
462 sseq->node_list = publ->node_list_next;
463 } else {
464 sseq->node_list = NULL;
465 }
466 sseq->node_list_size--;
467 } 419 }
468end_node:
469 420
470 /* Contract subseq list if no more publications for that subseq */ 421 /* Contract subseq list if no more publications for that subseq */
471 422
472 if (!sseq->zone_list) { 423 if (list_empty(&info->zone_list)) {
424 kfree(info);
473 free = &nseq->sseqs[nseq->first_free--]; 425 free = &nseq->sseqs[nseq->first_free--];
474 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); 426 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
475 removed_subseq = 1; 427 removed_subseq = 1;
@@ -506,12 +458,12 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
506 return; 458 return;
507 459
508 while (sseq != &nseq->sseqs[nseq->first_free]) { 460 while (sseq != &nseq->sseqs[nseq->first_free]) {
509 struct publication *zl = sseq->zone_list; 461 if (tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
510 if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { 462 struct publication *crs;
511 struct publication *crs = zl; 463 struct name_info *info = sseq->info;
512 int must_report = 1; 464 int must_report = 1;
513 465
514 do { 466 list_for_each_entry(crs, &info->zone_list, zone_list) {
515 tipc_subscr_report_overlap(s, 467 tipc_subscr_report_overlap(s,
516 sseq->lower, 468 sseq->lower,
517 sseq->upper, 469 sseq->upper,
@@ -520,8 +472,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
520 crs->node, 472 crs->node,
521 must_report); 473 must_report);
522 must_report = 0; 474 must_report = 0;
523 crs = crs->zone_list_next; 475 }
524 } while (crs != zl);
525 } 476 }
526 sseq++; 477 sseq++;
527 } 478 }
@@ -591,9 +542,10 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
591u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) 542u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
592{ 543{
593 struct sub_seq *sseq; 544 struct sub_seq *sseq;
594 struct publication *publ = NULL; 545 struct name_info *info;
546 struct publication *publ;
595 struct name_seq *seq; 547 struct name_seq *seq;
596 u32 ref; 548 u32 ref = 0;
597 549
598 if (!tipc_in_scope(*destnode, tipc_own_addr)) 550 if (!tipc_in_scope(*destnode, tipc_own_addr))
599 return 0; 551 return 0;
@@ -606,55 +558,57 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
606 if (unlikely(!sseq)) 558 if (unlikely(!sseq))
607 goto not_found; 559 goto not_found;
608 spin_lock_bh(&seq->lock); 560 spin_lock_bh(&seq->lock);
561 info = sseq->info;
609 562
610 /* Closest-First Algorithm: */ 563 /* Closest-First Algorithm: */
611 if (likely(!*destnode)) { 564 if (likely(!*destnode)) {
612 publ = sseq->node_list; 565 if (!list_empty(&info->node_list)) {
613 if (publ) { 566 publ = list_first_entry(&info->node_list,
614 sseq->node_list = publ->node_list_next; 567 struct publication,
615found: 568 node_list);
616 ref = publ->ref; 569 list_move_tail(&publ->node_list,
617 *destnode = publ->node; 570 &info->node_list);
618 spin_unlock_bh(&seq->lock); 571 } else if (!list_empty(&info->cluster_list)) {
619 read_unlock_bh(&tipc_nametbl_lock); 572 publ = list_first_entry(&info->cluster_list,
620 return ref; 573 struct publication,
621 } 574 cluster_list);
622 publ = sseq->cluster_list; 575 list_move_tail(&publ->cluster_list,
623 if (publ) { 576 &info->cluster_list);
624 sseq->cluster_list = publ->cluster_list_next; 577 } else {
625 goto found; 578 publ = list_first_entry(&info->zone_list,
626 } 579 struct publication,
627 publ = sseq->zone_list; 580 zone_list);
628 if (publ) { 581 list_move_tail(&publ->zone_list,
629 sseq->zone_list = publ->zone_list_next; 582 &info->zone_list);
630 goto found;
631 } 583 }
632 } 584 }
633 585
634 /* Round-Robin Algorithm: */ 586 /* Round-Robin Algorithm: */
635 else if (*destnode == tipc_own_addr) { 587 else if (*destnode == tipc_own_addr) {
636 publ = sseq->node_list; 588 if (list_empty(&info->node_list))
637 if (publ) { 589 goto no_match;
638 sseq->node_list = publ->node_list_next; 590 publ = list_first_entry(&info->node_list, struct publication,
639 goto found; 591 node_list);
640 } 592 list_move_tail(&publ->node_list, &info->node_list);
641 } else if (in_own_cluster(*destnode)) { 593 } else if (in_own_cluster(*destnode)) {
642 publ = sseq->cluster_list; 594 if (list_empty(&info->cluster_list))
643 if (publ) { 595 goto no_match;
644 sseq->cluster_list = publ->cluster_list_next; 596 publ = list_first_entry(&info->cluster_list, struct publication,
645 goto found; 597 cluster_list);
646 } 598 list_move_tail(&publ->cluster_list, &info->cluster_list);
647 } else { 599 } else {
648 publ = sseq->zone_list; 600 publ = list_first_entry(&info->zone_list, struct publication,
649 if (publ) { 601 zone_list);
650 sseq->zone_list = publ->zone_list_next; 602 list_move_tail(&publ->zone_list, &info->zone_list);
651 goto found;
652 }
653 } 603 }
604
605 ref = publ->ref;
606 *destnode = publ->node;
607no_match:
654 spin_unlock_bh(&seq->lock); 608 spin_unlock_bh(&seq->lock);
655not_found: 609not_found:
656 read_unlock_bh(&tipc_nametbl_lock); 610 read_unlock_bh(&tipc_nametbl_lock);
657 return 0; 611 return ref;
658} 612}
659 613
660/** 614/**
@@ -676,6 +630,7 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
676 struct name_seq *seq; 630 struct name_seq *seq;
677 struct sub_seq *sseq; 631 struct sub_seq *sseq;
678 struct sub_seq *sseq_stop; 632 struct sub_seq *sseq_stop;
633 struct name_info *info;
679 int res = 0; 634 int res = 0;
680 635
681 read_lock_bh(&tipc_nametbl_lock); 636 read_lock_bh(&tipc_nametbl_lock);
@@ -693,16 +648,13 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
693 if (sseq->lower > upper) 648 if (sseq->lower > upper)
694 break; 649 break;
695 650
696 publ = sseq->node_list; 651 info = sseq->info;
697 if (publ) { 652 list_for_each_entry(publ, &info->node_list, node_list) {
698 do { 653 if (publ->scope <= limit)
699 if (publ->scope <= limit) 654 tipc_port_list_add(dports, publ->ref);
700 tipc_port_list_add(dports, publ->ref);
701 publ = publ->node_list_next;
702 } while (publ != sseq->node_list);
703 } 655 }
704 656
705 if (sseq->cluster_list_size != sseq->node_list_size) 657 if (info->cluster_list_size != info->node_list_size)
706 res = 1; 658 res = 1;
707 } 659 }
708 660
@@ -840,16 +792,19 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
840{ 792{
841 char portIdStr[27]; 793 char portIdStr[27];
842 const char *scope_str[] = {"", " zone", " cluster", " node"}; 794 const char *scope_str[] = {"", " zone", " cluster", " node"};
843 struct publication *publ = sseq->zone_list; 795 struct publication *publ;
796 struct name_info *info;
844 797
845 tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); 798 tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
846 799
847 if (depth == 2 || !publ) { 800 if (depth == 2) {
848 tipc_printf(buf, "\n"); 801 tipc_printf(buf, "\n");
849 return; 802 return;
850 } 803 }
851 804
852 do { 805 info = sseq->info;
806
807 list_for_each_entry(publ, &info->zone_list, zone_list) {
853 sprintf(portIdStr, "<%u.%u.%u:%u>", 808 sprintf(portIdStr, "<%u.%u.%u:%u>",
854 tipc_zone(publ->node), tipc_cluster(publ->node), 809 tipc_zone(publ->node), tipc_cluster(publ->node),
855 tipc_node(publ->node), publ->ref); 810 tipc_node(publ->node), publ->ref);
@@ -858,13 +813,9 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
858 tipc_printf(buf, "%-10u %s", publ->key, 813 tipc_printf(buf, "%-10u %s", publ->key,
859 scope_str[publ->scope]); 814 scope_str[publ->scope]);
860 } 815 }
861 816 if (!list_is_last(&publ->zone_list, &info->zone_list))
862 publ = publ->zone_list_next; 817 tipc_printf(buf, "\n%33s", " ");
863 if (publ == sseq->zone_list) 818 };
864 break;
865
866 tipc_printf(buf, "\n%33s", " ");
867 } while (1);
868 819
869 tipc_printf(buf, "\n"); 820 tipc_printf(buf, "\n");
870} 821}
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index d228bd682655..62d77e5e902e 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -2,7 +2,7 @@
2 * net/tipc/name_table.h: Include file for TIPC name table code 2 * net/tipc/name_table.h: Include file for TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, 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
@@ -61,9 +61,9 @@ struct port_list;
61 * @subscr: subscription to "node down" event (for off-node publications only) 61 * @subscr: subscription to "node down" event (for off-node publications only)
62 * @local_list: adjacent entries in list of publications made by this node 62 * @local_list: adjacent entries in list of publications made by this node
63 * @pport_list: adjacent entries in list of publications made by this port 63 * @pport_list: adjacent entries in list of publications made by this port
64 * @node_list: next matching name seq publication with >= node scope 64 * @node_list: adjacent matching name seq publications with >= node scope
65 * @cluster_list: next matching name seq publication with >= cluster scope 65 * @cluster_list: adjacent matching name seq publications with >= cluster scope
66 * @zone_list: next matching name seq publication with >= zone scope 66 * @zone_list: adjacent matching name seq publications with >= zone scope
67 * 67 *
68 * Note that the node list, cluster list, and zone list are circular lists. 68 * Note that the node list, cluster list, and zone list are circular lists.
69 */ 69 */
@@ -79,9 +79,9 @@ struct publication {
79 struct tipc_node_subscr subscr; 79 struct tipc_node_subscr subscr;
80 struct list_head local_list; 80 struct list_head local_list;
81 struct list_head pport_list; 81 struct list_head pport_list;
82 struct publication *node_list_next; 82 struct list_head node_list;
83 struct publication *cluster_list_next; 83 struct list_head cluster_list;
84 struct publication *zone_list_next; 84 struct list_head zone_list;
85}; 85};
86 86
87 87
diff --git a/net/tipc/port.c b/net/tipc/port.c
index c68dc956a423..54d812a5a4d9 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -222,7 +222,7 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
222 p_ptr->max_pkt = MAX_PKT_DEFAULT; 222 p_ptr->max_pkt = MAX_PKT_DEFAULT;
223 p_ptr->ref = ref; 223 p_ptr->ref = ref;
224 msg = &p_ptr->phdr; 224 msg = &p_ptr->phdr;
225 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 225 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, NAMED_H_SIZE, 0);
226 msg_set_origport(msg, ref); 226 msg_set_origport(msg, ref);
227 INIT_LIST_HEAD(&p_ptr->wait_list); 227 INIT_LIST_HEAD(&p_ptr->wait_list);
228 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 228 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
@@ -327,26 +327,23 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
327} 327}
328 328
329/* 329/*
330 * port_build_proto_msg(): build a port level protocol 330 * port_build_proto_msg(): create connection protocol message for port
331 * or a connection abortion message. Called with 331 *
332 * tipc_port lock on. 332 * On entry the port must be locked and connected.
333 */ 333 */
334static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 334static struct sk_buff *port_build_proto_msg(struct tipc_port *p_ptr,
335 u32 origport, u32 orignode, 335 u32 type, u32 ack)
336 u32 usr, u32 type, u32 err,
337 u32 ack)
338{ 336{
339 struct sk_buff *buf; 337 struct sk_buff *buf;
340 struct tipc_msg *msg; 338 struct tipc_msg *msg;
341 339
342 buf = tipc_buf_acquire(LONG_H_SIZE); 340 buf = tipc_buf_acquire(INT_H_SIZE);
343 if (buf) { 341 if (buf) {
344 msg = buf_msg(buf); 342 msg = buf_msg(buf);
345 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); 343 tipc_msg_init(msg, CONN_MANAGER, type, INT_H_SIZE,
346 msg_set_errcode(msg, err); 344 port_peernode(p_ptr));
347 msg_set_destport(msg, destport); 345 msg_set_destport(msg, port_peerport(p_ptr));
348 msg_set_origport(msg, origport); 346 msg_set_origport(msg, p_ptr->ref);
349 msg_set_orignode(msg, orignode);
350 msg_set_msgcnt(msg, ack); 347 msg_set_msgcnt(msg, ack);
351 } 348 }
352 return buf; 349 return buf;
@@ -358,45 +355,48 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
358 struct sk_buff *rbuf; 355 struct sk_buff *rbuf;
359 struct tipc_msg *rmsg; 356 struct tipc_msg *rmsg;
360 int hdr_sz; 357 int hdr_sz;
361 u32 imp = msg_importance(msg); 358 u32 imp;
362 u32 data_sz = msg_data_sz(msg); 359 u32 data_sz = msg_data_sz(msg);
363 360 u32 src_node;
364 if (data_sz > MAX_REJECT_SIZE) 361 u32 rmsg_sz;
365 data_sz = MAX_REJECT_SIZE;
366 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
367 imp++;
368 362
369 /* discard rejected message if it shouldn't be returned to sender */ 363 /* discard rejected message if it shouldn't be returned to sender */
370 if (msg_errcode(msg) || msg_dest_droppable(msg)) {
371 buf_discard(buf);
372 return data_sz;
373 }
374 364
375 /* construct rejected message */ 365 if (WARN(!msg_isdata(msg),
376 if (msg_mcast(msg)) 366 "attempt to reject message with user=%u", msg_user(msg))) {
377 hdr_sz = MCAST_H_SIZE; 367 dump_stack();
378 else 368 goto exit;
379 hdr_sz = LONG_H_SIZE;
380 rbuf = tipc_buf_acquire(data_sz + hdr_sz);
381 if (rbuf == NULL) {
382 buf_discard(buf);
383 return data_sz;
384 } 369 }
370 if (msg_errcode(msg) || msg_dest_droppable(msg))
371 goto exit;
372
373 /*
374 * construct returned message by copying rejected message header and
375 * data (or subset), then updating header fields that need adjusting
376 */
377
378 hdr_sz = msg_hdr_sz(msg);
379 rmsg_sz = hdr_sz + min_t(u32, data_sz, MAX_REJECT_SIZE);
380
381 rbuf = tipc_buf_acquire(rmsg_sz);
382 if (rbuf == NULL)
383 goto exit;
384
385 rmsg = buf_msg(rbuf); 385 rmsg = buf_msg(rbuf);
386 tipc_msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); 386 skb_copy_to_linear_data(rbuf, msg, rmsg_sz);
387 msg_set_errcode(rmsg, err); 387
388 msg_set_destport(rmsg, msg_origport(msg)); 388 if (msg_connected(rmsg)) {
389 msg_set_origport(rmsg, msg_destport(msg)); 389 imp = msg_importance(rmsg);
390 if (msg_short(msg)) { 390 if (imp < TIPC_CRITICAL_IMPORTANCE)
391 msg_set_orignode(rmsg, tipc_own_addr); 391 msg_set_importance(rmsg, ++imp);
392 /* leave name type & instance as zeroes */
393 } else {
394 msg_set_orignode(rmsg, msg_destnode(msg));
395 msg_set_nametype(rmsg, msg_nametype(msg));
396 msg_set_nameinst(rmsg, msg_nameinst(msg));
397 } 392 }
398 msg_set_size(rmsg, data_sz + hdr_sz); 393 msg_set_non_seq(rmsg, 0);
399 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); 394 msg_set_size(rmsg, rmsg_sz);
395 msg_set_errcode(rmsg, err);
396 msg_set_prevnode(rmsg, tipc_own_addr);
397 msg_swap_words(rmsg, 4, 5);
398 if (!msg_short(rmsg))
399 msg_swap_words(rmsg, 6, 7);
400 400
401 /* send self-abort message when rejecting on a connected port */ 401 /* send self-abort message when rejecting on a connected port */
402 if (msg_connected(msg)) { 402 if (msg_connected(msg)) {
@@ -411,9 +411,15 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
411 tipc_net_route_msg(abuf); 411 tipc_net_route_msg(abuf);
412 } 412 }
413 413
414 /* send rejected message */ 414 /* send returned message & dispose of rejected message */
415
416 src_node = msg_prevnode(msg);
417 if (src_node == tipc_own_addr)
418 tipc_port_recv_msg(rbuf);
419 else
420 tipc_link_send(rbuf, src_node, msg_link_selector(rmsg));
421exit:
415 buf_discard(buf); 422 buf_discard(buf);
416 tipc_net_route_msg(rbuf);
417 return data_sz; 423 return data_sz;
418} 424}
419 425
@@ -449,14 +455,7 @@ static void port_timeout(unsigned long ref)
449 if (p_ptr->probing_state == PROBING) { 455 if (p_ptr->probing_state == PROBING) {
450 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 456 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
451 } else { 457 } else {
452 buf = port_build_proto_msg(port_peerport(p_ptr), 458 buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0);
453 port_peernode(p_ptr),
454 p_ptr->ref,
455 tipc_own_addr,
456 CONN_MANAGER,
457 CONN_PROBE,
458 TIPC_OK,
459 0);
460 p_ptr->probing_state = PROBING; 459 p_ptr->probing_state = PROBING;
461 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 460 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
462 } 461 }
@@ -480,100 +479,94 @@ static void port_handle_node_down(unsigned long ref)
480 479
481static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err) 480static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
482{ 481{
483 u32 imp = msg_importance(&p_ptr->phdr); 482 struct sk_buff *buf = port_build_peer_abort_msg(p_ptr, err);
484 483
485 if (!p_ptr->connected) 484 if (buf) {
486 return NULL; 485 struct tipc_msg *msg = buf_msg(buf);
487 if (imp < TIPC_CRITICAL_IMPORTANCE) 486 msg_swap_words(msg, 4, 5);
488 imp++; 487 msg_swap_words(msg, 6, 7);
489 return port_build_proto_msg(p_ptr->ref, 488 }
490 tipc_own_addr, 489 return buf;
491 port_peerport(p_ptr),
492 port_peernode(p_ptr),
493 imp,
494 TIPC_CONN_MSG,
495 err,
496 0);
497} 490}
498 491
499 492
500static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err) 493static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
501{ 494{
502 u32 imp = msg_importance(&p_ptr->phdr); 495 struct sk_buff *buf;
496 struct tipc_msg *msg;
497 u32 imp;
503 498
504 if (!p_ptr->connected) 499 if (!p_ptr->connected)
505 return NULL; 500 return NULL;
506 if (imp < TIPC_CRITICAL_IMPORTANCE) 501
507 imp++; 502 buf = tipc_buf_acquire(BASIC_H_SIZE);
508 return port_build_proto_msg(port_peerport(p_ptr), 503 if (buf) {
509 port_peernode(p_ptr), 504 msg = buf_msg(buf);
510 p_ptr->ref, 505 memcpy(msg, &p_ptr->phdr, BASIC_H_SIZE);
511 tipc_own_addr, 506 msg_set_hdr_sz(msg, BASIC_H_SIZE);
512 imp, 507 msg_set_size(msg, BASIC_H_SIZE);
513 TIPC_CONN_MSG, 508 imp = msg_importance(msg);
514 err, 509 if (imp < TIPC_CRITICAL_IMPORTANCE)
515 0); 510 msg_set_importance(msg, ++imp);
511 msg_set_errcode(msg, err);
512 }
513 return buf;
516} 514}
517 515
518void tipc_port_recv_proto_msg(struct sk_buff *buf) 516void tipc_port_recv_proto_msg(struct sk_buff *buf)
519{ 517{
520 struct tipc_msg *msg = buf_msg(buf); 518 struct tipc_msg *msg = buf_msg(buf);
521 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg)); 519 struct tipc_port *p_ptr;
522 u32 err = TIPC_OK;
523 struct sk_buff *r_buf = NULL; 520 struct sk_buff *r_buf = NULL;
524 struct sk_buff *abort_buf = NULL; 521 u32 orignode = msg_orignode(msg);
525 522 u32 origport = msg_origport(msg);
526 if (!p_ptr) { 523 u32 destport = msg_destport(msg);
527 err = TIPC_ERR_NO_PORT; 524 int wakeable;
528 } else if (p_ptr->connected) { 525
529 if ((port_peernode(p_ptr) != msg_orignode(msg)) || 526 /* Validate connection */
530 (port_peerport(p_ptr) != msg_origport(msg))) { 527
531 err = TIPC_ERR_NO_PORT; 528 p_ptr = tipc_port_lock(destport);
532 } else if (msg_type(msg) == CONN_ACK) { 529 if (!p_ptr || !p_ptr->connected ||
533 int wakeup = tipc_port_congested(p_ptr) && 530 (port_peernode(p_ptr) != orignode) ||
534 p_ptr->congested && 531 (port_peerport(p_ptr) != origport)) {
535 p_ptr->wakeup; 532 r_buf = tipc_buf_acquire(BASIC_H_SIZE);
536 p_ptr->acked += msg_msgcnt(msg); 533 if (r_buf) {
537 if (tipc_port_congested(p_ptr)) 534 msg = buf_msg(r_buf);
538 goto exit; 535 tipc_msg_init(msg, TIPC_HIGH_IMPORTANCE, TIPC_CONN_MSG,
539 p_ptr->congested = 0; 536 BASIC_H_SIZE, orignode);
540 if (!wakeup) 537 msg_set_errcode(msg, TIPC_ERR_NO_PORT);
541 goto exit; 538 msg_set_origport(msg, destport);
542 p_ptr->wakeup(p_ptr); 539 msg_set_destport(msg, origport);
543 goto exit;
544 } 540 }
545 } else if (p_ptr->published) { 541 if (p_ptr)
546 err = TIPC_ERR_NO_PORT; 542 tipc_port_unlock(p_ptr);
547 }
548 if (err) {
549 r_buf = port_build_proto_msg(msg_origport(msg),
550 msg_orignode(msg),
551 msg_destport(msg),
552 tipc_own_addr,
553 TIPC_HIGH_IMPORTANCE,
554 TIPC_CONN_MSG,
555 err,
556 0);
557 goto exit; 543 goto exit;
558 } 544 }
559 545
560 /* All is fine */ 546 /* Process protocol message sent by peer */
561 if (msg_type(msg) == CONN_PROBE) { 547
562 r_buf = port_build_proto_msg(msg_origport(msg), 548 switch (msg_type(msg)) {
563 msg_orignode(msg), 549 case CONN_ACK:
564 msg_destport(msg), 550 wakeable = tipc_port_congested(p_ptr) && p_ptr->congested &&
565 tipc_own_addr, 551 p_ptr->wakeup;
566 CONN_MANAGER, 552 p_ptr->acked += msg_msgcnt(msg);
567 CONN_PROBE_REPLY, 553 if (!tipc_port_congested(p_ptr)) {
568 TIPC_OK, 554 p_ptr->congested = 0;
569 0); 555 if (wakeable)
556 p_ptr->wakeup(p_ptr);
557 }
558 break;
559 case CONN_PROBE:
560 r_buf = port_build_proto_msg(p_ptr, CONN_PROBE_REPLY, 0);
561 break;
562 default:
563 /* CONN_PROBE_REPLY or unrecognized - no action required */
564 break;
570 } 565 }
571 p_ptr->probing_state = CONFIRMED; 566 p_ptr->probing_state = CONFIRMED;
567 tipc_port_unlock(p_ptr);
572exit: 568exit:
573 if (p_ptr)
574 tipc_port_unlock(p_ptr);
575 tipc_net_route_msg(r_buf); 569 tipc_net_route_msg(r_buf);
576 tipc_net_route_msg(abort_buf);
577 buf_discard(buf); 570 buf_discard(buf);
578} 571}
579 572
@@ -889,14 +882,7 @@ void tipc_acknowledge(u32 ref, u32 ack)
889 return; 882 return;
890 if (p_ptr->connected) { 883 if (p_ptr->connected) {
891 p_ptr->conn_unacked -= ack; 884 p_ptr->conn_unacked -= ack;
892 buf = port_build_proto_msg(port_peerport(p_ptr), 885 buf = port_build_proto_msg(p_ptr, CONN_ACK, ack);
893 port_peernode(p_ptr),
894 ref,
895 tipc_own_addr,
896 CONN_MANAGER,
897 CONN_ACK,
898 TIPC_OK,
899 ack);
900 } 886 }
901 tipc_port_unlock(p_ptr); 887 tipc_port_unlock(p_ptr);
902 tipc_net_route_msg(buf); 888 tipc_net_route_msg(buf);
@@ -1140,19 +1126,7 @@ int tipc_shutdown(u32 ref)
1140 if (!p_ptr) 1126 if (!p_ptr)
1141 return -EINVAL; 1127 return -EINVAL;
1142 1128
1143 if (p_ptr->connected) { 1129 buf = port_build_peer_abort_msg(p_ptr, TIPC_CONN_SHUTDOWN);
1144 u32 imp = msg_importance(&p_ptr->phdr);
1145 if (imp < TIPC_CRITICAL_IMPORTANCE)
1146 imp++;
1147 buf = port_build_proto_msg(port_peerport(p_ptr),
1148 port_peernode(p_ptr),
1149 ref,
1150 tipc_own_addr,
1151 imp,
1152 TIPC_CONN_MSG,
1153 TIPC_CONN_SHUTDOWN,
1154 0);
1155 }
1156 tipc_port_unlock(p_ptr); 1130 tipc_port_unlock(p_ptr);
1157 tipc_net_route_msg(buf); 1131 tipc_net_route_msg(buf);
1158 return tipc_disconnect(ref); 1132 return tipc_disconnect(ref);
@@ -1238,7 +1212,7 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1238 msg_set_type(msg, TIPC_NAMED_MSG); 1212 msg_set_type(msg, TIPC_NAMED_MSG);
1239 msg_set_orignode(msg, tipc_own_addr); 1213 msg_set_orignode(msg, tipc_own_addr);
1240 msg_set_origport(msg, ref); 1214 msg_set_origport(msg, ref);
1241 msg_set_hdr_sz(msg, LONG_H_SIZE); 1215 msg_set_hdr_sz(msg, NAMED_H_SIZE);
1242 msg_set_nametype(msg, name->type); 1216 msg_set_nametype(msg, name->type);
1243 msg_set_nameinst(msg, name->instance); 1217 msg_set_nameinst(msg, name->instance);
1244 msg_set_lookup_scope(msg, tipc_addr_scope(domain)); 1218 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
@@ -1291,7 +1265,7 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1291 msg_set_origport(msg, ref); 1265 msg_set_origport(msg, ref);
1292 msg_set_destnode(msg, dest->node); 1266 msg_set_destnode(msg, dest->node);
1293 msg_set_destport(msg, dest->ref); 1267 msg_set_destport(msg, dest->ref);
1294 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1268 msg_set_hdr_sz(msg, BASIC_H_SIZE);
1295 1269
1296 if (dest->node == tipc_own_addr) 1270 if (dest->node == tipc_own_addr)
1297 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, 1271 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
@@ -1331,13 +1305,13 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1331 msg_set_origport(msg, ref); 1305 msg_set_origport(msg, ref);
1332 msg_set_destnode(msg, dest->node); 1306 msg_set_destnode(msg, dest->node);
1333 msg_set_destport(msg, dest->ref); 1307 msg_set_destport(msg, dest->ref);
1334 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1308 msg_set_hdr_sz(msg, BASIC_H_SIZE);
1335 msg_set_size(msg, DIR_MSG_H_SIZE + dsz); 1309 msg_set_size(msg, BASIC_H_SIZE + dsz);
1336 if (skb_cow(buf, DIR_MSG_H_SIZE)) 1310 if (skb_cow(buf, BASIC_H_SIZE))
1337 return -ENOMEM; 1311 return -ENOMEM;
1338 1312
1339 skb_push(buf, DIR_MSG_H_SIZE); 1313 skb_push(buf, BASIC_H_SIZE);
1340 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1314 skb_copy_to_linear_data(buf, msg, BASIC_H_SIZE);
1341 1315
1342 if (dest->node == tipc_own_addr) 1316 if (dest->node == tipc_own_addr)
1343 res = tipc_port_recv_msg(buf); 1317 res = tipc_port_recv_msg(buf);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 338837396642..adb2eff4a102 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -36,9 +36,6 @@
36 36
37#include <net/sock.h> 37#include <net/sock.h>
38 38
39#include <linux/tipc.h>
40#include <linux/tipc_config.h>
41
42#include "core.h" 39#include "core.h"
43#include "port.h" 40#include "port.h"
44 41