diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 726 |
1 files changed, 222 insertions, 504 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e48da0479b..13418c509e 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -37,6 +37,7 @@ #include "nexthop.h" #include "vrf.h" #include "mpls.h" +#include "srcdest_table.h" #include "zebra/rib.h" #include "zebra/rt.h" @@ -88,7 +89,7 @@ static void __attribute__((format (printf, 5, 6))) _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority, const char *msgfmt, ...) { - char buf[PREFIX_STRLEN + 8]; + char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")]; char msgbuf[512]; va_list ap; @@ -98,9 +99,9 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int prior if (rn) { - rib_table_info_t *info = rn->table->info; + rib_table_info_t *info = srcdest_rnode_table_info (rn); + srcdest_rnode2str(rn, buf, sizeof(buf)); - prefix2str(&rn->p, buf, sizeof(buf)); if (info->safi == SAFI_MULTICAST) strcat(buf, " (MRIB)"); } @@ -347,10 +348,10 @@ nexthop_has_fib_child(struct nexthop *nexthop) /* If force flag is not set, do not modify falgs at all for uninstall the route from FIB. */ static int -nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, - struct route_node *top) +nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set, + struct route_node *top) { - struct prefix_ipv4 p; + struct prefix p; struct route_table *table; struct route_node *rn; struct rib *match; @@ -360,7 +361,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, int recursing = 0; struct interface *ifp; - if (nexthop->type == NEXTHOP_TYPE_IPV4) + if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) nexthop->ifindex = 0; if (set) @@ -398,13 +399,25 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, } /* Make lookup prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = nexthop->gate.ipv4; - + memset (&p, 0, sizeof (struct prefix)); + switch (afi) + { + case AFI_IP: + p.family = AF_INET; + p.prefixlen = IPV4_MAX_PREFIXLEN; + p.u.prefix4 = nexthop->gate.ipv4; + break; + case AFI_IP6: + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_PREFIXLEN; + p.u.prefix6 = nexthop->gate.ipv6; + break; + default: + assert (afi != AFI_IP && afi != AFI_IP6); + break; + } /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id); + table = zebra_vrf_table (afi, SAFI_UNICAST, rib->vrf_id); if (! table) return 0; @@ -457,9 +470,12 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, { /* Directly point connected route. */ newhop = match->nexthop; - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4) - nexthop->ifindex = newhop->ifindex; - + if (newhop) + { + if (nexthop->type == NEXTHOP_TYPE_IPV4 || + nexthop->type == NEXTHOP_TYPE_IPV6) + nexthop->ifindex = newhop->ifindex; + } return 1; } else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) @@ -491,6 +507,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; } } + if (newhop->type == NEXTHOP_TYPE_IPV6 + || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) + { + resolved_hop->type = newhop->type; + resolved_hop->gate.ipv6 = newhop->gate.ipv6; + + if (newhop->ifindex) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->ifindex = newhop->ifindex; + } + } /* If the resolving route is an interface route, * it means the gateway we are looking up is connected @@ -503,8 +531,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (newhop->type == NEXTHOP_TYPE_IFINDEX) { resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + if (afi == AFI_IP) + { + resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; + resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + } + else if (afi == AFI_IP6) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->gate.ipv6 = nexthop->gate.ipv6; + } resolved_hop->ifindex = newhop->ifindex; } @@ -541,151 +577,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; } } - - /* If the resolving route is an interface route, - * it means the gateway we are looking up is connected - * to that interface. (The actual network is _not_ onlink). - * Therefore, the resolved route should have the original - * gateway as nexthop as it is directly connected. - * - * On Linux, we have to set the onlink netlink flag because - * otherwise, the kernel won't accept the route. - */ - if (newhop->type == NEXTHOP_TYPE_IFINDEX) - { - resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - resolved_hop->gate.ipv4 = nexthop->gate.ipv4; - resolved_hop->ifindex = newhop->ifindex; - } - - nexthop_add(&nexthop->resolved, resolved_hop); - } - resolved = 1; - } - if (resolved && set) - rib->nexthop_mtu = match->mtu; - return resolved; - } - else - { - return 0; - } - } - } - return 0; -} - -/* If force flag is not set, do not modify falgs at all for uninstall - the route from FIB. */ -static int -nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, - struct route_node *top) -{ - struct prefix_ipv6 p; - struct route_table *table; - struct route_node *rn; - struct rib *match; - int resolved; - struct nexthop *newhop, *tnewhop; - int recursing = 0; - struct nexthop *resolved_hop; - - if (nexthop->type == NEXTHOP_TYPE_IPV6) - nexthop->ifindex = 0; - - if (set) - { - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top); - nexthops_free(nexthop->resolved); - nexthop->resolved = NULL; - } - - /* Skip nexthops that have been filtered out due to route-map */ - /* The nexthops are specific to this route and so the same */ - /* nexthop for a different route may not have this flag set */ - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) - return 0; - - /* Make lookup prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_PREFIXLEN; - p.prefix = nexthop->gate.ipv6; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id); - if (! table) - return 0; - - rn = route_node_match (table, (struct prefix *) &p); - while (rn) - { - route_unlock_node (rn); - - /* If lookup self prefix return immediately. */ - if (rn == top) - return 0; - - /* Pick up selected route. */ - /* However, do not resolve over default route unless explicitly allowed. */ - if (is_default_prefix (&rn->p) && - !nh_resolve_via_default (p.family)) - return 0; - - RNODE_FOREACH_RIB (rn, match) - { - if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) - continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) - break; - } - - /* If there is no selected route or matched route is EGP, go up - tree. */ - if (! match) - { - do { - rn = rn->parent; - } while (rn && rn->info == NULL); - if (rn) - route_lock_node (rn); - } - else - { - /* If the longest prefix match for the nexthop yields - * a blackhole, mark it as inactive. */ - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE) - || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT)) - return 0; - - if (match->type == ZEBRA_ROUTE_CONNECT) - { - /* Directly point connected route. */ - newhop = match->nexthop; - - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6) - nexthop->ifindex = newhop->ifindex; - - return 1; - } - else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) - { - resolved = 0; - for (newhop = match->nexthop; newhop; newhop = newhop->next) - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB) - && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE)) - { - if (set) - { - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); - - resolved_hop = nexthop_new(); - SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); - /* See nexthop_active_ipv4 for a description how the - * resolved nexthop is constructed. */ if (newhop->type == NEXTHOP_TYPE_IPV6 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { @@ -699,59 +590,37 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, } } + /* If the resolving route is an interface route, + * it means the gateway we are looking up is connected + * to that interface. (The actual network is _not_ onlink). + * Therefore, the resolved route should have the original + * gateway as nexthop as it is directly connected. + * + * On Linux, we have to set the onlink netlink flag because + * otherwise, the kernel won't accept the route. + */ if (newhop->type == NEXTHOP_TYPE_IFINDEX) { - resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->gate.ipv6 = nexthop->gate.ipv6; - resolved_hop->ifindex = newhop->ifindex; - } - - nexthop_add(&nexthop->resolved, resolved_hop); - } - resolved = 1; - } - return resolved; - } - else if (rib->type == ZEBRA_ROUTE_STATIC) - { - resolved = 0; - for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing)) - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)) - { - if (set) - { - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - - resolved_hop = nexthop_new(); - SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); - /* See nexthop_active_ipv4 for a description how the - * resolved nexthop is constructed. */ - if (newhop->type == NEXTHOP_TYPE_IPV6 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - { - resolved_hop->type = newhop->type; - resolved_hop->gate.ipv6 = newhop->gate.ipv6; - - if (newhop->ifindex) + resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; + if (afi == AFI_IP) { - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->ifindex = newhop->ifindex; + resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; + resolved_hop->gate.ipv4 = nexthop->gate.ipv4; } - } - - if (newhop->type == NEXTHOP_TYPE_IFINDEX) - { - resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; + else if (afi == AFI_IP6) + { resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; resolved_hop->gate.ipv6 = nexthop->gate.ipv6; - resolved_hop->ifindex = newhop->ifindex; + } + resolved_hop->ifindex = newhop->ifindex; } nexthop_add(&nexthop->resolved, resolved_hop); } resolved = 1; } + if (resolved && set) + rib->nexthop_mtu = match->mtu; return resolved; } else @@ -1051,11 +920,12 @@ static unsigned nexthop_active_check (struct route_node *rn, struct rib *rib, struct nexthop *nexthop, int set) { - rib_table_info_t *info = rn->table->info; struct interface *ifp; route_map_result_t ret = RMAP_MATCH; int family; - char buf[INET6_ADDRSTRLEN+1]; + char buf[SRCDEST2STR_BUFFER]; + struct prefix *p, *src_p; + srcdest_rnode_prefixes (rn, &p, &src_p); if (rn->p.family == AF_INET) family = AFI_IP; @@ -1075,14 +945,14 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: family = AFI_IP; - if (nexthop_active_ipv4 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; case NEXTHOP_TYPE_IPV6: family = AFI_IP6; - if (nexthop_active_ipv6 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -1101,7 +971,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, } else { - if (nexthop_active_ipv6 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -1119,8 +989,8 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, /* XXX: What exactly do those checks do? Do we support * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ if (RIB_SYSTEM_ROUTE(rib) || - (family == AFI_IP && rn->p.family != AF_INET) || - (family == AFI_IP6 && rn->p.family != AF_INET6)) + (family == AFI_IP && p->family != AF_INET) || + (family == AFI_IP6 && p->family != AF_INET6)) return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); /* The original code didn't determine the family correctly @@ -1130,20 +1000,25 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, * in every case. */ if (!family) - family = info->afi; + { + rib_table_info_t *info; + + info = srcdest_rnode_table_info(rn); + family = info->afi; + } memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); /* It'll get set if required inside */ - ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id, + ret = zebra_route_map_check(family, rib->type, p, nexthop, rib->vrf_id, rib->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)); - zlog_debug("%u:%s/%d: Filtering out with NH out %s due to route map", - rib->vrf_id, buf, rn->p.prefixlen, + srcdest_rnode2str(rn, buf, sizeof(buf)); + zlog_debug("%u:%s: Filtering out with NH out %s due to route map", + rib->vrf_id, buf, ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); } UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -1216,8 +1091,11 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old) { int ret = 0; struct nexthop *nexthop, *tnexthop; - rib_table_info_t *info = rn->table->info; + rib_table_info_t *info = srcdest_rnode_table_info(rn); int recursing; + struct prefix *p, *src_p; + + srcdest_rnode_prefixes (rn, &p, &src_p); if (info->safi != SAFI_UNICAST) { @@ -1231,7 +1109,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old) * the kernel. */ zfpm_trigger_update (rn, "installing in kernel"); - ret = kernel_route_rib (&rn->p, old, rib); + ret = kernel_route_rib (p, src_p, old, rib); /* If install succeeds, update FIB flag for nexthops. */ if (!ret) @@ -1257,8 +1135,11 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib) { int ret = 0; struct nexthop *nexthop, *tnexthop; - rib_table_info_t *info = rn->table->info; + rib_table_info_t *info = srcdest_rnode_table_info(rn); int recursing; + struct prefix *p, *src_p; + + srcdest_rnode_prefixes (rn, &p, &src_p); if (info->safi != SAFI_UNICAST) { @@ -1272,7 +1153,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib) * the kernel. */ zfpm_trigger_update (rn, "uninstalling from kernel"); - ret = kernel_route_rib (&rn->p, rib, NULL); + ret = kernel_route_rib (p, src_p, rib, NULL); for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); @@ -1284,7 +1165,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib) static void rib_uninstall (struct route_node *rn, struct rib *rib) { - rib_table_info_t *info = rn->table->info; + rib_table_info_t *info = srcdest_rnode_table_info(rn); if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) { @@ -1298,7 +1179,10 @@ rib_uninstall (struct route_node *rn, struct rib *rib) if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) { - redistribute_delete (&rn->p, rib); + struct prefix *p, *src_p; + srcdest_rnode_prefixes (rn, &p, &src_p); + + redistribute_delete (p, src_p, rib); UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED); } } @@ -1367,8 +1251,6 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, struct rib *new) { - char buf[INET6_ADDRSTRLEN]; - zfpm_trigger_update (rn, "new route selected"); /* Update real nexthop. This may actually determine if nexthop is active or not. */ @@ -1381,18 +1263,20 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); if (IS_ZEBRA_DEBUG_RIB) { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); + zlog_debug ("%u:%s: Adding route rn %p, rib %p (type %d)", + zvrf_id (zvrf), buf, rn, new, new->type); } if (!RIB_SYSTEM_ROUTE (new)) { if (rib_install_kernel (rn, new, NULL)) { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_warn ("%u:%s/%d: Route install failed", - zvrf_id (zvrf), buf, rn->p.prefixlen); + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); + zlog_warn ("%u:%s: Route install failed", + zvrf_id (zvrf), buf); } } @@ -1403,16 +1287,15 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, struct rib *old) { - char buf[INET6_ADDRSTRLEN]; - zfpm_trigger_update (rn, "removing existing route"); /* Uninstall from kernel. */ if (IS_ZEBRA_DEBUG_RIB) { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type); + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); + zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d)", + zvrf_id (zvrf), buf, rn, old, old->type); } if (!RIB_SYSTEM_ROUTE (old)) @@ -1429,15 +1312,11 @@ static void rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *old, struct rib *new) { - char buf[INET6_ADDRSTRLEN]; struct nexthop *nexthop = NULL, *tnexthop; int recursing; int nh_active = 0; int installed = 1; - if (IS_ZEBRA_DEBUG_RIB) - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - /* * We have to install or update if a new route has been selected or * something has changed. @@ -1459,23 +1338,25 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (IS_ZEBRA_DEBUG_RIB) { + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " - "old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen, + zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d) " + "old %p (type %d)", zvrf_id (zvrf), buf, rn, new, new->type, old, old->type); else - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); + zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d)", + zvrf_id (zvrf), buf, rn, new, new->type); } /* Non-system route should be installed. */ if (!RIB_SYSTEM_ROUTE (new)) { if (rib_install_kernel (rn, new, old)) { + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); installed = 0; - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_warn ("%u:%s/%d: Route install failed", - zvrf_id (zvrf), buf, rn->p.prefixlen); + zlog_warn ("%u:%s: Route install failed", zvrf_id (zvrf), buf); } } @@ -1507,14 +1388,16 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (IS_ZEBRA_DEBUG_RIB) { + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen, + zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) " + "old %p (type %d) - %s", zvrf_id (zvrf), buf, rn, new, new->type, old, old->type, nh_active ? "install failed" : "nexthop inactive"); else - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s", - zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, + zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) - %s", + zvrf_id (zvrf), buf, rn, new, new->type, nh_active ? "install failed" : "nexthop inactive"); } @@ -1613,9 +1496,11 @@ rib_process (struct route_node *rn) struct rib *old_fib = NULL; struct rib *new_fib = NULL; struct rib *best = NULL; - char buf[INET6_ADDRSTRLEN]; + char buf[SRCDEST2STR_BUFFER]; rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; + struct prefix *p, *src_p; + srcdest_rnode_prefixes(rn, &p, &src_p); vrf_id_t vrf_id = VRF_UNKNOWN; assert (rn); @@ -1628,17 +1513,17 @@ rib_process (struct route_node *rn) } if (IS_ZEBRA_DEBUG_RIB) - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); + srcdest_rnode2str(rn, buf, sizeof(buf)); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug ("%u:%s/%d: Processing rn %p", vrf_id, buf, rn->p.prefixlen, rn); + zlog_debug ("%u:%s: Processing rn %p", vrf_id, buf, rn); - RNODE_FOREACH_RIB (rn, rib) + RNODE_FOREACH_RIB_SAFE (rn, rib, next) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug ("%u:%s/%d: Examine rib %p (type %d) status %x flags %x " + zlog_debug ("%u:%s: Examine rib %p (type %d) status %x flags %x " "dist %d metric %d", - vrf_id, buf, rn->p.prefixlen, rib, rib->type, rib->status, + vrf_id, buf, rib, rib->type, rib->status, rib->flags, rib->distance, rib->metric); UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); @@ -1687,9 +1572,9 @@ rib_process (struct route_node *rn) if (rib != old_selected) { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%s: %s/%d: imported via import-table but denied " + zlog_debug ("%s: %s: imported via import-table but denied " "by the ip protocol table route-map", - __func__, buf, rn->p.prefixlen); + __func__, buf); rib_unlink (rn, rib); } else @@ -1740,8 +1625,8 @@ rib_process (struct route_node *rn) if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - zlog_debug ("%u:%s/%d: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", - vrf_id, buf, rn->p.prefixlen, + zlog_debug ("%u:%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", + vrf_id, buf, (void *)old_selected, (void *)new_selected, (void *)old_fib, @@ -1789,7 +1674,7 @@ rib_process (struct route_node *rn) if (old_selected) { if (!new_selected) - redistribute_delete(&rn->p, old_selected); + redistribute_delete(p, src_p, old_selected); if (old_selected != new_selected) UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED); } @@ -1798,185 +1683,10 @@ rib_process (struct route_node *rn) { /* Install new or replace existing redistributed entry */ SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED); - redistribute_update (&rn->p, new_selected, old_selected); - } - } - -#if 0 - if (select && select == fib) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, vrf_id, "Updating existing route, select %p, fib %p", - (void *)select, (void *)fib); - if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED)) - { - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "updating existing route"); - - /* Set real nexthop. */ - /* Need to check if any NHs are active to clear the - * the selected flag - */ - if (nexthop_active_update (rn, select, 1)) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - if (! RIB_SYSTEM_ROUTE (select)) - { - /* Clear FIB flag if performing a replace, will get set again - * as part of install. - */ - for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - rib_install_kernel (rn, select, 1); - } - - /* assuming that the receiver knows how to dedup */ - redistribute_update (&rn->p, select, NULL); - } - else - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "- nexthop inactive", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - - /* Withdraw unreachable redistribute route */ - redistribute_delete(&rn->p, select); - - /* Do the uninstall here, if not done earlier. */ - if (! RIB_SYSTEM_ROUTE (select)) - rib_uninstall_kernel (rn, select); - UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); - } - UNSET_FLAG (select->status, RIB_ENTRY_CHANGED); - } - else if (! RIB_SYSTEM_ROUTE (select)) - { - /* Housekeeping code to deal with - race conditions in kernel with linux - netlink reporting interface up before IPv4 or IPv6 protocol - is ready to add routes. - This makes sure the routes are IN the kernel. - */ - - for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing)) - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - { - installed = 1; - break; - } - if (! installed) - rib_install_kernel (rn, select, 0); + redistribute_update (p, src_p, new_selected, old_selected); } - goto end; } - /* At this point we either haven't found the best RIB entry or it is - * different from what we currently intend to flag with SELECTED. In both - * cases, if a RIB block is present in FIB, it should be withdrawn. - */ - if (fib) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, vrf_id, "Removing existing route, fib %p", (void *)fib); - - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "removing existing route"); - - /* If there's no route to replace this with, withdraw redistribute and - * uninstall from kernel. - */ - if (!select) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type); - - redistribute_delete(&rn->p, fib); - if (! RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - } - - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); - - /* Set real nexthop. */ - nexthop_active_update (rn, fib, 1); - UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED); - } - - /* Regardless of some RIB entry being SELECTED or not before, now we can - * tell, that if a new winner exists, FIB is still not updated with this - * data, but ready to be. - */ - if (select) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, "Adding route, select %p", (void *)select); - - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "new route selected"); - - /* Set real nexthop. */ - if (nexthop_active_update (rn, select, 1)) - { - if (IS_ZEBRA_DEBUG_RIB) - { - if (fib) - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " - "old %p (type %d)", vrf_id, buf, rn->p.prefixlen, rn, - select, select->type, fib, fib->type); - else - zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - } - - if (! RIB_SYSTEM_ROUTE (select)) - { - /* Clear FIB flag if performing a replace, will get set again - * as part of install. - */ - if (fib) - { - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - } - rib_install_kernel (rn, select, fib? 1 : 0); - } - else - { - /* Uninstall prior route here, if needed. */ - if (fib && !RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - } - - SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); - /* Unconditionally announce, this part is exercised by new routes */ - /* If we cannot add, for example route added is learnt by the */ - /* protocol we're trying to redistribute to, delete the redist */ - /* This is notified by setting the is_update to 1 */ - redistribute_update (&rn->p, select, fib); - } - else - { - /* Uninstall prior route here and do redist delete, if needed. */ - if (fib) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "- nexthop inactive", - vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type); - - if (!RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - redistribute_delete(&rn->p, fib); - } - } - UNSET_FLAG(select->status, RIB_ENTRY_CHANGED); - } -#endif - /* Remove all RIB entries queued for removal */ RNODE_FOREACH_RIB_SAFE (rn, rib, next) { @@ -2006,7 +1716,6 @@ process_subq (struct list * subq, u_char qindex) { struct listnode *lnode = listhead (subq); struct route_node *rnode; - char buf[INET6_ADDRSTRLEN]; rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; @@ -2022,9 +1731,10 @@ process_subq (struct list * subq, u_char qindex) if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u", - zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex); + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rnode, buf, sizeof(buf)); + zlog_debug ("%u:%s: rn %p dequeued from sub-queue %u", + zvrf ? zvrf_id (zvrf) : 0, buf, rnode, qindex); } if (rnode->info) @@ -2405,13 +2115,10 @@ rib_delnode (struct route_node *rn, struct rib *rib) /* Just clean up if non main table */ if (IS_ZEBRA_DEBUG_RIB) { - char buf[INET6_ADDRSTRLEN]; - if (IS_ZEBRA_DEBUG_RIB) - { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Freeing route rn %p, rib %p (type %d)", - rib->vrf_id, buf, rn->p.prefixlen, rn, rib, rib->type); - } + char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); + zlog_debug ("%u:%s: Freeing route rn %p, rib %p (type %d)", + rib->vrf_id, buf, rn, rib, rib->type); } rib_unlink(rn, rib); @@ -2428,15 +2135,23 @@ rib_delnode (struct route_node *rn, struct rib *rib) */ void _rib_dump (const char * func, - union prefix46constptr pp, const struct rib * rib) + union prefix46constptr pp, + union prefix46constptr src_pp, + const struct rib * rib) { const struct prefix *p = pp.p; + const struct prefix *src_p = src_pp.p; + bool is_srcdst = src_p && src_p->prefixlen; char straddr[PREFIX_STRLEN]; + char srcaddr[PREFIX_STRLEN]; struct nexthop *nexthop, *tnexthop; int recursing; - zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (const void *)rib, - prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id); + zlog_debug ("%s: dumping RIB entry %p for %s%s%s vrf %u", func, (const void *)rib, + prefix2str(pp, straddr, sizeof(straddr)), + is_srcdst ? " from " : "", + is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr)) : "", + rib->vrf_id); zlog_debug ( "%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d", @@ -2527,7 +2242,7 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id) (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"), (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected") ); - rib_dump (p, rib); + rib_dump (p, NULL, rib); } } @@ -2574,7 +2289,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id) char buf[PREFIX_STRLEN]; zlog_debug ("%u:%s: freeing way for connected prefix", rib->vrf_id, prefix2str(&rn->p, buf, sizeof(buf))); - rib_dump (&rn->p, rib); + rib_dump (&rn->p, NULL, rib); } rib_uninstall (rn, rib); } @@ -2585,7 +2300,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id) int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, - struct rib *rib) + struct prefix_ipv6 *src_p, struct rib *rib) { struct route_table *table; struct route_node *rn; @@ -2602,6 +2317,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, else family = AFI_IP6; + assert(!src_p || family == AFI_IP6); + /* Lookup table. */ table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table); if (! table) @@ -2609,6 +2326,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, /* Make it sure prefixlen is applied to the prefix. */ apply_mask (p); + if (src_p) + apply_mask_ipv6 (src_p); /* Set default distance by route type. */ if (rib->distance == 0) @@ -2622,7 +2341,7 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, } /* Lookup route node.*/ - rn = route_node_get (table, p); + rn = srcdest_rnode_get (table, p, src_p); /* If same type of route are installed, treat it as a implicit withdraw. */ @@ -2645,18 +2364,11 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, /* Link new rib to node.*/ if (IS_ZEBRA_DEBUG_RIB) { - char buf[INET6_ADDRSTRLEN]; - if (IS_ZEBRA_DEBUG_RIB) - { - inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) " - "existing %p", - rib->vrf_id, buf, p->prefixlen, (void *)rn, - (void *)rib, rib->type, (void *)same); - } + rnode_debug(rn, rib->vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p", + (void *)rn, (void *)rib, rib->type, (void *)same); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - rib_dump ((struct prefix *)p, rib); + rib_dump (p, src_p, rib); } rib_addnode (rn, rib, 1); ret = 1; @@ -2672,10 +2384,10 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, return ret; } -int +void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, - int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex, - u_int32_t table_id) + int flags, struct prefix *p, struct prefix_ipv6 *src_p, + union g_addr *gate, ifindex_t ifindex, u_int32_t table_id) { struct route_table *table; struct route_node *rn; @@ -2684,25 +2396,38 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, struct rib *same = NULL; struct nexthop *nexthop, *tnexthop; int recursing; - char buf1[PREFIX_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + assert(!src_p || afi == AFI_IP6); + /* Lookup table. */ table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); if (! table) - return 0; + return; /* Apply mask. */ apply_mask (p); + if (src_p) + apply_mask_ipv6 (src_p); /* Lookup route node. */ - rn = route_node_lookup (table, p); + rn = srcdest_rnode_lookup (table, p, src_p); if (! rn) { + char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; + + prefix2str(p, dst_buf, sizeof(dst_buf)); + if (src_p && src_p->prefixlen) + prefix2str(src_p, src_buf, sizeof(src_buf)); + else + src_buf[0] = '\0'; + if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s: doesn't exist in rib", - vrf_id, prefix2str (p, buf1, sizeof(buf1))); - return ZEBRA_ERR_RTNOEXIST; + zlog_debug ("%u:%s%s%s doesn't exist in rib", + vrf_id, dst_buf, + (src_buf[0] != '\0') ? " from " : "", + src_buf); + return; } /* Lookup same type route. */ @@ -2728,7 +2453,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, rib->refcnt--; route_unlock_node (rn); route_unlock_node (rn); - return 0; + return; } same = rib; break; @@ -2761,10 +2486,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, { if (IS_ZEBRA_DEBUG_RIB) { - zlog_debug ("%u:%s: rn %p, rib %p (type %d) was deleted " - "from kernel, adding", - vrf_id, prefix2str(p, buf1, INET6_ADDRSTRLEN), - rn, fib, fib->type); + rnode_debug (rn, vrf_id, "rn %p, rib %p (type %d) was deleted from kernel, adding", + rn, fib, fib->type); } if (allow_delete) { @@ -2786,20 +2509,18 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, if (IS_ZEBRA_DEBUG_RIB) { if (gate) - zlog_debug ("%u:%s: via %s ifindex %d type %d " + rnode_debug(rn, vrf_id, "via %s ifindex %d type %d " "doesn't exist in rib", - vrf_id, prefix2str (p, buf1, sizeof(buf1)), - inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN), + inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN), /* FIXME */ ifindex, type); else - zlog_debug ("%u:%s: ifindex %d type %d doesn't exist in rib", - vrf_id, prefix2str (p, buf1, sizeof(buf1)), + rnode_debug (rn, vrf_id, "ifindex %d type %d doesn't exist in rib", ifindex, type); } route_unlock_node (rn); - return ZEBRA_ERR_RTNOEXIST; + return; } } @@ -2807,7 +2528,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, rib_delnode (rn, same); route_unlock_node (rn); - return 0; + return; } @@ -2815,7 +2536,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, - union g_addr *gate, union g_addr *src, ifindex_t ifindex, + struct prefix_ipv6 *src_p, union g_addr *gate, + union g_addr *src, ifindex_t ifindex, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, u_char distance) { @@ -2825,6 +2547,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, struct route_node *rn; struct nexthop *nexthop; + assert(!src_p || afi == AFI_IP6); + /* Lookup table. */ table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); if (! table) @@ -2832,6 +2556,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* Make sure mask is applied. */ apply_mask (p); + if (src_p) + apply_mask_ipv6 (src_p); /* Set default distance by route type. */ if (distance == 0) @@ -2847,7 +2573,7 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } /* Lookup route node.*/ - rn = route_node_get (table, p); + rn = srcdest_rnode_get (table, p, src_p); /* If same type of route are installed, treat it as a implicit withdraw. */ @@ -2919,18 +2645,11 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* Link new rib to node.*/ if (IS_ZEBRA_DEBUG_RIB) { - char buf[INET6_ADDRSTRLEN]; - if (IS_ZEBRA_DEBUG_RIB) - { - inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) " - "existing %p", - vrf_id, buf, p->prefixlen, (void *)rn, - (void *)rib, rib->type, (void *)same); - } + rnode_debug (rn, vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p", + (void *)rn, (void *)rib, rib->type, (void *)same); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - rib_dump (p, rib); + rib_dump (p, src_p, rib); } rib_addnode (rn, rib, 1); @@ -2952,7 +2671,7 @@ rib_update_table (struct route_table *table, rib_update_event_t event) /* Walk all routes and queue for processing, if appropriate for * the trigger event. */ - for (rn = route_top (table); rn; rn = route_next (rn)) + for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) { switch (event) { @@ -3028,7 +2747,7 @@ rib_weed_table (struct route_table *table) struct rib *next; if (table) - for (rn = route_top (table); rn; rn = route_next (rn)) + for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) RNODE_FOREACH_RIB_SAFE (rn, rib, next) { if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) @@ -3065,7 +2784,7 @@ rib_sweep_table (struct route_table *table) int ret = 0; if (table) - for (rn = route_top (table); rn; rn = route_next (rn)) + for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) RNODE_FOREACH_RIB_SAFE (rn, rib, next) { if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) @@ -3106,7 +2825,7 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table unsigned long n = 0; if (table) - for (rn = route_top (table); rn; rn = route_next (rn)) + for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) RNODE_FOREACH_RIB_SAFE (rn, rib, next) { if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) @@ -3117,7 +2836,6 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table n++; } } - return n; } @@ -3146,7 +2864,7 @@ rib_close_table (struct route_table *table) struct rib *rib; if (table) - for (rn = route_top (table); rn; rn = route_next (rn)) + for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) RNODE_FOREACH_RIB (rn, rib) { if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) |
