45
45
#include "netlink.h"
46
46
47
47
#define INVALID_NODE_SIG 0x10000
48
+ #define NODE_CLEANUP_AFTER 300000
48
49
49
50
/* Flags used to take different actions according to flag type
50
51
* TIPC_NOTIFY_NODE_DOWN: notify node is down
@@ -96,6 +97,7 @@ struct tipc_bclink_entry {
96
97
* @link_id: local and remote bearer ids of changing link, if any
97
98
* @publ_list: list of publications
98
99
* @rcu: rcu struct for tipc_node
100
+ * @delete_at: indicates the time for deleting a down node
99
101
*/
100
102
struct tipc_node {
101
103
u32 addr ;
@@ -121,6 +123,7 @@ struct tipc_node {
121
123
unsigned long keepalive_intv ;
122
124
struct timer_list timer ;
123
125
struct rcu_head rcu ;
126
+ unsigned long delete_at ;
124
127
};
125
128
126
129
/* Node FSM states and events:
@@ -160,6 +163,7 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
160
163
static struct tipc_node * tipc_node_find_by_id (struct net * net , u8 * id );
161
164
static void tipc_node_put (struct tipc_node * node );
162
165
static bool node_is_up (struct tipc_node * n );
166
+ static void tipc_node_delete_from_list (struct tipc_node * node );
163
167
164
168
struct tipc_sock_conn {
165
169
u32 port ;
@@ -390,6 +394,7 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
390
394
for (i = 0 ; i < MAX_BEARERS ; i ++ )
391
395
spin_lock_init (& n -> links [i ].lock );
392
396
n -> state = SELF_DOWN_PEER_LEAVING ;
397
+ n -> delete_at = jiffies + msecs_to_jiffies (NODE_CLEANUP_AFTER );
393
398
n -> signature = INVALID_NODE_SIG ;
394
399
n -> active_links [0 ] = INVALID_BEARER_ID ;
395
400
n -> active_links [1 ] = INVALID_BEARER_ID ;
@@ -433,11 +438,16 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
433
438
tipc_link_set_abort_limit (l , tol / n -> keepalive_intv );
434
439
}
435
440
436
- static void tipc_node_delete (struct tipc_node * node )
441
+ static void tipc_node_delete_from_list (struct tipc_node * node )
437
442
{
438
443
list_del_rcu (& node -> list );
439
444
hlist_del_rcu (& node -> hash );
440
445
tipc_node_put (node );
446
+ }
447
+
448
+ static void tipc_node_delete (struct tipc_node * node )
449
+ {
450
+ tipc_node_delete_from_list (node );
441
451
442
452
del_timer_sync (& node -> timer );
443
453
tipc_node_put (node );
@@ -544,6 +554,42 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
544
554
tipc_node_put (node );
545
555
}
546
556
557
+ static void tipc_node_clear_links (struct tipc_node * node )
558
+ {
559
+ int i ;
560
+
561
+ for (i = 0 ; i < MAX_BEARERS ; i ++ ) {
562
+ struct tipc_link_entry * le = & node -> links [i ];
563
+
564
+ if (le -> link ) {
565
+ kfree (le -> link );
566
+ le -> link = NULL ;
567
+ node -> link_cnt -- ;
568
+ }
569
+ }
570
+ }
571
+
572
+ /* tipc_node_cleanup - delete nodes that does not
573
+ * have active links for NODE_CLEANUP_AFTER time
574
+ */
575
+ static int tipc_node_cleanup (struct tipc_node * peer )
576
+ {
577
+ struct tipc_net * tn = tipc_net (peer -> net );
578
+ bool deleted = false;
579
+
580
+ spin_lock_bh (& tn -> node_list_lock );
581
+ tipc_node_write_lock (peer );
582
+
583
+ if (!node_is_up (peer ) && time_after (jiffies , peer -> delete_at )) {
584
+ tipc_node_clear_links (peer );
585
+ tipc_node_delete_from_list (peer );
586
+ deleted = true;
587
+ }
588
+ tipc_node_write_unlock (peer );
589
+ spin_unlock_bh (& tn -> node_list_lock );
590
+ return deleted ;
591
+ }
592
+
547
593
/* tipc_node_timeout - handle expiration of node timer
548
594
*/
549
595
static void tipc_node_timeout (struct timer_list * t )
@@ -555,6 +601,12 @@ static void tipc_node_timeout(struct timer_list *t)
555
601
int bearer_id ;
556
602
int rc = 0 ;
557
603
604
+ if (!node_is_up (n ) && tipc_node_cleanup (n )) {
605
+ /*Removing the reference of Timer*/
606
+ tipc_node_put (n );
607
+ return ;
608
+ }
609
+
558
610
__skb_queue_head_init (& xmitq );
559
611
560
612
for (bearer_id = 0 ; remains && (bearer_id < MAX_BEARERS ); bearer_id ++ ) {
@@ -1173,6 +1225,7 @@ static void node_lost_contact(struct tipc_node *n,
1173
1225
uint i ;
1174
1226
1175
1227
pr_debug ("Lost contact with %x\n" , n -> addr );
1228
+ n -> delete_at = jiffies + msecs_to_jiffies (NODE_CLEANUP_AFTER );
1176
1229
1177
1230
/* Clean up broadcast state */
1178
1231
tipc_bcast_remove_peer (n -> net , n -> bc_entry .link );
@@ -1742,7 +1795,6 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
1742
1795
struct tipc_node * peer ;
1743
1796
u32 addr ;
1744
1797
int err ;
1745
- int i ;
1746
1798
1747
1799
/* We identify the peer by its net */
1748
1800
if (!info -> attrs [TIPC_NLA_NET ])
@@ -1777,15 +1829,7 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
1777
1829
goto err_out ;
1778
1830
}
1779
1831
1780
- for (i = 0 ; i < MAX_BEARERS ; i ++ ) {
1781
- struct tipc_link_entry * le = & peer -> links [i ];
1782
-
1783
- if (le -> link ) {
1784
- kfree (le -> link );
1785
- le -> link = NULL ;
1786
- peer -> link_cnt -- ;
1787
- }
1788
- }
1832
+ tipc_node_clear_links (peer );
1789
1833
tipc_node_write_unlock (peer );
1790
1834
tipc_node_delete (peer );
1791
1835
0 commit comments