]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospf6d/ospf6_asbr.c
libs, daemons: use const in route-map apply
[mirror_frr.git] / ospf6d / ospf6_asbr.c
index 1b46b9c68dcf2c12fdc251e1bc59ebf97d54028f..e6bd3faf405b6712e01c21c26e7b58f2aa60d718 100644 (file)
@@ -260,12 +260,12 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                        listnode_delete(old_route->nh_list,
                                                        rnh);
                                        ospf6_nexthop_delete(rnh);
-                                       route_updated = true;
                                }
                        }
 
                        listnode_delete(old_route->paths, o_path);
                        ospf6_path_free(o_path);
+                       route_updated = true;
 
                        /* Current route's path (adv_router info) is similar
                         * to route being added.
@@ -273,6 +273,19 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                         * Update FIB with effective NHs.
                         */
                        if (listcount(old_route->paths)) {
+                               for (ALL_LIST_ELEMENTS(old_route->paths,
+                                               anode, anext, o_path)) {
+                                       ospf6_merge_nexthops(
+                                               old_route->nh_list,
+                                               o_path->nh_list);
+                               }
+                               /* Update RIB/FIB with effective
+                                * nh_list
+                                */
+                               if (ospf6->route_table->hook_add)
+                                       (*ospf6->route_table->hook_add)
+                                               (old_route);
+
                                if (old_route->path.origin.id
                                            == route->path.origin.id
                                    && old_route->path.origin.adv_router
@@ -290,23 +303,6 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                        old_route->path.origin.adv_router =
                                                h_path->origin.adv_router;
                                }
-
-                               if (route_updated) {
-                                       for (ALL_LIST_ELEMENTS(old_route->paths,
-                                                              anode, anext,
-                                                              o_path)) {
-                                               ospf6_merge_nexthops(
-                                                       old_route->nh_list,
-                                                       o_path->nh_list);
-                                       }
-                                       /* Update RIB/FIB with effective
-                                        * nh_list
-                                        */
-                                       if (ospf6->route_table->hook_add)
-                                               (*ospf6->route_table->hook_add)(
-                                                       old_route);
-                                       break;
-                               }
                        } else {
                                if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
                                        prefix2str(&old_route->prefix, buf,
@@ -319,7 +315,6 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                }
                                ospf6_route_remove(old_route,
                                                   ospf6->route_table);
-                               break;
                        }
                }
                if (route_updated)
@@ -374,13 +369,6 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                /* Add a nh_list to new ecmp path */
                                ospf6_copy_nexthops(ecmp_path->nh_list,
                                                    route->nh_list);
-                               /* Merge nexthop to existing route's nh_list */
-                               ospf6_route_merge_nexthops(old_route, route);
-
-                               /* Update RIB/FIB */
-                               if (ospf6->route_table->hook_add)
-                                       (*ospf6->route_table->hook_add)(
-                                               old_route);
 
                                /* Add the new path to route's path list */
                                listnode_add_sort(old_route->paths, ecmp_path);
@@ -400,46 +388,52 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                                listcount(old_route->nh_list));
                                }
                        } else {
-                               for (ALL_LIST_ELEMENTS_RO(o_path->nh_list,
-                                                         nnode, nh)) {
-                                       for (ALL_LIST_ELEMENTS(
-                                                    old_route->nh_list, rnode,
-                                                    rnext, rnh)) {
-                                               if (!ospf6_nexthop_is_same(rnh,
-                                                                          nh))
-                                                       continue;
-
-                                               listnode_delete(
-                                                       old_route->nh_list,
-                                                       rnh);
-                                               ospf6_nexthop_delete(rnh);
-                                       }
-                               }
                                list_delete_all_node(o_path->nh_list);
                                ospf6_copy_nexthops(o_path->nh_list,
                                                    route->nh_list);
+                       }
 
-                               /* Merge nexthop to existing route's nh_list */
-                               ospf6_route_merge_nexthops(old_route, route);
+                       /* Reset nexthop lists, rebuild from brouter table
+                        * for each adv. router.
+                        */
+                       list_delete_all_node(old_route->nh_list);
 
-                               if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
-                                       prefix2str(&route->prefix, buf,
-                                                  sizeof(buf));
-                                       zlog_debug(
-                                               "%s: existing route %s with effective nh count %u",
-                                               __PRETTY_FUNCTION__, buf,
-                                               old_route->nh_list
-                                                       ? listcount(
-                                                                 old_route
-                                                                         ->nh_list)
-                                                       : 0);
+                       for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode,
+                                                 o_path)) {
+                               struct ospf6_route *asbr_entry;
+
+                               asbr_entry = ospf6_route_lookup(
+                                                       &o_path->ls_prefix,
+                                                       ospf6->brouter_table);
+                               if (asbr_entry == NULL) {
+                                       if (IS_OSPF6_DEBUG_EXAMIN(
+                                                       AS_EXTERNAL)) {
+                                               prefix2str(&old_route->prefix,
+                                                          buf, sizeof(buf));
+                                               zlog_debug("%s: ls_prfix %s asbr_entry not found.",
+                                                          __PRETTY_FUNCTION__,
+                                                          buf);
+                                       }
+                                       continue;
                                }
+                               ospf6_route_merge_nexthops(old_route,
+                                                          asbr_entry);
+                       }
 
-                               /* Update RIB/FIB */
-                               if (ospf6->route_table->hook_add)
-                                       (*ospf6->route_table->hook_add)(
-                                               old_route);
+                       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
+                               prefix2str(&route->prefix, buf, sizeof(buf));
+                               zlog_debug("%s: route %s with effective paths %u nh %u",
+                                          __PRETTY_FUNCTION__, buf,
+                                          old_route->paths ?
+                                          listcount(old_route->paths) : 0,
+                                          old_route->nh_list ?
+                                          listcount(old_route->nh_list) : 0);
                        }
+
+                       /* Update RIB/FIB */
+                       if (ospf6->route_table->hook_add)
+                               (*ospf6->route_table->hook_add)(old_route);
+
                        /* Delete the new route its info added to existing
                         * route.
                         */
@@ -503,14 +497,16 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
        route->type = OSPF6_DEST_TYPE_NETWORK;
        route->prefix.family = AF_INET6;
        route->prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&route->prefix.u.prefix6, &external->prefix);
+       ospf6_prefix_in6_addr(&route->prefix.u.prefix6, external,
+                             &external->prefix);
 
        route->path.area_id = asbr_entry->path.area_id;
        route->path.origin.type = lsa->header->type;
        route->path.origin.id = lsa->header->id;
        route->path.origin.adv_router = lsa->header->adv_router;
-
        route->path.prefix_options = external->prefix.prefix_options;
+       memcpy(&route->path.ls_prefix, &asbr_id, sizeof(struct prefix));
+
        if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_E)) {
                route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
                route->path.metric_type = 2;
@@ -581,7 +577,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        route_to_del->type = OSPF6_DEST_TYPE_NETWORK;
        route_to_del->prefix.family = AF_INET6;
        route_to_del->prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&route_to_del->prefix.u.prefix6,
+       ospf6_prefix_in6_addr(&route_to_del->prefix.u.prefix6, external,
                              &external->prefix);
 
        route_to_del->path.origin.type = lsa->header->type;
@@ -608,7 +604,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        memset(&prefix, 0, sizeof(struct prefix));
        prefix.family = AF_INET6;
        prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&prefix.u.prefix6, &external->prefix);
+       ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix);
 
        route = ospf6_route_lookup(&prefix, ospf6->route_table);
        if (route == NULL) {
@@ -685,8 +681,9 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
                                        prefix2str(&prefix, buf, sizeof(buf));
                                        zlog_debug(
-                                               "%s: route %s path found with nh %u to remove.",
+                                               "%s: route %s path found with cost %u nh %u to remove.",
                                                __PRETTY_FUNCTION__, buf,
+                                               route->path.cost,
                                                listcount(o_path->nh_list));
                                }
 
@@ -738,28 +735,37 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                                listcount(route->nh_list));
                                }
 
-                               /* Update RIB/FIB with effective nh_list */
-                               if (ospf6->route_table->hook_add)
-                                       (*ospf6->route_table->hook_add)(route);
+                               if (listcount(route->paths)) {
+                                       /* Update RIB/FIB with effective
+                                        * nh_list
+                                        */
+                                       if (ospf6->route_table->hook_add)
+                                               (*ospf6->route_table->hook_add)
+                                               (route);
 
-                               /* route's primary path is similar to LSA,
-                                * replace route's primary path with
-                                * route's paths list head.
-                                */
-                               if (route->path.origin.id == lsa->header->id
-                                   && route->path.origin.adv_router
-                                              == lsa->header->adv_router) {
-                                       struct ospf6_path *h_path;
+                                       /* route's primary path is similar
+                                        * to LSA, replace route's primary
+                                        * path with route's paths list head.
+                                        */
+                                       if ((route->path.origin.id ==
+                                           lsa->header->id) &&
+                                           (route->path.origin.adv_router
+                                                == lsa->header->adv_router)) {
+                                               struct ospf6_path *h_path;
 
-                                       h_path = (struct ospf6_path *)
+                                               h_path = (struct ospf6_path *)
                                                listgetdata(
                                                        listhead(route->paths));
-                                       route->path.origin.type =
-                                               h_path->origin.type;
-                                       route->path.origin.id =
-                                               h_path->origin.id;
-                                       route->path.origin.adv_router =
+                                               route->path.origin.type =
+                                                       h_path->origin.type;
+                                               route->path.origin.id =
+                                                       h_path->origin.id;
+                                               route->path.origin.adv_router =
                                                h_path->origin.adv_router;
+                                       }
+                               } else {
+                                       ospf6_route_remove(route,
+                                                          ospf6->route_table);
                                }
                        }
                        continue;
@@ -1339,7 +1345,8 @@ static void ospf6_redistribute_show_config(struct vty *vty)
 
 /* Routemap Functions */
 static route_map_result_t
-ospf6_routemap_rule_match_address_prefixlist(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_match_address_prefixlist(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -1378,7 +1385,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_match_address_prefixlist_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t
-ospf6_routemap_rule_match_interface(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_match_interface(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct interface *ifp;
@@ -1416,7 +1423,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_match_interface_cmd = {
 
 /* Match function for matching route tags */
 static route_map_result_t ospf6_routemap_rule_match_tag(void *rule,
-                                                       struct prefix *prefix,
+                                                       const struct prefix *p,
                                                        route_map_object_t type,
                                                        void *object)
 {
@@ -1436,7 +1443,7 @@ static struct route_map_rule_cmd ospf6_routemap_rule_match_tag_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_metric_type(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_metric_type(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        char *metric_type = rule;
@@ -1472,7 +1479,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_metric(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_metric(void *rule, const struct prefix *prefix,
                               route_map_object_t type, void *object)
 {
        char *metric = rule;
@@ -1507,7 +1514,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_metric_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_forwarding(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_forwarding(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        char *forwarding = rule;
@@ -1545,7 +1552,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_forwarding_cmd = {
 };
 
 static route_map_result_t ospf6_routemap_rule_set_tag(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *p,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -1700,7 +1707,8 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa,
                        lsa->header);
 
                if (pos == 0) {
-                       ospf6_prefix_in6_addr(&in6, &external->prefix);
+                       ospf6_prefix_in6_addr(&in6, external,
+                                             &external->prefix);
                        prefix_length = external->prefix.prefix_length;
                } else {
                        in6 = *((struct in6_addr