]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: Fix crash with xfrm interface type 11497/head
authorDonald Sharp <sharpd@nvidia.com>
Sat, 18 Jun 2022 18:37:14 +0000 (14:37 -0400)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Wed, 29 Jun 2022 15:10:45 +0000 (15:10 +0000)
When creating a xfrm interface FRR is crashing when configured
with isis.  This is because the weird pattern of not allocating
list's until needed and then allowing the crash when we have
a usage pattern that was not expected.  Just always allocate
the different lists that a circuit needs.

(gdb) bt
(gdb)

Fixes #11432
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit 91a5bbc4de1bfe03618b5c4d11cf32f45e20e8e7)

isisd/fabricd.c
isisd/isis_bfd.c
isisd/isis_circuit.c
isisd/isis_lsp.c
isisd/isis_pdu.c
isisd/isis_te.c

index 3e0d4ba549084d35daf66a8a1dda16194cd114bc..d431787ebb692d2f2a1dbdb464f6ef71d7182ed8 100644 (file)
@@ -728,7 +728,7 @@ void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped)
 
 struct list *fabricd_ip_addrs(struct isis_circuit *circuit)
 {
-       if (circuit->ip_addrs && listcount(circuit->ip_addrs))
+       if (listcount(circuit->ip_addrs))
                return circuit->ip_addrs;
 
        if (!fabricd || !circuit->area || !circuit->area->circuit_list)
@@ -741,7 +741,7 @@ struct list *fabricd_ip_addrs(struct isis_circuit *circuit)
                if (c->circ_type != CIRCUIT_T_LOOPBACK)
                        continue;
 
-               if (!c->ip_addrs || !listcount(c->ip_addrs))
+               if (!listcount(c->ip_addrs))
                        return NULL;
 
                return c->ip_addrs;
index 5311a384e784f23736ca3dbd15f676e52470cbbe..79d393f4e330399af886af0027506590662cd079 100644 (file)
@@ -97,7 +97,7 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj)
                family = AF_INET6;
                dst_ip.ipv6 = adj->ll_ipv6_addrs[0];
                local_ips = circuit->ipv6_link;
-               if (!local_ips || list_isempty(local_ips)) {
+               if (list_isempty(local_ips)) {
                        if (IS_DEBUG_BFD)
                                zlog_debug(
                                        "ISIS-BFD: skipping BFD initialization: IPv6 enabled and no local IPv6 addresses");
index fedceed3bb0be216b7259f9c79eae655964062e7..28d4b530fc3a631ee9399cae52a0331adbf9c21b 100644 (file)
@@ -185,6 +185,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 +213,10 @@ 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);
+
        XFREE(MTYPE_TMP, circuit->bfd_config.profile);
        XFREE(MTYPE_ISIS_CIRCUIT, circuit->tag);
 
@@ -509,10 +517,6 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
                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 +533,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;
 }
 
@@ -1046,7 +1035,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);
@@ -1058,7 +1047,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);
@@ -1070,8 +1059,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);
@@ -1183,20 +1171,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))
index eb7e9e725e34c218b43cfc19201815d60e97741e..8dbd41b5d9ab962fc244e9369abf8dc4815603a8 100644 (file)
@@ -1171,8 +1171,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                                          ? circuit->metric[level - 1]
                                          : circuit->te_metric[level - 1];
 
-               if (circuit->ip_router && circuit->ip_addrs
-                   && circuit->ip_addrs->count > 0) {
+               if (circuit->ip_router && circuit->ip_addrs->count > 0) {
                        lsp_debug(
                                "ISIS (%s): Circuit has IPv4 active, adding respective TLVs.",
                                area->area_tag);
@@ -1206,8 +1205,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                        }
                }
 
-               if (circuit->ipv6_router && circuit->ipv6_non_link
-                   && circuit->ipv6_non_link->count > 0) {
+               if (circuit->ipv6_router && circuit->ipv6_non_link->count > 0) {
                        struct listnode *ipnode;
                        struct prefix_ipv6 *ipv6;
 
index 016efd5cd7a802f645eaad7cbe27b62b76a47d5d..b1fbfd514037c59969710f3b6d03fea667f101da 100644 (file)
@@ -778,8 +778,8 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        iih.v4_usable = (fabricd_ip_addrs(circuit)
                         && iih.tlvs->ipv4_address.count);
 
-       iih.v6_usable = (circuit->ipv6_link && listcount(circuit->ipv6_link)
-                        && iih.tlvs->ipv6_address.count);
+       iih.v6_usable =
+               (listcount(circuit->ipv6_link) && iih.tlvs->ipv6_address.count);
 
        if (!iih.v4_usable && !iih.v6_usable) {
                if (IS_DEBUG_ADJ_PACKETS) {
@@ -1969,11 +1969,11 @@ int send_hello(struct isis_circuit *circuit, int level)
                        isis_tlvs_add_ipv4_addresses(tlvs, circuit_ip_addrs);
        }
 
-       if (circuit->ipv6_router && circuit->ipv6_link)
+       if (circuit->ipv6_router)
                isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link);
 
        /* RFC6119 section 4 define TLV 233 to provide Global IPv6 address */
-       if (circuit->ipv6_router && circuit->ipv6_non_link)
+       if (circuit->ipv6_router)
                isis_tlvs_add_global_ipv6_addresses(tlvs,
                                                    circuit->ipv6_non_link);
 
index 579ae6aabaf9324c83b740041ca42ade042d73f6..3faff1cc4d75d50a97c4f5cd7bac545b5ba60a96 100644 (file)
@@ -108,8 +108,7 @@ void isis_link_params_update(struct isis_circuit *circuit,
                        UNSET_SUBTLV(ext, EXT_ADM_GRP);
 
                /* If known, register local IPv4 addr from ip_addr list */
-               if (circuit->ip_addrs != NULL
-                   && listcount(circuit->ip_addrs) != 0) {
+               if (listcount(circuit->ip_addrs) != 0) {
                        addr = (struct prefix_ipv4 *)listgetdata(
                                (struct listnode *)listhead(circuit->ip_addrs));
                        IPV4_ADDR_COPY(&ext->local_addr, &addr->prefix);
@@ -118,8 +117,7 @@ void isis_link_params_update(struct isis_circuit *circuit,
                        UNSET_SUBTLV(ext, EXT_LOCAL_ADDR);
 
                /* If known, register local IPv6 addr from ip_addr list */
-               if (circuit->ipv6_non_link != NULL
-                   && listcount(circuit->ipv6_non_link) != 0) {
+               if (listcount(circuit->ipv6_non_link) != 0) {
                        addr6 = (struct prefix_ipv6 *)listgetdata(
                                (struct listnode *)listhead(
                                        circuit->ipv6_non_link));