1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2018 Cumulus Networks, Inc.
13 #include "srcdest_table.h"
15 #include "static_vrf.h"
16 #include "static_routes.h"
17 #include "static_zebra.h"
18 #include "static_nht.h"
20 static void static_nht_update_path(struct static_path
*pn
, struct prefix
*nhp
,
21 uint32_t nh_num
, vrf_id_t nh_vrf_id
,
24 struct static_nexthop
*nh
;
26 frr_each(static_nexthop_list
, &pn
->nexthop_list
, nh
) {
27 if (nh
->nh_vrf_id
!= nh_vrf_id
)
30 if (nh
->type
!= STATIC_IPV4_GATEWAY
31 && nh
->type
!= STATIC_IPV4_GATEWAY_IFNAME
32 && nh
->type
!= STATIC_IPV6_GATEWAY
33 && nh
->type
!= STATIC_IPV6_GATEWAY_IFNAME
)
36 if (nhp
->family
== AF_INET
37 && nhp
->u
.prefix4
.s_addr
== nh
->addr
.ipv4
.s_addr
)
38 nh
->nh_valid
= !!nh_num
;
40 if (nhp
->family
== AF_INET6
41 && memcmp(&nhp
->u
.prefix6
, &nh
->addr
.ipv6
, IPV6_MAX_BYTELEN
)
43 nh
->nh_valid
= !!nh_num
;
45 if (nh
->state
== STATIC_START
)
46 static_zebra_route_add(pn
, true);
50 static void static_nht_update_safi(struct prefix
*sp
, struct prefix
*nhp
,
51 uint32_t nh_num
, afi_t afi
, safi_t safi
,
52 struct vrf
*vrf
, vrf_id_t nh_vrf_id
)
54 struct route_table
*stable
;
55 struct static_vrf
*svrf
;
56 struct route_node
*rn
;
57 struct static_path
*pn
;
58 struct static_route_info
*si
;
64 stable
= static_vrf_static_table(afi
, safi
, svrf
);
69 rn
= srcdest_rnode_lookup(stable
, sp
, NULL
);
71 si
= static_route_info_from_rnode(rn
);
72 frr_each(static_path_list
, &si
->path_list
, pn
) {
73 static_nht_update_path(pn
, nhp
, nh_num
,
76 route_unlock_node(rn
);
81 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
82 si
= static_route_info_from_rnode(rn
);
85 frr_each(static_path_list
, &si
->path_list
, pn
) {
86 static_nht_update_path(pn
, nhp
, nh_num
, nh_vrf_id
, vrf
);
91 void static_nht_update(struct prefix
*sp
, struct prefix
*nhp
, uint32_t nh_num
,
92 afi_t afi
, safi_t safi
, vrf_id_t nh_vrf_id
)
97 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
98 static_nht_update_safi(sp
, nhp
, nh_num
, afi
, safi
, vrf
,
102 static void static_nht_reset_start_safi(struct prefix
*nhp
, afi_t afi
,
103 safi_t safi
, struct vrf
*vrf
,
106 struct static_vrf
*svrf
;
107 struct route_table
*stable
;
108 struct static_nexthop
*nh
;
109 struct static_path
*pn
;
110 struct route_node
*rn
;
111 struct static_route_info
*si
;
117 stable
= static_vrf_static_table(afi
, safi
, svrf
);
121 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
122 si
= static_route_info_from_rnode(rn
);
125 frr_each(static_path_list
, &si
->path_list
, pn
) {
126 frr_each(static_nexthop_list
, &pn
->nexthop_list
, nh
) {
127 if (nh
->nh_vrf_id
!= nh_vrf_id
)
130 if (nhp
->family
== AF_INET
131 && nhp
->u
.prefix4
.s_addr
132 != nh
->addr
.ipv4
.s_addr
)
135 if (nhp
->family
== AF_INET6
136 && memcmp(&nhp
->u
.prefix6
, &nh
->addr
.ipv6
,
142 * We've been told that a nexthop we
143 * depend on has changed in some manner,
144 * so reset the state machine to allow
147 nh
->state
= STATIC_START
;
153 void static_nht_reset_start(struct prefix
*nhp
, afi_t afi
, safi_t safi
,
158 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
159 static_nht_reset_start_safi(nhp
, afi
, safi
, vrf
, nh_vrf_id
);
162 static void static_nht_mark_state_safi(struct prefix
*sp
, afi_t afi
,
163 safi_t safi
, struct vrf
*vrf
,
164 enum static_install_states state
)
166 struct static_vrf
*svrf
;
167 struct route_table
*stable
;
168 struct route_node
*rn
;
169 struct static_nexthop
*nh
;
170 struct static_path
*pn
;
171 struct static_route_info
*si
;
177 stable
= static_vrf_static_table(afi
, safi
, svrf
);
181 rn
= srcdest_rnode_lookup(stable
, sp
, NULL
);
186 frr_each(static_path_list
, &si
->path_list
, pn
) {
187 frr_each(static_nexthop_list
, &pn
->nexthop_list
, nh
) {
193 route_unlock_node(rn
);
196 void static_nht_mark_state(struct prefix
*sp
, safi_t safi
, vrf_id_t vrf_id
,
197 enum static_install_states state
)
203 if (sp
->family
== AF_INET6
)
206 vrf
= vrf_lookup_by_id(vrf_id
);
207 if (!vrf
|| !vrf
->info
)
210 static_nht_mark_state_safi(sp
, afi
, safi
, vrf
, state
);