]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospfd: issue with the "default-information originate always" command #2980
authorrgirada <rgirada@vmware.com>
Mon, 1 Oct 2018 11:38:01 +0000 (04:38 -0700)
committerrgirada <rgirada@vmware.com>
Tue, 9 Oct 2018 09:52:27 +0000 (02:52 -0700)
Made changes such that message wont be sent to zebra to validate default
route existence  if user configured with “always”.

Signed-off-by: rgirada <rgirada@vmware.com>
ospfd/ospf_vty.c
ospfd/ospf_zebra.c

index e25d1a31dedf333b164a2708da6012f9ad1a25de..dd8ffa234df56f2e8409d7133761b62f0e75a2cd 100644 (file)
@@ -8386,6 +8386,9 @@ DEFUN (ospf_default_information_originate,
        int metric = -1;
        struct ospf_redist *red;
        int idx = 0;
+       int cur_originate = ospf->default_originate;
+       int sameRtmap = 0;
+       char *rtmap = NULL;
 
        red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
 
@@ -8407,7 +8410,28 @@ DEFUN (ospf_default_information_originate,
        idx = 1;
        /* Get route-map */
        if (argv_find(argv, argc, "WORD", &idx))
-               ospf_routemap_set(red, argv[idx]->arg);
+               rtmap = argv[idx]->arg;
+
+       /* To check ,if user is providing same route map */
+       if ((rtmap == ROUTEMAP_NAME(red)) ||
+           (rtmap && ROUTEMAP_NAME(red)
+           && (strcmp(rtmap, ROUTEMAP_NAME(red)) == 0)))
+               sameRtmap = 1;
+
+       /* Don't allow if the same lsa is aleardy originated. */
+       if ((sameRtmap)
+           && (red->dmetric.type == type)
+           && (red->dmetric.value == metric)
+           && (cur_originate == default_originate))
+               return CMD_SUCCESS;
+
+       /* Updating Metric details */
+       red->dmetric.type = type;
+       red->dmetric.value = metric;
+
+       /* updating route map details */
+       if (rtmap)
+               ospf_routemap_set(red, rtmap);
        else
                ospf_routemap_unset(red);
 
index 8a7f38b743ba3e1cf32f27dfa87c5d4eb61513cf..4de68b15f2a14cd80be5642f9721f7bbb6c34084 100644 (file)
@@ -626,6 +626,8 @@ struct ospf_redist *ospf_redist_add(struct ospf *ospf, uint8_t type,
        red->instance = instance;
        red->dmetric.type = -1;
        red->dmetric.value = -1;
+       ROUTEMAP_NAME(red) = NULL;
+       ROUTEMAP(red) = NULL;
 
        listnode_add(red_list, red);
 
@@ -753,11 +755,54 @@ int ospf_redistribute_unset(struct ospf *ospf, int type,
 int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
                                  int mvalue)
 {
+       struct ospf_external *ext;
+       struct prefix_ipv4 p;
+       struct in_addr nexthop;
+       int cur_originate = ospf->default_originate;
+
+       nexthop.s_addr = 0;
+       p.family = AF_INET;
+       p.prefix.s_addr = 0;
+       p.prefixlen = 0;
+
        ospf->default_originate = originate;
 
        ospf_external_add(ospf, DEFAULT_ROUTE, 0);
 
-       if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
+       if (cur_originate == DEFAULT_ORIGINATE_NONE) {
+               /* First time configuration */
+               if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
+                       zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
+                       metric_type(ospf, DEFAULT_ROUTE, 0),
+                       metric_value(ospf, DEFAULT_ROUTE, 0));
+
+               if (ospf->router_id.s_addr == 0)
+                       ospf->external_origin |= (1 << DEFAULT_ROUTE);
+               if ((originate == DEFAULT_ORIGINATE_ALWAYS)
+                         && (ospf->router_id.s_addr)) {
+
+                       /* always , so originate lsa even it doesn't
+                        * exist in RIB.
+                        */
+                       ospf_external_info_add(ospf, DEFAULT_ROUTE, 0,
+                                                p, 0, nexthop, 0);
+                       ospf_external_lsa_refresh_default(ospf);
+
+               } else if (originate == DEFAULT_ORIGINATE_ZEBRA) {
+                       /* Send msg to Zebra to validate default route
+                        * existance.
+                        */
+                       zclient_redistribute_default(
+                                       ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
+                                        zclient, ospf->vrf_id);
+               }
+
+               ospf_asbr_status_update(ospf, ++ospf->redistribute);
+               return CMD_SUCCESS;
+
+
+       } else if (originate == cur_originate) {
+               /* Refresh the lsa since metric might different */
                if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                        zlog_debug(
                                "Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
@@ -765,37 +810,58 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
                                metric_type(ospf, DEFAULT_ROUTE, 0),
                                metric_value(ospf, DEFAULT_ROUTE, 0));
 
-       zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
-                                    ospf->vrf_id);
+               ospf_external_lsa_refresh_default(ospf);
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
-               zlog_debug("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
-                          metric_type(ospf, DEFAULT_ROUTE, 0),
-                          metric_value(ospf, DEFAULT_ROUTE, 0));
+       } else {
+               /* "default-info originate always" configured now,
+                * where "default-info originate" configured previoulsly.
+                */
+               if (originate == DEFAULT_ORIGINATE_ALWAYS) {
+
+                       zclient_redistribute_default(
+                                       ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
+                                       zclient, ospf->vrf_id);
+                       /* here , ex-info should be added since ex-info might
+                        * have not updated earlier if def route is not exist.
+                        * If ex-iinfo ex-info already exist , it will return
+                        * smoothly.
+                        */
+                       ospf_external_info_add(ospf, DEFAULT_ROUTE, 0,
+                                                p, 0, nexthop, 0);
+                       ospf_external_lsa_refresh_default(ospf);
 
-       ospf_external_lsa_refresh_default(ospf);
+               } else {
+                       /* "default-info originate" configured now,where
+                        * "default-info originate always" configured
+                        * previoulsy.
+                        */
 
-       if (ospf->router_id.s_addr == 0)
-               ospf->external_origin |= (1 << DEFAULT_ROUTE);
-       else
-               thread_add_timer(master, ospf_default_originate_timer, ospf, 1,
-                                NULL);
+                       ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0);
 
-       ospf_asbr_status_update(ospf, ++ospf->redistribute);
+                       ext = ospf_external_lookup(ospf, DEFAULT_ROUTE, 0);
+                       if (ext && EXTERNAL_INFO(ext))
+                               ospf_external_info_delete(ospf,
+                                                DEFAULT_ROUTE, 0, p);
+
+                       zclient_redistribute_default(
+                                       ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
+                                       zclient, ospf->vrf_id);
+               }
+       }
 
        return CMD_SUCCESS;
 }
-
 int ospf_redistribute_default_unset(struct ospf *ospf)
 {
-       if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
-               return CMD_SUCCESS;
+       if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA) {
+               if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
+                       return CMD_SUCCESS;
+               zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
+                                zclient, ospf->vrf_id);
+       }
 
        ospf->default_originate = DEFAULT_ORIGINATE_NONE;
 
-       zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
-                                    ospf->vrf_id);
-
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                zlog_debug("Redistribute[DEFAULT]: Stop");
 
@@ -941,6 +1007,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
        struct external_info *ei;
        struct ospf *ospf;
        int i;
+       uint8_t rt_type;
 
        ospf = ospf_lookup_by_vrf_id(vrf_id);
        if (ospf == NULL)
@@ -951,11 +1018,21 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
 
        ifindex = api.nexthops[0].ifindex;
        nexthop = api.nexthops[0].gate.ipv4;
+       rt_type = api.type;
 
        memcpy(&p, &api.prefix, sizeof(p));
        if (IPV4_NET127(ntohl(p.prefix.s_addr)))
                return 0;
 
+       /* Re-destributed route is default route.
+        * Here, route type is used as 'ZEBRA_ROUTE_KERNEL' for
+        * updating ex-info. But in resetting (no default-info
+        * originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
+        * Resolved this inconsistency by maintaining same route type.
+        */
+       if (is_prefix_default(&p))
+               rt_type = DEFAULT_ROUTE;
+
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
                char buf_prefix[PREFIX_STRLEN];
                prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
@@ -973,8 +1050,8 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
                 */
 
                /* Protocol tag overwrites all other tag value sent by zebra */
-               if (ospf->dtag[api.type] > 0)
-                       api.tag = ospf->dtag[api.type];
+               if (ospf->dtag[rt_type] > 0)
+                       api.tag = ospf->dtag[rt_type];
 
                /*
                 * Given zebra sends update for a prefix via ADD message, it
@@ -983,12 +1060,12 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
                 * source
                 * types.
                 */
-               for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-                       if (i != api.type)
+               for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
+                       if (i != rt_type)
                                ospf_external_info_delete(ospf, i, api.instance,
                                                          p);
 
-               ei = ospf_external_info_add(ospf, api.type, api.instance, p,
+               ei = ospf_external_info_add(ospf, rt_type, api.instance, p,
                                            ifindex, nexthop, api.tag);
                if (ei == NULL) {
                        /* Nothing has changed, so nothing to do; return */
@@ -997,7 +1074,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
                if (ospf->router_id.s_addr == 0)
                        /* Set flags to generate AS-external-LSA originate event
                           for each redistributed protocols later. */
-                       ospf->external_origin |= (1 << api.type);
+                       ospf->external_origin |= (1 << rt_type);
                else {
                        if (ei) {
                                if (is_prefix_default(&p))
@@ -1027,11 +1104,11 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
                }
        } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
        {
-               ospf_external_info_delete(ospf, api.type, api.instance, p);
+               ospf_external_info_delete(ospf, rt_type, api.instance, p);
                if (is_prefix_default(&p))
                        ospf_external_lsa_refresh_default(ospf);
                else
-                       ospf_external_lsa_flush(ospf, api.type, &p,
+                       ospf_external_lsa_flush(ospf, rt_type, &p,
                                                ifindex /*, nexthop */);
        }