diff options
author | Olivier Dugeon <olivier.dugeon@orange.com> | 2023-04-07 22:48:24 +0200 |
---|---|---|
committer | Olivier Dugeon <olivier.dugeon@orange.com> | 2023-04-18 10:30:50 +0200 |
commit | 30ce6361b9b2b92c83ce6940d5c2bd94c67dccd7 (patch) | |
tree | 330dc80b6de0f8536fc18b0976bef0399fdfe0d0 /ospfd | |
parent | Merge pull request #13162 from donaldsharp/pass_by_value_no_no_no (diff) | |
download | frr-30ce6361b9b2b92c83ce6940d5c2bd94c67dccd7.tar.xz frr-30ce6361b9b2b92c83ce6940d5c2bd94c67dccd7.zip |
ospfd: Force Opaque LSA & co to default VRF
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>
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_opaque.c | 21 | ||||
-rw-r--r-- | ospfd/ospf_ri.c | 39 | ||||
-rw-r--r-- | ospfd/ospf_te.c | 49 |
3 files changed, 46 insertions, 63 deletions
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 6f66ee10a..c2b40af1c 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -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) { diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 0179f9ee0..725443f49 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -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; diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index b14002714..5f83e1c2c 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -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); |