aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c84
1 files changed, 81 insertions, 3 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 558df25a7fc6..6a0680ba98a9 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -407,6 +407,44 @@ bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b,
407 return true; 407 return true;
408} 408}
409 409
410void tipc_node_delete_links(struct net *net, int bearer_id)
411{
412 struct tipc_net *tn = net_generic(net, tipc_net_id);
413 struct tipc_link *l;
414 struct tipc_node *n;
415
416 rcu_read_lock();
417 list_for_each_entry_rcu(n, &tn->node_list, list) {
418 tipc_node_lock(n);
419 l = n->links[bearer_id].link;
420 if (l) {
421 tipc_link_reset(l);
422 n->links[bearer_id].link = NULL;
423 n->link_cnt--;
424 }
425 tipc_node_unlock(n);
426 kfree(l);
427 }
428 rcu_read_unlock();
429}
430
431static void tipc_node_reset_links(struct tipc_node *n)
432{
433 char addr_string[16];
434 u32 i;
435
436 tipc_node_lock(n);
437
438 pr_warn("Resetting all links to %s\n",
439 tipc_addr_string_fill(addr_string, n->addr));
440
441 for (i = 0; i < MAX_BEARERS; i++) {
442 if (n->links[i].link)
443 tipc_link_reset(n->links[i].link);
444 }
445 tipc_node_unlock(n);
446}
447
410void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 448void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
411{ 449{
412 n_ptr->links[l_ptr->bearer_id].link = l_ptr; 450 n_ptr->links[l_ptr->bearer_id].link = l_ptr;
@@ -721,7 +759,7 @@ void tipc_node_unlock(struct tipc_node *node)
721 tipc_bclink_input(net); 759 tipc_bclink_input(net);
722 760
723 if (flags & TIPC_BCAST_RESET) 761 if (flags & TIPC_BCAST_RESET)
724 tipc_link_reset_all(node); 762 tipc_node_reset_links(node);
725} 763}
726 764
727/* Caller should hold node lock for the passed node */ 765/* Caller should hold node lock for the passed node */
@@ -836,6 +874,40 @@ int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
836 return 0; 874 return 0;
837} 875}
838 876
877/* tipc_node_tnl_init(): handle a received TUNNEL_PROTOCOL packet,
878 * in order to control parallel link failover or synchronization
879 */
880static void tipc_node_tnl_init(struct tipc_node *n, int bearer_id,
881 struct sk_buff *skb)
882{
883 struct tipc_link *tnl, *pl;
884 struct tipc_msg *hdr = buf_msg(skb);
885 u16 oseqno = msg_seqno(hdr);
886 int pb_id = msg_bearer_id(hdr);
887
888 if (pb_id >= MAX_BEARERS)
889 return;
890
891 tnl = n->links[bearer_id].link;
892 if (!tnl)
893 return;
894
895 /* Ignore if duplicate */
896 if (less(oseqno, tnl->rcv_nxt))
897 return;
898
899 pl = n->links[pb_id].link;
900 if (!pl)
901 return;
902
903 if (msg_type(hdr) == FAILOVER_MSG) {
904 if (tipc_link_is_up(pl)) {
905 tipc_link_reset(pl);
906 pl->exec_mode = TIPC_LINK_BLOCKED;
907 }
908 }
909}
910
839/** 911/**
840 * tipc_rcv - process TIPC packets/messages arriving from off-node 912 * tipc_rcv - process TIPC packets/messages arriving from off-node
841 * @net: the applicable net namespace 913 * @net: the applicable net namespace
@@ -854,6 +926,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
854 struct tipc_media_addr *maddr; 926 struct tipc_media_addr *maddr;
855 int bearer_id = b->identity; 927 int bearer_id = b->identity;
856 int rc = 0; 928 int rc = 0;
929 int usr;
857 930
858 __skb_queue_head_init(&xmitq); 931 __skb_queue_head_init(&xmitq);
859 932
@@ -863,8 +936,9 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
863 936
864 /* Handle arrival of a non-unicast link packet */ 937 /* Handle arrival of a non-unicast link packet */
865 hdr = buf_msg(skb); 938 hdr = buf_msg(skb);
939 usr = msg_user(hdr);
866 if (unlikely(msg_non_seq(hdr))) { 940 if (unlikely(msg_non_seq(hdr))) {
867 if (msg_user(hdr) == LINK_CONFIG) 941 if (usr == LINK_CONFIG)
868 tipc_disc_rcv(net, skb, b); 942 tipc_disc_rcv(net, skb, b);
869 else 943 else
870 tipc_bclink_rcv(net, skb); 944 tipc_bclink_rcv(net, skb);
@@ -877,6 +951,10 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
877 goto discard; 951 goto discard;
878 tipc_node_lock(n); 952 tipc_node_lock(n);
879 953
954 /* Prepare links for tunneled reception if applicable */
955 if (unlikely(usr == TUNNEL_PROTOCOL))
956 tipc_node_tnl_init(n, bearer_id, skb);
957
880 /* Locate link endpoint that should handle packet */ 958 /* Locate link endpoint that should handle packet */
881 l = n->links[bearer_id].link; 959 l = n->links[bearer_id].link;
882 if (unlikely(!l)) 960 if (unlikely(!l))
@@ -887,7 +965,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
887 if (!tipc_node_filter_skb(n, l, hdr)) 965 if (!tipc_node_filter_skb(n, l, hdr))
888 goto unlock; 966 goto unlock;
889 967
890 if (unlikely(msg_user(hdr) == LINK_PROTOCOL)) 968 if (unlikely(usr == LINK_PROTOCOL))
891 tipc_bclink_sync_state(n, hdr); 969 tipc_bclink_sync_state(n, hdr);
892 970
893 /* Release acked broadcast messages */ 971 /* Release acked broadcast messages */