]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: Force Opaque LSA & co to default VRF 13236/head
authorOlivier Dugeon <olivier.dugeon@orange.com>
Fri, 7 Apr 2023 20:48:24 +0000 (22:48 +0200)
committerOlivier Dugeon <olivier.dugeon@orange.com>
Tue, 18 Apr 2023 08:30:50 +0000 (10:30 +0200)
Ospf segfault when Router Information is enabled in a non default VRF,
see issue #13144.

This patch forces vrf_id to default VRF for Opaque LSA and extension based
on Opaque LSA: Router Information, Traffic Engineering, Extended Prefix,
Extended Link and Segment Routing. Indeed, non default VRF is not yet
supported for Opaque LSA & co.

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
ospfd/ospf_opaque.c
ospfd/ospf_ri.c
ospfd/ospf_te.c

index 6f66ee10a1ebbd722ffe31ef32a274b02ed73c43..c2b40af1c4706161b93bfd35a39466c2786de044 100644 (file)
@@ -544,7 +544,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
                listnode_add(new->area->opaque_lsa_self, oipt);
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup_by_vrf_id(new->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (new->area != NULL && (top = new->area->ospf) == NULL) {
                        free_opaque_info_per_type(oipt, true);
                        oipt = NULL;
@@ -652,7 +652,7 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa)
                                "Type-10 Opaque-LSA: Reference to AREA is missing?");
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
                        flog_warn(
                                EC_OSPF_LSA,
@@ -758,6 +758,13 @@ DEFUN (capability_opaque,
 {
        VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
 
+       /* Check that OSPF is using default VRF */
+       if (ospf->vrf_id != VRF_DEFAULT) {
+               vty_out(vty,
+                       "OSPF Opaque LSA is only supported in default VRF\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        /* Turn on the "master switch" of opaque-lsa capability. */
        if (!CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) {
                if (IS_DEBUG_OSPF_EVENT)
@@ -1588,7 +1595,7 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc)
                }
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
                        /* Above conditions must have passed. */
                        flog_warn(EC_OSPF_LSA, "%s: Something wrong?",
@@ -1615,7 +1622,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
        struct ospf_opaque_functab *functab;
        struct ospf_lsa *new = NULL;
 
-       ospf = ospf_lookup_by_vrf_id(lsa->vrf_id);
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL
            || functab->lsa_refresher == NULL) {
@@ -1752,7 +1759,7 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
 
        /* Generate a dummy lsa to be passed for a lookup function. */
        lsa = pseudo_lsa(oi, area, lsa_type, opaque_type);
-       lsa->vrf_id = top->vrf_id;
+       lsa->vrf_id = VRF_DEFAULT;
 
        if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
                struct ospf_opaque_functab *functab;
@@ -1987,7 +1994,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
                ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
                break;
        case OSPF_OPAQUE_AS_LSA:
-               top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
                        top = lsa0->area->ospf;
                ospf_ls_retransmit_delete_nbr_as(top, lsa);
@@ -2037,7 +2044,7 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0)
        struct ospf_lsa *lsa;
        struct ospf *top;
 
-       top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
        if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
            || (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
index 0179f9ee0bea7ee41ffc55cec96870e786b1c27d..725443f490786a71b1a7898b0b6f269853f4a8ec 100644 (file)
@@ -798,13 +798,10 @@ static struct ospf_lsa *ospf_router_info_lsa_new(struct ospf_area *area)
        /* Now, create an OSPF LSA instance. */
        new = ospf_lsa_new_and_data(length);
 
+       /* Routing Information is only supported for default VRF */
+       new->vrf_id = VRF_DEFAULT;
        new->area = area;
 
-       if (new->area && new->area->ospf)
-               new->vrf_id = new->area->ospf->vrf_id;
-       else
-               new->vrf_id = VRF_DEFAULT;
-
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, lsah, length);
        stream_free(s);
@@ -817,7 +814,6 @@ static int ospf_router_info_lsa_originate_as(void *arg)
        struct ospf_lsa *new;
        struct ospf *top;
        int rc = -1;
-       vrf_id_t vrf_id = VRF_DEFAULT;
 
        /* Sanity Check */
        if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
@@ -830,13 +826,12 @@ static int ospf_router_info_lsa_originate_as(void *arg)
 
        /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
        new = ospf_router_info_lsa_new(NULL);
-       new->vrf_id = VRF_DEFAULT;
        top = (struct ospf *)arg;
 
        /* Check ospf info */
        if (top == NULL) {
                zlog_debug("RI (%s): ospf instance not found for vrf id %u",
-                          __func__, vrf_id);
+                          __func__, VRF_DEFAULT);
                ospf_lsa_unlock(&new);
                return rc;
        }
@@ -874,7 +869,6 @@ static int ospf_router_info_lsa_originate_area(void *arg)
        struct ospf *top;
        struct ospf_ri_area_info *ai = NULL;
        int rc = -1;
-       vrf_id_t vrf_id = VRF_DEFAULT;
 
        /* Sanity Check */
        if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
@@ -893,19 +887,18 @@ static int ospf_router_info_lsa_originate_area(void *arg)
                        __func__);
                return rc;
        }
-       if (ai->area->ospf) {
-               vrf_id = ai->area->ospf->vrf_id;
+
+       if (ai->area->ospf)
                top = ai->area->ospf;
-       } else {
-               top = ospf_lookup_by_vrf_id(vrf_id);
-       }
+       else
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
        new = ospf_router_info_lsa_new(ai->area);
-       new->vrf_id = vrf_id;
 
        /* Check ospf info */
        if (top == NULL) {
                zlog_debug("RI (%s): ospf instance not found for vrf id %u",
-                          __func__, vrf_id);
+                          __func__, VRF_DEFAULT);
                ospf_lsa_unlock(&new);
                return rc;
        }
@@ -1039,10 +1032,9 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
                /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
                new = ospf_router_info_lsa_new(ai->area);
                new->data->ls_seqnum = lsa_seqnum_increment(lsa);
-               new->vrf_id = lsa->vrf_id;
                /* Install this LSA into LSDB. */
                /* Given "lsa" will be freed in the next function. */
-               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
                        flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
                                  "RI (%s): ospf_lsa_install() ?", __func__);
@@ -1062,10 +1054,9 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
                /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
                new = ospf_router_info_lsa_new(NULL);
                new->data->ls_seqnum = lsa_seqnum_increment(lsa);
-               new->vrf_id = lsa->vrf_id;
                /* Install this LSA into LSDB. */
                /* Given "lsa" will be freed in the next function. */
-               top = ospf_lookup_by_vrf_id(lsa->vrf_id);
+               top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
                        flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
                                  "RI (%s): ospf_lsa_install() ?", __func__);
@@ -1676,10 +1667,18 @@ DEFUN (router_info,
 {
        int idx_mode = 1;
        uint8_t scope;
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
 
        if (OspfRI.enabled)
                return CMD_SUCCESS;
 
+       /* Check that the OSPF is using default VRF */
+       if (ospf->vrf_id != VRF_DEFAULT) {
+               vty_out(vty,
+                       "Router Information is only supported in default VRF\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        /* Check and get Area value if present */
        if (strncmp(argv[idx_mode]->arg, "as", 2) == 0)
                scope = OSPF_OPAQUE_AS_LSA;
index b140027147f3a3eb5280929fcae047b97b7b6258..5f83e1c2c7f0b8cf368633aff602598b1ac1b71e 100644 (file)
@@ -1207,10 +1207,9 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
        /* Now, create an OSPF LSA instance. */
        new = ospf_lsa_new_and_data(length);
 
-       new->vrf_id = ospf->vrf_id;
-       if (area && area->ospf)
-               new->vrf_id = area->ospf->vrf_id;
        new->area = area;
+       new->vrf_id = VRF_DEFAULT;
+
        SET_FLAG(new->flags, OSPF_LSA_SELF);
        memcpy(new->data, lsah, length);
        stream_free(s);
@@ -1329,7 +1328,6 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
                          __func__);
                return rc;
        }
-       new->vrf_id = top->vrf_id;
 
        /* Install this LSA into LSDB. */
        if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@@ -1482,7 +1480,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
                ospf_opaque_lsa_flush_schedule(lsa);
                return NULL;
        }
-       top = ospf_lookup_by_vrf_id(lsa->vrf_id);
+       top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        /* Create new Opaque-LSA/MPLS-TE instance. */
        new = ospf_mpls_te_lsa_new(top, area, lp);
        if (new == NULL) {
@@ -3847,6 +3845,12 @@ DEFUN (ospf_mpls_te_on,
        if (OspfMplsTE.enabled)
                return CMD_SUCCESS;
 
+       /* Check that the OSPF is using default VRF */
+       if (ospf->vrf_id != VRF_DEFAULT) {
+               vty_out(vty, "MPLS TE is only supported in default VRF\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        ote_debug("MPLS-TE: OFF -> ON");
 
        OspfMplsTE.enabled = true;
@@ -4229,12 +4233,10 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
 
 DEFUN (show_ip_ospf_mpls_te_link,
        show_ip_ospf_mpls_te_link_cmd,
-       "show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]",
+       "show ip ospf mpls-te interface [INTERFACE]",
        SHOW_STR
        IP_STR
        OSPF_STR
-       VRF_CMD_HELP_STR
-       "All VRFs\n"
        "MPLS-TE information\n"
        "Interface information\n"
        "Interface name\n")
@@ -4242,43 +4244,18 @@ DEFUN (show_ip_ospf_mpls_te_link,
        struct vrf *vrf;
        int idx_interface = 0;
        struct interface *ifp = NULL;
-       struct listnode *node;
-       char *vrf_name = NULL;
-       bool all_vrf = false;
-       int inst = 0;
-       int idx_vrf = 0;
        struct ospf *ospf = NULL;
 
-       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
-               vrf_name = argv[idx_vrf + 1]->arg;
-               all_vrf = strmatch(vrf_name, "all");
-       }
        argv_find(argv, argc, "INTERFACE", &idx_interface);
-       /* vrf input is provided could be all or specific vrf*/
-       if (vrf_name) {
-               if (all_vrf) {
-                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-                               if (!ospf->oi_running)
-                                       continue;
-                               vrf = vrf_lookup_by_id(ospf->vrf_id);
-                               FOR_ALL_INTERFACES (vrf, ifp)
-                                       show_mpls_te_link_sub(vty, ifp);
-                       }
-                       return CMD_SUCCESS;
-               }
-               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-       } else
-               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf == NULL || !ospf->oi_running)
                return CMD_SUCCESS;
 
-       vrf = vrf_lookup_by_id(ospf->vrf_id);
+       vrf = vrf_lookup_by_id(VRF_DEFAULT);
        if (!vrf)
                return CMD_SUCCESS;
        if (idx_interface) {
-               ifp = if_lookup_by_name(
-                                       argv[idx_interface]->arg,
-                                       ospf->vrf_id);
+               ifp = if_lookup_by_name(argv[idx_interface]->arg, VRF_DEFAULT);
                if (ifp == NULL) {
                        vty_out(vty, "No such interface name in vrf %s\n",
                                vrf->name);