]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: Fix memory leaks when the transition of neighbor state from non-UP to DOWN
authorzhou-run <166502045+zhou-run@users.noreply.github.com>
Tue, 9 Apr 2024 13:04:39 +0000 (21:04 +0800)
committerbaozhen (RD) <bao.zhen@h3c.com>
Thu, 23 May 2024 07:47:33 +0000 (15:47 +0800)
When receiving a hello packet, if the neighbor state transitions directly from a non-ISIS_ADJ_UP state (such as ISIS_ADJ_INITIALIZING) to ISIS_ADJ_DOWN state, the neighbor entry cannot be deleted. If the neighbor is removed or the neighbor's System ID changes, it may result in memory leakage in the neighbor entry.

Test Scenario:
LAN link between Router A and Router B is established. Router A does not configure neighbor authentication, while Router B is configured with neighbor authentication. When the neighbor entry on Router B ages out, the neighbor state on Router A transitions to INIT. If Router B is then removed, the neighbor state on Router A transitions to DOWN and persists.

Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com>
fix frrbot styling issues found.

fix frrbot styling issues found.

Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com>
isisd/isis_adjacency.c

index 7acd3a2b4e565e551f844ffbd1ed0f747982e571..d23a865ea4a7ef02adbcd416427221ed51a861c0 100644 (file)
@@ -358,12 +358,15 @@ void isis_adj_state_change(struct isis_adjacency **padj,
                                 * purposes */
                                adj->last_flap = time(NULL);
                                adj->flaps++;
-                       } else if (old_state == ISIS_ADJ_UP) {
-                               circuit->adj_state_changes++;
+                       } else {
+                               if (old_state == ISIS_ADJ_UP) {
+                                       circuit->adj_state_changes++;
 
-                               circuit->upadjcount[level - 1]--;
-                               if (circuit->upadjcount[level - 1] == 0)
-                                       isis_tx_queue_clean(circuit->tx_queue);
+                                       circuit->upadjcount[level - 1]--;
+                                       if (circuit->upadjcount[level - 1] == 0)
+                                               isis_tx_queue_clean(
+                                                       circuit->tx_queue);
+                               }
 
                                if (new_state == ISIS_ADJ_DOWN) {
                                        listnode_delete(
@@ -409,10 +412,13 @@ void isis_adj_state_change(struct isis_adjacency **padj,
                                                master, send_l2_csnp, circuit,
                                                0, &circuit->t_send_csnp[1]);
                                }
-                       } else if (old_state == ISIS_ADJ_UP) {
-                               circuit->upadjcount[level - 1]--;
-                               if (circuit->upadjcount[level - 1] == 0)
-                                       isis_tx_queue_clean(circuit->tx_queue);
+                       } else {
+                               if (old_state == ISIS_ADJ_UP) {
+                                       circuit->upadjcount[level - 1]--;
+                                       if (circuit->upadjcount[level - 1] == 0)
+                                               isis_tx_queue_clean(
+                                                       circuit->tx_queue);
+                               }
 
                                if (new_state == ISIS_ADJ_DOWN) {
                                        if (adj->circuit->u.p2p.neighbor == adj)