diff options
Diffstat (limited to 'net/tipc/node.c')
| -rw-r--r-- | net/tipc/node.c | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 488019766433..db2a6c3e0be9 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include "monitor.h" | 43 | #include "monitor.h" |
| 44 | #include "discover.h" | 44 | #include "discover.h" |
| 45 | #include "netlink.h" | 45 | #include "netlink.h" |
| 46 | #include "trace.h" | ||
| 46 | 47 | ||
| 47 | #define INVALID_NODE_SIG 0x10000 | 48 | #define INVALID_NODE_SIG 0x10000 |
| 48 | #define NODE_CLEANUP_AFTER 300000 | 49 | #define NODE_CLEANUP_AFTER 300000 |
| @@ -432,6 +433,7 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, | |||
| 432 | break; | 433 | break; |
| 433 | } | 434 | } |
| 434 | list_add_tail_rcu(&n->list, &temp_node->list); | 435 | list_add_tail_rcu(&n->list, &temp_node->list); |
| 436 | trace_tipc_node_create(n, true, " "); | ||
| 435 | exit: | 437 | exit: |
| 436 | spin_unlock_bh(&tn->node_list_lock); | 438 | spin_unlock_bh(&tn->node_list_lock); |
| 437 | return n; | 439 | return n; |
| @@ -459,6 +461,7 @@ static void tipc_node_delete_from_list(struct tipc_node *node) | |||
| 459 | 461 | ||
| 460 | static void tipc_node_delete(struct tipc_node *node) | 462 | static void tipc_node_delete(struct tipc_node *node) |
| 461 | { | 463 | { |
| 464 | trace_tipc_node_delete(node, true, " "); | ||
| 462 | tipc_node_delete_from_list(node); | 465 | tipc_node_delete_from_list(node); |
| 463 | 466 | ||
| 464 | del_timer_sync(&node->timer); | 467 | del_timer_sync(&node->timer); |
| @@ -616,6 +619,7 @@ static void tipc_node_timeout(struct timer_list *t) | |||
| 616 | int bearer_id; | 619 | int bearer_id; |
| 617 | int rc = 0; | 620 | int rc = 0; |
| 618 | 621 | ||
| 622 | trace_tipc_node_timeout(n, false, " "); | ||
| 619 | if (!node_is_up(n) && tipc_node_cleanup(n)) { | 623 | if (!node_is_up(n) && tipc_node_cleanup(n)) { |
| 620 | /*Removing the reference of Timer*/ | 624 | /*Removing the reference of Timer*/ |
| 621 | tipc_node_put(n); | 625 | tipc_node_put(n); |
| @@ -624,6 +628,12 @@ static void tipc_node_timeout(struct timer_list *t) | |||
| 624 | 628 | ||
| 625 | __skb_queue_head_init(&xmitq); | 629 | __skb_queue_head_init(&xmitq); |
| 626 | 630 | ||
| 631 | /* Initial node interval to value larger (10 seconds), then it will be | ||
| 632 | * recalculated with link lowest tolerance | ||
| 633 | */ | ||
| 634 | tipc_node_read_lock(n); | ||
| 635 | n->keepalive_intv = 10000; | ||
| 636 | tipc_node_read_unlock(n); | ||
| 627 | for (bearer_id = 0; remains && (bearer_id < MAX_BEARERS); bearer_id++) { | 637 | for (bearer_id = 0; remains && (bearer_id < MAX_BEARERS); bearer_id++) { |
| 628 | tipc_node_read_lock(n); | 638 | tipc_node_read_lock(n); |
| 629 | le = &n->links[bearer_id]; | 639 | le = &n->links[bearer_id]; |
| @@ -675,6 +685,7 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
| 675 | 685 | ||
| 676 | pr_debug("Established link <%s> on network plane %c\n", | 686 | pr_debug("Established link <%s> on network plane %c\n", |
| 677 | tipc_link_name(nl), tipc_link_plane(nl)); | 687 | tipc_link_name(nl), tipc_link_plane(nl)); |
| 688 | trace_tipc_node_link_up(n, true, " "); | ||
| 678 | 689 | ||
| 679 | /* Ensure that a STATE message goes first */ | 690 | /* Ensure that a STATE message goes first */ |
| 680 | tipc_link_build_state_msg(nl, xmitq); | 691 | tipc_link_build_state_msg(nl, xmitq); |
| @@ -777,6 +788,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, | |||
| 777 | if (tipc_link_peer_is_down(l)) | 788 | if (tipc_link_peer_is_down(l)) |
| 778 | tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); | 789 | tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); |
| 779 | tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); | 790 | tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); |
| 791 | trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link down!"); | ||
| 780 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | 792 | tipc_link_fsm_evt(l, LINK_RESET_EVT); |
| 781 | tipc_link_reset(l); | 793 | tipc_link_reset(l); |
| 782 | tipc_link_build_reset_msg(l, xmitq); | 794 | tipc_link_build_reset_msg(l, xmitq); |
| @@ -794,6 +806,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, | |||
| 794 | tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); | 806 | tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); |
| 795 | n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1); | 807 | n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1); |
| 796 | tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq); | 808 | tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq); |
| 809 | trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link down -> failover!"); | ||
| 797 | tipc_link_reset(l); | 810 | tipc_link_reset(l); |
| 798 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | 811 | tipc_link_fsm_evt(l, LINK_RESET_EVT); |
| 799 | tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); | 812 | tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); |
| @@ -826,6 +839,7 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) | |||
| 826 | /* Defuse pending tipc_node_link_up() */ | 839 | /* Defuse pending tipc_node_link_up() */ |
| 827 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | 840 | tipc_link_fsm_evt(l, LINK_RESET_EVT); |
| 828 | } | 841 | } |
| 842 | trace_tipc_node_link_down(n, true, "node link down or deleted!"); | ||
| 829 | tipc_node_write_unlock(n); | 843 | tipc_node_write_unlock(n); |
| 830 | if (delete) | 844 | if (delete) |
| 831 | tipc_mon_remove_peer(n->net, n->addr, old_bearer_id); | 845 | tipc_mon_remove_peer(n->net, n->addr, old_bearer_id); |
| @@ -1015,6 +1029,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, | |||
| 1015 | *respond = false; | 1029 | *respond = false; |
| 1016 | goto exit; | 1030 | goto exit; |
| 1017 | } | 1031 | } |
| 1032 | trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link created!"); | ||
| 1018 | tipc_link_reset(l); | 1033 | tipc_link_reset(l); |
| 1019 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | 1034 | tipc_link_fsm_evt(l, LINK_RESET_EVT); |
| 1020 | if (n->state == NODE_FAILINGOVER) | 1035 | if (n->state == NODE_FAILINGOVER) |
| @@ -1054,6 +1069,7 @@ static void tipc_node_reset_links(struct tipc_node *n) | |||
| 1054 | 1069 | ||
| 1055 | pr_warn("Resetting all links to %x\n", n->addr); | 1070 | pr_warn("Resetting all links to %x\n", n->addr); |
| 1056 | 1071 | ||
| 1072 | trace_tipc_node_reset_links(n, true, " "); | ||
| 1057 | for (i = 0; i < MAX_BEARERS; i++) { | 1073 | for (i = 0; i < MAX_BEARERS; i++) { |
| 1058 | tipc_node_link_down(n, i, false); | 1074 | tipc_node_link_down(n, i, false); |
| 1059 | } | 1075 | } |
| @@ -1229,11 +1245,13 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt) | |||
| 1229 | pr_err("Unknown node fsm state %x\n", state); | 1245 | pr_err("Unknown node fsm state %x\n", state); |
| 1230 | break; | 1246 | break; |
| 1231 | } | 1247 | } |
| 1248 | trace_tipc_node_fsm(n->peer_id, n->state, state, evt); | ||
| 1232 | n->state = state; | 1249 | n->state = state; |
| 1233 | return; | 1250 | return; |
| 1234 | 1251 | ||
| 1235 | illegal_evt: | 1252 | illegal_evt: |
| 1236 | pr_err("Illegal node fsm evt %x in state %x\n", evt, state); | 1253 | pr_err("Illegal node fsm evt %x in state %x\n", evt, state); |
| 1254 | trace_tipc_node_fsm(n->peer_id, n->state, state, evt); | ||
| 1237 | } | 1255 | } |
| 1238 | 1256 | ||
| 1239 | static void node_lost_contact(struct tipc_node *n, | 1257 | static void node_lost_contact(struct tipc_node *n, |
| @@ -1247,6 +1265,7 @@ static void node_lost_contact(struct tipc_node *n, | |||
| 1247 | 1265 | ||
| 1248 | pr_debug("Lost contact with %x\n", n->addr); | 1266 | pr_debug("Lost contact with %x\n", n->addr); |
| 1249 | n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER); | 1267 | n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER); |
| 1268 | trace_tipc_node_lost_contact(n, true, " "); | ||
| 1250 | 1269 | ||
| 1251 | /* Clean up broadcast state */ | 1270 | /* Clean up broadcast state */ |
| 1252 | tipc_bcast_remove_peer(n->net, n->bc_entry.link); | 1271 | tipc_bcast_remove_peer(n->net, n->bc_entry.link); |
| @@ -1543,6 +1562,10 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id | |||
| 1543 | if (!skb_queue_empty(&be->inputq1)) | 1562 | if (!skb_queue_empty(&be->inputq1)) |
| 1544 | tipc_node_mcast_rcv(n); | 1563 | tipc_node_mcast_rcv(n); |
| 1545 | 1564 | ||
| 1565 | /* Handle NAME_DISTRIBUTOR messages sent from 1.7 nodes */ | ||
| 1566 | if (!skb_queue_empty(&n->bc_entry.namedq)) | ||
| 1567 | tipc_named_rcv(net, &n->bc_entry.namedq); | ||
| 1568 | |||
| 1546 | /* If reassembly or retransmission failure => reset all links to peer */ | 1569 | /* If reassembly or retransmission failure => reset all links to peer */ |
| 1547 | if (rc & TIPC_LINK_DOWN_EVT) | 1570 | if (rc & TIPC_LINK_DOWN_EVT) |
| 1548 | tipc_node_reset_links(n); | 1571 | tipc_node_reset_links(n); |
| @@ -1571,6 +1594,10 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, | |||
| 1571 | struct tipc_media_addr *maddr; | 1594 | struct tipc_media_addr *maddr; |
| 1572 | int pb_id; | 1595 | int pb_id; |
| 1573 | 1596 | ||
| 1597 | if (trace_tipc_node_check_state_enabled()) { | ||
| 1598 | trace_tipc_skb_dump(skb, false, "skb for node state check"); | ||
| 1599 | trace_tipc_node_check_state(n, true, " "); | ||
| 1600 | } | ||
| 1574 | l = n->links[bearer_id].link; | 1601 | l = n->links[bearer_id].link; |
| 1575 | if (!l) | 1602 | if (!l) |
| 1576 | return false; | 1603 | return false; |
| @@ -1588,8 +1615,11 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, | |||
| 1588 | } | 1615 | } |
| 1589 | } | 1616 | } |
| 1590 | 1617 | ||
| 1591 | if (!tipc_link_validate_msg(l, hdr)) | 1618 | if (!tipc_link_validate_msg(l, hdr)) { |
| 1619 | trace_tipc_skb_dump(skb, false, "PROTO invalid (2)!"); | ||
| 1620 | trace_tipc_link_dump(l, TIPC_DUMP_NONE, "PROTO invalid (2)!"); | ||
| 1592 | return false; | 1621 | return false; |
| 1622 | } | ||
| 1593 | 1623 | ||
| 1594 | /* Check and update node accesibility if applicable */ | 1624 | /* Check and update node accesibility if applicable */ |
| 1595 | if (state == SELF_UP_PEER_COMING) { | 1625 | if (state == SELF_UP_PEER_COMING) { |
| @@ -1619,6 +1649,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, | |||
| 1619 | syncpt = oseqno + exp_pkts - 1; | 1649 | syncpt = oseqno + exp_pkts - 1; |
| 1620 | if (pl && tipc_link_is_up(pl)) { | 1650 | if (pl && tipc_link_is_up(pl)) { |
| 1621 | __tipc_node_link_down(n, &pb_id, xmitq, &maddr); | 1651 | __tipc_node_link_down(n, &pb_id, xmitq, &maddr); |
| 1652 | trace_tipc_node_link_down(n, true, | ||
| 1653 | "node link down <- failover!"); | ||
| 1622 | tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), | 1654 | tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), |
| 1623 | tipc_link_inputq(l)); | 1655 | tipc_link_inputq(l)); |
| 1624 | } | 1656 | } |
| @@ -2425,3 +2457,65 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, | |||
| 2425 | 2457 | ||
| 2426 | return skb->len; | 2458 | return skb->len; |
| 2427 | } | 2459 | } |
| 2460 | |||
| 2461 | u32 tipc_node_get_addr(struct tipc_node *node) | ||
| 2462 | { | ||
| 2463 | return (node) ? node->addr : 0; | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | /** | ||
| 2467 | * tipc_node_dump - dump TIPC node data | ||
| 2468 | * @n: tipc node to be dumped | ||
| 2469 | * @more: dump more? | ||
| 2470 | * - false: dump only tipc node data | ||
| 2471 | * - true: dump node link data as well | ||
| 2472 | * @buf: returned buffer of dump data in format | ||
| 2473 | */ | ||
| 2474 | int tipc_node_dump(struct tipc_node *n, bool more, char *buf) | ||
| 2475 | { | ||
| 2476 | int i = 0; | ||
| 2477 | size_t sz = (more) ? NODE_LMAX : NODE_LMIN; | ||
| 2478 | |||
| 2479 | if (!n) { | ||
| 2480 | i += scnprintf(buf, sz, "node data: (null)\n"); | ||
| 2481 | return i; | ||
| 2482 | } | ||
| 2483 | |||
| 2484 | i += scnprintf(buf, sz, "node data: %x", n->addr); | ||
| 2485 | i += scnprintf(buf + i, sz - i, " %x", n->state); | ||
| 2486 | i += scnprintf(buf + i, sz - i, " %d", n->active_links[0]); | ||
| 2487 | i += scnprintf(buf + i, sz - i, " %d", n->active_links[1]); | ||
| 2488 | i += scnprintf(buf + i, sz - i, " %x", n->action_flags); | ||
| 2489 | i += scnprintf(buf + i, sz - i, " %u", n->failover_sent); | ||
| 2490 | i += scnprintf(buf + i, sz - i, " %u", n->sync_point); | ||
| 2491 | i += scnprintf(buf + i, sz - i, " %d", n->link_cnt); | ||
| 2492 | i += scnprintf(buf + i, sz - i, " %u", n->working_links); | ||
| 2493 | i += scnprintf(buf + i, sz - i, " %x", n->capabilities); | ||
| 2494 | i += scnprintf(buf + i, sz - i, " %lu\n", n->keepalive_intv); | ||
| 2495 | |||
| 2496 | if (!more) | ||
| 2497 | return i; | ||
| 2498 | |||
| 2499 | i += scnprintf(buf + i, sz - i, "link_entry[0]:\n"); | ||
| 2500 | i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[0].mtu); | ||
| 2501 | i += scnprintf(buf + i, sz - i, " media: "); | ||
| 2502 | i += tipc_media_addr_printf(buf + i, sz - i, &n->links[0].maddr); | ||
| 2503 | i += scnprintf(buf + i, sz - i, "\n"); | ||
| 2504 | i += tipc_link_dump(n->links[0].link, TIPC_DUMP_NONE, buf + i); | ||
| 2505 | i += scnprintf(buf + i, sz - i, " inputq: "); | ||
| 2506 | i += tipc_list_dump(&n->links[0].inputq, false, buf + i); | ||
| 2507 | |||
| 2508 | i += scnprintf(buf + i, sz - i, "link_entry[1]:\n"); | ||
| 2509 | i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[1].mtu); | ||
| 2510 | i += scnprintf(buf + i, sz - i, " media: "); | ||
| 2511 | i += tipc_media_addr_printf(buf + i, sz - i, &n->links[1].maddr); | ||
| 2512 | i += scnprintf(buf + i, sz - i, "\n"); | ||
| 2513 | i += tipc_link_dump(n->links[1].link, TIPC_DUMP_NONE, buf + i); | ||
| 2514 | i += scnprintf(buf + i, sz - i, " inputq: "); | ||
| 2515 | i += tipc_list_dump(&n->links[1].inputq, false, buf + i); | ||
| 2516 | |||
| 2517 | i += scnprintf(buf + i, sz - i, "bclink:\n "); | ||
| 2518 | i += tipc_link_dump(n->bc_entry.link, TIPC_DUMP_NONE, buf + i); | ||
| 2519 | |||
| 2520 | return i; | ||
| 2521 | } | ||
