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

Merge branch 'tipc-Sep17-2011' of git://openlinux.windriver.com/people/paulg/net-next

+245 -203
+52 -59
net/tipc/bcast.c
··· 39 39 #include "link.h" 40 40 #include "port.h" 41 41 #include "bcast.h" 42 + #include "name_distr.h" 42 43 43 44 #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 44 45 ··· 299 298 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); 300 299 msg_set_bcast_tag(msg, tipc_own_tag); 301 300 302 - if (tipc_bearer_send(&bcbearer->bearer, buf, NULL)) { 303 - bcl->stats.sent_nacks++; 304 - buf_discard(buf); 305 - } else { 306 - tipc_bearer_schedule(bcl->b_ptr, bcl); 307 - bcl->proto_msg_queue = buf; 308 - bcl->stats.bearer_congs++; 309 - } 301 + tipc_bearer_send(&bcbearer->bearer, buf, NULL); 302 + bcl->stats.sent_nacks++; 303 + buf_discard(buf); 310 304 311 305 /* 312 306 * Ensure we doesn't send another NACK msg to the node ··· 422 426 void tipc_bclink_recv_pkt(struct sk_buff *buf) 423 427 { 424 428 struct tipc_msg *msg = buf_msg(buf); 425 - struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); 429 + struct tipc_node *node; 426 430 u32 next_in; 427 431 u32 seqno; 428 432 struct sk_buff *deferred; 429 433 430 - if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 431 - (msg_mc_netid(msg) != tipc_net_id))) { 432 - buf_discard(buf); 433 - return; 434 - } 434 + /* Screen out unwanted broadcast messages */ 435 + 436 + if (msg_mc_netid(msg) != tipc_net_id) 437 + goto exit; 438 + 439 + node = tipc_node_find(msg_prevnode(msg)); 440 + if (unlikely(!node)) 441 + goto exit; 442 + 443 + tipc_node_lock(node); 444 + if (unlikely(!node->bclink.supported)) 445 + goto unlock; 435 446 436 447 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 448 + if (msg_type(msg) != STATE_MSG) 449 + goto unlock; 437 450 if (msg_destnode(msg) == tipc_own_addr) { 438 - tipc_node_lock(node); 439 451 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 440 452 tipc_node_unlock(node); 441 453 spin_lock_bh(&bc_lock); ··· 453 449 msg_bcgap_to(msg)); 454 450 spin_unlock_bh(&bc_lock); 455 451 } else { 452 + tipc_node_unlock(node); 456 453 tipc_bclink_peek_nack(msg_destnode(msg), 457 454 msg_bcast_tag(msg), 458 455 msg_bcgap_after(msg), 459 456 msg_bcgap_to(msg)); 460 457 } 461 - buf_discard(buf); 462 - return; 458 + goto exit; 463 459 } 464 460 465 - tipc_node_lock(node); 461 + /* Handle in-sequence broadcast message */ 462 + 466 463 receive: 467 - deferred = node->bclink.deferred_head; 468 464 next_in = mod(node->bclink.last_in + 1); 469 465 seqno = msg_seqno(msg); 470 466 ··· 478 474 } 479 475 if (likely(msg_isdata(msg))) { 480 476 tipc_node_unlock(node); 481 - tipc_port_recv_mcast(buf, NULL); 477 + if (likely(msg_mcast(msg))) 478 + tipc_port_recv_mcast(buf, NULL); 479 + else 480 + buf_discard(buf); 482 481 } else if (msg_user(msg) == MSG_BUNDLER) { 483 482 bcl->stats.recv_bundles++; 484 483 bcl->stats.recv_bundled += msg_msgcnt(msg); ··· 494 487 bcl->stats.recv_fragmented++; 495 488 tipc_node_unlock(node); 496 489 tipc_net_route_msg(buf); 490 + } else if (msg_user(msg) == NAME_DISTRIBUTOR) { 491 + tipc_node_unlock(node); 492 + tipc_named_recv(buf); 497 493 } else { 498 494 tipc_node_unlock(node); 499 - tipc_net_route_msg(buf); 495 + buf_discard(buf); 500 496 } 497 + buf = NULL; 498 + tipc_node_lock(node); 499 + deferred = node->bclink.deferred_head; 501 500 if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { 502 - tipc_node_lock(node); 503 501 buf = deferred; 504 502 msg = buf_msg(buf); 505 503 node->bclink.deferred_head = deferred->next; 506 504 goto receive; 507 505 } 508 - return; 509 506 } else if (less(next_in, seqno)) { 510 507 u32 gap_after = node->bclink.gap_after; 511 508 u32 gap_to = node->bclink.gap_to; ··· 524 513 else if (less(gap_after, seqno) && less(seqno, gap_to)) 525 514 node->bclink.gap_to = seqno; 526 515 } 516 + buf = NULL; 527 517 if (bclink_ack_allowed(node->bclink.nack_sync)) { 528 518 if (gap_to != gap_after) 529 519 bclink_send_nack(node); ··· 532 520 } 533 521 } else { 534 522 bcl->stats.duplicates++; 535 - buf_discard(buf); 536 523 } 524 + unlock: 537 525 tipc_node_unlock(node); 526 + exit: 527 + buf_discard(buf); 538 528 } 539 529 540 530 u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) ··· 549 535 /** 550 536 * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer 551 537 * 552 - * Send through as many bearers as necessary to reach all nodes 553 - * that support TIPC multicasting. 538 + * Send packet over as many bearers as necessary to reach all nodes 539 + * that have joined the broadcast link. 554 540 * 555 - * Returns 0 if packet sent successfully, non-zero if not 541 + * Returns 0 (packet sent successfully) under all circumstances, 542 + * since the broadcast link's pseudo-bearer never blocks 556 543 */ 557 544 558 545 static int tipc_bcbearer_send(struct sk_buff *buf, ··· 562 547 { 563 548 int bp_index; 564 549 565 - /* Prepare buffer for broadcasting (if first time trying to send it) */ 550 + /* 551 + * Prepare broadcast link message for reliable transmission, 552 + * if first time trying to send it; 553 + * preparation is skipped for broadcast link protocol messages 554 + * since they are sent in an unreliable manner and don't need it 555 + */ 566 556 567 557 if (likely(!msg_non_seq(buf_msg(buf)))) { 568 558 struct tipc_msg *msg; ··· 616 596 } 617 597 618 598 if (bcbearer->remains_new.count == 0) 619 - return 0; 599 + break; /* all targets reached */ 620 600 621 601 bcbearer->remains = bcbearer->remains_new; 622 602 } 623 603 624 - /* 625 - * Unable to reach all targets (indicate success, since currently 626 - * there isn't code in place to properly block & unblock the 627 - * pseudo-bearer used by the broadcast link) 628 - */ 629 - 630 - return TIPC_OK; 604 + return 0; 631 605 } 632 606 633 607 /** ··· 678 664 bp_curr++; 679 665 } 680 666 681 - spin_unlock_bh(&bc_lock); 682 - } 683 - 684 - /** 685 - * tipc_bcbearer_push - resolve bearer congestion 686 - * 687 - * Forces bclink to push out any unsent packets, until all packets are gone 688 - * or congestion reoccurs. 689 - * No locks set when function called 690 - */ 691 - 692 - void tipc_bcbearer_push(void) 693 - { 694 - struct tipc_bearer *b_ptr; 695 - 696 - spin_lock_bh(&bc_lock); 697 - b_ptr = &bcbearer->bearer; 698 - if (b_ptr->blocked) { 699 - b_ptr->blocked = 0; 700 - tipc_bearer_lock_push(b_ptr); 701 - } 702 667 spin_unlock_bh(&bc_lock); 703 668 } 704 669 ··· 757 764 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 758 765 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 759 766 if (!bcbearer || !bclink) { 760 - warn("Multicast link creation failed, no memory\n"); 767 + warn("Broadcast link creation failed, no memory\n"); 761 768 kfree(bcbearer); 762 769 bcbearer = NULL; 763 770 kfree(bclink); ··· 768 775 INIT_LIST_HEAD(&bcbearer->bearer.cong_links); 769 776 bcbearer->bearer.media = &bcbearer->media; 770 777 bcbearer->media.send_msg = tipc_bcbearer_send; 771 - sprintf(bcbearer->media.name, "tipc-multicast"); 778 + sprintf(bcbearer->media.name, "tipc-broadcast"); 772 779 773 780 bcl = &bclink->link; 774 781 INIT_LIST_HEAD(&bcl->waiting_ports);
-1
net/tipc/bcast.h
··· 101 101 int tipc_bclink_reset_stats(void); 102 102 int tipc_bclink_set_queue_limits(u32 limit); 103 103 void tipc_bcbearer_sort(void); 104 - void tipc_bcbearer_push(void); 105 104 106 105 #endif
+3 -5
net/tipc/bearer.c
··· 385 385 386 386 void tipc_bearer_lock_push(struct tipc_bearer *b_ptr) 387 387 { 388 - int res; 389 - 390 388 spin_lock_bh(&b_ptr->lock); 391 - res = bearer_push(b_ptr); 389 + bearer_push(b_ptr); 392 390 spin_unlock_bh(&b_ptr->lock); 393 - if (res) 394 - tipc_bcbearer_push(); 395 391 } 396 392 397 393 ··· 604 608 info("Blocking bearer <%s>\n", name); 605 609 spin_lock_bh(&b_ptr->lock); 606 610 b_ptr->blocked = 1; 611 + list_splice_init(&b_ptr->cong_links, &b_ptr->links); 607 612 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 608 613 struct tipc_node *n_ptr = l_ptr->owner; 609 614 ··· 632 635 spin_lock_bh(&b_ptr->lock); 633 636 b_ptr->blocked = 1; 634 637 b_ptr->media->disable_bearer(b_ptr); 638 + list_splice_init(&b_ptr->cong_links, &b_ptr->links); 635 639 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 636 640 tipc_link_delete(l_ptr); 637 641 }
+2 -2
net/tipc/bearer.h
··· 39 39 40 40 #include "bcast.h" 41 41 42 - #define MAX_BEARERS 8 43 - #define MAX_MEDIA 4 42 + #define MAX_BEARERS 2 43 + #define MAX_MEDIA 2 44 44 45 45 /* 46 46 * Identifiers of supported TIPC media types
-1
net/tipc/config.h
··· 65 65 const void *req_tlv_area, int req_tlv_space, 66 66 int headroom); 67 67 68 - void tipc_cfg_link_event(u32 addr, char *name, int up); 69 68 int tipc_cfg_init(void); 70 69 void tipc_cfg_stop(void); 71 70
-6
net/tipc/discover.c
··· 159 159 } 160 160 tipc_node_lock(n_ptr); 161 161 162 - /* Don't talk to neighbor during cleanup after last session */ 163 - if (n_ptr->cleanup_required) { 164 - tipc_node_unlock(n_ptr); 165 - return; 166 - } 167 - 168 162 link = n_ptr->links[b_ptr->identity]; 169 163 170 164 /* Create a link endpoint for this bearer, if necessary */
+13 -17
net/tipc/eth_media.c
··· 2 2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC 3 3 * 4 4 * Copyright (c) 2001-2007, Ericsson AB 5 - * Copyright (c) 2005-2007, Wind River Systems 5 + * Copyright (c) 2005-2008, 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 #include "core.h" 38 38 #include "bearer.h" 39 39 40 - #define MAX_ETH_BEARERS 2 40 + #define MAX_ETH_BEARERS MAX_BEARERS 41 41 #define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI 42 42 #define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL 43 43 #define ETH_LINK_WINDOW TIPC_DEF_LINK_WIN ··· 144 144 145 145 /* Find device with specified name */ 146 146 147 + read_lock(&dev_base_lock); 147 148 for_each_netdev(&init_net, pdev) { 148 149 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { 149 150 dev = pdev; 151 + dev_hold(dev); 150 152 break; 151 153 } 152 154 } 155 + read_unlock(&dev_base_lock); 153 156 if (!dev) 154 157 return -ENODEV; 155 158 156 - /* Find Ethernet bearer for device (or create one) */ 159 + /* Create Ethernet bearer for device */ 157 160 158 - while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev)) 159 - eb_ptr++; 160 - if (eb_ptr == stop) 161 - return -EDQUOT; 162 - if (!eb_ptr->dev) { 163 - eb_ptr->dev = dev; 164 - eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC); 165 - eb_ptr->tipc_packet_type.dev = dev; 166 - eb_ptr->tipc_packet_type.func = recv_msg; 167 - eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; 168 - INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); 169 - dev_hold(dev); 170 - dev_add_pack(&eb_ptr->tipc_packet_type); 171 - } 161 + eb_ptr->dev = dev; 162 + eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC); 163 + eb_ptr->tipc_packet_type.dev = dev; 164 + eb_ptr->tipc_packet_type.func = recv_msg; 165 + eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; 166 + INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); 167 + dev_add_pack(&eb_ptr->tipc_packet_type); 172 168 173 169 /* Associate TIPC bearer with Ethernet bearer */ 174 170
+82 -33
net/tipc/link.c
··· 332 332 333 333 l_ptr->addr = peer; 334 334 if_name = strchr(b_ptr->name, ':') + 1; 335 - sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 335 + sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 336 336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 337 337 tipc_node(tipc_own_addr), 338 338 if_name, 339 339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 340 - /* note: peer i/f is appended to link name by reset/activate */ 340 + /* note: peer i/f name is updated by reset/activate message */ 341 341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 342 342 l_ptr->owner = n_ptr; 343 343 l_ptr->checkpoint = 1; 344 + l_ptr->peer_session = INVALID_SESSION; 344 345 l_ptr->b_ptr = b_ptr; 345 346 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 346 347 l_ptr->state = RESET_UNKNOWN; ··· 537 536 l_ptr->proto_msg_queue = NULL; 538 537 } 539 538 540 - /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ 541 - #define link_send_event(fcn, l_ptr, up) do { } while (0) 542 - 543 539 void tipc_link_reset(struct link *l_ptr) 544 540 { 545 541 struct sk_buff *buf; ··· 594 596 l_ptr->fsm_msg_cnt = 0; 595 597 l_ptr->stale_count = 0; 596 598 link_reset_statistics(l_ptr); 597 - 598 - link_send_event(tipc_cfg_link_event, l_ptr, 0); 599 - if (!in_own_cluster(l_ptr->addr)) 600 - link_send_event(tipc_disc_link_event, l_ptr, 0); 601 599 } 602 600 603 601 ··· 602 608 l_ptr->next_in_no = l_ptr->stats.recv_info = 1; 603 609 tipc_node_link_up(l_ptr->owner, l_ptr); 604 610 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr); 605 - link_send_event(tipc_cfg_link_event, l_ptr, 1); 606 - if (!in_own_cluster(l_ptr->addr)) 607 - link_send_event(tipc_disc_link_event, l_ptr, 1); 608 611 } 609 612 610 613 /** ··· 976 985 } 977 986 978 987 /* 988 + * tipc_link_send_names - send name table entries to new neighbor 989 + * 990 + * Send routine for bulk delivery of name table messages when contact 991 + * with a new neighbor occurs. No link congestion checking is performed 992 + * because name table messages *must* be delivered. The messages must be 993 + * small enough not to require fragmentation. 994 + * Called without any locks held. 995 + */ 996 + 997 + void tipc_link_send_names(struct list_head *message_list, u32 dest) 998 + { 999 + struct tipc_node *n_ptr; 1000 + struct link *l_ptr; 1001 + struct sk_buff *buf; 1002 + struct sk_buff *temp_buf; 1003 + 1004 + if (list_empty(message_list)) 1005 + return; 1006 + 1007 + read_lock_bh(&tipc_net_lock); 1008 + n_ptr = tipc_node_find(dest); 1009 + if (n_ptr) { 1010 + tipc_node_lock(n_ptr); 1011 + l_ptr = n_ptr->active_links[0]; 1012 + if (l_ptr) { 1013 + /* convert circular list to linear list */ 1014 + ((struct sk_buff *)message_list->prev)->next = NULL; 1015 + link_add_chain_to_outqueue(l_ptr, 1016 + (struct sk_buff *)message_list->next, 0); 1017 + tipc_link_push_queue(l_ptr); 1018 + INIT_LIST_HEAD(message_list); 1019 + } 1020 + tipc_node_unlock(n_ptr); 1021 + } 1022 + read_unlock_bh(&tipc_net_lock); 1023 + 1024 + /* discard the messages if they couldn't be sent */ 1025 + 1026 + list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { 1027 + list_del((struct list_head *)buf); 1028 + buf_discard(buf); 1029 + } 1030 + } 1031 + 1032 + /* 979 1033 * link_send_buf_fast: Entry for data messages where the 980 1034 * destination link is known and the header is complete, 981 1035 * inclusive total message length. Very time critical. ··· 1066 1030 int res; 1067 1031 u32 selector = msg_origport(buf_msg(buf)) & 1; 1068 1032 u32 dummy; 1069 - 1070 - if (destnode == tipc_own_addr) 1071 - return tipc_port_recv_msg(buf); 1072 1033 1073 1034 read_lock_bh(&tipc_net_lock); 1074 1035 n_ptr = tipc_node_find(destnode); ··· 1691 1658 continue; 1692 1659 } 1693 1660 1661 + /* Discard unicast link messages destined for another node */ 1662 + 1694 1663 if (unlikely(!msg_short(msg) && 1695 1664 (msg_destnode(msg) != tipc_own_addr))) 1696 1665 goto cont; 1697 - 1698 - /* Discard non-routeable messages destined for another node */ 1699 - 1700 - if (unlikely(!msg_isdata(msg) && 1701 - (msg_destnode(msg) != tipc_own_addr))) { 1702 - if ((msg_user(msg) != CONN_MANAGER) && 1703 - (msg_user(msg) != MSG_FRAGMENTER)) 1704 - goto cont; 1705 - } 1706 1666 1707 1667 /* Locate neighboring node that sent message */ 1708 1668 ··· 1704 1678 goto cont; 1705 1679 tipc_node_lock(n_ptr); 1706 1680 1707 - /* Don't talk to neighbor during cleanup after last session */ 1708 - 1709 - if (n_ptr->cleanup_required) { 1710 - tipc_node_unlock(n_ptr); 1711 - goto cont; 1712 - } 1713 - 1714 1681 /* Locate unicast link endpoint that should handle message */ 1715 1682 1716 1683 l_ptr = n_ptr->links[b_ptr->identity]; 1717 1684 if (unlikely(!l_ptr)) { 1685 + tipc_node_unlock(n_ptr); 1686 + goto cont; 1687 + } 1688 + 1689 + /* Verify that communication with node is currently allowed */ 1690 + 1691 + if ((n_ptr->block_setup & WAIT_PEER_DOWN) && 1692 + msg_user(msg) == LINK_PROTOCOL && 1693 + (msg_type(msg) == RESET_MSG || 1694 + msg_type(msg) == ACTIVATE_MSG) && 1695 + !msg_redundant_link(msg)) 1696 + n_ptr->block_setup &= ~WAIT_PEER_DOWN; 1697 + 1698 + if (n_ptr->block_setup) { 1718 1699 tipc_node_unlock(n_ptr); 1719 1700 goto cont; 1720 1701 } ··· 1956 1923 1957 1924 if (link_blocked(l_ptr)) 1958 1925 return; 1926 + 1927 + /* Abort non-RESET send if communication with node is prohibited */ 1928 + 1929 + if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG)) 1930 + return; 1931 + 1959 1932 msg_set_type(msg, msg_typ); 1960 1933 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); 1961 1934 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); ··· 2090 2051 case RESET_MSG: 2091 2052 if (!link_working_unknown(l_ptr) && 2092 2053 (l_ptr->peer_session != INVALID_SESSION)) { 2093 - if (msg_session(msg) == l_ptr->peer_session) 2094 - break; /* duplicate: ignore */ 2054 + if (less_eq(msg_session(msg), l_ptr->peer_session)) 2055 + break; /* duplicate or old reset: ignore */ 2095 2056 } 2057 + 2058 + if (!msg_redundant_link(msg) && (link_working_working(l_ptr) || 2059 + link_working_unknown(l_ptr))) { 2060 + /* 2061 + * peer has lost contact -- don't allow peer's links 2062 + * to reactivate before we recognize loss & clean up 2063 + */ 2064 + l_ptr->owner->block_setup = WAIT_NODE_DOWN; 2065 + } 2066 + 2096 2067 /* fall thru' */ 2097 2068 case ACTIVATE_MSG: 2098 2069 /* Update link settings according other endpoint's values */
+1
net/tipc/link.h
··· 223 223 struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space); 224 224 void tipc_link_reset(struct link *l_ptr); 225 225 int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 226 + void tipc_link_send_names(struct list_head *message_list, u32 dest); 226 227 int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 227 228 u32 tipc_link_get_max_pkt(u32 dest, u32 selector); 228 229 int tipc_link_send_sections_fast(struct tipc_port *sender,
+29 -6
net/tipc/name_distr.c
··· 173 173 * tipc_named_node_up - tell specified node about all publications by this node 174 174 */ 175 175 176 - void tipc_named_node_up(unsigned long node) 176 + void tipc_named_node_up(unsigned long nodearg) 177 177 { 178 + struct tipc_node *n_ptr; 179 + struct link *l_ptr; 178 180 struct publication *publ; 179 181 struct distr_item *item = NULL; 180 182 struct sk_buff *buf = NULL; 183 + struct list_head message_list; 184 + u32 node = (u32)nodearg; 181 185 u32 left = 0; 182 186 u32 rest; 183 - u32 max_item_buf; 187 + u32 max_item_buf = 0; 188 + 189 + /* compute maximum amount of publication data to send per message */ 190 + 191 + read_lock_bh(&tipc_net_lock); 192 + n_ptr = tipc_node_find(node); 193 + if (n_ptr) { 194 + tipc_node_lock(n_ptr); 195 + l_ptr = n_ptr->active_links[0]; 196 + if (l_ptr) 197 + max_item_buf = ((l_ptr->max_pkt - INT_H_SIZE) / 198 + ITEM_SIZE) * ITEM_SIZE; 199 + tipc_node_unlock(n_ptr); 200 + } 201 + read_unlock_bh(&tipc_net_lock); 202 + if (!max_item_buf) 203 + return; 204 + 205 + /* create list of publication messages, then send them as a unit */ 206 + 207 + INIT_LIST_HEAD(&message_list); 184 208 185 209 read_lock_bh(&tipc_nametbl_lock); 186 - max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE; 187 - max_item_buf *= ITEM_SIZE; 188 210 rest = publ_cnt * ITEM_SIZE; 189 211 190 212 list_for_each_entry(publ, &publ_root, local_list) { ··· 224 202 item++; 225 203 left -= ITEM_SIZE; 226 204 if (!left) { 227 - msg_set_link_selector(buf_msg(buf), node); 228 - tipc_link_send(buf, node, node); 205 + list_add_tail((struct list_head *)buf, &message_list); 229 206 buf = NULL; 230 207 } 231 208 } 232 209 exit: 233 210 read_unlock_bh(&tipc_nametbl_lock); 211 + 212 + tipc_link_send_names(&message_list, (u32)node); 234 213 } 235 214 236 215 /**
-11
net/tipc/net.c
··· 141 141 return; 142 142 msg = buf_msg(buf); 143 143 144 - msg_incr_reroute_cnt(msg); 145 - if (msg_reroute_cnt(msg) > 6) { 146 - if (msg_errcode(msg)) { 147 - buf_discard(buf); 148 - } else { 149 - tipc_reject_msg(buf, msg_destport(msg) ? 150 - TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); 151 - } 152 - return; 153 - } 154 - 155 144 /* Handle message for this node */ 156 145 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); 157 146 if (tipc_in_scope(dnode, tipc_own_addr)) {
+30 -25
net/tipc/node.c
··· 112 112 break; 113 113 } 114 114 list_add_tail(&n_ptr->list, &temp_node->list); 115 + n_ptr->block_setup = WAIT_PEER_DOWN; 115 116 116 117 tipc_num_nodes++; 117 118 ··· 313 312 } 314 313 } 315 314 316 - static void node_cleanup_finished(unsigned long node_addr) 315 + static void node_name_purge_complete(unsigned long node_addr) 317 316 { 318 317 struct tipc_node *n_ptr; 319 318 ··· 321 320 n_ptr = tipc_node_find(node_addr); 322 321 if (n_ptr) { 323 322 tipc_node_lock(n_ptr); 324 - n_ptr->cleanup_required = 0; 323 + n_ptr->block_setup &= ~WAIT_NAMES_GONE; 325 324 tipc_node_unlock(n_ptr); 326 325 } 327 326 read_unlock_bh(&tipc_net_lock); ··· 332 331 char addr_string[16]; 333 332 u32 i; 334 333 335 - /* Clean up broadcast reception remains */ 336 - n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; 337 - while (n_ptr->bclink.deferred_head) { 338 - struct sk_buff *buf = n_ptr->bclink.deferred_head; 339 - n_ptr->bclink.deferred_head = buf->next; 340 - buf_discard(buf); 341 - } 342 - if (n_ptr->bclink.defragm) { 343 - buf_discard(n_ptr->bclink.defragm); 344 - n_ptr->bclink.defragm = NULL; 345 - } 346 - 347 - if (n_ptr->bclink.supported) { 348 - tipc_bclink_acknowledge(n_ptr, 349 - mod(n_ptr->bclink.acked + 10000)); 350 - tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr); 351 - if (n_ptr->addr < tipc_own_addr) 352 - tipc_own_tag--; 353 - } 354 - 355 334 info("Lost contact with %s\n", 356 335 tipc_addr_string_fill(addr_string, n_ptr->addr)); 336 + 337 + /* Flush broadcast link info associated with lost node */ 338 + 339 + if (n_ptr->bclink.supported) { 340 + n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; 341 + while (n_ptr->bclink.deferred_head) { 342 + struct sk_buff *buf = n_ptr->bclink.deferred_head; 343 + n_ptr->bclink.deferred_head = buf->next; 344 + buf_discard(buf); 345 + } 346 + 347 + if (n_ptr->bclink.defragm) { 348 + buf_discard(n_ptr->bclink.defragm); 349 + n_ptr->bclink.defragm = NULL; 350 + } 351 + 352 + tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr); 353 + tipc_bclink_acknowledge(n_ptr, 354 + mod(n_ptr->bclink.acked + 10000)); 355 + if (n_ptr->addr < tipc_own_addr) 356 + tipc_own_tag--; 357 + 358 + n_ptr->bclink.supported = 0; 359 + } 357 360 358 361 /* Abort link changeover */ 359 362 for (i = 0; i < MAX_BEARERS; i++) { ··· 372 367 /* Notify subscribers */ 373 368 tipc_nodesub_notify(n_ptr); 374 369 375 - /* Prevent re-contact with node until all cleanup is done */ 370 + /* Prevent re-contact with node until cleanup is done */ 376 371 377 - n_ptr->cleanup_required = 1; 378 - tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); 372 + n_ptr->block_setup = WAIT_PEER_DOWN | WAIT_NAMES_GONE; 373 + tipc_k_signal((Handler)node_name_purge_complete, n_ptr->addr); 379 374 } 380 375 381 376 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
+8 -2
net/tipc/node.h
··· 42 42 #include "net.h" 43 43 #include "bearer.h" 44 44 45 + /* Flags used to block (re)establishment of contact with a neighboring node */ 46 + 47 + #define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */ 48 + #define WAIT_NAMES_GONE 0x0002 /* wait for peer's publications to be purged */ 49 + #define WAIT_NODE_DOWN 0x0004 /* wait until peer node is declared down */ 50 + 45 51 /** 46 52 * struct tipc_node - TIPC node structure 47 53 * @addr: network address of node ··· 58 52 * @active_links: pointers to active links to node 59 53 * @links: pointers to all links to node 60 54 * @working_links: number of working links to node (both active and standby) 61 - * @cleanup_required: non-zero if cleaning up after a prior loss of contact 55 + * @block_setup: bit mask of conditions preventing link establishment to node 62 56 * @link_cnt: number of links to node 63 57 * @permit_changeover: non-zero if node has redundant links to this system 64 58 * @bclink: broadcast-related info ··· 83 77 struct link *links[MAX_BEARERS]; 84 78 int link_cnt; 85 79 int working_links; 86 - int cleanup_required; 80 + int block_setup; 87 81 int permit_changeover; 88 82 struct { 89 83 int supported;
+24 -27
net/tipc/socket.c
··· 49 49 struct sock sk; 50 50 struct tipc_port *p; 51 51 struct tipc_portid peer_name; 52 - long conn_timeout; 52 + unsigned int conn_timeout; 53 53 }; 54 54 55 55 #define tipc_sk(sk) ((struct tipc_sock *)(sk)) ··· 231 231 sock_init_data(sock, sk); 232 232 sk->sk_backlog_rcv = backlog_rcv; 233 233 tipc_sk(sk)->p = tp_ptr; 234 - tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); 234 + tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; 235 235 236 236 spin_unlock_bh(tp_ptr->lock); 237 237 ··· 525 525 struct tipc_port *tport = tipc_sk_port(sk); 526 526 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; 527 527 int needs_conn; 528 + long timeout_val; 528 529 int res = -EINVAL; 529 530 530 531 if (unlikely(!dest)) ··· 565 564 reject_rx_queue(sk); 566 565 } 567 566 567 + timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 568 + 568 569 do { 569 570 if (dest->addrtype == TIPC_ADDR_NAME) { 570 571 res = dest_name_check(dest, m); ··· 603 600 sock->state = SS_CONNECTING; 604 601 break; 605 602 } 606 - if (m->msg_flags & MSG_DONTWAIT) { 607 - res = -EWOULDBLOCK; 603 + if (timeout_val <= 0L) { 604 + res = timeout_val ? timeout_val : -EWOULDBLOCK; 608 605 break; 609 606 } 610 607 release_sock(sk); 611 - res = wait_event_interruptible(*sk_sleep(sk), 612 - !tport->congested); 608 + timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), 609 + !tport->congested, timeout_val); 613 610 lock_sock(sk); 614 - if (res) 615 - break; 616 611 } while (1); 617 612 618 613 exit: ··· 637 636 struct sock *sk = sock->sk; 638 637 struct tipc_port *tport = tipc_sk_port(sk); 639 638 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; 639 + long timeout_val; 640 640 int res; 641 641 642 642 /* Handle implied connection establishment */ ··· 652 650 if (iocb) 653 651 lock_sock(sk); 654 652 653 + timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 654 + 655 655 do { 656 656 if (unlikely(sock->state != SS_CONNECTED)) { 657 657 if (sock->state == SS_DISCONNECTING) ··· 667 663 total_len); 668 664 if (likely(res != -ELINKCONG)) 669 665 break; 670 - if (m->msg_flags & MSG_DONTWAIT) { 671 - res = -EWOULDBLOCK; 666 + if (timeout_val <= 0L) { 667 + res = timeout_val ? timeout_val : -EWOULDBLOCK; 672 668 break; 673 669 } 674 670 release_sock(sk); 675 - res = wait_event_interruptible(*sk_sleep(sk), 676 - (!tport->congested || !tport->connected)); 671 + timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), 672 + (!tport->congested || !tport->connected), timeout_val); 677 673 lock_sock(sk); 678 - if (res) 679 - break; 680 674 } while (1); 681 675 682 676 if (iocb) ··· 1371 1369 struct msghdr m = {NULL,}; 1372 1370 struct sk_buff *buf; 1373 1371 struct tipc_msg *msg; 1374 - long timeout; 1372 + unsigned int timeout; 1375 1373 int res; 1376 1374 1377 1375 lock_sock(sk); ··· 1436 1434 res = wait_event_interruptible_timeout(*sk_sleep(sk), 1437 1435 (!skb_queue_empty(&sk->sk_receive_queue) || 1438 1436 (sock->state != SS_CONNECTING)), 1439 - timeout ? timeout : MAX_SCHEDULE_TIMEOUT); 1437 + timeout ? (long)msecs_to_jiffies(timeout) 1438 + : MAX_SCHEDULE_TIMEOUT); 1440 1439 lock_sock(sk); 1441 1440 1442 1441 if (res > 0) { ··· 1483 1480 1484 1481 lock_sock(sk); 1485 1482 1486 - if (sock->state == SS_READY) 1487 - res = -EOPNOTSUPP; 1488 - else if (sock->state != SS_UNCONNECTED) 1483 + if (sock->state != SS_UNCONNECTED) 1489 1484 res = -EINVAL; 1490 1485 else { 1491 1486 sock->state = SS_LISTENING; ··· 1511 1510 1512 1511 lock_sock(sk); 1513 1512 1514 - if (sock->state == SS_READY) { 1515 - res = -EOPNOTSUPP; 1516 - goto exit; 1517 - } 1518 1513 if (sock->state != SS_LISTENING) { 1519 1514 res = -EINVAL; 1520 1515 goto exit; ··· 1693 1696 res = tipc_set_portunreturnable(tport->ref, value); 1694 1697 break; 1695 1698 case TIPC_CONN_TIMEOUT: 1696 - tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); 1699 + tipc_sk(sk)->conn_timeout = value; 1697 1700 /* no need to set "res", since already 0 at this point */ 1698 1701 break; 1699 1702 default: ··· 1749 1752 res = tipc_portunreturnable(tport->ref, &value); 1750 1753 break; 1751 1754 case TIPC_CONN_TIMEOUT: 1752 - value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); 1755 + value = tipc_sk(sk)->conn_timeout; 1753 1756 /* no need to set "res", since already 0 at this point */ 1754 1757 break; 1755 1758 case TIPC_NODE_RECVQ_DEPTH: ··· 1787 1790 .bind = bind, 1788 1791 .connect = connect, 1789 1792 .socketpair = sock_no_socketpair, 1790 - .accept = accept, 1793 + .accept = sock_no_accept, 1791 1794 .getname = get_name, 1792 1795 .poll = poll, 1793 1796 .ioctl = sock_no_ioctl, 1794 - .listen = listen, 1797 + .listen = sock_no_listen, 1795 1798 .shutdown = shutdown, 1796 1799 .setsockopt = setsockopt, 1797 1800 .getsockopt = getsockopt,
+1 -2
net/tipc/subscr.c
··· 151 151 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 152 152 return; 153 153 154 - sub->event_cb(sub, found_lower, found_upper, event, port_ref, node); 154 + subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); 155 155 } 156 156 157 157 /** ··· 365 365 subscr_terminate(subscriber); 366 366 return NULL; 367 367 } 368 - sub->event_cb = subscr_send_event; 369 368 INIT_LIST_HEAD(&sub->nameseq_list); 370 369 list_add(&sub->subscription_list, &subscriber->subscription_list); 371 370 sub->server_ref = subscriber->port_ref;
-6
net/tipc/subscr.h
··· 39 39 40 40 struct subscription; 41 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 - 46 42 /** 47 43 * struct subscription - TIPC network topology subscription object 48 44 * @seq: name sequence associated with subscription 49 45 * @timeout: duration of subscription (in ms) 50 46 * @filter: event filtering to be done for subscription 51 - * @event_cb: routine invoked when a subscription event is detected 52 47 * @timer: timer governing subscription duration (optional) 53 48 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 54 49 * @subscription_list: adjacent subscriptions in subscriber's subscription list ··· 56 61 struct tipc_name_seq seq; 57 62 u32 timeout; 58 63 u32 filter; 59 - tipc_subscr_event event_cb; 60 64 struct timer_list timer; 61 65 struct list_head nameseq_list; 62 66 struct list_head subscription_list;