diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/bcast.c | 14 | ||||
| -rw-r--r-- | net/tipc/bearer.c | 8 | ||||
| -rw-r--r-- | net/tipc/cluster.c | 4 | ||||
| -rw-r--r-- | net/tipc/config.c | 11 | ||||
| -rw-r--r-- | net/tipc/core.c | 13 | ||||
| -rw-r--r-- | net/tipc/core.h | 137 | ||||
| -rw-r--r-- | net/tipc/dbg.c | 231 | ||||
| -rw-r--r-- | net/tipc/dbg.h | 12 | ||||
| -rw-r--r-- | net/tipc/discover.c | 14 | ||||
| -rw-r--r-- | net/tipc/discover.h | 2 | ||||
| -rw-r--r-- | net/tipc/eth_media.c | 10 | ||||
| -rw-r--r-- | net/tipc/link.c | 98 | ||||
| -rw-r--r-- | net/tipc/msg.c | 13 | ||||
| -rw-r--r-- | net/tipc/msg.h | 42 | ||||
| -rw-r--r-- | net/tipc/name_distr.c | 6 | ||||
| -rw-r--r-- | net/tipc/name_table.c | 55 | ||||
| -rw-r--r-- | net/tipc/net.c | 14 | ||||
| -rw-r--r-- | net/tipc/net.h | 2 | ||||
| -rw-r--r-- | net/tipc/netlink.c | 16 | ||||
| -rw-r--r-- | net/tipc/node.c | 55 | ||||
| -rw-r--r-- | net/tipc/port.c | 115 | ||||
| -rw-r--r-- | net/tipc/ref.c | 14 | ||||
| -rw-r--r-- | net/tipc/socket.c | 62 | ||||
| -rw-r--r-- | net/tipc/subscr.c | 249 | ||||
| -rw-r--r-- | net/tipc/subscr.h | 34 | ||||
| -rw-r--r-- | net/tipc/user_reg.c | 14 |
26 files changed, 692 insertions, 553 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index e7880172ef19..b1ff16aa4bdb 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -276,7 +276,7 @@ static void bclink_send_nack(struct node *n_ptr) | |||
| 276 | if (buf) { | 276 | if (buf) { |
| 277 | msg = buf_msg(buf); | 277 | msg = buf_msg(buf); |
| 278 | msg_init(msg, BCAST_PROTOCOL, STATE_MSG, | 278 | msg_init(msg, BCAST_PROTOCOL, STATE_MSG, |
| 279 | TIPC_OK, INT_H_SIZE, n_ptr->addr); | 279 | INT_H_SIZE, n_ptr->addr); |
| 280 | msg_set_mc_netid(msg, tipc_net_id); | 280 | msg_set_mc_netid(msg, tipc_net_id); |
| 281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); | 281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); |
| 282 | msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); | 282 | msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); |
| @@ -571,7 +571,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 571 | assert(tipc_cltr_bcast_nodes.count != 0); | 571 | assert(tipc_cltr_bcast_nodes.count != 0); |
| 572 | bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); | 572 | bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); |
| 573 | msg = buf_msg(buf); | 573 | msg = buf_msg(buf); |
| 574 | msg_set_non_seq(msg); | 574 | msg_set_non_seq(msg, 1); |
| 575 | msg_set_mc_netid(msg, tipc_net_id); | 575 | msg_set_mc_netid(msg, tipc_net_id); |
| 576 | } | 576 | } |
| 577 | 577 | ||
| @@ -611,7 +611,7 @@ swap: | |||
| 611 | bcbearer->bpairs[bp_index].secondary = p; | 611 | bcbearer->bpairs[bp_index].secondary = p; |
| 612 | update: | 612 | update: |
| 613 | if (bcbearer->remains_new.count == 0) | 613 | if (bcbearer->remains_new.count == 0) |
| 614 | return TIPC_OK; | 614 | return 0; |
| 615 | 615 | ||
| 616 | bcbearer->remains = bcbearer->remains_new; | 616 | bcbearer->remains = bcbearer->remains_new; |
| 617 | } | 617 | } |
| @@ -620,7 +620,7 @@ update: | |||
| 620 | 620 | ||
| 621 | bcbearer->bearer.publ.blocked = 1; | 621 | bcbearer->bearer.publ.blocked = 1; |
| 622 | bcl->stats.bearer_congs++; | 622 | bcl->stats.bearer_congs++; |
| 623 | return ~TIPC_OK; | 623 | return 1; |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | /** | 626 | /** |
| @@ -756,7 +756,7 @@ int tipc_bclink_reset_stats(void) | |||
| 756 | spin_lock_bh(&bc_lock); | 756 | spin_lock_bh(&bc_lock); |
| 757 | memset(&bcl->stats, 0, sizeof(bcl->stats)); | 757 | memset(&bcl->stats, 0, sizeof(bcl->stats)); |
| 758 | spin_unlock_bh(&bc_lock); | 758 | spin_unlock_bh(&bc_lock); |
| 759 | return TIPC_OK; | 759 | return 0; |
| 760 | } | 760 | } |
| 761 | 761 | ||
| 762 | int tipc_bclink_set_queue_limits(u32 limit) | 762 | int tipc_bclink_set_queue_limits(u32 limit) |
| @@ -769,7 +769,7 @@ int tipc_bclink_set_queue_limits(u32 limit) | |||
| 769 | spin_lock_bh(&bc_lock); | 769 | spin_lock_bh(&bc_lock); |
| 770 | tipc_link_set_queue_limits(bcl, limit); | 770 | tipc_link_set_queue_limits(bcl, limit); |
| 771 | spin_unlock_bh(&bc_lock); | 771 | spin_unlock_bh(&bc_lock); |
| 772 | return TIPC_OK; | 772 | return 0; |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | int tipc_bclink_init(void) | 775 | int tipc_bclink_init(void) |
| @@ -810,7 +810,7 @@ int tipc_bclink_init(void) | |||
| 810 | tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); | 810 | tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); |
| 811 | } | 811 | } |
| 812 | 812 | ||
| 813 | return TIPC_OK; | 813 | return 0; |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | void tipc_bclink_stop(void) | 816 | void tipc_bclink_stop(void) |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 271a375b49b7..6a9aba3edd08 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
| @@ -370,7 +370,7 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) | |||
| 370 | */ | 370 | */ |
| 371 | static int bearer_push(struct bearer *b_ptr) | 371 | static int bearer_push(struct bearer *b_ptr) |
| 372 | { | 372 | { |
| 373 | u32 res = TIPC_OK; | 373 | u32 res = 0; |
| 374 | struct link *ln, *tln; | 374 | struct link *ln, *tln; |
| 375 | 375 | ||
| 376 | if (b_ptr->publ.blocked) | 376 | if (b_ptr->publ.blocked) |
| @@ -607,7 +607,7 @@ int tipc_block_bearer(const char *name) | |||
| 607 | } | 607 | } |
| 608 | spin_unlock_bh(&b_ptr->publ.lock); | 608 | spin_unlock_bh(&b_ptr->publ.lock); |
| 609 | read_unlock_bh(&tipc_net_lock); | 609 | read_unlock_bh(&tipc_net_lock); |
| 610 | return TIPC_OK; | 610 | return 0; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | /** | 613 | /** |
| @@ -645,7 +645,7 @@ static int bearer_disable(const char *name) | |||
| 645 | } | 645 | } |
| 646 | spin_unlock_bh(&b_ptr->publ.lock); | 646 | spin_unlock_bh(&b_ptr->publ.lock); |
| 647 | memset(b_ptr, 0, sizeof(struct bearer)); | 647 | memset(b_ptr, 0, sizeof(struct bearer)); |
| 648 | return TIPC_OK; | 648 | return 0; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | int tipc_disable_bearer(const char *name) | 651 | int tipc_disable_bearer(const char *name) |
| @@ -668,7 +668,7 @@ int tipc_bearer_init(void) | |||
| 668 | tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); | 668 | tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); |
| 669 | media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); | 669 | media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); |
| 670 | if (tipc_bearers && media_list) { | 670 | if (tipc_bearers && media_list) { |
| 671 | res = TIPC_OK; | 671 | res = 0; |
| 672 | } else { | 672 | } else { |
| 673 | kfree(tipc_bearers); | 673 | kfree(tipc_bearers); |
| 674 | kfree(media_list); | 674 | kfree(media_list); |
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 4bb3404f610b..46ee6c58532d 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c | |||
| @@ -238,7 +238,7 @@ static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest) | |||
| 238 | if (buf) { | 238 | if (buf) { |
| 239 | msg = buf_msg(buf); | 239 | msg = buf_msg(buf); |
| 240 | memset((char *)msg, 0, size); | 240 | memset((char *)msg, 0, size); |
| 241 | msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest); | 241 | msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest); |
| 242 | } | 242 | } |
| 243 | return buf; | 243 | return buf; |
| 244 | } | 244 | } |
| @@ -571,6 +571,6 @@ exit: | |||
| 571 | int tipc_cltr_init(void) | 571 | int tipc_cltr_init(void) |
| 572 | { | 572 | { |
| 573 | tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; | 573 | tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; |
| 574 | return tipc_cltr_create(tipc_own_addr) ? TIPC_OK : -ENOMEM; | 574 | return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM; |
| 575 | } | 575 | } |
| 576 | 576 | ||
diff --git a/net/tipc/config.c b/net/tipc/config.c index c71337a22d33..ca3544d030c7 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/config.c: TIPC configuration management code | 2 | * net/tipc/config.c: TIPC configuration management code |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2002-2006, Ericsson AB | 4 | * Copyright (c) 2002-2006, Ericsson AB |
| 5 | * Copyright (c) 2004-2006, Wind River Systems | 5 | * Copyright (c) 2004-2007, 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 |
| @@ -293,7 +293,6 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
| 293 | if (tipc_mode == TIPC_NET_MODE) | 293 | if (tipc_mode == TIPC_NET_MODE) |
| 294 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 294 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
| 295 | " (cannot change node address once assigned)"); | 295 | " (cannot change node address once assigned)"); |
| 296 | tipc_own_addr = addr; | ||
| 297 | 296 | ||
| 298 | /* | 297 | /* |
| 299 | * Must release all spinlocks before calling start_net() because | 298 | * Must release all spinlocks before calling start_net() because |
| @@ -306,7 +305,7 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
| 306 | */ | 305 | */ |
| 307 | 306 | ||
| 308 | spin_unlock_bh(&config_lock); | 307 | spin_unlock_bh(&config_lock); |
| 309 | tipc_core_start_net(); | 308 | tipc_core_start_net(addr); |
| 310 | spin_lock_bh(&config_lock); | 309 | spin_lock_bh(&config_lock); |
| 311 | return tipc_cfg_reply_none(); | 310 | return tipc_cfg_reply_none(); |
| 312 | } | 311 | } |
| @@ -529,7 +528,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
| 529 | break; | 528 | break; |
| 530 | #endif | 529 | #endif |
| 531 | case TIPC_CMD_SET_LOG_SIZE: | 530 | case TIPC_CMD_SET_LOG_SIZE: |
| 532 | rep_tlv_buf = tipc_log_resize(req_tlv_area, req_tlv_space); | 531 | rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); |
| 533 | break; | 532 | break; |
| 534 | case TIPC_CMD_DUMP_LOG: | 533 | case TIPC_CMD_DUMP_LOG: |
| 535 | rep_tlv_buf = tipc_log_dump(); | 534 | rep_tlv_buf = tipc_log_dump(); |
| @@ -602,6 +601,10 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
| 602 | case TIPC_CMD_GET_NETID: | 601 | case TIPC_CMD_GET_NETID: |
| 603 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); | 602 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); |
| 604 | break; | 603 | break; |
| 604 | case TIPC_CMD_NOT_NET_ADMIN: | ||
| 605 | rep_tlv_buf = | ||
| 606 | tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); | ||
| 607 | break; | ||
| 605 | default: | 608 | default: |
| 606 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 609 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
| 607 | " (unknown command)"); | 610 | " (unknown command)"); |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 740aac5cdfb6..3256bd7d398f 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -49,7 +49,7 @@ | |||
| 49 | #include "config.h" | 49 | #include "config.h" |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | #define TIPC_MOD_VER "1.6.3" | 52 | #define TIPC_MOD_VER "1.6.4" |
| 53 | 53 | ||
| 54 | #ifndef CONFIG_TIPC_ZONES | 54 | #ifndef CONFIG_TIPC_ZONES |
| 55 | #define CONFIG_TIPC_ZONES 3 | 55 | #define CONFIG_TIPC_ZONES 3 |
| @@ -117,11 +117,11 @@ void tipc_core_stop_net(void) | |||
| 117 | * start_net - start TIPC networking sub-systems | 117 | * start_net - start TIPC networking sub-systems |
| 118 | */ | 118 | */ |
| 119 | 119 | ||
| 120 | int tipc_core_start_net(void) | 120 | int tipc_core_start_net(unsigned long addr) |
| 121 | { | 121 | { |
| 122 | int res; | 122 | int res; |
| 123 | 123 | ||
| 124 | if ((res = tipc_net_start()) || | 124 | if ((res = tipc_net_start(addr)) || |
| 125 | (res = tipc_eth_media_start())) { | 125 | (res = tipc_eth_media_start())) { |
| 126 | tipc_core_stop_net(); | 126 | tipc_core_stop_net(); |
| 127 | } | 127 | } |
| @@ -164,8 +164,7 @@ int tipc_core_start(void) | |||
| 164 | tipc_mode = TIPC_NODE_MODE; | 164 | tipc_mode = TIPC_NODE_MODE; |
| 165 | 165 | ||
| 166 | if ((res = tipc_handler_start()) || | 166 | if ((res = tipc_handler_start()) || |
| 167 | (res = tipc_ref_table_init(tipc_max_ports + tipc_max_subscriptions, | 167 | (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || |
| 168 | tipc_random)) || | ||
| 169 | (res = tipc_reg_start()) || | 168 | (res = tipc_reg_start()) || |
| 170 | (res = tipc_nametbl_init()) || | 169 | (res = tipc_nametbl_init()) || |
| 171 | (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || | 170 | (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || |
| @@ -182,7 +181,7 @@ static int __init tipc_init(void) | |||
| 182 | { | 181 | { |
| 183 | int res; | 182 | int res; |
| 184 | 183 | ||
| 185 | tipc_log_reinit(CONFIG_TIPC_LOG); | 184 | tipc_log_resize(CONFIG_TIPC_LOG); |
| 186 | info("Activated (version " TIPC_MOD_VER | 185 | info("Activated (version " TIPC_MOD_VER |
| 187 | " compiled " __DATE__ " " __TIME__ ")\n"); | 186 | " compiled " __DATE__ " " __TIME__ ")\n"); |
| 188 | 187 | ||
| @@ -209,7 +208,7 @@ static void __exit tipc_exit(void) | |||
| 209 | tipc_core_stop_net(); | 208 | tipc_core_stop_net(); |
| 210 | tipc_core_stop(); | 209 | tipc_core_stop(); |
| 211 | info("Deactivated\n"); | 210 | info("Deactivated\n"); |
| 212 | tipc_log_stop(); | 211 | tipc_log_resize(0); |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | module_init(tipc_init); | 214 | module_init(tipc_init); |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 325404fd4eb5..a881f92a8537 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/core.h: Include file for TIPC global declarations | 2 | * net/tipc/core.h: Include file for TIPC global declarations |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, Ericsson AB |
| 5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -59,84 +59,108 @@ | |||
| 59 | #include <linux/vmalloc.h> | 59 | #include <linux/vmalloc.h> |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * TIPC debugging code | 62 | * TIPC sanity test macros |
| 63 | */ | 63 | */ |
| 64 | 64 | ||
| 65 | #define assert(i) BUG_ON(!(i)) | 65 | #define assert(i) BUG_ON(!(i)) |
| 66 | 66 | ||
| 67 | struct tipc_msg; | ||
| 68 | extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; | ||
| 69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); | ||
| 70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); | ||
| 71 | void tipc_printf(struct print_buf *, const char *fmt, ...); | ||
| 72 | void tipc_dump(struct print_buf*,const char *fmt, ...); | ||
| 73 | |||
| 74 | #ifdef CONFIG_TIPC_DEBUG | ||
| 75 | |||
| 76 | /* | 67 | /* |
| 77 | * TIPC debug support included: | 68 | * TIPC system monitoring code |
| 78 | * - system messages are printed to TIPC_OUTPUT print buffer | ||
| 79 | * - debug messages are printed to DBG_OUTPUT print buffer | ||
| 80 | */ | 69 | */ |
| 81 | 70 | ||
| 82 | #define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_ERR "TIPC: " fmt, ## arg) | 71 | /* |
| 83 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) | 72 | * TIPC's print buffer subsystem supports the following print buffers: |
| 84 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) | 73 | * |
| 74 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
| 75 | * TIPC_CONS : system console | ||
| 76 | * TIPC_LOG : TIPC log buffer | ||
| 77 | * &buf : user-defined buffer (struct print_buf *) | ||
| 78 | * | ||
| 79 | * Note: TIPC_LOG is configured to echo its output to the system console; | ||
| 80 | * user-defined buffers can be configured to do the same thing. | ||
| 81 | */ | ||
| 85 | 82 | ||
| 86 | #define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) | 83 | extern struct print_buf *const TIPC_NULL; |
| 87 | #define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) | 84 | extern struct print_buf *const TIPC_CONS; |
| 88 | #define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) | 85 | extern struct print_buf *const TIPC_LOG; |
| 89 | 86 | ||
| 87 | void tipc_printf(struct print_buf *, const char *fmt, ...); | ||
| 90 | 88 | ||
| 91 | /* | 89 | /* |
| 92 | * By default, TIPC_OUTPUT is defined to be system console and TIPC log buffer, | 90 | * TIPC_OUTPUT is the destination print buffer for system messages. |
| 93 | * while DBG_OUTPUT is the null print buffer. These defaults can be changed | ||
| 94 | * here, or on a per .c file basis, by redefining these symbols. The following | ||
| 95 | * print buffer options are available: | ||
| 96 | * | ||
| 97 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
| 98 | * TIPC_CONS : system console | ||
| 99 | * TIPC_LOG : TIPC log buffer | ||
| 100 | * &buf : user-defined buffer (struct print_buf *) | ||
| 101 | * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG)) | ||
| 102 | */ | 91 | */ |
| 103 | 92 | ||
| 104 | #ifndef TIPC_OUTPUT | 93 | #ifndef TIPC_OUTPUT |
| 105 | #define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG) | 94 | #define TIPC_OUTPUT TIPC_LOG |
| 106 | #endif | ||
| 107 | |||
| 108 | #ifndef DBG_OUTPUT | ||
| 109 | #define DBG_OUTPUT TIPC_NULL | ||
| 110 | #endif | 95 | #endif |
| 111 | 96 | ||
| 112 | #else | ||
| 113 | |||
| 114 | /* | 97 | /* |
| 115 | * TIPC debug support not included: | 98 | * TIPC can be configured to send system messages to TIPC_OUTPUT |
| 116 | * - system messages are printed to system console | 99 | * or to the system console only. |
| 117 | * - debug messages are not printed | ||
| 118 | */ | 100 | */ |
| 119 | 101 | ||
| 102 | #ifdef CONFIG_TIPC_DEBUG | ||
| 103 | |||
| 104 | #define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
| 105 | KERN_ERR "TIPC: " fmt, ## arg) | ||
| 106 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
| 107 | KERN_WARNING "TIPC: " fmt, ## arg) | ||
| 108 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
| 109 | KERN_NOTICE "TIPC: " fmt, ## arg) | ||
| 110 | |||
| 111 | #else | ||
| 112 | |||
| 120 | #define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) | 113 | #define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) |
| 121 | #define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) | 114 | #define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) |
| 122 | #define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) | 115 | #define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) |
| 123 | 116 | ||
| 124 | #define dbg(fmt, arg...) do {} while (0) | 117 | #endif |
| 125 | #define msg_dbg(msg,txt) do {} while (0) | ||
| 126 | #define dump(fmt,arg...) do {} while (0) | ||
| 127 | 118 | ||
| 119 | /* | ||
| 120 | * DBG_OUTPUT is the destination print buffer for debug messages. | ||
| 121 | * It defaults to the the null print buffer, but can be redefined | ||
| 122 | * (typically in the individual .c files being debugged) to allow | ||
| 123 | * selected debug messages to be generated where needed. | ||
| 124 | */ | ||
| 125 | |||
| 126 | #ifndef DBG_OUTPUT | ||
| 127 | #define DBG_OUTPUT TIPC_NULL | ||
| 128 | #endif | ||
| 128 | 129 | ||
| 129 | /* | 130 | /* |
| 130 | * TIPC_OUTPUT is defined to be the system console, while DBG_OUTPUT is | 131 | * TIPC can be configured to send debug messages to the specified print buffer |
| 131 | * the null print buffer. Thes ensures that any system or debug messages | 132 | * (typically DBG_OUTPUT) or to suppress them entirely. |
| 132 | * that are generated without using the above macros are handled correctly. | ||
| 133 | */ | 133 | */ |
| 134 | 134 | ||
| 135 | #undef TIPC_OUTPUT | 135 | #ifdef CONFIG_TIPC_DEBUG |
| 136 | #define TIPC_OUTPUT TIPC_CONS | ||
| 137 | 136 | ||
| 138 | #undef DBG_OUTPUT | 137 | #define dbg(fmt, arg...) \ |
| 139 | #define DBG_OUTPUT TIPC_NULL | 138 | do { \ |
| 139 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
| 140 | tipc_printf(DBG_OUTPUT, fmt, ## arg); \ | ||
| 141 | } while (0) | ||
| 142 | #define msg_dbg(msg, txt) \ | ||
| 143 | do { \ | ||
| 144 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
| 145 | tipc_msg_dbg(DBG_OUTPUT, msg, txt); \ | ||
| 146 | } while (0) | ||
| 147 | #define dump(fmt, arg...) \ | ||
| 148 | do { \ | ||
| 149 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
| 150 | tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \ | ||
| 151 | } while (0) | ||
| 152 | |||
| 153 | void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); | ||
| 154 | void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); | ||
| 155 | |||
| 156 | #else | ||
| 157 | |||
| 158 | #define dbg(fmt, arg...) do {} while (0) | ||
| 159 | #define msg_dbg(msg, txt) do {} while (0) | ||
| 160 | #define dump(fmt, arg...) do {} while (0) | ||
| 161 | |||
| 162 | #define tipc_msg_dbg(...) do {} while (0) | ||
| 163 | #define tipc_dump_dbg(...) do {} while (0) | ||
| 140 | 164 | ||
| 141 | #endif | 165 | #endif |
| 142 | 166 | ||
| @@ -178,7 +202,7 @@ extern atomic_t tipc_user_count; | |||
| 178 | 202 | ||
| 179 | extern int tipc_core_start(void); | 203 | extern int tipc_core_start(void); |
| 180 | extern void tipc_core_stop(void); | 204 | extern void tipc_core_stop(void); |
| 181 | extern int tipc_core_start_net(void); | 205 | extern int tipc_core_start_net(unsigned long addr); |
| 182 | extern void tipc_core_stop_net(void); | 206 | extern void tipc_core_stop_net(void); |
| 183 | extern int tipc_handler_start(void); | 207 | extern int tipc_handler_start(void); |
| 184 | extern void tipc_handler_stop(void); | 208 | extern void tipc_handler_stop(void); |
| @@ -279,15 +303,14 @@ static inline void k_term_timer(struct timer_list *timer) | |||
| 279 | /* | 303 | /* |
| 280 | * TIPC message buffer code | 304 | * TIPC message buffer code |
| 281 | * | 305 | * |
| 282 | * TIPC message buffer headroom reserves space for a link-level header | 306 | * TIPC message buffer headroom reserves space for the worst-case |
| 283 | * (in case the message is sent off-node), | 307 | * link-level device header (in case the message is sent off-node). |
| 284 | * while ensuring TIPC header is word aligned for quicker access | ||
| 285 | * | 308 | * |
| 286 | * The largest header currently supported is 18 bytes, which is used when | 309 | * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields |
| 287 | * the standard 14 byte Ethernet header has 4 added bytes for VLAN info | 310 | * are word aligned for quicker access |
| 288 | */ | 311 | */ |
| 289 | 312 | ||
| 290 | #define BUF_HEADROOM 20u | 313 | #define BUF_HEADROOM LL_MAX_HEADER |
| 291 | 314 | ||
| 292 | struct tipc_skb_cb { | 315 | struct tipc_skb_cb { |
| 293 | void *handle; | 316 | void *handle; |
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index e809d2a2ce06..29ecae851668 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging | 2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 1996-2006, Ericsson AB | 4 | * Copyright (c) 1996-2006, Ericsson AB |
| 5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -38,17 +38,43 @@ | |||
| 38 | #include "config.h" | 38 | #include "config.h" |
| 39 | #include "dbg.h" | 39 | #include "dbg.h" |
| 40 | 40 | ||
| 41 | static char print_string[TIPC_PB_MAX_STR]; | 41 | /* |
| 42 | static DEFINE_SPINLOCK(print_lock); | 42 | * TIPC pre-defines the following print buffers: |
| 43 | * | ||
| 44 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
| 45 | * TIPC_CONS : system console | ||
| 46 | * TIPC_LOG : TIPC log buffer | ||
| 47 | * | ||
| 48 | * Additional user-defined print buffers are also permitted. | ||
| 49 | */ | ||
| 43 | 50 | ||
| 44 | static struct print_buf null_buf = { NULL, 0, NULL, NULL }; | 51 | static struct print_buf null_buf = { NULL, 0, NULL, 0 }; |
| 45 | struct print_buf *TIPC_NULL = &null_buf; | 52 | struct print_buf *const TIPC_NULL = &null_buf; |
| 46 | 53 | ||
| 47 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; | 54 | static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; |
| 48 | struct print_buf *TIPC_CONS = &cons_buf; | 55 | struct print_buf *const TIPC_CONS = &cons_buf; |
| 49 | 56 | ||
| 50 | static struct print_buf log_buf = { NULL, 0, NULL, NULL }; | 57 | static struct print_buf log_buf = { NULL, 0, NULL, 1 }; |
| 51 | struct print_buf *TIPC_LOG = &log_buf; | 58 | struct print_buf *const TIPC_LOG = &log_buf; |
| 59 | |||
| 60 | /* | ||
| 61 | * Locking policy when using print buffers. | ||
| 62 | * | ||
| 63 | * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to | ||
| 64 | * 'print_string' when writing to a print buffer. This also protects against | ||
| 65 | * concurrent writes to the print buffer being written to. | ||
| 66 | * | ||
| 67 | * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned | ||
| 68 | * use of 'print_lock' to protect against all types of concurrent operations | ||
| 69 | * on their associated print buffer (not just write operations). | ||
| 70 | * | ||
| 71 | * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely | ||
| 72 | * on the caller to prevent simultaneous use of the print buffer(s) being | ||
| 73 | * manipulated. | ||
| 74 | */ | ||
| 75 | |||
| 76 | static char print_string[TIPC_PB_MAX_STR]; | ||
| 77 | static DEFINE_SPINLOCK(print_lock); | ||
| 52 | 78 | ||
| 53 | 79 | ||
| 54 | #define FORMAT(PTR,LEN,FMT) \ | 80 | #define FORMAT(PTR,LEN,FMT) \ |
| @@ -60,27 +86,14 @@ struct print_buf *TIPC_LOG = &log_buf; | |||
| 60 | *(PTR + LEN) = '\0';\ | 86 | *(PTR + LEN) = '\0';\ |
| 61 | } | 87 | } |
| 62 | 88 | ||
| 63 | /* | ||
| 64 | * Locking policy when using print buffers. | ||
| 65 | * | ||
| 66 | * The following routines use 'print_lock' for protection: | ||
| 67 | * 1) tipc_printf() - to protect its print buffer(s) and 'print_string' | ||
| 68 | * 2) TIPC_TEE() - to protect its print buffer(s) | ||
| 69 | * 3) tipc_dump() - to protect its print buffer(s) and 'print_string' | ||
| 70 | * 4) tipc_log_XXX() - to protect TIPC_LOG | ||
| 71 | * | ||
| 72 | * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent | ||
| 73 | * simultaneous use of the print buffer(s) being manipulated. | ||
| 74 | */ | ||
| 75 | |||
| 76 | /** | 89 | /** |
| 77 | * tipc_printbuf_init - initialize print buffer to empty | 90 | * tipc_printbuf_init - initialize print buffer to empty |
| 78 | * @pb: pointer to print buffer structure | 91 | * @pb: pointer to print buffer structure |
| 79 | * @raw: pointer to character array used by print buffer | 92 | * @raw: pointer to character array used by print buffer |
| 80 | * @size: size of character array | 93 | * @size: size of character array |
| 81 | * | 94 | * |
| 82 | * Makes the print buffer a null device that discards anything written to it | 95 | * Note: If the character array is too small (or absent), the print buffer |
| 83 | * if the character array is too small (or absent). | 96 | * becomes a null device that discards anything written to it. |
| 84 | */ | 97 | */ |
| 85 | 98 | ||
| 86 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | 99 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) |
| @@ -88,13 +101,13 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | |||
| 88 | pb->buf = raw; | 101 | pb->buf = raw; |
| 89 | pb->crs = raw; | 102 | pb->crs = raw; |
| 90 | pb->size = size; | 103 | pb->size = size; |
| 91 | pb->next = NULL; | 104 | pb->echo = 0; |
| 92 | 105 | ||
| 93 | if (size < TIPC_PB_MIN_SIZE) { | 106 | if (size < TIPC_PB_MIN_SIZE) { |
| 94 | pb->buf = NULL; | 107 | pb->buf = NULL; |
| 95 | } else if (raw) { | 108 | } else if (raw) { |
| 96 | pb->buf[0] = 0; | 109 | pb->buf[0] = 0; |
| 97 | pb->buf[size-1] = ~0; | 110 | pb->buf[size - 1] = ~0; |
| 98 | } | 111 | } |
| 99 | } | 112 | } |
| 100 | 113 | ||
| @@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | |||
| 105 | 118 | ||
| 106 | void tipc_printbuf_reset(struct print_buf *pb) | 119 | void tipc_printbuf_reset(struct print_buf *pb) |
| 107 | { | 120 | { |
| 108 | tipc_printbuf_init(pb, pb->buf, pb->size); | 121 | if (pb->buf) { |
| 122 | pb->crs = pb->buf; | ||
| 123 | pb->buf[0] = 0; | ||
| 124 | pb->buf[pb->size - 1] = ~0; | ||
| 125 | } | ||
| 109 | } | 126 | } |
| 110 | 127 | ||
| 111 | /** | 128 | /** |
| @@ -141,7 +158,7 @@ int tipc_printbuf_validate(struct print_buf *pb) | |||
| 141 | 158 | ||
| 142 | if (pb->buf[pb->size - 1] == 0) { | 159 | if (pb->buf[pb->size - 1] == 0) { |
| 143 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); | 160 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); |
| 144 | if (cp_buf != NULL){ | 161 | if (cp_buf) { |
| 145 | tipc_printbuf_init(&cb, cp_buf, pb->size); | 162 | tipc_printbuf_init(&cb, cp_buf, pb->size); |
| 146 | tipc_printbuf_move(&cb, pb); | 163 | tipc_printbuf_move(&cb, pb); |
| 147 | tipc_printbuf_move(pb, &cb); | 164 | tipc_printbuf_move(pb, &cb); |
| @@ -179,15 +196,16 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
| 179 | } | 196 | } |
| 180 | 197 | ||
| 181 | if (pb_to->size < pb_from->size) { | 198 | if (pb_to->size < pb_from->size) { |
| 182 | tipc_printbuf_reset(pb_to); | 199 | strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); |
| 183 | tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); | 200 | pb_to->buf[pb_to->size - 1] = ~0; |
| 201 | pb_to->crs = strchr(pb_to->buf, 0); | ||
| 184 | return; | 202 | return; |
| 185 | } | 203 | } |
| 186 | 204 | ||
| 187 | /* Copy data from char after cursor to end (if used) */ | 205 | /* Copy data from char after cursor to end (if used) */ |
| 188 | 206 | ||
| 189 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; | 207 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; |
| 190 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { | 208 | if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) { |
| 191 | strcpy(pb_to->buf, pb_from->crs + 1); | 209 | strcpy(pb_to->buf, pb_from->crs + 1); |
| 192 | pb_to->crs = pb_to->buf + len; | 210 | pb_to->crs = pb_to->buf + len; |
| 193 | } else | 211 | } else |
| @@ -203,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
| 203 | } | 221 | } |
| 204 | 222 | ||
| 205 | /** | 223 | /** |
| 206 | * tipc_printf - append formatted output to print buffer chain | 224 | * tipc_printf - append formatted output to print buffer |
| 207 | * @pb: pointer to chain of print buffers (may be NULL) | 225 | * @pb: pointer to print buffer |
| 208 | * @fmt: formatted info to be printed | 226 | * @fmt: formatted info to be printed |
| 209 | */ | 227 | */ |
| 210 | 228 | ||
| @@ -213,68 +231,40 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
| 213 | int chars_to_add; | 231 | int chars_to_add; |
| 214 | int chars_left; | 232 | int chars_left; |
| 215 | char save_char; | 233 | char save_char; |
| 216 | struct print_buf *pb_next; | ||
| 217 | 234 | ||
| 218 | spin_lock_bh(&print_lock); | 235 | spin_lock_bh(&print_lock); |
| 236 | |||
| 219 | FORMAT(print_string, chars_to_add, fmt); | 237 | FORMAT(print_string, chars_to_add, fmt); |
| 220 | if (chars_to_add >= TIPC_PB_MAX_STR) | 238 | if (chars_to_add >= TIPC_PB_MAX_STR) |
| 221 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); | 239 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); |
| 222 | 240 | ||
| 223 | while (pb) { | 241 | if (pb->buf) { |
| 224 | if (pb == TIPC_CONS) | 242 | chars_left = pb->buf + pb->size - pb->crs - 1; |
| 225 | printk(print_string); | 243 | if (chars_to_add <= chars_left) { |
| 226 | else if (pb->buf) { | 244 | strcpy(pb->crs, print_string); |
| 227 | chars_left = pb->buf + pb->size - pb->crs - 1; | 245 | pb->crs += chars_to_add; |
| 228 | if (chars_to_add <= chars_left) { | 246 | } else if (chars_to_add >= (pb->size - 1)) { |
| 229 | strcpy(pb->crs, print_string); | 247 | strcpy(pb->buf, print_string + chars_to_add + 1 |
| 230 | pb->crs += chars_to_add; | 248 | - pb->size); |
| 231 | } else if (chars_to_add >= (pb->size - 1)) { | 249 | pb->crs = pb->buf + pb->size - 1; |
| 232 | strcpy(pb->buf, print_string + chars_to_add + 1 | 250 | } else { |
| 233 | - pb->size); | 251 | strcpy(pb->buf, print_string + chars_left); |
| 234 | pb->crs = pb->buf + pb->size - 1; | 252 | save_char = print_string[chars_left]; |
| 235 | } else { | 253 | print_string[chars_left] = 0; |
| 236 | strcpy(pb->buf, print_string + chars_left); | 254 | strcpy(pb->crs, print_string); |
| 237 | save_char = print_string[chars_left]; | 255 | print_string[chars_left] = save_char; |
| 238 | print_string[chars_left] = 0; | 256 | pb->crs = pb->buf + chars_to_add - chars_left; |
| 239 | strcpy(pb->crs, print_string); | ||
| 240 | print_string[chars_left] = save_char; | ||
| 241 | pb->crs = pb->buf + chars_to_add - chars_left; | ||
| 242 | } | ||
| 243 | } | 257 | } |
| 244 | pb_next = pb->next; | ||
| 245 | pb->next = NULL; | ||
| 246 | pb = pb_next; | ||
| 247 | } | 258 | } |
| 248 | spin_unlock_bh(&print_lock); | ||
| 249 | } | ||
| 250 | 259 | ||
| 251 | /** | 260 | if (pb->echo) |
| 252 | * TIPC_TEE - perform next output operation on both print buffers | 261 | printk(print_string); |
| 253 | * @b0: pointer to chain of print buffers (may be NULL) | ||
| 254 | * @b1: pointer to print buffer to add to chain | ||
| 255 | * | ||
| 256 | * Returns pointer to print buffer chain. | ||
| 257 | */ | ||
| 258 | 262 | ||
| 259 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | ||
| 260 | { | ||
| 261 | struct print_buf *pb = b0; | ||
| 262 | |||
| 263 | if (!b0 || (b0 == b1)) | ||
| 264 | return b1; | ||
| 265 | |||
| 266 | spin_lock_bh(&print_lock); | ||
| 267 | while (pb->next) { | ||
| 268 | if ((pb->next == b1) || (pb->next == b0)) | ||
| 269 | pb->next = pb->next->next; | ||
| 270 | else | ||
| 271 | pb = pb->next; | ||
| 272 | } | ||
| 273 | pb->next = b1; | ||
| 274 | spin_unlock_bh(&print_lock); | 263 | spin_unlock_bh(&print_lock); |
| 275 | return b0; | ||
| 276 | } | 264 | } |
| 277 | 265 | ||
| 266 | #ifdef CONFIG_TIPC_DEBUG | ||
| 267 | |||
| 278 | /** | 268 | /** |
| 279 | * print_to_console - write string of bytes to console in multiple chunks | 269 | * print_to_console - write string of bytes to console in multiple chunks |
| 280 | */ | 270 | */ |
| @@ -321,72 +311,66 @@ static void printbuf_dump(struct print_buf *pb) | |||
| 321 | } | 311 | } |
| 322 | 312 | ||
| 323 | /** | 313 | /** |
| 324 | * tipc_dump - dump non-console print buffer(s) to console | 314 | * tipc_dump_dbg - dump (non-console) print buffer to console |
| 325 | * @pb: pointer to chain of print buffers | 315 | * @pb: pointer to print buffer |
| 326 | */ | 316 | */ |
| 327 | 317 | ||
| 328 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) | 318 | void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...) |
| 329 | { | 319 | { |
| 330 | struct print_buf *pb_next; | ||
| 331 | int len; | 320 | int len; |
| 332 | 321 | ||
| 322 | if (pb == TIPC_CONS) | ||
| 323 | return; | ||
| 324 | |||
| 333 | spin_lock_bh(&print_lock); | 325 | spin_lock_bh(&print_lock); |
| 326 | |||
| 334 | FORMAT(print_string, len, fmt); | 327 | FORMAT(print_string, len, fmt); |
| 335 | printk(print_string); | 328 | printk(print_string); |
| 336 | 329 | ||
| 337 | for (; pb; pb = pb->next) { | 330 | printk("\n---- Start of %s log dump ----\n\n", |
| 338 | if (pb != TIPC_CONS) { | 331 | (pb == TIPC_LOG) ? "global" : "local"); |
| 339 | printk("\n---- Start of %s log dump ----\n\n", | 332 | printbuf_dump(pb); |
| 340 | (pb == TIPC_LOG) ? "global" : "local"); | 333 | tipc_printbuf_reset(pb); |
| 341 | printbuf_dump(pb); | 334 | printk("\n---- End of dump ----\n"); |
| 342 | tipc_printbuf_reset(pb); | 335 | |
| 343 | printk("\n---- End of dump ----\n"); | ||
| 344 | } | ||
| 345 | pb_next = pb->next; | ||
| 346 | pb->next = NULL; | ||
| 347 | pb = pb_next; | ||
| 348 | } | ||
| 349 | spin_unlock_bh(&print_lock); | 336 | spin_unlock_bh(&print_lock); |
| 350 | } | 337 | } |
| 351 | 338 | ||
| 339 | #endif | ||
| 340 | |||
| 352 | /** | 341 | /** |
| 353 | * tipc_log_stop - free up TIPC log print buffer | 342 | * tipc_log_resize - change the size of the TIPC log buffer |
| 343 | * @log_size: print buffer size to use | ||
| 354 | */ | 344 | */ |
| 355 | 345 | ||
| 356 | void tipc_log_stop(void) | 346 | int tipc_log_resize(int log_size) |
| 357 | { | 347 | { |
| 348 | int res = 0; | ||
| 349 | |||
| 358 | spin_lock_bh(&print_lock); | 350 | spin_lock_bh(&print_lock); |
| 359 | if (TIPC_LOG->buf) { | 351 | if (TIPC_LOG->buf) { |
| 360 | kfree(TIPC_LOG->buf); | 352 | kfree(TIPC_LOG->buf); |
| 361 | TIPC_LOG->buf = NULL; | 353 | TIPC_LOG->buf = NULL; |
| 362 | } | 354 | } |
| 363 | spin_unlock_bh(&print_lock); | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * tipc_log_reinit - (re)initialize TIPC log print buffer | ||
| 368 | * @log_size: print buffer size to use | ||
| 369 | */ | ||
| 370 | |||
| 371 | void tipc_log_reinit(int log_size) | ||
| 372 | { | ||
| 373 | tipc_log_stop(); | ||
| 374 | |||
| 375 | if (log_size) { | 355 | if (log_size) { |
| 376 | if (log_size < TIPC_PB_MIN_SIZE) | 356 | if (log_size < TIPC_PB_MIN_SIZE) |
| 377 | log_size = TIPC_PB_MIN_SIZE; | 357 | log_size = TIPC_PB_MIN_SIZE; |
| 378 | spin_lock_bh(&print_lock); | 358 | res = TIPC_LOG->echo; |
| 379 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), | 359 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), |
| 380 | log_size); | 360 | log_size); |
| 381 | spin_unlock_bh(&print_lock); | 361 | TIPC_LOG->echo = res; |
| 362 | res = !TIPC_LOG->buf; | ||
| 382 | } | 363 | } |
| 364 | spin_unlock_bh(&print_lock); | ||
| 365 | |||
| 366 | return res; | ||
| 383 | } | 367 | } |
| 384 | 368 | ||
| 385 | /** | 369 | /** |
| 386 | * tipc_log_resize - reconfigure size of TIPC log buffer | 370 | * tipc_log_resize_cmd - reconfigure size of TIPC log buffer |
| 387 | */ | 371 | */ |
| 388 | 372 | ||
| 389 | struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) | 373 | struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space) |
| 390 | { | 374 | { |
| 391 | u32 value; | 375 | u32 value; |
| 392 | 376 | ||
| @@ -397,7 +381,9 @@ struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) | |||
| 397 | if (value != delimit(value, 0, 32768)) | 381 | if (value != delimit(value, 0, 32768)) |
| 398 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 382 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
| 399 | " (log size must be 0-32768)"); | 383 | " (log size must be 0-32768)"); |
| 400 | tipc_log_reinit(value); | 384 | if (tipc_log_resize(value)) |
| 385 | return tipc_cfg_reply_error_string( | ||
| 386 | "unable to create specified log (log size is now 0)"); | ||
| 401 | return tipc_cfg_reply_none(); | 387 | return tipc_cfg_reply_none(); |
| 402 | } | 388 | } |
| 403 | 389 | ||
| @@ -410,27 +396,32 @@ struct sk_buff *tipc_log_dump(void) | |||
| 410 | struct sk_buff *reply; | 396 | struct sk_buff *reply; |
| 411 | 397 | ||
| 412 | spin_lock_bh(&print_lock); | 398 | spin_lock_bh(&print_lock); |
| 413 | if (!TIPC_LOG->buf) | 399 | if (!TIPC_LOG->buf) { |
| 400 | spin_unlock_bh(&print_lock); | ||
| 414 | reply = tipc_cfg_reply_ultra_string("log not activated\n"); | 401 | reply = tipc_cfg_reply_ultra_string("log not activated\n"); |
| 415 | else if (tipc_printbuf_empty(TIPC_LOG)) | 402 | } else if (tipc_printbuf_empty(TIPC_LOG)) { |
| 403 | spin_unlock_bh(&print_lock); | ||
| 416 | reply = tipc_cfg_reply_ultra_string("log is empty\n"); | 404 | reply = tipc_cfg_reply_ultra_string("log is empty\n"); |
| 405 | } | ||
| 417 | else { | 406 | else { |
| 418 | struct tlv_desc *rep_tlv; | 407 | struct tlv_desc *rep_tlv; |
| 419 | struct print_buf pb; | 408 | struct print_buf pb; |
| 420 | int str_len; | 409 | int str_len; |
| 421 | 410 | ||
| 422 | str_len = min(TIPC_LOG->size, 32768u); | 411 | str_len = min(TIPC_LOG->size, 32768u); |
| 412 | spin_unlock_bh(&print_lock); | ||
| 423 | reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); | 413 | reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); |
| 424 | if (reply) { | 414 | if (reply) { |
| 425 | rep_tlv = (struct tlv_desc *)reply->data; | 415 | rep_tlv = (struct tlv_desc *)reply->data; |
| 426 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); | 416 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); |
| 417 | spin_lock_bh(&print_lock); | ||
| 427 | tipc_printbuf_move(&pb, TIPC_LOG); | 418 | tipc_printbuf_move(&pb, TIPC_LOG); |
| 419 | spin_unlock_bh(&print_lock); | ||
| 428 | str_len = strlen(TLV_DATA(rep_tlv)) + 1; | 420 | str_len = strlen(TLV_DATA(rep_tlv)) + 1; |
| 429 | skb_put(reply, TLV_SPACE(str_len)); | 421 | skb_put(reply, TLV_SPACE(str_len)); |
| 430 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 422 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
| 431 | } | 423 | } |
| 432 | } | 424 | } |
| 433 | spin_unlock_bh(&print_lock); | ||
| 434 | return reply; | 425 | return reply; |
| 435 | } | 426 | } |
| 436 | 427 | ||
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h index c01b085000e0..5ef1bc8f64ef 100644 --- a/net/tipc/dbg.h +++ b/net/tipc/dbg.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines | 2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 1997-2006, Ericsson AB | 4 | * Copyright (c) 1997-2006, Ericsson AB |
| 5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -42,14 +42,14 @@ | |||
| 42 | * @buf: pointer to character array containing print buffer contents | 42 | * @buf: pointer to character array containing print buffer contents |
| 43 | * @size: size of character array | 43 | * @size: size of character array |
| 44 | * @crs: pointer to first unused space in character array (i.e. final NUL) | 44 | * @crs: pointer to first unused space in character array (i.e. final NUL) |
| 45 | * @next: used to link print buffers when printing to more than one at a time | 45 | * @echo: echo output to system console if non-zero |
| 46 | */ | 46 | */ |
| 47 | 47 | ||
| 48 | struct print_buf { | 48 | struct print_buf { |
| 49 | char *buf; | 49 | char *buf; |
| 50 | u32 size; | 50 | u32 size; |
| 51 | char *crs; | 51 | char *crs; |
| 52 | struct print_buf *next; | 52 | int echo; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | #define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ | 55 | #define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ |
| @@ -61,10 +61,10 @@ int tipc_printbuf_empty(struct print_buf *pb); | |||
| 61 | int tipc_printbuf_validate(struct print_buf *pb); | 61 | int tipc_printbuf_validate(struct print_buf *pb); |
| 62 | void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); | 62 | void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); |
| 63 | 63 | ||
| 64 | void tipc_log_reinit(int log_size); | 64 | int tipc_log_resize(int log_size); |
| 65 | void tipc_log_stop(void); | ||
| 66 | 65 | ||
| 67 | struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space); | 66 | struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, |
| 67 | int req_tlv_space); | ||
| 68 | struct sk_buff *tipc_log_dump(void); | 68 | struct sk_buff *tipc_log_dump(void); |
| 69 | 69 | ||
| 70 | #endif | 70 | #endif |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 5d643e5721eb..1657f0e795ff 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
| @@ -120,9 +120,8 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, | |||
| 120 | 120 | ||
| 121 | if (buf) { | 121 | if (buf) { |
| 122 | msg = buf_msg(buf); | 122 | msg = buf_msg(buf); |
| 123 | msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE, | 123 | msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); |
| 124 | dest_domain); | 124 | msg_set_non_seq(msg, 1); |
| 125 | msg_set_non_seq(msg); | ||
| 126 | msg_set_req_links(msg, req_links); | 125 | msg_set_req_links(msg, req_links); |
| 127 | msg_set_dest_domain(msg, dest_domain); | 126 | msg_set_dest_domain(msg, dest_domain); |
| 128 | msg_set_bc_netid(msg, tipc_net_id); | 127 | msg_set_bc_netid(msg, tipc_net_id); |
| @@ -156,11 +155,11 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, | |||
| 156 | /** | 155 | /** |
| 157 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) | 156 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) |
| 158 | * @buf: buffer containing message | 157 | * @buf: buffer containing message |
| 158 | * @b_ptr: bearer that message arrived on | ||
| 159 | */ | 159 | */ |
| 160 | 160 | ||
| 161 | void tipc_disc_recv_msg(struct sk_buff *buf) | 161 | void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) |
| 162 | { | 162 | { |
| 163 | struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle; | ||
| 164 | struct link *link; | 163 | struct link *link; |
| 165 | struct tipc_media_addr media_addr; | 164 | struct tipc_media_addr media_addr; |
| 166 | struct tipc_msg *msg = buf_msg(buf); | 165 | struct tipc_msg *msg = buf_msg(buf); |
| @@ -200,9 +199,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf) | |||
| 200 | dbg(" in own cluster\n"); | 199 | dbg(" in own cluster\n"); |
| 201 | if (n_ptr == NULL) { | 200 | if (n_ptr == NULL) { |
| 202 | n_ptr = tipc_node_create(orig); | 201 | n_ptr = tipc_node_create(orig); |
| 203 | } | 202 | if (!n_ptr) |
| 204 | if (n_ptr == NULL) { | 203 | return; |
| 205 | return; | ||
| 206 | } | 204 | } |
| 207 | spin_lock_bh(&n_ptr->lock); | 205 | spin_lock_bh(&n_ptr->lock); |
| 208 | link = n_ptr->links[b_ptr->identity]; | 206 | link = n_ptr->links[b_ptr->identity]; |
diff --git a/net/tipc/discover.h b/net/tipc/discover.h index 9fd7587b143a..c36eaeb7d5d0 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h | |||
| @@ -48,7 +48,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, | |||
| 48 | void tipc_disc_update_link_req(struct link_req *req); | 48 | void tipc_disc_update_link_req(struct link_req *req); |
| 49 | void tipc_disc_stop_link_req(struct link_req *req); | 49 | void tipc_disc_stop_link_req(struct link_req *req); |
| 50 | 50 | ||
| 51 | void tipc_disc_recv_msg(struct sk_buff *buf); | 51 | void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); |
| 52 | 52 | ||
| 53 | void tipc_disc_link_event(u32 addr, char *name, int up); | 53 | void tipc_disc_link_event(u32 addr, char *name, int up); |
| 54 | #if 0 | 54 | #if 0 |
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 9cd35eec3e7f..fe43ef7dd7e3 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c | |||
| @@ -82,7 +82,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, | |||
| 82 | dev->dev_addr, clone->len); | 82 | dev->dev_addr, clone->len); |
| 83 | dev_queue_xmit(clone); | 83 | dev_queue_xmit(clone); |
| 84 | } | 84 | } |
| 85 | return TIPC_OK; | 85 | return 0; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /** | 88 | /** |
| @@ -101,7 +101,7 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
| 101 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; | 101 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; |
| 102 | u32 size; | 102 | u32 size; |
| 103 | 103 | ||
| 104 | if (dev_net(dev) != &init_net) { | 104 | if (!net_eq(dev_net(dev), &init_net)) { |
| 105 | kfree_skb(buf); | 105 | kfree_skb(buf); |
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| @@ -113,12 +113,12 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
| 113 | if (likely(buf->len == size)) { | 113 | if (likely(buf->len == size)) { |
| 114 | buf->next = NULL; | 114 | buf->next = NULL; |
| 115 | tipc_recv_msg(buf, eb_ptr->bearer); | 115 | tipc_recv_msg(buf, eb_ptr->bearer); |
| 116 | return TIPC_OK; | 116 | return 0; |
| 117 | } | 117 | } |
| 118 | } | 118 | } |
| 119 | } | 119 | } |
| 120 | kfree_skb(buf); | 120 | kfree_skb(buf); |
| 121 | return TIPC_OK; | 121 | return 0; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | /** | 124 | /** |
| @@ -198,7 +198,7 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt, | |||
| 198 | struct eth_bearer *eb_ptr = ð_bearers[0]; | 198 | struct eth_bearer *eb_ptr = ð_bearers[0]; |
| 199 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; | 199 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; |
| 200 | 200 | ||
| 201 | if (dev_net(dev) != &init_net) | 201 | if (!net_eq(dev_net(dev), &init_net)) |
| 202 | return NOTIFY_DONE; | 202 | return NOTIFY_DONE; |
| 203 | 203 | ||
| 204 | while ((eb_ptr->dev != dev)) { | 204 | while ((eb_ptr->dev != dev)) { |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 2a26a16e269f..d60113ba4b1b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -51,6 +51,12 @@ | |||
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | /* | 53 | /* |
| 54 | * Out-of-range value for link session numbers | ||
| 55 | */ | ||
| 56 | |||
| 57 | #define INVALID_SESSION 0x10000 | ||
| 58 | |||
| 59 | /* | ||
| 54 | * Limit for deferred reception queue: | 60 | * Limit for deferred reception queue: |
| 55 | */ | 61 | */ |
| 56 | 62 | ||
| @@ -147,9 +153,21 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
| 147 | 153 | ||
| 148 | #define LINK_LOG_BUF_SIZE 0 | 154 | #define LINK_LOG_BUF_SIZE 0 |
| 149 | 155 | ||
| 150 | #define dbg_link(fmt, arg...) do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0) | 156 | #define dbg_link(fmt, arg...) \ |
| 151 | #define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) tipc_msg_print(&l_ptr->print_buf, msg, txt); } while(0) | 157 | do { \ |
| 152 | #define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0) | 158 | if (LINK_LOG_BUF_SIZE) \ |
| 159 | tipc_printf(&l_ptr->print_buf, fmt, ## arg); \ | ||
| 160 | } while (0) | ||
| 161 | #define dbg_link_msg(msg, txt) \ | ||
| 162 | do { \ | ||
| 163 | if (LINK_LOG_BUF_SIZE) \ | ||
| 164 | tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \ | ||
| 165 | } while (0) | ||
| 166 | #define dbg_link_state(txt) \ | ||
| 167 | do { \ | ||
| 168 | if (LINK_LOG_BUF_SIZE) \ | ||
| 169 | link_print(l_ptr, &l_ptr->print_buf, txt); \ | ||
| 170 | } while (0) | ||
| 153 | #define dbg_link_dump() do { \ | 171 | #define dbg_link_dump() do { \ |
| 154 | if (LINK_LOG_BUF_SIZE) { \ | 172 | if (LINK_LOG_BUF_SIZE) { \ |
| 155 | tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ | 173 | tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ |
| @@ -450,9 +468,9 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, | |||
| 450 | 468 | ||
| 451 | l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; | 469 | l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; |
| 452 | msg = l_ptr->pmsg; | 470 | msg = l_ptr->pmsg; |
| 453 | msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 471 | msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr); |
| 454 | msg_set_size(msg, sizeof(l_ptr->proto_msg)); | 472 | msg_set_size(msg, sizeof(l_ptr->proto_msg)); |
| 455 | msg_set_session(msg, tipc_random); | 473 | msg_set_session(msg, (tipc_random & 0xffff)); |
| 456 | msg_set_bearer_id(msg, b_ptr->identity); | 474 | msg_set_bearer_id(msg, b_ptr->identity); |
| 457 | strcpy((char *)msg_data(msg), if_name); | 475 | strcpy((char *)msg_data(msg), if_name); |
| 458 | 476 | ||
| @@ -693,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr) | |||
| 693 | u32 checkpoint = l_ptr->next_in_no; | 711 | u32 checkpoint = l_ptr->next_in_no; |
| 694 | int was_active_link = tipc_link_is_active(l_ptr); | 712 | int was_active_link = tipc_link_is_active(l_ptr); |
| 695 | 713 | ||
| 696 | msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); | 714 | msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff)); |
| 697 | 715 | ||
| 698 | /* Link is down, accept any session: */ | 716 | /* Link is down, accept any session */ |
| 699 | l_ptr->peer_session = 0; | 717 | l_ptr->peer_session = INVALID_SESSION; |
| 700 | 718 | ||
| 701 | /* Prepare for max packet size negotiation */ | 719 | /* Prepare for max packet size negotiation */ |
| 702 | link_init_max_pkt(l_ptr); | 720 | link_init_max_pkt(l_ptr); |
| @@ -1110,7 +1128,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
| 1110 | 1128 | ||
| 1111 | if (bundler) { | 1129 | if (bundler) { |
| 1112 | msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, | 1130 | msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, |
| 1113 | TIPC_OK, INT_H_SIZE, l_ptr->addr); | 1131 | INT_H_SIZE, l_ptr->addr); |
| 1114 | skb_copy_to_linear_data(bundler, &bundler_hdr, | 1132 | skb_copy_to_linear_data(bundler, &bundler_hdr, |
| 1115 | INT_H_SIZE); | 1133 | INT_H_SIZE); |
| 1116 | skb_trim(bundler, INT_H_SIZE); | 1134 | skb_trim(bundler, INT_H_SIZE); |
| @@ -1374,7 +1392,7 @@ again: | |||
| 1374 | 1392 | ||
| 1375 | msg_dbg(hdr, ">FRAGMENTING>"); | 1393 | msg_dbg(hdr, ">FRAGMENTING>"); |
| 1376 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 1394 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
| 1377 | TIPC_OK, INT_H_SIZE, msg_destnode(hdr)); | 1395 | INT_H_SIZE, msg_destnode(hdr)); |
| 1378 | msg_set_link_selector(&fragm_hdr, sender->publ.ref); | 1396 | msg_set_link_selector(&fragm_hdr, sender->publ.ref); |
| 1379 | msg_set_size(&fragm_hdr, max_pkt); | 1397 | msg_set_size(&fragm_hdr, max_pkt); |
| 1380 | msg_set_fragm_no(&fragm_hdr, 1); | 1398 | msg_set_fragm_no(&fragm_hdr, 1); |
| @@ -1543,7 +1561,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
| 1543 | l_ptr->retransm_queue_head = mod(++r_q_head); | 1561 | l_ptr->retransm_queue_head = mod(++r_q_head); |
| 1544 | l_ptr->retransm_queue_size = --r_q_size; | 1562 | l_ptr->retransm_queue_size = --r_q_size; |
| 1545 | l_ptr->stats.retransmitted++; | 1563 | l_ptr->stats.retransmitted++; |
| 1546 | return TIPC_OK; | 1564 | return 0; |
| 1547 | } else { | 1565 | } else { |
| 1548 | l_ptr->stats.bearer_congs++; | 1566 | l_ptr->stats.bearer_congs++; |
| 1549 | msg_dbg(buf_msg(buf), "|>DEF-RETR>"); | 1567 | msg_dbg(buf_msg(buf), "|>DEF-RETR>"); |
| @@ -1562,7 +1580,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
| 1562 | l_ptr->unacked_window = 0; | 1580 | l_ptr->unacked_window = 0; |
| 1563 | buf_discard(buf); | 1581 | buf_discard(buf); |
| 1564 | l_ptr->proto_msg_queue = NULL; | 1582 | l_ptr->proto_msg_queue = NULL; |
| 1565 | return TIPC_OK; | 1583 | return 0; |
| 1566 | } else { | 1584 | } else { |
| 1567 | msg_dbg(buf_msg(buf), "|>DEF-PROT>"); | 1585 | msg_dbg(buf_msg(buf), "|>DEF-PROT>"); |
| 1568 | l_ptr->stats.bearer_congs++; | 1586 | l_ptr->stats.bearer_congs++; |
| @@ -1586,7 +1604,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
| 1586 | msg_set_type(msg, CLOSED_MSG); | 1604 | msg_set_type(msg, CLOSED_MSG); |
| 1587 | msg_dbg(msg, ">PUSH-DATA>"); | 1605 | msg_dbg(msg, ">PUSH-DATA>"); |
| 1588 | l_ptr->next_out = buf->next; | 1606 | l_ptr->next_out = buf->next; |
| 1589 | return TIPC_OK; | 1607 | return 0; |
| 1590 | } else { | 1608 | } else { |
| 1591 | msg_dbg(msg, "|PUSH-DATA|"); | 1609 | msg_dbg(msg, "|PUSH-DATA|"); |
| 1592 | l_ptr->stats.bearer_congs++; | 1610 | l_ptr->stats.bearer_congs++; |
| @@ -1610,8 +1628,8 @@ void tipc_link_push_queue(struct link *l_ptr) | |||
| 1610 | 1628 | ||
| 1611 | do { | 1629 | do { |
| 1612 | res = tipc_link_push_packet(l_ptr); | 1630 | res = tipc_link_push_packet(l_ptr); |
| 1613 | } | 1631 | } while (!res); |
| 1614 | while (res == TIPC_OK); | 1632 | |
| 1615 | if (res == PUSH_FAILED) | 1633 | if (res == PUSH_FAILED) |
| 1616 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | 1634 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); |
| 1617 | } | 1635 | } |
| @@ -1651,7 +1669,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) | |||
| 1651 | struct tipc_msg *msg = buf_msg(buf); | 1669 | struct tipc_msg *msg = buf_msg(buf); |
| 1652 | 1670 | ||
| 1653 | warn("Retransmission failure on link <%s>\n", l_ptr->name); | 1671 | warn("Retransmission failure on link <%s>\n", l_ptr->name); |
| 1654 | tipc_msg_print(TIPC_OUTPUT, msg, ">RETR-FAIL>"); | 1672 | tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>"); |
| 1655 | 1673 | ||
| 1656 | if (l_ptr->addr) { | 1674 | if (l_ptr->addr) { |
| 1657 | 1675 | ||
| @@ -1748,21 +1766,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, | |||
| 1748 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; | 1766 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; |
| 1749 | } | 1767 | } |
| 1750 | 1768 | ||
| 1751 | /* | ||
| 1752 | * link_recv_non_seq: Receive packets which are outside | ||
| 1753 | * the link sequence flow | ||
| 1754 | */ | ||
| 1755 | |||
| 1756 | static void link_recv_non_seq(struct sk_buff *buf) | ||
| 1757 | { | ||
| 1758 | struct tipc_msg *msg = buf_msg(buf); | ||
| 1759 | |||
| 1760 | if (msg_user(msg) == LINK_CONFIG) | ||
| 1761 | tipc_disc_recv_msg(buf); | ||
| 1762 | else | ||
| 1763 | tipc_bclink_recv_pkt(buf); | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | /** | 1769 | /** |
| 1767 | * link_insert_deferred_queue - insert deferred messages back into receive chain | 1770 | * link_insert_deferred_queue - insert deferred messages back into receive chain |
| 1768 | */ | 1771 | */ |
| @@ -1839,7 +1842,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
| 1839 | { | 1842 | { |
| 1840 | read_lock_bh(&tipc_net_lock); | 1843 | read_lock_bh(&tipc_net_lock); |
| 1841 | while (head) { | 1844 | while (head) { |
| 1842 | struct bearer *b_ptr; | 1845 | struct bearer *b_ptr = (struct bearer *)tb_ptr; |
| 1843 | struct node *n_ptr; | 1846 | struct node *n_ptr; |
| 1844 | struct link *l_ptr; | 1847 | struct link *l_ptr; |
| 1845 | struct sk_buff *crs; | 1848 | struct sk_buff *crs; |
| @@ -1850,9 +1853,6 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
| 1850 | u32 released = 0; | 1853 | u32 released = 0; |
| 1851 | int type; | 1854 | int type; |
| 1852 | 1855 | ||
| 1853 | b_ptr = (struct bearer *)tb_ptr; | ||
| 1854 | TIPC_SKB_CB(buf)->handle = b_ptr; | ||
| 1855 | |||
| 1856 | head = head->next; | 1856 | head = head->next; |
| 1857 | 1857 | ||
| 1858 | /* Ensure message is well-formed */ | 1858 | /* Ensure message is well-formed */ |
| @@ -1871,7 +1871,10 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
| 1871 | msg = buf_msg(buf); | 1871 | msg = buf_msg(buf); |
| 1872 | 1872 | ||
| 1873 | if (unlikely(msg_non_seq(msg))) { | 1873 | if (unlikely(msg_non_seq(msg))) { |
| 1874 | link_recv_non_seq(buf); | 1874 | if (msg_user(msg) == LINK_CONFIG) |
| 1875 | tipc_disc_recv_msg(buf, b_ptr); | ||
| 1876 | else | ||
| 1877 | tipc_bclink_recv_pkt(buf); | ||
| 1875 | continue; | 1878 | continue; |
| 1876 | } | 1879 | } |
| 1877 | 1880 | ||
| @@ -1978,8 +1981,6 @@ deliver: | |||
| 1978 | if (link_recv_changeover_msg(&l_ptr, &buf)) { | 1981 | if (link_recv_changeover_msg(&l_ptr, &buf)) { |
| 1979 | msg = buf_msg(buf); | 1982 | msg = buf_msg(buf); |
| 1980 | seq_no = msg_seqno(msg); | 1983 | seq_no = msg_seqno(msg); |
| 1981 | TIPC_SKB_CB(buf)->handle | ||
| 1982 | = b_ptr; | ||
| 1983 | if (type == ORIGINAL_MSG) | 1984 | if (type == ORIGINAL_MSG) |
| 1984 | goto deliver; | 1985 | goto deliver; |
| 1985 | goto protocol_check; | 1986 | goto protocol_check; |
| @@ -2263,7 +2264,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
| 2263 | switch (msg_type(msg)) { | 2264 | switch (msg_type(msg)) { |
| 2264 | 2265 | ||
| 2265 | case RESET_MSG: | 2266 | case RESET_MSG: |
| 2266 | if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { | 2267 | if (!link_working_unknown(l_ptr) && |
| 2268 | (l_ptr->peer_session != INVALID_SESSION)) { | ||
| 2267 | if (msg_session(msg) == l_ptr->peer_session) { | 2269 | if (msg_session(msg) == l_ptr->peer_session) { |
| 2268 | dbg("Duplicate RESET: %u<->%u\n", | 2270 | dbg("Duplicate RESET: %u<->%u\n", |
| 2269 | msg_session(msg), l_ptr->peer_session); | 2271 | msg_session(msg), l_ptr->peer_session); |
| @@ -2424,7 +2426,7 @@ void tipc_link_changeover(struct link *l_ptr) | |||
| 2424 | } | 2426 | } |
| 2425 | 2427 | ||
| 2426 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, | 2428 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, |
| 2427 | ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 2429 | ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); |
| 2428 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2430 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
| 2429 | msg_set_msgcnt(&tunnel_hdr, msgcount); | 2431 | msg_set_msgcnt(&tunnel_hdr, msgcount); |
| 2430 | dbg("Link changeover requires %u tunnel messages\n", msgcount); | 2432 | dbg("Link changeover requires %u tunnel messages\n", msgcount); |
| @@ -2479,7 +2481,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) | |||
| 2479 | struct tipc_msg tunnel_hdr; | 2481 | struct tipc_msg tunnel_hdr; |
| 2480 | 2482 | ||
| 2481 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, | 2483 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, |
| 2482 | DUPLICATE_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 2484 | DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr); |
| 2483 | msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); | 2485 | msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); |
| 2484 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2486 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
| 2485 | iter = l_ptr->first_out; | 2487 | iter = l_ptr->first_out; |
| @@ -2672,10 +2674,12 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
| 2672 | u32 pack_sz = link_max_pkt(l_ptr); | 2674 | u32 pack_sz = link_max_pkt(l_ptr); |
| 2673 | u32 fragm_sz = pack_sz - INT_H_SIZE; | 2675 | u32 fragm_sz = pack_sz - INT_H_SIZE; |
| 2674 | u32 fragm_no = 1; | 2676 | u32 fragm_no = 1; |
| 2675 | u32 destaddr = msg_destnode(inmsg); | 2677 | u32 destaddr; |
| 2676 | 2678 | ||
| 2677 | if (msg_short(inmsg)) | 2679 | if (msg_short(inmsg)) |
| 2678 | destaddr = l_ptr->addr; | 2680 | destaddr = l_ptr->addr; |
| 2681 | else | ||
| 2682 | destaddr = msg_destnode(inmsg); | ||
| 2679 | 2683 | ||
| 2680 | if (msg_routed(inmsg)) | 2684 | if (msg_routed(inmsg)) |
| 2681 | msg_set_prevnode(inmsg, tipc_own_addr); | 2685 | msg_set_prevnode(inmsg, tipc_own_addr); |
| @@ -2683,7 +2687,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
| 2683 | /* Prepare reusable fragment header: */ | 2687 | /* Prepare reusable fragment header: */ |
| 2684 | 2688 | ||
| 2685 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2689 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
| 2686 | TIPC_OK, INT_H_SIZE, destaddr); | 2690 | INT_H_SIZE, destaddr); |
| 2687 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); | 2691 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); |
| 2688 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); | 2692 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); |
| 2689 | msg_set_fragm_no(&fragm_hdr, fragm_no); | 2693 | msg_set_fragm_no(&fragm_hdr, fragm_no); |
| @@ -2994,7 +2998,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space | |||
| 2994 | link_set_supervision_props(l_ptr, new_value); | 2998 | link_set_supervision_props(l_ptr, new_value); |
| 2995 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 2999 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
| 2996 | 0, 0, new_value, 0, 0); | 3000 | 0, 0, new_value, 0, 0); |
| 2997 | res = TIPC_OK; | 3001 | res = 0; |
| 2998 | } | 3002 | } |
| 2999 | break; | 3003 | break; |
| 3000 | case TIPC_CMD_SET_LINK_PRI: | 3004 | case TIPC_CMD_SET_LINK_PRI: |
| @@ -3003,14 +3007,14 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space | |||
| 3003 | l_ptr->priority = new_value; | 3007 | l_ptr->priority = new_value; |
| 3004 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 3008 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
| 3005 | 0, 0, 0, new_value, 0); | 3009 | 0, 0, 0, new_value, 0); |
| 3006 | res = TIPC_OK; | 3010 | res = 0; |
| 3007 | } | 3011 | } |
| 3008 | break; | 3012 | break; |
| 3009 | case TIPC_CMD_SET_LINK_WINDOW: | 3013 | case TIPC_CMD_SET_LINK_WINDOW: |
| 3010 | if ((new_value >= TIPC_MIN_LINK_WIN) && | 3014 | if ((new_value >= TIPC_MIN_LINK_WIN) && |
| 3011 | (new_value <= TIPC_MAX_LINK_WIN)) { | 3015 | (new_value <= TIPC_MAX_LINK_WIN)) { |
| 3012 | tipc_link_set_queue_limits(l_ptr, new_value); | 3016 | tipc_link_set_queue_limits(l_ptr, new_value); |
| 3013 | res = TIPC_OK; | 3017 | res = 0; |
| 3014 | } | 3018 | } |
| 3015 | break; | 3019 | break; |
| 3016 | } | 3020 | } |
| @@ -3226,7 +3230,7 @@ int link_control(const char *name, u32 op, u32 val) | |||
| 3226 | if (op == TIPC_CMD_UNBLOCK_LINK) { | 3230 | if (op == TIPC_CMD_UNBLOCK_LINK) { |
| 3227 | l_ptr->blocked = 0; | 3231 | l_ptr->blocked = 0; |
| 3228 | } | 3232 | } |
| 3229 | res = TIPC_OK; | 3233 | res = 0; |
| 3230 | } | 3234 | } |
| 3231 | tipc_node_unlock(node); | 3235 | tipc_node_unlock(node); |
| 3232 | } | 3236 | } |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 696a8633df75..73dcd00d674e 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
| @@ -41,7 +41,9 @@ | |||
| 41 | #include "bearer.h" | 41 | #include "bearer.h" |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str) | 44 | #ifdef CONFIG_TIPC_DEBUG |
| 45 | |||
| 46 | void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | ||
| 45 | { | 47 | { |
| 46 | u32 usr = msg_user(msg); | 48 | u32 usr = msg_user(msg); |
| 47 | tipc_printf(buf, str); | 49 | tipc_printf(buf, str); |
| @@ -228,13 +230,10 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str | |||
| 228 | 230 | ||
| 229 | switch (usr) { | 231 | switch (usr) { |
| 230 | case CONN_MANAGER: | 232 | case CONN_MANAGER: |
| 231 | case NAME_DISTRIBUTOR: | ||
| 232 | case TIPC_LOW_IMPORTANCE: | 233 | case TIPC_LOW_IMPORTANCE: |
| 233 | case TIPC_MEDIUM_IMPORTANCE: | 234 | case TIPC_MEDIUM_IMPORTANCE: |
| 234 | case TIPC_HIGH_IMPORTANCE: | 235 | case TIPC_HIGH_IMPORTANCE: |
| 235 | case TIPC_CRITICAL_IMPORTANCE: | 236 | case TIPC_CRITICAL_IMPORTANCE: |
| 236 | if (msg_short(msg)) | ||
| 237 | break; /* No error */ | ||
| 238 | switch (msg_errcode(msg)) { | 237 | switch (msg_errcode(msg)) { |
| 239 | case TIPC_OK: | 238 | case TIPC_OK: |
| 240 | break; | 239 | break; |
| @@ -315,9 +314,11 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str | |||
| 315 | } | 314 | } |
| 316 | tipc_printf(buf, "\n"); | 315 | tipc_printf(buf, "\n"); |
| 317 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { | 316 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { |
| 318 | tipc_msg_print(buf,msg_get_wrapped(msg)," /"); | 317 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
| 319 | } | 318 | } |
| 320 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { | 319 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { |
| 321 | tipc_msg_print(buf,msg_get_wrapped(msg)," /"); | 320 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
| 322 | } | 321 | } |
| 323 | } | 322 | } |
| 323 | |||
| 324 | #endif | ||
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index ad487e8abcc2..7ee6ae238147 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/msg.h: Include file for TIPC message header routines | 2 | * net/tipc/msg.h: Include file for TIPC message header routines |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2000-2007, Ericsson AB | 4 | * Copyright (c) 2000-2007, Ericsson AB |
| 5 | * Copyright (c) 2005-2007, Wind River Systems | 5 | * Copyright (c) 2005-2008, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
| @@ -75,6 +75,14 @@ static inline void msg_set_bits(struct tipc_msg *m, u32 w, | |||
| 75 | m->hdr[w] |= htonl(val); | 75 | m->hdr[w] |= htonl(val); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b) | ||
| 79 | { | ||
| 80 | u32 temp = msg->hdr[a]; | ||
| 81 | |||
| 82 | msg->hdr[a] = msg->hdr[b]; | ||
| 83 | msg->hdr[b] = temp; | ||
| 84 | } | ||
| 85 | |||
| 78 | /* | 86 | /* |
| 79 | * Word 0 | 87 | * Word 0 |
| 80 | */ | 88 | */ |
| @@ -119,9 +127,9 @@ static inline int msg_non_seq(struct tipc_msg *m) | |||
| 119 | return msg_bits(m, 0, 20, 1); | 127 | return msg_bits(m, 0, 20, 1); |
| 120 | } | 128 | } |
| 121 | 129 | ||
| 122 | static inline void msg_set_non_seq(struct tipc_msg *m) | 130 | static inline void msg_set_non_seq(struct tipc_msg *m, u32 n) |
| 123 | { | 131 | { |
| 124 | msg_set_bits(m, 0, 20, 1, 1); | 132 | msg_set_bits(m, 0, 20, 1, n); |
| 125 | } | 133 | } |
| 126 | 134 | ||
| 127 | static inline int msg_dest_droppable(struct tipc_msg *m) | 135 | static inline int msg_dest_droppable(struct tipc_msg *m) |
| @@ -224,6 +232,25 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n) | |||
| 224 | msg_set_bits(m, 2, 0, 0xffff, n); | 232 | msg_set_bits(m, 2, 0, 0xffff, n); |
| 225 | } | 233 | } |
| 226 | 234 | ||
| 235 | /* | ||
| 236 | * TIPC may utilize the "link ack #" and "link seq #" fields of a short | ||
| 237 | * message header to hold the destination node for the message, since the | ||
| 238 | * normal "dest node" field isn't present. This cache is only referenced | ||
| 239 | * when required, so populating the cache of a longer message header is | ||
| 240 | * harmless (as long as the header has the two link sequence fields present). | ||
| 241 | * | ||
| 242 | * Note: Host byte order is OK here, since the info never goes off-card. | ||
| 243 | */ | ||
| 244 | |||
| 245 | static inline u32 msg_destnode_cache(struct tipc_msg *m) | ||
| 246 | { | ||
| 247 | return m->hdr[2]; | ||
| 248 | } | ||
| 249 | |||
| 250 | static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode) | ||
| 251 | { | ||
| 252 | m->hdr[2] = dnode; | ||
| 253 | } | ||
| 227 | 254 | ||
| 228 | /* | 255 | /* |
| 229 | * Words 3-10 | 256 | * Words 3-10 |
| @@ -325,7 +352,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
| 325 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 352 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 326 | w0:|vers |msg usr|hdr sz |n|resrv| packet size | | 353 | w0:|vers |msg usr|hdr sz |n|resrv| packet size | |
| 327 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 354 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 328 | w1:|m typ|rsv=0| sequence gap | broadcast ack no | | 355 | w1:|m typ| sequence gap | broadcast ack no | |
| 329 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 356 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 330 | w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | | 357 | w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | |
| 331 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 358 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| @@ -388,12 +415,12 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
| 388 | 415 | ||
| 389 | static inline u32 msg_seq_gap(struct tipc_msg *m) | 416 | static inline u32 msg_seq_gap(struct tipc_msg *m) |
| 390 | { | 417 | { |
| 391 | return msg_bits(m, 1, 16, 0xff); | 418 | return msg_bits(m, 1, 16, 0x1fff); |
| 392 | } | 419 | } |
| 393 | 420 | ||
| 394 | static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) | 421 | static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) |
| 395 | { | 422 | { |
| 396 | msg_set_bits(m, 1, 16, 0xff, n); | 423 | msg_set_bits(m, 1, 16, 0x1fff, n); |
| 397 | } | 424 | } |
| 398 | 425 | ||
| 399 | static inline u32 msg_req_links(struct tipc_msg *m) | 426 | static inline u32 msg_req_links(struct tipc_msg *m) |
| @@ -696,7 +723,7 @@ static inline u32 msg_tot_importance(struct tipc_msg *m) | |||
| 696 | 723 | ||
| 697 | 724 | ||
| 698 | static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, | 725 | static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, |
| 699 | u32 err, u32 hsize, u32 destnode) | 726 | u32 hsize, u32 destnode) |
| 700 | { | 727 | { |
| 701 | memset(m, 0, hsize); | 728 | memset(m, 0, hsize); |
| 702 | msg_set_version(m); | 729 | msg_set_version(m); |
| @@ -705,7 +732,6 @@ static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, | |||
| 705 | msg_set_size(m, hsize); | 732 | msg_set_size(m, hsize); |
| 706 | msg_set_prevnode(m, tipc_own_addr); | 733 | msg_set_prevnode(m, tipc_own_addr); |
| 707 | msg_set_type(m, type); | 734 | msg_set_type(m, type); |
| 708 | msg_set_errcode(m, err); | ||
| 709 | if (!msg_short(m)) { | 735 | if (!msg_short(m)) { |
| 710 | msg_set_orignode(m, tipc_own_addr); | 736 | msg_set_orignode(m, tipc_own_addr); |
| 711 | msg_set_destnode(m, destnode); | 737 | msg_set_destnode(m, destnode); |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 39fd1619febf..10a69894e2fd 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
| @@ -41,9 +41,6 @@ | |||
| 41 | #include "msg.h" | 41 | #include "msg.h" |
| 42 | #include "name_distr.h" | 42 | #include "name_distr.h" |
| 43 | 43 | ||
| 44 | #undef DBG_OUTPUT | ||
| 45 | #define DBG_OUTPUT NULL | ||
| 46 | |||
| 47 | #define ITEM_SIZE sizeof(struct distr_item) | 44 | #define ITEM_SIZE sizeof(struct distr_item) |
| 48 | 45 | ||
| 49 | /** | 46 | /** |
| @@ -106,8 +103,7 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) | |||
| 106 | 103 | ||
| 107 | if (buf != NULL) { | 104 | if (buf != NULL) { |
| 108 | msg = buf_msg(buf); | 105 | msg = buf_msg(buf); |
| 109 | msg_init(msg, NAME_DISTRIBUTOR, type, TIPC_OK, | 106 | msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest); |
| 110 | LONG_H_SIZE, dest); | ||
| 111 | msg_set_size(msg, LONG_H_SIZE + size); | 107 | msg_set_size(msg, LONG_H_SIZE + size); |
| 112 | } | 108 | } |
| 113 | return buf; | 109 | return buf; |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index ac7dfdda7973..cd72e22b132b 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-2005, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
| @@ -52,9 +52,16 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | |||
| 52 | * struct sub_seq - container for all published instances of a name sequence | 52 | * struct sub_seq - container for all published instances of a name sequence |
| 53 | * @lower: name sequence lower bound | 53 | * @lower: name sequence lower bound |
| 54 | * @upper: name sequence upper bound | 54 | * @upper: name sequence upper bound |
| 55 | * @node_list: circular list of matching publications with >= node scope | 55 | * @node_list: circular list of publications made by own node |
| 56 | * @cluster_list: circular list of matching publications with >= cluster scope | 56 | * @cluster_list: circular list of publications made by own cluster |
| 57 | * @zone_list: circular list of matching publications with >= zone scope | 57 | * @zone_list: circular list of publications made by own zone |
| 58 | * @node_list_size: number of entries in "node_list" | ||
| 59 | * @cluster_list_size: number of entries in "cluster_list" | ||
| 60 | * @zone_list_size: number of entries in "zone_list" | ||
| 61 | * | ||
| 62 | * Note: The zone list always contains at least one entry, since all | ||
| 63 | * publications of the associated name sequence belong to it. | ||
| 64 | * (The cluster and node lists may be empty.) | ||
| 58 | */ | 65 | */ |
| 59 | 66 | ||
| 60 | struct sub_seq { | 67 | struct sub_seq { |
| @@ -63,6 +70,9 @@ struct sub_seq { | |||
| 63 | struct publication *node_list; | 70 | struct publication *node_list; |
| 64 | struct publication *cluster_list; | 71 | struct publication *cluster_list; |
| 65 | struct publication *zone_list; | 72 | struct publication *zone_list; |
| 73 | u32 node_list_size; | ||
| 74 | u32 cluster_list_size; | ||
| 75 | u32 zone_list_size; | ||
| 66 | }; | 76 | }; |
| 67 | 77 | ||
| 68 | /** | 78 | /** |
| @@ -74,7 +84,7 @@ struct sub_seq { | |||
| 74 | * @first_free: array index of first unused sub-sequence entry | 84 | * @first_free: array index of first unused sub-sequence entry |
| 75 | * @ns_list: links to adjacent name sequences in hash chain | 85 | * @ns_list: links to adjacent name sequences in hash chain |
| 76 | * @subscriptions: list of subscriptions for this 'type' | 86 | * @subscriptions: list of subscriptions for this 'type' |
| 77 | * @lock: spinlock controlling access to name sequence structure | 87 | * @lock: spinlock controlling access to publication lists of all sub-sequences |
| 78 | */ | 88 | */ |
| 79 | 89 | ||
| 80 | struct name_seq { | 90 | struct name_seq { |
| @@ -317,6 +327,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
| 317 | dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", | 327 | dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", |
| 318 | publ, node, publ->node, publ->subscr.node); | 328 | publ, node, publ->node, publ->subscr.node); |
| 319 | 329 | ||
| 330 | sseq->zone_list_size++; | ||
| 320 | if (!sseq->zone_list) | 331 | if (!sseq->zone_list) |
| 321 | sseq->zone_list = publ->zone_list_next = publ; | 332 | sseq->zone_list = publ->zone_list_next = publ; |
| 322 | else { | 333 | else { |
| @@ -325,6 +336,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
| 325 | } | 336 | } |
| 326 | 337 | ||
| 327 | if (in_own_cluster(node)) { | 338 | if (in_own_cluster(node)) { |
| 339 | sseq->cluster_list_size++; | ||
| 328 | if (!sseq->cluster_list) | 340 | if (!sseq->cluster_list) |
| 329 | sseq->cluster_list = publ->cluster_list_next = publ; | 341 | sseq->cluster_list = publ->cluster_list_next = publ; |
| 330 | else { | 342 | else { |
| @@ -335,6 +347,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
| 335 | } | 347 | } |
| 336 | 348 | ||
| 337 | if (node == tipc_own_addr) { | 349 | if (node == tipc_own_addr) { |
| 350 | sseq->node_list_size++; | ||
| 338 | if (!sseq->node_list) | 351 | if (!sseq->node_list) |
| 339 | sseq->node_list = publ->node_list_next = publ; | 352 | sseq->node_list = publ->node_list_next = publ; |
| 340 | else { | 353 | else { |
| @@ -411,6 +424,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
| 411 | } else { | 424 | } else { |
| 412 | sseq->zone_list = NULL; | 425 | sseq->zone_list = NULL; |
| 413 | } | 426 | } |
| 427 | sseq->zone_list_size--; | ||
| 414 | 428 | ||
| 415 | /* Remove publication from cluster scope list, if present */ | 429 | /* Remove publication from cluster scope list, if present */ |
| 416 | 430 | ||
| @@ -439,6 +453,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
| 439 | } else { | 453 | } else { |
| 440 | sseq->cluster_list = NULL; | 454 | sseq->cluster_list = NULL; |
| 441 | } | 455 | } |
| 456 | sseq->cluster_list_size--; | ||
| 442 | } | 457 | } |
| 443 | end_cluster: | 458 | end_cluster: |
| 444 | 459 | ||
| @@ -469,6 +484,7 @@ end_cluster: | |||
| 469 | } else { | 484 | } else { |
| 470 | sseq->node_list = NULL; | 485 | sseq->node_list = NULL; |
| 471 | } | 486 | } |
| 487 | sseq->node_list_size--; | ||
| 472 | } | 488 | } |
| 473 | end_node: | 489 | end_node: |
| 474 | 490 | ||
| @@ -709,15 +725,18 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
| 709 | 725 | ||
| 710 | if (sseq->lower > upper) | 726 | if (sseq->lower > upper) |
| 711 | break; | 727 | break; |
| 712 | publ = sseq->cluster_list; | 728 | |
| 713 | if (publ && (publ->scope <= limit)) | 729 | publ = sseq->node_list; |
| 730 | if (publ) { | ||
| 714 | do { | 731 | do { |
| 715 | if (publ->node == tipc_own_addr) | 732 | if (publ->scope <= limit) |
| 716 | tipc_port_list_add(dports, publ->ref); | 733 | tipc_port_list_add(dports, publ->ref); |
| 717 | else | 734 | publ = publ->node_list_next; |
| 718 | res = 1; | 735 | } while (publ != sseq->node_list); |
| 719 | publ = publ->cluster_list_next; | 736 | } |
| 720 | } while (publ != sseq->cluster_list); | 737 | |
| 738 | if (sseq->cluster_list_size != sseq->node_list_size) | ||
| 739 | res = 1; | ||
| 721 | } | 740 | } |
| 722 | 741 | ||
| 723 | spin_unlock_bh(&seq->lock); | 742 | spin_unlock_bh(&seq->lock); |
| @@ -905,6 +924,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | |||
| 905 | struct sub_seq *sseq; | 924 | struct sub_seq *sseq; |
| 906 | char typearea[11]; | 925 | char typearea[11]; |
| 907 | 926 | ||
| 927 | if (seq->first_free == 0) | ||
| 928 | return; | ||
| 929 | |||
| 908 | sprintf(typearea, "%-10u", seq->type); | 930 | sprintf(typearea, "%-10u", seq->type); |
| 909 | 931 | ||
| 910 | if (depth == 1) { | 932 | if (depth == 1) { |
| @@ -915,7 +937,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | |||
| 915 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { | 937 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { |
| 916 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { | 938 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { |
| 917 | tipc_printf(buf, "%s ", typearea); | 939 | tipc_printf(buf, "%s ", typearea); |
| 940 | spin_lock_bh(&seq->lock); | ||
| 918 | subseq_list(sseq, buf, depth, index); | 941 | subseq_list(sseq, buf, depth, index); |
| 942 | spin_unlock_bh(&seq->lock); | ||
| 919 | sprintf(typearea, "%10s", " "); | 943 | sprintf(typearea, "%10s", " "); |
| 920 | } | 944 | } |
| 921 | } | 945 | } |
| @@ -1050,15 +1074,12 @@ void tipc_nametbl_dump(void) | |||
| 1050 | 1074 | ||
| 1051 | int tipc_nametbl_init(void) | 1075 | int tipc_nametbl_init(void) |
| 1052 | { | 1076 | { |
| 1053 | int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; | 1077 | table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), |
| 1054 | 1078 | GFP_ATOMIC); | |
| 1055 | table.types = kzalloc(array_size, GFP_ATOMIC); | ||
| 1056 | if (!table.types) | 1079 | if (!table.types) |
| 1057 | return -ENOMEM; | 1080 | return -ENOMEM; |
| 1058 | 1081 | ||
| 1059 | write_lock_bh(&tipc_nametbl_lock); | ||
| 1060 | table.local_publ_count = 0; | 1082 | table.local_publ_count = 0; |
| 1061 | write_unlock_bh(&tipc_nametbl_lock); | ||
| 1062 | return 0; | 1083 | return 0; |
| 1063 | } | 1084 | } |
| 1064 | 1085 | ||
diff --git a/net/tipc/net.c b/net/tipc/net.c index c39c76201e8e..ec7b04fbdc43 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
| @@ -165,7 +165,7 @@ static int net_init(void) | |||
| 165 | if (!tipc_net.zones) { | 165 | if (!tipc_net.zones) { |
| 166 | return -ENOMEM; | 166 | return -ENOMEM; |
| 167 | } | 167 | } |
| 168 | return TIPC_OK; | 168 | return 0; |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static void net_stop(void) | 171 | static void net_stop(void) |
| @@ -266,7 +266,7 @@ void tipc_net_route_msg(struct sk_buff *buf) | |||
| 266 | tipc_link_send(buf, dnode, msg_link_selector(msg)); | 266 | tipc_link_send(buf, dnode, msg_link_selector(msg)); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | int tipc_net_start(void) | 269 | int tipc_net_start(u32 addr) |
| 270 | { | 270 | { |
| 271 | char addr_string[16]; | 271 | char addr_string[16]; |
| 272 | int res; | 272 | int res; |
| @@ -274,6 +274,10 @@ int tipc_net_start(void) | |||
| 274 | if (tipc_mode != TIPC_NODE_MODE) | 274 | if (tipc_mode != TIPC_NODE_MODE) |
| 275 | return -ENOPROTOOPT; | 275 | return -ENOPROTOOPT; |
| 276 | 276 | ||
| 277 | tipc_subscr_stop(); | ||
| 278 | tipc_cfg_stop(); | ||
| 279 | |||
| 280 | tipc_own_addr = addr; | ||
| 277 | tipc_mode = TIPC_NET_MODE; | 281 | tipc_mode = TIPC_NET_MODE; |
| 278 | tipc_named_reinit(); | 282 | tipc_named_reinit(); |
| 279 | tipc_port_reinit(); | 283 | tipc_port_reinit(); |
| @@ -284,14 +288,14 @@ int tipc_net_start(void) | |||
| 284 | (res = tipc_bclink_init())) { | 288 | (res = tipc_bclink_init())) { |
| 285 | return res; | 289 | return res; |
| 286 | } | 290 | } |
| 287 | tipc_subscr_stop(); | 291 | |
| 288 | tipc_cfg_stop(); | ||
| 289 | tipc_k_signal((Handler)tipc_subscr_start, 0); | 292 | tipc_k_signal((Handler)tipc_subscr_start, 0); |
| 290 | tipc_k_signal((Handler)tipc_cfg_init, 0); | 293 | tipc_k_signal((Handler)tipc_cfg_init, 0); |
| 294 | |||
| 291 | info("Started in network mode\n"); | 295 | info("Started in network mode\n"); |
| 292 | info("Own node address %s, network identity %u\n", | 296 | info("Own node address %s, network identity %u\n", |
| 293 | addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); | 297 | addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); |
| 294 | return TIPC_OK; | 298 | return 0; |
| 295 | } | 299 | } |
| 296 | 300 | ||
| 297 | void tipc_net_stop(void) | 301 | void tipc_net_stop(void) |
diff --git a/net/tipc/net.h b/net/tipc/net.h index a6a0e9976ac9..d154ac2bda9a 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
| @@ -58,7 +58,7 @@ void tipc_net_route_msg(struct sk_buff *buf); | |||
| 58 | struct node *tipc_net_select_remote_node(u32 addr, u32 ref); | 58 | struct node *tipc_net_select_remote_node(u32 addr, u32 ref); |
| 59 | u32 tipc_net_select_router(u32 addr, u32 ref); | 59 | u32 tipc_net_select_router(u32 addr, u32 ref); |
| 60 | 60 | ||
| 61 | int tipc_net_start(void); | 61 | int tipc_net_start(u32 addr); |
| 62 | void tipc_net_stop(void); | 62 | void tipc_net_stop(void); |
| 63 | 63 | ||
| 64 | #endif | 64 | #endif |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 6a7f7b4c2595..c387217bb230 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/netlink.c: TIPC configuration handling | 2 | * net/tipc/netlink.c: TIPC configuration handling |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, Ericsson AB |
| 5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -45,15 +45,17 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
| 45 | struct nlmsghdr *req_nlh = info->nlhdr; | 45 | struct nlmsghdr *req_nlh = info->nlhdr; |
| 46 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; | 46 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; |
| 47 | int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); | 47 | int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); |
| 48 | u16 cmd; | ||
| 48 | 49 | ||
| 49 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) | 50 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) |
| 50 | rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); | 51 | cmd = TIPC_CMD_NOT_NET_ADMIN; |
| 51 | else | 52 | else |
| 52 | rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, | 53 | cmd = req_userhdr->cmd; |
| 53 | req_userhdr->cmd, | 54 | |
| 54 | NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, | 55 | rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd, |
| 55 | NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), | 56 | NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, |
| 56 | hdr_space); | 57 | NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), |
| 58 | hdr_space); | ||
| 57 | 59 | ||
| 58 | if (rep_buf) { | 60 | if (rep_buf) { |
| 59 | skb_push(rep_buf, hdr_space); | 61 | skb_push(rep_buf, hdr_space); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 598f4d3a0098..ee952ad60218 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -52,16 +52,40 @@ static void node_established_contact(struct node *n_ptr); | |||
| 52 | 52 | ||
| 53 | struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ | 53 | struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ |
| 54 | 54 | ||
| 55 | static DEFINE_SPINLOCK(node_create_lock); | ||
| 56 | |||
| 55 | u32 tipc_own_tag = 0; | 57 | u32 tipc_own_tag = 0; |
| 56 | 58 | ||
| 59 | /** | ||
| 60 | * tipc_node_create - create neighboring node | ||
| 61 | * | ||
| 62 | * Currently, this routine is called by neighbor discovery code, which holds | ||
| 63 | * net_lock for reading only. We must take node_create_lock to ensure a node | ||
| 64 | * isn't created twice if two different bearers discover the node at the same | ||
| 65 | * time. (It would be preferable to switch to holding net_lock in write mode, | ||
| 66 | * but this is a non-trivial change.) | ||
| 67 | */ | ||
| 68 | |||
| 57 | struct node *tipc_node_create(u32 addr) | 69 | struct node *tipc_node_create(u32 addr) |
| 58 | { | 70 | { |
| 59 | struct cluster *c_ptr; | 71 | struct cluster *c_ptr; |
| 60 | struct node *n_ptr; | 72 | struct node *n_ptr; |
| 61 | struct node **curr_node; | 73 | struct node **curr_node; |
| 62 | 74 | ||
| 75 | spin_lock_bh(&node_create_lock); | ||
| 76 | |||
| 77 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { | ||
| 78 | if (addr < n_ptr->addr) | ||
| 79 | break; | ||
| 80 | if (addr == n_ptr->addr) { | ||
| 81 | spin_unlock_bh(&node_create_lock); | ||
| 82 | return n_ptr; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 63 | n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); | 86 | n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); |
| 64 | if (!n_ptr) { | 87 | if (!n_ptr) { |
| 88 | spin_unlock_bh(&node_create_lock); | ||
| 65 | warn("Node creation failed, no memory\n"); | 89 | warn("Node creation failed, no memory\n"); |
| 66 | return NULL; | 90 | return NULL; |
| 67 | } | 91 | } |
| @@ -71,6 +95,7 @@ struct node *tipc_node_create(u32 addr) | |||
| 71 | c_ptr = tipc_cltr_create(addr); | 95 | c_ptr = tipc_cltr_create(addr); |
| 72 | } | 96 | } |
| 73 | if (!c_ptr) { | 97 | if (!c_ptr) { |
| 98 | spin_unlock_bh(&node_create_lock); | ||
| 74 | kfree(n_ptr); | 99 | kfree(n_ptr); |
| 75 | return NULL; | 100 | return NULL; |
| 76 | } | 101 | } |
| @@ -91,6 +116,7 @@ struct node *tipc_node_create(u32 addr) | |||
| 91 | } | 116 | } |
| 92 | } | 117 | } |
| 93 | (*curr_node) = n_ptr; | 118 | (*curr_node) = n_ptr; |
| 119 | spin_unlock_bh(&node_create_lock); | ||
| 94 | return n_ptr; | 120 | return n_ptr; |
| 95 | } | 121 | } |
| 96 | 122 | ||
| @@ -574,12 +600,14 @@ u32 tipc_available_nodes(const u32 domain) | |||
| 574 | struct node *n_ptr; | 600 | struct node *n_ptr; |
| 575 | u32 cnt = 0; | 601 | u32 cnt = 0; |
| 576 | 602 | ||
| 603 | read_lock_bh(&tipc_net_lock); | ||
| 577 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { | 604 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { |
| 578 | if (!in_scope(domain, n_ptr->addr)) | 605 | if (!in_scope(domain, n_ptr->addr)) |
| 579 | continue; | 606 | continue; |
| 580 | if (tipc_node_is_up(n_ptr)) | 607 | if (tipc_node_is_up(n_ptr)) |
| 581 | cnt++; | 608 | cnt++; |
| 582 | } | 609 | } |
| 610 | read_unlock_bh(&tipc_net_lock); | ||
| 583 | return cnt; | 611 | return cnt; |
| 584 | } | 612 | } |
| 585 | 613 | ||
| @@ -599,19 +627,26 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
| 599 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 627 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
| 600 | " (network address)"); | 628 | " (network address)"); |
| 601 | 629 | ||
| 602 | if (!tipc_nodes) | 630 | read_lock_bh(&tipc_net_lock); |
| 631 | if (!tipc_nodes) { | ||
| 632 | read_unlock_bh(&tipc_net_lock); | ||
| 603 | return tipc_cfg_reply_none(); | 633 | return tipc_cfg_reply_none(); |
| 634 | } | ||
| 604 | 635 | ||
| 605 | /* For now, get space for all other nodes | 636 | /* For now, get space for all other nodes |
| 606 | (will need to modify this when slave nodes are supported */ | 637 | (will need to modify this when slave nodes are supported */ |
| 607 | 638 | ||
| 608 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); | 639 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); |
| 609 | if (payload_size > 32768u) | 640 | if (payload_size > 32768u) { |
| 641 | read_unlock_bh(&tipc_net_lock); | ||
| 610 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 642 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
| 611 | " (too many nodes)"); | 643 | " (too many nodes)"); |
| 644 | } | ||
| 612 | buf = tipc_cfg_reply_alloc(payload_size); | 645 | buf = tipc_cfg_reply_alloc(payload_size); |
| 613 | if (!buf) | 646 | if (!buf) { |
| 647 | read_unlock_bh(&tipc_net_lock); | ||
| 614 | return NULL; | 648 | return NULL; |
| 649 | } | ||
| 615 | 650 | ||
| 616 | /* Add TLVs for all nodes in scope */ | 651 | /* Add TLVs for all nodes in scope */ |
| 617 | 652 | ||
| @@ -624,6 +659,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
| 624 | &node_info, sizeof(node_info)); | 659 | &node_info, sizeof(node_info)); |
| 625 | } | 660 | } |
| 626 | 661 | ||
| 662 | read_unlock_bh(&tipc_net_lock); | ||
| 627 | return buf; | 663 | return buf; |
| 628 | } | 664 | } |
| 629 | 665 | ||
| @@ -646,16 +682,22 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
| 646 | if (tipc_mode != TIPC_NET_MODE) | 682 | if (tipc_mode != TIPC_NET_MODE) |
| 647 | return tipc_cfg_reply_none(); | 683 | return tipc_cfg_reply_none(); |
| 648 | 684 | ||
| 685 | read_lock_bh(&tipc_net_lock); | ||
| 686 | |||
| 649 | /* Get space for all unicast links + multicast link */ | 687 | /* Get space for all unicast links + multicast link */ |
| 650 | 688 | ||
| 651 | payload_size = TLV_SPACE(sizeof(link_info)) * | 689 | payload_size = TLV_SPACE(sizeof(link_info)) * |
| 652 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); | 690 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); |
| 653 | if (payload_size > 32768u) | 691 | if (payload_size > 32768u) { |
| 692 | read_unlock_bh(&tipc_net_lock); | ||
| 654 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 693 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
| 655 | " (too many links)"); | 694 | " (too many links)"); |
| 695 | } | ||
| 656 | buf = tipc_cfg_reply_alloc(payload_size); | 696 | buf = tipc_cfg_reply_alloc(payload_size); |
| 657 | if (!buf) | 697 | if (!buf) { |
| 698 | read_unlock_bh(&tipc_net_lock); | ||
| 658 | return NULL; | 699 | return NULL; |
| 700 | } | ||
| 659 | 701 | ||
| 660 | /* Add TLV for broadcast link */ | 702 | /* Add TLV for broadcast link */ |
| 661 | 703 | ||
| @@ -671,6 +713,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
| 671 | 713 | ||
| 672 | if (!in_scope(domain, n_ptr->addr)) | 714 | if (!in_scope(domain, n_ptr->addr)) |
| 673 | continue; | 715 | continue; |
| 716 | tipc_node_lock(n_ptr); | ||
| 674 | for (i = 0; i < MAX_BEARERS; i++) { | 717 | for (i = 0; i < MAX_BEARERS; i++) { |
| 675 | if (!n_ptr->links[i]) | 718 | if (!n_ptr->links[i]) |
| 676 | continue; | 719 | continue; |
| @@ -680,7 +723,9 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
| 680 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, | 723 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, |
| 681 | &link_info, sizeof(link_info)); | 724 | &link_info, sizeof(link_info)); |
| 682 | } | 725 | } |
| 726 | tipc_node_unlock(n_ptr); | ||
| 683 | } | 727 | } |
| 684 | 728 | ||
| 729 | read_unlock_bh(&tipc_net_lock); | ||
| 685 | return buf; | 730 | return buf; |
| 686 | } | 731 | } |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 2f5806410c64..e70d27ea6578 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/port.c: TIPC port code | 2 | * net/tipc/port.c: TIPC port code |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 1992-2007, Ericsson AB | 4 | * Copyright (c) 1992-2007, Ericsson AB |
| 5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
| @@ -211,12 +211,12 @@ exit: | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /** | 213 | /** |
| 214 | * tipc_createport_raw - create a native TIPC port | 214 | * tipc_createport_raw - create a generic TIPC port |
| 215 | * | 215 | * |
| 216 | * Returns local port reference | 216 | * Returns pointer to (locked) TIPC port, or NULL if unable to create it |
| 217 | */ | 217 | */ |
| 218 | 218 | ||
| 219 | u32 tipc_createport_raw(void *usr_handle, | 219 | struct tipc_port *tipc_createport_raw(void *usr_handle, |
| 220 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), | 220 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), |
| 221 | void (*wakeup)(struct tipc_port *), | 221 | void (*wakeup)(struct tipc_port *), |
| 222 | const u32 importance) | 222 | const u32 importance) |
| @@ -228,26 +228,21 @@ u32 tipc_createport_raw(void *usr_handle, | |||
| 228 | p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); | 228 | p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); |
| 229 | if (!p_ptr) { | 229 | if (!p_ptr) { |
| 230 | warn("Port creation failed, no memory\n"); | 230 | warn("Port creation failed, no memory\n"); |
| 231 | return 0; | 231 | return NULL; |
| 232 | } | 232 | } |
| 233 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); | 233 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); |
| 234 | if (!ref) { | 234 | if (!ref) { |
| 235 | warn("Port creation failed, reference table exhausted\n"); | 235 | warn("Port creation failed, reference table exhausted\n"); |
| 236 | kfree(p_ptr); | 236 | kfree(p_ptr); |
| 237 | return 0; | 237 | return NULL; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | tipc_port_lock(ref); | ||
| 241 | p_ptr->publ.usr_handle = usr_handle; | 240 | p_ptr->publ.usr_handle = usr_handle; |
| 242 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; | 241 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; |
| 243 | p_ptr->publ.ref = ref; | 242 | p_ptr->publ.ref = ref; |
| 244 | msg = &p_ptr->publ.phdr; | 243 | msg = &p_ptr->publ.phdr; |
| 245 | msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, | 244 | msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); |
| 246 | 0); | ||
| 247 | msg_set_orignode(msg, tipc_own_addr); | ||
| 248 | msg_set_prevnode(msg, tipc_own_addr); | ||
| 249 | msg_set_origport(msg, ref); | 245 | msg_set_origport(msg, ref); |
| 250 | msg_set_importance(msg,importance); | ||
| 251 | p_ptr->last_in_seqno = 41; | 246 | p_ptr->last_in_seqno = 41; |
| 252 | p_ptr->sent = 1; | 247 | p_ptr->sent = 1; |
| 253 | INIT_LIST_HEAD(&p_ptr->wait_list); | 248 | INIT_LIST_HEAD(&p_ptr->wait_list); |
| @@ -262,8 +257,7 @@ u32 tipc_createport_raw(void *usr_handle, | |||
| 262 | INIT_LIST_HEAD(&p_ptr->port_list); | 257 | INIT_LIST_HEAD(&p_ptr->port_list); |
| 263 | list_add_tail(&p_ptr->port_list, &ports); | 258 | list_add_tail(&p_ptr->port_list, &ports); |
| 264 | spin_unlock_bh(&tipc_port_list_lock); | 259 | spin_unlock_bh(&tipc_port_list_lock); |
| 265 | tipc_port_unlock(p_ptr); | 260 | return &(p_ptr->publ); |
| 266 | return ref; | ||
| 267 | } | 261 | } |
| 268 | 262 | ||
| 269 | int tipc_deleteport(u32 ref) | 263 | int tipc_deleteport(u32 ref) |
| @@ -297,7 +291,7 @@ int tipc_deleteport(u32 ref) | |||
| 297 | kfree(p_ptr); | 291 | kfree(p_ptr); |
| 298 | dbg("Deleted port %u\n", ref); | 292 | dbg("Deleted port %u\n", ref); |
| 299 | tipc_net_route_msg(buf); | 293 | tipc_net_route_msg(buf); |
| 300 | return TIPC_OK; | 294 | return 0; |
| 301 | } | 295 | } |
| 302 | 296 | ||
| 303 | /** | 297 | /** |
| @@ -342,7 +336,7 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable) | |||
| 342 | return -EINVAL; | 336 | return -EINVAL; |
| 343 | *isunreliable = port_unreliable(p_ptr); | 337 | *isunreliable = port_unreliable(p_ptr); |
| 344 | tipc_port_unlock(p_ptr); | 338 | tipc_port_unlock(p_ptr); |
| 345 | return TIPC_OK; | 339 | return 0; |
| 346 | } | 340 | } |
| 347 | 341 | ||
| 348 | int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) | 342 | int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) |
| @@ -354,7 +348,7 @@ int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) | |||
| 354 | return -EINVAL; | 348 | return -EINVAL; |
| 355 | msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); | 349 | msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); |
| 356 | tipc_port_unlock(p_ptr); | 350 | tipc_port_unlock(p_ptr); |
| 357 | return TIPC_OK; | 351 | return 0; |
| 358 | } | 352 | } |
| 359 | 353 | ||
| 360 | static int port_unreturnable(struct port *p_ptr) | 354 | static int port_unreturnable(struct port *p_ptr) |
| @@ -371,7 +365,7 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) | |||
| 371 | return -EINVAL; | 365 | return -EINVAL; |
| 372 | *isunrejectable = port_unreturnable(p_ptr); | 366 | *isunrejectable = port_unreturnable(p_ptr); |
| 373 | tipc_port_unlock(p_ptr); | 367 | tipc_port_unlock(p_ptr); |
| 374 | return TIPC_OK; | 368 | return 0; |
| 375 | } | 369 | } |
| 376 | 370 | ||
| 377 | int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) | 371 | int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) |
| @@ -383,7 +377,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) | |||
| 383 | return -EINVAL; | 377 | return -EINVAL; |
| 384 | msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); | 378 | msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); |
| 385 | tipc_port_unlock(p_ptr); | 379 | tipc_port_unlock(p_ptr); |
| 386 | return TIPC_OK; | 380 | return 0; |
| 387 | } | 381 | } |
| 388 | 382 | ||
| 389 | /* | 383 | /* |
| @@ -402,10 +396,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, | |||
| 402 | buf = buf_acquire(LONG_H_SIZE); | 396 | buf = buf_acquire(LONG_H_SIZE); |
| 403 | if (buf) { | 397 | if (buf) { |
| 404 | msg = buf_msg(buf); | 398 | msg = buf_msg(buf); |
| 405 | msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); | 399 | msg_init(msg, usr, type, LONG_H_SIZE, destnode); |
| 400 | msg_set_errcode(msg, err); | ||
| 406 | msg_set_destport(msg, destport); | 401 | msg_set_destport(msg, destport); |
| 407 | msg_set_origport(msg, origport); | 402 | msg_set_origport(msg, origport); |
| 408 | msg_set_destnode(msg, destnode); | ||
| 409 | msg_set_orignode(msg, orignode); | 403 | msg_set_orignode(msg, orignode); |
| 410 | msg_set_transp_seqno(msg, seqno); | 404 | msg_set_transp_seqno(msg, seqno); |
| 411 | msg_set_msgcnt(msg, ack); | 405 | msg_set_msgcnt(msg, ack); |
| @@ -446,17 +440,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
| 446 | return data_sz; | 440 | return data_sz; |
| 447 | } | 441 | } |
| 448 | rmsg = buf_msg(rbuf); | 442 | rmsg = buf_msg(rbuf); |
| 449 | msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); | 443 | msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); |
| 444 | msg_set_errcode(rmsg, err); | ||
| 450 | msg_set_destport(rmsg, msg_origport(msg)); | 445 | msg_set_destport(rmsg, msg_origport(msg)); |
| 451 | msg_set_prevnode(rmsg, tipc_own_addr); | ||
| 452 | msg_set_origport(rmsg, msg_destport(msg)); | 446 | msg_set_origport(rmsg, msg_destport(msg)); |
| 453 | if (msg_short(msg)) | 447 | if (msg_short(msg)) { |
| 454 | msg_set_orignode(rmsg, tipc_own_addr); | 448 | msg_set_orignode(rmsg, tipc_own_addr); |
| 455 | else | 449 | /* leave name type & instance as zeroes */ |
| 450 | } else { | ||
| 456 | msg_set_orignode(rmsg, msg_destnode(msg)); | 451 | msg_set_orignode(rmsg, msg_destnode(msg)); |
| 452 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
| 453 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
| 454 | } | ||
| 457 | msg_set_size(rmsg, data_sz + hdr_sz); | 455 | msg_set_size(rmsg, data_sz + hdr_sz); |
| 458 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
| 459 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
| 460 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); | 456 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); |
| 461 | 457 | ||
| 462 | /* send self-abort message when rejecting on a connected port */ | 458 | /* send self-abort message when rejecting on a connected port */ |
| @@ -778,6 +774,7 @@ void tipc_port_reinit(void) | |||
| 778 | msg = &p_ptr->publ.phdr; | 774 | msg = &p_ptr->publ.phdr; |
| 779 | if (msg_orignode(msg) == tipc_own_addr) | 775 | if (msg_orignode(msg) == tipc_own_addr) |
| 780 | break; | 776 | break; |
| 777 | msg_set_prevnode(msg, tipc_own_addr); | ||
| 781 | msg_set_orignode(msg, tipc_own_addr); | 778 | msg_set_orignode(msg, tipc_own_addr); |
| 782 | } | 779 | } |
| 783 | spin_unlock_bh(&tipc_port_list_lock); | 780 | spin_unlock_bh(&tipc_port_list_lock); |
| @@ -838,16 +835,13 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 838 | u32 peer_node = port_peernode(p_ptr); | 835 | u32 peer_node = port_peernode(p_ptr); |
| 839 | 836 | ||
| 840 | tipc_port_unlock(p_ptr); | 837 | tipc_port_unlock(p_ptr); |
| 838 | if (unlikely(!cb)) | ||
| 839 | goto reject; | ||
| 841 | if (unlikely(!connected)) { | 840 | if (unlikely(!connected)) { |
| 842 | if (unlikely(published)) | 841 | if (tipc_connect2port(dref, &orig)) |
| 843 | goto reject; | 842 | goto reject; |
| 844 | tipc_connect2port(dref,&orig); | 843 | } else if ((msg_origport(msg) != peer_port) || |
| 845 | } | 844 | (msg_orignode(msg) != peer_node)) |
| 846 | if (unlikely(msg_origport(msg) != peer_port)) | ||
| 847 | goto reject; | ||
| 848 | if (unlikely(msg_orignode(msg) != peer_node)) | ||
| 849 | goto reject; | ||
| 850 | if (unlikely(!cb)) | ||
| 851 | goto reject; | 845 | goto reject; |
| 852 | if (unlikely(++p_ptr->publ.conn_unacked >= | 846 | if (unlikely(++p_ptr->publ.conn_unacked >= |
| 853 | TIPC_FLOW_CONTROL_WIN)) | 847 | TIPC_FLOW_CONTROL_WIN)) |
| @@ -862,9 +856,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 862 | tipc_msg_event cb = up_ptr->msg_cb; | 856 | tipc_msg_event cb = up_ptr->msg_cb; |
| 863 | 857 | ||
| 864 | tipc_port_unlock(p_ptr); | 858 | tipc_port_unlock(p_ptr); |
| 865 | if (unlikely(connected)) | 859 | if (unlikely(!cb || connected)) |
| 866 | goto reject; | ||
| 867 | if (unlikely(!cb)) | ||
| 868 | goto reject; | 860 | goto reject; |
| 869 | skb_pull(buf, msg_hdr_sz(msg)); | 861 | skb_pull(buf, msg_hdr_sz(msg)); |
| 870 | cb(usr_handle, dref, &buf, msg_data(msg), | 862 | cb(usr_handle, dref, &buf, msg_data(msg), |
| @@ -877,11 +869,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 877 | tipc_named_msg_event cb = up_ptr->named_msg_cb; | 869 | tipc_named_msg_event cb = up_ptr->named_msg_cb; |
| 878 | 870 | ||
| 879 | tipc_port_unlock(p_ptr); | 871 | tipc_port_unlock(p_ptr); |
| 880 | if (unlikely(connected)) | 872 | if (unlikely(!cb || connected || !published)) |
| 881 | goto reject; | ||
| 882 | if (unlikely(!cb)) | ||
| 883 | goto reject; | ||
| 884 | if (unlikely(!published)) | ||
| 885 | goto reject; | 873 | goto reject; |
| 886 | dseq.type = msg_nametype(msg); | 874 | dseq.type = msg_nametype(msg); |
| 887 | dseq.lower = msg_nameinst(msg); | 875 | dseq.lower = msg_nameinst(msg); |
| @@ -908,11 +896,10 @@ err: | |||
| 908 | u32 peer_node = port_peernode(p_ptr); | 896 | u32 peer_node = port_peernode(p_ptr); |
| 909 | 897 | ||
| 910 | tipc_port_unlock(p_ptr); | 898 | tipc_port_unlock(p_ptr); |
| 911 | if (!connected || !cb) | 899 | if (!cb || !connected) |
| 912 | break; | ||
| 913 | if (msg_origport(msg) != peer_port) | ||
| 914 | break; | 900 | break; |
| 915 | if (msg_orignode(msg) != peer_node) | 901 | if ((msg_origport(msg) != peer_port) || |
| 902 | (msg_orignode(msg) != peer_node)) | ||
| 916 | break; | 903 | break; |
| 917 | tipc_disconnect(dref); | 904 | tipc_disconnect(dref); |
| 918 | skb_pull(buf, msg_hdr_sz(msg)); | 905 | skb_pull(buf, msg_hdr_sz(msg)); |
| @@ -924,7 +911,7 @@ err: | |||
| 924 | tipc_msg_err_event cb = up_ptr->err_cb; | 911 | tipc_msg_err_event cb = up_ptr->err_cb; |
| 925 | 912 | ||
| 926 | tipc_port_unlock(p_ptr); | 913 | tipc_port_unlock(p_ptr); |
| 927 | if (connected || !cb) | 914 | if (!cb || connected) |
| 928 | break; | 915 | break; |
| 929 | skb_pull(buf, msg_hdr_sz(msg)); | 916 | skb_pull(buf, msg_hdr_sz(msg)); |
| 930 | cb(usr_handle, dref, &buf, msg_data(msg), | 917 | cb(usr_handle, dref, &buf, msg_data(msg), |
| @@ -937,7 +924,7 @@ err: | |||
| 937 | up_ptr->named_err_cb; | 924 | up_ptr->named_err_cb; |
| 938 | 925 | ||
| 939 | tipc_port_unlock(p_ptr); | 926 | tipc_port_unlock(p_ptr); |
| 940 | if (connected || !cb) | 927 | if (!cb || connected) |
| 941 | break; | 928 | break; |
| 942 | dseq.type = msg_nametype(msg); | 929 | dseq.type = msg_nametype(msg); |
| 943 | dseq.lower = msg_nameinst(msg); | 930 | dseq.lower = msg_nameinst(msg); |
| @@ -976,7 +963,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf) | |||
| 976 | tipc_k_signal((Handler)port_dispatcher_sigh, 0); | 963 | tipc_k_signal((Handler)port_dispatcher_sigh, 0); |
| 977 | } | 964 | } |
| 978 | spin_unlock_bh(&queue_lock); | 965 | spin_unlock_bh(&queue_lock); |
| 979 | return TIPC_OK; | 966 | return 0; |
| 980 | } | 967 | } |
| 981 | 968 | ||
| 982 | /* | 969 | /* |
| @@ -1053,15 +1040,14 @@ int tipc_createport(u32 user_ref, | |||
| 1053 | { | 1040 | { |
| 1054 | struct user_port *up_ptr; | 1041 | struct user_port *up_ptr; |
| 1055 | struct port *p_ptr; | 1042 | struct port *p_ptr; |
| 1056 | u32 ref; | ||
| 1057 | 1043 | ||
| 1058 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); | 1044 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); |
| 1059 | if (!up_ptr) { | 1045 | if (!up_ptr) { |
| 1060 | warn("Port creation failed, no memory\n"); | 1046 | warn("Port creation failed, no memory\n"); |
| 1061 | return -ENOMEM; | 1047 | return -ENOMEM; |
| 1062 | } | 1048 | } |
| 1063 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); | 1049 | p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, |
| 1064 | p_ptr = tipc_port_lock(ref); | 1050 | port_wakeup, importance); |
| 1065 | if (!p_ptr) { | 1051 | if (!p_ptr) { |
| 1066 | kfree(up_ptr); | 1052 | kfree(up_ptr); |
| 1067 | return -ENOMEM; | 1053 | return -ENOMEM; |
| @@ -1081,16 +1067,15 @@ int tipc_createport(u32 user_ref, | |||
| 1081 | INIT_LIST_HEAD(&up_ptr->uport_list); | 1067 | INIT_LIST_HEAD(&up_ptr->uport_list); |
| 1082 | tipc_reg_add_port(up_ptr); | 1068 | tipc_reg_add_port(up_ptr); |
| 1083 | *portref = p_ptr->publ.ref; | 1069 | *portref = p_ptr->publ.ref; |
| 1084 | dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref); | ||
| 1085 | tipc_port_unlock(p_ptr); | 1070 | tipc_port_unlock(p_ptr); |
| 1086 | return TIPC_OK; | 1071 | return 0; |
| 1087 | } | 1072 | } |
| 1088 | 1073 | ||
| 1089 | int tipc_ownidentity(u32 ref, struct tipc_portid *id) | 1074 | int tipc_ownidentity(u32 ref, struct tipc_portid *id) |
| 1090 | { | 1075 | { |
| 1091 | id->ref = ref; | 1076 | id->ref = ref; |
| 1092 | id->node = tipc_own_addr; | 1077 | id->node = tipc_own_addr; |
| 1093 | return TIPC_OK; | 1078 | return 0; |
| 1094 | } | 1079 | } |
| 1095 | 1080 | ||
| 1096 | int tipc_portimportance(u32 ref, unsigned int *importance) | 1081 | int tipc_portimportance(u32 ref, unsigned int *importance) |
| @@ -1102,7 +1087,7 @@ int tipc_portimportance(u32 ref, unsigned int *importance) | |||
| 1102 | return -EINVAL; | 1087 | return -EINVAL; |
| 1103 | *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); | 1088 | *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); |
| 1104 | tipc_port_unlock(p_ptr); | 1089 | tipc_port_unlock(p_ptr); |
| 1105 | return TIPC_OK; | 1090 | return 0; |
| 1106 | } | 1091 | } |
| 1107 | 1092 | ||
| 1108 | int tipc_set_portimportance(u32 ref, unsigned int imp) | 1093 | int tipc_set_portimportance(u32 ref, unsigned int imp) |
| @@ -1117,7 +1102,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp) | |||
| 1117 | return -EINVAL; | 1102 | return -EINVAL; |
| 1118 | msg_set_importance(&p_ptr->publ.phdr, (u32)imp); | 1103 | msg_set_importance(&p_ptr->publ.phdr, (u32)imp); |
| 1119 | tipc_port_unlock(p_ptr); | 1104 | tipc_port_unlock(p_ptr); |
| 1120 | return TIPC_OK; | 1105 | return 0; |
| 1121 | } | 1106 | } |
| 1122 | 1107 | ||
| 1123 | 1108 | ||
| @@ -1152,7 +1137,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
| 1152 | list_add(&publ->pport_list, &p_ptr->publications); | 1137 | list_add(&publ->pport_list, &p_ptr->publications); |
| 1153 | p_ptr->pub_count++; | 1138 | p_ptr->pub_count++; |
| 1154 | p_ptr->publ.published = 1; | 1139 | p_ptr->publ.published = 1; |
| 1155 | res = TIPC_OK; | 1140 | res = 0; |
| 1156 | } | 1141 | } |
| 1157 | exit: | 1142 | exit: |
| 1158 | tipc_port_unlock(p_ptr); | 1143 | tipc_port_unlock(p_ptr); |
| @@ -1175,7 +1160,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
| 1175 | tipc_nametbl_withdraw(publ->type, publ->lower, | 1160 | tipc_nametbl_withdraw(publ->type, publ->lower, |
| 1176 | publ->ref, publ->key); | 1161 | publ->ref, publ->key); |
| 1177 | } | 1162 | } |
| 1178 | res = TIPC_OK; | 1163 | res = 0; |
| 1179 | } else { | 1164 | } else { |
| 1180 | list_for_each_entry_safe(publ, tpubl, | 1165 | list_for_each_entry_safe(publ, tpubl, |
| 1181 | &p_ptr->publications, pport_list) { | 1166 | &p_ptr->publications, pport_list) { |
| @@ -1189,7 +1174,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
| 1189 | break; | 1174 | break; |
| 1190 | tipc_nametbl_withdraw(publ->type, publ->lower, | 1175 | tipc_nametbl_withdraw(publ->type, publ->lower, |
| 1191 | publ->ref, publ->key); | 1176 | publ->ref, publ->key); |
| 1192 | res = TIPC_OK; | 1177 | res = 0; |
| 1193 | break; | 1178 | break; |
| 1194 | } | 1179 | } |
| 1195 | } | 1180 | } |
| @@ -1233,7 +1218,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) | |||
| 1233 | tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, | 1218 | tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, |
| 1234 | (void *)(unsigned long)ref, | 1219 | (void *)(unsigned long)ref, |
| 1235 | (net_ev_handler)port_handle_node_down); | 1220 | (net_ev_handler)port_handle_node_down); |
| 1236 | res = TIPC_OK; | 1221 | res = 0; |
| 1237 | exit: | 1222 | exit: |
| 1238 | tipc_port_unlock(p_ptr); | 1223 | tipc_port_unlock(p_ptr); |
| 1239 | p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); | 1224 | p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); |
| @@ -1255,7 +1240,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr) | |||
| 1255 | /* let timer expire on it's own to avoid deadlock! */ | 1240 | /* let timer expire on it's own to avoid deadlock! */ |
| 1256 | tipc_nodesub_unsubscribe( | 1241 | tipc_nodesub_unsubscribe( |
| 1257 | &((struct port *)tp_ptr)->subscription); | 1242 | &((struct port *)tp_ptr)->subscription); |
| 1258 | res = TIPC_OK; | 1243 | res = 0; |
| 1259 | } else { | 1244 | } else { |
| 1260 | res = -ENOTCONN; | 1245 | res = -ENOTCONN; |
| 1261 | } | 1246 | } |
| @@ -1320,7 +1305,7 @@ int tipc_isconnected(u32 ref, int *isconnected) | |||
| 1320 | return -EINVAL; | 1305 | return -EINVAL; |
| 1321 | *isconnected = p_ptr->publ.connected; | 1306 | *isconnected = p_ptr->publ.connected; |
| 1322 | tipc_port_unlock(p_ptr); | 1307 | tipc_port_unlock(p_ptr); |
| 1323 | return TIPC_OK; | 1308 | return 0; |
| 1324 | } | 1309 | } |
| 1325 | 1310 | ||
| 1326 | int tipc_peer(u32 ref, struct tipc_portid *peer) | 1311 | int tipc_peer(u32 ref, struct tipc_portid *peer) |
| @@ -1334,7 +1319,7 @@ int tipc_peer(u32 ref, struct tipc_portid *peer) | |||
| 1334 | if (p_ptr->publ.connected) { | 1319 | if (p_ptr->publ.connected) { |
| 1335 | peer->ref = port_peerport(p_ptr); | 1320 | peer->ref = port_peerport(p_ptr); |
| 1336 | peer->node = port_peernode(p_ptr); | 1321 | peer->node = port_peernode(p_ptr); |
| 1337 | res = TIPC_OK; | 1322 | res = 0; |
| 1338 | } else | 1323 | } else |
| 1339 | res = -ENOTCONN; | 1324 | res = -ENOTCONN; |
| 1340 | tipc_port_unlock(p_ptr); | 1325 | tipc_port_unlock(p_ptr); |
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 89cbab24d08f..414fc34b8bea 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
| @@ -123,7 +123,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
| 123 | tipc_ref_table.index_mask = actual_size - 1; | 123 | tipc_ref_table.index_mask = actual_size - 1; |
| 124 | tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; | 124 | tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; |
| 125 | 125 | ||
| 126 | return TIPC_OK; | 126 | return 0; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | /** | 129 | /** |
| @@ -142,9 +142,13 @@ void tipc_ref_table_stop(void) | |||
| 142 | /** | 142 | /** |
| 143 | * tipc_ref_acquire - create reference to an object | 143 | * tipc_ref_acquire - create reference to an object |
| 144 | * | 144 | * |
| 145 | * Return a unique reference value which can be translated back to the pointer | 145 | * Register an object pointer in reference table and lock the object. |
| 146 | * 'object' at a later time. Also, pass back a pointer to the lock protecting | 146 | * Returns a unique reference value that is used from then on to retrieve the |
| 147 | * the object, but without locking it. | 147 | * object pointer, or to determine that the object has been deregistered. |
| 148 | * | ||
| 149 | * Note: The object is returned in the locked state so that the caller can | ||
| 150 | * register a partially initialized object, without running the risk that | ||
| 151 | * the object will be accessed before initialization is complete. | ||
| 148 | */ | 152 | */ |
| 149 | 153 | ||
| 150 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) | 154 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) |
| @@ -178,13 +182,13 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) | |||
| 178 | ref = (next_plus_upper & ~index_mask) + index; | 182 | ref = (next_plus_upper & ~index_mask) + index; |
| 179 | entry->ref = ref; | 183 | entry->ref = ref; |
| 180 | entry->object = object; | 184 | entry->object = object; |
| 181 | spin_unlock_bh(&entry->lock); | ||
| 182 | *lock = &entry->lock; | 185 | *lock = &entry->lock; |
| 183 | } | 186 | } |
| 184 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { | 187 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { |
| 185 | index = tipc_ref_table.init_point++; | 188 | index = tipc_ref_table.init_point++; |
| 186 | entry = &(tipc_ref_table.entries[index]); | 189 | entry = &(tipc_ref_table.entries[index]); |
| 187 | spin_lock_init(&entry->lock); | 190 | spin_lock_init(&entry->lock); |
| 191 | spin_lock_bh(&entry->lock); | ||
| 188 | ref = tipc_ref_table.start_mask + index; | 192 | ref = tipc_ref_table.start_mask + index; |
| 189 | entry->ref = ref; | 193 | entry->ref = ref; |
| 190 | entry->object = object; | 194 | entry->object = object; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 230f9ca2ad6b..1848693ebb82 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2007, Ericsson AB | 4 | * Copyright (c) 2001-2007, Ericsson AB |
| 5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
| @@ -63,6 +63,7 @@ | |||
| 63 | struct tipc_sock { | 63 | struct tipc_sock { |
| 64 | struct sock sk; | 64 | struct sock sk; |
| 65 | struct tipc_port *p; | 65 | struct tipc_port *p; |
| 66 | struct tipc_portid peer_name; | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 69 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
| @@ -188,7 +189,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 188 | const struct proto_ops *ops; | 189 | const struct proto_ops *ops; |
| 189 | socket_state state; | 190 | socket_state state; |
| 190 | struct sock *sk; | 191 | struct sock *sk; |
| 191 | u32 portref; | 192 | struct tipc_port *tp_ptr; |
| 192 | 193 | ||
| 193 | /* Validate arguments */ | 194 | /* Validate arguments */ |
| 194 | 195 | ||
| @@ -224,9 +225,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 224 | 225 | ||
| 225 | /* Allocate TIPC port for socket to use */ | 226 | /* Allocate TIPC port for socket to use */ |
| 226 | 227 | ||
| 227 | portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 228 | tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, |
| 228 | TIPC_LOW_IMPORTANCE); | 229 | TIPC_LOW_IMPORTANCE); |
| 229 | if (unlikely(portref == 0)) { | 230 | if (unlikely(!tp_ptr)) { |
| 230 | sk_free(sk); | 231 | sk_free(sk); |
| 231 | return -ENOMEM; | 232 | return -ENOMEM; |
| 232 | } | 233 | } |
| @@ -239,12 +240,14 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 239 | sock_init_data(sock, sk); | 240 | sock_init_data(sock, sk); |
| 240 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | 241 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); |
| 241 | sk->sk_backlog_rcv = backlog_rcv; | 242 | sk->sk_backlog_rcv = backlog_rcv; |
| 242 | tipc_sk(sk)->p = tipc_get_port(portref); | 243 | tipc_sk(sk)->p = tp_ptr; |
| 244 | |||
| 245 | spin_unlock_bh(tp_ptr->lock); | ||
| 243 | 246 | ||
| 244 | if (sock->state == SS_READY) { | 247 | if (sock->state == SS_READY) { |
| 245 | tipc_set_portunreturnable(portref, 1); | 248 | tipc_set_portunreturnable(tp_ptr->ref, 1); |
| 246 | if (sock->type == SOCK_DGRAM) | 249 | if (sock->type == SOCK_DGRAM) |
| 247 | tipc_set_portunreliable(portref, 1); | 250 | tipc_set_portunreliable(tp_ptr->ref, 1); |
| 248 | } | 251 | } |
| 249 | 252 | ||
| 250 | atomic_inc(&tipc_user_count); | 253 | atomic_inc(&tipc_user_count); |
| @@ -375,27 +378,29 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
| 375 | * @sock: socket structure | 378 | * @sock: socket structure |
| 376 | * @uaddr: area for returned socket address | 379 | * @uaddr: area for returned socket address |
| 377 | * @uaddr_len: area for returned length of socket address | 380 | * @uaddr_len: area for returned length of socket address |
| 378 | * @peer: 0 to obtain socket name, 1 to obtain peer socket name | 381 | * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID |
| 379 | * | 382 | * |
| 380 | * Returns 0 on success, errno otherwise | 383 | * Returns 0 on success, errno otherwise |
| 381 | * | 384 | * |
| 382 | * NOTE: This routine doesn't need to take the socket lock since it doesn't | 385 | * NOTE: This routine doesn't need to take the socket lock since it only |
| 383 | * access any non-constant socket information. | 386 | * accesses socket information that is unchanging (or which changes in |
| 387 | * a completely predictable manner). | ||
| 384 | */ | 388 | */ |
| 385 | 389 | ||
| 386 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 390 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
| 387 | int *uaddr_len, int peer) | 391 | int *uaddr_len, int peer) |
| 388 | { | 392 | { |
| 389 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 393 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
| 390 | u32 portref = tipc_sk_port(sock->sk)->ref; | 394 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
| 391 | u32 res; | ||
| 392 | 395 | ||
| 393 | if (peer) { | 396 | if (peer) { |
| 394 | res = tipc_peer(portref, &addr->addr.id); | 397 | if ((sock->state != SS_CONNECTED) && |
| 395 | if (res) | 398 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) |
| 396 | return res; | 399 | return -ENOTCONN; |
| 400 | addr->addr.id.ref = tsock->peer_name.ref; | ||
| 401 | addr->addr.id.node = tsock->peer_name.node; | ||
| 397 | } else { | 402 | } else { |
| 398 | tipc_ownidentity(portref, &addr->addr.id); | 403 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); |
| 399 | } | 404 | } |
| 400 | 405 | ||
| 401 | *uaddr_len = sizeof(*addr); | 406 | *uaddr_len = sizeof(*addr); |
| @@ -764,18 +769,17 @@ exit: | |||
| 764 | 769 | ||
| 765 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) | 770 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) |
| 766 | { | 771 | { |
| 767 | struct tipc_port *tport = tipc_sk_port(sock->sk); | 772 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
| 768 | struct tipc_portid peer; | ||
| 769 | 773 | ||
| 770 | if (msg_errcode(msg)) { | 774 | if (msg_errcode(msg)) { |
| 771 | sock->state = SS_DISCONNECTING; | 775 | sock->state = SS_DISCONNECTING; |
| 772 | return -ECONNREFUSED; | 776 | return -ECONNREFUSED; |
| 773 | } | 777 | } |
| 774 | 778 | ||
| 775 | peer.ref = msg_origport(msg); | 779 | tsock->peer_name.ref = msg_origport(msg); |
| 776 | peer.node = msg_orignode(msg); | 780 | tsock->peer_name.node = msg_orignode(msg); |
| 777 | tipc_connect2port(tport->ref, &peer); | 781 | tipc_connect2port(tsock->p->ref, &tsock->peer_name); |
| 778 | tipc_set_portimportance(tport->ref, msg_importance(msg)); | 782 | tipc_set_portimportance(tsock->p->ref, msg_importance(msg)); |
| 779 | sock->state = SS_CONNECTED; | 783 | sock->state = SS_CONNECTED; |
| 780 | return 0; | 784 | return 0; |
| 781 | } | 785 | } |
| @@ -1131,7 +1135,7 @@ restart: | |||
| 1131 | /* Loop around if more data is required */ | 1135 | /* Loop around if more data is required */ |
| 1132 | 1136 | ||
| 1133 | if ((sz_copied < buf_len) /* didn't get all requested data */ | 1137 | if ((sz_copied < buf_len) /* didn't get all requested data */ |
| 1134 | && (!skb_queue_empty(&sock->sk->sk_receive_queue) || | 1138 | && (!skb_queue_empty(&sk->sk_receive_queue) || |
| 1135 | (flags & MSG_WAITALL)) | 1139 | (flags & MSG_WAITALL)) |
| 1136 | /* ... and more is ready or required */ | 1140 | /* ... and more is ready or required */ |
| 1137 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ | 1141 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ |
| @@ -1527,9 +1531,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1527 | res = tipc_create(sock_net(sock->sk), new_sock, 0); | 1531 | res = tipc_create(sock_net(sock->sk), new_sock, 0); |
| 1528 | if (!res) { | 1532 | if (!res) { |
| 1529 | struct sock *new_sk = new_sock->sk; | 1533 | struct sock *new_sk = new_sock->sk; |
| 1530 | struct tipc_port *new_tport = tipc_sk_port(new_sk); | 1534 | struct tipc_sock *new_tsock = tipc_sk(new_sk); |
| 1535 | struct tipc_port *new_tport = new_tsock->p; | ||
| 1531 | u32 new_ref = new_tport->ref; | 1536 | u32 new_ref = new_tport->ref; |
| 1532 | struct tipc_portid id; | ||
| 1533 | struct tipc_msg *msg = buf_msg(buf); | 1537 | struct tipc_msg *msg = buf_msg(buf); |
| 1534 | 1538 | ||
| 1535 | lock_sock(new_sk); | 1539 | lock_sock(new_sk); |
| @@ -1543,9 +1547,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1543 | 1547 | ||
| 1544 | /* Connect new socket to it's peer */ | 1548 | /* Connect new socket to it's peer */ |
| 1545 | 1549 | ||
| 1546 | id.ref = msg_origport(msg); | 1550 | new_tsock->peer_name.ref = msg_origport(msg); |
| 1547 | id.node = msg_orignode(msg); | 1551 | new_tsock->peer_name.node = msg_orignode(msg); |
| 1548 | tipc_connect2port(new_ref, &id); | 1552 | tipc_connect2port(new_ref, &new_tsock->peer_name); |
| 1549 | new_sock->state = SS_CONNECTED; | 1553 | new_sock->state = SS_CONNECTED; |
| 1550 | 1554 | ||
| 1551 | tipc_set_portimportance(new_ref, msg_importance(msg)); | 1555 | tipc_set_portimportance(new_ref, msg_importance(msg)); |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 8c01ccd3626c..0326d3060bc7 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * net/tipc/subscr.c: TIPC subscription service | 2 | * net/tipc/subscr.c: TIPC network topology service |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2000-2006, Ericsson AB | 4 | * Copyright (c) 2000-2006, Ericsson AB |
| 5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -36,27 +36,24 @@ | |||
| 36 | 36 | ||
| 37 | #include "core.h" | 37 | #include "core.h" |
| 38 | #include "dbg.h" | 38 | #include "dbg.h" |
| 39 | #include "subscr.h" | ||
| 40 | #include "name_table.h" | 39 | #include "name_table.h" |
| 40 | #include "port.h" | ||
| 41 | #include "ref.h" | 41 | #include "ref.h" |
| 42 | #include "subscr.h" | ||
| 42 | 43 | ||
| 43 | /** | 44 | /** |
| 44 | * struct subscriber - TIPC network topology subscriber | 45 | * struct subscriber - TIPC network topology subscriber |
| 45 | * @ref: object reference to subscriber object itself | 46 | * @port_ref: object reference to server port connecting to subscriber |
| 46 | * @lock: pointer to spinlock controlling access to subscriber object | 47 | * @lock: pointer to spinlock controlling access to subscriber's server port |
| 47 | * @subscriber_list: adjacent subscribers in top. server's list of subscribers | 48 | * @subscriber_list: adjacent subscribers in top. server's list of subscribers |
| 48 | * @subscription_list: list of subscription objects for this subscriber | 49 | * @subscription_list: list of subscription objects for this subscriber |
| 49 | * @port_ref: object reference to port used to communicate with subscriber | ||
| 50 | * @swap: indicates if subscriber uses opposite endianness in its messages | ||
| 51 | */ | 50 | */ |
| 52 | 51 | ||
| 53 | struct subscriber { | 52 | struct subscriber { |
| 54 | u32 ref; | 53 | u32 port_ref; |
| 55 | spinlock_t *lock; | 54 | spinlock_t *lock; |
| 56 | struct list_head subscriber_list; | 55 | struct list_head subscriber_list; |
| 57 | struct list_head subscription_list; | 56 | struct list_head subscription_list; |
| 58 | u32 port_ref; | ||
| 59 | int swap; | ||
| 60 | }; | 57 | }; |
| 61 | 58 | ||
| 62 | /** | 59 | /** |
| @@ -88,13 +85,14 @@ static struct top_srv topsrv = { 0 }; | |||
| 88 | 85 | ||
| 89 | static u32 htohl(u32 in, int swap) | 86 | static u32 htohl(u32 in, int swap) |
| 90 | { | 87 | { |
| 91 | char *c = (char *)∈ | 88 | return swap ? (u32)___constant_swab32(in) : in; |
| 92 | |||
| 93 | return swap ? ((c[3] << 3) + (c[2] << 2) + (c[1] << 1) + c[0]) : in; | ||
| 94 | } | 89 | } |
| 95 | 90 | ||
| 96 | /** | 91 | /** |
| 97 | * subscr_send_event - send a message containing a tipc_event to the subscriber | 92 | * subscr_send_event - send a message containing a tipc_event to the subscriber |
| 93 | * | ||
| 94 | * Note: Must not hold subscriber's server port lock, since tipc_send() will | ||
| 95 | * try to take the lock if the message is rejected and returned! | ||
| 98 | */ | 96 | */ |
| 99 | 97 | ||
| 100 | static void subscr_send_event(struct subscription *sub, | 98 | static void subscr_send_event(struct subscription *sub, |
| @@ -109,12 +107,12 @@ static void subscr_send_event(struct subscription *sub, | |||
| 109 | msg_sect.iov_base = (void *)&sub->evt; | 107 | msg_sect.iov_base = (void *)&sub->evt; |
| 110 | msg_sect.iov_len = sizeof(struct tipc_event); | 108 | msg_sect.iov_len = sizeof(struct tipc_event); |
| 111 | 109 | ||
| 112 | sub->evt.event = htohl(event, sub->owner->swap); | 110 | sub->evt.event = htohl(event, sub->swap); |
| 113 | sub->evt.found_lower = htohl(found_lower, sub->owner->swap); | 111 | sub->evt.found_lower = htohl(found_lower, sub->swap); |
| 114 | sub->evt.found_upper = htohl(found_upper, sub->owner->swap); | 112 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
| 115 | sub->evt.port.ref = htohl(port_ref, sub->owner->swap); | 113 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
| 116 | sub->evt.port.node = htohl(node, sub->owner->swap); | 114 | sub->evt.port.node = htohl(node, sub->swap); |
| 117 | tipc_send(sub->owner->port_ref, 1, &msg_sect); | 115 | tipc_send(sub->server_ref, 1, &msg_sect); |
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /** | 118 | /** |
| @@ -151,13 +149,12 @@ void tipc_subscr_report_overlap(struct subscription *sub, | |||
| 151 | u32 node, | 149 | u32 node, |
| 152 | int must) | 150 | int must) |
| 153 | { | 151 | { |
| 154 | dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower, | ||
| 155 | sub->seq.upper, found_lower, found_upper); | ||
| 156 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) | 152 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) |
| 157 | return; | 153 | return; |
| 158 | if (!must && !(sub->filter & TIPC_SUB_PORTS)) | 154 | if (!must && !(sub->filter & TIPC_SUB_PORTS)) |
| 159 | return; | 155 | return; |
| 160 | subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); | 156 | |
| 157 | sub->event_cb(sub, found_lower, found_upper, event, port_ref, node); | ||
| 161 | } | 158 | } |
| 162 | 159 | ||
| 163 | /** | 160 | /** |
| @@ -166,20 +163,18 @@ void tipc_subscr_report_overlap(struct subscription *sub, | |||
| 166 | 163 | ||
| 167 | static void subscr_timeout(struct subscription *sub) | 164 | static void subscr_timeout(struct subscription *sub) |
| 168 | { | 165 | { |
| 169 | struct subscriber *subscriber; | 166 | struct port *server_port; |
| 170 | u32 subscriber_ref; | ||
| 171 | 167 | ||
| 172 | /* Validate subscriber reference (in case subscriber is terminating) */ | 168 | /* Validate server port reference (in case subscriber is terminating) */ |
| 173 | 169 | ||
| 174 | subscriber_ref = sub->owner->ref; | 170 | server_port = tipc_port_lock(sub->server_ref); |
| 175 | subscriber = (struct subscriber *)tipc_ref_lock(subscriber_ref); | 171 | if (server_port == NULL) |
| 176 | if (subscriber == NULL) | ||
| 177 | return; | 172 | return; |
| 178 | 173 | ||
| 179 | /* Validate timeout (in case subscription is being cancelled) */ | 174 | /* Validate timeout (in case subscription is being cancelled) */ |
| 180 | 175 | ||
| 181 | if (sub->timeout == TIPC_WAIT_FOREVER) { | 176 | if (sub->timeout == TIPC_WAIT_FOREVER) { |
| 182 | tipc_ref_unlock(subscriber_ref); | 177 | tipc_port_unlock(server_port); |
| 183 | return; | 178 | return; |
| 184 | } | 179 | } |
| 185 | 180 | ||
| @@ -187,19 +182,21 @@ static void subscr_timeout(struct subscription *sub) | |||
| 187 | 182 | ||
| 188 | tipc_nametbl_unsubscribe(sub); | 183 | tipc_nametbl_unsubscribe(sub); |
| 189 | 184 | ||
| 190 | /* Notify subscriber of timeout, then unlink subscription */ | 185 | /* Unlink subscription from subscriber */ |
| 191 | 186 | ||
| 192 | subscr_send_event(sub, | ||
| 193 | sub->evt.s.seq.lower, | ||
| 194 | sub->evt.s.seq.upper, | ||
| 195 | TIPC_SUBSCR_TIMEOUT, | ||
| 196 | 0, | ||
| 197 | 0); | ||
| 198 | list_del(&sub->subscription_list); | 187 | list_del(&sub->subscription_list); |
| 199 | 188 | ||
| 189 | /* Release subscriber's server port */ | ||
| 190 | |||
| 191 | tipc_port_unlock(server_port); | ||
| 192 | |||
| 193 | /* Notify subscriber of timeout */ | ||
| 194 | |||
| 195 | subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, | ||
| 196 | TIPC_SUBSCR_TIMEOUT, 0, 0); | ||
| 197 | |||
| 200 | /* Now destroy subscription */ | 198 | /* Now destroy subscription */ |
| 201 | 199 | ||
| 202 | tipc_ref_unlock(subscriber_ref); | ||
| 203 | k_term_timer(&sub->timer); | 200 | k_term_timer(&sub->timer); |
| 204 | kfree(sub); | 201 | kfree(sub); |
| 205 | atomic_dec(&topsrv.subscription_count); | 202 | atomic_dec(&topsrv.subscription_count); |
| @@ -208,7 +205,7 @@ static void subscr_timeout(struct subscription *sub) | |||
| 208 | /** | 205 | /** |
| 209 | * subscr_del - delete a subscription within a subscription list | 206 | * subscr_del - delete a subscription within a subscription list |
| 210 | * | 207 | * |
| 211 | * Called with subscriber locked. | 208 | * Called with subscriber port locked. |
| 212 | */ | 209 | */ |
| 213 | 210 | ||
| 214 | static void subscr_del(struct subscription *sub) | 211 | static void subscr_del(struct subscription *sub) |
| @@ -222,7 +219,7 @@ static void subscr_del(struct subscription *sub) | |||
| 222 | /** | 219 | /** |
| 223 | * subscr_terminate - terminate communication with a subscriber | 220 | * subscr_terminate - terminate communication with a subscriber |
| 224 | * | 221 | * |
| 225 | * Called with subscriber locked. Routine must temporarily release this lock | 222 | * Called with subscriber port locked. Routine must temporarily release lock |
| 226 | * to enable subscription timeout routine(s) to finish without deadlocking; | 223 | * to enable subscription timeout routine(s) to finish without deadlocking; |
| 227 | * the lock is then reclaimed to allow caller to release it upon return. | 224 | * the lock is then reclaimed to allow caller to release it upon return. |
| 228 | * (This should work even in the unlikely event some other thread creates | 225 | * (This should work even in the unlikely event some other thread creates |
| @@ -232,14 +229,21 @@ static void subscr_del(struct subscription *sub) | |||
| 232 | 229 | ||
| 233 | static void subscr_terminate(struct subscriber *subscriber) | 230 | static void subscr_terminate(struct subscriber *subscriber) |
| 234 | { | 231 | { |
| 232 | u32 port_ref; | ||
| 235 | struct subscription *sub; | 233 | struct subscription *sub; |
| 236 | struct subscription *sub_temp; | 234 | struct subscription *sub_temp; |
| 237 | 235 | ||
| 238 | /* Invalidate subscriber reference */ | 236 | /* Invalidate subscriber reference */ |
| 239 | 237 | ||
| 240 | tipc_ref_discard(subscriber->ref); | 238 | port_ref = subscriber->port_ref; |
| 239 | subscriber->port_ref = 0; | ||
| 241 | spin_unlock_bh(subscriber->lock); | 240 | spin_unlock_bh(subscriber->lock); |
| 242 | 241 | ||
| 242 | /* Sever connection to subscriber */ | ||
| 243 | |||
| 244 | tipc_shutdown(port_ref); | ||
| 245 | tipc_deleteport(port_ref); | ||
| 246 | |||
| 243 | /* Destroy any existing subscriptions for subscriber */ | 247 | /* Destroy any existing subscriptions for subscriber */ |
| 244 | 248 | ||
| 245 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | 249 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, |
| @@ -253,27 +257,25 @@ static void subscr_terminate(struct subscriber *subscriber) | |||
| 253 | subscr_del(sub); | 257 | subscr_del(sub); |
| 254 | } | 258 | } |
| 255 | 259 | ||
| 256 | /* Sever connection to subscriber */ | ||
| 257 | |||
| 258 | tipc_shutdown(subscriber->port_ref); | ||
| 259 | tipc_deleteport(subscriber->port_ref); | ||
| 260 | |||
| 261 | /* Remove subscriber from topology server's subscriber list */ | 260 | /* Remove subscriber from topology server's subscriber list */ |
| 262 | 261 | ||
| 263 | spin_lock_bh(&topsrv.lock); | 262 | spin_lock_bh(&topsrv.lock); |
| 264 | list_del(&subscriber->subscriber_list); | 263 | list_del(&subscriber->subscriber_list); |
| 265 | spin_unlock_bh(&topsrv.lock); | 264 | spin_unlock_bh(&topsrv.lock); |
| 266 | 265 | ||
| 267 | /* Now destroy subscriber */ | 266 | /* Reclaim subscriber lock */ |
| 268 | 267 | ||
| 269 | spin_lock_bh(subscriber->lock); | 268 | spin_lock_bh(subscriber->lock); |
| 269 | |||
| 270 | /* Now destroy subscriber */ | ||
| 271 | |||
| 270 | kfree(subscriber); | 272 | kfree(subscriber); |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | /** | 275 | /** |
| 274 | * subscr_cancel - handle subscription cancellation request | 276 | * subscr_cancel - handle subscription cancellation request |
| 275 | * | 277 | * |
| 276 | * Called with subscriber locked. Routine must temporarily release this lock | 278 | * Called with subscriber port locked. Routine must temporarily release lock |
| 277 | * to enable the subscription timeout routine to finish without deadlocking; | 279 | * to enable the subscription timeout routine to finish without deadlocking; |
| 278 | * the lock is then reclaimed to allow caller to release it upon return. | 280 | * the lock is then reclaimed to allow caller to release it upon return. |
| 279 | * | 281 | * |
| @@ -316,27 +318,25 @@ static void subscr_cancel(struct tipc_subscr *s, | |||
| 316 | /** | 318 | /** |
| 317 | * subscr_subscribe - create subscription for subscriber | 319 | * subscr_subscribe - create subscription for subscriber |
| 318 | * | 320 | * |
| 319 | * Called with subscriber locked | 321 | * Called with subscriber port locked. |
| 320 | */ | 322 | */ |
| 321 | 323 | ||
| 322 | static void subscr_subscribe(struct tipc_subscr *s, | 324 | static struct subscription *subscr_subscribe(struct tipc_subscr *s, |
| 323 | struct subscriber *subscriber) | 325 | struct subscriber *subscriber) |
| 324 | { | 326 | { |
| 325 | struct subscription *sub; | 327 | struct subscription *sub; |
| 328 | int swap; | ||
| 326 | 329 | ||
| 327 | /* Determine/update subscriber's endianness */ | 330 | /* Determine subscriber's endianness */ |
| 328 | 331 | ||
| 329 | if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) | 332 | swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); |
| 330 | subscriber->swap = 0; | ||
| 331 | else | ||
| 332 | subscriber->swap = 1; | ||
| 333 | 333 | ||
| 334 | /* Detect & process a subscription cancellation request */ | 334 | /* Detect & process a subscription cancellation request */ |
| 335 | 335 | ||
| 336 | if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { | 336 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
| 337 | s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); | 337 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
| 338 | subscr_cancel(s, subscriber); | 338 | subscr_cancel(s, subscriber); |
| 339 | return; | 339 | return NULL; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | /* Refuse subscription if global limit exceeded */ | 342 | /* Refuse subscription if global limit exceeded */ |
| @@ -345,63 +345,66 @@ static void subscr_subscribe(struct tipc_subscr *s, | |||
| 345 | warn("Subscription rejected, subscription limit reached (%u)\n", | 345 | warn("Subscription rejected, subscription limit reached (%u)\n", |
| 346 | tipc_max_subscriptions); | 346 | tipc_max_subscriptions); |
| 347 | subscr_terminate(subscriber); | 347 | subscr_terminate(subscriber); |
| 348 | return; | 348 | return NULL; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | /* Allocate subscription object */ | 351 | /* Allocate subscription object */ |
| 352 | 352 | ||
| 353 | sub = kzalloc(sizeof(*sub), GFP_ATOMIC); | 353 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
| 354 | if (!sub) { | 354 | if (!sub) { |
| 355 | warn("Subscription rejected, no memory\n"); | 355 | warn("Subscription rejected, no memory\n"); |
| 356 | subscr_terminate(subscriber); | 356 | subscr_terminate(subscriber); |
| 357 | return; | 357 | return NULL; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | /* Initialize subscription object */ | 360 | /* Initialize subscription object */ |
| 361 | 361 | ||
| 362 | sub->seq.type = htohl(s->seq.type, subscriber->swap); | 362 | sub->seq.type = htohl(s->seq.type, swap); |
| 363 | sub->seq.lower = htohl(s->seq.lower, subscriber->swap); | 363 | sub->seq.lower = htohl(s->seq.lower, swap); |
| 364 | sub->seq.upper = htohl(s->seq.upper, subscriber->swap); | 364 | sub->seq.upper = htohl(s->seq.upper, swap); |
| 365 | sub->timeout = htohl(s->timeout, subscriber->swap); | 365 | sub->timeout = htohl(s->timeout, swap); |
| 366 | sub->filter = htohl(s->filter, subscriber->swap); | 366 | sub->filter = htohl(s->filter, swap); |
| 367 | if ((!(sub->filter & TIPC_SUB_PORTS) | 367 | if ((!(sub->filter & TIPC_SUB_PORTS) |
| 368 | == !(sub->filter & TIPC_SUB_SERVICE)) | 368 | == !(sub->filter & TIPC_SUB_SERVICE)) |
| 369 | || (sub->seq.lower > sub->seq.upper)) { | 369 | || (sub->seq.lower > sub->seq.upper)) { |
| 370 | warn("Subscription rejected, illegal request\n"); | 370 | warn("Subscription rejected, illegal request\n"); |
| 371 | kfree(sub); | 371 | kfree(sub); |
| 372 | subscr_terminate(subscriber); | 372 | subscr_terminate(subscriber); |
| 373 | return; | 373 | return NULL; |
| 374 | } | 374 | } |
| 375 | memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); | 375 | sub->event_cb = subscr_send_event; |
| 376 | INIT_LIST_HEAD(&sub->subscription_list); | ||
| 377 | INIT_LIST_HEAD(&sub->nameseq_list); | 376 | INIT_LIST_HEAD(&sub->nameseq_list); |
| 378 | list_add(&sub->subscription_list, &subscriber->subscription_list); | 377 | list_add(&sub->subscription_list, &subscriber->subscription_list); |
| 378 | sub->server_ref = subscriber->port_ref; | ||
| 379 | sub->swap = swap; | ||
| 380 | memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); | ||
| 379 | atomic_inc(&topsrv.subscription_count); | 381 | atomic_inc(&topsrv.subscription_count); |
| 380 | if (sub->timeout != TIPC_WAIT_FOREVER) { | 382 | if (sub->timeout != TIPC_WAIT_FOREVER) { |
| 381 | k_init_timer(&sub->timer, | 383 | k_init_timer(&sub->timer, |
| 382 | (Handler)subscr_timeout, (unsigned long)sub); | 384 | (Handler)subscr_timeout, (unsigned long)sub); |
| 383 | k_start_timer(&sub->timer, sub->timeout); | 385 | k_start_timer(&sub->timer, sub->timeout); |
| 384 | } | 386 | } |
| 385 | sub->owner = subscriber; | 387 | |
| 386 | tipc_nametbl_subscribe(sub); | 388 | return sub; |
| 387 | } | 389 | } |
| 388 | 390 | ||
| 389 | /** | 391 | /** |
| 390 | * subscr_conn_shutdown_event - handle termination request from subscriber | 392 | * subscr_conn_shutdown_event - handle termination request from subscriber |
| 393 | * | ||
| 394 | * Called with subscriber's server port unlocked. | ||
| 391 | */ | 395 | */ |
| 392 | 396 | ||
| 393 | static void subscr_conn_shutdown_event(void *usr_handle, | 397 | static void subscr_conn_shutdown_event(void *usr_handle, |
| 394 | u32 portref, | 398 | u32 port_ref, |
| 395 | struct sk_buff **buf, | 399 | struct sk_buff **buf, |
| 396 | unsigned char const *data, | 400 | unsigned char const *data, |
| 397 | unsigned int size, | 401 | unsigned int size, |
| 398 | int reason) | 402 | int reason) |
| 399 | { | 403 | { |
| 400 | struct subscriber *subscriber; | 404 | struct subscriber *subscriber = usr_handle; |
| 401 | spinlock_t *subscriber_lock; | 405 | spinlock_t *subscriber_lock; |
| 402 | 406 | ||
| 403 | subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); | 407 | if (tipc_port_lock(port_ref) == NULL) |
| 404 | if (subscriber == NULL) | ||
| 405 | return; | 408 | return; |
| 406 | 409 | ||
| 407 | subscriber_lock = subscriber->lock; | 410 | subscriber_lock = subscriber->lock; |
| @@ -411,6 +414,8 @@ static void subscr_conn_shutdown_event(void *usr_handle, | |||
| 411 | 414 | ||
| 412 | /** | 415 | /** |
| 413 | * subscr_conn_msg_event - handle new subscription request from subscriber | 416 | * subscr_conn_msg_event - handle new subscription request from subscriber |
| 417 | * | ||
| 418 | * Called with subscriber's server port unlocked. | ||
| 414 | */ | 419 | */ |
| 415 | 420 | ||
| 416 | static void subscr_conn_msg_event(void *usr_handle, | 421 | static void subscr_conn_msg_event(void *usr_handle, |
| @@ -419,20 +424,46 @@ static void subscr_conn_msg_event(void *usr_handle, | |||
| 419 | const unchar *data, | 424 | const unchar *data, |
| 420 | u32 size) | 425 | u32 size) |
| 421 | { | 426 | { |
| 422 | struct subscriber *subscriber; | 427 | struct subscriber *subscriber = usr_handle; |
| 423 | spinlock_t *subscriber_lock; | 428 | spinlock_t *subscriber_lock; |
| 429 | struct subscription *sub; | ||
| 430 | |||
| 431 | /* | ||
| 432 | * Lock subscriber's server port (& make a local copy of lock pointer, | ||
| 433 | * in case subscriber is deleted while processing subscription request) | ||
| 434 | */ | ||
| 424 | 435 | ||
| 425 | subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); | 436 | if (tipc_port_lock(port_ref) == NULL) |
| 426 | if (subscriber == NULL) | ||
| 427 | return; | 437 | return; |
| 428 | 438 | ||
| 429 | subscriber_lock = subscriber->lock; | 439 | subscriber_lock = subscriber->lock; |
| 430 | if (size != sizeof(struct tipc_subscr)) | ||
| 431 | subscr_terminate(subscriber); | ||
| 432 | else | ||
| 433 | subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
| 434 | 440 | ||
| 435 | spin_unlock_bh(subscriber_lock); | 441 | if (size != sizeof(struct tipc_subscr)) { |
| 442 | subscr_terminate(subscriber); | ||
| 443 | spin_unlock_bh(subscriber_lock); | ||
| 444 | } else { | ||
| 445 | sub = subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
| 446 | spin_unlock_bh(subscriber_lock); | ||
| 447 | if (sub != NULL) { | ||
| 448 | |||
| 449 | /* | ||
| 450 | * We must release the server port lock before adding a | ||
| 451 | * subscription to the name table since TIPC needs to be | ||
| 452 | * able to (re)acquire the port lock if an event message | ||
| 453 | * issued by the subscription process is rejected and | ||
| 454 | * returned. The subscription cannot be deleted while | ||
| 455 | * it is being added to the name table because: | ||
| 456 | * a) the single-threading of the native API port code | ||
| 457 | * ensures the subscription cannot be cancelled and | ||
| 458 | * the subscriber connection cannot be broken, and | ||
| 459 | * b) the name table lock ensures the subscription | ||
| 460 | * timeout code cannot delete the subscription, | ||
| 461 | * so the subscription object is still protected. | ||
| 462 | */ | ||
| 463 | |||
| 464 | tipc_nametbl_subscribe(sub); | ||
| 465 | } | ||
| 466 | } | ||
| 436 | } | 467 | } |
| 437 | 468 | ||
| 438 | /** | 469 | /** |
| @@ -448,16 +479,10 @@ static void subscr_named_msg_event(void *usr_handle, | |||
| 448 | struct tipc_portid const *orig, | 479 | struct tipc_portid const *orig, |
| 449 | struct tipc_name_seq const *dest) | 480 | struct tipc_name_seq const *dest) |
| 450 | { | 481 | { |
| 451 | struct subscriber *subscriber; | 482 | static struct iovec msg_sect = {NULL, 0}; |
| 452 | struct iovec msg_sect = {NULL, 0}; | ||
| 453 | spinlock_t *subscriber_lock; | ||
| 454 | 483 | ||
| 455 | dbg("subscr_named_msg_event: orig = %x own = %x,\n", | 484 | struct subscriber *subscriber; |
| 456 | orig->node, tipc_own_addr); | 485 | u32 server_port_ref; |
| 457 | if (size && (size != sizeof(struct tipc_subscr))) { | ||
| 458 | warn("Subscriber rejected, invalid subscription size\n"); | ||
| 459 | return; | ||
| 460 | } | ||
| 461 | 486 | ||
| 462 | /* Create subscriber object */ | 487 | /* Create subscriber object */ |
| 463 | 488 | ||
| @@ -468,17 +493,11 @@ static void subscr_named_msg_event(void *usr_handle, | |||
| 468 | } | 493 | } |
| 469 | INIT_LIST_HEAD(&subscriber->subscription_list); | 494 | INIT_LIST_HEAD(&subscriber->subscription_list); |
| 470 | INIT_LIST_HEAD(&subscriber->subscriber_list); | 495 | INIT_LIST_HEAD(&subscriber->subscriber_list); |
| 471 | subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock); | ||
| 472 | if (subscriber->ref == 0) { | ||
| 473 | warn("Subscriber rejected, reference table exhausted\n"); | ||
| 474 | kfree(subscriber); | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | 496 | ||
| 478 | /* Establish a connection to subscriber */ | 497 | /* Create server port & establish connection to subscriber */ |
| 479 | 498 | ||
| 480 | tipc_createport(topsrv.user_ref, | 499 | tipc_createport(topsrv.user_ref, |
| 481 | (void *)(unsigned long)subscriber->ref, | 500 | subscriber, |
| 482 | importance, | 501 | importance, |
| 483 | NULL, | 502 | NULL, |
| 484 | NULL, | 503 | NULL, |
| @@ -490,32 +509,36 @@ static void subscr_named_msg_event(void *usr_handle, | |||
| 490 | &subscriber->port_ref); | 509 | &subscriber->port_ref); |
| 491 | if (subscriber->port_ref == 0) { | 510 | if (subscriber->port_ref == 0) { |
| 492 | warn("Subscriber rejected, unable to create port\n"); | 511 | warn("Subscriber rejected, unable to create port\n"); |
| 493 | tipc_ref_discard(subscriber->ref); | ||
| 494 | kfree(subscriber); | 512 | kfree(subscriber); |
| 495 | return; | 513 | return; |
| 496 | } | 514 | } |
| 497 | tipc_connect2port(subscriber->port_ref, orig); | 515 | tipc_connect2port(subscriber->port_ref, orig); |
| 498 | 516 | ||
| 517 | /* Lock server port (& save lock address for future use) */ | ||
| 518 | |||
| 519 | subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; | ||
| 499 | 520 | ||
| 500 | /* Add subscriber to topology server's subscriber list */ | 521 | /* Add subscriber to topology server's subscriber list */ |
| 501 | 522 | ||
| 502 | tipc_ref_lock(subscriber->ref); | ||
| 503 | spin_lock_bh(&topsrv.lock); | 523 | spin_lock_bh(&topsrv.lock); |
| 504 | list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); | 524 | list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); |
| 505 | spin_unlock_bh(&topsrv.lock); | 525 | spin_unlock_bh(&topsrv.lock); |
| 506 | 526 | ||
| 507 | /* | 527 | /* Unlock server port */ |
| 508 | * Subscribe now if message contains a subscription, | ||
| 509 | * otherwise send an empty response to complete connection handshaking | ||
| 510 | */ | ||
| 511 | 528 | ||
| 512 | subscriber_lock = subscriber->lock; | 529 | server_port_ref = subscriber->port_ref; |
| 513 | if (size) | 530 | spin_unlock_bh(subscriber->lock); |
| 514 | subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
| 515 | else | ||
| 516 | tipc_send(subscriber->port_ref, 1, &msg_sect); | ||
| 517 | 531 | ||
| 518 | spin_unlock_bh(subscriber_lock); | 532 | /* Send an ACK- to complete connection handshaking */ |
| 533 | |||
| 534 | tipc_send(server_port_ref, 1, &msg_sect); | ||
| 535 | |||
| 536 | /* Handle optional subscription request */ | ||
| 537 | |||
| 538 | if (size != 0) { | ||
| 539 | subscr_conn_msg_event(subscriber, server_port_ref, | ||
| 540 | buf, data, size); | ||
| 541 | } | ||
| 519 | } | 542 | } |
| 520 | 543 | ||
| 521 | int tipc_subscr_start(void) | 544 | int tipc_subscr_start(void) |
| @@ -574,8 +597,8 @@ void tipc_subscr_stop(void) | |||
| 574 | list_for_each_entry_safe(subscriber, subscriber_temp, | 597 | list_for_each_entry_safe(subscriber, subscriber_temp, |
| 575 | &topsrv.subscriber_list, | 598 | &topsrv.subscriber_list, |
| 576 | subscriber_list) { | 599 | subscriber_list) { |
| 577 | tipc_ref_lock(subscriber->ref); | ||
| 578 | subscriber_lock = subscriber->lock; | 600 | subscriber_lock = subscriber->lock; |
| 601 | spin_lock_bh(subscriber_lock); | ||
| 579 | subscr_terminate(subscriber); | 602 | subscr_terminate(subscriber); |
| 580 | spin_unlock_bh(subscriber_lock); | 603 | spin_unlock_bh(subscriber_lock); |
| 581 | } | 604 | } |
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index 93a8e674fac1..45d89bf4d202 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * net/tipc/subscr.h: Include file for TIPC subscription service | 2 | * net/tipc/subscr.h: Include file for TIPC network topology service |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2003-2006, Ericsson AB | 4 | * Copyright (c) 2003-2006, Ericsson AB |
| 5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, 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 |
| @@ -37,34 +37,44 @@ | |||
| 37 | #ifndef _TIPC_SUBSCR_H | 37 | #ifndef _TIPC_SUBSCR_H |
| 38 | #define _TIPC_SUBSCR_H | 38 | #define _TIPC_SUBSCR_H |
| 39 | 39 | ||
| 40 | struct subscription; | ||
| 41 | |||
| 42 | typedef void (*tipc_subscr_event) (struct subscription *sub, | ||
| 43 | u32 found_lower, u32 found_upper, | ||
| 44 | u32 event, u32 port_ref, u32 node); | ||
| 45 | |||
| 40 | /** | 46 | /** |
| 41 | * struct subscription - TIPC network topology subscription object | 47 | * struct subscription - TIPC network topology subscription object |
| 42 | * @seq: name sequence associated with subscription | 48 | * @seq: name sequence associated with subscription |
| 43 | * @timeout: duration of subscription (in ms) | 49 | * @timeout: duration of subscription (in ms) |
| 44 | * @filter: event filtering to be done for subscription | 50 | * @filter: event filtering to be done for subscription |
| 45 | * @evt: template for events generated by subscription | 51 | * @event_cb: routine invoked when a subscription event is detected |
| 46 | * @subscription_list: adjacent subscriptions in subscriber's subscription list | 52 | * @timer: timer governing subscription duration (optional) |
| 47 | * @nameseq_list: adjacent subscriptions in name sequence's subscription list | 53 | * @nameseq_list: adjacent subscriptions in name sequence's subscription list |
| 48 | * @timer_ref: reference to timer governing subscription duration (may be NULL) | 54 | * @subscription_list: adjacent subscriptions in subscriber's subscription list |
| 49 | * @owner: pointer to subscriber object associated with this subscription | 55 | * @server_ref: object reference of server port associated with subscription |
| 56 | * @swap: indicates if subscriber uses opposite endianness in its messages | ||
| 57 | * @evt: template for events generated by subscription | ||
| 50 | */ | 58 | */ |
| 51 | 59 | ||
| 52 | struct subscription { | 60 | struct subscription { |
| 53 | struct tipc_name_seq seq; | 61 | struct tipc_name_seq seq; |
| 54 | u32 timeout; | 62 | u32 timeout; |
| 55 | u32 filter; | 63 | u32 filter; |
| 56 | struct tipc_event evt; | 64 | tipc_subscr_event event_cb; |
| 57 | struct list_head subscription_list; | ||
| 58 | struct list_head nameseq_list; | ||
| 59 | struct timer_list timer; | 65 | struct timer_list timer; |
| 60 | struct subscriber *owner; | 66 | struct list_head nameseq_list; |
| 67 | struct list_head subscription_list; | ||
| 68 | u32 server_ref; | ||
| 69 | int swap; | ||
| 70 | struct tipc_event evt; | ||
| 61 | }; | 71 | }; |
| 62 | 72 | ||
| 63 | int tipc_subscr_overlap(struct subscription * sub, | 73 | int tipc_subscr_overlap(struct subscription *sub, |
| 64 | u32 found_lower, | 74 | u32 found_lower, |
| 65 | u32 found_upper); | 75 | u32 found_upper); |
| 66 | 76 | ||
| 67 | void tipc_subscr_report_overlap(struct subscription * sub, | 77 | void tipc_subscr_report_overlap(struct subscription *sub, |
| 68 | u32 found_lower, | 78 | u32 found_lower, |
| 69 | u32 found_upper, | 79 | u32 found_upper, |
| 70 | u32 event, | 80 | u32 event, |
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c index 4146c40cd20b..506928803162 100644 --- a/net/tipc/user_reg.c +++ b/net/tipc/user_reg.c | |||
| @@ -91,7 +91,7 @@ static int reg_init(void) | |||
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | spin_unlock_bh(®_lock); | 93 | spin_unlock_bh(®_lock); |
| 94 | return users ? TIPC_OK : -ENOMEM; | 94 | return users ? 0 : -ENOMEM; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | /** | 97 | /** |
| @@ -129,7 +129,7 @@ int tipc_reg_start(void) | |||
| 129 | tipc_k_signal((Handler)reg_callback, | 129 | tipc_k_signal((Handler)reg_callback, |
| 130 | (unsigned long)&users[u]); | 130 | (unsigned long)&users[u]); |
| 131 | } | 131 | } |
| 132 | return TIPC_OK; | 132 | return 0; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | /** | 135 | /** |
| @@ -184,7 +184,7 @@ int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle) | |||
| 184 | 184 | ||
| 185 | if (cb && (tipc_mode != TIPC_NOT_RUNNING)) | 185 | if (cb && (tipc_mode != TIPC_NOT_RUNNING)) |
| 186 | tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); | 186 | tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); |
| 187 | return TIPC_OK; | 187 | return 0; |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | /** | 190 | /** |
| @@ -230,7 +230,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
| 230 | struct tipc_user *user_ptr; | 230 | struct tipc_user *user_ptr; |
| 231 | 231 | ||
| 232 | if (up_ptr->user_ref == 0) | 232 | if (up_ptr->user_ref == 0) |
| 233 | return TIPC_OK; | 233 | return 0; |
| 234 | if (up_ptr->user_ref > MAX_USERID) | 234 | if (up_ptr->user_ref > MAX_USERID) |
| 235 | return -EINVAL; | 235 | return -EINVAL; |
| 236 | if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) | 236 | if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) |
| @@ -240,7 +240,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
| 240 | user_ptr = &users[up_ptr->user_ref]; | 240 | user_ptr = &users[up_ptr->user_ref]; |
| 241 | list_add(&up_ptr->uport_list, &user_ptr->ports); | 241 | list_add(&up_ptr->uport_list, &user_ptr->ports); |
| 242 | spin_unlock_bh(®_lock); | 242 | spin_unlock_bh(®_lock); |
| 243 | return TIPC_OK; | 243 | return 0; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | /** | 246 | /** |
| @@ -250,7 +250,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
| 250 | int tipc_reg_remove_port(struct user_port *up_ptr) | 250 | int tipc_reg_remove_port(struct user_port *up_ptr) |
| 251 | { | 251 | { |
| 252 | if (up_ptr->user_ref == 0) | 252 | if (up_ptr->user_ref == 0) |
| 253 | return TIPC_OK; | 253 | return 0; |
| 254 | if (up_ptr->user_ref > MAX_USERID) | 254 | if (up_ptr->user_ref > MAX_USERID) |
| 255 | return -EINVAL; | 255 | return -EINVAL; |
| 256 | if (!users ) | 256 | if (!users ) |
| @@ -259,6 +259,6 @@ int tipc_reg_remove_port(struct user_port *up_ptr) | |||
| 259 | spin_lock_bh(®_lock); | 259 | spin_lock_bh(®_lock); |
| 260 | list_del_init(&up_ptr->uport_list); | 260 | list_del_init(&up_ptr->uport_list); |
| 261 | spin_unlock_bh(®_lock); | 261 | spin_unlock_bh(®_lock); |
| 262 | return TIPC_OK; | 262 | return 0; |
| 263 | } | 263 | } |
| 264 | 264 | ||
