]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_circuit.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / isisd / isis_circuit.c
index 5d3e5f390615296b9912b457a58fbf162252bad7..dd5f921bef38a40fe51a9ed1aeab410c8c1ac5f4 100644 (file)
@@ -1,23 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * IS-IS Rout(e)ing protocol - isis_circuit.h
  *
  * Copyright (C) 2001,2002   Sampo Saaristo
  *                           Tampere University of Technology
  *                           Institute of Communications Engineering
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public Licenseas published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <zebra.h>
 #ifdef GNU_LINUX
@@ -217,6 +204,11 @@ void isis_circuit_del(struct isis_circuit *circuit)
        list_delete(&circuit->ipv6_link);
        list_delete(&circuit->ipv6_non_link);
 
+       if (circuit->ext) {
+               isis_del_ext_subtlvs(circuit->ext);
+               circuit->ext = NULL;
+       }
+
        XFREE(MTYPE_TMP, circuit->bfd_config.profile);
        XFREE(MTYPE_ISIS_CIRCUIT, circuit->tag);
 
@@ -513,7 +505,7 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
        } else {
                /* It's normal in case of loopback etc. */
                if (IS_DEBUG_EVENTS)
-                       zlog_debug("isis_circuit_if_add: unsupported media");
+                       zlog_debug("%s: unsupported media", __func__);
                circuit->circ_type = CIRCUIT_T_UNKNOWN;
        }
 
@@ -603,7 +595,12 @@ static bool isis_circuit_lfa_enabled(struct isis_circuit *circuit, int level)
 void isis_circuit_switchover_routes(struct isis_circuit *circuit, int family,
                                    union g_addr *nexthop_ip, ifindex_t ifindex)
 {
-       char is_type = circuit->area->is_type;
+       char is_type;
+
+       if (!circuit->area)
+               return;
+
+       is_type = circuit->area->is_type;
        if ((is_type == IS_LEVEL_1 || is_type == IS_LEVEL_1_AND_2) &&
            isis_circuit_lfa_enabled(circuit, IS_LEVEL_1))
                isis_area_switchover_routes(circuit->area, family, nexthop_ip,
@@ -699,10 +696,10 @@ int isis_circuit_up(struct isis_circuit *circuit)
                }
 #ifdef EXTREME_DEGUG
                if (IS_DEBUG_EVENTS)
-                       zlog_debug(
-                               "isis_circuit_if_add: if_id %d, isomtu %d snpa %s",
-                               circuit->interface->ifindex, ISO_MTU(circuit),
-                               snpa_print(circuit->u.bc.snpa));
+                       zlog_debug("%s: if_id %d, isomtu %d snpa %s", __func__,
+                                  circuit->interface->ifindex,
+                                  ISO_MTU(circuit),
+                                  snpa_print(circuit->u.bc.snpa));
 #endif /* EXTREME_DEBUG */
 
                circuit->u.bc.adjdb[0] = list_new();
@@ -866,12 +863,12 @@ void isis_circuit_down(struct isis_circuit *circuit)
                memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
                memset(circuit->u.bc.snpa, 0, ETH_ALEN);
 
-               thread_cancel(&circuit->u.bc.t_send_lan_hello[0]);
-               thread_cancel(&circuit->u.bc.t_send_lan_hello[1]);
-               thread_cancel(&circuit->u.bc.t_run_dr[0]);
-               thread_cancel(&circuit->u.bc.t_run_dr[1]);
-               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[0]);
-               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[1]);
+               THREAD_OFF(circuit->u.bc.t_send_lan_hello[0]);
+               THREAD_OFF(circuit->u.bc.t_send_lan_hello[1]);
+               THREAD_OFF(circuit->u.bc.t_run_dr[0]);
+               THREAD_OFF(circuit->u.bc.t_run_dr[1]);
+               THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]);
+               THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]);
                circuit->lsp_regenerate_pending[0] = 0;
                circuit->lsp_regenerate_pending[1] = 0;
 
@@ -881,7 +878,7 @@ void isis_circuit_down(struct isis_circuit *circuit)
        } else if (circuit->circ_type == CIRCUIT_T_P2P) {
                isis_delete_adj(circuit->u.p2p.neighbor);
                circuit->u.p2p.neighbor = NULL;
-               thread_cancel(&circuit->u.p2p.t_send_p2p_hello);
+               THREAD_OFF(circuit->u.p2p.t_send_p2p_hello);
        }
 
        /*
@@ -894,11 +891,11 @@ void isis_circuit_down(struct isis_circuit *circuit)
        circuit->snmp_adj_idx_gen = 0;
 
        /* Cancel all active threads */
-       thread_cancel(&circuit->t_send_csnp[0]);
-       thread_cancel(&circuit->t_send_csnp[1]);
-       thread_cancel(&circuit->t_send_psnp[0]);
-       thread_cancel(&circuit->t_send_psnp[1]);
-       thread_cancel(&circuit->t_read);
+       THREAD_OFF(circuit->t_send_csnp[0]);
+       THREAD_OFF(circuit->t_send_csnp[1]);
+       THREAD_OFF(circuit->t_send_psnp[0]);
+       THREAD_OFF(circuit->t_send_psnp[1]);
+       THREAD_OFF(circuit->t_read);
 
        if (circuit->tx_queue) {
                isis_tx_queue_free(circuit->tx_queue);
@@ -1618,8 +1615,10 @@ static int isis_ifp_up(struct interface *ifp)
 {
        struct isis_circuit *circuit = ifp->info;
 
-       if (circuit)
+       if (circuit) {
+               UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
                isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
+       }
 
        return 0;
 }
@@ -1629,7 +1628,9 @@ static int isis_ifp_down(struct interface *ifp)
        afi_t afi;
        struct isis_circuit *circuit = ifp->info;
 
-       if (circuit) {
+       if (circuit &&
+           !CHECK_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z)) {
+               SET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
                for (afi = AFI_IP; afi <= AFI_IP6; afi++)
                        isis_circuit_switchover_routes(
                                circuit, afi == AFI_IP ? AF_INET : AF_INET6,