zebra,pimd,lib: Modify ZEBRA_NEXTHOP_LOOKUP_MRIB

Modified ZEBRA_NEXTHOP_LOOKUP_MRIB to include the SAFI from which to do the lookup.
This generalizes the API away from MRIB specifically and allows the user to decide how it should do lookups.
Rename ZEBRA_NEXTHOP_LOOKUP_MRIB to ZEBRA_NEXTHOP_LOOKUP now that it is more generalized.
This change is in preperation to remove multicast lookup mode completely from zebra.

Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
This commit is contained in:
Nathan Bahr 2024-09-24 19:57:46 +00:00
parent f170e9bba9
commit 4250eae00d
6 changed files with 31 additions and 81 deletions

View file

@ -358,7 +358,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_BFD_CLIENT_DEREGISTER), DESC_ENTRY(ZEBRA_BFD_CLIENT_DEREGISTER),
DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV),
DESC_ENTRY(ZEBRA_INTERFACE_DISABLE_RADV), DESC_ENTRY(ZEBRA_INTERFACE_DISABLE_RADV),
DESC_ENTRY(ZEBRA_NEXTHOP_LOOKUP_MRIB), DESC_ENTRY(ZEBRA_NEXTHOP_LOOKUP),
DESC_ENTRY(ZEBRA_INTERFACE_LINK_PARAMS), DESC_ENTRY(ZEBRA_INTERFACE_LINK_PARAMS),
DESC_ENTRY(ZEBRA_MPLS_LABELS_ADD), DESC_ENTRY(ZEBRA_MPLS_LABELS_ADD),
DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE), DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE),

View file

@ -131,7 +131,7 @@ typedef enum {
ZEBRA_BFD_CLIENT_DEREGISTER, ZEBRA_BFD_CLIENT_DEREGISTER,
ZEBRA_INTERFACE_ENABLE_RADV, ZEBRA_INTERFACE_ENABLE_RADV,
ZEBRA_INTERFACE_DISABLE_RADV, ZEBRA_INTERFACE_DISABLE_RADV,
ZEBRA_NEXTHOP_LOOKUP_MRIB, ZEBRA_NEXTHOP_LOOKUP,
ZEBRA_INTERFACE_LINK_PARAMS, ZEBRA_INTERFACE_LINK_PARAMS,
ZEBRA_MPLS_LABELS_ADD, ZEBRA_MPLS_LABELS_ADD,
ZEBRA_MPLS_LABELS_DELETE, ZEBRA_MPLS_LABELS_DELETE,

View file

@ -162,7 +162,7 @@ static int zclient_read_nexthop(struct pim_instance *pim,
s = zlookup->ibuf; s = zlookup->ibuf;
while (command != ZEBRA_NEXTHOP_LOOKUP_MRIB) { while (command != ZEBRA_NEXTHOP_LOOKUP) {
stream_reset(s); stream_reset(s);
err = zclient_read_header(s, zlookup->sock, &length, &marker, err = zclient_read_header(s, zlookup->sock, &length, &marker,
&version, &vrf_id, &command); &version, &vrf_id, &command);
@ -337,8 +337,9 @@ static int zclient_lookup_nexthop_once(struct pim_instance *pim,
s = zlookup->obuf; s = zlookup->obuf;
stream_reset(s); stream_reset(s);
zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP_MRIB, pim->vrf->vrf_id); zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP, pim->vrf->vrf_id);
stream_put_ipaddr(s, &ipaddr); stream_put_ipaddr(s, &ipaddr);
stream_putc(s, SAFI_MULTICAST); // TODO NEB Set the real safi
stream_putw_at(s, 0, stream_get_endp(s)); stream_putw_at(s, 0, stream_get_endp(s));
ret = writen(zlookup->sock, s->data, stream_get_endp(s)); ret = writen(zlookup->sock, s->data, stream_get_endp(s));

View file

@ -402,11 +402,7 @@ extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
bool fromkernel); bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id, extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
const union g_addr *addr, const union g_addr *addr, struct route_node **rn_out);
struct route_node **rn_out);
extern struct route_entry *rib_match_multicast(afi_t afi, vrf_id_t vrf_id,
union g_addr *gaddr,
struct route_node **rn_out);
extern void rib_update(enum rib_update_event event); extern void rib_update(enum rib_update_event event);
extern void rib_update_table(struct route_table *table, extern void rib_update_table(struct route_table *table,

View file

@ -640,10 +640,15 @@ int zsend_redistribute_route(int cmd, struct zserv *client,
* (Otherwise we would need to implement sending NHT updates for the result of * (Otherwise we would need to implement sending NHT updates for the result of
* this "URIB-MRIB-combined" table, but we only decide that here on the fly, * this "URIB-MRIB-combined" table, but we only decide that here on the fly,
* so it'd be rather complex to do NHT for.) * so it'd be rather complex to do NHT for.)
*
* 9/19/24 NEB I've updated this API to include the SAFI in the lookup
* request and response. This allows PIM to do a syncronous lookup for the
* correct table along side NHT.
* This also makes this a more generic synchronous lookup not specifically
* tied to the mrib.
*/ */
static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr, static int zsend_nexthop_lookup(struct zserv *client, struct ipaddr *addr, struct route_entry *re,
struct route_entry *re, struct route_node *rn, struct zebra_vrf *zvrf, safi_t safi)
struct zebra_vrf *zvrf)
{ {
struct stream *s; struct stream *s;
unsigned long nump; unsigned long nump;
@ -655,14 +660,16 @@ static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr,
stream_reset(s); stream_reset(s);
/* Fill in result. */ /* Fill in result. */
zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf)); zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP, zvrf_id(zvrf));
stream_put_ipaddr(s, addr); stream_put_ipaddr(s, addr);
if (re) { if (re && rn) {
struct nexthop_group *nhg; struct nexthop_group *nhg;
stream_putc(s, re->distance); stream_putc(s, re->distance);
stream_putl(s, re->metric); stream_putl(s, re->metric);
stream_putw(s, rn->p.prefixlen);
num = 0; num = 0;
/* remember position for nexthop_num */ /* remember position for nexthop_num */
nump = stream_get_endp(s); nump = stream_get_endp(s);
@ -679,6 +686,7 @@ static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr,
} else { } else {
stream_putc(s, 0); /* distance */ stream_putc(s, 0); /* distance */
stream_putl(s, 0); /* metric */ stream_putl(s, 0); /* metric */
stream_putw(s, 0); /* prefix len */
stream_putw(s, 0); /* nexthop_num */ stream_putw(s, 0); /* nexthop_num */
} }
@ -2315,33 +2323,37 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
} }
} }
/* MRIB Nexthop lookup for IPv4. */ /* Syncronous Nexthop lookup. */
static void zread_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS) static void zread_nexthop_lookup(ZAPI_HANDLER_ARGS)
{ {
struct ipaddr addr; struct ipaddr addr;
struct route_entry *re = NULL; struct route_entry *re = NULL;
struct route_node *rn = NULL;
union g_addr gaddr; union g_addr gaddr;
afi_t afi = AFI_IP;
safi_t safi = SAFI_UNICAST;
STREAM_GET_IPADDR(msg, &addr); STREAM_GET_IPADDR(msg, &addr);
STREAM_GETC(msg, safi);
switch (addr.ipa_type) { switch (addr.ipa_type) {
case IPADDR_V4: case IPADDR_V4:
gaddr.ipv4 = addr.ipaddr_v4; gaddr.ipv4 = addr.ipaddr_v4;
re = rib_match_multicast(AFI_IP, zvrf_id(zvrf), &gaddr, NULL); afi = AFI_IP;
break; break;
case IPADDR_V6: case IPADDR_V6:
gaddr.ipv6 = addr.ipaddr_v6; gaddr.ipv6 = addr.ipaddr_v6;
re = rib_match_multicast(AFI_IP6, zvrf_id(zvrf), &gaddr, NULL); afi = AFI_IP6;
break; break;
case IPADDR_NONE: case IPADDR_NONE:
/* ??? */ /* ??? */
goto stream_failure; goto stream_failure;
} }
zsend_nexthop_lookup_mrib(client, &addr, re, zvrf); re = rib_match(afi, safi, zvrf_id(zvrf), &gaddr, &rn);
stream_failure: stream_failure:
return; zsend_nexthop_lookup(client, &addr, re, rn, zvrf, safi);
} }
/* Register zebra server router-id information. Send current router-id */ /* Register zebra server router-id information. Send current router-id */
@ -4027,7 +4039,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete, [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
[ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add, [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
[ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete, [ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete,
[ZEBRA_NEXTHOP_LOOKUP_MRIB] = zread_nexthop_lookup_mrib, [ZEBRA_NEXTHOP_LOOKUP] = zread_nexthop_lookup,
[ZEBRA_HELLO] = zread_hello, [ZEBRA_HELLO] = zread_hello,
[ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register, [ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
[ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister, [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,

View file

@ -503,7 +503,7 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
/* Lookup table. */ /* Lookup table. */
table = zebra_vrf_table(afi, safi, vrf_id); table = zebra_vrf_table(afi, safi, vrf_id);
if (!table) if (!table)
return 0; return NULL;
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
p.family = afi; p.family = afi;
@ -552,65 +552,6 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
return NULL; return NULL;
} }
struct route_entry *rib_match_multicast(afi_t afi, vrf_id_t vrf_id,
union g_addr *gaddr,
struct route_node **rn_out)
{
struct route_entry *re = NULL, *mre = NULL, *ure = NULL;
struct route_node *m_rn = NULL, *u_rn = NULL;
switch (zrouter.ipv4_multicast_mode) {
case MCAST_MRIB_ONLY:
return rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, rn_out);
case MCAST_URIB_ONLY:
return rib_match(afi, SAFI_UNICAST, vrf_id, gaddr, rn_out);
case MCAST_NO_CONFIG:
case MCAST_MIX_MRIB_FIRST:
re = mre = rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
if (!mre)
re = ure = rib_match(afi, SAFI_UNICAST, vrf_id, gaddr,
&u_rn);
break;
case MCAST_MIX_DISTANCE:
mre = rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
ure = rib_match(afi, 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, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
ure = rib_match(afi, 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) {
char buf[BUFSIZ];
inet_ntop(afi == AFI_IP ? AF_INET : AF_INET6, gaddr, buf,
BUFSIZ);
zlog_debug("%s: %s: %pRN vrf: %s(%u) found %s, using %s",
__func__, buf, (re == mre) ? m_rn : u_rn,
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;
}
/* /*
* Is this RIB labeled-unicast? It must be of type BGP and all paths * Is this RIB labeled-unicast? It must be of type BGP and all paths
* (nexthops) must have a label. * (nexthops) must have a label.