]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: prevent segfault in isis_circuit_af_set
authorEmanuele Di Pascale <emanuele@voltanet.io>
Wed, 10 Jun 2020 12:29:02 +0000 (14:29 +0200)
committerEmanuele Di Pascale <emanuele@voltanet.io>
Wed, 10 Jun 2020 14:34:33 +0000 (16:34 +0200)
before the last commit, it was possible under some
circumstances to call isis_circuit_af_set on a circuit
with a NULL area, e.g. if the circuit was deconfigured
due to a validation error. While this should not happen
now, let's add an explicit check to avoid crashing if
a regression is introduced.

Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
isisd/isis_circuit.c

index 003be8d68238b28f575d216dad4ce500ebee4bcb..e0013e4f1f6f51c81d18a686ee515187122c561b 100644 (file)
@@ -1233,23 +1233,35 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
                         bool ipv6_router)
 {
        struct isis_area *area = circuit->area;
-       bool change = circuit->ip_router != ip_router
-                     || circuit->ipv6_router != ipv6_router;
+       int old_ipr = circuit->ip_router;
+       int old_ipv6r = circuit->ipv6_router;
+
+       /* is there something to do? */
+       if (old_ipr == ip_router && old_ipv6r == ipv6_router)
+               return;
 
-       area->ip_circuits += ip_router - circuit->ip_router;
-       area->ipv6_circuits += ipv6_router - circuit->ipv6_router;
        circuit->ip_router = ip_router;
        circuit->ipv6_router = ipv6_router;
+       circuit_update_nlpids(circuit);
 
-       if (!change)
+       /* the area should always be there if we get here, but in the past
+        * there were corner cases where the area was NULL (e.g. because the
+        * circuit was deconfigured following a validation error). Do not
+        * segfault if this happens again.
+        */
+       if (!area) {
+               zlog_err("%s: NULL area for circuit %u", __func__,
+                        circuit->circuit_id);
                return;
+       }
 
-       circuit_update_nlpids(circuit);
+       area->ip_circuits += ip_router - old_ipr;
+       area->ipv6_circuits += ipv6_router - old_ipv6r;
 
        if (!ip_router && !ipv6_router)
                isis_csm_state_change(ISIS_DISABLE, circuit, area);
        else
-               lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
+               lsp_regenerate_schedule(area, circuit->is_type, 0);
 }
 
 ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive)