zebra: add rib_match_ipv4_safi()
This is the same as rib_lookup_ipv4(), without the SAFI hardcoded.
Cc: Balaji G <balajig81@gmail.com>
Cc: Everton Marques <everton.marques@gmail.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/zebra/rib.h b/zebra/rib.h
index d3a83c6..13011e2 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -419,6 +419,7 @@
u_int32_t, safi_t safi);
extern struct rib *rib_match_ipv4 (struct in_addr);
+extern struct rib *rib_match_ipv4_safi (struct in_addr addr, safi_t safi);
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 8354513..5b9b00e 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -782,6 +782,63 @@
}
struct rib *
+rib_match_ipv4_safi (struct in_addr addr, safi_t safi)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct rib *match;
+ struct nexthop *newhop, *tnewhop;
+ int recursing;
+
+ /* Lookup table. */
+ table = vrf_table (AFI_IP, safi, 0);
+ if (! table)
+ return 0;
+
+ rn = route_node_match_ipv4 (table, &addr);
+
+ while (rn)
+ {
+ route_unlock_node (rn);
+
+ /* Pick up selected route. */
+ RNODE_FOREACH_RIB (rn, match)
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
+
+ /* If there is no selected route or matched route is EGP, go up
+ tree. */
+ if (! match
+ || match->type == ZEBRA_ROUTE_BGP)
+ {
+ do {
+ rn = rn->parent;
+ } while (rn && rn->info == NULL);
+ if (rn)
+ route_lock_node (rn);
+ }
+ else
+ {
+ if (match->type == ZEBRA_ROUTE_CONNECT)
+ /* Directly point connected route. */
+ return match;
+ else
+ {
+ for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
+ if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
+ return match;
+ return NULL;
+ }
+ }
+ }
+ return NULL;
+}
+
+struct rib *
rib_lookup_ipv4 (struct prefix_ipv4 *p)
{
struct route_table *table;