1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Routing Information Base.
3 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
18 #include "sockunion.h"
19 #include "srcdest_table.h"
23 #include "workqueue.h"
24 #include "nexthop_group_private.h"
25 #include "frr_pthread.h"
27 #include "frrscript.h"
29 #include "zebra/zebra_router.h"
30 #include "zebra/connected.h"
31 #include "zebra/debug.h"
32 #include "zebra/interface.h"
33 #include "zebra/redistribute.h"
34 #include "zebra/rib.h"
36 #include "zebra/zapi_msg.h"
37 #include "zebra/zebra_errors.h"
38 #include "zebra/zebra_ns.h"
39 #include "zebra/zebra_rnh.h"
40 #include "zebra/zebra_routemap.h"
41 #include "zebra/zebra_vrf.h"
42 #include "zebra/zebra_vxlan.h"
43 #include "zebra/zapi_msg.h"
44 #include "zebra/zebra_dplane.h"
45 #include "zebra/zebra_evpn_mh.h"
46 #include "zebra/zebra_script.h"
48 DEFINE_MGROUP(ZEBRA
, "zebra");
50 DEFINE_MTYPE(ZEBRA
, RE
, "Route Entry");
51 DEFINE_MTYPE_STATIC(ZEBRA
, RIB_DEST
, "RIB destination");
52 DEFINE_MTYPE_STATIC(ZEBRA
, RIB_UPDATE_CTX
, "Rib update context object");
53 DEFINE_MTYPE_STATIC(ZEBRA
, WQ_WRAPPER
, "WQ wrapper");
56 * Event, list, and mutex for delivery of dataplane results
58 static pthread_mutex_t dplane_mutex
;
59 static struct event
*t_dplane
;
60 static struct dplane_ctx_list_head rib_dplane_q
;
62 DEFINE_HOOK(rib_update
, (struct route_node
* rn
, const char *reason
),
64 DEFINE_HOOK(rib_shutdown
, (struct route_node
* rn
), (rn
));
68 * Meta Q's specific names
70 * If you add something here ensure that you
71 * change MQ_SIZE as well over in rib.h
73 enum meta_queue_indexes
{
76 META_QUEUE_EARLY_ROUTE
,
77 META_QUEUE_EARLY_LABEL
,
87 /* Each route type's string and default distance value. */
91 enum meta_queue_indexes meta_q_map
;
92 } route_info
[ZEBRA_ROUTE_MAX
] = {
95 ZEBRA_MAX_DISTANCE_DEFAULT
/* Unneeded for nhg's */,
97 [ZEBRA_ROUTE_SYSTEM
] = {ZEBRA_ROUTE_SYSTEM
,
98 ZEBRA_KERNEL_DISTANCE_DEFAULT
,
100 [ZEBRA_ROUTE_KERNEL
] = {ZEBRA_ROUTE_KERNEL
,
101 ZEBRA_KERNEL_DISTANCE_DEFAULT
,
103 [ZEBRA_ROUTE_CONNECT
] = {ZEBRA_ROUTE_CONNECT
,
104 ZEBRA_CONNECT_DISTANCE_DEFAULT
,
105 META_QUEUE_CONNECTED
},
106 [ZEBRA_ROUTE_STATIC
] = {ZEBRA_ROUTE_STATIC
,
107 ZEBRA_STATIC_DISTANCE_DEFAULT
,
109 [ZEBRA_ROUTE_RIP
] = {ZEBRA_ROUTE_RIP
, ZEBRA_RIP_DISTANCE_DEFAULT
,
111 [ZEBRA_ROUTE_RIPNG
] = {ZEBRA_ROUTE_RIPNG
, ZEBRA_RIP_DISTANCE_DEFAULT
,
113 [ZEBRA_ROUTE_OSPF
] = {ZEBRA_ROUTE_OSPF
, ZEBRA_OSPF_DISTANCE_DEFAULT
,
115 [ZEBRA_ROUTE_OSPF6
] = {ZEBRA_ROUTE_OSPF6
, ZEBRA_OSPF6_DISTANCE_DEFAULT
,
117 [ZEBRA_ROUTE_ISIS
] = {ZEBRA_ROUTE_ISIS
, ZEBRA_ISIS_DISTANCE_DEFAULT
,
119 [ZEBRA_ROUTE_BGP
] = {ZEBRA_ROUTE_BGP
,
120 ZEBRA_EBGP_DISTANCE_DEFAULT
/* IBGP is 200. */,
122 [ZEBRA_ROUTE_PIM
] = {ZEBRA_ROUTE_PIM
, ZEBRA_MAX_DISTANCE_DEFAULT
,
124 [ZEBRA_ROUTE_EIGRP
] = {ZEBRA_ROUTE_EIGRP
, ZEBRA_EIGRP_DISTANCE_DEFAULT
,
126 [ZEBRA_ROUTE_NHRP
] = {ZEBRA_ROUTE_NHRP
, ZEBRA_NHRP_DISTANCE_DEFAULT
,
128 [ZEBRA_ROUTE_HSLS
] = {ZEBRA_ROUTE_HSLS
, ZEBRA_MAX_DISTANCE_DEFAULT
,
130 [ZEBRA_ROUTE_OLSR
] = {ZEBRA_ROUTE_OLSR
, ZEBRA_MAX_DISTANCE_DEFAULT
,
132 [ZEBRA_ROUTE_TABLE
] = {ZEBRA_ROUTE_TABLE
, ZEBRA_TABLE_DISTANCE_DEFAULT
, META_QUEUE_STATIC
},
133 [ZEBRA_ROUTE_LDP
] = {ZEBRA_ROUTE_LDP
, ZEBRA_LDP_DISTANCE_DEFAULT
,
135 [ZEBRA_ROUTE_VNC
] = {ZEBRA_ROUTE_VNC
, ZEBRA_EBGP_DISTANCE_DEFAULT
,
137 [ZEBRA_ROUTE_VNC_DIRECT
] = {ZEBRA_ROUTE_VNC_DIRECT
,
138 ZEBRA_EBGP_DISTANCE_DEFAULT
,
140 [ZEBRA_ROUTE_VNC_DIRECT_RH
] = {ZEBRA_ROUTE_VNC_DIRECT_RH
,
141 ZEBRA_EBGP_DISTANCE_DEFAULT
,
143 [ZEBRA_ROUTE_BGP_DIRECT
] = {ZEBRA_ROUTE_BGP_DIRECT
,
144 ZEBRA_EBGP_DISTANCE_DEFAULT
,
146 [ZEBRA_ROUTE_BGP_DIRECT_EXT
] = {ZEBRA_ROUTE_BGP_DIRECT_EXT
,
147 ZEBRA_EBGP_DISTANCE_DEFAULT
,
149 [ZEBRA_ROUTE_BABEL
] = {ZEBRA_ROUTE_BABEL
, ZEBRA_BABEL_DISTANCE_DEFAULT
,
151 [ZEBRA_ROUTE_SHARP
] = {ZEBRA_ROUTE_SHARP
, ZEBRA_SHARP_DISTANCE_DEFAULT
,
153 [ZEBRA_ROUTE_PBR
] = {ZEBRA_ROUTE_PBR
, ZEBRA_PBR_DISTANCE_DEFAULT
,
155 [ZEBRA_ROUTE_BFD
] = {ZEBRA_ROUTE_BFD
, ZEBRA_MAX_DISTANCE_DEFAULT
,
157 [ZEBRA_ROUTE_OPENFABRIC
] = {ZEBRA_ROUTE_OPENFABRIC
,
158 ZEBRA_OPENFABRIC_DISTANCE_DEFAULT
,
160 [ZEBRA_ROUTE_VRRP
] = {ZEBRA_ROUTE_VRRP
, ZEBRA_MAX_DISTANCE_DEFAULT
,
162 [ZEBRA_ROUTE_SRTE
] = {ZEBRA_ROUTE_SRTE
, ZEBRA_MAX_DISTANCE_DEFAULT
,
164 [ZEBRA_ROUTE_ALL
] = {ZEBRA_ROUTE_ALL
, ZEBRA_MAX_DISTANCE_DEFAULT
,
166 /* Any new route type added to zebra, should be mirrored here */
168 /* no entry/default: 150 */
171 /* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
172 * from the OS, and an 'nhe' is a nhe update.
174 struct wq_nhg_wrapper
{
178 struct nhg_hash_entry
*nhe
;
182 #define WQ_NHG_WRAPPER_TYPE_CTX 0x01
183 #define WQ_NHG_WRAPPER_TYPE_NHG 0x02
185 /* Wrapper structs for evpn/vxlan workqueue items. */
186 struct wq_evpn_wrapper
{
198 struct ethaddr macaddr
;
199 struct prefix prefix
;
200 struct in_addr vtep_ip
;
203 #define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01
204 #define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02
205 #define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03
206 #define WQ_EVPN_WRAPPER_TYPE_REM_VTEP 0x04
208 enum wq_label_types
{
209 WQ_LABEL_FTN_UNINSTALL
,
210 WQ_LABEL_LABELS_PROCESS
,
213 struct wq_label_wrapper
{
214 enum wq_label_types type
;
218 enum lsp_types_t ltype
;
220 uint8_t route_instance
;
223 struct zapi_labels zl
;
228 static void rib_addnode(struct route_node
*rn
, struct route_entry
*re
,
231 /* %pRN is already a printer for route_nodes that just prints the prefix */
232 #ifdef _FRR_ATTRIBUTE_PRINTFRR
233 #pragma FRR printfrr_ext "%pZN" (struct route_node *)
236 static const char *subqueue2str(enum meta_queue_indexes index
)
240 return "NHG Objects";
241 case META_QUEUE_EVPN
:
242 return "EVPN/VxLan Objects";
243 case META_QUEUE_EARLY_ROUTE
:
244 return "Early Route Processing";
245 case META_QUEUE_EARLY_LABEL
:
246 return "Early Label Handling";
247 case META_QUEUE_CONNECTED
:
248 return "Connected Routes";
249 case META_QUEUE_KERNEL
:
250 return "Kernel Routes";
251 case META_QUEUE_STATIC
:
252 return "Static Routes";
253 case META_QUEUE_NOTBGP
:
254 return "RIP/OSPF/ISIS/EIGRP/NHRP Routes";
257 case META_QUEUE_OTHER
:
258 return "Other Routes";
259 case META_QUEUE_GR_RUN
:
260 return "Graceful Restart";
266 printfrr_ext_autoreg_p("ZN", printfrr_zebra_node
);
267 static ssize_t
printfrr_zebra_node(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
270 struct route_node
*rn
= (struct route_node
*)ptr
;
273 /* just the table number? */
274 if (ea
->fmt
[0] == 't') {
276 struct route_entry
*re
= NULL
;
281 return bputch(buf
, '!');
283 dest
= rib_dest_from_rnode(rn
);
285 re
= re_list_first(&dest
->routes
);
287 rv
+= bprintfrr(buf
, "%u", re
->table
);
289 rv
+= bputch(buf
, '?');
292 char cbuf
[PREFIX_STRLEN
* 2 + 6];
293 struct rib_table_info
*info
;
296 return bputs(buf
, "{(route_node *) NULL}");
298 srcdest_rnode2str(rn
, cbuf
, sizeof(cbuf
));
299 rv
+= bputs(buf
, cbuf
);
301 info
= srcdest_rnode_table_info(rn
);
302 if (info
->safi
== SAFI_MULTICAST
)
303 rv
+= bputs(buf
, " (MRIB)");
308 #define rnode_debug(node, vrf_id, msg, ...) \
309 zlog_debug("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
312 #define rnode_info(node, vrf_id, msg, ...) \
313 zlog_info("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
316 static char *_dump_re_status(const struct route_entry
*re
, char *buf
,
319 if (re
->status
== 0) {
320 snprintfrr(buf
, len
, "None ");
325 buf
, len
, "%s%s%s%s%s%s%s%s",
326 CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
) ? "Removed " : "",
327 CHECK_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
) ? "Changed " : "",
328 CHECK_FLAG(re
->status
, ROUTE_ENTRY_LABELS_CHANGED
)
331 CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
) ? "Queued " : "",
332 CHECK_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
)
335 CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
) ? "Installed "
337 CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
) ? "Failed " : "",
338 CHECK_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
) ? "Fib NHG "
343 uint8_t route_distance(int type
)
347 if ((unsigned)type
>= array_size(route_info
))
350 distance
= route_info
[type
].distance
;
355 int is_zebra_valid_kernel_table(uint32_t table_id
)
358 if ((table_id
== RT_TABLE_UNSPEC
) || (table_id
== RT_TABLE_LOCAL
)
359 || (table_id
== RT_TABLE_COMPAT
))
366 int is_zebra_main_routing_table(uint32_t table_id
)
368 if (table_id
== RT_TABLE_MAIN
)
373 int zebra_check_addr(const struct prefix
*p
)
375 if (p
->family
== AF_INET
) {
378 addr
= p
->u
.prefix4
.s_addr
;
381 if (IPV4_NET127(addr
) || IN_CLASSD(addr
)
382 || IPV4_LINKLOCAL(addr
))
385 if (p
->family
== AF_INET6
) {
386 if (IN6_IS_ADDR_LOOPBACK(&p
->u
.prefix6
))
388 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
394 static void route_entry_attach_ref(struct route_entry
*re
,
395 struct nhg_hash_entry
*new)
398 re
->nhe_id
= new->id
;
399 re
->nhe_installed_id
= 0;
401 zebra_nhg_increment_ref(new);
404 /* Replace (if 'new_nhghe') or clear (if that's NULL) an re's nhe. */
405 int route_entry_update_nhe(struct route_entry
*re
,
406 struct nhg_hash_entry
*new_nhghe
)
409 struct nhg_hash_entry
*old_nhg
= NULL
;
411 if (new_nhghe
== NULL
) {
415 re
->nhe_installed_id
= 0;
420 if ((re
->nhe_id
!= 0) && re
->nhe
&& (re
->nhe
!= new_nhghe
)) {
421 /* Capture previous nhg, if any */
424 route_entry_attach_ref(re
, new_nhghe
);
426 /* This is the first time it's being attached */
427 route_entry_attach_ref(re
, new_nhghe
);
430 /* Detach / deref previous nhg */
432 zebra_nhg_decrement_ref(old_nhg
);
437 void rib_handle_nhg_replace(struct nhg_hash_entry
*old_entry
,
438 struct nhg_hash_entry
*new_entry
)
440 struct zebra_router_table
*zrt
;
441 struct route_node
*rn
;
442 struct route_entry
*re
, *next
;
444 if (IS_ZEBRA_DEBUG_RIB_DETAILED
|| IS_ZEBRA_DEBUG_NHG_DETAIL
)
445 zlog_debug("%s: replacing routes nhe (%u) OLD %p NEW %p",
446 __func__
, new_entry
->id
, new_entry
, old_entry
);
448 /* We have to do them ALL */
449 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
450 for (rn
= route_top(zrt
->table
); rn
;
451 rn
= srcdest_route_next(rn
)) {
452 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
453 if (re
->nhe
&& re
->nhe
== old_entry
)
454 route_entry_update_nhe(re
, new_entry
);
460 struct route_entry
*rib_match(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
,
461 const union g_addr
*addr
,
462 struct route_node
**rn_out
)
465 struct route_table
*table
;
466 struct route_node
*rn
;
467 struct route_entry
*match
= NULL
;
470 table
= zebra_vrf_table(afi
, safi
, vrf_id
);
474 memset(&p
, 0, sizeof(p
));
477 p
.u
.prefix4
= addr
->ipv4
;
478 p
.prefixlen
= IPV4_MAX_BITLEN
;
480 p
.u
.prefix6
= addr
->ipv6
;
481 p
.prefixlen
= IPV6_MAX_BITLEN
;
484 rn
= route_node_match(table
, &p
);
489 route_unlock_node(rn
);
491 dest
= rib_dest_from_rnode(rn
);
492 if (dest
&& dest
->selected_fib
493 && !CHECK_FLAG(dest
->selected_fib
->status
,
494 ROUTE_ENTRY_REMOVED
))
495 match
= dest
->selected_fib
;
497 /* If there is no selected route or matched route is EGP, go up
502 } while (rn
&& rn
->info
== NULL
);
506 if (match
->type
!= ZEBRA_ROUTE_CONNECT
) {
507 if (!CHECK_FLAG(match
->status
,
508 ROUTE_ENTRY_INSTALLED
))
520 struct route_entry
*rib_match_multicast(afi_t afi
, vrf_id_t vrf_id
,
522 struct route_node
**rn_out
)
524 struct route_entry
*re
= NULL
, *mre
= NULL
, *ure
= NULL
;
525 struct route_node
*m_rn
= NULL
, *u_rn
= NULL
;
527 switch (zrouter
.ipv4_multicast_mode
) {
528 case MCAST_MRIB_ONLY
:
529 return rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, rn_out
);
530 case MCAST_URIB_ONLY
:
531 return rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, rn_out
);
532 case MCAST_NO_CONFIG
:
533 case MCAST_MIX_MRIB_FIRST
:
534 re
= mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
536 re
= ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
,
539 case MCAST_MIX_DISTANCE
:
540 mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
541 ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, &u_rn
);
543 re
= ure
->distance
< mre
->distance
? ure
: mre
;
549 case MCAST_MIX_PFXLEN
:
550 mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
551 ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, &u_rn
);
553 re
= u_rn
->p
.prefixlen
> m_rn
->p
.prefixlen
? ure
: mre
;
562 *rn_out
= (re
== mre
) ? m_rn
: u_rn
;
564 if (IS_ZEBRA_DEBUG_RIB
) {
566 inet_ntop(afi
== AFI_IP
? AF_INET
: AF_INET6
, gaddr
, buf
,
569 zlog_debug("%s: %s: %pRN vrf: %s(%u) found %s, using %s",
570 __func__
, buf
, (re
== mre
) ? m_rn
: u_rn
,
571 vrf_id_to_name(vrf_id
), vrf_id
,
572 mre
? (ure
? "MRIB+URIB" : "MRIB")
573 : ure
? "URIB" : "nothing",
574 re
== ure
? "URIB" : re
== mre
? "MRIB" : "none");
579 struct route_entry
*rib_lookup_ipv4(struct prefix_ipv4
*p
, vrf_id_t vrf_id
)
581 struct route_table
*table
;
582 struct route_node
*rn
;
583 struct route_entry
*match
= NULL
;
587 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
591 rn
= route_node_lookup(table
, (struct prefix
*)p
);
593 /* No route for this prefix. */
598 route_unlock_node(rn
);
599 dest
= rib_dest_from_rnode(rn
);
601 if (dest
&& dest
->selected_fib
602 && !CHECK_FLAG(dest
->selected_fib
->status
, ROUTE_ENTRY_REMOVED
))
603 match
= dest
->selected_fib
;
608 if (match
->type
== ZEBRA_ROUTE_CONNECT
)
611 if (CHECK_FLAG(match
->status
, ROUTE_ENTRY_INSTALLED
))
618 * Is this RIB labeled-unicast? It must be of type BGP and all paths
619 * (nexthops) must have a label.
621 int zebra_rib_labeled_unicast(struct route_entry
*re
)
623 struct nexthop
*nexthop
= NULL
;
625 if (re
->type
!= ZEBRA_ROUTE_BGP
)
628 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
629 if (!nexthop
->nh_label
|| !nexthop
->nh_label
->num_labels
)
635 /* Update flag indicates whether this is a "replace" or not. Currently, this
636 * is only used for IPv4.
638 void rib_install_kernel(struct route_node
*rn
, struct route_entry
*re
,
639 struct route_entry
*old
)
641 struct nexthop
*nexthop
;
642 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
643 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
644 const struct prefix
*p
, *src_p
;
645 enum zebra_dplane_result ret
;
647 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
649 srcdest_rnode_prefixes(rn
, &p
, &src_p
);
651 if (info
->safi
!= SAFI_UNICAST
) {
652 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
653 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
659 * Install the resolved nexthop object first.
661 zebra_nhg_install_kernel(re
->nhe
);
664 * If this is a replace to a new RE let the originator of the RE
665 * know that they've lost
667 if (old
&& (old
!= re
) && (old
->type
!= re
->type
))
668 zsend_route_notify_owner(rn
, old
, ZAPI_ROUTE_BETTER_ADMIN_WON
,
669 info
->afi
, info
->safi
);
671 /* Update fib selection */
672 dest
->selected_fib
= re
;
675 * Make sure we update the FPM any time we send new information to
678 hook_call(rib_update
, rn
, "installing in kernel");
680 /* Send add or update */
682 ret
= dplane_route_update(rn
, re
, old
);
684 ret
= dplane_route_add(rn
, re
);
687 case ZEBRA_DPLANE_REQUEST_QUEUED
:
688 SET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
691 SET_FLAG(old
->status
, ROUTE_ENTRY_QUEUED
);
692 SET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
694 /* Free old FIB nexthop group */
695 UNSET_FLAG(old
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
696 if (old
->fib_ng
.nexthop
) {
697 nexthops_free(old
->fib_ng
.nexthop
);
698 old
->fib_ng
.nexthop
= NULL
;
703 zvrf
->installs_queued
++;
705 case ZEBRA_DPLANE_REQUEST_FAILURE
:
707 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
708 "%u:%u:%pRN: Failed to enqueue dataplane install",
709 re
->vrf_id
, re
->table
, rn
);
712 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
721 /* Uninstall the route from kernel. */
722 void rib_uninstall_kernel(struct route_node
*rn
, struct route_entry
*re
)
724 struct nexthop
*nexthop
;
725 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
726 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
728 if (info
->safi
!= SAFI_UNICAST
) {
729 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
730 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
731 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
736 * Make sure we update the FPM any time we send new information to
739 hook_call(rib_update
, rn
, "uninstalling from kernel");
741 switch (dplane_route_delete(rn
, re
)) {
742 case ZEBRA_DPLANE_REQUEST_QUEUED
:
744 zvrf
->removals_queued
++;
746 case ZEBRA_DPLANE_REQUEST_FAILURE
:
747 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
748 "%u:%pRN: Failed to enqueue dataplane uninstall",
751 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
761 * rib_can_delete_dest
763 * Returns true if the given dest can be deleted from the table.
765 static int rib_can_delete_dest(rib_dest_t
*dest
)
767 if (re_list_first(&dest
->routes
)) {
772 * Unresolved rnh's are stored on the default route's list
774 * dest->rnode can also be the source prefix node in an
775 * ipv6 sourcedest table. Fortunately the prefix of a
776 * source prefix node can never be the default prefix.
778 if (is_default_prefix(&dest
->rnode
->p
))
782 * Don't delete the dest if we have to update the FPM about this
785 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_FPM
)
786 || CHECK_FLAG(dest
->flags
, RIB_DEST_SENT_TO_FPM
))
792 void zebra_rib_evaluate_rn_nexthops(struct route_node
*rn
, uint32_t seq
,
795 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
799 * We are storing the rnh's associated withb
800 * the tracked nexthop as a list of the rn's.
801 * Unresolved rnh's are placed at the top
802 * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
803 * As such for each rn we need to walk up the tree
804 * and see if any rnh's need to see if they
805 * would match a more specific route
808 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
810 "%s: %pRN Being examined for Nexthop Tracking Count: %zd",
812 dest
? rnh_list_count(&dest
->nht
) : 0);
814 if (rt_delete
&& (!dest
|| !rnh_list_count(&dest
->nht
))) {
815 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
816 zlog_debug("%pRN has no tracking NHTs. Bailing",
823 dest
= rib_dest_from_rnode(rn
);
827 * If we have any rnh's stored in the nht list
828 * then we know that this route node was used for
829 * nht resolution and as such we need to call the
830 * nexthop tracking evaluation code
832 frr_each_safe(rnh_list
, &dest
->nht
, rnh
) {
833 struct zebra_vrf
*zvrf
=
834 zebra_vrf_lookup_by_id(rnh
->vrf_id
);
835 struct prefix
*p
= &rnh
->node
->p
;
837 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
839 "%s(%u):%pRN has Nexthop(%pRN) depending on it, evaluating %u:%u",
840 zvrf_name(zvrf
), zvrf_id(zvrf
), rn
,
841 rnh
->node
, seq
, rnh
->seqno
);
844 * If we have evaluated this node on this pass
845 * already, due to following the tree up
846 * then we know that we can move onto the next
849 * Additionally we call zebra_evaluate_rnh
850 * when we gc the dest. In this case we know
851 * that there must be no other re's where
852 * we were originally as such we know that
853 * that sequence number is ok to respect.
855 if (rnh
->seqno
== seq
) {
856 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
858 " Node processed and moved already");
863 zebra_evaluate_rnh(zvrf
, family2afi(p
->family
), 0, p
,
869 dest
= rib_dest_from_rnode(rn
);
876 * Garbage collect the rib dest corresponding to the given route node
879 * Returns true if the dest was deleted, false otherwise.
881 int rib_gc_dest(struct route_node
*rn
)
885 dest
= rib_dest_from_rnode(rn
);
889 if (!rib_can_delete_dest(dest
))
892 if (IS_ZEBRA_DEBUG_RIB
) {
893 struct zebra_vrf
*zvrf
;
895 zvrf
= rib_dest_vrf(dest
);
896 rnode_debug(rn
, zvrf_id(zvrf
), "removing dest from table");
899 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
903 rnh_list_fini(&dest
->nht
);
904 XFREE(MTYPE_RIB_DEST
, dest
);
908 * Release the one reference that we keep on the route node.
910 route_unlock_node(rn
);
914 void zebra_rtable_node_cleanup(struct route_table
*table
,
915 struct route_node
*node
)
917 struct route_entry
*re
, *next
;
919 RNODE_FOREACH_RE_SAFE (node
, re
, next
) {
920 rib_unlink(node
, re
);
924 rib_dest_t
*dest
= node
->info
;
926 /* Remove from update queue of FPM module */
927 hook_call(rib_shutdown
, node
);
929 rnh_list_fini(&dest
->nht
);
930 XFREE(MTYPE_RIB_DEST
, node
->info
);
934 static void rib_process_add_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
935 struct route_entry
*new)
937 hook_call(rib_update
, rn
, "new route selected");
939 /* Update real nexthop. This may actually determine if nexthop is active
941 if (!nexthop_group_active_nexthop_num(&(new->nhe
->nhg
))) {
942 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
946 if (IS_ZEBRA_DEBUG_RIB
)
947 zlog_debug("%s(%u:%u):%pRN: Adding route rn %p, re %p (%s)",
948 zvrf_name(zvrf
), zvrf_id(zvrf
), new->table
, rn
, rn
,
949 new, zebra_route_string(new->type
));
951 /* If labeled-unicast route, install transit LSP. */
952 if (zebra_rib_labeled_unicast(new))
953 zebra_mpls_lsp_install(zvrf
, rn
, new);
955 rib_install_kernel(rn
, new, NULL
);
957 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
960 static void rib_process_del_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
961 struct route_entry
*old
)
963 hook_call(rib_update
, rn
, "removing existing route");
965 /* Uninstall from kernel. */
966 if (IS_ZEBRA_DEBUG_RIB
)
967 zlog_debug("%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s)",
968 zvrf_name(zvrf
), zvrf_id(zvrf
), old
->table
, rn
, rn
,
969 old
, zebra_route_string(old
->type
));
971 /* If labeled-unicast route, uninstall transit LSP. */
972 if (zebra_rib_labeled_unicast(old
))
973 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
975 rib_uninstall_kernel(rn
, old
);
977 /* Update nexthop for route, reset changed flag. */
978 /* Note: this code also handles the Linux case when an interface goes
979 * down, causing the kernel to delete routes without sending DELROUTE
982 if (RIB_KERNEL_ROUTE(old
))
983 SET_FLAG(old
->status
, ROUTE_ENTRY_REMOVED
);
985 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
988 static void rib_process_update_fib(struct zebra_vrf
*zvrf
,
989 struct route_node
*rn
,
990 struct route_entry
*old
,
991 struct route_entry
*new)
996 * We have to install or update if a new route has been selected or
997 * something has changed.
999 if (new != old
|| CHECK_FLAG(new->status
, ROUTE_ENTRY_CHANGED
)) {
1000 hook_call(rib_update
, rn
, "updating existing route");
1002 /* Update the nexthop; we could determine here that nexthop is
1004 if (nexthop_group_active_nexthop_num(&(new->nhe
->nhg
)))
1007 /* If nexthop is active, install the selected route, if
1009 * the install succeeds, cleanup flags for prior route, if
1014 if (IS_ZEBRA_DEBUG_RIB
) {
1017 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s) old %p (%s)",
1018 zvrf_name(zvrf
), zvrf_id(zvrf
),
1019 new->table
, rn
, rn
, new,
1020 zebra_route_string(new->type
),
1022 zebra_route_string(old
->type
));
1025 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s)",
1026 zvrf_name(zvrf
), zvrf_id(zvrf
),
1027 new->table
, rn
, rn
, new,
1028 zebra_route_string(new->type
));
1031 /* If labeled-unicast route, uninstall transit LSP. */
1032 if (zebra_rib_labeled_unicast(old
))
1033 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1036 * Non-system route should be installed.
1037 * If labeled-unicast route, install transit
1040 if (zebra_rib_labeled_unicast(new))
1041 zebra_mpls_lsp_install(zvrf
, rn
, new);
1043 rib_install_kernel(rn
, new, old
);
1047 * If nexthop for selected route is not active or install
1049 * may need to uninstall and delete for redistribution.
1052 if (IS_ZEBRA_DEBUG_RIB
) {
1055 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
1056 zvrf_name(zvrf
), zvrf_id(zvrf
),
1057 new->table
, rn
, rn
, new,
1058 zebra_route_string(new->type
),
1060 zebra_route_string(old
->type
));
1063 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) - nexthop inactive",
1064 zvrf_name(zvrf
), zvrf_id(zvrf
),
1065 new->table
, rn
, rn
, new,
1066 zebra_route_string(new->type
));
1070 * When we have gotten to this point
1071 * the new route entry has no nexthops
1072 * that are usable and as such we need
1073 * to remove the old route, but only
1074 * if we were the one who installed
1077 if (!RIB_SYSTEM_ROUTE(old
)) {
1078 /* If labeled-unicast route, uninstall transit
1080 if (zebra_rib_labeled_unicast(old
))
1081 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1083 rib_uninstall_kernel(rn
, old
);
1088 * Same route selected; check if in the FIB and if not,
1089 * re-install. This is housekeeping code to deal with
1090 * race conditions in kernel with linux netlink reporting
1091 * interface up before IPv4 or IPv6 protocol is ready
1094 if (!CHECK_FLAG(new->status
, ROUTE_ENTRY_INSTALLED
) ||
1095 RIB_SYSTEM_ROUTE(new))
1096 rib_install_kernel(rn
, new, NULL
);
1099 /* Update prior route. */
1101 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
1103 /* Clear changed flag. */
1104 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
1107 /* Check if 'alternate' RIB entry is better than 'current'. */
1108 static struct route_entry
*rib_choose_best(struct route_entry
*current
,
1109 struct route_entry
*alternate
)
1111 if (current
== NULL
)
1114 /* filter route selection in following order:
1115 * - connected beats other types
1116 * - if both connected, loopback or vrf wins
1117 * - lower distance beats higher
1118 * - lower metric beats higher for equal distance
1119 * - last, hence oldest, route wins tie break.
1122 /* Connected routes. Check to see if either are a vrf
1123 * or loopback interface. If not, pick the last connected
1124 * route of the set of lowest metric connected routes.
1126 if (alternate
->type
== ZEBRA_ROUTE_CONNECT
) {
1127 if (current
->type
!= ZEBRA_ROUTE_CONNECT
)
1130 /* both are connected. are either loop or vrf? */
1131 struct nexthop
*nexthop
= NULL
;
1133 for (ALL_NEXTHOPS(alternate
->nhe
->nhg
, nexthop
)) {
1134 struct interface
*ifp
= if_lookup_by_index(
1135 nexthop
->ifindex
, alternate
->vrf_id
);
1137 if (ifp
&& if_is_loopback(ifp
))
1141 for (ALL_NEXTHOPS(current
->nhe
->nhg
, nexthop
)) {
1142 struct interface
*ifp
= if_lookup_by_index(
1143 nexthop
->ifindex
, current
->vrf_id
);
1145 if (ifp
&& if_is_loopback(ifp
))
1149 /* Neither are loop or vrf so pick best metric */
1150 if (alternate
->metric
<= current
->metric
)
1156 if (current
->type
== ZEBRA_ROUTE_CONNECT
)
1159 /* higher distance loses */
1160 if (alternate
->distance
< current
->distance
)
1162 if (current
->distance
< alternate
->distance
)
1165 /* metric tie-breaks equal distance */
1166 if (alternate
->metric
<= current
->metric
)
1172 /* Core function for processing routing information base. */
1173 static void rib_process(struct route_node
*rn
)
1175 struct route_entry
*re
;
1176 struct route_entry
*next
;
1177 struct route_entry
*old_selected
= NULL
;
1178 struct route_entry
*new_selected
= NULL
;
1179 struct route_entry
*old_fib
= NULL
;
1180 struct route_entry
*new_fib
= NULL
;
1181 struct route_entry
*best
= NULL
;
1183 struct zebra_vrf
*zvrf
= NULL
;
1186 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1190 dest
= rib_dest_from_rnode(rn
);
1192 * We have an enqueued node with nothing to process here
1193 * let's just finish up and return;
1198 zvrf
= rib_dest_vrf(dest
);
1199 vrf_id
= zvrf_id(zvrf
);
1201 vrf
= vrf_lookup_by_id(vrf_id
);
1204 * we can have rn's that have a NULL info pointer
1205 * (dest). As such let's not let the deref happen
1206 * additionally we know RNODE_FOREACH_RE_SAFE
1207 * will not iterate so we are ok.
1209 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1210 struct route_entry
*re
= re_list_first(&dest
->routes
);
1212 zlog_debug("%s(%u:%u):%pRN: Processing rn %p",
1213 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
,
1217 old_fib
= dest
->selected_fib
;
1219 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1220 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1221 char flags_buf
[128];
1222 char status_buf
[128];
1225 "%s(%u:%u):%pRN: Examine re %p (%s) status: %sflags: %sdist %d metric %d",
1226 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
, re
,
1227 zebra_route_string(re
->type
),
1228 _dump_re_status(re
, status_buf
,
1229 sizeof(status_buf
)),
1230 zclient_dump_route_flags(re
->flags
, flags_buf
,
1232 re
->distance
, re
->metric
);
1235 /* Currently selected re. */
1236 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1237 assert(old_selected
== NULL
);
1241 /* Skip deleted entries from selection */
1242 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1246 * If the route entry has changed, verify/resolve
1247 * the nexthops associated with the entry.
1249 * In any event if we have nexthops that are not active
1250 * then we cannot use this particular route entry so
1253 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
)) {
1254 if (!nexthop_active_update(rn
, re
)) {
1255 const struct prefix
*p
;
1256 struct rib_table_info
*info
;
1258 if (re
->type
== ZEBRA_ROUTE_TABLE
) {
1259 /* XXX: HERE BE DRAGONS!!!!!
1260 * In all honesty, I have not yet
1261 * figured out what this part does or
1262 * why the ROUTE_ENTRY_CHANGED test
1263 * above is correct or why we need to
1264 * delete a route here, and also not
1265 * whether this concerns both selected
1266 * and fib route, or only selected
1269 * This entry was denied by the 'ip
1271 * table' route-map, we need to delete
1273 if (re
!= old_selected
) {
1274 if (IS_ZEBRA_DEBUG_RIB
)
1276 "%s: %s(%u):%pRN: imported via import-table but denied by the ip protocol table route-map",
1284 SET_FLAG(re
->status
,
1285 ROUTE_ENTRY_REMOVED
);
1288 info
= srcdest_rnode_table_info(rn
);
1289 srcdest_rnode_prefixes(rn
, &p
, NULL
);
1290 zsend_route_notify_owner(
1291 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
1292 info
->afi
, info
->safi
);
1297 * If the re has not changed and the nhg we have is
1298 * not usable, then we cannot use this route entry
1299 * for consideration, as that the route will just
1300 * not install if it is selected.
1302 if (!nexthop_group_active_nexthop_num(&re
->nhe
->nhg
))
1306 /* Infinite distance. */
1307 if (re
->distance
== DISTANCE_INFINITY
&&
1308 re
->type
!= ZEBRA_ROUTE_KERNEL
) {
1309 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1313 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_FIB_OVERRIDE
)) {
1314 best
= rib_choose_best(new_fib
, re
);
1315 if (new_fib
&& best
!= new_fib
)
1316 UNSET_FLAG(new_fib
->status
,
1317 ROUTE_ENTRY_CHANGED
);
1320 best
= rib_choose_best(new_selected
, re
);
1321 if (new_selected
&& best
!= new_selected
)
1322 UNSET_FLAG(new_selected
->status
,
1323 ROUTE_ENTRY_CHANGED
);
1324 new_selected
= best
;
1327 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1328 } /* RNODE_FOREACH_RE */
1330 /* If no FIB override route, use the selected route also for FIB */
1331 if (new_fib
== NULL
)
1332 new_fib
= new_selected
;
1334 /* After the cycle is finished, the following pointers will be set:
1335 * old_selected --- RE entry currently having SELECTED
1336 * new_selected --- RE entry that is newly SELECTED
1337 * old_fib --- RE entry currently in kernel FIB
1338 * new_fib --- RE entry that is newly to be in kernel FIB
1340 * new_selected will get SELECTED flag, and is going to be redistributed
1341 * the zclients. new_fib (which can be new_selected) will be installed
1345 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1346 struct route_entry
*entry
;
1348 entry
= old_selected
1353 : new_fib
? new_fib
: NULL
;
1356 "%s(%u:%u):%pRN: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
1357 VRF_LOGNAME(vrf
), vrf_id
, entry
? entry
->table
: 0, rn
,
1358 (void *)old_selected
, (void *)new_selected
,
1359 (void *)old_fib
, (void *)new_fib
);
1362 /* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
1363 * fib == selected */
1364 bool selected_changed
= new_selected
&& CHECK_FLAG(new_selected
->status
,
1365 ROUTE_ENTRY_CHANGED
);
1367 /* Update SELECTED entry */
1368 if (old_selected
!= new_selected
|| selected_changed
) {
1370 if (new_selected
&& new_selected
!= new_fib
)
1371 UNSET_FLAG(new_selected
->status
, ROUTE_ENTRY_CHANGED
);
1374 SET_FLAG(new_selected
->flags
, ZEBRA_FLAG_SELECTED
);
1378 * If we're removing the old entry, we should tell
1379 * redist subscribers about that *if* they aren't
1380 * going to see a redist for the new entry.
1382 if (!new_selected
|| CHECK_FLAG(old_selected
->status
,
1383 ROUTE_ENTRY_REMOVED
))
1384 redistribute_delete(rn
, old_selected
,
1387 if (old_selected
!= new_selected
)
1388 UNSET_FLAG(old_selected
->flags
,
1389 ZEBRA_FLAG_SELECTED
);
1393 /* Update fib according to selection results */
1394 if (new_fib
&& old_fib
)
1395 rib_process_update_fib(zvrf
, rn
, old_fib
, new_fib
);
1397 rib_process_add_fib(zvrf
, rn
, new_fib
);
1399 rib_process_del_fib(zvrf
, rn
, old_fib
);
1401 /* Remove all RE entries queued for removal */
1402 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1403 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1404 if (IS_ZEBRA_DEBUG_RIB
) {
1405 rnode_debug(rn
, vrf_id
, "rn %p, removing re %p",
1406 (void *)rn
, (void *)re
);
1413 * Check if the dest can be deleted now.
1418 static void zebra_rib_evaluate_mpls(struct route_node
*rn
)
1420 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
1421 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
1426 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_LSPS
)) {
1427 if (IS_ZEBRA_DEBUG_MPLS
)
1429 "%s(%u): Scheduling all LSPs upon RIB completion",
1430 zvrf_name(zvrf
), zvrf_id(zvrf
));
1431 zebra_mpls_lsp_schedule(zvrf
);
1432 mpls_unmark_lsps_for_processing(rn
);
1437 * Utility to match route with dplane context data
1439 static bool rib_route_match_ctx(const struct route_entry
*re
,
1440 const struct zebra_dplane_ctx
*ctx
,
1443 bool result
= false;
1447 * In 'update' case, we test info about the 'previous' or
1450 if ((re
->type
== dplane_ctx_get_old_type(ctx
)) &&
1451 (re
->instance
== dplane_ctx_get_old_instance(ctx
))) {
1454 /* We use an extra test for statics, and another for
1457 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1458 (re
->distance
!= dplane_ctx_get_old_distance(ctx
) ||
1459 re
->tag
!= dplane_ctx_get_old_tag(ctx
))) {
1461 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1463 dplane_ctx_get_old_metric(ctx
)) {
1470 * Ordinary, single-route case using primary context info
1472 if ((dplane_ctx_get_op(ctx
) != DPLANE_OP_ROUTE_DELETE
) &&
1473 CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1474 /* Skip route that's been deleted */
1478 if ((re
->type
== dplane_ctx_get_type(ctx
)) &&
1479 (re
->instance
== dplane_ctx_get_instance(ctx
))) {
1482 /* We use an extra test for statics, and another for
1485 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1486 (re
->distance
!= dplane_ctx_get_distance(ctx
) ||
1487 re
->tag
!= dplane_ctx_get_tag(ctx
))) {
1489 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1490 re
->metric
!= dplane_ctx_get_metric(ctx
)) {
1492 } else if (re
->type
== ZEBRA_ROUTE_CONNECT
) {
1493 result
= nexthop_group_equal_no_recurse(
1494 &re
->nhe
->nhg
, dplane_ctx_get_ng(ctx
));
1503 static void zebra_rib_fixup_system(struct route_node
*rn
)
1505 struct route_entry
*re
;
1507 RNODE_FOREACH_RE(rn
, re
) {
1508 struct nexthop
*nhop
;
1510 if (!RIB_SYSTEM_ROUTE(re
))
1513 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1516 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
1517 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
1518 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
1520 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nhop
)) {
1521 if (CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1524 SET_FLAG(nhop
->flags
, NEXTHOP_FLAG_FIB
);
1529 /* Route comparison logic, with various special cases. */
1530 static bool rib_compare_routes(const struct route_entry
*re1
,
1531 const struct route_entry
*re2
)
1533 if (re1
->type
!= re2
->type
)
1536 if (re1
->instance
!= re2
->instance
)
1539 if (re1
->type
== ZEBRA_ROUTE_KERNEL
&& re1
->metric
!= re2
->metric
)
1542 if (CHECK_FLAG(re1
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
1543 re1
->distance
!= re2
->distance
)
1546 /* We support multiple connected routes: this supports multiple
1547 * v6 link-locals, and we also support multiple addresses in the same
1548 * subnet on a single interface.
1550 if (re1
->type
!= ZEBRA_ROUTE_CONNECT
)
1557 * Compare nexthop lists from a route and a dplane context; test whether
1558 * the list installed in the FIB matches the route's list.
1559 * Set 'changed_p' to 'true' if there were changes to the route's
1560 * installed nexthops.
1562 * Return 'false' if any ACTIVE route nexthops are not mentioned in the FIB
1565 static bool rib_update_nhg_from_ctx(struct nexthop_group
*re_nhg
,
1566 const struct nexthop_group
*ctx_nhg
,
1569 bool matched_p
= true;
1570 struct nexthop
*nexthop
, *ctx_nexthop
;
1572 /* Get the first `installed` one to check against.
1573 * If the dataplane doesn't set these to be what was actually installed,
1574 * it will just be whatever was in re->nhe->nhg?
1576 ctx_nexthop
= ctx_nhg
->nexthop
;
1578 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
1579 || !CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1580 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1582 for (ALL_NEXTHOPS_PTR(re_nhg
, nexthop
)) {
1584 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1587 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1590 /* Check for a FIB nexthop corresponding to the RIB nexthop */
1591 if (!nexthop_same(ctx_nexthop
, nexthop
)) {
1592 /* If the FIB doesn't know about the nexthop,
1593 * it's not installed
1595 if (IS_ZEBRA_DEBUG_RIB_DETAILED
||
1596 IS_ZEBRA_DEBUG_NHG_DETAIL
) {
1597 zlog_debug("%s: no ctx match for rib nh %pNHv %s",
1599 (CHECK_FLAG(nexthop
->flags
,
1605 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1608 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1610 /* Keep checking nexthops */
1614 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1615 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1616 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1617 zlog_debug("%s: rib nh %pNHv -> installed",
1623 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1625 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1626 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1627 zlog_debug("%s: rib nh %pNHv -> uninstalled",
1633 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1636 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1643 * Update a route from a dplane context. This consolidates common code
1644 * that can be used in processing of results from FIB updates, and in
1645 * async notification processing.
1646 * The return is 'true' if the installed nexthops changed; 'false' otherwise.
1648 static bool rib_update_re_from_ctx(struct route_entry
*re
,
1649 struct route_node
*rn
,
1650 struct zebra_dplane_ctx
*ctx
)
1652 struct nexthop
*nexthop
;
1654 const struct nexthop_group
*ctxnhg
;
1655 struct nexthop_group
*re_nhg
;
1656 bool is_selected
= false; /* Is 're' currently the selected re? */
1657 bool changed_p
= false; /* Change to nexthops? */
1661 vrf
= vrf_lookup_by_id(re
->vrf_id
);
1663 dest
= rib_dest_from_rnode(rn
);
1665 is_selected
= (re
== dest
->selected_fib
);
1667 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1668 zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p",
1669 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1670 (is_selected
? "" : "NOT "), re
);
1672 /* Update zebra's nexthop FIB flag for each nexthop that was installed.
1673 * If the installed set differs from the set requested by the rib/owner,
1674 * we use the fib-specific nexthop-group to record the actual FIB
1678 ctxnhg
= dplane_ctx_get_ng(ctx
);
1680 /* Check route's fib group and incoming notif group for equivalence.
1682 * Let's assume the nexthops are ordered here to save time.
1684 /* TODO -- this isn't testing or comparing the FIB flags; we should
1685 * do a more explicit loop, checking the incoming notification's flags.
1687 if (re
->fib_ng
.nexthop
&& ctxnhg
->nexthop
&&
1688 nexthop_group_equal(&re
->fib_ng
, ctxnhg
))
1691 /* If the new FIB set matches the existing FIB set, we're done. */
1693 if (IS_ZEBRA_DEBUG_RIB
)
1695 "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change",
1696 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1699 } else if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
)) {
1701 * Free stale fib list and move on to check the rib nhg.
1703 if (IS_ZEBRA_DEBUG_RIB
)
1705 "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg",
1706 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1707 nexthops_free(re
->fib_ng
.nexthop
);
1708 re
->fib_ng
.nexthop
= NULL
;
1710 UNSET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1712 /* Note that the installed nexthops have changed */
1715 if (IS_ZEBRA_DEBUG_RIB
)
1717 "%s(%u:%u):%pRN update_from_ctx(): no fib nhg",
1718 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1722 * Compare with the rib nexthop group. The comparison here is different:
1723 * the RIB group may be a superset of the list installed in the FIB. We
1724 * walk the RIB group, looking for the 'installable' candidate
1725 * nexthops, and then check those against the set
1726 * that is actually installed.
1728 * Assume nexthops are ordered here as well.
1731 /* If nothing is installed, we can skip some of the checking/comparison
1734 if (ctxnhg
->nexthop
== NULL
) {
1739 matched
= rib_update_nhg_from_ctx(&(re
->nhe
->nhg
), ctxnhg
, &changed_p
);
1741 /* If all nexthops were processed, we're done */
1743 if (IS_ZEBRA_DEBUG_RIB
)
1745 "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'",
1746 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1747 (changed_p
? "true" : "false"));
1753 /* FIB nexthop set differs from the RIB set:
1754 * create a fib-specific nexthop-group
1756 if (IS_ZEBRA_DEBUG_RIB
)
1758 "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s",
1759 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1760 (changed_p
? "true" : "false"),
1761 ctxnhg
->nexthop
!= NULL
? "" : " (empty)");
1763 /* Set the flag about the dedicated fib list */
1764 if (zrouter
.asic_notification_nexthop_control
) {
1765 SET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1766 if (ctxnhg
->nexthop
)
1767 copy_nexthops(&(re
->fib_ng
.nexthop
), ctxnhg
->nexthop
,
1774 * Check the status of the route's backup nexthops, if any.
1775 * The logic for backups is somewhat different: if any backup is
1776 * installed, a new fib nhg will be attached to the route.
1778 re_nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1780 goto done
; /* No backup nexthops */
1782 /* First check the route's 'fib' list of backups, if it's present
1783 * from some previous event.
1785 re_nhg
= &re
->fib_backup_ng
;
1786 ctxnhg
= dplane_ctx_get_backup_ng(ctx
);
1789 if (re_nhg
->nexthop
&& ctxnhg
&& nexthop_group_equal(re_nhg
, ctxnhg
))
1792 /* If the new FIB set matches an existing FIB set, we're done. */
1794 if (IS_ZEBRA_DEBUG_RIB
)
1796 "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change",
1797 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1800 } else if (re
->fib_backup_ng
.nexthop
) {
1802 * Free stale fib backup list and move on to check
1803 * the route's backups.
1805 if (IS_ZEBRA_DEBUG_RIB
)
1807 "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg",
1808 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1809 nexthops_free(re
->fib_backup_ng
.nexthop
);
1810 re
->fib_backup_ng
.nexthop
= NULL
;
1812 /* Note that the installed nexthops have changed */
1815 if (IS_ZEBRA_DEBUG_RIB
)
1817 "%s(%u):%pRN update_from_ctx(): no fib backup nhg",
1818 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1822 * If a FIB backup nexthop set exists, attach a copy
1823 * to the route if any backup is installed
1825 if (ctxnhg
&& ctxnhg
->nexthop
) {
1827 for (ALL_NEXTHOPS_PTR(ctxnhg
, nexthop
)) {
1828 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1832 /* If no installed backups, we're done */
1833 if (nexthop
== NULL
)
1836 if (IS_ZEBRA_DEBUG_RIB
)
1838 "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg",
1839 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
,
1840 (changed_p
? "true" : "false"));
1842 copy_nexthops(&(re
->fib_backup_ng
.nexthop
), ctxnhg
->nexthop
,
1852 * Helper to locate a zebra route-node from a dplane context. This is used
1853 * when processing dplane results, e.g. Note well: the route-node is returned
1854 * with a ref held - route_unlock_node() must be called eventually.
1856 struct route_node
*rib_find_rn_from_ctx(const struct zebra_dplane_ctx
*ctx
)
1858 struct route_table
*table
= NULL
;
1859 struct route_node
*rn
= NULL
;
1860 const struct prefix
*dest_pfx
, *src_pfx
;
1862 /* Locate rn and re(s) from ctx */
1864 table
= zebra_vrf_lookup_table_with_table_id(
1865 dplane_ctx_get_afi(ctx
), dplane_ctx_get_safi(ctx
),
1866 dplane_ctx_get_vrf(ctx
), dplane_ctx_get_table(ctx
));
1867 if (table
== NULL
) {
1868 if (IS_ZEBRA_DEBUG_DPLANE
) {
1870 "Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u)",
1871 dplane_ctx_get_afi(ctx
),
1872 dplane_ctx_get_safi(ctx
),
1873 vrf_id_to_name(dplane_ctx_get_vrf(ctx
)),
1874 dplane_ctx_get_vrf(ctx
));
1879 dest_pfx
= dplane_ctx_get_dest(ctx
);
1880 src_pfx
= dplane_ctx_get_src(ctx
);
1882 rn
= srcdest_rnode_get(table
, dest_pfx
,
1883 src_pfx
? (struct prefix_ipv6
*)src_pfx
: NULL
);
1892 * Route-update results processing after async dataplane update.
1894 static void rib_process_result(struct zebra_dplane_ctx
*ctx
)
1896 struct zebra_vrf
*zvrf
= NULL
;
1898 struct route_node
*rn
= NULL
;
1899 struct route_entry
*re
= NULL
, *old_re
= NULL
, *rib
;
1900 bool is_update
= false;
1901 enum dplane_op_e op
;
1902 enum zebra_dplane_result status
;
1905 bool fib_changed
= false;
1906 struct rib_table_info
*info
;
1907 bool rt_delete
= false;
1909 zvrf
= zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
1910 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
1912 /* Locate rn and re(s) from ctx */
1913 rn
= rib_find_rn_from_ctx(ctx
);
1915 if (IS_ZEBRA_DEBUG_DPLANE
) {
1917 "Failed to process dplane results: no route for %s(%u):%pRN",
1918 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
), rn
);
1923 dest
= rib_dest_from_rnode(rn
);
1924 info
= srcdest_rnode_table_info(rn
);
1926 op
= dplane_ctx_get_op(ctx
);
1927 status
= dplane_ctx_get_status(ctx
);
1929 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1931 "%s(%u:%u):%pRN Processing dplane result ctx %p, op %s result %s",
1932 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
1933 dplane_ctx_get_table(ctx
), rn
, ctx
, dplane_op2str(op
),
1934 dplane_res2str(status
));
1937 * Update is a bit of a special case, where we may have both old and new
1938 * routes to post-process.
1940 is_update
= dplane_ctx_is_update(ctx
);
1943 * Take a pass through the routes, look for matches with the context
1946 RNODE_FOREACH_RE(rn
, rib
) {
1949 if (rib_route_match_ctx(rib
, ctx
, false))
1953 /* Check for old route match */
1954 if (is_update
&& (old_re
== NULL
)) {
1955 if (rib_route_match_ctx(rib
, ctx
, true /*is_update*/))
1959 /* Have we found the routes we need to work on? */
1960 if (re
&& ((!is_update
|| old_re
)))
1964 seq
= dplane_ctx_get_seq(ctx
);
1967 * Check sequence number(s) to detect stale results before continuing
1970 if (re
->dplane_sequence
!= seq
) {
1971 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1973 "%s(%u):%pRN Stale dplane result for re %p",
1975 dplane_ctx_get_vrf(ctx
), rn
, re
);
1977 if (!zrouter
.asic_offloaded
||
1978 (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
) ||
1979 CHECK_FLAG(re
->flags
,
1980 ZEBRA_FLAG_OFFLOAD_FAILED
))) {
1981 UNSET_FLAG(re
->status
,
1982 ROUTE_ENTRY_ROUTE_REPLACING
);
1983 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
1989 if (old_re
->dplane_sequence
!= dplane_ctx_get_old_seq(ctx
)) {
1990 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1992 "%s(%u:%u):%pRN Stale dplane result for old_re %p",
1994 dplane_ctx_get_vrf(ctx
), old_re
->table
,
1997 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_QUEUED
);
2001 case DPLANE_OP_ROUTE_INSTALL
:
2002 case DPLANE_OP_ROUTE_UPDATE
:
2003 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
2005 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2006 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2009 * On an update operation from the same route type
2010 * context retrieval currently has no way to know
2011 * which was the old and which was the new.
2012 * So don't unset our flags that we just set.
2013 * We know redistribution is ok because the
2014 * old_re in this case is used for nothing
2015 * more than knowing whom to contact if necessary.
2017 if (old_re
&& old_re
!= re
) {
2018 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2019 UNSET_FLAG(old_re
->status
,
2020 ROUTE_ENTRY_INSTALLED
);
2023 /* Update zebra route based on the results in
2024 * the context struct.
2028 rib_update_re_from_ctx(re
, rn
, ctx
);
2031 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
2033 "%s(%u:%u):%pRN no fib change for re",
2035 dplane_ctx_get_vrf(ctx
),
2036 dplane_ctx_get_table(
2041 /* Redistribute if this is the selected re */
2042 if (dest
&& re
== dest
->selected_fib
)
2043 redistribute_update(rn
, re
, old_re
);
2047 * System routes are weird in that they
2048 * allow multiple to be installed that match
2049 * to the same prefix, so after we get the
2050 * result we need to clean them up so that
2051 * we can actually use them.
2053 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2054 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2055 zebra_rib_fixup_system(rn
);
2060 /* Notify route owner */
2061 if (zebra_router_notify_on_ack())
2062 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2065 if (CHECK_FLAG(re
->flags
,
2066 ZEBRA_FLAG_OFFLOADED
))
2067 zsend_route_notify_owner_ctx(
2069 ZAPI_ROUTE_INSTALLED
);
2072 ZEBRA_FLAG_OFFLOAD_FAILED
))
2073 zsend_route_notify_owner_ctx(
2075 ZAPI_ROUTE_FAIL_INSTALL
);
2080 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2081 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2083 SET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2085 zsend_route_notify_owner(
2086 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
2087 info
->afi
, info
->safi
);
2089 zlog_warn("%s(%u:%u):%pRN: Route install failed",
2090 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2091 dplane_ctx_get_table(ctx
), rn
);
2094 case DPLANE_OP_ROUTE_DELETE
:
2097 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2099 * In the delete case, the zebra core datastructs were
2100 * updated (or removed) at the time the delete was issued,
2101 * so we're just notifying the route owner.
2103 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
2105 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2106 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2108 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_REMOVED
);
2114 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2115 zsend_route_notify_owner_ctx(ctx
,
2116 ZAPI_ROUTE_REMOVE_FAIL
);
2118 zlog_warn("%s(%u:%u):%pRN: Route Deletion failure",
2119 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2120 dplane_ctx_get_table(ctx
), rn
);
2124 * System routes are weird in that they
2125 * allow multiple to be installed that match
2126 * to the same prefix, so after we get the
2127 * result we need to clean them up so that
2128 * we can actually use them.
2130 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2131 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2132 zebra_rib_fixup_system(rn
);
2135 case DPLANE_OP_NONE
:
2136 case DPLANE_OP_ROUTE_NOTIFY
:
2137 case DPLANE_OP_NH_INSTALL
:
2138 case DPLANE_OP_NH_UPDATE
:
2139 case DPLANE_OP_NH_DELETE
:
2140 case DPLANE_OP_LSP_INSTALL
:
2141 case DPLANE_OP_LSP_UPDATE
:
2142 case DPLANE_OP_LSP_DELETE
:
2143 case DPLANE_OP_LSP_NOTIFY
:
2144 case DPLANE_OP_PW_INSTALL
:
2145 case DPLANE_OP_PW_UNINSTALL
:
2146 case DPLANE_OP_SYS_ROUTE_ADD
:
2147 case DPLANE_OP_SYS_ROUTE_DELETE
:
2148 case DPLANE_OP_ADDR_INSTALL
:
2149 case DPLANE_OP_ADDR_UNINSTALL
:
2150 case DPLANE_OP_MAC_INSTALL
:
2151 case DPLANE_OP_MAC_DELETE
:
2152 case DPLANE_OP_NEIGH_INSTALL
:
2153 case DPLANE_OP_NEIGH_UPDATE
:
2154 case DPLANE_OP_NEIGH_DELETE
:
2155 case DPLANE_OP_VTEP_ADD
:
2156 case DPLANE_OP_VTEP_DELETE
:
2157 case DPLANE_OP_RULE_ADD
:
2158 case DPLANE_OP_RULE_DELETE
:
2159 case DPLANE_OP_RULE_UPDATE
:
2160 case DPLANE_OP_NEIGH_DISCOVER
:
2161 case DPLANE_OP_BR_PORT_UPDATE
:
2162 case DPLANE_OP_IPTABLE_ADD
:
2163 case DPLANE_OP_IPTABLE_DELETE
:
2164 case DPLANE_OP_IPSET_ADD
:
2165 case DPLANE_OP_IPSET_DELETE
:
2166 case DPLANE_OP_IPSET_ENTRY_ADD
:
2167 case DPLANE_OP_IPSET_ENTRY_DELETE
:
2168 case DPLANE_OP_NEIGH_IP_INSTALL
:
2169 case DPLANE_OP_NEIGH_IP_DELETE
:
2170 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
2171 case DPLANE_OP_GRE_SET
:
2172 case DPLANE_OP_INTF_ADDR_ADD
:
2173 case DPLANE_OP_INTF_ADDR_DEL
:
2174 case DPLANE_OP_INTF_NETCONFIG
:
2175 case DPLANE_OP_INTF_INSTALL
:
2176 case DPLANE_OP_INTF_UPDATE
:
2177 case DPLANE_OP_INTF_DELETE
:
2178 case DPLANE_OP_TC_QDISC_INSTALL
:
2179 case DPLANE_OP_TC_QDISC_UNINSTALL
:
2180 case DPLANE_OP_TC_CLASS_ADD
:
2181 case DPLANE_OP_TC_CLASS_DELETE
:
2182 case DPLANE_OP_TC_CLASS_UPDATE
:
2183 case DPLANE_OP_TC_FILTER_ADD
:
2184 case DPLANE_OP_TC_FILTER_DELETE
:
2185 case DPLANE_OP_TC_FILTER_UPDATE
:
2189 zebra_rib_evaluate_rn_nexthops(rn
, seq
, rt_delete
);
2190 zebra_rib_evaluate_mpls(rn
);
2194 route_unlock_node(rn
);
2198 * Count installed/FIB nexthops
2200 static int rib_count_installed_nh(struct route_entry
*re
)
2203 struct nexthop
*nexthop
;
2204 struct nexthop_group
*nhg
;
2206 nhg
= rib_get_fib_nhg(re
);
2208 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2209 /* The meaningful flag depends on where the installed
2212 if (nhg
== &(re
->fib_ng
)) {
2213 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2216 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2221 nhg
= rib_get_fib_backup_nhg(re
);
2223 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2224 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2233 * Handle notification from async dataplane: the dataplane has detected
2234 * some change to a route, and notifies zebra so that the control plane
2235 * can reflect that change.
2237 static void rib_process_dplane_notify(struct zebra_dplane_ctx
*ctx
)
2239 struct route_node
*rn
= NULL
;
2240 struct route_entry
*re
= NULL
;
2242 struct nexthop
*nexthop
;
2244 bool fib_changed
= false;
2245 bool debug_p
= IS_ZEBRA_DEBUG_DPLANE
| IS_ZEBRA_DEBUG_RIB
;
2246 int start_count
, end_count
;
2248 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
2250 /* Locate rn and re(s) from ctx */
2251 rn
= rib_find_rn_from_ctx(ctx
);
2255 "Failed to process dplane notification: no routes for %s(%u:%u):%pRN",
2256 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2257 dplane_ctx_get_table(ctx
), rn
);
2262 dest
= rib_dest_from_rnode(rn
);
2265 zlog_debug("%s(%u:%u):%pRN Processing dplane notif ctx %p",
2266 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2267 dplane_ctx_get_table(ctx
), rn
, ctx
);
2270 * Take a pass through the routes, look for matches with the context
2273 RNODE_FOREACH_RE(rn
, re
) {
2274 if (rib_route_match_ctx(re
, ctx
, false /*!update*/))
2278 /* No match? Nothing we can do */
2282 "%s(%u:%u):%pRN Unable to process dplane notification: no entry for type %s",
2283 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2284 dplane_ctx_get_table(ctx
), rn
,
2285 zebra_route_string(dplane_ctx_get_type(ctx
)));
2290 /* Ensure we clear the QUEUED flag */
2291 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
2292 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
2294 /* Is this a notification that ... matters? We mostly care about
2295 * the route that is currently selected for installation; we may also
2296 * get an un-install notification, and handle that too.
2298 if (re
!= dest
->selected_fib
) {
2300 * If we need to, clean up after a delete that was part of
2301 * an update operation.
2304 for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx
), nexthop
)) {
2305 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2309 /* If no nexthops or none installed, ensure that this re
2310 * gets its 'installed' flag cleared.
2312 if (end_count
== 0) {
2313 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2314 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2317 "%s(%u:%u):%pRN dplane notif, uninstalled type %s route",
2319 dplane_ctx_get_vrf(ctx
),
2320 dplane_ctx_get_table(ctx
), rn
,
2322 dplane_ctx_get_type(ctx
)));
2324 /* At least report on the event. */
2327 "%s(%u:%u):%pRN dplane notif, but type %s not selected_fib",
2329 dplane_ctx_get_vrf(ctx
),
2330 dplane_ctx_get_table(ctx
), rn
,
2332 dplane_ctx_get_type(ctx
)));
2336 uint32_t flags
= dplane_ctx_get_flags(ctx
);
2338 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOADED
)) {
2339 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2340 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2342 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOAD_FAILED
)) {
2343 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2344 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2346 if (CHECK_FLAG(flags
, ZEBRA_FLAG_TRAPPED
))
2347 SET_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
);
2350 /* We'll want to determine whether the installation status of the
2351 * route has changed: we'll check the status before processing,
2352 * and then again if there's been a change.
2356 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2357 start_count
= rib_count_installed_nh(re
);
2359 /* Update zebra's nexthop FIB flags based on the context struct's
2362 fib_changed
= rib_update_re_from_ctx(re
, rn
, ctx
);
2367 "%s(%u:%u):%pRN dplane notification: rib_update returns FALSE",
2368 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2369 dplane_ctx_get_table(ctx
), rn
);
2373 * Perform follow-up work if the actual status of the prefix
2376 end_count
= rib_count_installed_nh(re
);
2378 /* Various fib transitions: changed nexthops; from installed to
2379 * not-installed; or not-installed to installed.
2381 if (zrouter
.asic_notification_nexthop_control
) {
2382 if (start_count
> 0 && end_count
> 0) {
2385 "%s(%u:%u):%pRN applied nexthop changes from dplane notification",
2387 dplane_ctx_get_vrf(ctx
),
2388 dplane_ctx_get_table(ctx
), rn
);
2390 /* Changed nexthops - update kernel/others */
2391 dplane_route_notif_update(rn
, re
,
2392 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2394 } else if (start_count
== 0 && end_count
> 0) {
2397 "%s(%u:%u):%pRN installed transition from dplane notification",
2399 dplane_ctx_get_vrf(ctx
),
2400 dplane_ctx_get_table(ctx
), rn
);
2402 /* We expect this to be the selected route, so we want
2403 * to tell others about this transition.
2405 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2407 /* Changed nexthops - update kernel/others */
2408 dplane_route_notif_update(rn
, re
,
2409 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2411 /* Redistribute, lsp, and nht update */
2412 redistribute_update(rn
, re
, NULL
);
2414 } else if (start_count
> 0 && end_count
== 0) {
2417 "%s(%u:%u):%pRN un-installed transition from dplane notification",
2419 dplane_ctx_get_vrf(ctx
),
2420 dplane_ctx_get_table(ctx
), rn
);
2422 /* Transition from _something_ installed to _nothing_
2425 /* We expect this to be the selected route, so we want
2426 * to tell others about this transistion.
2428 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2430 /* Changed nexthops - update kernel/others */
2431 dplane_route_notif_update(rn
, re
,
2432 DPLANE_OP_ROUTE_DELETE
, ctx
);
2434 /* Redistribute, lsp, and nht update */
2435 redistribute_delete(rn
, re
, NULL
);
2439 if (!zebra_router_notify_on_ack()) {
2440 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
2441 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2442 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
2443 zsend_route_notify_owner_ctx(ctx
,
2444 ZAPI_ROUTE_FAIL_INSTALL
);
2447 /* Make any changes visible for lsp and nexthop-tracking processing */
2448 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
2451 zebra_rib_evaluate_mpls(rn
);
2455 route_unlock_node(rn
);
2459 * Process a node from the EVPN/VXLAN subqueue.
2461 static void process_subq_evpn(struct listnode
*lnode
)
2463 struct wq_evpn_wrapper
*w
;
2465 /* In general, the list node points to a wrapper object
2466 * holding the info necessary to make some update.
2468 w
= listgetdata(lnode
);
2472 if (w
->type
== WQ_EVPN_WRAPPER_TYPE_VRFROUTE
) {
2474 zebra_vxlan_evpn_vrf_route_add(w
->vrf_id
, &w
->macaddr
,
2475 &w
->ip
, &w
->prefix
);
2477 zebra_vxlan_evpn_vrf_route_del(w
->vrf_id
, &w
->ip
,
2479 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_ES
) {
2481 zebra_evpn_remote_es_add(&w
->esi
, w
->ip
.ipaddr_v4
,
2482 w
->esr_rxed
, w
->df_alg
,
2485 zebra_evpn_remote_es_del(&w
->esi
, w
->ip
.ipaddr_v4
);
2486 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_MACIP
) {
2487 uint16_t ipa_len
= 0;
2489 if (w
->ip
.ipa_type
== IPADDR_V4
)
2490 ipa_len
= IPV4_MAX_BYTELEN
;
2491 else if (w
->ip
.ipa_type
== IPADDR_V6
)
2492 ipa_len
= IPV6_MAX_BYTELEN
;
2495 zebra_evpn_rem_macip_add(w
->vni
, &w
->macaddr
, ipa_len
,
2496 &w
->ip
, w
->flags
, w
->seq
,
2497 w
->vtep_ip
, &w
->esi
);
2499 zebra_evpn_rem_macip_del(w
->vni
, &w
->macaddr
, ipa_len
,
2500 &w
->ip
, w
->vtep_ip
);
2501 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_VTEP
) {
2503 zebra_vxlan_remote_vtep_add(w
->vrf_id
, w
->vni
,
2504 w
->vtep_ip
, w
->flags
);
2506 zebra_vxlan_remote_vtep_del(w
->vrf_id
, w
->vni
,
2511 XFREE(MTYPE_WQ_WRAPPER
, w
);
2515 * Process the nexthop-group workqueue subqueue
2517 static void process_subq_nhg(struct listnode
*lnode
)
2519 struct nhg_ctx
*ctx
;
2520 struct nhg_hash_entry
*nhe
, *newnhe
;
2521 struct wq_nhg_wrapper
*w
;
2522 uint8_t qindex
= META_QUEUE_NHG
;
2524 w
= listgetdata(lnode
);
2529 /* Two types of object - an update from the local kernel, or
2530 * an nhg update from a daemon.
2532 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
) {
2535 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2537 "NHG Context id=%u dequeued from sub-queue %s",
2538 ctx
->id
, subqueue2str(qindex
));
2541 /* Process nexthop group updates coming 'up' from the OS */
2542 nhg_ctx_process(ctx
);
2544 } else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
) {
2547 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2548 zlog_debug("NHG %u dequeued from sub-queue %s", nhe
->id
,
2549 subqueue2str(qindex
));
2551 /* Process incoming nhg update, probably from a proto daemon */
2552 newnhe
= zebra_nhg_proto_add(nhe
->id
, nhe
->type
,
2554 nhe
->zapi_session
, &nhe
->nhg
, 0);
2556 /* Report error to daemon via ZAPI */
2558 zsend_nhg_notify(nhe
->type
, nhe
->zapi_instance
,
2559 nhe
->zapi_session
, nhe
->id
,
2560 ZAPI_NHG_FAIL_INSTALL
);
2562 /* Free temp nhe - we own that memory. */
2563 zebra_nhg_free(nhe
);
2566 XFREE(MTYPE_WQ_WRAPPER
, w
);
2569 static void process_subq_early_label(struct listnode
*lnode
)
2571 struct wq_label_wrapper
*w
= listgetdata(lnode
);
2572 struct zebra_vrf
*zvrf
;
2577 zvrf
= zebra_vrf_lookup_by_id(w
->vrf_id
);
2579 XFREE(MTYPE_WQ_WRAPPER
, w
);
2584 case WQ_LABEL_FTN_UNINSTALL
:
2585 zebra_mpls_ftn_uninstall(zvrf
, w
->ltype
, &w
->p
, w
->route_type
,
2588 case WQ_LABEL_LABELS_PROCESS
:
2589 zebra_mpls_zapi_labels_process(w
->add_p
, zvrf
, &w
->zl
);
2593 XFREE(MTYPE_WQ_WRAPPER
, w
);
2596 static void process_subq_route(struct listnode
*lnode
, uint8_t qindex
)
2598 struct route_node
*rnode
= NULL
;
2599 rib_dest_t
*dest
= NULL
;
2600 struct zebra_vrf
*zvrf
= NULL
;
2602 rnode
= listgetdata(lnode
);
2603 dest
= rib_dest_from_rnode(rnode
);
2606 zvrf
= rib_dest_vrf(dest
);
2610 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
2611 struct route_entry
*re
= NULL
;
2614 * rib_process may have freed the dest
2615 * as part of the garbage collection. Let's
2616 * prevent stupidity from happening.
2618 dest
= rib_dest_from_rnode(rnode
);
2620 re
= re_list_first(&dest
->routes
);
2622 zlog_debug("%s(%u:%u):%pRN rn %p dequeued from sub-queue %s",
2623 zvrf_name(zvrf
), zvrf_id(zvrf
), re
? re
->table
: 0,
2624 rnode
, rnode
, subqueue2str(qindex
));
2628 UNSET_FLAG(rib_dest_from_rnode(rnode
)->flags
,
2629 RIB_ROUTE_QUEUED(qindex
));
2631 route_unlock_node(rnode
);
2634 static void rib_re_nhg_free(struct route_entry
*re
)
2636 if (re
->nhe
&& re
->nhe_id
) {
2637 assert(re
->nhe
->id
== re
->nhe_id
);
2638 route_entry_update_nhe(re
, NULL
);
2639 } else if (re
->nhe
&& re
->nhe
->nhg
.nexthop
)
2640 nexthops_free(re
->nhe
->nhg
.nexthop
);
2642 nexthops_free(re
->fib_ng
.nexthop
);
2645 struct zebra_early_route
{
2649 struct prefix_ipv6 src_p
;
2650 bool src_p_provided
;
2651 struct route_entry
*re
;
2652 struct nhg_hash_entry
*re_nhe
;
2658 static void early_route_memory_free(struct zebra_early_route
*ere
)
2661 zebra_nhg_free(ere
->re_nhe
);
2663 XFREE(MTYPE_RE
, ere
->re
);
2664 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2667 static void process_subq_early_route_add(struct zebra_early_route
*ere
)
2669 struct route_entry
*re
= ere
->re
;
2670 struct route_table
*table
;
2671 struct nhg_hash_entry
*nhe
= NULL
;
2672 struct route_node
*rn
;
2673 struct route_entry
*same
= NULL
, *first_same
= NULL
;
2678 table
= zebra_vrf_get_table_with_table_id(ere
->afi
, ere
->safi
,
2679 re
->vrf_id
, re
->table
);
2681 early_route_memory_free(ere
);
2685 if (re
->nhe_id
> 0) {
2686 nhe
= zebra_nhg_lookup_id(re
->nhe_id
);
2690 * We've received from the kernel a nexthop id
2691 * that we don't have saved yet. More than likely
2692 * it has not been processed and is on the
2693 * queue to be processed. Let's stop what we
2694 * are doing and cause the meta q to be processed
2695 * storing this for later.
2697 * This is being done this way because zebra
2698 * runs with the assumption t
2701 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2702 "Zebra failed to find the nexthop hash entry for id=%u in a route entry %pFX",
2703 re
->nhe_id
, &ere
->p
);
2705 early_route_memory_free(ere
);
2709 /* Lookup nhe from route information */
2710 nhe
= zebra_nhg_rib_find_nhe(ere
->re_nhe
, ere
->afi
);
2712 char buf2
[PREFIX_STRLEN
] = "";
2715 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2716 "Zebra failed to find or create a nexthop hash entry for %pFX%s%s",
2717 &ere
->p
, ere
->src_p_provided
? " from " : "",
2719 ? prefix2str(&ere
->src_p
, buf2
,
2723 early_route_memory_free(ere
);
2729 * Attach the re to the nhe's nexthop group.
2731 * TODO: This will need to change when we start getting IDs from upper
2732 * level protocols, as the refcnt might be wrong, since it checks
2733 * if old_id != new_id.
2735 route_entry_update_nhe(re
, nhe
);
2737 /* Make it sure prefixlen is applied to the prefix. */
2738 apply_mask(&ere
->p
);
2739 if (ere
->src_p_provided
)
2740 apply_mask_ipv6(&ere
->src_p
);
2742 /* Lookup route node.*/
2743 rn
= srcdest_rnode_get(table
, &ere
->p
,
2744 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2747 * If same type of route are installed, treat it as a implicit
2748 * withdraw. If the user has specified the No route replace semantics
2749 * for the install don't do a route replace.
2751 RNODE_FOREACH_RE (rn
, same
) {
2752 if (CHECK_FLAG(same
->status
, ROUTE_ENTRY_REMOVED
)) {
2757 /* Compare various route_entry properties */
2758 if (rib_compare_routes(re
, same
)) {
2761 if (first_same
== NULL
)
2768 if (!ere
->startup
&& (re
->flags
& ZEBRA_FLAG_SELFROUTE
) &&
2769 zrouter
.asic_offloaded
) {
2771 if (IS_ZEBRA_DEBUG_RIB
)
2773 "prefix: %pRN is a self route where we do not have an entry for it. Dropping this update, it's useless",
2776 * We are not on startup, this is a self route
2777 * and we have asic offload. Which means
2778 * we are getting a callback for a entry
2779 * that was already deleted to the kernel
2780 * but an earlier response was just handed
2781 * back. Drop it on the floor
2783 early_route_memory_free(ere
);
2788 /* Set default distance by route type. */
2789 if (re
->distance
== 0) {
2790 if (same
&& !zebra_router_notify_on_ack())
2791 re
->distance
= same
->distance
;
2793 re
->distance
= route_distance(re
->type
);
2796 if (re
->metric
== ROUTE_INSTALLATION_METRIC
&&
2797 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
2798 if (same
&& !zebra_router_notify_on_ack())
2799 re
->metric
= same
->metric
;
2804 /* If this route is kernel/connected route, notify the dataplane. */
2805 if (RIB_SYSTEM_ROUTE(re
)) {
2806 /* Notify dataplane */
2807 dplane_sys_route_add(rn
, re
);
2810 /* Link new re to node.*/
2811 if (IS_ZEBRA_DEBUG_RIB
) {
2814 "Inserting route rn %p, re %p (%s) existing %p, same_count %d",
2815 rn
, re
, zebra_route_string(re
->type
), same
, same_count
);
2817 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2820 ere
->src_p_provided
? &ere
->src_p
: NULL
, re
);
2823 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
2824 rib_addnode(rn
, re
, 1);
2826 /* Free implicit route.*/
2828 rib_delnode(rn
, same
);
2830 /* See if we can remove some RE entries that are queued for
2831 * removal, but won't be considered in rib processing.
2833 dest
= rib_dest_from_rnode(rn
);
2834 RNODE_FOREACH_RE_SAFE (rn
, re
, same
) {
2835 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
2836 /* If the route was used earlier, must retain it. */
2837 if (dest
&& re
== dest
->selected_fib
)
2840 if (IS_ZEBRA_DEBUG_RIB
)
2841 rnode_debug(rn
, re
->vrf_id
,
2842 "rn %p, removing unneeded re %p",
2849 route_unlock_node(rn
);
2851 zebra_nhg_free(ere
->re_nhe
);
2852 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2855 static void process_subq_early_route_delete(struct zebra_early_route
*ere
)
2857 struct route_table
*table
;
2858 struct route_node
*rn
;
2859 struct route_entry
*re
;
2860 struct route_entry
*fib
= NULL
;
2861 struct route_entry
*same
= NULL
;
2862 struct nexthop
*rtnh
;
2863 char buf2
[INET6_ADDRSTRLEN
];
2866 if (ere
->src_p_provided
)
2867 assert(!ere
->src_p
.prefixlen
|| ere
->afi
== AFI_IP6
);
2870 table
= zebra_vrf_lookup_table_with_table_id(
2871 ere
->afi
, ere
->safi
, ere
->re
->vrf_id
, ere
->re
->table
);
2873 early_route_memory_free(ere
);
2878 apply_mask(&ere
->p
);
2879 if (ere
->src_p_provided
)
2880 apply_mask_ipv6(&ere
->src_p
);
2882 /* Lookup route node. */
2883 rn
= srcdest_rnode_lookup(table
, &ere
->p
,
2884 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2886 if (IS_ZEBRA_DEBUG_RIB
) {
2887 char src_buf
[PREFIX_STRLEN
];
2888 struct vrf
*vrf
= vrf_lookup_by_id(ere
->re
->vrf_id
);
2890 if (ere
->src_p_provided
&& ere
->src_p
.prefixlen
)
2891 prefix2str(&ere
->src_p
, src_buf
,
2896 zlog_debug("%s[%d]:%pRN%s%s doesn't exist in rib",
2897 vrf
->name
, ere
->re
->table
, rn
,
2898 (src_buf
[0] != '\0') ? " from " : "",
2901 early_route_memory_free(ere
);
2905 dest
= rib_dest_from_rnode(rn
);
2906 fib
= dest
->selected_fib
;
2908 struct nexthop
*nh
= NULL
;
2911 nh
= ere
->re
->nhe
->nhg
.nexthop
;
2913 /* Lookup same type route. */
2914 RNODE_FOREACH_RE (rn
, re
) {
2915 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
2918 if (re
->type
!= ere
->re
->type
)
2920 if (re
->instance
!= ere
->re
->instance
)
2922 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
2923 ere
->re
->distance
!= re
->distance
)
2926 if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
2927 re
->metric
!= ere
->re
->metric
)
2929 if (re
->type
== ZEBRA_ROUTE_CONNECT
&& (rtnh
= nh
) &&
2930 rtnh
->type
== NEXTHOP_TYPE_IFINDEX
&& nh
) {
2931 if (rtnh
->ifindex
!= nh
->ifindex
)
2937 /* Make sure that the route found has the same gateway. */
2938 if (ere
->re
->nhe_id
&& re
->nhe_id
== ere
->re
->nhe_id
) {
2947 for (ALL_NEXTHOPS(re
->nhe
->nhg
, rtnh
)) {
2949 * No guarantee all kernel send nh with labels
2952 if (nexthop_same_no_labels(rtnh
, nh
)) {
2962 * If same type of route can't be found and this message is from
2967 * In the past(HA!) we could get here because
2968 * we were receiving a route delete from the
2969 * kernel and we're not marking the proto
2970 * as coming from it's appropriate originator.
2971 * Now that we are properly noticing the fact
2972 * that the kernel has deleted our route we
2973 * are not going to get called in this path
2974 * I am going to leave this here because
2975 * this might still work this way on non-linux
2976 * platforms as well as some weird state I have
2977 * not properly thought of yet.
2978 * If we can show that this code path is
2979 * dead then we can remove it.
2981 if (fib
&& CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
2982 if (IS_ZEBRA_DEBUG_RIB
) {
2984 rn
, ere
->re
->vrf_id
,
2985 "rn %p, re %p (%s) was deleted from kernel, adding",
2986 rn
, fib
, zebra_route_string(fib
->type
));
2988 if (zrouter
.allow_delete
||
2989 CHECK_FLAG(dest
->flags
, RIB_ROUTE_ANY_QUEUED
)) {
2990 UNSET_FLAG(fib
->status
, ROUTE_ENTRY_INSTALLED
);
2992 for (rtnh
= fib
->nhe
->nhg
.nexthop
; rtnh
;
2994 UNSET_FLAG(rtnh
->flags
,
2998 * This is a non FRR route
2999 * as such we should mark
3002 dest
->selected_fib
= NULL
;
3005 * This means someone else, other than Zebra,
3006 * has deleted a Zebra router from the kernel.
3007 * We will add it back
3009 rib_install_kernel(rn
, fib
, NULL
);
3012 if (IS_ZEBRA_DEBUG_RIB
) {
3015 rn
, ere
->re
->vrf_id
,
3016 "via %s ifindex %d type %d doesn't exist in rib",
3017 inet_ntop(afi2family(ere
->afi
),
3020 nh
->ifindex
, ere
->re
->type
);
3023 rn
, ere
->re
->vrf_id
,
3024 "type %d doesn't exist in rib",
3027 route_unlock_node(rn
);
3028 early_route_memory_free(ere
);
3034 struct nexthop
*tmp_nh
;
3036 if (ere
->fromkernel
&&
3037 CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
) &&
3038 !zrouter
.allow_delete
) {
3039 rib_install_kernel(rn
, same
, NULL
);
3040 route_unlock_node(rn
);
3042 early_route_memory_free(ere
);
3046 /* Special handling for IPv4 or IPv6 routes sourced from
3047 * EVPN - the nexthop (and associated MAC) need to be
3048 * uninstalled if no more refs.
3050 for (ALL_NEXTHOPS(re
->nhe
->nhg
, tmp_nh
)) {
3051 struct ipaddr vtep_ip
;
3053 if (CHECK_FLAG(tmp_nh
->flags
, NEXTHOP_FLAG_EVPN
)) {
3054 memset(&vtep_ip
, 0, sizeof(struct ipaddr
));
3055 if (ere
->afi
== AFI_IP
) {
3056 vtep_ip
.ipa_type
= IPADDR_V4
;
3057 memcpy(&(vtep_ip
.ipaddr_v4
),
3058 &(tmp_nh
->gate
.ipv4
),
3059 sizeof(struct in_addr
));
3061 vtep_ip
.ipa_type
= IPADDR_V6
;
3062 memcpy(&(vtep_ip
.ipaddr_v6
),
3063 &(tmp_nh
->gate
.ipv6
),
3064 sizeof(struct in6_addr
));
3066 zebra_rib_queue_evpn_route_del(
3067 re
->vrf_id
, &vtep_ip
, &ere
->p
);
3071 /* Notify dplane if system route changes */
3072 if (RIB_SYSTEM_ROUTE(re
))
3073 dplane_sys_route_del(rn
, same
);
3075 rib_delnode(rn
, same
);
3078 route_unlock_node(rn
);
3080 early_route_memory_free(ere
);
3084 * When FRR receives a route we need to match the route up to
3085 * nexthop groups. That we also may have just received
3086 * place the data on this queue so that this work of finding
3087 * the nexthop group entries for the route entry is always
3088 * done after the nexthop group has had a chance to be processed
3090 static void process_subq_early_route(struct listnode
*lnode
)
3092 struct zebra_early_route
*ere
= listgetdata(lnode
);
3095 process_subq_early_route_delete(ere
);
3097 process_subq_early_route_add(ere
);
3100 struct meta_q_gr_run
{
3107 static void process_subq_gr_run(struct listnode
*lnode
)
3109 struct meta_q_gr_run
*gr_run
= listgetdata(lnode
);
3111 zebra_gr_process_client(gr_run
->afi
, gr_run
->vrf_id
, gr_run
->proto
,
3114 XFREE(MTYPE_WQ_WRAPPER
, gr_run
);
3118 * Examine the specified subqueue; process one entry and return 1 if
3119 * there is a node, return 0 otherwise.
3121 static unsigned int process_subq(struct list
*subq
,
3122 enum meta_queue_indexes qindex
)
3124 struct listnode
*lnode
= listhead(subq
);
3130 case META_QUEUE_EVPN
:
3131 process_subq_evpn(lnode
);
3133 case META_QUEUE_NHG
:
3134 process_subq_nhg(lnode
);
3136 case META_QUEUE_EARLY_ROUTE
:
3137 process_subq_early_route(lnode
);
3139 case META_QUEUE_EARLY_LABEL
:
3140 process_subq_early_label(lnode
);
3142 case META_QUEUE_CONNECTED
:
3143 case META_QUEUE_KERNEL
:
3144 case META_QUEUE_STATIC
:
3145 case META_QUEUE_NOTBGP
:
3146 case META_QUEUE_BGP
:
3147 case META_QUEUE_OTHER
:
3148 process_subq_route(lnode
, qindex
);
3150 case META_QUEUE_GR_RUN
:
3151 process_subq_gr_run(lnode
);
3155 list_delete_node(subq
, lnode
);
3160 /* Dispatch the meta queue by picking and processing the next node from
3161 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
3162 * data is pointed to the meta queue structure.
3164 static wq_item_status
meta_queue_process(struct work_queue
*dummy
, void *data
)
3166 struct meta_queue
*mq
= data
;
3168 uint32_t queue_len
, queue_limit
;
3170 /* Ensure there's room for more dataplane updates */
3171 queue_limit
= dplane_get_in_queue_limit();
3172 queue_len
= dplane_get_in_queue_len();
3173 if (queue_len
> queue_limit
) {
3174 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3176 "rib queue: dplane queue len %u, limit %u, retrying",
3177 queue_len
, queue_limit
);
3179 /* Ensure that the meta-queue is actually enqueued */
3180 if (work_queue_empty(zrouter
.ribq
))
3181 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3183 return WQ_QUEUE_BLOCKED
;
3186 for (i
= 0; i
< MQ_SIZE
; i
++)
3187 if (process_subq(mq
->subq
[i
], i
)) {
3191 return mq
->size
? WQ_REQUEUE
: WQ_SUCCESS
;
3196 * Look into the RN and queue it into the highest priority queue
3197 * at this point in time for processing.
3199 * We will enqueue a route node only once per invocation.
3201 * There are two possibilities here that should be kept in mind.
3202 * If the original invocation has not been pulled off for processing
3203 * yet, A subsuquent invocation can have a route entry with a better
3204 * meta queue index value and we can have a situation where
3205 * we might have the same node enqueued 2 times. Not necessarily
3206 * an optimal situation but it should be ok.
3208 * The other possibility is that the original invocation has not
3209 * been pulled off for processing yet, A subsusquent invocation
3210 * doesn't have a route_entry with a better meta-queue and the
3211 * original metaqueue index value will win and we'll end up with
3212 * the route node enqueued once.
3214 static int rib_meta_queue_add(struct meta_queue
*mq
, void *data
)
3216 struct route_node
*rn
= NULL
;
3217 struct route_entry
*re
= NULL
, *curr_re
= NULL
;
3218 uint8_t qindex
= MQ_SIZE
, curr_qindex
= MQ_SIZE
;
3220 rn
= (struct route_node
*)data
;
3222 RNODE_FOREACH_RE (rn
, curr_re
) {
3223 curr_qindex
= route_info
[curr_re
->type
].meta_q_map
;
3225 if (curr_qindex
<= qindex
) {
3227 qindex
= curr_qindex
;
3234 /* Invariant: at this point we always have rn->info set. */
3235 if (CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
3236 RIB_ROUTE_QUEUED(qindex
))) {
3237 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3238 rnode_debug(rn
, re
->vrf_id
,
3239 "rn %p is already queued in sub-queue %s",
3240 (void *)rn
, subqueue2str(qindex
));
3244 SET_FLAG(rib_dest_from_rnode(rn
)->flags
, RIB_ROUTE_QUEUED(qindex
));
3245 listnode_add(mq
->subq
[qindex
], rn
);
3246 route_lock_node(rn
);
3249 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3250 rnode_debug(rn
, re
->vrf_id
, "queued rn %p into sub-queue %s",
3251 (void *)rn
, subqueue2str(qindex
));
3256 static int early_label_meta_queue_add(struct meta_queue
*mq
, void *data
)
3258 listnode_add(mq
->subq
[META_QUEUE_EARLY_LABEL
], data
);
3263 static int rib_meta_queue_nhg_ctx_add(struct meta_queue
*mq
, void *data
)
3265 struct nhg_ctx
*ctx
= NULL
;
3266 uint8_t qindex
= META_QUEUE_NHG
;
3267 struct wq_nhg_wrapper
*w
;
3269 ctx
= (struct nhg_ctx
*)data
;
3274 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3276 w
->type
= WQ_NHG_WRAPPER_TYPE_CTX
;
3279 listnode_add(mq
->subq
[qindex
], w
);
3282 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3283 zlog_debug("NHG Context id=%u queued into sub-queue %s",
3284 ctx
->id
, subqueue2str(qindex
));
3289 static int rib_meta_queue_nhg_add(struct meta_queue
*mq
, void *data
)
3291 struct nhg_hash_entry
*nhe
= NULL
;
3292 uint8_t qindex
= META_QUEUE_NHG
;
3293 struct wq_nhg_wrapper
*w
;
3295 nhe
= (struct nhg_hash_entry
*)data
;
3300 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3302 w
->type
= WQ_NHG_WRAPPER_TYPE_NHG
;
3305 listnode_add(mq
->subq
[qindex
], w
);
3308 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3309 zlog_debug("NHG id=%u queued into sub-queue %s", nhe
->id
,
3310 subqueue2str(qindex
));
3315 static int rib_meta_queue_evpn_add(struct meta_queue
*mq
, void *data
)
3317 listnode_add(mq
->subq
[META_QUEUE_EVPN
], data
);
3323 static int mq_add_handler(void *data
,
3324 int (*mq_add_func
)(struct meta_queue
*mq
, void *data
))
3326 if (zrouter
.ribq
== NULL
) {
3327 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3328 "%s: work_queue does not exist!", __func__
);
3333 * The RIB queue should normally be either empty or holding the only
3334 * work_queue_item element. In the latter case this element would
3335 * hold a pointer to the meta queue structure, which must be used to
3336 * actually queue the route nodes to process. So create the MQ
3337 * holder, if necessary, then push the work into it in any case.
3338 * This semantics was introduced after 0.99.9 release.
3340 if (work_queue_empty(zrouter
.ribq
))
3341 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3343 return mq_add_func(zrouter
.mq
, data
);
3346 void mpls_ftn_uninstall(struct zebra_vrf
*zvrf
, enum lsp_types_t type
,
3347 struct prefix
*prefix
, uint8_t route_type
,
3348 uint8_t route_instance
)
3350 struct wq_label_wrapper
*w
;
3352 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3354 w
->type
= WQ_LABEL_FTN_UNINSTALL
;
3355 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3358 w
->route_type
= route_type
;
3359 w
->route_instance
= route_instance
;
3361 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3362 zlog_debug("Early Label Handling for %pFX", prefix
);
3364 mq_add_handler(w
, early_label_meta_queue_add
);
3367 void mpls_zapi_labels_process(bool add_p
, struct zebra_vrf
*zvrf
,
3368 const struct zapi_labels
*zl
)
3370 struct wq_label_wrapper
*w
;
3372 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3373 w
->type
= WQ_LABEL_LABELS_PROCESS
;
3374 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3378 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3379 zlog_debug("Early Label Handling: Labels Process");
3381 mq_add_handler(w
, early_label_meta_queue_add
);
3384 /* Add route_node to work queue and schedule processing */
3385 int rib_queue_add(struct route_node
*rn
)
3389 /* Pointless to queue a route_node with no RIB entries to add or remove
3391 if (!rnode_to_ribs(rn
)) {
3392 zlog_debug("%s: called for route_node (%p, %u) with no ribs",
3393 __func__
, (void *)rn
, route_node_get_lock_count(rn
));
3394 zlog_backtrace(LOG_DEBUG
);
3398 return mq_add_handler(rn
, rib_meta_queue_add
);
3402 * Enqueue incoming nhg info from OS for processing
3404 int rib_queue_nhg_ctx_add(struct nhg_ctx
*ctx
)
3408 return mq_add_handler(ctx
, rib_meta_queue_nhg_ctx_add
);
3412 * Enqueue incoming nhg from proto daemon for processing
3414 int rib_queue_nhe_add(struct nhg_hash_entry
*nhe
)
3419 return mq_add_handler(nhe
, rib_meta_queue_nhg_add
);
3423 * Enqueue evpn route for processing
3425 int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id
, const struct ethaddr
*rmac
,
3426 const struct ipaddr
*vtep_ip
,
3427 const struct prefix
*host_prefix
)
3429 struct wq_evpn_wrapper
*w
;
3431 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3433 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3438 w
->prefix
= *host_prefix
;
3440 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3441 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3442 vrf_id
, vtep_ip
, host_prefix
);
3444 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3447 int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id
,
3448 const struct ipaddr
*vtep_ip
,
3449 const struct prefix
*host_prefix
)
3451 struct wq_evpn_wrapper
*w
;
3453 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3455 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3459 w
->prefix
= *host_prefix
;
3461 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3462 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3463 vrf_id
, vtep_ip
, host_prefix
);
3465 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3468 /* Enqueue EVPN remote ES for processing */
3469 int zebra_rib_queue_evpn_rem_es_add(const esi_t
*esi
,
3470 const struct in_addr
*vtep_ip
,
3471 bool esr_rxed
, uint8_t df_alg
,
3474 struct wq_evpn_wrapper
*w
;
3475 char buf
[ESI_STR_LEN
];
3477 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3479 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3482 w
->ip
.ipa_type
= IPADDR_V4
;
3483 w
->ip
.ipaddr_v4
= *vtep_ip
;
3484 w
->esr_rxed
= esr_rxed
;
3486 w
->df_pref
= df_pref
;
3488 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3489 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3490 esi_to_str(esi
, buf
, sizeof(buf
)));
3492 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3495 int zebra_rib_queue_evpn_rem_es_del(const esi_t
*esi
,
3496 const struct in_addr
*vtep_ip
)
3498 struct wq_evpn_wrapper
*w
;
3499 char buf
[ESI_STR_LEN
];
3501 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3503 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3506 w
->ip
.ipa_type
= IPADDR_V4
;
3507 w
->ip
.ipaddr_v4
= *vtep_ip
;
3509 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3510 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3511 esi_to_str(esi
, buf
, sizeof(buf
));
3513 strlcpy(buf
, "-", sizeof(buf
));
3515 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3519 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3523 * Enqueue EVPN remote macip update for processing
3525 int zebra_rib_queue_evpn_rem_macip_add(vni_t vni
, const struct ethaddr
*macaddr
,
3526 const struct ipaddr
*ipaddr
,
3527 uint8_t flags
, uint32_t seq
,
3528 struct in_addr vtep_ip
, const esi_t
*esi
)
3530 struct wq_evpn_wrapper
*w
;
3531 char buf
[ESI_STR_LEN
];
3533 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3535 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3538 w
->macaddr
= *macaddr
;
3542 w
->vtep_ip
= vtep_ip
;
3545 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3546 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3547 esi_to_str(esi
, buf
, sizeof(buf
));
3549 strlcpy(buf
, "-", sizeof(buf
));
3551 zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__
,
3552 macaddr
, &vtep_ip
, buf
);
3555 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3558 int zebra_rib_queue_evpn_rem_macip_del(vni_t vni
, const struct ethaddr
*macaddr
,
3559 const struct ipaddr
*ip
,
3560 struct in_addr vtep_ip
)
3562 struct wq_evpn_wrapper
*w
;
3564 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3566 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3569 w
->macaddr
= *macaddr
;
3571 w
->vtep_ip
= vtep_ip
;
3573 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3574 zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__
,
3577 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3581 * Enqueue remote VTEP address for processing
3583 int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id
, vni_t vni
,
3584 struct in_addr vtep_ip
, int flood_control
)
3586 struct wq_evpn_wrapper
*w
;
3588 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3590 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3594 w
->vtep_ip
= vtep_ip
;
3595 w
->flags
= flood_control
;
3597 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3598 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3601 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3604 int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id
, vni_t vni
,
3605 struct in_addr vtep_ip
)
3607 struct wq_evpn_wrapper
*w
;
3609 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3611 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3615 w
->vtep_ip
= vtep_ip
;
3617 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3618 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3621 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3624 /* Create new meta queue.
3625 A destructor function doesn't seem to be necessary here.
3627 static struct meta_queue
*meta_queue_new(void)
3629 struct meta_queue
*new;
3632 new = XCALLOC(MTYPE_WORK_QUEUE
, sizeof(struct meta_queue
));
3634 for (i
= 0; i
< MQ_SIZE
; i
++) {
3635 new->subq
[i
] = list_new();
3636 assert(new->subq
[i
]);
3642 /* Clean up the EVPN meta-queue list */
3643 static void evpn_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3644 struct zebra_vrf
*zvrf
)
3646 struct listnode
*node
, *nnode
;
3647 struct wq_evpn_wrapper
*w
;
3649 /* Free the node wrapper object, and the struct it wraps */
3650 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3652 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3654 if (w
->vrf_id
!= vrf_id
)
3660 XFREE(MTYPE_WQ_WRAPPER
, w
);
3662 list_delete_node(l
, node
);
3667 /* Clean up the nhg meta-queue list */
3668 static void nhg_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3669 struct zebra_vrf
*zvrf
)
3671 struct wq_nhg_wrapper
*w
;
3672 struct listnode
*node
, *nnode
;
3674 /* Free the node wrapper object, and the struct it wraps */
3675 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3677 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3679 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
&&
3680 w
->u
.ctx
->vrf_id
!= vrf_id
)
3682 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
&&
3683 w
->u
.nhe
->vrf_id
!= vrf_id
)
3686 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
)
3687 nhg_ctx_free(&w
->u
.ctx
);
3688 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
)
3689 zebra_nhg_free(w
->u
.nhe
);
3692 XFREE(MTYPE_WQ_WRAPPER
, w
);
3694 list_delete_node(l
, node
);
3699 static void early_label_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3700 struct zebra_vrf
*zvrf
)
3702 struct wq_label_wrapper
*w
;
3703 struct listnode
*node
, *nnode
;
3705 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3706 if (zvrf
&& zvrf
->vrf
->vrf_id
!= w
->vrf_id
)
3710 case WQ_LABEL_FTN_UNINSTALL
:
3711 case WQ_LABEL_LABELS_PROCESS
:
3716 XFREE(MTYPE_WQ_WRAPPER
, w
);
3717 list_delete_node(l
, node
);
3722 static void rib_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3723 struct zebra_vrf
*zvrf
)
3725 struct route_node
*rnode
;
3726 struct listnode
*node
, *nnode
;
3728 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, rnode
)) {
3729 rib_dest_t
*dest
= rib_dest_from_rnode(rnode
);
3731 if (dest
&& rib_dest_vrf(dest
) != zvrf
)
3734 route_unlock_node(rnode
);
3736 list_delete_node(l
, node
);
3741 static void early_route_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3742 struct zebra_vrf
*zvrf
)
3744 struct zebra_early_route
*ere
;
3745 struct listnode
*node
, *nnode
;
3747 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, ere
)) {
3748 if (zvrf
&& ere
->re
->vrf_id
!= zvrf
->vrf
->vrf_id
)
3751 early_route_memory_free(ere
);
3753 list_delete_node(l
, node
);
3758 static void rib_meta_queue_gr_run_free(struct meta_queue
*mq
, struct list
*l
,
3759 struct zebra_vrf
*zvrf
)
3761 struct meta_q_gr_run
*gr_run
;
3762 struct listnode
*node
, *nnode
;
3764 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, gr_run
)) {
3765 if (zvrf
&& zvrf
->vrf
->vrf_id
!= gr_run
->vrf_id
)
3768 XFREE(MTYPE_WQ_WRAPPER
, gr_run
);
3770 list_delete_node(l
, node
);
3775 void meta_queue_free(struct meta_queue
*mq
, struct zebra_vrf
*zvrf
)
3777 enum meta_queue_indexes i
;
3779 for (i
= 0; i
< MQ_SIZE
; i
++) {
3780 /* Some subqueues may need cleanup - nhgs for example */
3782 case META_QUEUE_NHG
:
3783 nhg_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3785 case META_QUEUE_EVPN
:
3786 evpn_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3788 case META_QUEUE_EARLY_ROUTE
:
3789 early_route_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3791 case META_QUEUE_EARLY_LABEL
:
3792 early_label_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3794 case META_QUEUE_CONNECTED
:
3795 case META_QUEUE_KERNEL
:
3796 case META_QUEUE_STATIC
:
3797 case META_QUEUE_NOTBGP
:
3798 case META_QUEUE_BGP
:
3799 case META_QUEUE_OTHER
:
3800 rib_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3802 case META_QUEUE_GR_RUN
:
3803 rib_meta_queue_gr_run_free(mq
, mq
->subq
[i
], zvrf
);
3807 list_delete(&mq
->subq
[i
]);
3811 XFREE(MTYPE_WORK_QUEUE
, mq
);
3814 /* initialise zebra rib work queue */
3815 static void rib_queue_init(void)
3817 if (!(zrouter
.ribq
= work_queue_new(zrouter
.master
,
3818 "route_node processing"))) {
3819 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3820 "%s: could not initialise work queue!", __func__
);
3824 /* fill in the work queue spec */
3825 zrouter
.ribq
->spec
.workfunc
= &meta_queue_process
;
3826 zrouter
.ribq
->spec
.completion_func
= NULL
;
3827 /* XXX: TODO: These should be runtime configurable via vty */
3828 zrouter
.ribq
->spec
.max_retries
= 3;
3829 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3830 zrouter
.ribq
->spec
.retry
= ZEBRA_RIB_PROCESS_RETRY_TIME
;
3832 if (!(zrouter
.mq
= meta_queue_new())) {
3833 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3834 "%s: could not initialise meta queue!", __func__
);
3840 rib_dest_t
*zebra_rib_create_dest(struct route_node
*rn
)
3844 dest
= XCALLOC(MTYPE_RIB_DEST
, sizeof(rib_dest_t
));
3845 rnh_list_init(&dest
->nht
);
3846 re_list_init(&dest
->routes
);
3847 route_lock_node(rn
); /* rn route table reference */
3854 /* RIB updates are processed via a queue of pointers to route_nodes.
3856 * The queue length is bounded by the maximal size of the routing table,
3857 * as a route_node will not be requeued, if already queued.
3859 * REs are submitted via rib_addnode or rib_delnode which set minimal
3860 * state, or static_install_route (when an existing RE is updated)
3861 * and then submit route_node to queue for best-path selection later.
3862 * Order of add/delete state changes are preserved for any given RE.
3864 * Deleted REs are reaped during best-path selection.
3867 * |-> rib_link or unset ROUTE_ENTRY_REMOVE |->Update kernel with
3868 * |-------->| | best RE, if required
3870 * static_install->|->rib_addqueue...... -> rib_process
3872 * |-------->| |-> rib_unlink
3873 * |-> set ROUTE_ENTRY_REMOVE |
3874 * rib_delnode (RE freed)
3876 * The 'info' pointer of a route_node points to a rib_dest_t
3877 * ('dest'). Queueing state for a route_node is kept on the dest. The
3878 * dest is created on-demand by rib_link() and is kept around at least
3879 * as long as there are ribs hanging off it (@see rib_gc_dest()).
3881 * Refcounting (aka "locking" throughout the Zebra and FRR code):
3883 * - route_nodes: refcounted by:
3884 * - dest attached to route_node:
3885 * - managed by: rib_link/rib_gc_dest
3886 * - route_node processing queue
3887 * - managed by: rib_addqueue, rib_process.
3891 /* Add RE to head of the route node. */
3892 static void rib_link(struct route_node
*rn
, struct route_entry
*re
, int process
)
3896 const char *rmap_name
;
3900 dest
= rib_dest_from_rnode(rn
);
3902 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3903 rnode_debug(rn
, re
->vrf_id
, "rn %p adding dest", rn
);
3905 dest
= zebra_rib_create_dest(rn
);
3908 re_list_add_head(&dest
->routes
, re
);
3910 afi
= (rn
->p
.family
== AF_INET
)
3912 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3913 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3914 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3916 rmap_name
= zebra_get_import_table_route_map(afi
, re
->table
);
3917 zebra_add_import_table_entry(zvrf
, rn
, re
, rmap_name
);
3924 static void rib_addnode(struct route_node
*rn
,
3925 struct route_entry
*re
, int process
)
3927 /* RE node has been un-removed before route-node is processed.
3928 * route_node must hence already be on the queue for processing..
3930 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
3931 if (IS_ZEBRA_DEBUG_RIB
)
3932 rnode_debug(rn
, re
->vrf_id
, "rn %p, un-removed re %p",
3933 (void *)rn
, (void *)re
);
3935 UNSET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3938 rib_link(rn
, re
, process
);
3944 * Detach a rib structure from a route_node.
3946 * Note that a call to rib_unlink() should be followed by a call to
3947 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
3948 * longer required to be deleted.
3950 void rib_unlink(struct route_node
*rn
, struct route_entry
*re
)
3956 if (IS_ZEBRA_DEBUG_RIB
)
3957 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p", (void *)rn
,
3960 dest
= rib_dest_from_rnode(rn
);
3962 re_list_del(&dest
->routes
, re
);
3964 if (dest
->selected_fib
== re
)
3965 dest
->selected_fib
= NULL
;
3967 rib_re_nhg_free(re
);
3969 zapi_re_opaque_free(re
->opaque
);
3971 XFREE(MTYPE_RE
, re
);
3974 void rib_delnode(struct route_node
*rn
, struct route_entry
*re
)
3978 if (IS_ZEBRA_DEBUG_RIB
)
3979 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p, removing",
3980 (void *)rn
, (void *)re
);
3981 SET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3983 afi
= (rn
->p
.family
== AF_INET
)
3985 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3986 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3987 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3989 zebra_del_import_table_entry(zvrf
, rn
, re
);
3990 /* Just clean up if non main table */
3991 if (IS_ZEBRA_DEBUG_RIB
)
3992 zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)",
3993 vrf_id_to_name(re
->vrf_id
), re
->vrf_id
, rn
,
3994 rn
, re
, zebra_route_string(re
->type
));
4001 * Helper that debugs a single nexthop within a route-entry
4003 static void _route_entry_dump_nh(const struct route_entry
*re
,
4004 const char *straddr
,
4005 const struct nexthop
*nexthop
)
4007 char nhname
[PREFIX_STRLEN
];
4008 char backup_str
[50];
4011 char label_str
[MPLS_LABEL_STRLEN
];
4013 struct interface
*ifp
;
4014 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
4016 switch (nexthop
->type
) {
4017 case NEXTHOP_TYPE_BLACKHOLE
:
4018 snprintf(nhname
, sizeof(nhname
), "Blackhole");
4020 case NEXTHOP_TYPE_IFINDEX
:
4021 ifp
= if_lookup_by_index(nexthop
->ifindex
, nexthop
->vrf_id
);
4022 snprintf(nhname
, sizeof(nhname
), "%s",
4023 ifp
? ifp
->name
: "Unknown");
4025 case NEXTHOP_TYPE_IPV4
:
4027 case NEXTHOP_TYPE_IPV4_IFINDEX
:
4028 inet_ntop(AF_INET
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
4030 case NEXTHOP_TYPE_IPV6
:
4031 case NEXTHOP_TYPE_IPV6_IFINDEX
:
4032 inet_ntop(AF_INET6
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
4037 label_str
[0] = '\0';
4038 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
> 0) {
4039 mpls_label2str(nexthop
->nh_label
->num_labels
,
4040 nexthop
->nh_label
->label
, label_str
,
4041 sizeof(label_str
), nexthop
->nh_label_type
,
4043 strlcat(label_str
, ", ", sizeof(label_str
));
4046 backup_str
[0] = '\0';
4047 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
4048 snprintf(backup_str
, sizeof(backup_str
), "backup ");
4049 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
4050 snprintf(temp_str
, sizeof(temp_str
), "%d, ",
4051 nexthop
->backup_idx
[i
]);
4052 strlcat(backup_str
, temp_str
, sizeof(backup_str
));
4057 if (nexthop
->weight
)
4058 snprintf(wgt_str
, sizeof(wgt_str
), "wgt %d,", nexthop
->weight
);
4060 zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s%s",
4061 straddr
, (nexthop
->rparent
? " NH" : "NH"), nhname
,
4062 nexthop
->ifindex
, label_str
, vrf
? vrf
->name
: "Unknown",
4064 wgt_str
, backup_str
,
4065 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
)
4068 (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)
4071 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
4074 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
)
4077 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
4080 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RNH_FILTERED
)
4081 ? "FILTERED " : ""),
4082 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)
4084 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_SRTE
)
4086 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_EVPN
)
4091 /* This function dumps the contents of a given RE entry into
4092 * standard debug log. Calling function name and IP prefix in
4093 * question are passed as 1st and 2nd arguments.
4095 void _route_entry_dump(const char *func
, union prefixconstptr pp
,
4096 union prefixconstptr src_pp
,
4097 const struct route_entry
*re
)
4099 const struct prefix
*src_p
= src_pp
.p
;
4100 bool is_srcdst
= src_p
&& src_p
->prefixlen
;
4101 char straddr
[PREFIX_STRLEN
];
4102 char srcaddr
[PREFIX_STRLEN
];
4103 char flags_buf
[128];
4104 char status_buf
[128];
4105 struct nexthop
*nexthop
;
4106 struct vrf
*vrf
= vrf_lookup_by_id(re
->vrf_id
);
4107 struct nexthop_group
*nhg
;
4109 prefix2str(pp
, straddr
, sizeof(straddr
));
4111 zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %s(%u)", func
,
4112 (const void *)re
, straddr
,
4113 is_srcdst
? " from " : "",
4114 is_srcdst
? prefix2str(src_pp
, srcaddr
, sizeof(srcaddr
))
4116 VRF_LOGNAME(vrf
), re
->vrf_id
);
4117 zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
4118 straddr
, (unsigned long)re
->uptime
, re
->type
, re
->instance
,
4121 "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s",
4122 straddr
, re
->metric
, re
->mtu
, re
->distance
,
4123 zclient_dump_route_flags(re
->flags
, flags_buf
,
4125 _dump_re_status(re
, status_buf
, sizeof(status_buf
)));
4126 zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr
,
4127 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)),
4128 nexthop_group_active_nexthop_num(&(re
->nhe
->nhg
)));
4131 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4132 _route_entry_dump_nh(re
, straddr
, nexthop
);
4134 if (zebra_nhg_get_backup_nhg(re
->nhe
)) {
4135 zlog_debug("%s: backup nexthops:", straddr
);
4137 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
4138 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
))
4139 _route_entry_dump_nh(re
, straddr
, nexthop
);
4142 zlog_debug("%s: dump complete", straddr
);
4145 static int rib_meta_queue_gr_run_add(struct meta_queue
*mq
, void *data
)
4147 listnode_add(mq
->subq
[META_QUEUE_GR_RUN
], data
);
4150 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
4151 zlog_debug("Graceful Run adding");
4156 static int rib_meta_queue_early_route_add(struct meta_queue
*mq
, void *data
)
4158 struct zebra_early_route
*ere
= data
;
4160 listnode_add(mq
->subq
[META_QUEUE_EARLY_ROUTE
], data
);
4163 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
4165 "Route %pFX(%u) queued for processing into sub-queue %s",
4166 &ere
->p
, ere
->re
->vrf_id
,
4167 subqueue2str(META_QUEUE_EARLY_ROUTE
));
4172 int rib_add_gr_run(afi_t afi
, vrf_id_t vrf_id
, uint8_t proto
, uint8_t instance
)
4174 struct meta_q_gr_run
*gr_run
;
4176 gr_run
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*gr_run
));
4179 gr_run
->proto
= proto
;
4180 gr_run
->vrf_id
= vrf_id
;
4181 gr_run
->instance
= instance
;
4183 return mq_add_handler(gr_run
, rib_meta_queue_gr_run_add
);
4186 struct route_entry
*zebra_rib_route_entry_new(vrf_id_t vrf_id
, int type
,
4187 uint8_t instance
, uint32_t flags
,
4190 uint32_t metric
, uint32_t mtu
,
4191 uint8_t distance
, route_tag_t tag
)
4193 struct route_entry
*re
;
4195 re
= XCALLOC(MTYPE_RE
, sizeof(struct route_entry
));
4197 re
->instance
= instance
;
4198 re
->distance
= distance
;
4200 re
->metric
= metric
;
4202 re
->table
= table_id
;
4203 re
->vrf_id
= vrf_id
;
4204 re
->uptime
= monotime(NULL
);
4206 re
->nhe_id
= nhe_id
;
4211 * Internal route-add implementation; there are a couple of different public
4212 * signatures. Callers in this path are responsible for the memory they
4213 * allocate: if they allocate a nexthop_group or backup nexthop info, they
4214 * must free those objects. If this returns < 0, an error has occurred and the
4215 * route_entry 're' has not been captured; the caller should free that also.
4221 int rib_add_multipath_nhe(afi_t afi
, safi_t safi
, struct prefix
*p
,
4222 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4223 struct nhg_hash_entry
*re_nhe
, bool startup
)
4225 struct zebra_early_route
*ere
;
4230 assert(!src_p
|| !src_p
->prefixlen
|| afi
== AFI_IP6
);
4232 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4237 ere
->src_p
= *src_p
;
4238 ere
->src_p_provided
= !!src_p
;
4240 ere
->re_nhe
= re_nhe
;
4241 ere
->startup
= startup
;
4243 return mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4247 * Add a single route.
4249 int rib_add_multipath(afi_t afi
, safi_t safi
, struct prefix
*p
,
4250 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4251 struct nexthop_group
*ng
, bool startup
)
4254 struct nhg_hash_entry nhe
, *n
;
4259 /* We either need nexthop(s) or an existing nexthop id */
4260 if (ng
== NULL
&& re
->nhe_id
== 0)
4264 * Use a temporary nhe to convey info to the common/main api.
4266 zebra_nhe_init(&nhe
, afi
, (ng
? ng
->nexthop
: NULL
));
4268 nhe
.nhg
.nexthop
= ng
->nexthop
;
4269 else if (re
->nhe_id
> 0)
4270 nhe
.id
= re
->nhe_id
;
4272 n
= zebra_nhe_copy(&nhe
, 0);
4273 ret
= rib_add_multipath_nhe(afi
, safi
, p
, src_p
, re
, n
, startup
);
4275 /* In error cases, free the route also */
4277 XFREE(MTYPE_RE
, re
);
4282 void rib_delete(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4283 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4284 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4285 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
,
4286 uint8_t distance
, bool fromkernel
)
4288 struct zebra_early_route
*ere
;
4289 struct route_entry
*re
= NULL
;
4290 struct nhg_hash_entry
*nhe
= NULL
;
4292 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4293 table_id
, metric
, 0, distance
, 0);
4296 nhe
= zebra_nhg_alloc();
4297 nhe
->nhg
.nexthop
= nexthop_dup(nh
, NULL
);
4300 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4305 ere
->src_p
= *src_p
;
4306 ere
->src_p_provided
= !!src_p
;
4309 ere
->startup
= false;
4310 ere
->deletion
= true;
4311 ere
->fromkernel
= fromkernel
;
4313 mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4317 int rib_add(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4318 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4319 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4320 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
, uint32_t mtu
,
4321 uint8_t distance
, route_tag_t tag
, bool startup
)
4323 struct route_entry
*re
= NULL
;
4324 struct nexthop nexthop
= {};
4325 struct nexthop_group ng
= {};
4327 /* Allocate new route_entry structure. */
4328 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4329 table_id
, metric
, mtu
, distance
, tag
);
4331 /* If the owner of the route supplies a shared nexthop-group id,
4332 * we'll use that. Otherwise, pass the nexthop along directly.
4337 nexthop_group_add_sorted(&ng
, &nexthop
);
4340 return rib_add_multipath(afi
, safi
, p
, src_p
, re
, &ng
, startup
);
4343 static const char *rib_update_event2str(enum rib_update_event event
)
4345 const char *ret
= "UNKNOWN";
4348 case RIB_UPDATE_KERNEL
:
4349 ret
= "RIB_UPDATE_KERNEL";
4351 case RIB_UPDATE_RMAP_CHANGE
:
4352 ret
= "RIB_UPDATE_RMAP_CHANGE";
4354 case RIB_UPDATE_OTHER
:
4355 ret
= "RIB_UPDATE_OTHER";
4357 case RIB_UPDATE_MAX
:
4365 /* Schedule route nodes to be processed if they match the type */
4366 static void rib_update_route_node(struct route_node
*rn
, int type
)
4368 struct route_entry
*re
, *next
;
4369 bool re_changed
= false;
4371 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4372 if (type
== ZEBRA_ROUTE_ALL
|| type
== re
->type
) {
4373 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
4382 /* Schedule routes of a particular table (address-family) based on event. */
4383 void rib_update_table(struct route_table
*table
, enum rib_update_event event
,
4386 struct route_node
*rn
;
4388 if (IS_ZEBRA_DEBUG_EVENT
) {
4389 struct zebra_vrf
*zvrf
;
4393 ? ((struct rib_table_info
*)table
->info
)->zvrf
4395 vrf
= zvrf
? zvrf
->vrf
: NULL
;
4397 zlog_debug("%s: %s VRF %s Table %u event %s Route type: %s", __func__
,
4398 table
->info
? afi2str(
4399 ((struct rib_table_info
*)table
->info
)->afi
)
4401 VRF_LOGNAME(vrf
), zvrf
? zvrf
->table_id
: 0,
4402 rib_update_event2str(event
), zebra_route_string(rtype
));
4405 /* Walk all routes and queue for processing, if appropriate for
4406 * the trigger event.
4408 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4410 * If we are looking at a route node and the node
4411 * has already been queued we don't
4412 * need to queue it up again
4415 && CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
4416 RIB_ROUTE_ANY_QUEUED
))
4420 case RIB_UPDATE_KERNEL
:
4421 rib_update_route_node(rn
, ZEBRA_ROUTE_KERNEL
);
4423 case RIB_UPDATE_RMAP_CHANGE
:
4424 case RIB_UPDATE_OTHER
:
4425 rib_update_route_node(rn
, rtype
);
4427 case RIB_UPDATE_MAX
:
4433 static void rib_update_handle_vrf_all(enum rib_update_event event
, int rtype
)
4435 struct zebra_router_table
*zrt
;
4437 if (IS_ZEBRA_DEBUG_EVENT
)
4438 zlog_debug("%s: Handling VRF (ALL) event %s", __func__
,
4439 rib_update_event2str(event
));
4441 /* Just iterate over all the route tables, rather than vrf lookups */
4442 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
)
4443 rib_update_table(zrt
->table
, event
, rtype
);
4446 struct rib_update_ctx
{
4447 enum rib_update_event event
;
4451 static struct rib_update_ctx
*rib_update_ctx_init(vrf_id_t vrf_id
,
4452 enum rib_update_event event
)
4454 struct rib_update_ctx
*ctx
;
4456 ctx
= XCALLOC(MTYPE_RIB_UPDATE_CTX
, sizeof(struct rib_update_ctx
));
4459 ctx
->vrf_id
= vrf_id
;
4464 static void rib_update_ctx_fini(struct rib_update_ctx
**ctx
)
4466 XFREE(MTYPE_RIB_UPDATE_CTX
, *ctx
);
4469 static void rib_update_handler(struct event
*thread
)
4471 struct rib_update_ctx
*ctx
;
4473 ctx
= EVENT_ARG(thread
);
4475 rib_update_handle_vrf_all(ctx
->event
, ZEBRA_ROUTE_ALL
);
4477 rib_update_ctx_fini(&ctx
);
4481 * Thread list to ensure we don't schedule a ton of events
4482 * if interfaces are flapping for instance.
4484 static struct event
*t_rib_update_threads
[RIB_UPDATE_MAX
];
4486 void rib_update_finish(void)
4490 for (i
= RIB_UPDATE_KERNEL
; i
< RIB_UPDATE_MAX
; i
++) {
4491 if (event_is_scheduled(t_rib_update_threads
[i
])) {
4492 struct rib_update_ctx
*ctx
;
4494 ctx
= EVENT_ARG(t_rib_update_threads
[i
]);
4496 rib_update_ctx_fini(&ctx
);
4497 EVENT_OFF(t_rib_update_threads
[i
]);
4502 /* Schedule a RIB update event for all vrfs */
4503 void rib_update(enum rib_update_event event
)
4505 struct rib_update_ctx
*ctx
;
4507 if (event_is_scheduled(t_rib_update_threads
[event
]))
4510 if (zebra_router_in_shutdown())
4513 ctx
= rib_update_ctx_init(0, event
);
4515 event_add_event(zrouter
.master
, rib_update_handler
, ctx
, 0,
4516 &t_rib_update_threads
[event
]);
4518 if (IS_ZEBRA_DEBUG_EVENT
)
4519 zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__
,
4520 rib_update_event2str(event
));
4523 /* Delete self installed routes after zebra is relaunched. */
4524 void rib_sweep_table(struct route_table
*table
)
4526 struct route_node
*rn
;
4527 struct route_entry
*re
;
4528 struct route_entry
*next
;
4529 struct nexthop
*nexthop
;
4534 if (IS_ZEBRA_DEBUG_RIB
)
4535 zlog_debug("%s: starting", __func__
);
4537 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4538 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4540 if (IS_ZEBRA_DEBUG_RIB
)
4541 route_entry_dump(&rn
->p
, NULL
, re
);
4543 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4546 if (!CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
))
4550 * If routes are older than startup_time then
4551 * we know we read them in from the kernel.
4552 * As such we can safely remove them.
4554 if (zrouter
.startup_time
< re
->uptime
)
4558 * So we are starting up and have received
4559 * routes from the kernel that we have installed
4560 * from a previous run of zebra but not cleaned
4561 * up ( say a kill -9 )
4562 * But since we haven't actually installed
4563 * them yet( we received them from the kernel )
4564 * we don't think they are active.
4565 * So let's pretend they are active to actually
4567 * In all honesty I'm not sure if we should
4568 * mark them as active when we receive them
4569 * This is startup only so probably ok.
4571 * If we ever decide to move rib_sweep_table
4572 * to a different spot (ie startup )
4573 * this decision needs to be revisited
4575 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
4576 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4577 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
4579 rib_uninstall_kernel(rn
, re
);
4580 rib_delnode(rn
, re
);
4584 if (IS_ZEBRA_DEBUG_RIB
)
4585 zlog_debug("%s: ends", __func__
);
4588 /* Sweep all RIB tables. */
4589 void rib_sweep_route(struct event
*t
)
4592 struct zebra_vrf
*zvrf
;
4594 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4595 if ((zvrf
= vrf
->info
) == NULL
)
4598 rib_sweep_table(zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
4599 rib_sweep_table(zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4602 zebra_router_sweep_route();
4603 zebra_router_sweep_nhgs();
4606 /* Remove specific by protocol routes from 'table'. */
4607 unsigned long rib_score_proto_table(uint8_t proto
, unsigned short instance
,
4608 struct route_table
*table
)
4610 struct route_node
*rn
;
4611 struct route_entry
*re
;
4612 struct route_entry
*next
;
4613 unsigned long n
= 0;
4616 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
4617 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4618 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4620 if (re
->type
== proto
4621 && re
->instance
== instance
) {
4622 rib_delnode(rn
, re
);
4629 /* Remove specific by protocol routes. */
4630 unsigned long rib_score_proto(uint8_t proto
, unsigned short instance
)
4633 struct zebra_vrf
*zvrf
;
4634 struct other_route_table
*ort
;
4635 unsigned long cnt
= 0;
4637 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4642 cnt
+= rib_score_proto_table(proto
, instance
,
4643 zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
4644 + rib_score_proto_table(
4646 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4648 frr_each(otable
, &zvrf
->other_tables
, ort
) cnt
+=
4649 rib_score_proto_table(proto
, instance
, ort
->table
);
4655 /* Close RIB and clean up kernel routes. */
4656 void rib_close_table(struct route_table
*table
)
4658 struct route_node
*rn
;
4664 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4665 dest
= rib_dest_from_rnode(rn
);
4667 if (dest
&& dest
->selected_fib
) {
4668 rib_uninstall_kernel(rn
, dest
->selected_fib
);
4669 dest
->selected_fib
= NULL
;
4675 * Handler for async dataplane results after a pseudowire installation
4677 static void handle_pw_result(struct zebra_dplane_ctx
*ctx
)
4679 struct zebra_pw
*pw
;
4680 struct zebra_vrf
*vrf
;
4682 /* The pseudowire code assumes success - we act on an error
4683 * result for installation attempts here.
4685 if (dplane_ctx_get_op(ctx
) != DPLANE_OP_PW_INSTALL
)
4688 if (dplane_ctx_get_status(ctx
) != ZEBRA_DPLANE_REQUEST_SUCCESS
) {
4689 vrf
= zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
4690 pw
= zebra_pw_find(vrf
, dplane_ctx_get_ifname(ctx
));
4692 zebra_pw_install_failure(pw
,
4693 dplane_ctx_get_pw_status(ctx
));
4698 * Handle results from the dataplane system. Dequeue update context
4699 * structs, dispatch to appropriate internal handlers.
4701 static void rib_process_dplane_results(struct event
*thread
)
4703 struct zebra_dplane_ctx
*ctx
;
4704 struct dplane_ctx_list_head ctxlist
;
4705 bool shut_p
= false;
4707 #ifdef HAVE_SCRIPTING
4709 frrscript_names_get_script_name(ZEBRA_ON_RIB_PROCESS_HOOK_CALL
);
4712 struct frrscript
*fs
= NULL
;
4715 fs
= frrscript_new(script_name
);
4717 ret
= frrscript_load(fs
, ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4720 #endif /* HAVE_SCRIPTING */
4722 /* Dequeue a list of completed updates with one lock/unlock cycle */
4725 dplane_ctx_q_init(&ctxlist
);
4727 /* Take lock controlling queue of results */
4728 frr_with_mutex (&dplane_mutex
) {
4729 /* Dequeue list of context structs */
4730 dplane_ctx_list_append(&ctxlist
, &rib_dplane_q
);
4733 /* Dequeue context block */
4734 ctx
= dplane_ctx_dequeue(&ctxlist
);
4736 /* If we've emptied the results queue, we're done */
4740 /* If zebra is shutting down, avoid processing results,
4741 * just drain the results queue.
4743 shut_p
= atomic_load_explicit(&zrouter
.in_shutdown
,
4744 memory_order_relaxed
);
4747 dplane_ctx_fini(&ctx
);
4749 ctx
= dplane_ctx_dequeue(&ctxlist
);
4756 #ifdef HAVE_SCRIPTING
4759 ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4761 #endif /* HAVE_SCRIPTING */
4763 switch (dplane_ctx_get_op(ctx
)) {
4764 case DPLANE_OP_ROUTE_INSTALL
:
4765 case DPLANE_OP_ROUTE_UPDATE
:
4766 case DPLANE_OP_ROUTE_DELETE
:
4767 /* Bit of special case for route updates
4768 * that were generated by async notifications:
4769 * we don't want to continue processing these
4772 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4773 rib_process_result(ctx
);
4776 case DPLANE_OP_ROUTE_NOTIFY
:
4777 rib_process_dplane_notify(ctx
);
4780 case DPLANE_OP_NH_INSTALL
:
4781 case DPLANE_OP_NH_UPDATE
:
4782 case DPLANE_OP_NH_DELETE
:
4783 zebra_nhg_dplane_result(ctx
);
4786 case DPLANE_OP_LSP_INSTALL
:
4787 case DPLANE_OP_LSP_UPDATE
:
4788 case DPLANE_OP_LSP_DELETE
:
4789 /* Bit of special case for LSP updates
4790 * that were generated by async notifications:
4791 * we don't want to continue processing these.
4793 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4794 zebra_mpls_lsp_dplane_result(ctx
);
4797 case DPLANE_OP_LSP_NOTIFY
:
4798 zebra_mpls_process_dplane_notify(ctx
);
4801 case DPLANE_OP_PW_INSTALL
:
4802 case DPLANE_OP_PW_UNINSTALL
:
4803 handle_pw_result(ctx
);
4806 case DPLANE_OP_SYS_ROUTE_ADD
:
4807 case DPLANE_OP_SYS_ROUTE_DELETE
:
4810 case DPLANE_OP_MAC_INSTALL
:
4811 case DPLANE_OP_MAC_DELETE
:
4812 zebra_vxlan_handle_result(ctx
);
4815 case DPLANE_OP_RULE_ADD
:
4816 case DPLANE_OP_RULE_DELETE
:
4817 case DPLANE_OP_RULE_UPDATE
:
4818 case DPLANE_OP_IPTABLE_ADD
:
4819 case DPLANE_OP_IPTABLE_DELETE
:
4820 case DPLANE_OP_IPSET_ADD
:
4821 case DPLANE_OP_IPSET_DELETE
:
4822 case DPLANE_OP_IPSET_ENTRY_ADD
:
4823 case DPLANE_OP_IPSET_ENTRY_DELETE
:
4824 zebra_pbr_dplane_result(ctx
);
4827 case DPLANE_OP_INTF_ADDR_ADD
:
4828 case DPLANE_OP_INTF_ADDR_DEL
:
4829 case DPLANE_OP_INTF_INSTALL
:
4830 case DPLANE_OP_INTF_UPDATE
:
4831 case DPLANE_OP_INTF_DELETE
:
4832 case DPLANE_OP_INTF_NETCONFIG
:
4833 zebra_if_dplane_result(ctx
);
4836 case DPLANE_OP_TC_QDISC_INSTALL
:
4837 case DPLANE_OP_TC_QDISC_UNINSTALL
:
4838 case DPLANE_OP_TC_CLASS_ADD
:
4839 case DPLANE_OP_TC_CLASS_DELETE
:
4840 case DPLANE_OP_TC_CLASS_UPDATE
:
4841 case DPLANE_OP_TC_FILTER_ADD
:
4842 case DPLANE_OP_TC_FILTER_DELETE
:
4843 case DPLANE_OP_TC_FILTER_UPDATE
:
4846 /* Some op codes not handled here */
4847 case DPLANE_OP_ADDR_INSTALL
:
4848 case DPLANE_OP_ADDR_UNINSTALL
:
4849 case DPLANE_OP_NEIGH_INSTALL
:
4850 case DPLANE_OP_NEIGH_UPDATE
:
4851 case DPLANE_OP_NEIGH_DELETE
:
4852 case DPLANE_OP_NEIGH_IP_INSTALL
:
4853 case DPLANE_OP_NEIGH_IP_DELETE
:
4854 case DPLANE_OP_VTEP_ADD
:
4855 case DPLANE_OP_VTEP_DELETE
:
4856 case DPLANE_OP_NEIGH_DISCOVER
:
4857 case DPLANE_OP_BR_PORT_UPDATE
:
4858 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
4859 case DPLANE_OP_GRE_SET
:
4860 case DPLANE_OP_NONE
:
4863 } /* Dispatch by op code */
4865 dplane_ctx_fini(&ctx
);
4866 ctx
= dplane_ctx_dequeue(&ctxlist
);
4871 #ifdef HAVE_SCRIPTING
4873 frrscript_delete(fs
);
4878 * Results are returned from the dataplane subsystem, in the context of
4879 * the dataplane pthread. We enqueue the results here for processing by
4880 * the main thread later.
4882 static int rib_dplane_results(struct dplane_ctx_list_head
*ctxlist
)
4884 /* Take lock controlling queue of results */
4885 frr_with_mutex (&dplane_mutex
) {
4886 /* Enqueue context blocks */
4887 dplane_ctx_list_append(&rib_dplane_q
, ctxlist
);
4890 /* Ensure event is signalled to zebra main pthread */
4891 event_add_event(zrouter
.master
, rib_process_dplane_results
, NULL
, 0,
4898 * Ensure there are no empty slots in the route_info array.
4899 * Every route type in zebra should be present there.
4901 static void check_route_info(void)
4903 int len
= array_size(route_info
);
4906 * ZEBRA_ROUTE_SYSTEM is special cased since
4907 * its key is 0 anyway.
4909 * ZEBRA_ROUTE_ALL is also ignored.
4911 for (int i
= 0; i
< len
; i
++) {
4912 assert(route_info
[i
].key
>= ZEBRA_ROUTE_SYSTEM
&&
4913 route_info
[i
].key
< ZEBRA_ROUTE_MAX
);
4914 assert(route_info
[i
].meta_q_map
< MQ_SIZE
);
4918 /* Routing information base initialize. */
4925 /* Init dataplane, and register for results */
4926 pthread_mutex_init(&dplane_mutex
, NULL
);
4927 dplane_ctx_q_init(&rib_dplane_q
);
4928 zebra_dplane_init(rib_dplane_results
);
4934 * Get the first vrf id that is greater than the given vrf id if any.
4936 * Returns true if a vrf id was found, false otherwise.
4938 static inline int vrf_id_get_next(vrf_id_t vrf_id
, vrf_id_t
*next_id_p
)
4942 vrf
= vrf_lookup_by_id(vrf_id
);
4944 vrf
= RB_NEXT(vrf_id_head
, vrf
);
4946 *next_id_p
= vrf
->vrf_id
;
4955 * rib_tables_iter_next
4957 * Returns the next table in the iteration.
4959 struct route_table
*rib_tables_iter_next(rib_tables_iter_t
*iter
)
4961 struct route_table
*table
;
4964 * Array that helps us go over all AFI/SAFI combinations via one
4967 static const struct {
4971 {AFI_IP
, SAFI_UNICAST
}, {AFI_IP
, SAFI_MULTICAST
},
4972 {AFI_IP
, SAFI_LABELED_UNICAST
}, {AFI_IP6
, SAFI_UNICAST
},
4973 {AFI_IP6
, SAFI_MULTICAST
}, {AFI_IP6
, SAFI_LABELED_UNICAST
},
4978 switch (iter
->state
) {
4980 case RIB_TABLES_ITER_S_INIT
:
4981 iter
->vrf_id
= VRF_DEFAULT
;
4982 iter
->afi_safi_ix
= -1;
4986 case RIB_TABLES_ITER_S_ITERATING
:
4987 iter
->afi_safi_ix
++;
4990 while (iter
->afi_safi_ix
4991 < (int)array_size(afi_safis
)) {
4992 table
= zebra_vrf_table(
4993 afi_safis
[iter
->afi_safi_ix
].afi
,
4994 afi_safis
[iter
->afi_safi_ix
].safi
,
4999 iter
->afi_safi_ix
++;
5003 * Found another table in this vrf.
5009 * Done with all tables in the current vrf, go to the
5013 if (!vrf_id_get_next(iter
->vrf_id
, &iter
->vrf_id
))
5016 iter
->afi_safi_ix
= 0;
5021 case RIB_TABLES_ITER_S_DONE
:
5026 iter
->state
= RIB_TABLES_ITER_S_ITERATING
;
5028 iter
->state
= RIB_TABLES_ITER_S_DONE
;