-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
I want to propagate an AS-external route via OSPF. The route is a default-route with a specific metric from my local kernel routing table. I want to announce this route with the metric from the kernel routing table.
afaik I have to use a route-map in order to achieve this. So I added
default-information originate route-map ABCD
and
route-map ABCD permit 10
set metric +1
to the config for my OSPF-daemon.
But this still results in the OSPF-daemon annoucing the route with a default-value of 10. When I do the same for non-default routes (with "redistribute kernel route-map ABCD"), then it works as expected.
I looked into the code and got a patch that is working for my case, but which is very likely breaking some other stuff.
The main problem I found was that the route-map was only applied in ospf_external_lsa_default_routemap_apply(), but I guess at that point the OSPF-daemon already sent the LS-update (with metric 10) via the call to ospf_external_lsa_refresh_default() before.
My patch:
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index aee938fea..31d893d32 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -363,7 +363,7 @@ static void ospf_asbr_redist_update_timer(struct event *thread)
LSA_REFRESH_FORCE);
}
- ospf_external_lsa_refresh_default(ospf);
+ ospf_external_lsa_refresh_default(ospf, NULL);
}
void ospf_schedule_asbr_redist_update(struct ospf *ospf)
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index cd17f0a93..b6729070c 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2588,7 +2588,7 @@ void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type,
zlog_debug("%s: stop", __func__);
}
-void ospf_external_lsa_refresh_default(struct ospf *ospf)
+void ospf_external_lsa_refresh_default(struct ospf *ospf, struct external_info *default_ei)
{
struct prefix_ipv4 p;
struct external_info *ei;
@@ -2598,7 +2598,11 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf)
p.prefixlen = 0;
p.prefix.s_addr = INADDR_ANY;
- ei = ospf_default_external_info(ospf);
+ if (default_ei) {
+ ei = default_ei;
+ } else {
+ ei = ospf_default_external_info(ospf);
+ }
lsa = ospf_external_info_find_lsa(ospf, &p);
if (ei && lsa) {
@@ -2696,6 +2700,14 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
{
struct ospf_lsa *new;
int changed = 0;
+ struct external_info *default_ei;
+
+ if (is_default_prefix4(&ei->p)) {
+ default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE, ospf->instance, &ei->p);
+ if (default_ei) {
+ ospf_external_info_apply_default_routemap(ospf, ei, default_ei);
+ }
+ }
/* Check the AS-external-LSA should be originated. */
if (!is_aggr)
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 418675cb1..aba458425 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -303,7 +303,7 @@ extern uint32_t get_metric(uint8_t *metric);
extern void ospf_lsa_maxage_walker(struct event *event);
extern struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa);
-extern void ospf_external_lsa_refresh_default(struct ospf *ospf);
+extern void ospf_external_lsa_refresh_default(struct ospf *ospf, struct external_info *default_ei);
extern void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, uint8_t instance,
int force);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index f45135f44..6a451fd23 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -924,7 +924,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
metric_type(ospf, DEFAULT_ROUTE, 0),
metric_value(ospf, DEFAULT_ROUTE, 0));
- ospf_external_lsa_refresh_default(ospf);
+ ospf_external_lsa_refresh_default(ospf, NULL);
return CMD_SUCCESS;
}
@@ -968,7 +968,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
metric_type(ospf, DEFAULT_ROUTE, 0),
metric_value(ospf, DEFAULT_ROUTE, 0));
- ospf_external_lsa_refresh_default(ospf);
+ ospf_external_lsa_refresh_default(ospf, NULL);
ospf_asbr_status_update(ospf, ospf->redistribute);
return CMD_SUCCESS;
}
@@ -1077,64 +1077,6 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei);
- /* If deny then nothing to be done both in add and del case. */
- if (!ret) {
- if (IS_DEBUG_OSPF_DEFAULT_INFO)
- zlog_debug("Default originte routemap deny for ei: %pI4(%s)",
- &ei->p.prefix,
- ospf_vrf_id_to_name(ospf->vrf_id));
- return false;
- }
-
- /* Get the default LSA. */
- lsa = ospf_external_info_find_lsa(ospf, &p);
-
- /* If this is add route and permit then ooriginate default. */
- if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
- /* If permit and default already advertise then return. */
- if (lsa && !IS_LSA_MAXAGE(lsa)) {
- if (IS_DEBUG_OSPF_DEFAULT_INFO)
- zlog_debug("Default lsa already originated(%s)",
- ospf_vrf_id_to_name(ospf->vrf_id));
- return true;
- }
-
- if (IS_DEBUG_OSPF_DEFAULT_INFO)
- zlog_debug("Originating/Refreshing default lsa(%s)",
- ospf_vrf_id_to_name(ospf->vrf_id));
-
- if (lsa && IS_LSA_MAXAGE(lsa))
- /* Refresh lsa.*/
- ospf_external_lsa_refresh(ospf, lsa, default_ei, true,
- false);
- else
- /* If permit and default not advertised then advertise.
- */
- ospf_external_lsa_originate(ospf, default_ei);
-
- } else if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) {
- /* If deny and lsa is not originated then nothing to be done.*/
- if (!lsa) {
- if (IS_DEBUG_OSPF_DEFAULT_INFO)
- zlog_debug("Default lsa not originated, not flushing(%s)",
- ospf_vrf_id_to_name(ospf->vrf_id));
- return true;
- }
-
- if (IS_DEBUG_OSPF_DEFAULT_INFO)
- zlog_debug("Running default route-map again as ei: %pI4(%s) deleted",
- &ei->p.prefix,
- ospf_vrf_id_to_name(ospf->vrf_id));
- /*
- * if this route delete was permitted then we need to check
- * there are any other external info which can still trigger
- * default route origination else flush it.
- */
- event_add_event(master,
- ospf_external_lsa_default_routemap_timer, ospf,
- 0, &ospf->t_default_routemap_timer);
- }
-
return true;
}
@@ -1355,9 +1297,15 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
return 0;
}
if (ospf->router_id.s_addr != INADDR_ANY) {
- if (is_default_prefix4(&p))
- ospf_external_lsa_refresh_default(ospf);
- else {
+ if (is_default_prefix4(&p)) {
+ /*
+ * Check if default-information originate is
+ * with some routemap prefix/access list match.
+ */
+ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
+
+ ospf_external_lsa_refresh_default(ospf, ei);
+ } else {
struct ospf_external_aggr_rt *aggr;
struct as_external_lsa *al;
struct ospf_lsa *lsa = NULL;
@@ -1448,12 +1396,6 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
}
}
- /*
- * Check if default-information originate is
- * with some routemap prefix/access list match.
- */
- ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
-
} else { /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
struct ospf_external_aggr_rt *aggr;
@@ -1480,7 +1422,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
p);
if (is_default_prefix4(&p))
- ospf_external_lsa_refresh_default(ospf);
+ ospf_external_lsa_refresh_default(ospf, NULL);
else
ospf_external_lsa_flush(ospf, rt_type, &p,
ifindex /*, nexthop */);
@@ -1695,7 +1637,7 @@ static void ospf_distribute_list_update_timer(struct event *thread)
}
}
if (default_refresh)
- ospf_external_lsa_refresh_default(ospf);
+ ospf_external_lsa_refresh_default(ospf, NULL);
}
/* Update distribute-list and set timer to apply access-list. */
Version
10.3.1
How to reproduce
Try to use a route-map to propagate a default-route with metric via OSPF
Expected behavior
default-route is propagated with metric computed by route-map
Actual behavior
default-route is propagated with metric 10
Additional context
No response
Checklist
- I have searched the open issues for this bug.
- I have not included sensitive information in this report.