Skip to content

ospfd: route-map is not applied for default-routes #20286

@Max-Mustermann33

Description

@Max-Mustermann33

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNeeds further investigation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions