summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlynnemorrison <lynne.morrison@ibm.com>2022-04-13 16:07:44 -0400
committerlynnemorrison <lynne.morrison@ibm.com>2022-04-18 11:15:15 -0400
commitc7b253d0bbcb9e55029bfcd72d2488dd6595a177 (patch)
treed5ff51bc2232791628e3939cd97628b3c9c86a09
parent926e00236e525aebb9fa49039bec876c222c1c7d (diff)
isisd: Fix crash in ISIS when mtu mismatch occurs
When lsp-mtu is configured larger than interface mtu and the interface is brought up, the ISIS code would crash. When other vendors have this misconfiguration they just continue ISIS running and allow the LSP packets to be created but not sent. When the misconfiguration is corrected the LSP packets start being sent. This change creates that same behavior in FRR. The startup issue I am hitting is when the isis lsp-mtu is larger that the interfaces mtu. We run into this case when we are in the process of changing the mtu on a tunnel. I issue a shutdown/no shutdown on the interface, because the tunnel MTU is smaller than the lsp-mtu, it is considered an error and calls circuit_if_del. This deletes part of the circuit information, which includes the circuit->ip_addr list. Later on we get an address update from zebra and try to add the interface address to this list and crash. 2022/04/07 20:19:52.032 ISIS: [GTRPJ-X68CG] CSM_EVENT for tun_gw2: IF_UP_FROM_Z calls isis_circuit_if_add this initialize the circuit->ip_addrs isis_circuit_up has the mtu check circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit) and fails returns ISIS_ERROR on failure call isis_circuit_if_del this deletes the circiut->ip_addrs list <---- 2022/04/07 20:19:52.032 ZEBRA: [NXYHN-ZKW2V] zebra_if_addr_update_ctx: INTF_ADDR_ADD: ifindex 3, addr 192.168.0.1/24 message to isisd to add address isis_zebra_if_address_add isis_circuit_add_addr circuit->ip_addr we try to add the ip address to the list, but it was deleted above and isisd crashes Signed-off-by: Lynne Morrison <lynne.morrison@ibm.com>
-rw-r--r--isisd/isis_circuit.c7
-rw-r--r--isisd/isis_nb_config.c48
2 files changed, 5 insertions, 50 deletions
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index c7bf1e2012..fedceed3bb 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -661,8 +661,11 @@ int isis_circuit_up(struct isis_circuit *circuit)
"Interface MTU %zu on %s is too low to support area lsp mtu %u!",
isis_circuit_pdu_size(circuit),
circuit->interface->name, circuit->area->lsp_mtu);
- isis_circuit_update_all_srmflags(circuit, 0);
- return ISIS_ERROR;
+
+ /* Allow ISIS to continue configuration. With this
+ * configuration failure ISIS will attempt to send lsp
+ * packets but will fail until the mtu is configured properly
+ */
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index de7797813a..cf4c2aea0a 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -393,30 +393,11 @@ int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args)
*/
int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args)
{
- struct listnode *node;
- struct isis_circuit *circuit;
uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL);
struct isis_area *area;
switch (args->event) {
case NB_EV_VALIDATE:
- area = nb_running_get_entry(args->dnode, NULL, false);
- if (!area)
- break;
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
- if (circuit->state != C_STATE_INIT
- && circuit->state != C_STATE_UP)
- continue;
- if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
- circuit->interface->name,
- isis_circuit_pdu_size(circuit));
- return NB_ERR_VALIDATION;
- }
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -2552,43 +2533,14 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
*/
int lib_interface_isis_create(struct nb_cb_create_args *args)
{
- struct isis_area *area = NULL;
struct interface *ifp;
struct isis_circuit *circuit = NULL;
const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
- uint32_t min_mtu, actual_mtu;
switch (args->event) {
case NB_EV_PREPARE:
case NB_EV_ABORT:
- break;
case NB_EV_VALIDATE:
- /* check if interface mtu is sufficient. If the area has not
- * been created yet, assume default MTU for the area
- */
- ifp = nb_running_get_entry(args->dnode, NULL, false);
- /* zebra might not know yet about the MTU - nothing we can do */
- if (!ifp || ifp->mtu == 0)
- break;
- actual_mtu =
- if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
-
- area = isis_area_lookup(area_tag, ifp->vrf->vrf_id);
- if (area)
- min_mtu = area->lsp_mtu;
- else
-#ifndef FABRICD
- min_mtu = yang_get_default_uint16(
- "/frr-isisd:isis/instance/lsp/mtu");
-#else
- min_mtu = DEFAULT_LSP_MTU;
-#endif /* ifndef FABRICD */
- if (actual_mtu < min_mtu) {
- snprintf(args->errmsg, args->errmsg_len,
- "Interface %s has MTU %u, minimum MTU for the area is %u",
- ifp->name, actual_mtu, min_mtu);
- return NB_ERR_VALIDATION;
- }
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);