]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_zebra.c
lib: enforce vrf_name_to_id by returning default_vrf when name is null
[mirror_frr.git] / ospfd / ospf_zebra.c
index 8c94a8ef9949bde227fa446aa0b05d7014a7e82e..c7bde55cd9d12c10ebd0e87a8586ec5c916cb386 100644 (file)
@@ -152,10 +152,6 @@ static int ospf_interface_delete(int command, struct zclient *zclient,
        if (ifp == NULL)
                return 0;
 
-       if (if_is_up(ifp))
-               zlog_warn("Zebra: got delete of %s, but interface is still up",
-                         ifp->name);
-
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
                        "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
@@ -587,7 +583,7 @@ void ospf_external_del(struct ospf *ospf, uint8_t type, unsigned short instance)
                listnode_delete(ospf->external[type], ext);
 
                if (!ospf->external[type]->count)
-                       list_delete_and_null(&ospf->external[type]);
+                       list_delete(&ospf->external[type]);
 
                XFREE(MTYPE_OSPF_EXTERNAL, ext);
        }
@@ -630,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);
 
@@ -645,7 +643,7 @@ void ospf_redist_del(struct ospf *ospf, uint8_t type, unsigned short instance)
        if (red) {
                listnode_delete(ospf->redist[type], red);
                if (!ospf->redist[type]->count) {
-                       list_delete_and_null(&ospf->redist[type]);
+                       list_delete(&ospf->redist[type]);
                }
                ospf_routemap_unset(red);
                XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
@@ -744,8 +742,6 @@ int ospf_redistribute_unset(struct ospf *ospf, int type,
                zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
                           ospf_redist_string(type), instance, ospf->vrf_id);
 
-       ospf_redist_del(ospf, type, instance);
-
        /* Remove the routes from OSPF table. */
        ospf_redistribute_withdraw(ospf, type, instance);
 
@@ -759,60 +755,112 @@ 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_redist *red;
+       struct ospf_external *ext;
+       struct prefix_ipv4 p;
+       struct in_addr nexthop;
+       int cur_originate = ospf->default_originate;
 
-       ospf->default_originate = originate;
+       nexthop.s_addr = 0;
+       p.family = AF_INET;
+       p.prefix.s_addr = 0;
+       p.prefixlen = 0;
 
-       red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
-       red->dmetric.type = mtype;
-       red->dmetric.value = mvalue;
+       ospf->default_originate = originate;
 
        ospf_external_add(ospf, DEFAULT_ROUTE, 0);
 
-       if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
-               /* if ospf->default_originate changes value, is calling
-                  ospf_external_lsa_refresh_default sufficient to implement
-                  the change? */
-               ospf_external_lsa_refresh_default(ospf);
+       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]",
                                ospf_redist_string(DEFAULT_ROUTE),
                                metric_type(ospf, DEFAULT_ROUTE, 0),
                                metric_value(ospf, DEFAULT_ROUTE, 0));
-               return CMD_SUCCESS;
-       }
 
-       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);
 
-       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);
+               } else {
+                       /* "default-info originate" configured now,where
+                        * "default-info originate always" configured
+                        * previoulsy.
+                        */
 
-       ospf_asbr_status_update(ospf, ++ospf->redistribute);
+                       ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0);
+
+                       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;
-       ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
-
-       zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
-                                    ospf->vrf_id);
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                zlog_debug("Redistribute[DEFAULT]: Stop");
@@ -959,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)
@@ -969,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));
@@ -991,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
@@ -1001,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 */
@@ -1015,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))
@@ -1045,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 */);
        }
 
@@ -1209,7 +1268,6 @@ static void ospf_filter_update(struct access_list *access)
                /* Update distribute-list, and apply filter. */
                for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
                        struct list *red_list;
-                       struct listnode *node;
                        struct ospf_redist *red;
 
                        red_list = ospf->redist[type];
@@ -1299,7 +1357,6 @@ void ospf_prefix_list_update(struct prefix_list *plist)
                 */
                for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
                        struct list *red_list;
-                       struct listnode *node;
                        struct ospf_redist *red;
 
                        red_list = ospf->redist[type];
@@ -1520,7 +1577,7 @@ static void ospf_zebra_connected(struct zclient *zclient)
 void ospf_zebra_init(struct thread_master *master, unsigned short instance)
 {
        /* Allocate zebra structure. */
-       zclient = zclient_new_notify(master, &zclient_options_default);
+       zclient = zclient_new(master, &zclient_options_default);
        zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
        zclient->zebra_connected = ospf_zebra_connected;
        zclient->router_id_update = ospf_router_id_update_zebra;