]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: check MTU when configuring circuit
authorEmanuele Di Pascale <emanuele@voltanet.io>
Fri, 23 Aug 2019 09:18:03 +0000 (11:18 +0200)
committerEmanuele Di Pascale <emanuele@voltanet.io>
Tue, 27 Aug 2019 14:39:43 +0000 (16:39 +0200)
as part of the 'ip router isis TAG' command we were not validating
the MTU of the interface against the minimum LSP MTU of the area.
This could cause an assertion when the circuit is created in the
APPLY phase.

Fixes issue #4825

Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
isisd/isis_northbound.c

index 0982a468a62ed5ab98825d49ba46752e9ee2fe42..5f5620b4bada89597e95a594dfe76ac418b37713 100644 (file)
@@ -1524,29 +1524,64 @@ static int lib_interface_isis_create(enum nb_event event,
        struct interface *ifp;
        struct isis_circuit *circuit;
        const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
+       uint32_t min_mtu, actual_mtu;
 
-       if (event != NB_EV_APPLY)
-               return NB_OK;
+       switch (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(dnode, NULL, true);
+               /* zebra might not know yet about the MTU - nothing we can do */
+               if (ifp->mtu == 0)
+                       break;
+               actual_mtu =
+                       if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
+               area = isis_area_lookup(area_tag);
+               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) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "Interface %s has MTU %" PRIu32
+                                 ", minimum MTU for the area is %" PRIu32 "",
+                                 ifp->name, actual_mtu, min_mtu);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_APPLY:
+               area = isis_area_lookup(area_tag);
+               /* The area should have already be created. We are
+                * setting the priority of the global isis area creation
+                * slightly lower, so it should be executed first, but I
+                * cannot rely on that so here I have to check.
+                */
+               if (!area) {
+                       flog_err(
+                               EC_LIB_NB_CB_CONFIG_APPLY,
+                               "%s: attempt to create circuit for area %s before the area has been created",
+                               __func__, area_tag);
+                       abort();
+               }
 
-       area = isis_area_lookup(area_tag);
-       /* The area should have already be created. We are
-        * setting the priority of the global isis area creation
-        * slightly lower, so it should be executed first, but I
-        * cannot rely on that so here I have to check.
-        */
-       if (!area) {
-               flog_err(
-                       EC_LIB_NB_CB_CONFIG_APPLY,
-                       "%s: attempt to create circuit for area %s before the area has been created",
-                       __func__, area_tag);
-               abort();
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               circuit = isis_circuit_create(area, ifp);
+               assert(circuit
+                      && (circuit->state == C_STATE_CONF
+                          || circuit->state == C_STATE_UP));
+               nb_running_set_entry(dnode, circuit);
+               break;
        }
 
-       ifp = nb_running_get_entry(dnode, NULL, true);
-       circuit = isis_circuit_create(area, ifp);
-       assert(circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
-       nb_running_set_entry(dnode, circuit);
-
        return NB_OK;
 }