diff options
author | David S. Miller <davem@davemloft.net> | 2011-06-24 19:49:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-24 19:49:10 -0400 |
commit | 1897fe55e1385ddfb7733d0e0819588571cca867 (patch) | |
tree | 672c324c49e0252da94d15ddd68d78d2df4da903 | |
parent | cd5f3e2064ea21e1cbe140728a1b04e7d32f68eb (diff) | |
parent | e4a0aee47e1823025972b8f3defde432e485b7b9 (diff) |
Merge branch 'tipc-Jun24-2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/net-next-2.6
-rw-r--r-- | net/tipc/bcast.c | 6 | ||||
-rw-r--r-- | net/tipc/bearer.c | 1 | ||||
-rw-r--r-- | net/tipc/bearer.h | 2 | ||||
-rw-r--r-- | net/tipc/core.h | 6 | ||||
-rw-r--r-- | net/tipc/link.c | 6 | ||||
-rw-r--r-- | net/tipc/msg.c | 6 | ||||
-rw-r--r-- | net/tipc/msg.h | 34 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 6 | ||||
-rw-r--r-- | net/tipc/name_table.c | 289 | ||||
-rw-r--r-- | net/tipc/name_table.h | 14 | ||||
-rw-r--r-- | net/tipc/port.c | 284 | ||||
-rw-r--r-- | net/tipc/socket.c | 3 |
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) | |||
402 | void tipc_continue(struct tipc_bearer *b_ptr) | 402 | void 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 */ | |||
62 | struct print_buf; /* log.h */ | 62 | struct 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, | |||
1572 | static int link_recv_buf_validate(struct sk_buff *buf) | 1572 | static 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 | |||
323 | static inline u32 msg_destnode_cache(struct tipc_msg *m) | ||
324 | { | ||
325 | return m->hdr[2]; | ||
326 | } | ||
327 | |||
328 | static 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 | ||
378 | static inline int msg_short(struct tipc_msg *m) | 358 | static 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 | ||
383 | static inline u32 msg_orignode(struct tipc_msg *m) | 363 | static inline u32 msg_orignode(struct tipc_msg *m) |
@@ -635,7 +615,7 @@ static inline u32 msg_link_selector(struct tipc_msg *m) | |||
635 | 615 | ||
636 | static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) | 616 | static 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 | ||
660 | static inline void msg_set_probe(struct tipc_msg *m, u32 val) | 640 | static 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 | ||
665 | static inline char msg_net_plane(struct tipc_msg *m) | 645 | static 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 | ||
95 | static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) | 95 | static 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 @@ | |||
44 | static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | 44 | static 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 | ||
62 | struct sub_seq { | 60 | struct 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 | |||
76 | struct 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 | |||
401 | found: | ||
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 | } |
437 | end_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 | } |
468 | end_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, | |||
591 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | 542 | u32 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, |
615 | found: | 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; | ||
607 | no_match: | ||
654 | spin_unlock_bh(&seq->lock); | 608 | spin_unlock_bh(&seq->lock); |
655 | not_found: | 609 | not_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 | */ |
334 | static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, | 334 | static 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)); | ||
421 | exit: | ||
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 | ||
481 | static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err) | 480 | static 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 | ||
500 | static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err) | 493 | static 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 | ||
518 | void tipc_port_recv_proto_msg(struct sk_buff *buf) | 516 | void 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); | ||
572 | exit: | 568 | exit: |
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 | ||