From 7bced643b977e48bc36791614c949ddf19bc97a1 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Wed, 5 May 2021 19:26:19 +0300 Subject: [PATCH] ospfd: fix redistribution config when vrf doesn't exist Currently ospfd relies on vrf bitmaps in zclient to check that the redistribution is configured. This doesn't work when the VRF for OSPF instance doesn't exist yet, because vrf bitmaps ignore VRF_UNKNOWN id. Because of this, the following problems occur when the VRF doesn't exist: - repeated "redistribute smth" command is processed as a first-time instead of an update - "no redistribute smth" doesn't work at all This commit fixes both issues by relying on internal redistribution config instead of zclient vrf bitmaps. Signed-off-by: Igor Ryzhov --- ospfd/ospf_vty.c | 31 ++++++++++++++++++++----- ospfd/ospf_zebra.c | 56 ++++++++++++++++++---------------------------- ospfd/ospf_zebra.h | 6 +++-- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 57ef6029ad..50943c4ccf 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -9111,14 +9111,13 @@ DEFUN (ospf_redistribute_source, int metric = -1; struct ospf_redist *red; int idx = 0; + bool update = false; /* Get distribute source. */ source = proto_redistnum(AFI_IP, argv[idx_protocol]->text); if (source < 0) return CMD_WARNING_CONFIG_FAILED; - red = ospf_redist_add(ospf, source, 0); - /* Get metric value. */ if (argv_find(argv, argc, "(0-16777214)", &idx)) { if (!str2metric(argv[idx]->arg, &metric)) @@ -9131,13 +9130,25 @@ DEFUN (ospf_redistribute_source, return CMD_WARNING_CONFIG_FAILED; } idx = 1; + + red = ospf_redist_lookup(ospf, source, 0); + if (!red) + red = ospf_redist_add(ospf, source, 0); + else + update = true; + /* Get route-map */ if (argv_find(argv, argc, "WORD", &idx)) { ospf_routemap_set(red, argv[idx]->arg); } else ospf_routemap_unset(red); - return ospf_redistribute_set(ospf, source, 0, type, metric); + if (update) + return ospf_redistribute_update(ospf, red, source, 0, type, + metric); + else + return ospf_redistribute_set(ospf, red, source, 0, type, + metric); } DEFUN (no_ospf_redistribute_source, @@ -9195,6 +9206,7 @@ DEFUN (ospf_redistribute_instance_source, int metric = -1; unsigned short instance; struct ospf_redist *red; + bool update = false; source = proto_redistnum(AFI_IP, argv[idx_ospf_table]->text); @@ -9227,7 +9239,11 @@ DEFUN (ospf_redistribute_instance_source, if (!str2metric_type(argv[idx + 1]->arg, &type)) return CMD_WARNING_CONFIG_FAILED; - red = ospf_redist_add(ospf, source, instance); + red = ospf_redist_lookup(ospf, source, instance); + if (!red) + red = ospf_redist_add(ospf, source, instance); + else + update = true; idx = 3; if (argv_find(argv, argc, "route-map", &idx)) @@ -9235,7 +9251,12 @@ DEFUN (ospf_redistribute_instance_source, else ospf_routemap_unset(red); - return ospf_redistribute_set(ospf, source, instance, type, metric); + if (update) + return ospf_redistribute_update(ospf, red, source, instance, + type, metric); + else + return ospf_redistribute_set(ospf, red, source, instance, type, + metric); } DEFUN (no_ospf_redistribute_instance_source, diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index a2ce4d1ce7..2911052dad 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -773,45 +773,36 @@ int ospf_is_type_redistributed(struct ospf *ospf, int type, ospf->vrf_id)))); } -int ospf_redistribute_set(struct ospf *ospf, int type, unsigned short instance, - int mtype, int mvalue) +int ospf_redistribute_update(struct ospf *ospf, struct ospf_redist *red, + int type, unsigned short instance, int mtype, + int mvalue) { int force = 0; - struct ospf_redist *red; - - red = ospf_redist_lookup(ospf, type, instance); - if (red == NULL) { - zlog_err( - "Redistribute[%s][%d]: Lookup failed Type[%d] , Metric[%d]", - ospf_redist_string(type), instance, - metric_type(ospf, type, instance), - metric_value(ospf, type, instance)); - return CMD_WARNING_CONFIG_FAILED; + if (mtype != red->dmetric.type) { + red->dmetric.type = mtype; + force = LSA_REFRESH_FORCE; + } + if (mvalue != red->dmetric.value) { + red->dmetric.value = mvalue; + force = LSA_REFRESH_FORCE; } - if (ospf_is_type_redistributed(ospf, type, instance)) { - if (mtype != red->dmetric.type) { - red->dmetric.type = mtype; - force = LSA_REFRESH_FORCE; - } - if (mvalue != red->dmetric.value) { - red->dmetric.value = mvalue; - force = LSA_REFRESH_FORCE; - } - - ospf_external_lsa_refresh_type(ospf, type, instance, force); + ospf_external_lsa_refresh_type(ospf, type, instance, force); - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]", - ospf_redist_string(type), instance, - metric_type(ospf, type, instance), - metric_value(ospf, type, instance)); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug( + "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]", + ospf_redist_string(type), instance, + metric_type(ospf, type, instance), + metric_value(ospf, type, instance)); - return CMD_SUCCESS; - } + return CMD_SUCCESS; +} +int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type, + unsigned short instance, int mtype, int mvalue) +{ red->dmetric.type = mtype; red->dmetric.value = mvalue; @@ -838,9 +829,6 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, if (type == zclient->redist_default && instance == zclient->instance) return CMD_SUCCESS; - if (!ospf_is_type_redistributed(ospf, type, instance)) - return CMD_SUCCESS; - zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, instance, ospf->vrf_id); diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index bdc8af0402..3f4edfa29c 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -78,10 +78,12 @@ extern struct ospf_redist *ospf_redist_add(struct ospf *, uint8_t, unsigned short); extern void ospf_redist_del(struct ospf *, uint8_t, unsigned short); -extern int ospf_redistribute_set(struct ospf *, int, unsigned short, int, int); +extern int ospf_redistribute_update(struct ospf *, struct ospf_redist *, int, + unsigned short, int, int); +extern int ospf_redistribute_set(struct ospf *, struct ospf_redist *, int, + unsigned short, int, int); extern int ospf_redistribute_unset(struct ospf *, int, unsigned short); extern int ospf_redistribute_default_set(struct ospf *, int, int, int); -extern int ospf_redistribute_default_unset(struct ospf *); extern int ospf_distribute_list_out_set(struct ospf *, int, const char *); extern int ospf_distribute_list_out_unset(struct ospf *, int, const char *); extern void ospf_routemap_set(struct ospf_redist *, const char *); -- 2.39.5