3 * Copyright (C) 2018 Cumulus Networks, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <lib/nexthop.h>
23 #include <lib/memory.h>
24 #include <lib/srcdest_table.h>
28 #include <lib/memory.h>
30 #include "static_vrf.h"
31 #include "static_routes.h"
32 #include "static_memory.h"
33 #include "static_zebra.h"
35 /* Install static route into rib. */
36 static void static_install_route(struct route_node
*rn
,
37 struct static_route
*si_changed
, safi_t safi
)
39 struct static_route
*si
;
41 for (si
= rn
->info
; si
; si
= si
->next
)
42 static_zebra_nht_register(rn
, si
, true);
46 static_zebra_route_add(rn
, si_changed
, si
->vrf_id
, safi
, true);
50 /* Uninstall static route from RIB. */
51 static void static_uninstall_route(vrf_id_t vrf_id
, safi_t safi
,
52 struct route_node
*rn
,
53 struct static_route
*si_changed
)
57 static_zebra_route_add(rn
, si_changed
, vrf_id
, safi
, true);
59 static_zebra_route_add(rn
, si_changed
, vrf_id
, safi
, false);
62 int static_add_route(afi_t afi
, safi_t safi
, uint8_t type
, struct prefix
*p
,
63 struct prefix_ipv6
*src_p
, union g_addr
*gate
,
64 const char *ifname
, enum static_blackhole_type bh_type
,
65 route_tag_t tag
, uint8_t distance
, struct static_vrf
*svrf
,
66 struct static_vrf
*nh_svrf
,
67 struct static_nh_label
*snh_label
, uint32_t table_id
,
70 struct route_node
*rn
;
71 struct static_route
*si
;
72 struct static_route
*pp
;
73 struct static_route
*cp
;
74 struct static_route
*update
= NULL
;
75 struct route_table
*stable
= svrf
->stable
[afi
][safi
];
76 struct interface
*ifp
;
81 if (!gate
&& (type
== STATIC_IPV4_GATEWAY
82 || type
== STATIC_IPV4_GATEWAY_IFNAME
83 || type
== STATIC_IPV6_GATEWAY
84 || type
== STATIC_IPV6_GATEWAY_IFNAME
))
88 && (type
== STATIC_IFNAME
|| type
== STATIC_IPV4_GATEWAY_IFNAME
89 || type
== STATIC_IPV6_GATEWAY_IFNAME
))
92 /* Lookup static route prefix. */
93 rn
= srcdest_rnode_get(stable
, p
, src_p
);
95 /* Do nothing if there is a same static route. */
96 for (si
= rn
->info
; si
; si
= si
->next
) {
100 && IPV4_ADDR_SAME(&gate
->ipv4
, &si
->addr
.ipv4
))
102 && IPV6_ADDR_SAME(gate
, &si
->addr
.ipv6
))))
103 && (!strcmp(ifname
? ifname
: "", si
->ifname
))
104 && nh_svrf
->vrf
->vrf_id
== si
->nh_vrf_id
) {
105 if ((distance
== si
->distance
) && (tag
== si
->tag
)
106 && (table_id
== si
->table_id
)
107 && !memcmp(&si
->snh_label
, snh_label
,
108 sizeof(struct static_nh_label
))
109 && si
->bh_type
== bh_type
&& si
->onlink
== onlink
) {
110 route_unlock_node(rn
);
117 /* Distance or tag or label changed, delete existing first. */
119 static_delete_route(afi
, safi
, type
, p
, src_p
, gate
, ifname
,
120 update
->tag
, update
->distance
, svrf
,
121 &update
->snh_label
, table_id
);
123 /* Make new static route structure. */
124 si
= XCALLOC(MTYPE_STATIC_ROUTE
, sizeof(struct static_route
));
127 si
->distance
= distance
;
128 si
->bh_type
= bh_type
;
130 si
->vrf_id
= svrf
->vrf
->vrf_id
;
131 si
->nh_vrf_id
= nh_svrf
->vrf
->vrf_id
;
132 strlcpy(si
->nh_vrfname
, nh_svrf
->vrf
->name
, sizeof(si
->nh_vrfname
));
133 si
->table_id
= table_id
;
137 strlcpy(si
->ifname
, ifname
, sizeof(si
->ifname
));
138 si
->ifindex
= IFINDEX_INTERNAL
;
141 case STATIC_IPV4_GATEWAY
:
142 case STATIC_IPV4_GATEWAY_IFNAME
:
143 si
->addr
.ipv4
= gate
->ipv4
;
145 case STATIC_IPV6_GATEWAY
:
146 case STATIC_IPV6_GATEWAY_IFNAME
:
147 si
->addr
.ipv6
= gate
->ipv6
;
153 /* Save labels, if any. */
154 memcpy(&si
->snh_label
, snh_label
, sizeof(struct static_nh_label
));
157 * Add new static route information to the tree with sort by
158 * distance value and gateway address.
160 for (pp
= NULL
, cp
= rn
->info
; cp
; pp
= cp
, cp
= cp
->next
) {
161 if (si
->distance
< cp
->distance
)
163 if (si
->distance
> cp
->distance
)
165 if (si
->type
== STATIC_IPV4_GATEWAY
166 && cp
->type
== STATIC_IPV4_GATEWAY
) {
167 if (ntohl(si
->addr
.ipv4
.s_addr
)
168 < ntohl(cp
->addr
.ipv4
.s_addr
))
170 if (ntohl(si
->addr
.ipv4
.s_addr
)
171 > ntohl(cp
->addr
.ipv4
.s_addr
))
176 /* Make linked list. */
186 /* check whether interface exists in system & install if it does */
188 case STATIC_IPV4_GATEWAY
:
189 case STATIC_IPV6_GATEWAY
:
190 static_zebra_nht_register(rn
, si
, true);
192 case STATIC_IPV4_GATEWAY_IFNAME
:
193 case STATIC_IPV6_GATEWAY_IFNAME
:
194 ifp
= if_lookup_by_name(ifname
, nh_svrf
->vrf
->vrf_id
);
195 if (ifp
&& ifp
->ifindex
!= IFINDEX_INTERNAL
)
196 si
->ifindex
= ifp
->ifindex
;
198 zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf",
201 static_zebra_nht_register(rn
, si
, true);
203 case STATIC_BLACKHOLE
:
204 static_install_route(rn
, si
, safi
);
207 ifp
= if_lookup_by_name(ifname
, nh_svrf
->vrf
->vrf_id
);
208 if (ifp
&& ifp
->ifindex
!= IFINDEX_INTERNAL
) {
209 si
->ifindex
= ifp
->ifindex
;
210 static_install_route(rn
, si
, safi
);
212 zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf",
221 int static_delete_route(afi_t afi
, safi_t safi
, uint8_t type
, struct prefix
*p
,
222 struct prefix_ipv6
*src_p
, union g_addr
*gate
,
223 const char *ifname
, route_tag_t tag
, uint8_t distance
,
224 struct static_vrf
*svrf
,
225 struct static_nh_label
*snh_label
,
228 struct route_node
*rn
;
229 struct static_route
*si
;
230 struct route_table
*stable
;
233 stable
= static_vrf_static_table(afi
, safi
, svrf
);
237 /* Lookup static route prefix. */
238 rn
= srcdest_rnode_lookup(stable
, p
, src_p
);
242 /* Find same static route is the tree */
243 for (si
= rn
->info
; si
; si
= si
->next
)
247 && IPV4_ADDR_SAME(&gate
->ipv4
, &si
->addr
.ipv4
))
249 && IPV6_ADDR_SAME(gate
, &si
->addr
.ipv6
))))
250 && (!strcmp(ifname
? ifname
: "", si
->ifname
))
251 && (!tag
|| (tag
== si
->tag
))
252 && (table_id
== si
->table_id
)
253 && (!snh_label
->num_labels
254 || !memcmp(&si
->snh_label
, snh_label
,
255 sizeof(struct static_nh_label
))))
258 /* Can't find static route. */
260 route_unlock_node(rn
);
264 static_zebra_nht_register(rn
, si
, false);
266 /* Unlink static route from linked list. */
268 si
->prev
->next
= si
->next
;
272 si
->next
->prev
= si
->prev
;
275 * If we have other si nodes then route replace
276 * else delete the route
278 static_uninstall_route(si
->vrf_id
, safi
, rn
, si
);
279 route_unlock_node(rn
);
281 /* Free static route configuration. */
282 XFREE(MTYPE_STATIC_ROUTE
, si
);
284 route_unlock_node(rn
);
289 static void static_ifindex_update_af(struct interface
*ifp
, bool up
, afi_t afi
,
292 struct route_table
*stable
;
293 struct route_node
*rn
;
294 struct static_route
*si
;
297 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
298 struct static_vrf
*svrf
;
302 stable
= static_vrf_static_table(afi
, safi
, svrf
);
306 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
)) {
307 for (si
= rn
->info
; si
; si
= si
->next
) {
311 if (strcmp(si
->ifname
, ifp
->name
))
313 if (si
->nh_vrf_id
!= ifp
->vrf_id
)
315 si
->ifindex
= ifp
->ifindex
;
317 if (si
->ifindex
!= ifp
->ifindex
)
319 if (si
->nh_vrf_id
!= ifp
->vrf_id
)
321 si
->ifindex
= IFINDEX_INTERNAL
;
324 static_install_route(rn
, si
, safi
);
331 * This function looks at a svrf's stable and notices if any of the
332 * nexthops we are using are part of the vrf coming up.
333 * If we are using them then cleanup the nexthop vrf id
334 * to be the new value and then re-installs them
337 * stable -> The table we are looking at.
338 * svrf -> The newly changed vrf.
339 * afi -> The afi to look at
340 * safi -> the safi to look at
342 static void static_fixup_vrf(struct static_vrf
*svrf
,
343 struct route_table
*stable
, afi_t afi
, safi_t safi
)
345 struct route_node
*rn
;
346 struct static_route
*si
;
347 struct interface
*ifp
;
349 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
350 for (si
= rn
->info
; si
; si
= si
->next
) {
351 if (strcmp(svrf
->vrf
->name
, si
->nh_vrfname
) != 0)
354 si
->nh_vrf_id
= svrf
->vrf
->vrf_id
;
355 si
->nh_registered
= false;
357 ifp
= if_lookup_by_name(si
->ifname
,
360 si
->ifindex
= ifp
->ifindex
;
365 static_install_route(rn
, si
, safi
);
371 * This function enables static routes in a svrf as it
372 * is coming up. It sets the new vrf_id as appropriate.
374 * svrf -> The svrf that is being brought up and enabled by the kernel
375 * stable -> The stable we are looking at.
376 * afi -> the afi in question
377 * safi -> the safi in question
379 static void static_enable_vrf(struct static_vrf
*svrf
,
380 struct route_table
*stable
,
381 afi_t afi
, safi_t safi
)
383 struct route_node
*rn
;
384 struct static_route
*si
;
385 struct interface
*ifp
;
386 struct vrf
*vrf
= svrf
->vrf
;
388 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
389 for (si
= rn
->info
; si
; si
= si
->next
) {
390 si
->vrf_id
= vrf
->vrf_id
;
392 ifp
= if_lookup_by_name(si
->ifname
,
395 si
->ifindex
= ifp
->ifindex
;
399 static_install_route(rn
, si
, safi
);
405 * When a vrf is being enabled by the kernel, go through all the
406 * static routes in the system that use this vrf (both nexthops vrfs
407 * and the routes vrf )
409 * enable_svrf -> the vrf being enabled
411 void static_fixup_vrf_ids(struct static_vrf
*enable_svrf
)
413 struct route_table
*stable
;
418 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
419 struct static_vrf
*svrf
;
422 /* Install any static routes configured for this VRF. */
423 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
424 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
425 stable
= svrf
->stable
[afi
][safi
];
429 static_fixup_vrf(enable_svrf
, stable
,
432 if (enable_svrf
== svrf
)
433 static_enable_vrf(svrf
, stable
,
441 * Look at the specified stable and if any of the routes in
442 * this table are using the svrf as the nexthop, uninstall
445 * svrf -> the vrf being disabled
446 * stable -> the table we need to look at.
447 * afi -> the afi in question
448 * safi -> the safi in question
450 static void static_cleanup_vrf(struct static_vrf
*svrf
,
451 struct route_table
*stable
,
452 afi_t afi
, safi_t safi
)
454 struct route_node
*rn
;
455 struct static_route
*si
;
457 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
458 for (si
= rn
->info
; si
; si
= si
->next
) {
459 if (strcmp(svrf
->vrf
->name
, si
->nh_vrfname
) != 0)
462 static_uninstall_route(si
->vrf_id
, safi
, rn
, si
);
468 * Look at all static routes in this table and uninstall
471 * stable -> The table to uninstall from
472 * afi -> The afi in question
473 * safi -> the safi in question
475 static void static_disable_vrf(struct route_table
*stable
,
476 afi_t afi
, safi_t safi
)
478 struct route_node
*rn
;
479 struct static_route
*si
;
481 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
))
482 for (si
= rn
->info
; si
; si
= si
->next
)
483 static_uninstall_route(si
->vrf_id
, safi
, rn
, si
);
487 * When the disable_svrf is shutdown by the kernel, we call
488 * this function and it cleans up all static routes using
489 * this vrf as a nexthop as well as all static routes
492 * disable_svrf - The vrf being disabled
494 void static_cleanup_vrf_ids(struct static_vrf
*disable_svrf
)
500 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
501 struct static_vrf
*svrf
;
505 /* Uninstall any static routes configured for this VRF. */
506 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
507 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
508 struct route_table
*stable
;
510 stable
= svrf
->stable
[afi
][safi
];
514 static_cleanup_vrf(disable_svrf
, stable
,
517 if (disable_svrf
== svrf
)
518 static_disable_vrf(stable
, afi
, safi
);
525 * This function enables static routes when an interface it relies
526 * on in a different vrf is coming up.
528 * stable -> The stable we are looking at.
529 * ifp -> interface coming up
530 * afi -> the afi in question
531 * safi -> the safi in question
533 static void static_fixup_intf_nh(struct route_table
*stable
,
534 struct interface
*ifp
,
535 afi_t afi
, safi_t safi
)
537 struct route_node
*rn
;
538 struct static_route
*si
;
540 for (rn
= route_top(stable
); rn
; rn
= route_next(rn
)) {
541 for (si
= rn
->info
; si
; si
= si
->next
) {
542 if (si
->nh_vrf_id
!= ifp
->vrf_id
)
545 if (si
->ifindex
!= ifp
->ifindex
)
548 static_install_route(rn
, si
, safi
);
554 * This function enables static routes that rely on an interface in
555 * a different vrf when that interface comes up.
557 void static_install_intf_nh(struct interface
*ifp
)
559 struct route_table
*stable
;
564 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
565 struct static_vrf
*svrf
= vrf
->info
;
567 /* Not needed if same vrf since happens naturally */
568 if (vrf
->vrf_id
== ifp
->vrf_id
)
571 /* Install any static routes configured for this interface. */
572 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
573 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
574 stable
= svrf
->stable
[afi
][safi
];
578 static_fixup_intf_nh(stable
, ifp
, afi
, safi
);
584 /* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */
585 void static_ifindex_update(struct interface
*ifp
, bool up
)
587 static_ifindex_update_af(ifp
, up
, AFI_IP
, SAFI_UNICAST
);
588 static_ifindex_update_af(ifp
, up
, AFI_IP
, SAFI_MULTICAST
);
589 static_ifindex_update_af(ifp
, up
, AFI_IP6
, SAFI_UNICAST
);
590 static_ifindex_update_af(ifp
, up
, AFI_IP6
, SAFI_MULTICAST
);