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.c726
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))