]> 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 c23fe99bc8bd5cb6eb09256b21234964bb8b5847..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) {
@@ -616,6 +612,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                        prefix2str(&prefix, buf, sizeof(buf));
                        zlog_debug("AS-External route %s not found", buf);
                }
+
+               ospf6_route_delete(route_to_del);
                return;
        }
 
@@ -683,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));
                                }
 
@@ -736,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;
@@ -811,8 +819,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
 void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry)
 {
        struct ospf6_lsa *lsa;
-       u_int16_t type;
-       u_int32_t router;
+       uint16_t type;
+       uint32_t router;
 
        if (!CHECK_FLAG(asbr_entry->flag, OSPF6_ROUTE_BEST)) {
                char buf[16];
@@ -833,8 +841,8 @@ void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry)
 void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry)
 {
        struct ospf6_lsa *lsa;
-       u_int16_t type;
-       u_int32_t router;
+       uint16_t type;
+       uint32_t router;
 
        type = htons(OSPF6_LSTYPE_AS_EXTERNAL);
        router = ospf6_linkstate_prefix_adv_router(&asbr_entry->prefix);
@@ -995,7 +1003,8 @@ void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa)
 }
 
 void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
-                                struct prefix *prefix, u_int nexthop_num,
+                                struct prefix *prefix,
+                                unsigned int nexthop_num,
                                 struct in6_addr *nexthop, route_tag_t tag)
 {
        int ret;
@@ -1336,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)
 {
@@ -1375,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;
@@ -1413,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)
 {
@@ -1433,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;
@@ -1469,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;
@@ -1484,7 +1494,7 @@ ospf6_routemap_rule_set_metric(void *rule, struct prefix *prefix,
 
 static void *ospf6_routemap_rule_set_metric_compile(const char *arg)
 {
-       u_int32_t metric;
+       uint32_t metric;
        char *endp;
        metric = strtoul(arg, &endp, 0);
        if (metric > OSPF_LS_INFINITY || *endp != '\0')
@@ -1504,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;
@@ -1542,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)
 {
@@ -1697,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
@@ -1738,7 +1749,7 @@ static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
 
        vty_out(vty, "     Bits: %s\n", buf);
        vty_out(vty, "     Metric: %5lu\n",
-               (u_long)OSPF6_ASBR_METRIC(external));
+               (unsigned long)OSPF6_ASBR_METRIC(external));
 
        ospf6_prefix_options_printbuf(external->prefix.prefix_options, buf,
                                      sizeof(buf));
@@ -1771,7 +1782,7 @@ static void ospf6_asbr_external_route_show(struct vty *vty,
 {
        struct ospf6_external_info *info = route->route_option;
        char prefix[PREFIX2STR_BUFFER], id[16], forwarding[64];
-       u_int32_t tmp_id;
+       uint32_t tmp_id;
 
        prefix2str(&route->prefix, prefix, sizeof(prefix));
        tmp_id = ntohl(info->id);
@@ -1786,8 +1797,9 @@ static void ospf6_asbr_external_route_show(struct vty *vty,
        vty_out(vty, "%c %-32s %-15s type-%d %5lu %s\n",
                zebra_route_char(info->type), prefix, id,
                route->path.metric_type,
-               (u_long)(route->path.metric_type == 2 ? route->path.u.cost_e2
-                                                     : route->path.cost),
+               (unsigned long)(route->path.metric_type == 2
+                                       ? route->path.u.cost_e2
+                                       : route->path.cost),
                forwarding);
 }