2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2018-05-08 13:58:32 +02:00
|
|
|
/*
|
|
|
|
* Static NHT code.
|
|
|
|
* Copyright (C) 2018 Cumulus Networks, Inc.
|
|
|
|
* Donald Sharp
|
|
|
|
*/
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "vrf.h"
|
|
|
|
#include "nexthop.h"
|
2019-07-15 22:26:17 +02:00
|
|
|
#include "srcdest_table.h"
|
2018-05-08 13:58:32 +02:00
|
|
|
|
|
|
|
#include "static_vrf.h"
|
|
|
|
#include "static_routes.h"
|
|
|
|
#include "static_zebra.h"
|
|
|
|
#include "static_nht.h"
|
|
|
|
|
2021-07-09 21:55:29 +02:00
|
|
|
static void static_nht_update_path(struct static_path *pn, struct prefix *nhp,
|
2024-02-03 20:34:18 +01:00
|
|
|
uint32_t nh_num, vrf_id_t nh_vrf_id)
|
2018-05-08 13:58:32 +02:00
|
|
|
{
|
2020-04-24 14:38:43 +02:00
|
|
|
struct static_nexthop *nh;
|
2024-12-27 05:16:17 +01:00
|
|
|
bool route_changed = false;
|
2019-07-15 22:26:17 +02:00
|
|
|
|
2020-04-24 14:38:43 +02:00
|
|
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
|
|
|
if (nh->nh_vrf_id != nh_vrf_id)
|
2019-07-15 22:26:17 +02:00
|
|
|
continue;
|
|
|
|
|
2020-04-24 14:38:43 +02:00
|
|
|
if (nh->type != STATIC_IPV4_GATEWAY
|
|
|
|
&& nh->type != STATIC_IPV4_GATEWAY_IFNAME
|
|
|
|
&& nh->type != STATIC_IPV6_GATEWAY
|
|
|
|
&& nh->type != STATIC_IPV6_GATEWAY_IFNAME)
|
2019-07-15 22:26:17 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (nhp->family == AF_INET
|
2020-04-24 14:38:43 +02:00
|
|
|
&& nhp->u.prefix4.s_addr == nh->addr.ipv4.s_addr)
|
|
|
|
nh->nh_valid = !!nh_num;
|
2019-07-15 22:26:17 +02:00
|
|
|
|
|
|
|
if (nhp->family == AF_INET6
|
2021-07-01 22:29:26 +02:00
|
|
|
&& memcmp(&nhp->u.prefix6, &nh->addr.ipv6, IPV6_MAX_BYTELEN)
|
|
|
|
== 0)
|
2020-04-24 14:38:43 +02:00
|
|
|
nh->nh_valid = !!nh_num;
|
2019-07-15 22:26:17 +02:00
|
|
|
|
2020-04-24 14:38:43 +02:00
|
|
|
if (nh->state == STATIC_START)
|
2024-12-27 05:16:17 +01:00
|
|
|
route_changed = true;
|
2019-07-15 22:26:17 +02:00
|
|
|
}
|
2024-12-27 05:16:17 +01:00
|
|
|
if (route_changed)
|
|
|
|
static_zebra_route_add(pn, true);
|
2019-07-15 22:26:17 +02:00
|
|
|
}
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
static void static_nht_update_safi(const struct prefix *sp, const struct prefix *ssrc_p,
|
|
|
|
struct prefix *nhp, uint32_t nh_num, afi_t afi, safi_t safi,
|
2024-02-03 20:34:18 +01:00
|
|
|
struct static_vrf *svrf, vrf_id_t nh_vrf_id)
|
2019-07-15 22:26:17 +02:00
|
|
|
{
|
|
|
|
struct route_table *stable;
|
2018-05-08 13:58:32 +02:00
|
|
|
struct route_node *rn;
|
2020-04-24 14:38:43 +02:00
|
|
|
struct static_path *pn;
|
|
|
|
struct static_route_info *si;
|
2018-05-08 13:58:32 +02:00
|
|
|
|
staticd: Fix nht to include SAFI_MULTICAST
The nexthop tracking was correctly registering the nexthops in
the SAFI_UNICAST table, but we need to apply them to the
SAFI_MULTICAST mroute information( if any ) as well.
donna.cumulusnetworks.com# conf t
donna.cumulusnetworks.com(config)# ip mroute 230.0.4.0/24 192.168.210.50
donna.cumulusnetworks.com(config)# end
donna.cumulusnetworks.com# show ip rpf
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:08:28
C>* 192.168.209.0/24 is directly connected, enp0s8, 00:08:28
C>* 192.168.210.0/24 is directly connected, enp0s9, 00:08:28
S>* 230.0.4.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:56
S>* 230.0.5.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:17
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 15:42:11 +01:00
|
|
|
stable = static_vrf_static_table(afi, safi, svrf);
|
|
|
|
if (!stable)
|
|
|
|
return;
|
2018-05-08 13:58:32 +02:00
|
|
|
|
2019-07-15 22:26:17 +02:00
|
|
|
if (sp) {
|
2025-01-27 17:57:54 +01:00
|
|
|
rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p);
|
2020-04-24 14:38:43 +02:00
|
|
|
if (rn && rn->info) {
|
|
|
|
si = static_route_info_from_rnode(rn);
|
|
|
|
frr_each(static_path_list, &si->path_list, pn) {
|
2021-07-09 21:55:29 +02:00
|
|
|
static_nht_update_path(pn, nhp, nh_num,
|
2024-02-03 20:34:18 +01:00
|
|
|
nh_vrf_id);
|
2020-04-24 14:38:43 +02:00
|
|
|
}
|
2019-07-15 22:26:17 +02:00
|
|
|
route_unlock_node(rn);
|
2018-05-08 13:58:32 +02:00
|
|
|
}
|
2019-07-15 22:26:17 +02:00
|
|
|
return;
|
2018-05-08 13:58:32 +02:00
|
|
|
}
|
2019-07-15 22:26:17 +02:00
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
|
2020-04-24 14:38:43 +02:00
|
|
|
si = static_route_info_from_rnode(rn);
|
|
|
|
if (!si)
|
|
|
|
continue;
|
|
|
|
frr_each(static_path_list, &si->path_list, pn) {
|
2024-02-03 20:34:18 +01:00
|
|
|
static_nht_update_path(pn, nhp, nh_num, nh_vrf_id);
|
2020-04-24 14:38:43 +02:00
|
|
|
}
|
|
|
|
}
|
2018-05-08 13:58:32 +02:00
|
|
|
}
|
staticd: Fix nht to include SAFI_MULTICAST
The nexthop tracking was correctly registering the nexthops in
the SAFI_UNICAST table, but we need to apply them to the
SAFI_MULTICAST mroute information( if any ) as well.
donna.cumulusnetworks.com# conf t
donna.cumulusnetworks.com(config)# ip mroute 230.0.4.0/24 192.168.210.50
donna.cumulusnetworks.com(config)# end
donna.cumulusnetworks.com# show ip rpf
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:08:28
C>* 192.168.209.0/24 is directly connected, enp0s8, 00:08:28
C>* 192.168.210.0/24 is directly connected, enp0s9, 00:08:28
S>* 230.0.4.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:56
S>* 230.0.5.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:17
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 15:42:11 +01:00
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
void static_nht_update(const struct prefix *sp, const struct prefix *ssrc_p, struct prefix *nhp,
|
|
|
|
uint32_t nh_num, afi_t afi, safi_t safi, vrf_id_t nh_vrf_id)
|
staticd: Fix nht to include SAFI_MULTICAST
The nexthop tracking was correctly registering the nexthops in
the SAFI_UNICAST table, but we need to apply them to the
SAFI_MULTICAST mroute information( if any ) as well.
donna.cumulusnetworks.com# conf t
donna.cumulusnetworks.com(config)# ip mroute 230.0.4.0/24 192.168.210.50
donna.cumulusnetworks.com(config)# end
donna.cumulusnetworks.com# show ip rpf
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:08:28
C>* 192.168.209.0/24 is directly connected, enp0s8, 00:08:28
C>* 192.168.210.0/24 is directly connected, enp0s9, 00:08:28
S>* 230.0.4.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:56
S>* 230.0.5.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:17
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 15:42:11 +01:00
|
|
|
{
|
2024-02-03 20:34:18 +01:00
|
|
|
struct static_vrf *svrf;
|
staticd: Fix nht to include SAFI_MULTICAST
The nexthop tracking was correctly registering the nexthops in
the SAFI_UNICAST table, but we need to apply them to the
SAFI_MULTICAST mroute information( if any ) as well.
donna.cumulusnetworks.com# conf t
donna.cumulusnetworks.com(config)# ip mroute 230.0.4.0/24 192.168.210.50
donna.cumulusnetworks.com(config)# end
donna.cumulusnetworks.com# show ip rpf
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:08:28
C>* 192.168.209.0/24 is directly connected, enp0s8, 00:08:28
C>* 192.168.210.0/24 is directly connected, enp0s9, 00:08:28
S>* 230.0.4.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:56
S>* 230.0.5.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:17
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 15:42:11 +01:00
|
|
|
|
2024-02-03 20:34:18 +01:00
|
|
|
RB_FOREACH (svrf, svrf_name_head, &svrfs)
|
2025-01-27 17:57:54 +01:00
|
|
|
static_nht_update_safi(sp, ssrc_p, nhp, nh_num, afi, safi, svrf, nh_vrf_id);
|
staticd: Fix nht to include SAFI_MULTICAST
The nexthop tracking was correctly registering the nexthops in
the SAFI_UNICAST table, but we need to apply them to the
SAFI_MULTICAST mroute information( if any ) as well.
donna.cumulusnetworks.com# conf t
donna.cumulusnetworks.com(config)# ip mroute 230.0.4.0/24 192.168.210.50
donna.cumulusnetworks.com(config)# end
donna.cumulusnetworks.com# show ip rpf
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:08:28
C>* 192.168.209.0/24 is directly connected, enp0s8, 00:08:28
C>* 192.168.210.0/24 is directly connected, enp0s9, 00:08:28
S>* 230.0.4.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:56
S>* 230.0.5.0/24 [1/0] via 192.168.210.50, enp0s9, 00:07:17
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 15:42:11 +01:00
|
|
|
}
|
2019-07-16 14:27:31 +02:00
|
|
|
|
|
|
|
static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
|
2024-02-03 20:34:18 +01:00
|
|
|
safi_t safi, struct static_vrf *svrf,
|
2019-07-16 14:27:31 +02:00
|
|
|
vrf_id_t nh_vrf_id)
|
|
|
|
{
|
|
|
|
struct route_table *stable;
|
2020-04-24 14:38:43 +02:00
|
|
|
struct static_nexthop *nh;
|
|
|
|
struct static_path *pn;
|
2019-07-16 14:27:31 +02:00
|
|
|
struct route_node *rn;
|
2020-04-24 14:38:43 +02:00
|
|
|
struct static_route_info *si;
|
2019-07-16 14:27:31 +02:00
|
|
|
|
|
|
|
stable = static_vrf_static_table(afi, safi, svrf);
|
|
|
|
if (!stable)
|
|
|
|
return;
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
|
2020-04-24 14:38:43 +02:00
|
|
|
si = static_route_info_from_rnode(rn);
|
|
|
|
if (!si)
|
|
|
|
continue;
|
|
|
|
frr_each(static_path_list, &si->path_list, pn) {
|
|
|
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
|
|
|
if (nh->nh_vrf_id != nh_vrf_id)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (nhp->family == AF_INET
|
|
|
|
&& nhp->u.prefix4.s_addr
|
|
|
|
!= nh->addr.ipv4.s_addr)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (nhp->family == AF_INET6
|
|
|
|
&& memcmp(&nhp->u.prefix6, &nh->addr.ipv6,
|
|
|
|
16)
|
|
|
|
!= 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We've been told that a nexthop we
|
|
|
|
* depend on has changed in some manner,
|
|
|
|
* so reset the state machine to allow
|
|
|
|
* us to start over.
|
|
|
|
*/
|
|
|
|
nh->state = STATIC_START;
|
|
|
|
}
|
2019-07-16 14:27:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-04 13:05:18 +02:00
|
|
|
void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi,
|
|
|
|
vrf_id_t nh_vrf_id)
|
2019-07-16 14:27:31 +02:00
|
|
|
{
|
2024-02-03 20:34:18 +01:00
|
|
|
struct static_vrf *svrf;
|
2019-07-16 14:27:31 +02:00
|
|
|
|
2024-02-03 20:34:18 +01:00
|
|
|
RB_FOREACH (svrf, svrf_name_head, &svrfs)
|
|
|
|
static_nht_reset_start_safi(nhp, afi, safi, svrf, nh_vrf_id);
|
2019-07-16 14:27:31 +02:00
|
|
|
}
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
static void static_nht_mark_state_safi(const struct prefix *sp, const struct prefix *ssrc_p,
|
|
|
|
afi_t afi, safi_t safi, struct vrf *vrf,
|
2019-07-16 14:27:31 +02:00
|
|
|
enum static_install_states state)
|
|
|
|
{
|
|
|
|
struct static_vrf *svrf;
|
|
|
|
struct route_table *stable;
|
|
|
|
struct route_node *rn;
|
2020-04-24 14:38:43 +02:00
|
|
|
struct static_nexthop *nh;
|
|
|
|
struct static_path *pn;
|
|
|
|
struct static_route_info *si;
|
2019-07-16 14:27:31 +02:00
|
|
|
|
|
|
|
svrf = vrf->info;
|
|
|
|
if (!svrf)
|
|
|
|
return;
|
|
|
|
|
|
|
|
stable = static_vrf_static_table(afi, safi, svrf);
|
|
|
|
if (!stable)
|
|
|
|
return;
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p);
|
2019-07-16 14:27:31 +02:00
|
|
|
if (!rn)
|
|
|
|
return;
|
2020-04-24 14:38:43 +02:00
|
|
|
si = rn->info;
|
|
|
|
if (si) {
|
|
|
|
frr_each(static_path_list, &si->path_list, pn) {
|
|
|
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
|
|
|
nh->state = state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-16 14:27:31 +02:00
|
|
|
|
|
|
|
route_unlock_node(rn);
|
|
|
|
}
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
void static_nht_mark_state(const struct prefix *sp, const struct prefix *ssrc_p, safi_t safi,
|
|
|
|
vrf_id_t vrf_id, enum static_install_states state)
|
2019-07-16 14:27:31 +02:00
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
|
|
|
afi_t afi = AFI_IP;
|
|
|
|
|
|
|
|
if (sp->family == AF_INET6)
|
|
|
|
afi = AFI_IP6;
|
|
|
|
|
|
|
|
vrf = vrf_lookup_by_id(vrf_id);
|
|
|
|
if (!vrf || !vrf->info)
|
|
|
|
return;
|
|
|
|
|
2025-01-27 17:57:54 +01:00
|
|
|
static_nht_mark_state_safi(sp, ssrc_p, afi, safi, vrf, state);
|
2019-07-16 14:27:31 +02:00
|
|
|
}
|