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;