summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2022-04-26 14:29:38 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2022-04-26 16:15:00 +0200
commit425fd200c92392c4614b07c5ea416fddb495f792 (patch)
tree19f4a074667366f539cd7e93edbf3022a96423b5
parentd1b7dfbe0841bbfb94a72fe6ea46ae9d059b5230 (diff)
zebra: add rib_match_ipv6_multicast variant
... for IPv6, analogous to v4. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--zebra/rib.h3
-rw-r--r--zebra/zebra_rib.c56
2 files changed, 59 insertions, 0 deletions
diff --git a/zebra/rib.h b/zebra/rib.h
index c8abfaf023..281791d1f8 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -424,6 +424,9 @@ extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
extern struct route_entry *rib_match_ipv4_multicast(vrf_id_t vrf_id,
struct in_addr addr,
struct route_node **rn_out);
+extern struct route_entry *rib_match_ipv6_multicast(vrf_id_t vrf_id,
+ struct in6_addr addr,
+ struct route_node **rn_out);
extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
vrf_id_t vrf_id);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index c6840a503c..2732967ee6 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -487,6 +487,62 @@ struct route_entry *rib_match_ipv4_multicast(vrf_id_t vrf_id,
return re;
}
+struct route_entry *rib_match_ipv6_multicast(vrf_id_t vrf_id,
+ struct in6_addr addr,
+ struct route_node **rn_out)
+{
+ struct route_entry *re = NULL, *mre = NULL, *ure = NULL;
+ struct route_node *m_rn = NULL, *u_rn = NULL;
+ union g_addr gaddr = {.ipv6 = addr};
+
+ switch (zrouter.ipv4_multicast_mode) {
+ case MCAST_MRIB_ONLY:
+ return rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr,
+ rn_out);
+ case MCAST_URIB_ONLY:
+ return rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, rn_out);
+ case MCAST_NO_CONFIG:
+ case MCAST_MIX_MRIB_FIRST:
+ re = mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr,
+ &m_rn);
+ if (!mre)
+ re = ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id,
+ &gaddr, &u_rn);
+ break;
+ case MCAST_MIX_DISTANCE:
+ mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
+ ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
+ if (mre && ure)
+ re = ure->distance < mre->distance ? ure : mre;
+ else if (mre)
+ re = mre;
+ else if (ure)
+ re = ure;
+ break;
+ case MCAST_MIX_PFXLEN:
+ mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
+ ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
+ if (mre && ure)
+ re = u_rn->p.prefixlen > m_rn->p.prefixlen ? ure : mre;
+ else if (mre)
+ re = mre;
+ else if (ure)
+ re = ure;
+ break;
+ }
+
+ if (rn_out)
+ *rn_out = (re == mre) ? m_rn : u_rn;
+
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug("%s: %pI6: vrf: %s(%u) found %s, using %s", __func__,
+ &addr, vrf_id_to_name(vrf_id), vrf_id,
+ mre ? (ure ? "MRIB+URIB" : "MRIB")
+ : ure ? "URIB" : "nothing",
+ re == ure ? "URIB" : re == mre ? "MRIB" : "none");
+ return re;
+}
+
struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
{
struct route_table *table;