summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c96
1 files changed, 82 insertions, 14 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index ab07549ec2..2c8fa77c32 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -266,7 +266,8 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
There was a crash because ifp here was coming to be NULL */
if (ifp)
if (connected_is_unnumbered(ifp)
- || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
}
@@ -303,8 +304,10 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6;
nexthop->ifindex = ifindex;
- if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
+ }
route_entry_nexthop_add(re, nexthop);
@@ -428,8 +431,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
/* 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))
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Nexthop Filtered",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/*
* Check to see if we should trust the passed in information
@@ -438,13 +445,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
*/
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) {
ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
- if (ifp && connected_is_unnumbered(ifp)) {
+ if ((ifp && connected_is_unnumbered(ifp))
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
if (if_is_operative(ifp))
return 1;
- else
+ else {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Onlink and interface %s is not operative",
+ __PRETTY_FUNCTION__, ifp->name);
return 0;
- } else
+ }
+ } else {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Interface %s is not unnumbered",
+ __PRETTY_FUNCTION__,
+ ifp ? ifp->name : "Unknown");
return 0;
+ }
}
/* Make lookup prefix. */
@@ -466,8 +485,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
/* Lookup table. */
table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id);
- if (!table)
+ if (!table) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Table not found",
+ __PRETTY_FUNCTION__);
return 0;
+ }
rn = route_node_match(table, (struct prefix *)&p);
while (rn) {
@@ -480,15 +503,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
*/
if (top && rn == top)
if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
- || ((afi == AFI_IP6) && (rn->p.prefixlen != 128)))
+ || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Matched against ourself and prefix length is not max bit length",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/* Pick up selected route. */
/* However, do not resolve over default route unless explicitly
* allowed. */
if (is_default_prefix(&rn->p)
- && !rnh_resolve_via_default(p.family))
+ && !rnh_resolve_via_default(p.family)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t:%s: Resolved against default route",
+ __PRETTY_FUNCTION__);
return 0;
+ }
dest = rib_dest_from_rnode(rn);
if (dest && dest->selected_fib
@@ -540,6 +573,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
+ if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Recursion failed to find",
+ __PRETTY_FUNCTION__);
return resolved;
} else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0;
@@ -558,6 +594,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
+
+ if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Static route unable to resolve",
+ __PRETTY_FUNCTION__);
return resolved;
} else {
return 0;
@@ -900,8 +941,12 @@ static unsigned nexthop_active_check(struct route_node *rn,
default:
break;
}
- if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Unable to find a active nexthop",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/* XXX: What exactly do those checks do? Do we support
* e.g. IPv4 routes with IPv6 nexthops or vice versa? */
@@ -2209,7 +2254,6 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
union prefixconstptr src_pp,
const struct route_entry *re)
{
- 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];
@@ -2232,10 +2276,34 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
re->nexthop_num, re->nexthop_active_num);
for (ALL_NEXTHOPS(re->ng, nexthop)) {
- inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
- zlog_debug("%s: %s %s[%u] vrf %u with flags %s%s%s", func,
+ struct interface *ifp;
+ struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
+
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_BLACKHOLE:
+ sprintf(straddr, "Blackhole");
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ ifp = if_lookup_by_index(nexthop->ifindex,
+ nexthop->vrf_id);
+ sprintf(straddr, "%s", ifp ? ifp->name : "Unknown");
+ break;
+ case NEXTHOP_TYPE_IPV4:
+ /* fallthrough */
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ inet_ntop(AF_INET, &nexthop->gate, straddr,
+ INET6_ADDRSTRLEN);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ inet_ntop(AF_INET6, &nexthop->gate, straddr,
+ INET6_ADDRSTRLEN);
+ break;
+ }
+ zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s", func,
(nexthop->rparent ? " NH" : "NH"), straddr,
- nexthop->ifindex, nexthop->vrf_id,
+ nexthop->ifindex, vrf ? vrf->name : "Unknown",
+ nexthop->vrf_id,
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
? "ACTIVE "
: ""),