]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: fix memory handling in isis_adj_process_threeway()
authorMark Stapp <mjs@cisco.com>
Fri, 9 Aug 2024 14:08:21 +0000 (10:08 -0400)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Mon, 12 Aug 2024 19:02:07 +0000 (19:02 +0000)
The adj_process_threeway() api may call the adj_state_change()
api, which may delete the adj struct being examined. Change the
signature so that callers pass a ptr-to-ptr so that they will
see that deletion.

Signed-off-by: Mark Stapp <mjs@cisco.com>
(cherry picked from commit 3eb7d1641166872591554519607483f6d77657f5)

isisd/isis_adjacency.c
isisd/isis_adjacency.h
isisd/isis_pdu.c

index 32d3466f5c4be672a6f5af4b275f54bf6d2b5cc8..44555079adc52efa6dfa50ebcfd745577c03ebe6 100644 (file)
@@ -231,11 +231,12 @@ static void isis_adj_route_switchover(struct isis_adjacency *adj)
        }
 }
 
-void isis_adj_process_threeway(struct isis_adjacency *adj,
+void isis_adj_process_threeway(struct isis_adjacency **padj,
                               struct isis_threeway_adj *tw_adj,
                               enum isis_adj_usage adj_usage)
 {
        enum isis_threeway_state next_tw_state = ISIS_THREEWAY_DOWN;
+       struct isis_adjacency *adj = *padj;
 
        if (tw_adj && !adj->circuit->disable_threeway_adj) {
                if (tw_adj->state == ISIS_THREEWAY_DOWN) {
@@ -265,14 +266,13 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
                fabricd_initial_sync_hello(adj->circuit);
 
        if (next_tw_state == ISIS_THREEWAY_DOWN) {
-               isis_adj_state_change(&adj, ISIS_ADJ_DOWN,
-                                     "Neighbor restarted");
+               isis_adj_state_change(padj, ISIS_ADJ_DOWN, "Neighbor restarted");
                return;
        }
 
        if (next_tw_state == ISIS_THREEWAY_UP) {
                if (adj->adj_state != ISIS_ADJ_UP) {
-                       isis_adj_state_change(&adj, ISIS_ADJ_UP, NULL);
+                       isis_adj_state_change(padj, ISIS_ADJ_UP, NULL);
                        adj->adj_usage = adj_usage;
                }
        }
index b5c7dd8d736cc84da7bfb16b48a73e5887f2194b..0ad36e4c5f2a5ee6557e0861569ecd2ee48b0e80 100644 (file)
@@ -111,7 +111,7 @@ struct isis_adjacency *isis_adj_find(const struct isis_area *area, int level,
 struct isis_adjacency *isis_new_adj(const uint8_t *id, const uint8_t *snpa,
                                    int level, struct isis_circuit *circuit);
 void isis_delete_adj(void *adj);
-void isis_adj_process_threeway(struct isis_adjacency *adj,
+void isis_adj_process_threeway(struct isis_adjacency **padj,
                               struct isis_threeway_adj *tw_adj,
                               enum isis_adj_usage adj_usage);
 DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj));
index 6f410d342e2873e4a5cccf1169a66dc44f252f07..6a6c461144c5f19c75573786d7cd2937f7f0dde7 100644 (file)
@@ -281,14 +281,14 @@ static int process_p2p_hello(struct iih_info *iih)
                if (iih->calculated_type == IS_LEVEL_1) {
                        switch (iih->circ_type) {
                        case IS_LEVEL_1:
-                               isis_adj_process_threeway(adj, tw_adj,
+                               isis_adj_process_threeway(&adj, tw_adj,
                                                          iih->calculated_type);
                                break;
                        case IS_LEVEL_1_AND_2:
                                if ((adj->adj_state != ISIS_ADJ_UP) ||
                                    (adj->adj_usage == ISIS_ADJ_LEVEL1) ||
                                    (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                }
                                break;
@@ -301,7 +301,7 @@ static int process_p2p_hello(struct iih_info *iih)
                        case IS_LEVEL_1:
                                if (adj->adj_state != ISIS_ADJ_UP
                                    || adj->adj_usage == ISIS_ADJ_LEVEL1) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                } else if ((adj->adj_usage == ISIS_ADJ_LEVEL2) ||
                                           (adj->adj_usage ==
@@ -315,7 +315,7 @@ static int process_p2p_hello(struct iih_info *iih)
                        case IS_LEVEL_2:
                                if (adj->adj_state != ISIS_ADJ_UP
                                    || adj->adj_usage == ISIS_ADJ_LEVEL2) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
                                           (adj->adj_usage ==
@@ -329,7 +329,7 @@ static int process_p2p_hello(struct iih_info *iih)
                        case IS_LEVEL_1_AND_2:
                                if (adj->adj_state != ISIS_ADJ_UP
                                    || adj->adj_usage == ISIS_ADJ_LEVEL1AND2) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
                                           (adj->adj_usage == ISIS_ADJ_LEVEL2)) {
@@ -349,12 +349,12 @@ static int process_p2p_hello(struct iih_info *iih)
                                if (adj->adj_state != ISIS_ADJ_UP ||
                                    adj->adj_usage == ISIS_ADJ_LEVEL2 ||
                                    adj->adj_usage == ISIS_ADJ_LEVEL1AND2) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                }
                                break;
                        case IS_LEVEL_2:
-                               isis_adj_process_threeway(adj, tw_adj,
+                               isis_adj_process_threeway(&adj, tw_adj,
                                                          iih->calculated_type);
                                break;
                        }
@@ -401,7 +401,7 @@ static int process_p2p_hello(struct iih_info *iih)
                        case IS_LEVEL_2:
                                if (adj->adj_state != ISIS_ADJ_UP
                                    || adj->adj_usage == ISIS_ADJ_LEVEL2) {
-                                       isis_adj_process_threeway(adj, tw_adj,
+                                       isis_adj_process_threeway(&adj, tw_adj,
                                                                  iih->calculated_type);
                                } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
                                        /* (7) down - wrong system */