forked from Mirror/frr
staticd: fix NHT for dst-src routes
staticd's NHT code wasn't updating dst-src routes :( Fixes: FRRouting/frr#14247 Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
2af780650f
commit
2726a239d4
|
@ -49,8 +49,8 @@ static void static_nht_update_path(struct static_path *pn, struct prefix *nhp,
|
||||||
static_zebra_route_add(pn, true);
|
static_zebra_route_add(pn, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
|
static void static_nht_update_safi(const struct prefix *sp, const struct prefix *ssrc_p,
|
||||||
uint32_t nh_num, afi_t afi, safi_t safi,
|
struct prefix *nhp, uint32_t nh_num, afi_t afi, safi_t safi,
|
||||||
struct static_vrf *svrf, vrf_id_t nh_vrf_id)
|
struct static_vrf *svrf, vrf_id_t nh_vrf_id)
|
||||||
{
|
{
|
||||||
struct route_table *stable;
|
struct route_table *stable;
|
||||||
|
@ -63,7 +63,7 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sp) {
|
if (sp) {
|
||||||
rn = srcdest_rnode_lookup(stable, sp, NULL);
|
rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p);
|
||||||
if (rn && rn->info) {
|
if (rn && rn->info) {
|
||||||
si = static_route_info_from_rnode(rn);
|
si = static_route_info_from_rnode(rn);
|
||||||
frr_each(static_path_list, &si->path_list, pn) {
|
frr_each(static_path_list, &si->path_list, pn) {
|
||||||
|
@ -75,7 +75,7 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rn = route_top(stable); rn; rn = route_next(rn)) {
|
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
|
||||||
si = static_route_info_from_rnode(rn);
|
si = static_route_info_from_rnode(rn);
|
||||||
if (!si)
|
if (!si)
|
||||||
continue;
|
continue;
|
||||||
|
@ -85,14 +85,13 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void static_nht_update(struct prefix *sp, struct prefix *nhp, uint32_t nh_num,
|
void static_nht_update(const struct prefix *sp, const struct prefix *ssrc_p, struct prefix *nhp,
|
||||||
afi_t afi, safi_t safi, vrf_id_t nh_vrf_id)
|
uint32_t nh_num, afi_t afi, safi_t safi, vrf_id_t nh_vrf_id)
|
||||||
{
|
{
|
||||||
struct static_vrf *svrf;
|
struct static_vrf *svrf;
|
||||||
|
|
||||||
RB_FOREACH (svrf, svrf_name_head, &svrfs)
|
RB_FOREACH (svrf, svrf_name_head, &svrfs)
|
||||||
static_nht_update_safi(sp, nhp, nh_num, afi, safi, svrf,
|
static_nht_update_safi(sp, ssrc_p, nhp, nh_num, afi, safi, svrf, nh_vrf_id);
|
||||||
nh_vrf_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
|
static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
|
||||||
|
@ -109,7 +108,7 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
|
||||||
if (!stable)
|
if (!stable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (rn = route_top(stable); rn; rn = route_next(rn)) {
|
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
|
||||||
si = static_route_info_from_rnode(rn);
|
si = static_route_info_from_rnode(rn);
|
||||||
if (!si)
|
if (!si)
|
||||||
continue;
|
continue;
|
||||||
|
@ -150,8 +149,8 @@ void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi,
|
||||||
static_nht_reset_start_safi(nhp, afi, safi, svrf, nh_vrf_id);
|
static_nht_reset_start_safi(nhp, afi, safi, svrf, nh_vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
|
static void static_nht_mark_state_safi(const struct prefix *sp, const struct prefix *ssrc_p,
|
||||||
safi_t safi, struct vrf *vrf,
|
afi_t afi, safi_t safi, struct vrf *vrf,
|
||||||
enum static_install_states state)
|
enum static_install_states state)
|
||||||
{
|
{
|
||||||
struct static_vrf *svrf;
|
struct static_vrf *svrf;
|
||||||
|
@ -169,7 +168,7 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
|
||||||
if (!stable)
|
if (!stable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rn = srcdest_rnode_lookup(stable, sp, NULL);
|
rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p);
|
||||||
if (!rn)
|
if (!rn)
|
||||||
return;
|
return;
|
||||||
si = rn->info;
|
si = rn->info;
|
||||||
|
@ -184,8 +183,8 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static_nht_mark_state(struct prefix *sp, safi_t safi, vrf_id_t vrf_id,
|
void static_nht_mark_state(const struct prefix *sp, const struct prefix *ssrc_p, safi_t safi,
|
||||||
enum static_install_states state)
|
vrf_id_t vrf_id, enum static_install_states state)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
@ -198,5 +197,5 @@ void static_nht_mark_state(struct prefix *sp, safi_t safi, vrf_id_t vrf_id,
|
||||||
if (!vrf || !vrf->info)
|
if (!vrf || !vrf->info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static_nht_mark_state_safi(sp, afi, safi, vrf, state);
|
static_nht_mark_state_safi(sp, ssrc_p, afi, safi, vrf, state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,14 @@ extern "C" {
|
||||||
* us call this function to find the nexthop we are tracking so it
|
* us call this function to find the nexthop we are tracking so it
|
||||||
* can be installed or removed.
|
* can be installed or removed.
|
||||||
*
|
*
|
||||||
* sp -> The route we are looking at. If NULL then look at all
|
* sp + ssrc_p -> The route we are looking at. If NULL then look at all routes.
|
||||||
* routes.
|
|
||||||
* nhp -> The nexthop that is being tracked.
|
* nhp -> The nexthop that is being tracked.
|
||||||
* nh_num -> number of valid nexthops.
|
* nh_num -> number of valid nexthops.
|
||||||
* afi -> The afi we are working in.
|
* afi -> The afi we are working in.
|
||||||
* vrf_id -> The vrf the nexthop is in.
|
* vrf_id -> The vrf the nexthop is in.
|
||||||
*/
|
*/
|
||||||
extern void static_nht_update(struct prefix *sp, struct prefix *nhp,
|
extern void static_nht_update(const struct prefix *sp, const struct prefix *ssrc_p,
|
||||||
uint32_t nh_num, afi_t afi, safi_t safi,
|
struct prefix *nhp, uint32_t nh_num, afi_t afi, safi_t safi,
|
||||||
vrf_id_t vrf_id);
|
vrf_id_t vrf_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,11 +34,10 @@ extern void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi,
|
||||||
vrf_id_t nh_vrf_id);
|
vrf_id_t nh_vrf_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the given prefix, sp, mark it as in a particular state
|
* For the given prefix, sp + ssrc_p, mark it as in a particular state
|
||||||
*/
|
*/
|
||||||
extern void static_nht_mark_state(struct prefix *sp, safi_t safi,
|
extern void static_nht_mark_state(const struct prefix *sp, const struct prefix *ssrc_p, safi_t safi,
|
||||||
vrf_id_t vrf_id,
|
vrf_id_t vrf_id, enum static_install_states state);
|
||||||
enum static_install_states state);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the given nexthop, returns the string
|
* For the given nexthop, returns the string
|
||||||
|
|
|
@ -132,35 +132,37 @@ static int static_ifp_down(struct interface *ifp)
|
||||||
|
|
||||||
static int route_notify_owner(ZAPI_CALLBACK_ARGS)
|
static int route_notify_owner(ZAPI_CALLBACK_ARGS)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p, src_p, *src_pp;
|
||||||
enum zapi_route_notify_owner note;
|
enum zapi_route_notify_owner note;
|
||||||
uint32_t table_id;
|
uint32_t table_id;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e, NULL,
|
if (!zapi_route_notify_decode_srcdest(zclient->ibuf, &p, &src_p, &table_id, ¬e, NULL,
|
||||||
&safi))
|
&safi))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
src_pp = src_p.prefixlen ? &src_p : NULL;
|
||||||
|
|
||||||
switch (note) {
|
switch (note) {
|
||||||
case ZAPI_ROUTE_FAIL_INSTALL:
|
case ZAPI_ROUTE_FAIL_INSTALL:
|
||||||
static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
|
static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED);
|
||||||
zlog_warn("%s: Route %pFX failed to install for table: %u",
|
zlog_warn("%s: Route %pFX failed to install for table: %u",
|
||||||
__func__, &p, table_id);
|
__func__, &p, table_id);
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_BETTER_ADMIN_WON:
|
case ZAPI_ROUTE_BETTER_ADMIN_WON:
|
||||||
static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
|
static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED);
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: Route %pFX over-ridden by better route for table: %u",
|
"%s: Route %pFX over-ridden by better route for table: %u",
|
||||||
__func__, &p, table_id);
|
__func__, &p, table_id);
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_INSTALLED:
|
case ZAPI_ROUTE_INSTALLED:
|
||||||
static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED);
|
static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_INSTALLED);
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_REMOVED:
|
case ZAPI_ROUTE_REMOVED:
|
||||||
static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
|
static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED);
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_REMOVE_FAIL:
|
case ZAPI_ROUTE_REMOVE_FAIL:
|
||||||
static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED);
|
static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_INSTALLED);
|
||||||
zlog_warn("%s: Route %pFX failure to remove for table: %u",
|
zlog_warn("%s: Route %pFX failure to remove for table: %u",
|
||||||
__func__, &p, table_id);
|
__func__, &p, table_id);
|
||||||
break;
|
break;
|
||||||
|
@ -226,8 +228,8 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
|
||||||
nhtd->nh_num = nhr->nexthop_num;
|
nhtd->nh_num = nhr->nexthop_num;
|
||||||
|
|
||||||
static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
|
static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
|
||||||
static_nht_update(NULL, matched, nhr->nexthop_num, afi,
|
static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi,
|
||||||
nhr->safi, nhtd->nh_vrf_id);
|
nhtd->nh_vrf_id);
|
||||||
} else
|
} else
|
||||||
zlog_err("No nhtd?");
|
zlog_err("No nhtd?");
|
||||||
}
|
}
|
||||||
|
@ -312,10 +314,13 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
|
||||||
{
|
{
|
||||||
struct static_path *pn = nh->pn;
|
struct static_path *pn = nh->pn;
|
||||||
struct route_node *rn = pn->rn;
|
struct route_node *rn = pn->rn;
|
||||||
|
const struct prefix *p, *src_p;
|
||||||
struct static_route_info *si = static_route_info_from_rnode(rn);
|
struct static_route_info *si = static_route_info_from_rnode(rn);
|
||||||
struct static_nht_data *nhtd, lookup = {};
|
struct static_nht_data *nhtd, lookup = {};
|
||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
|
|
||||||
|
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||||
|
|
||||||
if (!static_zebra_nht_get_prefix(nh, &lookup.nh))
|
if (!static_zebra_nht_get_prefix(nh, &lookup.nh))
|
||||||
return;
|
return;
|
||||||
lookup.nh_vrf_id = nh->nh_vrf_id;
|
lookup.nh_vrf_id = nh->nh_vrf_id;
|
||||||
|
@ -351,8 +356,8 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
|
||||||
if (nh->state == STATIC_NOT_INSTALLED ||
|
if (nh->state == STATIC_NOT_INSTALLED ||
|
||||||
nh->state == STATIC_SENT_TO_ZEBRA)
|
nh->state == STATIC_SENT_TO_ZEBRA)
|
||||||
nh->state = STATIC_START;
|
nh->state = STATIC_START;
|
||||||
static_nht_update(&rn->p, &nhtd->nh, nhtd->nh_num, afi,
|
static_nht_update(p, src_p, &nhtd->nh, nhtd->nh_num, afi, si->safi,
|
||||||
si->safi, nh->nh_vrf_id);
|
nh->nh_vrf_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue