diff options
author | lynnemorrison <lynne.morrison@ibm.com> | 2022-04-13 22:07:44 +0200 |
---|---|---|
committer | lynnemorrison <lynne.morrison@ibm.com> | 2022-04-18 17:15:15 +0200 |
commit | c7b253d0bbcb9e55029bfcd72d2488dd6595a177 (patch) | |
tree | d5ff51bc2232791628e3939cd97628b3c9c86a09 /isisd/isis_nb_config.c | |
parent | Merge pull request #10910 from donaldsharp/doc_nht (diff) | |
download | frr-c7b253d0bbcb9e55029bfcd72d2488dd6595a177.tar.xz frr-c7b253d0bbcb9e55029bfcd72d2488dd6595a177.zip |
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>
Diffstat (limited to 'isisd/isis_nb_config.c')
-rw-r--r-- | isisd/isis_nb_config.c | 48 |
1 files changed, 0 insertions, 48 deletions
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index de7797813..cf4c2aea0 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); |