]> 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 6072d6bf741353deb6d0b1b0a9fe345dbf8cd8bc..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
@@ -185,6 +172,10 @@ struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
 
        isis_circuit_if_bind(circuit, ifp);
 
+       circuit->ip_addrs = list_new();
+       circuit->ipv6_link = list_new();
+       circuit->ipv6_non_link = list_new();
+
        if (ifp->ifindex != IFINDEX_INTERNAL)
                isis_circuit_enable(circuit);
 
@@ -209,6 +200,15 @@ void isis_circuit_del(struct isis_circuit *circuit)
        isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL1);
        isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL2);
 
+       list_delete(&circuit->ip_addrs);
+       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);
 
@@ -505,14 +505,10 @@ 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;
        }
 
-       circuit->ip_addrs = list_new();
-       circuit->ipv6_link = list_new();
-       circuit->ipv6_non_link = list_new();
-
        for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, conn))
                isis_circuit_add_addr(circuit, conn);
 
@@ -529,21 +525,6 @@ void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp)
        for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, conn))
                isis_circuit_del_addr(circuit, conn);
 
-       if (circuit->ip_addrs) {
-               assert(listcount(circuit->ip_addrs) == 0);
-               list_delete(&circuit->ip_addrs);
-       }
-
-       if (circuit->ipv6_link) {
-               assert(listcount(circuit->ipv6_link) == 0);
-               list_delete(&circuit->ipv6_link);
-       }
-
-       if (circuit->ipv6_non_link) {
-               assert(listcount(circuit->ipv6_non_link) == 0);
-               list_delete(&circuit->ipv6_non_link);
-       }
-
        circuit->circ_type = CIRCUIT_T_UNKNOWN;
 }
 
@@ -614,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,
@@ -710,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();
@@ -877,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;
 
@@ -892,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);
        }
 
        /*
@@ -905,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);
@@ -1067,7 +1053,7 @@ void isis_circuit_print_json(struct isis_circuit *circuit,
                        json_object_array_add(levels_json, level_json);
                }
 
-               if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) {
+               if (listcount(circuit->ip_addrs) > 0) {
                        ipv4_addr_json = json_object_new_object();
                        json_object_object_add(iface_json, "ip-prefix",
                                               ipv4_addr_json);
@@ -1079,7 +1065,7 @@ void isis_circuit_print_json(struct isis_circuit *circuit,
                                                       buf_prx);
                        }
                }
-               if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) {
+               if (listcount(circuit->ipv6_link) > 0) {
                        ipv6_link_json = json_object_new_object();
                        json_object_object_add(iface_json, "ipv6-link-locals",
                                               ipv6_link_json);
@@ -1091,8 +1077,7 @@ void isis_circuit_print_json(struct isis_circuit *circuit,
                                                       buf_prx);
                        }
                }
-               if (circuit->ipv6_non_link &&
-                   listcount(circuit->ipv6_non_link) > 0) {
+               if (listcount(circuit->ipv6_non_link) > 0) {
                        ipv6_non_link_json = json_object_new_object();
                        json_object_object_add(iface_json, "ipv6-prefixes",
                                               ipv6_non_link_json);
@@ -1204,20 +1189,19 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
                                vty_out(vty, "\n");
                        }
                }
-               if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) {
+               if (listcount(circuit->ip_addrs) > 0) {
                        vty_out(vty, "    IP Prefix(es):\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
                                                  ip_addr))
                                vty_out(vty, "      %pFX\n", ip_addr);
                }
-               if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) {
+               if (listcount(circuit->ipv6_link) > 0) {
                        vty_out(vty, "    IPv6 Link-Locals:\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
                                                  ip_addr))
                                vty_out(vty, "      %pFX\n", ip_addr);
                }
-               if (circuit->ipv6_non_link
-                   && listcount(circuit->ipv6_non_link) > 0) {
+               if (listcount(circuit->ipv6_non_link) > 0) {
                        vty_out(vty, "    IPv6 Prefixes:\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
                                                  ip_addr))
@@ -1631,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;
 }
@@ -1642,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,