Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'tipc-Mar13-2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/net-next-2.6

+279 -395
+2 -4
MAINTAINERS
··· 6083 6083 TIPC NETWORK LAYER 6084 6084 M: Jon Maloy <jon.maloy@ericsson.com> 6085 6085 M: Allan Stephens <allan.stephens@windriver.com> 6086 - L: tipc-discussion@lists.sourceforge.net 6086 + L: netdev@vger.kernel.org (core kernel code) 6087 + L: tipc-discussion@lists.sourceforge.net (user apps, general discussion) 6087 6088 W: http://tipc.sourceforge.net/ 6088 - W: http://tipc.cslab.ericsson.net/ 6089 - T: git git://tipc.cslab.ericsson.net/pub/git/tipc.git 6090 6089 S: Maintained 6091 6090 F: include/linux/tipc*.h 6092 - F: include/net/tipc/ 6093 6091 F: net/tipc/ 6094 6092 6095 6093 TILE ARCHITECTURE
+3 -3
include/linux/tipc_config.h
··· 89 89 #define TIPC_CMD_GET_MAX_SUBSCR 0x4006 /* tx none, rx unsigned */ 90 90 #define TIPC_CMD_GET_MAX_ZONES 0x4007 /* obsoleted */ 91 91 #define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* obsoleted */ 92 - #define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */ 92 + #define TIPC_CMD_GET_MAX_NODES 0x4009 /* obsoleted */ 93 93 #define TIPC_CMD_GET_MAX_SLAVES 0x400A /* obsoleted */ 94 94 #define TIPC_CMD_GET_NETID 0x400B /* tx none, rx unsigned */ 95 95 ··· 115 115 #define TIPC_CMD_SET_MAX_SUBSCR 0x8006 /* tx unsigned, rx none */ 116 116 #define TIPC_CMD_SET_MAX_ZONES 0x8007 /* obsoleted */ 117 117 #define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* obsoleted */ 118 - #define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */ 118 + #define TIPC_CMD_SET_MAX_NODES 0x8009 /* obsoleted */ 119 119 #define TIPC_CMD_SET_MAX_SLAVES 0x800A /* obsoleted */ 120 120 #define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */ 121 121 ··· 202 202 203 203 struct tipc_bearer_config { 204 204 __be32 priority; /* Range [1,31]. Override per link */ 205 - __be32 detect_scope; 205 + __be32 disc_domain; /* <Z.C.N> describing desired nodes */ 206 206 char name[TIPC_MAX_BEARER_NAME]; 207 207 }; 208 208
-12
net/tipc/Kconfig
··· 29 29 Saying Y here will open some advanced configuration for TIPC. 30 30 Most users do not need to bother; if unsure, just say N. 31 31 32 - config TIPC_NODES 33 - int "Maximum number of nodes in a cluster" 34 - depends on TIPC_ADVANCED 35 - range 8 2047 36 - default "255" 37 - help 38 - Specifies how many nodes can be supported in a TIPC cluster. 39 - Can range from 8 to 2047 nodes; default is 255. 40 - 41 - Setting this to a smaller value saves some memory; 42 - setting it to higher allows for more nodes. 43 - 44 32 config TIPC_PORTS 45 33 int "Maximum number of ports in a node" 46 34 depends on TIPC_ADVANCED
+5 -10
net/tipc/addr.c
··· 2 2 * net/tipc/addr.c: TIPC address utility routines 3 3 * 4 4 * Copyright (c) 2000-2006, Ericsson AB 5 - * Copyright (c) 2004-2005, Wind River Systems 5 + * Copyright (c) 2004-2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 41 41 * tipc_addr_domain_valid - validates a network domain address 42 42 * 43 43 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 44 - * where Z, C, and N are non-zero and do not exceed the configured limits. 44 + * where Z, C, and N are non-zero. 45 45 * 46 46 * Returns 1 if domain address is valid, otherwise 0 47 47 */ ··· 51 51 u32 n = tipc_node(addr); 52 52 u32 c = tipc_cluster(addr); 53 53 u32 z = tipc_zone(addr); 54 - u32 max_nodes = tipc_max_nodes; 55 - 56 - if (n > max_nodes) 57 - return 0; 58 54 59 55 if (n && (!z || !c)) 60 56 return 0; ··· 62 66 /** 63 67 * tipc_addr_node_valid - validates a proposed network address for this node 64 68 * 65 - * Accepts <Z.C.N>, where Z, C, and N are non-zero and do not exceed 66 - * the configured limits. 69 + * Accepts <Z.C.N>, where Z, C, and N are non-zero. 67 70 * 68 71 * Returns 1 if address can be used, otherwise 0 69 72 */ ··· 76 81 { 77 82 if (!domain || (domain == addr)) 78 83 return 1; 79 - if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */ 84 + if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */ 80 85 return 1; 81 - if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */ 86 + if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */ 82 87 return 1; 83 88 return 0; 84 89 }
+13 -4
net/tipc/addr.h
··· 37 37 #ifndef _TIPC_ADDR_H 38 38 #define _TIPC_ADDR_H 39 39 40 + static inline u32 tipc_zone_mask(u32 addr) 41 + { 42 + return addr & 0xff000000u; 43 + } 44 + 45 + static inline u32 tipc_cluster_mask(u32 addr) 46 + { 47 + return addr & 0xfffff000u; 48 + } 49 + 40 50 static inline int in_own_cluster(u32 addr) 41 51 { 42 52 return !((addr ^ tipc_own_addr) >> 12); ··· 59 49 * after a network hop. 60 50 */ 61 51 62 - static inline int addr_domain(int sc) 52 + static inline u32 addr_domain(u32 sc) 63 53 { 64 54 if (likely(sc == TIPC_NODE_SCOPE)) 65 55 return tipc_own_addr; 66 56 if (sc == TIPC_CLUSTER_SCOPE) 67 - return tipc_addr(tipc_zone(tipc_own_addr), 68 - tipc_cluster(tipc_own_addr), 0); 69 - return tipc_addr(tipc_zone(tipc_own_addr), 0, 0); 57 + return tipc_cluster_mask(tipc_own_addr); 58 + return tipc_zone_mask(tipc_own_addr); 70 59 } 71 60 72 61 int tipc_addr_domain_valid(u32);
+7 -11
net/tipc/bearer.c
··· 158 158 m_ptr->disable_bearer = disable; 159 159 m_ptr->addr2str = addr2str; 160 160 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 161 - m_ptr->bcast = 1; 162 161 strcpy(m_ptr->name, name); 163 162 m_ptr->priority = bearer_priority; 164 163 m_ptr->tolerance = link_tolerance; ··· 473 474 * tipc_enable_bearer - enable bearer with the given name 474 475 */ 475 476 476 - int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 477 + int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) 477 478 { 478 479 struct tipc_bearer *b_ptr; 479 480 struct media *m_ptr; ··· 493 494 warn("Bearer <%s> rejected, illegal name\n", name); 494 495 return -EINVAL; 495 496 } 496 - if (!tipc_addr_domain_valid(bcast_scope) || 497 - !tipc_in_scope(bcast_scope, tipc_own_addr)) { 498 - warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 497 + if (!tipc_addr_domain_valid(disc_domain) || 498 + !tipc_in_scope(disc_domain, tipc_own_addr)) { 499 + warn("Bearer <%s> rejected, illegal discovery domain\n", name); 499 500 return -EINVAL; 500 501 } 501 502 if ((priority < TIPC_MIN_LINK_PRI || ··· 559 560 b_ptr->media = m_ptr; 560 561 b_ptr->net_plane = bearer_id + 'A'; 561 562 b_ptr->active = 1; 562 - b_ptr->detect_scope = bcast_scope; 563 563 b_ptr->priority = priority; 564 564 INIT_LIST_HEAD(&b_ptr->cong_links); 565 565 INIT_LIST_HEAD(&b_ptr->links); 566 - if (m_ptr->bcast) { 567 - b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 568 - bcast_scope); 569 - } 566 + b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 567 + disc_domain); 570 568 spin_lock_init(&b_ptr->lock); 571 569 write_unlock_bh(&tipc_net_lock); 572 570 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 573 - name, tipc_addr_string_fill(addr_string, bcast_scope), priority); 571 + name, tipc_addr_string_fill(addr_string, disc_domain), priority); 574 572 return 0; 575 573 failed: 576 574 write_unlock_bh(&tipc_net_lock);
+1 -5
net/tipc/bearer.h
··· 70 70 * @disable_bearer: routine which disables a bearer 71 71 * @addr2str: routine which converts bearer's address to string form 72 72 * @bcast_addr: media address used in broadcasting 73 - * @bcast: non-zero if media supports broadcasting [currently mandatory] 74 73 * @priority: default link (and bearer) priority 75 74 * @tolerance: default time (in ms) before declaring link failure 76 75 * @window: default window (in packets) before declaring link congestion ··· 86 87 char *(*addr2str)(struct tipc_media_addr *a, 87 88 char *str_buf, int str_size); 88 89 struct tipc_media_addr bcast_addr; 89 - int bcast; 90 90 u32 priority; 91 91 u32 tolerance; 92 92 u32 window; ··· 103 105 * @name: bearer name (format = media:interface) 104 106 * @media: ptr to media structure associated with bearer 105 107 * @priority: default link priority for bearer 106 - * @detect_scope: network address mask used during automatic link creation 107 108 * @identity: array index of this bearer within TIPC bearer array 108 109 * @link_req: ptr to (optional) structure making periodic link setup requests 109 110 * @links: list of non-congested links associated with bearer ··· 125 128 spinlock_t lock; 126 129 struct media *media; 127 130 u32 priority; 128 - u32 detect_scope; 129 131 u32 identity; 130 132 struct link_req *link_req; 131 133 struct list_head links; ··· 163 167 int tipc_block_bearer(const char *name); 164 168 void tipc_continue(struct tipc_bearer *tb_ptr); 165 169 166 - int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority); 170 + int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority); 167 171 int tipc_disable_bearer(const char *name); 168 172 169 173 /*
+4 -27
net/tipc/config.c
··· 2 2 * net/tipc/config.c: TIPC configuration management code 3 3 * 4 4 * Copyright (c) 2002-2006, Ericsson AB 5 - * Copyright (c) 2004-2007, Wind River Systems 5 + * Copyright (c) 2004-2007, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 148 148 149 149 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); 150 150 if (tipc_enable_bearer(args->name, 151 - ntohl(args->detect_scope), 151 + ntohl(args->disc_domain), 152 152 ntohl(args->priority))) 153 153 return tipc_cfg_reply_error_string("unable to enable bearer"); 154 154 ··· 257 257 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 258 258 " (cannot change max ports while TIPC is active)"); 259 259 tipc_max_ports = value; 260 - return tipc_cfg_reply_none(); 261 - } 262 - 263 - static struct sk_buff *cfg_set_max_nodes(void) 264 - { 265 - u32 value; 266 - 267 - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 268 - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 269 - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 270 - if (value == tipc_max_nodes) 271 - return tipc_cfg_reply_none(); 272 - if (value != delimit(value, 8, 2047)) 273 - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 274 - " (max nodes must be 8-2047)"); 275 - if (tipc_mode == TIPC_NET_MODE) 276 - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 277 - " (cannot change max nodes once TIPC has joined a network)"); 278 - tipc_max_nodes = value; 279 260 return tipc_cfg_reply_none(); 280 261 } 281 262 ··· 378 397 case TIPC_CMD_SET_MAX_SUBSCR: 379 398 rep_tlv_buf = cfg_set_max_subscriptions(); 380 399 break; 381 - case TIPC_CMD_SET_MAX_NODES: 382 - rep_tlv_buf = cfg_set_max_nodes(); 383 - break; 384 400 case TIPC_CMD_SET_NETID: 385 401 rep_tlv_buf = cfg_set_netid(); 386 402 break; ··· 393 415 case TIPC_CMD_GET_MAX_SUBSCR: 394 416 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 395 417 break; 396 - case TIPC_CMD_GET_MAX_NODES: 397 - rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes); 398 - break; 399 418 case TIPC_CMD_GET_NETID: 400 419 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 401 420 break; ··· 406 431 case TIPC_CMD_GET_MAX_SLAVES: 407 432 case TIPC_CMD_SET_MAX_CLUSTERS: 408 433 case TIPC_CMD_GET_MAX_CLUSTERS: 434 + case TIPC_CMD_SET_MAX_NODES: 435 + case TIPC_CMD_GET_MAX_NODES: 409 436 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 410 437 " (obsolete command)"); 411 438 break;
-6
net/tipc/core.c
··· 41 41 #include "config.h" 42 42 43 43 44 - #ifndef CONFIG_TIPC_NODES 45 - #define CONFIG_TIPC_NODES 255 46 - #endif 47 - 48 44 #ifndef CONFIG_TIPC_PORTS 49 45 #define CONFIG_TIPC_PORTS 8191 50 46 #endif ··· 60 64 /* configurable TIPC parameters */ 61 65 62 66 u32 tipc_own_addr; 63 - int tipc_max_nodes; 64 67 int tipc_max_ports; 65 68 int tipc_max_subscriptions; 66 69 int tipc_max_publications; ··· 187 192 tipc_max_publications = 10000; 188 193 tipc_max_subscriptions = 2000; 189 194 tipc_max_ports = CONFIG_TIPC_PORTS; 190 - tipc_max_nodes = CONFIG_TIPC_NODES; 191 195 tipc_net_id = 4711; 192 196 193 197 res = tipc_core_start();
-1
net/tipc/core.h
··· 147 147 */ 148 148 149 149 extern u32 tipc_own_addr; 150 - extern int tipc_max_nodes; 151 150 extern int tipc_max_ports; 152 151 extern int tipc_max_subscriptions; 153 152 extern int tipc_max_publications;
+61 -44
net/tipc/discover.c
··· 75 75 u32 dest_domain, 76 76 struct tipc_bearer *b_ptr) 77 77 { 78 - struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE); 78 + struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE); 79 79 struct tipc_msg *msg; 80 80 81 81 if (buf) { 82 82 msg = buf_msg(buf); 83 - tipc_msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); 83 + tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain); 84 84 msg_set_non_seq(msg, 1); 85 85 msg_set_dest_domain(msg, dest_domain); 86 86 msg_set_bc_netid(msg, tipc_net_id); ··· 119 119 120 120 void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr) 121 121 { 122 + struct tipc_node *n_ptr; 122 123 struct link *link; 123 - struct tipc_media_addr media_addr; 124 + struct tipc_media_addr media_addr, *addr; 125 + struct sk_buff *rbuf; 124 126 struct tipc_msg *msg = buf_msg(buf); 125 127 u32 dest = msg_dest_domain(msg); 126 128 u32 orig = msg_prevnode(msg); 127 129 u32 net_id = msg_bc_netid(msg); 128 130 u32 type = msg_type(msg); 131 + int link_fully_up; 129 132 130 133 msg_get_media_addr(msg, &media_addr); 131 134 buf_discard(buf); 132 135 136 + /* Validate discovery message from requesting node */ 133 137 if (net_id != tipc_net_id) 134 138 return; 135 139 if (!tipc_addr_domain_valid(dest)) ··· 147 143 } 148 144 if (!tipc_in_scope(dest, tipc_own_addr)) 149 145 return; 150 - if (in_own_cluster(orig)) { 151 - /* Always accept link here */ 152 - struct sk_buff *rbuf; 153 - struct tipc_media_addr *addr; 154 - struct tipc_node *n_ptr = tipc_node_find(orig); 155 - int link_fully_up; 146 + if (!in_own_cluster(orig)) 147 + return; 156 148 157 - if (n_ptr == NULL) { 158 - n_ptr = tipc_node_create(orig); 159 - if (!n_ptr) 160 - return; 161 - } 162 - spin_lock_bh(&n_ptr->lock); 163 - 164 - /* Don't talk to neighbor during cleanup after last session */ 165 - 166 - if (n_ptr->cleanup_required) { 167 - spin_unlock_bh(&n_ptr->lock); 149 + /* Locate structure corresponding to requesting node */ 150 + n_ptr = tipc_node_find(orig); 151 + if (!n_ptr) { 152 + n_ptr = tipc_node_create(orig); 153 + if (!n_ptr) 168 154 return; 169 - } 155 + } 156 + tipc_node_lock(n_ptr); 170 157 171 - link = n_ptr->links[b_ptr->identity]; 158 + /* Don't talk to neighbor during cleanup after last session */ 159 + if (n_ptr->cleanup_required) { 160 + tipc_node_unlock(n_ptr); 161 + return; 162 + } 163 + 164 + link = n_ptr->links[b_ptr->identity]; 165 + 166 + /* Create a link endpoint for this bearer, if necessary */ 167 + if (!link) { 168 + link = tipc_link_create(n_ptr, b_ptr, &media_addr); 172 169 if (!link) { 173 - link = tipc_link_create(b_ptr, orig, &media_addr); 174 - if (!link) { 175 - spin_unlock_bh(&n_ptr->lock); 176 - return; 177 - } 178 - } 179 - addr = &link->media_addr; 180 - if (memcmp(addr, &media_addr, sizeof(*addr))) { 181 - if (tipc_link_is_up(link) || (!link->started)) { 182 - disc_dupl_alert(b_ptr, orig, &media_addr); 183 - spin_unlock_bh(&n_ptr->lock); 184 - return; 185 - } 186 - warn("Resetting link <%s>, peer interface address changed\n", 187 - link->name); 188 - memcpy(addr, &media_addr, sizeof(*addr)); 189 - tipc_link_reset(link); 190 - } 191 - link_fully_up = link_working_working(link); 192 - spin_unlock_bh(&n_ptr->lock); 193 - if ((type == DSC_RESP_MSG) || link_fully_up) 170 + tipc_node_unlock(n_ptr); 194 171 return; 172 + } 173 + } 174 + 175 + /* 176 + * Ensure requesting node's media address is correct 177 + * 178 + * If media address doesn't match and the link is working, reject the 179 + * request (must be from a duplicate node). 180 + * 181 + * If media address doesn't match and the link is not working, accept 182 + * the new media address and reset the link to ensure it starts up 183 + * cleanly. 184 + */ 185 + addr = &link->media_addr; 186 + if (memcmp(addr, &media_addr, sizeof(*addr))) { 187 + if (tipc_link_is_up(link) || (!link->started)) { 188 + disc_dupl_alert(b_ptr, orig, &media_addr); 189 + tipc_node_unlock(n_ptr); 190 + return; 191 + } 192 + warn("Resetting link <%s>, peer interface address changed\n", 193 + link->name); 194 + memcpy(addr, &media_addr, sizeof(*addr)); 195 + tipc_link_reset(link); 196 + } 197 + 198 + /* Accept discovery message & send response, if necessary */ 199 + link_fully_up = link_working_working(link); 200 + 201 + if ((type == DSC_REQ_MSG) && !link_fully_up && !b_ptr->blocked) { 195 202 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr); 196 - if (rbuf != NULL) { 203 + if (rbuf) { 197 204 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr); 198 205 buf_discard(rbuf); 199 206 } 200 207 } 208 + 209 + tipc_node_unlock(n_ptr); 201 210 } 202 211 203 212 /**
+29 -21
net/tipc/link.c
··· 293 293 294 294 /** 295 295 * tipc_link_create - create a new link 296 + * @n_ptr: pointer to associated node 296 297 * @b_ptr: pointer to associated bearer 297 - * @peer: network address of node at other end of link 298 298 * @media_addr: media address to use when sending messages over link 299 299 * 300 300 * Returns pointer to link. 301 301 */ 302 302 303 - struct link *tipc_link_create(struct tipc_bearer *b_ptr, const u32 peer, 303 + struct link *tipc_link_create(struct tipc_node *n_ptr, 304 + struct tipc_bearer *b_ptr, 304 305 const struct tipc_media_addr *media_addr) 305 306 { 306 307 struct link *l_ptr; 307 308 struct tipc_msg *msg; 308 309 char *if_name; 310 + char addr_string[16]; 311 + u32 peer = n_ptr->addr; 312 + 313 + if (n_ptr->link_cnt >= 2) { 314 + tipc_addr_string_fill(addr_string, n_ptr->addr); 315 + err("Attempt to establish third link to %s\n", addr_string); 316 + return NULL; 317 + } 318 + 319 + if (n_ptr->links[b_ptr->identity]) { 320 + tipc_addr_string_fill(addr_string, n_ptr->addr); 321 + err("Attempt to establish second link on <%s> to %s\n", 322 + b_ptr->name, addr_string); 323 + return NULL; 324 + } 309 325 310 326 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 311 327 if (!l_ptr) { ··· 338 322 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 339 323 /* note: peer i/f is appended to link name by reset/activate */ 340 324 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 325 + l_ptr->owner = n_ptr; 341 326 l_ptr->checkpoint = 1; 342 327 l_ptr->b_ptr = b_ptr; 343 328 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); ··· 362 345 363 346 link_reset_statistics(l_ptr); 364 347 365 - l_ptr->owner = tipc_node_attach_link(l_ptr); 366 - if (!l_ptr->owner) { 367 - kfree(l_ptr); 368 - return NULL; 369 - } 348 + tipc_node_attach_link(n_ptr, l_ptr); 370 349 371 350 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 372 351 list_add_tail(&l_ptr->link_list, &b_ptr->links); ··· 561 548 tipc_node_link_down(l_ptr->owner, l_ptr); 562 549 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 563 550 564 - if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && 551 + if (was_active_link && tipc_node_active_links(l_ptr->owner) && 565 552 l_ptr->owner->permit_changeover) { 566 553 l_ptr->reset_checkpoint = checkpoint; 567 554 l_ptr->exp_msg_count = START_CHANGEOVER; ··· 1746 1733 tipc_node_unlock(n_ptr); 1747 1734 tipc_link_recv_bundle(buf); 1748 1735 continue; 1749 - case ROUTE_DISTRIBUTOR: 1750 - tipc_node_unlock(n_ptr); 1751 - buf_discard(buf); 1752 - continue; 1753 1736 case NAME_DISTRIBUTOR: 1754 1737 tipc_node_unlock(n_ptr); 1755 1738 tipc_named_recv(buf); ··· 1771 1762 goto deliver; 1772 1763 goto protocol_check; 1773 1764 } 1765 + break; 1766 + default: 1767 + buf_discard(buf); 1768 + buf = NULL; 1774 1769 break; 1775 1770 } 1776 1771 } ··· 1911 1898 struct sk_buff *buf = NULL; 1912 1899 struct tipc_msg *msg = l_ptr->pmsg; 1913 1900 u32 msg_size = sizeof(l_ptr->proto_msg); 1901 + int r_flag; 1914 1902 1915 1903 if (link_blocked(l_ptr)) 1916 1904 return; ··· 1968 1954 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1969 1955 } 1970 1956 1971 - if (tipc_node_has_redundant_links(l_ptr->owner)) 1972 - msg_set_redundant_link(msg); 1973 - else 1974 - msg_clear_redundant_link(msg); 1957 + r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); 1958 + msg_set_redundant_link(msg, r_flag); 1975 1959 msg_set_linkprio(msg, l_ptr->priority); 1976 1960 1977 1961 /* Ensure sequence number will not fit : */ ··· 1989 1977 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 1990 1978 return; 1991 1979 } 1992 - msg_set_timestamp(msg, jiffies_to_msecs(jiffies)); 1993 1980 1994 1981 /* Message can be sent */ 1995 1982 ··· 2076 2065 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2077 2066 2078 2067 /* Synchronize broadcast sequence numbers */ 2079 - if (!tipc_node_has_redundant_links(l_ptr->owner)) 2068 + if (!tipc_node_redundant_links(l_ptr->owner)) 2080 2069 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2081 2070 break; 2082 2071 case STATE_MSG: ··· 2422 2411 destaddr = l_ptr->addr; 2423 2412 else 2424 2413 destaddr = msg_destnode(inmsg); 2425 - 2426 - if (msg_routed(inmsg)) 2427 - msg_set_prevnode(inmsg, tipc_own_addr); 2428 2414 2429 2415 /* Prepare reusable fragment header: */ 2430 2416
+2 -1
net/tipc/link.h
··· 207 207 208 208 struct tipc_port; 209 209 210 - struct link *tipc_link_create(struct tipc_bearer *b_ptr, const u32 peer, 210 + struct link *tipc_link_create(struct tipc_node *n_ptr, 211 + struct tipc_bearer *b_ptr, 211 212 const struct tipc_media_addr *media_addr); 212 213 void tipc_link_delete(struct link *l_ptr); 213 214 void tipc_link_changeover(struct link *l_ptr);
-34
net/tipc/msg.c
··· 192 192 default: 193 193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); 194 194 } 195 - if (msg_routed(msg) && !msg_non_seq(msg)) 196 - tipc_printf(buf, "ROUT:"); 197 195 if (msg_reroute_cnt(msg)) 198 196 tipc_printf(buf, "REROUTED(%u):", 199 197 msg_reroute_cnt(msg)); ··· 208 210 default: 209 211 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); 210 212 } 211 - if (msg_routed(msg)) 212 - tipc_printf(buf, "ROUT:"); 213 213 if (msg_reroute_cnt(msg)) 214 214 tipc_printf(buf, "REROUTED(%u):", 215 215 msg_reroute_cnt(msg)); ··· 228 232 default: 229 233 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); 230 234 } 231 - if (msg_routed(msg)) 232 - tipc_printf(buf, "ROUT:"); 233 235 if (msg_reroute_cnt(msg)) 234 236 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); 235 237 break; 236 238 case LINK_PROTOCOL: 237 - tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg)); 238 239 switch (msg_type(msg)) { 239 240 case STATE_MSG: 240 241 tipc_printf(buf, "STATE:"); ··· 263 270 case ORIGINAL_MSG: 264 271 tipc_printf(buf, "ORIG:"); 265 272 tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg)); 266 - break; 267 - default: 268 - tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); 269 - } 270 - break; 271 - case ROUTE_DISTRIBUTOR: 272 - tipc_printf(buf, "ROUTING_MNG:"); 273 - switch (msg_type(msg)) { 274 - case EXT_ROUTING_TABLE: 275 - tipc_printf(buf, "EXT_TBL:"); 276 - tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); 277 - break; 278 - case LOCAL_ROUTING_TABLE: 279 - tipc_printf(buf, "LOCAL_TBL:"); 280 - tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); 281 - break; 282 - case SLAVE_ROUTING_TABLE: 283 - tipc_printf(buf, "DP_TBL:"); 284 - tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); 285 - break; 286 - case ROUTE_ADDITION: 287 - tipc_printf(buf, "ADD:"); 288 - tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); 289 - break; 290 - case ROUTE_REMOVAL: 291 - tipc_printf(buf, "REMOVE:"); 292 - tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); 293 273 break; 294 274 default: 295 275 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
+2 -40
net/tipc/msg.h
··· 421 421 return msg_short(m) || (msg_destnode(m) == d); 422 422 } 423 423 424 - static inline u32 msg_routed(struct tipc_msg *m) 425 - { 426 - if (likely(msg_short(m))) 427 - return 0; 428 - return (msg_destnode(m) ^ msg_orignode(m)) >> 11; 429 - } 430 - 431 424 static inline u32 msg_nametype(struct tipc_msg *m) 432 425 { 433 426 return msg_word(m, 8); ··· 429 436 static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 430 437 { 431 438 msg_set_word(m, 8, n); 432 - } 433 - 434 - static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 435 - { 436 - msg_set_word(m, 8, n); 437 - } 438 - 439 - static inline u32 msg_timestamp(struct tipc_msg *m) 440 - { 441 - return msg_word(m, 8); 442 439 } 443 440 444 441 static inline u32 msg_nameinst(struct tipc_msg *m) ··· 518 535 #define NAME_DISTRIBUTOR 11 519 536 #define MSG_FRAGMENTER 12 520 537 #define LINK_CONFIG 13 521 - #define DSC_H_SIZE 40 522 538 523 539 /* 524 540 * Connection management protocol messages ··· 711 729 return msg_bits(m, 5, 12, 0x1); 712 730 } 713 731 714 - static inline void msg_set_redundant_link(struct tipc_msg *m) 732 + static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r) 715 733 { 716 - msg_set_bits(m, 5, 12, 0x1, 1); 717 - } 718 - 719 - static inline void msg_clear_redundant_link(struct tipc_msg *m) 720 - { 721 - msg_set_bits(m, 5, 12, 0x1, 0); 734 + msg_set_bits(m, 5, 12, 0x1, r); 722 735 } 723 736 724 737 ··· 759 782 static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) 760 783 { 761 784 msg_set_bits(m, 9, 0, 0xffff, n); 762 - } 763 - 764 - /* 765 - * Routing table message data 766 - */ 767 - 768 - 769 - static inline u32 msg_remote_node(struct tipc_msg *m) 770 - { 771 - return msg_word(m, msg_hdr_sz(m)/4); 772 - } 773 - 774 - static inline void msg_set_remote_node(struct tipc_msg *m, u32 a) 775 - { 776 - msg_set_word(m, msg_hdr_sz(m)/4, a); 777 785 } 778 786 779 787 /*
+9 -9
net/tipc/name_distr.c
··· 2 2 * net/tipc/name_distr.c: TIPC name distribution code 3 3 * 4 4 * Copyright (c) 2000-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 109 109 { 110 110 struct sk_buff *buf_copy; 111 111 struct tipc_node *n_ptr; 112 - u32 n_num; 113 112 114 - for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 115 - n_ptr = tipc_net.nodes[n_num]; 116 - if (n_ptr && tipc_node_has_active_links(n_ptr)) { 113 + list_for_each_entry(n_ptr, &tipc_node_list, list) { 114 + if (tipc_node_active_links(n_ptr)) { 117 115 buf_copy = skb_copy(buf, GFP_ATOMIC); 118 116 if (!buf_copy) 119 117 break; ··· 212 214 } 213 215 214 216 /** 215 - * node_is_down - remove publication associated with a failed node 217 + * named_purge_publ - remove publication associated with a failed node 216 218 * 217 219 * Invoked for each publication issued by a newly failed node. 218 220 * Removes publication structure from name table & deletes it. 219 221 * In rare cases the link may have come back up again when this 220 222 * function is called, and we have two items representing the same 221 223 * publication. Nudge this item's key to distinguish it from the other. 222 - * (Note: Publication's node subscription is already unsubscribed.) 223 224 */ 224 225 225 - static void node_is_down(struct publication *publ) 226 + static void named_purge_publ(struct publication *publ) 226 227 { 227 228 struct publication *p; 228 229 ··· 229 232 publ->key += 1222345; 230 233 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 231 234 publ->node, publ->ref, publ->key); 235 + if (p) 236 + tipc_nodesub_unsubscribe(&p->subscr); 232 237 write_unlock_bh(&tipc_nametbl_lock); 233 238 234 239 if (p != publ) { ··· 267 268 tipc_nodesub_subscribe(&publ->subscr, 268 269 msg_orignode(msg), 269 270 publ, 270 - (net_ev_handler)node_is_down); 271 + (net_ev_handler) 272 + named_purge_publ); 271 273 } 272 274 } else if (msg_type(msg) == WITHDRAWAL) { 273 275 publ = tipc_nametbl_remove_publ(ntohl(item->type),
+6 -26
net/tipc/net.c
··· 2 2 * net/tipc/net.c: TIPC network routing code 3 3 * 4 4 * Copyright (c) 1995-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 39 39 #include "name_distr.h" 40 40 #include "subscr.h" 41 41 #include "port.h" 42 + #include "node.h" 42 43 #include "config.h" 43 44 44 45 /* ··· 109 108 */ 110 109 111 110 DEFINE_RWLOCK(tipc_net_lock); 112 - struct network tipc_net; 113 - 114 - static int net_start(void) 115 - { 116 - tipc_net.nodes = kcalloc(tipc_max_nodes + 1, 117 - sizeof(*tipc_net.nodes), GFP_ATOMIC); 118 - tipc_net.highest_node = 0; 119 - 120 - return tipc_net.nodes ? 0 : -ENOMEM; 121 - } 122 - 123 - static void net_stop(void) 124 - { 125 - u32 n_num; 126 - 127 - for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) 128 - tipc_node_delete(tipc_net.nodes[n_num]); 129 - kfree(tipc_net.nodes); 130 - tipc_net.nodes = NULL; 131 - } 132 111 133 112 static void net_route_named_msg(struct sk_buff *buf) 134 113 { ··· 198 217 tipc_named_reinit(); 199 218 tipc_port_reinit(); 200 219 201 - res = net_start(); 202 - if (res) 203 - return res; 204 220 res = tipc_bclink_init(); 205 221 if (res) 206 222 return res; ··· 213 235 214 236 void tipc_net_stop(void) 215 237 { 238 + struct tipc_node *node, *t_node; 239 + 216 240 if (tipc_mode != TIPC_NET_MODE) 217 241 return; 218 242 write_lock_bh(&tipc_net_lock); 219 243 tipc_bearer_stop(); 220 244 tipc_mode = TIPC_NODE_MODE; 221 245 tipc_bclink_stop(); 222 - net_stop(); 246 + list_for_each_entry_safe(node, t_node, &tipc_node_list, list); 247 + tipc_node_delete(node); 223 248 write_unlock_bh(&tipc_net_lock); 224 249 info("Left network mode\n"); 225 250 } 226 -
+1 -18
net/tipc/net.h
··· 2 2 * net/tipc/net.h: Include file for TIPC network routing code 3 3 * 4 4 * Copyright (c) 1995-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 37 37 #ifndef _TIPC_NET_H 38 38 #define _TIPC_NET_H 39 39 40 - struct tipc_node; 41 - 42 - /** 43 - * struct network - TIPC network structure 44 - * @nodes: array of pointers to all nodes within cluster 45 - * @highest_node: id of highest numbered node within cluster 46 - * @links: number of (unicast) links to cluster 47 - */ 48 - 49 - struct network { 50 - struct tipc_node **nodes; 51 - u32 highest_node; 52 - u32 links; 53 - }; 54 - 55 - 56 - extern struct network tipc_net; 57 40 extern rwlock_t tipc_net_lock; 58 41 59 42 void tipc_net_route_msg(struct sk_buff *buf);
+57 -66
net/tipc/node.c
··· 44 44 45 45 static DEFINE_SPINLOCK(node_create_lock); 46 46 47 + static struct hlist_head node_htable[NODE_HTABLE_SIZE]; 48 + LIST_HEAD(tipc_node_list); 49 + static u32 tipc_num_nodes; 50 + 51 + static atomic_t tipc_num_links = ATOMIC_INIT(0); 47 52 u32 tipc_own_tag; 53 + 54 + /** 55 + * tipc_node_find - locate specified node object, if it exists 56 + */ 57 + 58 + struct tipc_node *tipc_node_find(u32 addr) 59 + { 60 + struct tipc_node *node; 61 + struct hlist_node *pos; 62 + 63 + if (unlikely(!in_own_cluster(addr))) 64 + return NULL; 65 + 66 + hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) { 67 + if (node->addr == addr) 68 + return node; 69 + } 70 + return NULL; 71 + } 48 72 49 73 /** 50 74 * tipc_node_create - create neighboring node ··· 82 58 83 59 struct tipc_node *tipc_node_create(u32 addr) 84 60 { 85 - struct tipc_node *n_ptr; 86 - u32 n_num; 61 + struct tipc_node *n_ptr, *temp_node; 87 62 88 63 spin_lock_bh(&node_create_lock); 89 64 ··· 101 78 102 79 n_ptr->addr = addr; 103 80 spin_lock_init(&n_ptr->lock); 81 + INIT_HLIST_NODE(&n_ptr->hash); 82 + INIT_LIST_HEAD(&n_ptr->list); 104 83 INIT_LIST_HEAD(&n_ptr->nsub); 105 84 106 - n_num = tipc_node(addr); 107 - tipc_net.nodes[n_num] = n_ptr; 108 - if (n_num > tipc_net.highest_node) 109 - tipc_net.highest_node = n_num; 85 + hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); 86 + 87 + list_for_each_entry(temp_node, &tipc_node_list, list) { 88 + if (n_ptr->addr < temp_node->addr) 89 + break; 90 + } 91 + list_add_tail(&n_ptr->list, &temp_node->list); 92 + 93 + tipc_num_nodes++; 110 94 111 95 spin_unlock_bh(&node_create_lock); 112 96 return n_ptr; ··· 121 91 122 92 void tipc_node_delete(struct tipc_node *n_ptr) 123 93 { 124 - u32 n_num; 125 - 126 - if (!n_ptr) 127 - return; 128 - 129 - n_num = tipc_node(n_ptr->addr); 130 - tipc_net.nodes[n_num] = NULL; 94 + list_del(&n_ptr->list); 95 + hlist_del(&n_ptr->hash); 131 96 kfree(n_ptr); 132 97 133 - while (!tipc_net.nodes[tipc_net.highest_node]) 134 - if (--tipc_net.highest_node == 0) 135 - break; 98 + tipc_num_nodes--; 136 99 } 137 100 138 101 ··· 223 200 node_lost_contact(n_ptr); 224 201 } 225 202 226 - int tipc_node_has_active_links(struct tipc_node *n_ptr) 203 + int tipc_node_active_links(struct tipc_node *n_ptr) 227 204 { 228 205 return n_ptr->active_links[0] != NULL; 229 206 } 230 207 231 - int tipc_node_has_redundant_links(struct tipc_node *n_ptr) 208 + int tipc_node_redundant_links(struct tipc_node *n_ptr) 232 209 { 233 210 return n_ptr->working_links > 1; 234 211 } 235 212 236 213 int tipc_node_is_up(struct tipc_node *n_ptr) 237 214 { 238 - return tipc_node_has_active_links(n_ptr); 215 + return tipc_node_active_links(n_ptr); 239 216 } 240 217 241 - struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 218 + void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr) 242 219 { 243 - struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr); 244 - 245 - if (!n_ptr) 246 - n_ptr = tipc_node_create(l_ptr->addr); 247 - if (n_ptr) { 248 - u32 bearer_id = l_ptr->b_ptr->identity; 249 - char addr_string[16]; 250 - 251 - if (n_ptr->link_cnt >= 2) { 252 - err("Attempt to create third link to %s\n", 253 - tipc_addr_string_fill(addr_string, n_ptr->addr)); 254 - return NULL; 255 - } 256 - 257 - if (!n_ptr->links[bearer_id]) { 258 - n_ptr->links[bearer_id] = l_ptr; 259 - tipc_net.links++; 260 - n_ptr->link_cnt++; 261 - return n_ptr; 262 - } 263 - err("Attempt to establish second link on <%s> to %s\n", 264 - l_ptr->b_ptr->name, 265 - tipc_addr_string_fill(addr_string, l_ptr->addr)); 266 - } 267 - return NULL; 220 + n_ptr->links[l_ptr->b_ptr->identity] = l_ptr; 221 + atomic_inc(&tipc_num_links); 222 + n_ptr->link_cnt++; 268 223 } 269 224 270 225 void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) 271 226 { 272 227 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 273 - tipc_net.links--; 228 + atomic_dec(&tipc_num_links); 274 229 n_ptr->link_cnt--; 275 230 } 276 231 ··· 328 327 329 328 static void node_lost_contact(struct tipc_node *n_ptr) 330 329 { 331 - struct tipc_node_subscr *ns, *tns; 332 330 char addr_string[16]; 333 331 u32 i; 334 332 ··· 365 365 } 366 366 367 367 /* Notify subscribers */ 368 - list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) { 369 - ns->node = NULL; 370 - list_del_init(&ns->nodesub_list); 371 - tipc_k_signal((Handler)ns->handle_node_down, 372 - (unsigned long)ns->usr_handle); 373 - } 368 + tipc_nodesub_notify(n_ptr); 374 369 375 370 /* Prevent re-contact with node until all cleanup is done */ 376 371 ··· 380 385 struct tipc_node *n_ptr; 381 386 struct tipc_node_info node_info; 382 387 u32 payload_size; 383 - u32 n_num; 384 388 385 389 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 386 390 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); ··· 390 396 " (network address)"); 391 397 392 398 read_lock_bh(&tipc_net_lock); 393 - if (!tipc_net.nodes) { 399 + if (!tipc_num_nodes) { 394 400 read_unlock_bh(&tipc_net_lock); 395 401 return tipc_cfg_reply_none(); 396 402 } 397 403 398 404 /* For now, get space for all other nodes */ 399 405 400 - payload_size = TLV_SPACE(sizeof(node_info)) * 401 - (tipc_net.highest_node - 1); 406 + payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes; 402 407 if (payload_size > 32768u) { 403 408 read_unlock_bh(&tipc_net_lock); 404 409 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED ··· 411 418 412 419 /* Add TLVs for all nodes in scope */ 413 420 414 - for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 415 - n_ptr = tipc_net.nodes[n_num]; 416 - if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) 421 + list_for_each_entry(n_ptr, &tipc_node_list, list) { 422 + if (!tipc_in_scope(domain, n_ptr->addr)) 417 423 continue; 418 424 node_info.addr = htonl(n_ptr->addr); 419 425 node_info.up = htonl(tipc_node_is_up(n_ptr)); ··· 431 439 struct tipc_node *n_ptr; 432 440 struct tipc_link_info link_info; 433 441 u32 payload_size; 434 - u32 n_num; 435 442 436 443 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 437 444 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); ··· 447 456 448 457 /* Get space for all unicast links + multicast link */ 449 458 450 - payload_size = TLV_SPACE(sizeof(link_info)) * (tipc_net.links + 1); 459 + payload_size = TLV_SPACE(sizeof(link_info)) * 460 + (atomic_read(&tipc_num_links) + 1); 451 461 if (payload_size > 32768u) { 452 462 read_unlock_bh(&tipc_net_lock); 453 463 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED ··· 462 470 463 471 /* Add TLV for broadcast link */ 464 472 465 - link_info.dest = htonl(tipc_own_addr & 0xfffff00); 473 + link_info.dest = htonl(tipc_cluster_mask(tipc_own_addr)); 466 474 link_info.up = htonl(1); 467 475 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); 468 476 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); 469 477 470 478 /* Add TLVs for any other links in scope */ 471 479 472 - for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 480 + list_for_each_entry(n_ptr, &tipc_node_list, list) { 473 481 u32 i; 474 482 475 - n_ptr = tipc_net.nodes[n_num]; 476 - if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) 483 + if (!tipc_in_scope(domain, n_ptr->addr)) 477 484 continue; 478 485 tipc_node_lock(n_ptr); 479 486 for (i = 0; i < MAX_BEARERS; i++) {
+23 -13
net/tipc/node.h
··· 2 2 * net/tipc/node.h: Include file for TIPC node management routines 3 3 * 4 4 * Copyright (c) 2000-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 46 46 * struct tipc_node - TIPC node structure 47 47 * @addr: network address of node 48 48 * @lock: spinlock governing access to structure 49 - * @next: pointer to next node in sorted list of cluster's nodes 49 + * @hash: links to adjacent nodes in unsorted hash chain 50 + * @list: links to adjacent nodes in sorted list of cluster's nodes 50 51 * @nsub: list of "node down" subscriptions monitoring node 51 52 * @active_links: pointers to active links to node 52 53 * @links: pointers to all links to node ··· 70 69 struct tipc_node { 71 70 u32 addr; 72 71 spinlock_t lock; 73 - struct tipc_node *next; 72 + struct hlist_node hash; 73 + struct list_head list; 74 74 struct list_head nsub; 75 75 struct link *active_links[2]; 76 76 struct link *links[MAX_BEARERS]; ··· 92 90 } bclink; 93 91 }; 94 92 93 + #define NODE_HTABLE_SIZE 512 94 + extern struct list_head tipc_node_list; 95 + 96 + /* 97 + * A trivial power-of-two bitmask technique is used for speed, since this 98 + * operation is done for every incoming TIPC packet. The number of hash table 99 + * entries has been chosen so that no hash chain exceeds 8 nodes and will 100 + * usually be much smaller (typically only a single node). 101 + */ 102 + static inline unsigned int tipc_hashfn(u32 addr) 103 + { 104 + return addr & (NODE_HTABLE_SIZE - 1); 105 + } 106 + 95 107 extern u32 tipc_own_tag; 96 108 109 + struct tipc_node *tipc_node_find(u32 addr); 97 110 struct tipc_node *tipc_node_create(u32 addr); 98 111 void tipc_node_delete(struct tipc_node *n_ptr); 99 - struct tipc_node *tipc_node_attach_link(struct link *l_ptr); 112 + void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr); 100 113 void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr); 101 114 void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr); 102 115 void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 103 - int tipc_node_has_active_links(struct tipc_node *n_ptr); 104 - int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 116 + int tipc_node_active_links(struct tipc_node *n_ptr); 117 + int tipc_node_redundant_links(struct tipc_node *n_ptr); 105 118 int tipc_node_is_up(struct tipc_node *n_ptr); 106 119 struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); 107 120 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 108 - 109 - static inline struct tipc_node *tipc_node_find(u32 addr) 110 - { 111 - if (likely(in_own_cluster(addr))) 112 - return tipc_net.nodes[tipc_node(addr)]; 113 - return NULL; 114 - } 115 121 116 122 static inline void tipc_node_lock(struct tipc_node *n_ptr) 117 123 {
+20 -1
net/tipc/node_subscr.c
··· 2 2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling 3 3 * 4 4 * Copyright (c) 1995-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 75 75 tipc_node_lock(node_sub->node); 76 76 list_del_init(&node_sub->nodesub_list); 77 77 tipc_node_unlock(node_sub->node); 78 + } 79 + 80 + /** 81 + * tipc_nodesub_notify - notify subscribers that a node is unreachable 82 + * 83 + * Note: node is locked by caller 84 + */ 85 + 86 + void tipc_nodesub_notify(struct tipc_node *node) 87 + { 88 + struct tipc_node_subscr *ns; 89 + 90 + list_for_each_entry(ns, &node->nsub, nodesub_list) { 91 + if (ns->handle_node_down) { 92 + tipc_k_signal((Handler)ns->handle_node_down, 93 + (unsigned long)ns->usr_handle); 94 + ns->handle_node_down = NULL; 95 + } 96 + } 78 97 }
+2 -1
net/tipc/node_subscr.h
··· 2 2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling 3 3 * 4 4 * Copyright (c) 1995-2006, Ericsson AB 5 - * Copyright (c) 2005, Wind River Systems 5 + * Copyright (c) 2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 59 59 void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, 60 60 void *usr_handle, net_ev_handler handle_down); 61 61 void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub); 62 + void tipc_nodesub_notify(struct tipc_node *node); 62 63 63 64 #endif
+32 -38
net/tipc/socket.c
··· 58 58 #define tipc_sk(sk) ((struct tipc_sock *)(sk)) 59 59 #define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 60 60 61 + #define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \ 62 + (sock->state == SS_DISCONNECTING)) 63 + 61 64 static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 62 65 static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 63 66 static void wakeupdispatch(struct tipc_port *tport); ··· 292 289 if (buf == NULL) 293 290 break; 294 291 atomic_dec(&tipc_queue_size); 295 - if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) 292 + if (TIPC_SKB_CB(buf)->handle != 0) 296 293 buf_discard(buf); 297 294 else { 298 295 if ((sock->state == SS_CONNECTING) || ··· 914 911 struct tipc_port *tport = tipc_sk_port(sk); 915 912 struct sk_buff *buf; 916 913 struct tipc_msg *msg; 914 + long timeout; 917 915 unsigned int sz; 918 916 u32 err; 919 917 int res; 920 918 921 919 /* Catch invalid receive requests */ 922 - 923 - if (m->msg_iovlen != 1) 924 - return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */ 925 920 926 921 if (unlikely(!buf_len)) 927 922 return -EINVAL; ··· 931 930 goto exit; 932 931 } 933 932 933 + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 934 934 restart: 935 935 936 936 /* Look for a message in receive queue; wait if necessary */ ··· 941 939 res = -ENOTCONN; 942 940 goto exit; 943 941 } 944 - if (flags & MSG_DONTWAIT) { 945 - res = -EWOULDBLOCK; 942 + if (timeout <= 0L) { 943 + res = timeout ? timeout : -EWOULDBLOCK; 946 944 goto exit; 947 945 } 948 946 release_sock(sk); 949 - res = wait_event_interruptible(*sk_sleep(sk), 950 - (!skb_queue_empty(&sk->sk_receive_queue) || 951 - (sock->state == SS_DISCONNECTING))); 947 + timeout = wait_event_interruptible_timeout(*sk_sleep(sk), 948 + tipc_rx_ready(sock), 949 + timeout); 952 950 lock_sock(sk); 953 - if (res) 954 - goto exit; 955 951 } 956 952 957 953 /* Look at first message in receive queue */ ··· 991 991 sz = buf_len; 992 992 m->msg_flags |= MSG_TRUNC; 993 993 } 994 - if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 995 - sz))) { 996 - res = -EFAULT; 994 + res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg), 995 + m->msg_iov, sz); 996 + if (res) 997 997 goto exit; 998 - } 999 998 res = sz; 1000 999 } else { 1001 1000 if ((sock->state == SS_READY) || ··· 1037 1038 struct tipc_port *tport = tipc_sk_port(sk); 1038 1039 struct sk_buff *buf; 1039 1040 struct tipc_msg *msg; 1041 + long timeout; 1040 1042 unsigned int sz; 1041 1043 int sz_to_copy, target, needed; 1042 1044 int sz_copied = 0; 1043 - char __user *crs = m->msg_iov->iov_base; 1044 - unsigned char *buf_crs; 1045 1045 u32 err; 1046 1046 int res = 0; 1047 1047 1048 1048 /* Catch invalid receive attempts */ 1049 - 1050 - if (m->msg_iovlen != 1) 1051 - return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */ 1052 1049 1053 1050 if (unlikely(!buf_len)) 1054 1051 return -EINVAL; ··· 1058 1063 } 1059 1064 1060 1065 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1061 - 1066 + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 1062 1067 restart: 1063 1068 1064 1069 /* Look for a message in receive queue; wait if necessary */ ··· 1068 1073 res = -ENOTCONN; 1069 1074 goto exit; 1070 1075 } 1071 - if (flags & MSG_DONTWAIT) { 1072 - res = -EWOULDBLOCK; 1076 + if (timeout <= 0L) { 1077 + res = timeout ? timeout : -EWOULDBLOCK; 1073 1078 goto exit; 1074 1079 } 1075 1080 release_sock(sk); 1076 - res = wait_event_interruptible(*sk_sleep(sk), 1077 - (!skb_queue_empty(&sk->sk_receive_queue) || 1078 - (sock->state == SS_DISCONNECTING))); 1081 + timeout = wait_event_interruptible_timeout(*sk_sleep(sk), 1082 + tipc_rx_ready(sock), 1083 + timeout); 1079 1084 lock_sock(sk); 1080 - if (res) 1081 - goto exit; 1082 1085 } 1083 1086 1084 1087 /* Look at first message in receive queue */ ··· 1105 1112 /* Capture message data (if valid) & compute return value (always) */ 1106 1113 1107 1114 if (!err) { 1108 - buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1109 - sz = (unsigned char *)msg + msg_size(msg) - buf_crs; 1115 + u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle); 1110 1116 1117 + sz -= offset; 1111 1118 needed = (buf_len - sz_copied); 1112 1119 sz_to_copy = (sz <= needed) ? sz : needed; 1113 - if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1114 - res = -EFAULT; 1120 + 1121 + res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset, 1122 + m->msg_iov, sz_to_copy); 1123 + if (res) 1115 1124 goto exit; 1116 - } 1125 + 1117 1126 sz_copied += sz_to_copy; 1118 1127 1119 1128 if (sz_to_copy < sz) { 1120 1129 if (!(flags & MSG_PEEK)) 1121 - TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1130 + TIPC_SKB_CB(buf)->handle = 1131 + (void *)(unsigned long)(offset + sz_to_copy); 1122 1132 goto exit; 1123 1133 } 1124 - 1125 - crs += sz_to_copy; 1126 1134 } else { 1127 1135 if (sz_copied != 0) 1128 1136 goto exit; /* can't add error msg to valid data */ ··· 1250 1256 1251 1257 /* Enqueue message (finally!) */ 1252 1258 1253 - TIPC_SKB_CB(buf)->handle = msg_data(msg); 1259 + TIPC_SKB_CB(buf)->handle = 0; 1254 1260 atomic_inc(&tipc_queue_size); 1255 1261 __skb_queue_tail(&sk->sk_receive_queue, buf); 1256 1262 ··· 1602 1608 buf = __skb_dequeue(&sk->sk_receive_queue); 1603 1609 if (buf) { 1604 1610 atomic_dec(&tipc_queue_size); 1605 - if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1611 + if (TIPC_SKB_CB(buf)->handle != 0) { 1606 1612 buf_discard(buf); 1607 1613 goto restart; 1608 1614 }