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
));
67 /* Meta Q's specific names */
68 enum meta_queue_indexes
{
71 META_QUEUE_EARLY_ROUTE
,
72 META_QUEUE_EARLY_LABEL
,
81 /* Each route type's string and default distance value. */
85 enum meta_queue_indexes meta_q_map
;
86 } route_info
[ZEBRA_ROUTE_MAX
] = {
89 ZEBRA_MAX_DISTANCE_DEFAULT
/* Unneeded for nhg's */,
91 [ZEBRA_ROUTE_SYSTEM
] = {ZEBRA_ROUTE_SYSTEM
,
92 ZEBRA_KERNEL_DISTANCE_DEFAULT
,
94 [ZEBRA_ROUTE_KERNEL
] = {ZEBRA_ROUTE_KERNEL
,
95 ZEBRA_KERNEL_DISTANCE_DEFAULT
,
97 [ZEBRA_ROUTE_CONNECT
] = {ZEBRA_ROUTE_CONNECT
,
98 ZEBRA_CONNECT_DISTANCE_DEFAULT
,
99 META_QUEUE_CONNECTED
},
100 [ZEBRA_ROUTE_STATIC
] = {ZEBRA_ROUTE_STATIC
,
101 ZEBRA_STATIC_DISTANCE_DEFAULT
,
103 [ZEBRA_ROUTE_RIP
] = {ZEBRA_ROUTE_RIP
, ZEBRA_RIP_DISTANCE_DEFAULT
,
105 [ZEBRA_ROUTE_RIPNG
] = {ZEBRA_ROUTE_RIPNG
, ZEBRA_RIP_DISTANCE_DEFAULT
,
107 [ZEBRA_ROUTE_OSPF
] = {ZEBRA_ROUTE_OSPF
, ZEBRA_OSPF_DISTANCE_DEFAULT
,
109 [ZEBRA_ROUTE_OSPF6
] = {ZEBRA_ROUTE_OSPF6
, ZEBRA_OSPF6_DISTANCE_DEFAULT
,
111 [ZEBRA_ROUTE_ISIS
] = {ZEBRA_ROUTE_ISIS
, ZEBRA_ISIS_DISTANCE_DEFAULT
,
113 [ZEBRA_ROUTE_BGP
] = {ZEBRA_ROUTE_BGP
,
114 ZEBRA_EBGP_DISTANCE_DEFAULT
/* IBGP is 200. */,
116 [ZEBRA_ROUTE_PIM
] = {ZEBRA_ROUTE_PIM
, ZEBRA_MAX_DISTANCE_DEFAULT
,
118 [ZEBRA_ROUTE_EIGRP
] = {ZEBRA_ROUTE_EIGRP
, ZEBRA_EIGRP_DISTANCE_DEFAULT
,
120 [ZEBRA_ROUTE_NHRP
] = {ZEBRA_ROUTE_NHRP
, ZEBRA_NHRP_DISTANCE_DEFAULT
,
122 [ZEBRA_ROUTE_HSLS
] = {ZEBRA_ROUTE_HSLS
, ZEBRA_MAX_DISTANCE_DEFAULT
,
124 [ZEBRA_ROUTE_OLSR
] = {ZEBRA_ROUTE_OLSR
, ZEBRA_MAX_DISTANCE_DEFAULT
,
126 [ZEBRA_ROUTE_TABLE
] = {ZEBRA_ROUTE_TABLE
, ZEBRA_TABLE_DISTANCE_DEFAULT
, META_QUEUE_STATIC
},
127 [ZEBRA_ROUTE_LDP
] = {ZEBRA_ROUTE_LDP
, ZEBRA_LDP_DISTANCE_DEFAULT
,
129 [ZEBRA_ROUTE_VNC
] = {ZEBRA_ROUTE_VNC
, ZEBRA_EBGP_DISTANCE_DEFAULT
,
131 [ZEBRA_ROUTE_VNC_DIRECT
] = {ZEBRA_ROUTE_VNC_DIRECT
,
132 ZEBRA_EBGP_DISTANCE_DEFAULT
,
134 [ZEBRA_ROUTE_VNC_DIRECT_RH
] = {ZEBRA_ROUTE_VNC_DIRECT_RH
,
135 ZEBRA_EBGP_DISTANCE_DEFAULT
,
137 [ZEBRA_ROUTE_BGP_DIRECT
] = {ZEBRA_ROUTE_BGP_DIRECT
,
138 ZEBRA_EBGP_DISTANCE_DEFAULT
,
140 [ZEBRA_ROUTE_BGP_DIRECT_EXT
] = {ZEBRA_ROUTE_BGP_DIRECT_EXT
,
141 ZEBRA_EBGP_DISTANCE_DEFAULT
,
143 [ZEBRA_ROUTE_BABEL
] = {ZEBRA_ROUTE_BABEL
, ZEBRA_BABEL_DISTANCE_DEFAULT
,
145 [ZEBRA_ROUTE_SHARP
] = {ZEBRA_ROUTE_SHARP
, ZEBRA_SHARP_DISTANCE_DEFAULT
,
147 [ZEBRA_ROUTE_PBR
] = {ZEBRA_ROUTE_PBR
, ZEBRA_PBR_DISTANCE_DEFAULT
,
149 [ZEBRA_ROUTE_BFD
] = {ZEBRA_ROUTE_BFD
, ZEBRA_MAX_DISTANCE_DEFAULT
,
151 [ZEBRA_ROUTE_OPENFABRIC
] = {ZEBRA_ROUTE_OPENFABRIC
,
152 ZEBRA_OPENFABRIC_DISTANCE_DEFAULT
,
154 [ZEBRA_ROUTE_VRRP
] = {ZEBRA_ROUTE_VRRP
, ZEBRA_MAX_DISTANCE_DEFAULT
,
156 [ZEBRA_ROUTE_SRTE
] = {ZEBRA_ROUTE_SRTE
, ZEBRA_MAX_DISTANCE_DEFAULT
,
158 [ZEBRA_ROUTE_ALL
] = {ZEBRA_ROUTE_ALL
, ZEBRA_MAX_DISTANCE_DEFAULT
,
160 /* Any new route type added to zebra, should be mirrored here */
162 /* no entry/default: 150 */
165 /* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
166 * from the OS, and an 'nhe' is a nhe update.
168 struct wq_nhg_wrapper
{
172 struct nhg_hash_entry
*nhe
;
176 #define WQ_NHG_WRAPPER_TYPE_CTX 0x01
177 #define WQ_NHG_WRAPPER_TYPE_NHG 0x02
179 /* Wrapper structs for evpn/vxlan workqueue items. */
180 struct wq_evpn_wrapper
{
192 struct ethaddr macaddr
;
193 struct prefix prefix
;
194 struct in_addr vtep_ip
;
197 #define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01
198 #define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02
199 #define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03
200 #define WQ_EVPN_WRAPPER_TYPE_REM_VTEP 0x04
202 enum wq_label_types
{
203 WQ_LABEL_FTN_UNINSTALL
,
204 WQ_LABEL_LABELS_PROCESS
,
207 struct wq_label_wrapper
{
208 enum wq_label_types type
;
212 enum lsp_types_t ltype
;
214 uint8_t route_instance
;
217 struct zapi_labels zl
;
222 static void rib_addnode(struct route_node
*rn
, struct route_entry
*re
,
225 /* %pRN is already a printer for route_nodes that just prints the prefix */
226 #ifdef _FRR_ATTRIBUTE_PRINTFRR
227 #pragma FRR printfrr_ext "%pZN" (struct route_node *)
230 static const char *subqueue2str(enum meta_queue_indexes index
)
234 return "NHG Objects";
235 case META_QUEUE_EVPN
:
236 return "EVPN/VxLan Objects";
237 case META_QUEUE_EARLY_ROUTE
:
238 return "Early Route Processing";
239 case META_QUEUE_EARLY_LABEL
:
240 return "Early Label Handling";
241 case META_QUEUE_CONNECTED
:
242 return "Connected Routes";
243 case META_QUEUE_KERNEL
:
244 return "Kernel Routes";
245 case META_QUEUE_STATIC
:
246 return "Static Routes";
247 case META_QUEUE_NOTBGP
:
248 return "RIP/OSPF/ISIS/EIGRP/NHRP Routes";
251 case META_QUEUE_OTHER
:
252 return "Other Routes";
258 printfrr_ext_autoreg_p("ZN", printfrr_zebra_node
);
259 static ssize_t
printfrr_zebra_node(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
262 struct route_node
*rn
= (struct route_node
*)ptr
;
265 /* just the table number? */
266 if (ea
->fmt
[0] == 't') {
268 struct route_entry
*re
= NULL
;
273 return bputch(buf
, '!');
275 dest
= rib_dest_from_rnode(rn
);
277 re
= re_list_first(&dest
->routes
);
279 rv
+= bprintfrr(buf
, "%u", re
->table
);
281 rv
+= bputch(buf
, '?');
284 char cbuf
[PREFIX_STRLEN
* 2 + 6];
285 struct rib_table_info
*info
;
288 return bputs(buf
, "{(route_node *) NULL}");
290 srcdest_rnode2str(rn
, cbuf
, sizeof(cbuf
));
291 rv
+= bputs(buf
, cbuf
);
293 info
= srcdest_rnode_table_info(rn
);
294 if (info
->safi
== SAFI_MULTICAST
)
295 rv
+= bputs(buf
, " (MRIB)");
300 #define rnode_debug(node, vrf_id, msg, ...) \
301 zlog_debug("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
304 #define rnode_info(node, vrf_id, msg, ...) \
305 zlog_info("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
308 static char *_dump_re_status(const struct route_entry
*re
, char *buf
,
311 if (re
->status
== 0) {
312 snprintfrr(buf
, len
, "None ");
317 buf
, len
, "%s%s%s%s%s%s%s%s",
318 CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
) ? "Removed " : "",
319 CHECK_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
) ? "Changed " : "",
320 CHECK_FLAG(re
->status
, ROUTE_ENTRY_LABELS_CHANGED
)
323 CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
) ? "Queued " : "",
324 CHECK_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
)
327 CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
) ? "Installed "
329 CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
) ? "Failed " : "",
330 CHECK_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
) ? "Fib NHG "
335 uint8_t route_distance(int type
)
339 if ((unsigned)type
>= array_size(route_info
))
342 distance
= route_info
[type
].distance
;
347 int is_zebra_valid_kernel_table(uint32_t table_id
)
350 if ((table_id
== RT_TABLE_UNSPEC
) || (table_id
== RT_TABLE_LOCAL
)
351 || (table_id
== RT_TABLE_COMPAT
))
358 int is_zebra_main_routing_table(uint32_t table_id
)
360 if (table_id
== RT_TABLE_MAIN
)
365 int zebra_check_addr(const struct prefix
*p
)
367 if (p
->family
== AF_INET
) {
370 addr
= p
->u
.prefix4
.s_addr
;
373 if (IPV4_NET127(addr
) || IN_CLASSD(addr
)
374 || IPV4_LINKLOCAL(addr
))
377 if (p
->family
== AF_INET6
) {
378 if (IN6_IS_ADDR_LOOPBACK(&p
->u
.prefix6
))
380 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
386 static void route_entry_attach_ref(struct route_entry
*re
,
387 struct nhg_hash_entry
*new)
390 re
->nhe_id
= new->id
;
391 re
->nhe_installed_id
= 0;
393 zebra_nhg_increment_ref(new);
396 /* Replace (if 'new_nhghe') or clear (if that's NULL) an re's nhe. */
397 int route_entry_update_nhe(struct route_entry
*re
,
398 struct nhg_hash_entry
*new_nhghe
)
401 struct nhg_hash_entry
*old_nhg
= NULL
;
403 if (new_nhghe
== NULL
) {
407 re
->nhe_installed_id
= 0;
412 if ((re
->nhe_id
!= 0) && re
->nhe
&& (re
->nhe
!= new_nhghe
)) {
413 /* Capture previous nhg, if any */
416 route_entry_attach_ref(re
, new_nhghe
);
418 /* This is the first time it's being attached */
419 route_entry_attach_ref(re
, new_nhghe
);
422 /* Detach / deref previous nhg */
424 zebra_nhg_decrement_ref(old_nhg
);
429 void rib_handle_nhg_replace(struct nhg_hash_entry
*old_entry
,
430 struct nhg_hash_entry
*new_entry
)
432 struct zebra_router_table
*zrt
;
433 struct route_node
*rn
;
434 struct route_entry
*re
, *next
;
436 if (IS_ZEBRA_DEBUG_RIB_DETAILED
|| IS_ZEBRA_DEBUG_NHG_DETAIL
)
437 zlog_debug("%s: replacing routes nhe (%u) OLD %p NEW %p",
438 __func__
, new_entry
->id
, new_entry
, old_entry
);
440 /* We have to do them ALL */
441 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
442 for (rn
= route_top(zrt
->table
); rn
;
443 rn
= srcdest_route_next(rn
)) {
444 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
445 if (re
->nhe
&& re
->nhe
== old_entry
)
446 route_entry_update_nhe(re
, new_entry
);
452 struct route_entry
*rib_match(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
,
453 const union g_addr
*addr
,
454 struct route_node
**rn_out
)
457 struct route_table
*table
;
458 struct route_node
*rn
;
459 struct route_entry
*match
= NULL
;
462 table
= zebra_vrf_table(afi
, safi
, vrf_id
);
466 memset(&p
, 0, sizeof(p
));
469 p
.u
.prefix4
= addr
->ipv4
;
470 p
.prefixlen
= IPV4_MAX_BITLEN
;
472 p
.u
.prefix6
= addr
->ipv6
;
473 p
.prefixlen
= IPV6_MAX_BITLEN
;
476 rn
= route_node_match(table
, &p
);
481 route_unlock_node(rn
);
483 dest
= rib_dest_from_rnode(rn
);
484 if (dest
&& dest
->selected_fib
485 && !CHECK_FLAG(dest
->selected_fib
->status
,
486 ROUTE_ENTRY_REMOVED
))
487 match
= dest
->selected_fib
;
489 /* If there is no selected route or matched route is EGP, go up
494 } while (rn
&& rn
->info
== NULL
);
498 if (match
->type
!= ZEBRA_ROUTE_CONNECT
) {
499 if (!CHECK_FLAG(match
->status
,
500 ROUTE_ENTRY_INSTALLED
))
512 struct route_entry
*rib_match_multicast(afi_t afi
, vrf_id_t vrf_id
,
514 struct route_node
**rn_out
)
516 struct route_entry
*re
= NULL
, *mre
= NULL
, *ure
= NULL
;
517 struct route_node
*m_rn
= NULL
, *u_rn
= NULL
;
519 switch (zrouter
.ipv4_multicast_mode
) {
520 case MCAST_MRIB_ONLY
:
521 return rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, rn_out
);
522 case MCAST_URIB_ONLY
:
523 return rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, rn_out
);
524 case MCAST_NO_CONFIG
:
525 case MCAST_MIX_MRIB_FIRST
:
526 re
= mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
528 re
= ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
,
531 case MCAST_MIX_DISTANCE
:
532 mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
533 ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, &u_rn
);
535 re
= ure
->distance
< mre
->distance
? ure
: mre
;
541 case MCAST_MIX_PFXLEN
:
542 mre
= rib_match(afi
, SAFI_MULTICAST
, vrf_id
, gaddr
, &m_rn
);
543 ure
= rib_match(afi
, SAFI_UNICAST
, vrf_id
, gaddr
, &u_rn
);
545 re
= u_rn
->p
.prefixlen
> m_rn
->p
.prefixlen
? ure
: mre
;
554 *rn_out
= (re
== mre
) ? m_rn
: u_rn
;
556 if (IS_ZEBRA_DEBUG_RIB
) {
558 inet_ntop(afi
== AFI_IP
? AF_INET
: AF_INET6
, gaddr
, buf
,
561 zlog_debug("%s: %s: %pRN vrf: %s(%u) found %s, using %s",
562 __func__
, buf
, (re
== mre
) ? m_rn
: u_rn
,
563 vrf_id_to_name(vrf_id
), vrf_id
,
564 mre
? (ure
? "MRIB+URIB" : "MRIB")
565 : ure
? "URIB" : "nothing",
566 re
== ure
? "URIB" : re
== mre
? "MRIB" : "none");
571 struct route_entry
*rib_lookup_ipv4(struct prefix_ipv4
*p
, vrf_id_t vrf_id
)
573 struct route_table
*table
;
574 struct route_node
*rn
;
575 struct route_entry
*match
= NULL
;
579 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
583 rn
= route_node_lookup(table
, (struct prefix
*)p
);
585 /* No route for this prefix. */
590 route_unlock_node(rn
);
591 dest
= rib_dest_from_rnode(rn
);
593 if (dest
&& dest
->selected_fib
594 && !CHECK_FLAG(dest
->selected_fib
->status
, ROUTE_ENTRY_REMOVED
))
595 match
= dest
->selected_fib
;
600 if (match
->type
== ZEBRA_ROUTE_CONNECT
)
603 if (CHECK_FLAG(match
->status
, ROUTE_ENTRY_INSTALLED
))
610 * Is this RIB labeled-unicast? It must be of type BGP and all paths
611 * (nexthops) must have a label.
613 int zebra_rib_labeled_unicast(struct route_entry
*re
)
615 struct nexthop
*nexthop
= NULL
;
617 if (re
->type
!= ZEBRA_ROUTE_BGP
)
620 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
621 if (!nexthop
->nh_label
|| !nexthop
->nh_label
->num_labels
)
627 /* Update flag indicates whether this is a "replace" or not. Currently, this
628 * is only used for IPv4.
630 void rib_install_kernel(struct route_node
*rn
, struct route_entry
*re
,
631 struct route_entry
*old
)
633 struct nexthop
*nexthop
;
634 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
635 struct zebra_vrf
*zvrf
= vrf_info_lookup(re
->vrf_id
);
636 const struct prefix
*p
, *src_p
;
637 enum zebra_dplane_result ret
;
639 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
641 srcdest_rnode_prefixes(rn
, &p
, &src_p
);
643 if (info
->safi
!= SAFI_UNICAST
) {
644 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
645 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
651 * Install the resolved nexthop object first.
653 zebra_nhg_install_kernel(re
->nhe
);
656 * If this is a replace to a new RE let the originator of the RE
657 * know that they've lost
659 if (old
&& (old
!= re
) && (old
->type
!= re
->type
))
660 zsend_route_notify_owner(rn
, old
, ZAPI_ROUTE_BETTER_ADMIN_WON
,
661 info
->afi
, info
->safi
);
663 /* Update fib selection */
664 dest
->selected_fib
= re
;
667 * Make sure we update the FPM any time we send new information to
670 hook_call(rib_update
, rn
, "installing in kernel");
672 /* Send add or update */
674 ret
= dplane_route_update(rn
, re
, old
);
676 ret
= dplane_route_add(rn
, re
);
679 case ZEBRA_DPLANE_REQUEST_QUEUED
:
680 SET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
683 SET_FLAG(old
->status
, ROUTE_ENTRY_QUEUED
);
684 SET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
686 /* Free old FIB nexthop group */
687 UNSET_FLAG(old
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
688 if (old
->fib_ng
.nexthop
) {
689 nexthops_free(old
->fib_ng
.nexthop
);
690 old
->fib_ng
.nexthop
= NULL
;
695 zvrf
->installs_queued
++;
697 case ZEBRA_DPLANE_REQUEST_FAILURE
:
699 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
700 "%u:%u:%pRN: Failed to enqueue dataplane install",
701 re
->vrf_id
, re
->table
, rn
);
704 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
713 /* Uninstall the route from kernel. */
714 void rib_uninstall_kernel(struct route_node
*rn
, struct route_entry
*re
)
716 struct nexthop
*nexthop
;
717 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
718 struct zebra_vrf
*zvrf
= vrf_info_lookup(re
->vrf_id
);
720 if (info
->safi
!= SAFI_UNICAST
) {
721 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
722 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
723 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
728 * Make sure we update the FPM any time we send new information to
731 hook_call(rib_update
, rn
, "uninstalling from kernel");
733 switch (dplane_route_delete(rn
, re
)) {
734 case ZEBRA_DPLANE_REQUEST_QUEUED
:
736 zvrf
->removals_queued
++;
738 case ZEBRA_DPLANE_REQUEST_FAILURE
:
739 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
740 "%u:%pRN: Failed to enqueue dataplane uninstall",
743 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
753 * rib_can_delete_dest
755 * Returns true if the given dest can be deleted from the table.
757 static int rib_can_delete_dest(rib_dest_t
*dest
)
759 if (re_list_first(&dest
->routes
)) {
764 * Unresolved rnh's are stored on the default route's list
766 * dest->rnode can also be the source prefix node in an
767 * ipv6 sourcedest table. Fortunately the prefix of a
768 * source prefix node can never be the default prefix.
770 if (is_default_prefix(&dest
->rnode
->p
))
774 * Don't delete the dest if we have to update the FPM about this
777 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_FPM
)
778 || CHECK_FLAG(dest
->flags
, RIB_DEST_SENT_TO_FPM
))
784 void zebra_rib_evaluate_rn_nexthops(struct route_node
*rn
, uint32_t seq
,
787 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
791 * We are storing the rnh's associated withb
792 * the tracked nexthop as a list of the rn's.
793 * Unresolved rnh's are placed at the top
794 * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
795 * As such for each rn we need to walk up the tree
796 * and see if any rnh's need to see if they
797 * would match a more specific route
800 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
802 "%s: %pRN Being examined for Nexthop Tracking Count: %zd",
804 dest
? rnh_list_count(&dest
->nht
) : 0);
806 if (rt_delete
&& (!dest
|| !rnh_list_count(&dest
->nht
))) {
807 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
808 zlog_debug("%pRN has no tracking NHTs. Bailing",
815 dest
= rib_dest_from_rnode(rn
);
819 * If we have any rnh's stored in the nht list
820 * then we know that this route node was used for
821 * nht resolution and as such we need to call the
822 * nexthop tracking evaluation code
824 frr_each_safe(rnh_list
, &dest
->nht
, rnh
) {
825 struct zebra_vrf
*zvrf
=
826 zebra_vrf_lookup_by_id(rnh
->vrf_id
);
827 struct prefix
*p
= &rnh
->node
->p
;
829 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
831 "%s(%u):%pRN has Nexthop(%pRN) depending on it, evaluating %u:%u",
832 zvrf_name(zvrf
), zvrf_id(zvrf
), rn
,
833 rnh
->node
, seq
, rnh
->seqno
);
836 * If we have evaluated this node on this pass
837 * already, due to following the tree up
838 * then we know that we can move onto the next
841 * Additionally we call zebra_evaluate_rnh
842 * when we gc the dest. In this case we know
843 * that there must be no other re's where
844 * we were originally as such we know that
845 * that sequence number is ok to respect.
847 if (rnh
->seqno
== seq
) {
848 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
850 " Node processed and moved already");
855 zebra_evaluate_rnh(zvrf
, family2afi(p
->family
), 0, p
,
861 dest
= rib_dest_from_rnode(rn
);
868 * Garbage collect the rib dest corresponding to the given route node
871 * Returns true if the dest was deleted, false otherwise.
873 int rib_gc_dest(struct route_node
*rn
)
877 dest
= rib_dest_from_rnode(rn
);
881 if (!rib_can_delete_dest(dest
))
884 if (IS_ZEBRA_DEBUG_RIB
) {
885 struct zebra_vrf
*zvrf
;
887 zvrf
= rib_dest_vrf(dest
);
888 rnode_debug(rn
, zvrf_id(zvrf
), "removing dest from table");
891 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
895 rnh_list_fini(&dest
->nht
);
896 XFREE(MTYPE_RIB_DEST
, dest
);
900 * Release the one reference that we keep on the route node.
902 route_unlock_node(rn
);
906 void zebra_rtable_node_cleanup(struct route_table
*table
,
907 struct route_node
*node
)
909 struct route_entry
*re
, *next
;
911 RNODE_FOREACH_RE_SAFE (node
, re
, next
) {
912 rib_unlink(node
, re
);
916 rib_dest_t
*dest
= node
->info
;
918 /* Remove from update queue of FPM module */
919 hook_call(rib_shutdown
, node
);
921 rnh_list_fini(&dest
->nht
);
922 XFREE(MTYPE_RIB_DEST
, node
->info
);
926 static void rib_process_add_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
927 struct route_entry
*new)
929 hook_call(rib_update
, rn
, "new route selected");
931 /* Update real nexthop. This may actually determine if nexthop is active
933 if (!nexthop_group_active_nexthop_num(&(new->nhe
->nhg
))) {
934 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
938 if (IS_ZEBRA_DEBUG_RIB
)
939 zlog_debug("%s(%u:%u):%pRN: Adding route rn %p, re %p (%s)",
940 zvrf_name(zvrf
), zvrf_id(zvrf
), new->table
, rn
, rn
,
941 new, zebra_route_string(new->type
));
943 /* If labeled-unicast route, install transit LSP. */
944 if (zebra_rib_labeled_unicast(new))
945 zebra_mpls_lsp_install(zvrf
, rn
, new);
947 rib_install_kernel(rn
, new, NULL
);
949 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
952 static void rib_process_del_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
953 struct route_entry
*old
)
955 hook_call(rib_update
, rn
, "removing existing route");
957 /* Uninstall from kernel. */
958 if (IS_ZEBRA_DEBUG_RIB
)
959 zlog_debug("%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s)",
960 zvrf_name(zvrf
), zvrf_id(zvrf
), old
->table
, rn
, rn
,
961 old
, zebra_route_string(old
->type
));
963 /* If labeled-unicast route, uninstall transit LSP. */
964 if (zebra_rib_labeled_unicast(old
))
965 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
967 rib_uninstall_kernel(rn
, old
);
969 /* Update nexthop for route, reset changed flag. */
970 /* Note: this code also handles the Linux case when an interface goes
971 * down, causing the kernel to delete routes without sending DELROUTE
974 if (RIB_KERNEL_ROUTE(old
))
975 SET_FLAG(old
->status
, ROUTE_ENTRY_REMOVED
);
977 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
980 static void rib_process_update_fib(struct zebra_vrf
*zvrf
,
981 struct route_node
*rn
,
982 struct route_entry
*old
,
983 struct route_entry
*new)
988 * We have to install or update if a new route has been selected or
989 * something has changed.
991 if (new != old
|| CHECK_FLAG(new->status
, ROUTE_ENTRY_CHANGED
)) {
992 hook_call(rib_update
, rn
, "updating existing route");
994 /* Update the nexthop; we could determine here that nexthop is
996 if (nexthop_group_active_nexthop_num(&(new->nhe
->nhg
)))
999 /* If nexthop is active, install the selected route, if
1001 * the install succeeds, cleanup flags for prior route, if
1006 if (IS_ZEBRA_DEBUG_RIB
) {
1009 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s) old %p (%s)",
1010 zvrf_name(zvrf
), zvrf_id(zvrf
),
1011 new->table
, rn
, rn
, new,
1012 zebra_route_string(new->type
),
1014 zebra_route_string(old
->type
));
1017 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s)",
1018 zvrf_name(zvrf
), zvrf_id(zvrf
),
1019 new->table
, rn
, rn
, new,
1020 zebra_route_string(new->type
));
1023 /* If labeled-unicast route, uninstall transit LSP. */
1024 if (zebra_rib_labeled_unicast(old
))
1025 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1028 * Non-system route should be installed.
1029 * If labeled-unicast route, install transit
1032 if (zebra_rib_labeled_unicast(new))
1033 zebra_mpls_lsp_install(zvrf
, rn
, new);
1035 rib_install_kernel(rn
, new, old
);
1039 * If nexthop for selected route is not active or install
1041 * may need to uninstall and delete for redistribution.
1044 if (IS_ZEBRA_DEBUG_RIB
) {
1047 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
1048 zvrf_name(zvrf
), zvrf_id(zvrf
),
1049 new->table
, rn
, rn
, new,
1050 zebra_route_string(new->type
),
1052 zebra_route_string(old
->type
));
1055 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) - nexthop inactive",
1056 zvrf_name(zvrf
), zvrf_id(zvrf
),
1057 new->table
, rn
, rn
, new,
1058 zebra_route_string(new->type
));
1062 * When we have gotten to this point
1063 * the new route entry has no nexthops
1064 * that are usable and as such we need
1065 * to remove the old route, but only
1066 * if we were the one who installed
1069 if (!RIB_SYSTEM_ROUTE(old
)) {
1070 /* If labeled-unicast route, uninstall transit
1072 if (zebra_rib_labeled_unicast(old
))
1073 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1075 rib_uninstall_kernel(rn
, old
);
1080 * Same route selected; check if in the FIB and if not,
1081 * re-install. This is housekeeping code to deal with
1082 * race conditions in kernel with linux netlink reporting
1083 * interface up before IPv4 or IPv6 protocol is ready
1086 if (!CHECK_FLAG(new->status
, ROUTE_ENTRY_INSTALLED
) ||
1087 RIB_SYSTEM_ROUTE(new))
1088 rib_install_kernel(rn
, new, NULL
);
1091 /* Update prior route. */
1093 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
1095 /* Clear changed flag. */
1096 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
1099 /* Check if 'alternate' RIB entry is better than 'current'. */
1100 static struct route_entry
*rib_choose_best(struct route_entry
*current
,
1101 struct route_entry
*alternate
)
1103 if (current
== NULL
)
1106 /* filter route selection in following order:
1107 * - connected beats other types
1108 * - if both connected, loopback or vrf wins
1109 * - lower distance beats higher
1110 * - lower metric beats higher for equal distance
1111 * - last, hence oldest, route wins tie break.
1114 /* Connected routes. Check to see if either are a vrf
1115 * or loopback interface. If not, pick the last connected
1116 * route of the set of lowest metric connected routes.
1118 if (alternate
->type
== ZEBRA_ROUTE_CONNECT
) {
1119 if (current
->type
!= ZEBRA_ROUTE_CONNECT
)
1122 /* both are connected. are either loop or vrf? */
1123 struct nexthop
*nexthop
= NULL
;
1125 for (ALL_NEXTHOPS(alternate
->nhe
->nhg
, nexthop
)) {
1126 struct interface
*ifp
= if_lookup_by_index(
1127 nexthop
->ifindex
, alternate
->vrf_id
);
1129 if (ifp
&& if_is_loopback(ifp
))
1133 for (ALL_NEXTHOPS(current
->nhe
->nhg
, nexthop
)) {
1134 struct interface
*ifp
= if_lookup_by_index(
1135 nexthop
->ifindex
, current
->vrf_id
);
1137 if (ifp
&& if_is_loopback(ifp
))
1141 /* Neither are loop or vrf so pick best metric */
1142 if (alternate
->metric
<= current
->metric
)
1148 if (current
->type
== ZEBRA_ROUTE_CONNECT
)
1151 /* higher distance loses */
1152 if (alternate
->distance
< current
->distance
)
1154 if (current
->distance
< alternate
->distance
)
1157 /* metric tie-breaks equal distance */
1158 if (alternate
->metric
<= current
->metric
)
1164 /* Core function for processing routing information base. */
1165 static void rib_process(struct route_node
*rn
)
1167 struct route_entry
*re
;
1168 struct route_entry
*next
;
1169 struct route_entry
*old_selected
= NULL
;
1170 struct route_entry
*new_selected
= NULL
;
1171 struct route_entry
*old_fib
= NULL
;
1172 struct route_entry
*new_fib
= NULL
;
1173 struct route_entry
*best
= NULL
;
1175 struct zebra_vrf
*zvrf
= NULL
;
1178 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1182 dest
= rib_dest_from_rnode(rn
);
1184 * We have an enqueued node with nothing to process here
1185 * let's just finish up and return;
1190 zvrf
= rib_dest_vrf(dest
);
1191 vrf_id
= zvrf_id(zvrf
);
1193 vrf
= vrf_lookup_by_id(vrf_id
);
1196 * we can have rn's that have a NULL info pointer
1197 * (dest). As such let's not let the deref happen
1198 * additionally we know RNODE_FOREACH_RE_SAFE
1199 * will not iterate so we are ok.
1201 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1202 struct route_entry
*re
= re_list_first(&dest
->routes
);
1204 zlog_debug("%s(%u:%u):%pRN: Processing rn %p",
1205 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
,
1209 old_fib
= dest
->selected_fib
;
1211 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1212 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1213 char flags_buf
[128];
1214 char status_buf
[128];
1217 "%s(%u:%u):%pRN: Examine re %p (%s) status: %sflags: %sdist %d metric %d",
1218 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
, re
,
1219 zebra_route_string(re
->type
),
1220 _dump_re_status(re
, status_buf
,
1221 sizeof(status_buf
)),
1222 zclient_dump_route_flags(re
->flags
, flags_buf
,
1224 re
->distance
, re
->metric
);
1227 /* Currently selected re. */
1228 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1229 assert(old_selected
== NULL
);
1233 /* Skip deleted entries from selection */
1234 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1238 * If the route entry has changed, verify/resolve
1239 * the nexthops associated with the entry.
1241 * In any event if we have nexthops that are not active
1242 * then we cannot use this particular route entry so
1245 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
)) {
1246 if (!nexthop_active_update(rn
, re
)) {
1247 const struct prefix
*p
;
1248 struct rib_table_info
*info
;
1250 if (re
->type
== ZEBRA_ROUTE_TABLE
) {
1251 /* XXX: HERE BE DRAGONS!!!!!
1252 * In all honesty, I have not yet
1253 * figured out what this part does or
1254 * why the ROUTE_ENTRY_CHANGED test
1255 * above is correct or why we need to
1256 * delete a route here, and also not
1257 * whether this concerns both selected
1258 * and fib route, or only selected
1261 * This entry was denied by the 'ip
1263 * table' route-map, we need to delete
1265 if (re
!= old_selected
) {
1266 if (IS_ZEBRA_DEBUG_RIB
)
1268 "%s: %s(%u):%pRN: imported via import-table but denied by the ip protocol table route-map",
1276 SET_FLAG(re
->status
,
1277 ROUTE_ENTRY_REMOVED
);
1280 info
= srcdest_rnode_table_info(rn
);
1281 srcdest_rnode_prefixes(rn
, &p
, NULL
);
1282 zsend_route_notify_owner(
1283 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
1284 info
->afi
, info
->safi
);
1289 * If the re has not changed and the nhg we have is
1290 * not usable, then we cannot use this route entry
1291 * for consideration, as that the route will just
1292 * not install if it is selected.
1294 if (!nexthop_group_active_nexthop_num(&re
->nhe
->nhg
))
1298 /* Infinite distance. */
1299 if (re
->distance
== DISTANCE_INFINITY
&&
1300 re
->type
!= ZEBRA_ROUTE_KERNEL
) {
1301 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1305 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_FIB_OVERRIDE
)) {
1306 best
= rib_choose_best(new_fib
, re
);
1307 if (new_fib
&& best
!= new_fib
)
1308 UNSET_FLAG(new_fib
->status
,
1309 ROUTE_ENTRY_CHANGED
);
1312 best
= rib_choose_best(new_selected
, re
);
1313 if (new_selected
&& best
!= new_selected
)
1314 UNSET_FLAG(new_selected
->status
,
1315 ROUTE_ENTRY_CHANGED
);
1316 new_selected
= best
;
1319 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1320 } /* RNODE_FOREACH_RE */
1322 /* If no FIB override route, use the selected route also for FIB */
1323 if (new_fib
== NULL
)
1324 new_fib
= new_selected
;
1326 /* After the cycle is finished, the following pointers will be set:
1327 * old_selected --- RE entry currently having SELECTED
1328 * new_selected --- RE entry that is newly SELECTED
1329 * old_fib --- RE entry currently in kernel FIB
1330 * new_fib --- RE entry that is newly to be in kernel FIB
1332 * new_selected will get SELECTED flag, and is going to be redistributed
1333 * the zclients. new_fib (which can be new_selected) will be installed
1337 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1338 struct route_entry
*entry
;
1340 entry
= old_selected
1345 : new_fib
? new_fib
: NULL
;
1348 "%s(%u:%u):%pRN: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
1349 VRF_LOGNAME(vrf
), vrf_id
, entry
? entry
->table
: 0, rn
,
1350 (void *)old_selected
, (void *)new_selected
,
1351 (void *)old_fib
, (void *)new_fib
);
1354 /* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
1355 * fib == selected */
1356 bool selected_changed
= new_selected
&& CHECK_FLAG(new_selected
->status
,
1357 ROUTE_ENTRY_CHANGED
);
1359 /* Update SELECTED entry */
1360 if (old_selected
!= new_selected
|| selected_changed
) {
1362 if (new_selected
&& new_selected
!= new_fib
)
1363 UNSET_FLAG(new_selected
->status
, ROUTE_ENTRY_CHANGED
);
1366 SET_FLAG(new_selected
->flags
, ZEBRA_FLAG_SELECTED
);
1370 * If we're removing the old entry, we should tell
1371 * redist subscribers about that *if* they aren't
1372 * going to see a redist for the new entry.
1374 if (!new_selected
|| CHECK_FLAG(old_selected
->status
,
1375 ROUTE_ENTRY_REMOVED
))
1376 redistribute_delete(rn
, old_selected
,
1379 if (old_selected
!= new_selected
)
1380 UNSET_FLAG(old_selected
->flags
,
1381 ZEBRA_FLAG_SELECTED
);
1385 /* Update fib according to selection results */
1386 if (new_fib
&& old_fib
)
1387 rib_process_update_fib(zvrf
, rn
, old_fib
, new_fib
);
1389 rib_process_add_fib(zvrf
, rn
, new_fib
);
1391 rib_process_del_fib(zvrf
, rn
, old_fib
);
1393 /* Remove all RE entries queued for removal */
1394 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1395 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1396 if (IS_ZEBRA_DEBUG_RIB
) {
1397 rnode_debug(rn
, vrf_id
, "rn %p, removing re %p",
1398 (void *)rn
, (void *)re
);
1405 * Check if the dest can be deleted now.
1410 static void zebra_rib_evaluate_mpls(struct route_node
*rn
)
1412 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
1413 struct zebra_vrf
*zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1418 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_LSPS
)) {
1419 if (IS_ZEBRA_DEBUG_MPLS
)
1421 "%s(%u): Scheduling all LSPs upon RIB completion",
1422 zvrf_name(zvrf
), zvrf_id(zvrf
));
1423 zebra_mpls_lsp_schedule(zvrf
);
1424 mpls_unmark_lsps_for_processing(rn
);
1429 * Utility to match route with dplane context data
1431 static bool rib_route_match_ctx(const struct route_entry
*re
,
1432 const struct zebra_dplane_ctx
*ctx
,
1435 bool result
= false;
1439 * In 'update' case, we test info about the 'previous' or
1442 if ((re
->type
== dplane_ctx_get_old_type(ctx
)) &&
1443 (re
->instance
== dplane_ctx_get_old_instance(ctx
))) {
1446 /* We use an extra test for statics, and another for
1449 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1450 (re
->distance
!= dplane_ctx_get_old_distance(ctx
) ||
1451 re
->tag
!= dplane_ctx_get_old_tag(ctx
))) {
1453 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1455 dplane_ctx_get_old_metric(ctx
)) {
1462 * Ordinary, single-route case using primary context info
1464 if ((dplane_ctx_get_op(ctx
) != DPLANE_OP_ROUTE_DELETE
) &&
1465 CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1466 /* Skip route that's been deleted */
1470 if ((re
->type
== dplane_ctx_get_type(ctx
)) &&
1471 (re
->instance
== dplane_ctx_get_instance(ctx
))) {
1474 /* We use an extra test for statics, and another for
1477 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1478 (re
->distance
!= dplane_ctx_get_distance(ctx
) ||
1479 re
->tag
!= dplane_ctx_get_tag(ctx
))) {
1481 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1482 re
->metric
!= dplane_ctx_get_metric(ctx
)) {
1484 } else if (re
->type
== ZEBRA_ROUTE_CONNECT
) {
1485 result
= nexthop_group_equal_no_recurse(
1486 &re
->nhe
->nhg
, dplane_ctx_get_ng(ctx
));
1495 static void zebra_rib_fixup_system(struct route_node
*rn
)
1497 struct route_entry
*re
;
1499 RNODE_FOREACH_RE(rn
, re
) {
1500 struct nexthop
*nhop
;
1502 if (!RIB_SYSTEM_ROUTE(re
))
1505 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1508 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
1509 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
1510 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
1512 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nhop
)) {
1513 if (CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1516 SET_FLAG(nhop
->flags
, NEXTHOP_FLAG_FIB
);
1521 /* Route comparison logic, with various special cases. */
1522 static bool rib_compare_routes(const struct route_entry
*re1
,
1523 const struct route_entry
*re2
)
1525 if (re1
->type
!= re2
->type
)
1528 if (re1
->instance
!= re2
->instance
)
1531 if (re1
->type
== ZEBRA_ROUTE_KERNEL
&& re1
->metric
!= re2
->metric
)
1534 if (CHECK_FLAG(re1
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
1535 re1
->distance
!= re2
->distance
)
1538 /* We support multiple connected routes: this supports multiple
1539 * v6 link-locals, and we also support multiple addresses in the same
1540 * subnet on a single interface.
1542 if (re1
->type
!= ZEBRA_ROUTE_CONNECT
)
1549 * Compare nexthop lists from a route and a dplane context; test whether
1550 * the list installed in the FIB matches the route's list.
1551 * Set 'changed_p' to 'true' if there were changes to the route's
1552 * installed nexthops.
1554 * Return 'false' if any ACTIVE route nexthops are not mentioned in the FIB
1557 static bool rib_update_nhg_from_ctx(struct nexthop_group
*re_nhg
,
1558 const struct nexthop_group
*ctx_nhg
,
1561 bool matched_p
= true;
1562 struct nexthop
*nexthop
, *ctx_nexthop
;
1564 /* Get the first `installed` one to check against.
1565 * If the dataplane doesn't set these to be what was actually installed,
1566 * it will just be whatever was in re->nhe->nhg?
1568 ctx_nexthop
= ctx_nhg
->nexthop
;
1570 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
1571 || !CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1572 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1574 for (ALL_NEXTHOPS_PTR(re_nhg
, nexthop
)) {
1576 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1579 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1582 /* Check for a FIB nexthop corresponding to the RIB nexthop */
1583 if (!nexthop_same(ctx_nexthop
, nexthop
)) {
1584 /* If the FIB doesn't know about the nexthop,
1585 * it's not installed
1587 if (IS_ZEBRA_DEBUG_RIB_DETAILED
||
1588 IS_ZEBRA_DEBUG_NHG_DETAIL
) {
1589 zlog_debug("%s: no ctx match for rib nh %pNHv %s",
1591 (CHECK_FLAG(nexthop
->flags
,
1597 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1600 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1602 /* Keep checking nexthops */
1606 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1607 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1608 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1609 zlog_debug("%s: rib nh %pNHv -> installed",
1615 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1617 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1618 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1619 zlog_debug("%s: rib nh %pNHv -> uninstalled",
1625 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1628 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1635 * Update a route from a dplane context. This consolidates common code
1636 * that can be used in processing of results from FIB updates, and in
1637 * async notification processing.
1638 * The return is 'true' if the installed nexthops changed; 'false' otherwise.
1640 static bool rib_update_re_from_ctx(struct route_entry
*re
,
1641 struct route_node
*rn
,
1642 struct zebra_dplane_ctx
*ctx
)
1644 struct nexthop
*nexthop
;
1646 const struct nexthop_group
*ctxnhg
;
1647 struct nexthop_group
*re_nhg
;
1648 bool is_selected
= false; /* Is 're' currently the selected re? */
1649 bool changed_p
= false; /* Change to nexthops? */
1653 vrf
= vrf_lookup_by_id(re
->vrf_id
);
1655 dest
= rib_dest_from_rnode(rn
);
1657 is_selected
= (re
== dest
->selected_fib
);
1659 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1660 zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p",
1661 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1662 (is_selected
? "" : "NOT "), re
);
1664 /* Update zebra's nexthop FIB flag for each nexthop that was installed.
1665 * If the installed set differs from the set requested by the rib/owner,
1666 * we use the fib-specific nexthop-group to record the actual FIB
1670 ctxnhg
= dplane_ctx_get_ng(ctx
);
1672 /* Check route's fib group and incoming notif group for equivalence.
1674 * Let's assume the nexthops are ordered here to save time.
1676 /* TODO -- this isn't testing or comparing the FIB flags; we should
1677 * do a more explicit loop, checking the incoming notification's flags.
1679 if (re
->fib_ng
.nexthop
&& ctxnhg
->nexthop
&&
1680 nexthop_group_equal(&re
->fib_ng
, ctxnhg
))
1683 /* If the new FIB set matches the existing FIB set, we're done. */
1685 if (IS_ZEBRA_DEBUG_RIB
)
1687 "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change",
1688 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1691 } else if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
)) {
1693 * Free stale fib list and move on to check the rib nhg.
1695 if (IS_ZEBRA_DEBUG_RIB
)
1697 "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg",
1698 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1699 nexthops_free(re
->fib_ng
.nexthop
);
1700 re
->fib_ng
.nexthop
= NULL
;
1702 UNSET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1704 /* Note that the installed nexthops have changed */
1707 if (IS_ZEBRA_DEBUG_RIB
)
1709 "%s(%u:%u):%pRN update_from_ctx(): no fib nhg",
1710 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1714 * Compare with the rib nexthop group. The comparison here is different:
1715 * the RIB group may be a superset of the list installed in the FIB. We
1716 * walk the RIB group, looking for the 'installable' candidate
1717 * nexthops, and then check those against the set
1718 * that is actually installed.
1720 * Assume nexthops are ordered here as well.
1723 /* If nothing is installed, we can skip some of the checking/comparison
1726 if (ctxnhg
->nexthop
== NULL
) {
1731 matched
= rib_update_nhg_from_ctx(&(re
->nhe
->nhg
), ctxnhg
, &changed_p
);
1733 /* If all nexthops were processed, we're done */
1735 if (IS_ZEBRA_DEBUG_RIB
)
1737 "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'",
1738 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1739 (changed_p
? "true" : "false"));
1745 /* FIB nexthop set differs from the RIB set:
1746 * create a fib-specific nexthop-group
1748 if (IS_ZEBRA_DEBUG_RIB
)
1750 "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s",
1751 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1752 (changed_p
? "true" : "false"),
1753 ctxnhg
->nexthop
!= NULL
? "" : " (empty)");
1755 /* Set the flag about the dedicated fib list */
1756 if (zrouter
.asic_notification_nexthop_control
) {
1757 SET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1758 if (ctxnhg
->nexthop
)
1759 copy_nexthops(&(re
->fib_ng
.nexthop
), ctxnhg
->nexthop
,
1766 * Check the status of the route's backup nexthops, if any.
1767 * The logic for backups is somewhat different: if any backup is
1768 * installed, a new fib nhg will be attached to the route.
1770 re_nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1772 goto done
; /* No backup nexthops */
1774 /* First check the route's 'fib' list of backups, if it's present
1775 * from some previous event.
1777 re_nhg
= &re
->fib_backup_ng
;
1778 ctxnhg
= dplane_ctx_get_backup_ng(ctx
);
1781 if (re_nhg
->nexthop
&& ctxnhg
&& nexthop_group_equal(re_nhg
, ctxnhg
))
1784 /* If the new FIB set matches an existing FIB set, we're done. */
1786 if (IS_ZEBRA_DEBUG_RIB
)
1788 "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change",
1789 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1792 } else if (re
->fib_backup_ng
.nexthop
) {
1794 * Free stale fib backup list and move on to check
1795 * the route's backups.
1797 if (IS_ZEBRA_DEBUG_RIB
)
1799 "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg",
1800 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1801 nexthops_free(re
->fib_backup_ng
.nexthop
);
1802 re
->fib_backup_ng
.nexthop
= NULL
;
1804 /* Note that the installed nexthops have changed */
1807 if (IS_ZEBRA_DEBUG_RIB
)
1809 "%s(%u):%pRN update_from_ctx(): no fib backup nhg",
1810 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1814 * If a FIB backup nexthop set exists, attach a copy
1815 * to the route if any backup is installed
1817 if (ctxnhg
&& ctxnhg
->nexthop
) {
1819 for (ALL_NEXTHOPS_PTR(ctxnhg
, nexthop
)) {
1820 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1824 /* If no installed backups, we're done */
1825 if (nexthop
== NULL
)
1828 if (IS_ZEBRA_DEBUG_RIB
)
1830 "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg",
1831 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
,
1832 (changed_p
? "true" : "false"));
1834 copy_nexthops(&(re
->fib_backup_ng
.nexthop
), ctxnhg
->nexthop
,
1844 * Helper to locate a zebra route-node from a dplane context. This is used
1845 * when processing dplane results, e.g. Note well: the route-node is returned
1846 * with a ref held - route_unlock_node() must be called eventually.
1848 struct route_node
*rib_find_rn_from_ctx(const struct zebra_dplane_ctx
*ctx
)
1850 struct route_table
*table
= NULL
;
1851 struct route_node
*rn
= NULL
;
1852 const struct prefix
*dest_pfx
, *src_pfx
;
1854 /* Locate rn and re(s) from ctx */
1856 table
= zebra_vrf_lookup_table_with_table_id(
1857 dplane_ctx_get_afi(ctx
), dplane_ctx_get_safi(ctx
),
1858 dplane_ctx_get_vrf(ctx
), dplane_ctx_get_table(ctx
));
1859 if (table
== NULL
) {
1860 if (IS_ZEBRA_DEBUG_DPLANE
) {
1862 "Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u)",
1863 dplane_ctx_get_afi(ctx
),
1864 dplane_ctx_get_safi(ctx
),
1865 vrf_id_to_name(dplane_ctx_get_vrf(ctx
)),
1866 dplane_ctx_get_vrf(ctx
));
1871 dest_pfx
= dplane_ctx_get_dest(ctx
);
1872 src_pfx
= dplane_ctx_get_src(ctx
);
1874 rn
= srcdest_rnode_get(table
, dest_pfx
,
1875 src_pfx
? (struct prefix_ipv6
*)src_pfx
: NULL
);
1884 * Route-update results processing after async dataplane update.
1886 static void rib_process_result(struct zebra_dplane_ctx
*ctx
)
1888 struct zebra_vrf
*zvrf
= NULL
;
1890 struct route_node
*rn
= NULL
;
1891 struct route_entry
*re
= NULL
, *old_re
= NULL
, *rib
;
1892 bool is_update
= false;
1893 enum dplane_op_e op
;
1894 enum zebra_dplane_result status
;
1897 bool fib_changed
= false;
1898 struct rib_table_info
*info
;
1899 bool rt_delete
= false;
1901 zvrf
= vrf_info_lookup(dplane_ctx_get_vrf(ctx
));
1902 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
1904 /* Locate rn and re(s) from ctx */
1905 rn
= rib_find_rn_from_ctx(ctx
);
1907 if (IS_ZEBRA_DEBUG_DPLANE
) {
1909 "Failed to process dplane results: no route for %s(%u):%pRN",
1910 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
), rn
);
1915 dest
= rib_dest_from_rnode(rn
);
1916 info
= srcdest_rnode_table_info(rn
);
1918 op
= dplane_ctx_get_op(ctx
);
1919 status
= dplane_ctx_get_status(ctx
);
1921 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1923 "%s(%u:%u):%pRN Processing dplane result ctx %p, op %s result %s",
1924 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
1925 dplane_ctx_get_table(ctx
), rn
, ctx
, dplane_op2str(op
),
1926 dplane_res2str(status
));
1929 * Update is a bit of a special case, where we may have both old and new
1930 * routes to post-process.
1932 is_update
= dplane_ctx_is_update(ctx
);
1935 * Take a pass through the routes, look for matches with the context
1938 RNODE_FOREACH_RE(rn
, rib
) {
1941 if (rib_route_match_ctx(rib
, ctx
, false))
1945 /* Check for old route match */
1946 if (is_update
&& (old_re
== NULL
)) {
1947 if (rib_route_match_ctx(rib
, ctx
, true /*is_update*/))
1951 /* Have we found the routes we need to work on? */
1952 if (re
&& ((!is_update
|| old_re
)))
1956 seq
= dplane_ctx_get_seq(ctx
);
1959 * Check sequence number(s) to detect stale results before continuing
1962 if (re
->dplane_sequence
!= seq
) {
1963 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1965 "%s(%u):%pRN Stale dplane result for re %p",
1967 dplane_ctx_get_vrf(ctx
), rn
, re
);
1969 if (!zrouter
.asic_offloaded
||
1970 (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
) ||
1971 CHECK_FLAG(re
->flags
,
1972 ZEBRA_FLAG_OFFLOAD_FAILED
))) {
1973 UNSET_FLAG(re
->status
,
1974 ROUTE_ENTRY_ROUTE_REPLACING
);
1975 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
1981 if (old_re
->dplane_sequence
!= dplane_ctx_get_old_seq(ctx
)) {
1982 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1984 "%s(%u:%u):%pRN Stale dplane result for old_re %p",
1986 dplane_ctx_get_vrf(ctx
), old_re
->table
,
1989 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_QUEUED
);
1993 case DPLANE_OP_ROUTE_INSTALL
:
1994 case DPLANE_OP_ROUTE_UPDATE
:
1995 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
1997 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
1998 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2001 * On an update operation from the same route type
2002 * context retrieval currently has no way to know
2003 * which was the old and which was the new.
2004 * So don't unset our flags that we just set.
2005 * We know redistribution is ok because the
2006 * old_re in this case is used for nothing
2007 * more than knowing whom to contact if necessary.
2009 if (old_re
&& old_re
!= re
) {
2010 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2011 UNSET_FLAG(old_re
->status
,
2012 ROUTE_ENTRY_INSTALLED
);
2015 /* Update zebra route based on the results in
2016 * the context struct.
2020 rib_update_re_from_ctx(re
, rn
, ctx
);
2023 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
2025 "%s(%u:%u):%pRN no fib change for re",
2027 dplane_ctx_get_vrf(ctx
),
2028 dplane_ctx_get_table(
2033 /* Redistribute if this is the selected re */
2034 if (dest
&& re
== dest
->selected_fib
)
2035 redistribute_update(rn
, re
, old_re
);
2039 * System routes are weird in that they
2040 * allow multiple to be installed that match
2041 * to the same prefix, so after we get the
2042 * result we need to clean them up so that
2043 * we can actually use them.
2045 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2046 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2047 zebra_rib_fixup_system(rn
);
2052 /* Notify route owner */
2053 if (zebra_router_notify_on_ack())
2054 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2057 if (CHECK_FLAG(re
->flags
,
2058 ZEBRA_FLAG_OFFLOADED
))
2059 zsend_route_notify_owner_ctx(
2061 ZAPI_ROUTE_INSTALLED
);
2064 ZEBRA_FLAG_OFFLOAD_FAILED
))
2065 zsend_route_notify_owner_ctx(
2067 ZAPI_ROUTE_FAIL_INSTALL
);
2072 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2073 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2075 SET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2077 zsend_route_notify_owner(
2078 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
2079 info
->afi
, info
->safi
);
2081 zlog_warn("%s(%u:%u):%pRN: Route install failed",
2082 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2083 dplane_ctx_get_table(ctx
), rn
);
2086 case DPLANE_OP_ROUTE_DELETE
:
2089 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2091 * In the delete case, the zebra core datastructs were
2092 * updated (or removed) at the time the delete was issued,
2093 * so we're just notifying the route owner.
2095 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
2097 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2098 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2100 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_REMOVED
);
2106 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2107 zsend_route_notify_owner_ctx(ctx
,
2108 ZAPI_ROUTE_REMOVE_FAIL
);
2110 zlog_warn("%s(%u:%u):%pRN: Route Deletion failure",
2111 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2112 dplane_ctx_get_table(ctx
), rn
);
2116 * System routes are weird in that they
2117 * allow multiple to be installed that match
2118 * to the same prefix, so after we get the
2119 * result we need to clean them up so that
2120 * we can actually use them.
2122 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2123 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2124 zebra_rib_fixup_system(rn
);
2127 case DPLANE_OP_NONE
:
2128 case DPLANE_OP_ROUTE_NOTIFY
:
2129 case DPLANE_OP_NH_INSTALL
:
2130 case DPLANE_OP_NH_UPDATE
:
2131 case DPLANE_OP_NH_DELETE
:
2132 case DPLANE_OP_LSP_INSTALL
:
2133 case DPLANE_OP_LSP_UPDATE
:
2134 case DPLANE_OP_LSP_DELETE
:
2135 case DPLANE_OP_LSP_NOTIFY
:
2136 case DPLANE_OP_PW_INSTALL
:
2137 case DPLANE_OP_PW_UNINSTALL
:
2138 case DPLANE_OP_SYS_ROUTE_ADD
:
2139 case DPLANE_OP_SYS_ROUTE_DELETE
:
2140 case DPLANE_OP_ADDR_INSTALL
:
2141 case DPLANE_OP_ADDR_UNINSTALL
:
2142 case DPLANE_OP_MAC_INSTALL
:
2143 case DPLANE_OP_MAC_DELETE
:
2144 case DPLANE_OP_NEIGH_INSTALL
:
2145 case DPLANE_OP_NEIGH_UPDATE
:
2146 case DPLANE_OP_NEIGH_DELETE
:
2147 case DPLANE_OP_VTEP_ADD
:
2148 case DPLANE_OP_VTEP_DELETE
:
2149 case DPLANE_OP_RULE_ADD
:
2150 case DPLANE_OP_RULE_DELETE
:
2151 case DPLANE_OP_RULE_UPDATE
:
2152 case DPLANE_OP_NEIGH_DISCOVER
:
2153 case DPLANE_OP_BR_PORT_UPDATE
:
2154 case DPLANE_OP_IPTABLE_ADD
:
2155 case DPLANE_OP_IPTABLE_DELETE
:
2156 case DPLANE_OP_IPSET_ADD
:
2157 case DPLANE_OP_IPSET_DELETE
:
2158 case DPLANE_OP_IPSET_ENTRY_ADD
:
2159 case DPLANE_OP_IPSET_ENTRY_DELETE
:
2160 case DPLANE_OP_NEIGH_IP_INSTALL
:
2161 case DPLANE_OP_NEIGH_IP_DELETE
:
2162 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
2163 case DPLANE_OP_GRE_SET
:
2164 case DPLANE_OP_INTF_ADDR_ADD
:
2165 case DPLANE_OP_INTF_ADDR_DEL
:
2166 case DPLANE_OP_INTF_NETCONFIG
:
2167 case DPLANE_OP_INTF_INSTALL
:
2168 case DPLANE_OP_INTF_UPDATE
:
2169 case DPLANE_OP_INTF_DELETE
:
2170 case DPLANE_OP_TC_QDISC_INSTALL
:
2171 case DPLANE_OP_TC_QDISC_UNINSTALL
:
2172 case DPLANE_OP_TC_CLASS_ADD
:
2173 case DPLANE_OP_TC_CLASS_DELETE
:
2174 case DPLANE_OP_TC_CLASS_UPDATE
:
2175 case DPLANE_OP_TC_FILTER_ADD
:
2176 case DPLANE_OP_TC_FILTER_DELETE
:
2177 case DPLANE_OP_TC_FILTER_UPDATE
:
2181 zebra_rib_evaluate_rn_nexthops(rn
, seq
, rt_delete
);
2182 zebra_rib_evaluate_mpls(rn
);
2186 route_unlock_node(rn
);
2190 * Count installed/FIB nexthops
2192 static int rib_count_installed_nh(struct route_entry
*re
)
2195 struct nexthop
*nexthop
;
2196 struct nexthop_group
*nhg
;
2198 nhg
= rib_get_fib_nhg(re
);
2200 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2201 /* The meaningful flag depends on where the installed
2204 if (nhg
== &(re
->fib_ng
)) {
2205 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2208 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2213 nhg
= rib_get_fib_backup_nhg(re
);
2215 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2216 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2225 * Handle notification from async dataplane: the dataplane has detected
2226 * some change to a route, and notifies zebra so that the control plane
2227 * can reflect that change.
2229 static void rib_process_dplane_notify(struct zebra_dplane_ctx
*ctx
)
2231 struct route_node
*rn
= NULL
;
2232 struct route_entry
*re
= NULL
;
2234 struct nexthop
*nexthop
;
2236 bool fib_changed
= false;
2237 bool debug_p
= IS_ZEBRA_DEBUG_DPLANE
| IS_ZEBRA_DEBUG_RIB
;
2238 int start_count
, end_count
;
2240 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
2242 /* Locate rn and re(s) from ctx */
2243 rn
= rib_find_rn_from_ctx(ctx
);
2247 "Failed to process dplane notification: no routes for %s(%u:%u):%pRN",
2248 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2249 dplane_ctx_get_table(ctx
), rn
);
2254 dest
= rib_dest_from_rnode(rn
);
2257 zlog_debug("%s(%u:%u):%pRN Processing dplane notif ctx %p",
2258 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2259 dplane_ctx_get_table(ctx
), rn
, ctx
);
2262 * Take a pass through the routes, look for matches with the context
2265 RNODE_FOREACH_RE(rn
, re
) {
2266 if (rib_route_match_ctx(re
, ctx
, false /*!update*/))
2270 /* No match? Nothing we can do */
2274 "%s(%u:%u):%pRN Unable to process dplane notification: no entry for type %s",
2275 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2276 dplane_ctx_get_table(ctx
), rn
,
2277 zebra_route_string(dplane_ctx_get_type(ctx
)));
2282 /* Ensure we clear the QUEUED flag */
2283 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
2284 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
2286 /* Is this a notification that ... matters? We mostly care about
2287 * the route that is currently selected for installation; we may also
2288 * get an un-install notification, and handle that too.
2290 if (re
!= dest
->selected_fib
) {
2292 * If we need to, clean up after a delete that was part of
2293 * an update operation.
2296 for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx
), nexthop
)) {
2297 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2301 /* If no nexthops or none installed, ensure that this re
2302 * gets its 'installed' flag cleared.
2304 if (end_count
== 0) {
2305 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2306 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2309 "%s(%u:%u):%pRN dplane notif, uninstalled type %s route",
2311 dplane_ctx_get_vrf(ctx
),
2312 dplane_ctx_get_table(ctx
), rn
,
2314 dplane_ctx_get_type(ctx
)));
2316 /* At least report on the event. */
2319 "%s(%u:%u):%pRN dplane notif, but type %s not selected_fib",
2321 dplane_ctx_get_vrf(ctx
),
2322 dplane_ctx_get_table(ctx
), rn
,
2324 dplane_ctx_get_type(ctx
)));
2328 uint32_t flags
= dplane_ctx_get_flags(ctx
);
2330 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOADED
)) {
2331 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2332 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2334 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOAD_FAILED
)) {
2335 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2336 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2338 if (CHECK_FLAG(flags
, ZEBRA_FLAG_TRAPPED
))
2339 SET_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
);
2342 /* We'll want to determine whether the installation status of the
2343 * route has changed: we'll check the status before processing,
2344 * and then again if there's been a change.
2348 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2349 start_count
= rib_count_installed_nh(re
);
2351 /* Update zebra's nexthop FIB flags based on the context struct's
2354 fib_changed
= rib_update_re_from_ctx(re
, rn
, ctx
);
2359 "%s(%u:%u):%pRN dplane notification: rib_update returns FALSE",
2360 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2361 dplane_ctx_get_table(ctx
), rn
);
2365 * Perform follow-up work if the actual status of the prefix
2368 end_count
= rib_count_installed_nh(re
);
2370 /* Various fib transitions: changed nexthops; from installed to
2371 * not-installed; or not-installed to installed.
2373 if (zrouter
.asic_notification_nexthop_control
) {
2374 if (start_count
> 0 && end_count
> 0) {
2377 "%s(%u:%u):%pRN applied nexthop changes from dplane notification",
2379 dplane_ctx_get_vrf(ctx
),
2380 dplane_ctx_get_table(ctx
), rn
);
2382 /* Changed nexthops - update kernel/others */
2383 dplane_route_notif_update(rn
, re
,
2384 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2386 } else if (start_count
== 0 && end_count
> 0) {
2389 "%s(%u:%u):%pRN installed transition from dplane notification",
2391 dplane_ctx_get_vrf(ctx
),
2392 dplane_ctx_get_table(ctx
), rn
);
2394 /* We expect this to be the selected route, so we want
2395 * to tell others about this transition.
2397 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2399 /* Changed nexthops - update kernel/others */
2400 dplane_route_notif_update(rn
, re
,
2401 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2403 /* Redistribute, lsp, and nht update */
2404 redistribute_update(rn
, re
, NULL
);
2406 } else if (start_count
> 0 && end_count
== 0) {
2409 "%s(%u:%u):%pRN un-installed transition from dplane notification",
2411 dplane_ctx_get_vrf(ctx
),
2412 dplane_ctx_get_table(ctx
), rn
);
2414 /* Transition from _something_ installed to _nothing_
2417 /* We expect this to be the selected route, so we want
2418 * to tell others about this transistion.
2420 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2422 /* Changed nexthops - update kernel/others */
2423 dplane_route_notif_update(rn
, re
,
2424 DPLANE_OP_ROUTE_DELETE
, ctx
);
2426 /* Redistribute, lsp, and nht update */
2427 redistribute_delete(rn
, re
, NULL
);
2431 if (!zebra_router_notify_on_ack()) {
2432 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
2433 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2434 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
2435 zsend_route_notify_owner_ctx(ctx
,
2436 ZAPI_ROUTE_FAIL_INSTALL
);
2439 /* Make any changes visible for lsp and nexthop-tracking processing */
2440 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
2443 zebra_rib_evaluate_mpls(rn
);
2447 route_unlock_node(rn
);
2451 * Process a node from the EVPN/VXLAN subqueue.
2453 static void process_subq_evpn(struct listnode
*lnode
)
2455 struct wq_evpn_wrapper
*w
;
2457 /* In general, the list node points to a wrapper object
2458 * holding the info necessary to make some update.
2460 w
= listgetdata(lnode
);
2464 if (w
->type
== WQ_EVPN_WRAPPER_TYPE_VRFROUTE
) {
2466 zebra_vxlan_evpn_vrf_route_add(w
->vrf_id
, &w
->macaddr
,
2467 &w
->ip
, &w
->prefix
);
2469 zebra_vxlan_evpn_vrf_route_del(w
->vrf_id
, &w
->ip
,
2471 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_ES
) {
2473 zebra_evpn_remote_es_add(&w
->esi
, w
->ip
.ipaddr_v4
,
2474 w
->esr_rxed
, w
->df_alg
,
2477 zebra_evpn_remote_es_del(&w
->esi
, w
->ip
.ipaddr_v4
);
2478 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_MACIP
) {
2479 uint16_t ipa_len
= 0;
2481 if (w
->ip
.ipa_type
== IPADDR_V4
)
2482 ipa_len
= IPV4_MAX_BYTELEN
;
2483 else if (w
->ip
.ipa_type
== IPADDR_V6
)
2484 ipa_len
= IPV6_MAX_BYTELEN
;
2487 zebra_evpn_rem_macip_add(w
->vni
, &w
->macaddr
, ipa_len
,
2488 &w
->ip
, w
->flags
, w
->seq
,
2489 w
->vtep_ip
, &w
->esi
);
2491 zebra_evpn_rem_macip_del(w
->vni
, &w
->macaddr
, ipa_len
,
2492 &w
->ip
, w
->vtep_ip
);
2493 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_VTEP
) {
2495 zebra_vxlan_remote_vtep_add(w
->vrf_id
, w
->vni
,
2496 w
->vtep_ip
, w
->flags
);
2498 zebra_vxlan_remote_vtep_del(w
->vrf_id
, w
->vni
,
2503 XFREE(MTYPE_WQ_WRAPPER
, w
);
2507 * Process the nexthop-group workqueue subqueue
2509 static void process_subq_nhg(struct listnode
*lnode
)
2511 struct nhg_ctx
*ctx
;
2512 struct nhg_hash_entry
*nhe
, *newnhe
;
2513 struct wq_nhg_wrapper
*w
;
2514 uint8_t qindex
= META_QUEUE_NHG
;
2516 w
= listgetdata(lnode
);
2521 /* Two types of object - an update from the local kernel, or
2522 * an nhg update from a daemon.
2524 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
) {
2527 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2529 "NHG Context id=%u dequeued from sub-queue %s",
2530 ctx
->id
, subqueue2str(qindex
));
2533 /* Process nexthop group updates coming 'up' from the OS */
2534 nhg_ctx_process(ctx
);
2536 } else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
) {
2539 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2540 zlog_debug("NHG %u dequeued from sub-queue %s", nhe
->id
,
2541 subqueue2str(qindex
));
2543 /* Process incoming nhg update, probably from a proto daemon */
2544 newnhe
= zebra_nhg_proto_add(nhe
->id
, nhe
->type
,
2546 nhe
->zapi_session
, &nhe
->nhg
, 0);
2548 /* Report error to daemon via ZAPI */
2550 zsend_nhg_notify(nhe
->type
, nhe
->zapi_instance
,
2551 nhe
->zapi_session
, nhe
->id
,
2552 ZAPI_NHG_FAIL_INSTALL
);
2554 /* Free temp nhe - we own that memory. */
2555 zebra_nhg_free(nhe
);
2558 XFREE(MTYPE_WQ_WRAPPER
, w
);
2561 static void process_subq_early_label(struct listnode
*lnode
)
2563 struct wq_label_wrapper
*w
= listgetdata(lnode
);
2564 struct zebra_vrf
*zvrf
;
2569 zvrf
= vrf_info_lookup(w
->vrf_id
);
2571 XFREE(MTYPE_WQ_WRAPPER
, w
);
2576 case WQ_LABEL_FTN_UNINSTALL
:
2577 zebra_mpls_ftn_uninstall(zvrf
, w
->ltype
, &w
->p
, w
->route_type
,
2580 case WQ_LABEL_LABELS_PROCESS
:
2581 zebra_mpls_zapi_labels_process(w
->add_p
, zvrf
, &w
->zl
);
2585 XFREE(MTYPE_WQ_WRAPPER
, w
);
2588 static void process_subq_route(struct listnode
*lnode
, uint8_t qindex
)
2590 struct route_node
*rnode
= NULL
;
2591 rib_dest_t
*dest
= NULL
;
2592 struct zebra_vrf
*zvrf
= NULL
;
2594 rnode
= listgetdata(lnode
);
2595 dest
= rib_dest_from_rnode(rnode
);
2598 zvrf
= rib_dest_vrf(dest
);
2602 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
2603 struct route_entry
*re
= NULL
;
2606 * rib_process may have freed the dest
2607 * as part of the garbage collection. Let's
2608 * prevent stupidity from happening.
2610 dest
= rib_dest_from_rnode(rnode
);
2612 re
= re_list_first(&dest
->routes
);
2614 zlog_debug("%s(%u:%u):%pRN rn %p dequeued from sub-queue %s",
2615 zvrf_name(zvrf
), zvrf_id(zvrf
), re
? re
->table
: 0,
2616 rnode
, rnode
, subqueue2str(qindex
));
2620 UNSET_FLAG(rib_dest_from_rnode(rnode
)->flags
,
2621 RIB_ROUTE_QUEUED(qindex
));
2623 route_unlock_node(rnode
);
2626 static void rib_re_nhg_free(struct route_entry
*re
)
2628 if (re
->nhe
&& re
->nhe_id
) {
2629 assert(re
->nhe
->id
== re
->nhe_id
);
2630 route_entry_update_nhe(re
, NULL
);
2631 } else if (re
->nhe
&& re
->nhe
->nhg
.nexthop
)
2632 nexthops_free(re
->nhe
->nhg
.nexthop
);
2634 nexthops_free(re
->fib_ng
.nexthop
);
2637 struct zebra_early_route
{
2641 struct prefix_ipv6 src_p
;
2642 bool src_p_provided
;
2643 struct route_entry
*re
;
2644 struct nhg_hash_entry
*re_nhe
;
2650 static void early_route_memory_free(struct zebra_early_route
*ere
)
2653 zebra_nhg_free(ere
->re_nhe
);
2655 XFREE(MTYPE_RE
, ere
->re
);
2656 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2659 static void process_subq_early_route_add(struct zebra_early_route
*ere
)
2661 struct route_entry
*re
= ere
->re
;
2662 struct route_table
*table
;
2663 struct nhg_hash_entry
*nhe
= NULL
;
2664 struct route_node
*rn
;
2665 struct route_entry
*same
= NULL
, *first_same
= NULL
;
2670 table
= zebra_vrf_get_table_with_table_id(ere
->afi
, ere
->safi
,
2671 re
->vrf_id
, re
->table
);
2673 early_route_memory_free(ere
);
2677 if (re
->nhe_id
> 0) {
2678 nhe
= zebra_nhg_lookup_id(re
->nhe_id
);
2682 * We've received from the kernel a nexthop id
2683 * that we don't have saved yet. More than likely
2684 * it has not been processed and is on the
2685 * queue to be processed. Let's stop what we
2686 * are doing and cause the meta q to be processed
2687 * storing this for later.
2689 * This is being done this way because zebra
2690 * runs with the assumption t
2693 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2694 "Zebra failed to find the nexthop hash entry for id=%u in a route entry %pFX",
2695 re
->nhe_id
, &ere
->p
);
2697 early_route_memory_free(ere
);
2701 /* Lookup nhe from route information */
2702 nhe
= zebra_nhg_rib_find_nhe(ere
->re_nhe
, ere
->afi
);
2704 char buf2
[PREFIX_STRLEN
] = "";
2707 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2708 "Zebra failed to find or create a nexthop hash entry for %pFX%s%s",
2709 &ere
->p
, ere
->src_p_provided
? " from " : "",
2711 ? prefix2str(&ere
->src_p
, buf2
,
2715 early_route_memory_free(ere
);
2721 * Attach the re to the nhe's nexthop group.
2723 * TODO: This will need to change when we start getting IDs from upper
2724 * level protocols, as the refcnt might be wrong, since it checks
2725 * if old_id != new_id.
2727 route_entry_update_nhe(re
, nhe
);
2729 /* Make it sure prefixlen is applied to the prefix. */
2730 apply_mask(&ere
->p
);
2731 if (ere
->src_p_provided
)
2732 apply_mask_ipv6(&ere
->src_p
);
2734 /* Lookup route node.*/
2735 rn
= srcdest_rnode_get(table
, &ere
->p
,
2736 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2739 * If same type of route are installed, treat it as a implicit
2740 * withdraw. If the user has specified the No route replace semantics
2741 * for the install don't do a route replace.
2743 RNODE_FOREACH_RE (rn
, same
) {
2744 if (CHECK_FLAG(same
->status
, ROUTE_ENTRY_REMOVED
)) {
2749 /* Compare various route_entry properties */
2750 if (rib_compare_routes(re
, same
)) {
2753 if (first_same
== NULL
)
2760 if (!ere
->startup
&& (re
->flags
& ZEBRA_FLAG_SELFROUTE
) &&
2761 zrouter
.asic_offloaded
) {
2763 if (IS_ZEBRA_DEBUG_RIB
)
2765 "prefix: %pRN is a self route where we do not have an entry for it. Dropping this update, it's useless",
2768 * We are not on startup, this is a self route
2769 * and we have asic offload. Which means
2770 * we are getting a callback for a entry
2771 * that was already deleted to the kernel
2772 * but an earlier response was just handed
2773 * back. Drop it on the floor
2775 early_route_memory_free(ere
);
2780 /* Set default distance by route type. */
2781 if (re
->distance
== 0) {
2782 if (same
&& !zebra_router_notify_on_ack())
2783 re
->distance
= same
->distance
;
2785 re
->distance
= route_distance(re
->type
);
2788 if (re
->metric
== ROUTE_INSTALLATION_METRIC
&&
2789 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
2790 if (same
&& !zebra_router_notify_on_ack())
2791 re
->metric
= same
->metric
;
2796 /* If this route is kernel/connected route, notify the dataplane. */
2797 if (RIB_SYSTEM_ROUTE(re
)) {
2798 /* Notify dataplane */
2799 dplane_sys_route_add(rn
, re
);
2802 /* Link new re to node.*/
2803 if (IS_ZEBRA_DEBUG_RIB
) {
2806 "Inserting route rn %p, re %p (%s) existing %p, same_count %d",
2807 rn
, re
, zebra_route_string(re
->type
), same
, same_count
);
2809 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2812 ere
->src_p_provided
? &ere
->src_p
: NULL
, re
);
2815 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
2816 rib_addnode(rn
, re
, 1);
2818 /* Free implicit route.*/
2820 rib_delnode(rn
, same
);
2822 /* See if we can remove some RE entries that are queued for
2823 * removal, but won't be considered in rib processing.
2825 dest
= rib_dest_from_rnode(rn
);
2826 RNODE_FOREACH_RE_SAFE (rn
, re
, same
) {
2827 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
2828 /* If the route was used earlier, must retain it. */
2829 if (dest
&& re
== dest
->selected_fib
)
2832 if (IS_ZEBRA_DEBUG_RIB
)
2833 rnode_debug(rn
, re
->vrf_id
,
2834 "rn %p, removing unneeded re %p",
2841 route_unlock_node(rn
);
2843 zebra_nhg_free(ere
->re_nhe
);
2844 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2847 static void process_subq_early_route_delete(struct zebra_early_route
*ere
)
2849 struct route_table
*table
;
2850 struct route_node
*rn
;
2851 struct route_entry
*re
;
2852 struct route_entry
*fib
= NULL
;
2853 struct route_entry
*same
= NULL
;
2854 struct nexthop
*rtnh
;
2855 char buf2
[INET6_ADDRSTRLEN
];
2858 if (ere
->src_p_provided
)
2859 assert(!ere
->src_p
.prefixlen
|| ere
->afi
== AFI_IP6
);
2862 table
= zebra_vrf_lookup_table_with_table_id(
2863 ere
->afi
, ere
->safi
, ere
->re
->vrf_id
, ere
->re
->table
);
2865 early_route_memory_free(ere
);
2870 apply_mask(&ere
->p
);
2871 if (ere
->src_p_provided
)
2872 apply_mask_ipv6(&ere
->src_p
);
2874 /* Lookup route node. */
2875 rn
= srcdest_rnode_lookup(table
, &ere
->p
,
2876 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2878 if (IS_ZEBRA_DEBUG_RIB
) {
2879 char src_buf
[PREFIX_STRLEN
];
2880 struct vrf
*vrf
= vrf_lookup_by_id(ere
->re
->vrf_id
);
2882 if (ere
->src_p_provided
&& ere
->src_p
.prefixlen
)
2883 prefix2str(&ere
->src_p
, src_buf
,
2888 zlog_debug("%s[%d]:%pRN%s%s doesn't exist in rib",
2889 vrf
->name
, ere
->re
->table
, rn
,
2890 (src_buf
[0] != '\0') ? " from " : "",
2893 early_route_memory_free(ere
);
2897 dest
= rib_dest_from_rnode(rn
);
2898 fib
= dest
->selected_fib
;
2900 struct nexthop
*nh
= NULL
;
2903 nh
= ere
->re
->nhe
->nhg
.nexthop
;
2905 /* Lookup same type route. */
2906 RNODE_FOREACH_RE (rn
, re
) {
2907 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
2910 if (re
->type
!= ere
->re
->type
)
2912 if (re
->instance
!= ere
->re
->instance
)
2914 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
2915 ere
->re
->distance
!= re
->distance
)
2918 if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
2919 re
->metric
!= ere
->re
->metric
)
2921 if (re
->type
== ZEBRA_ROUTE_CONNECT
&& (rtnh
= nh
) &&
2922 rtnh
->type
== NEXTHOP_TYPE_IFINDEX
&& nh
) {
2923 if (rtnh
->ifindex
!= nh
->ifindex
)
2929 /* Make sure that the route found has the same gateway. */
2930 if (ere
->re
->nhe_id
&& re
->nhe_id
== ere
->re
->nhe_id
) {
2939 for (ALL_NEXTHOPS(re
->nhe
->nhg
, rtnh
)) {
2941 * No guarantee all kernel send nh with labels
2944 if (nexthop_same_no_labels(rtnh
, nh
)) {
2954 * If same type of route can't be found and this message is from
2959 * In the past(HA!) we could get here because
2960 * we were receiving a route delete from the
2961 * kernel and we're not marking the proto
2962 * as coming from it's appropriate originator.
2963 * Now that we are properly noticing the fact
2964 * that the kernel has deleted our route we
2965 * are not going to get called in this path
2966 * I am going to leave this here because
2967 * this might still work this way on non-linux
2968 * platforms as well as some weird state I have
2969 * not properly thought of yet.
2970 * If we can show that this code path is
2971 * dead then we can remove it.
2973 if (fib
&& CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
2974 if (IS_ZEBRA_DEBUG_RIB
) {
2976 rn
, ere
->re
->vrf_id
,
2977 "rn %p, re %p (%s) was deleted from kernel, adding",
2978 rn
, fib
, zebra_route_string(fib
->type
));
2980 if (zrouter
.allow_delete
||
2981 CHECK_FLAG(dest
->flags
, RIB_ROUTE_ANY_QUEUED
)) {
2982 UNSET_FLAG(fib
->status
, ROUTE_ENTRY_INSTALLED
);
2984 for (rtnh
= fib
->nhe
->nhg
.nexthop
; rtnh
;
2986 UNSET_FLAG(rtnh
->flags
,
2990 * This is a non FRR route
2991 * as such we should mark
2994 dest
->selected_fib
= NULL
;
2997 * This means someone else, other than Zebra,
2998 * has deleted a Zebra router from the kernel.
2999 * We will add it back
3001 rib_install_kernel(rn
, fib
, NULL
);
3004 if (IS_ZEBRA_DEBUG_RIB
) {
3007 rn
, ere
->re
->vrf_id
,
3008 "via %s ifindex %d type %d doesn't exist in rib",
3009 inet_ntop(afi2family(ere
->afi
),
3012 nh
->ifindex
, ere
->re
->type
);
3015 rn
, ere
->re
->vrf_id
,
3016 "type %d doesn't exist in rib",
3019 route_unlock_node(rn
);
3020 early_route_memory_free(ere
);
3026 struct nexthop
*tmp_nh
;
3028 if (ere
->fromkernel
&&
3029 CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
) &&
3030 !zrouter
.allow_delete
) {
3031 rib_install_kernel(rn
, same
, NULL
);
3032 route_unlock_node(rn
);
3034 early_route_memory_free(ere
);
3038 /* Special handling for IPv4 or IPv6 routes sourced from
3039 * EVPN - the nexthop (and associated MAC) need to be
3040 * uninstalled if no more refs.
3042 for (ALL_NEXTHOPS(re
->nhe
->nhg
, tmp_nh
)) {
3043 struct ipaddr vtep_ip
;
3045 if (CHECK_FLAG(tmp_nh
->flags
, NEXTHOP_FLAG_EVPN
)) {
3046 memset(&vtep_ip
, 0, sizeof(struct ipaddr
));
3047 if (ere
->afi
== AFI_IP
) {
3048 vtep_ip
.ipa_type
= IPADDR_V4
;
3049 memcpy(&(vtep_ip
.ipaddr_v4
),
3050 &(tmp_nh
->gate
.ipv4
),
3051 sizeof(struct in_addr
));
3053 vtep_ip
.ipa_type
= IPADDR_V6
;
3054 memcpy(&(vtep_ip
.ipaddr_v6
),
3055 &(tmp_nh
->gate
.ipv6
),
3056 sizeof(struct in6_addr
));
3058 zebra_rib_queue_evpn_route_del(
3059 re
->vrf_id
, &vtep_ip
, &ere
->p
);
3063 /* Notify dplane if system route changes */
3064 if (RIB_SYSTEM_ROUTE(re
))
3065 dplane_sys_route_del(rn
, same
);
3067 rib_delnode(rn
, same
);
3070 route_unlock_node(rn
);
3072 early_route_memory_free(ere
);
3076 * When FRR receives a route we need to match the route up to
3077 * nexthop groups. That we also may have just received
3078 * place the data on this queue so that this work of finding
3079 * the nexthop group entries for the route entry is always
3080 * done after the nexthop group has had a chance to be processed
3082 static void process_subq_early_route(struct listnode
*lnode
)
3084 struct zebra_early_route
*ere
= listgetdata(lnode
);
3087 process_subq_early_route_delete(ere
);
3089 process_subq_early_route_add(ere
);
3093 * Examine the specified subqueue; process one entry and return 1 if
3094 * there is a node, return 0 otherwise.
3096 static unsigned int process_subq(struct list
*subq
,
3097 enum meta_queue_indexes qindex
)
3099 struct listnode
*lnode
= listhead(subq
);
3105 case META_QUEUE_EVPN
:
3106 process_subq_evpn(lnode
);
3108 case META_QUEUE_NHG
:
3109 process_subq_nhg(lnode
);
3111 case META_QUEUE_EARLY_ROUTE
:
3112 process_subq_early_route(lnode
);
3114 case META_QUEUE_EARLY_LABEL
:
3115 process_subq_early_label(lnode
);
3117 case META_QUEUE_CONNECTED
:
3118 case META_QUEUE_KERNEL
:
3119 case META_QUEUE_STATIC
:
3120 case META_QUEUE_NOTBGP
:
3121 case META_QUEUE_BGP
:
3122 case META_QUEUE_OTHER
:
3123 process_subq_route(lnode
, qindex
);
3127 list_delete_node(subq
, lnode
);
3132 /* Dispatch the meta queue by picking and processing the next node from
3133 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
3134 * data is pointed to the meta queue structure.
3136 static wq_item_status
meta_queue_process(struct work_queue
*dummy
, void *data
)
3138 struct meta_queue
*mq
= data
;
3140 uint32_t queue_len
, queue_limit
;
3142 /* Ensure there's room for more dataplane updates */
3143 queue_limit
= dplane_get_in_queue_limit();
3144 queue_len
= dplane_get_in_queue_len();
3145 if (queue_len
> queue_limit
) {
3146 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3148 "rib queue: dplane queue len %u, limit %u, retrying",
3149 queue_len
, queue_limit
);
3151 /* Ensure that the meta-queue is actually enqueued */
3152 if (work_queue_empty(zrouter
.ribq
))
3153 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3155 return WQ_QUEUE_BLOCKED
;
3158 for (i
= 0; i
< MQ_SIZE
; i
++)
3159 if (process_subq(mq
->subq
[i
], i
)) {
3163 return mq
->size
? WQ_REQUEUE
: WQ_SUCCESS
;
3168 * Look into the RN and queue it into the highest priority queue
3169 * at this point in time for processing.
3171 * We will enqueue a route node only once per invocation.
3173 * There are two possibilities here that should be kept in mind.
3174 * If the original invocation has not been pulled off for processing
3175 * yet, A subsuquent invocation can have a route entry with a better
3176 * meta queue index value and we can have a situation where
3177 * we might have the same node enqueued 2 times. Not necessarily
3178 * an optimal situation but it should be ok.
3180 * The other possibility is that the original invocation has not
3181 * been pulled off for processing yet, A subsusquent invocation
3182 * doesn't have a route_entry with a better meta-queue and the
3183 * original metaqueue index value will win and we'll end up with
3184 * the route node enqueued once.
3186 static int rib_meta_queue_add(struct meta_queue
*mq
, void *data
)
3188 struct route_node
*rn
= NULL
;
3189 struct route_entry
*re
= NULL
, *curr_re
= NULL
;
3190 uint8_t qindex
= MQ_SIZE
, curr_qindex
= MQ_SIZE
;
3192 rn
= (struct route_node
*)data
;
3194 RNODE_FOREACH_RE (rn
, curr_re
) {
3195 curr_qindex
= route_info
[curr_re
->type
].meta_q_map
;
3197 if (curr_qindex
<= qindex
) {
3199 qindex
= curr_qindex
;
3206 /* Invariant: at this point we always have rn->info set. */
3207 if (CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
3208 RIB_ROUTE_QUEUED(qindex
))) {
3209 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3210 rnode_debug(rn
, re
->vrf_id
,
3211 "rn %p is already queued in sub-queue %s",
3212 (void *)rn
, subqueue2str(qindex
));
3216 SET_FLAG(rib_dest_from_rnode(rn
)->flags
, RIB_ROUTE_QUEUED(qindex
));
3217 listnode_add(mq
->subq
[qindex
], rn
);
3218 route_lock_node(rn
);
3221 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3222 rnode_debug(rn
, re
->vrf_id
, "queued rn %p into sub-queue %s",
3223 (void *)rn
, subqueue2str(qindex
));
3228 static int early_label_meta_queue_add(struct meta_queue
*mq
, void *data
)
3230 listnode_add(mq
->subq
[META_QUEUE_EARLY_LABEL
], data
);
3235 static int rib_meta_queue_nhg_ctx_add(struct meta_queue
*mq
, void *data
)
3237 struct nhg_ctx
*ctx
= NULL
;
3238 uint8_t qindex
= META_QUEUE_NHG
;
3239 struct wq_nhg_wrapper
*w
;
3241 ctx
= (struct nhg_ctx
*)data
;
3246 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3248 w
->type
= WQ_NHG_WRAPPER_TYPE_CTX
;
3251 listnode_add(mq
->subq
[qindex
], w
);
3254 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3255 zlog_debug("NHG Context id=%u queued into sub-queue %s",
3256 ctx
->id
, subqueue2str(qindex
));
3261 static int rib_meta_queue_nhg_add(struct meta_queue
*mq
, void *data
)
3263 struct nhg_hash_entry
*nhe
= NULL
;
3264 uint8_t qindex
= META_QUEUE_NHG
;
3265 struct wq_nhg_wrapper
*w
;
3267 nhe
= (struct nhg_hash_entry
*)data
;
3272 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3274 w
->type
= WQ_NHG_WRAPPER_TYPE_NHG
;
3277 listnode_add(mq
->subq
[qindex
], w
);
3280 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3281 zlog_debug("NHG id=%u queued into sub-queue %s", nhe
->id
,
3282 subqueue2str(qindex
));
3287 static int rib_meta_queue_evpn_add(struct meta_queue
*mq
, void *data
)
3289 listnode_add(mq
->subq
[META_QUEUE_EVPN
], data
);
3295 static int mq_add_handler(void *data
,
3296 int (*mq_add_func
)(struct meta_queue
*mq
, void *data
))
3298 if (zrouter
.ribq
== NULL
) {
3299 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3300 "%s: work_queue does not exist!", __func__
);
3305 * The RIB queue should normally be either empty or holding the only
3306 * work_queue_item element. In the latter case this element would
3307 * hold a pointer to the meta queue structure, which must be used to
3308 * actually queue the route nodes to process. So create the MQ
3309 * holder, if necessary, then push the work into it in any case.
3310 * This semantics was introduced after 0.99.9 release.
3312 if (work_queue_empty(zrouter
.ribq
))
3313 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3315 return mq_add_func(zrouter
.mq
, data
);
3318 void mpls_ftn_uninstall(struct zebra_vrf
*zvrf
, enum lsp_types_t type
,
3319 struct prefix
*prefix
, uint8_t route_type
,
3320 uint8_t route_instance
)
3322 struct wq_label_wrapper
*w
;
3324 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3326 w
->type
= WQ_LABEL_FTN_UNINSTALL
;
3327 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3330 w
->route_type
= route_type
;
3331 w
->route_instance
= route_instance
;
3333 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3334 zlog_debug("Early Label Handling for %pFX", prefix
);
3336 mq_add_handler(w
, early_label_meta_queue_add
);
3339 void mpls_zapi_labels_process(bool add_p
, struct zebra_vrf
*zvrf
,
3340 const struct zapi_labels
*zl
)
3342 struct wq_label_wrapper
*w
;
3344 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3345 w
->type
= WQ_LABEL_LABELS_PROCESS
;
3346 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3350 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3351 zlog_debug("Early Label Handling: Labels Process");
3353 mq_add_handler(w
, early_label_meta_queue_add
);
3356 /* Add route_node to work queue and schedule processing */
3357 int rib_queue_add(struct route_node
*rn
)
3361 /* Pointless to queue a route_node with no RIB entries to add or remove
3363 if (!rnode_to_ribs(rn
)) {
3364 zlog_debug("%s: called for route_node (%p, %u) with no ribs",
3365 __func__
, (void *)rn
, route_node_get_lock_count(rn
));
3366 zlog_backtrace(LOG_DEBUG
);
3370 return mq_add_handler(rn
, rib_meta_queue_add
);
3374 * Enqueue incoming nhg info from OS for processing
3376 int rib_queue_nhg_ctx_add(struct nhg_ctx
*ctx
)
3380 return mq_add_handler(ctx
, rib_meta_queue_nhg_ctx_add
);
3384 * Enqueue incoming nhg from proto daemon for processing
3386 int rib_queue_nhe_add(struct nhg_hash_entry
*nhe
)
3391 return mq_add_handler(nhe
, rib_meta_queue_nhg_add
);
3395 * Enqueue evpn route for processing
3397 int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id
, const struct ethaddr
*rmac
,
3398 const struct ipaddr
*vtep_ip
,
3399 const struct prefix
*host_prefix
)
3401 struct wq_evpn_wrapper
*w
;
3403 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3405 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3410 w
->prefix
= *host_prefix
;
3412 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3413 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3414 vrf_id
, vtep_ip
, host_prefix
);
3416 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3419 int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id
,
3420 const struct ipaddr
*vtep_ip
,
3421 const struct prefix
*host_prefix
)
3423 struct wq_evpn_wrapper
*w
;
3425 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3427 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3431 w
->prefix
= *host_prefix
;
3433 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3434 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3435 vrf_id
, vtep_ip
, host_prefix
);
3437 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3440 /* Enqueue EVPN remote ES for processing */
3441 int zebra_rib_queue_evpn_rem_es_add(const esi_t
*esi
,
3442 const struct in_addr
*vtep_ip
,
3443 bool esr_rxed
, uint8_t df_alg
,
3446 struct wq_evpn_wrapper
*w
;
3447 char buf
[ESI_STR_LEN
];
3449 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3451 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3454 w
->ip
.ipa_type
= IPADDR_V4
;
3455 w
->ip
.ipaddr_v4
= *vtep_ip
;
3456 w
->esr_rxed
= esr_rxed
;
3458 w
->df_pref
= df_pref
;
3460 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3461 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3462 esi_to_str(esi
, buf
, sizeof(buf
)));
3464 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3467 int zebra_rib_queue_evpn_rem_es_del(const esi_t
*esi
,
3468 const struct in_addr
*vtep_ip
)
3470 struct wq_evpn_wrapper
*w
;
3471 char buf
[ESI_STR_LEN
];
3473 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3475 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3478 w
->ip
.ipa_type
= IPADDR_V4
;
3479 w
->ip
.ipaddr_v4
= *vtep_ip
;
3481 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3482 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3483 esi_to_str(esi
, buf
, sizeof(buf
));
3485 strlcpy(buf
, "-", sizeof(buf
));
3487 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3491 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3495 * Enqueue EVPN remote macip update for processing
3497 int zebra_rib_queue_evpn_rem_macip_add(vni_t vni
, const struct ethaddr
*macaddr
,
3498 const struct ipaddr
*ipaddr
,
3499 uint8_t flags
, uint32_t seq
,
3500 struct in_addr vtep_ip
, const esi_t
*esi
)
3502 struct wq_evpn_wrapper
*w
;
3503 char buf
[ESI_STR_LEN
];
3505 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3507 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3510 w
->macaddr
= *macaddr
;
3514 w
->vtep_ip
= vtep_ip
;
3517 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3518 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3519 esi_to_str(esi
, buf
, sizeof(buf
));
3521 strlcpy(buf
, "-", sizeof(buf
));
3523 zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__
,
3524 macaddr
, &vtep_ip
, buf
);
3527 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3530 int zebra_rib_queue_evpn_rem_macip_del(vni_t vni
, const struct ethaddr
*macaddr
,
3531 const struct ipaddr
*ip
,
3532 struct in_addr vtep_ip
)
3534 struct wq_evpn_wrapper
*w
;
3536 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3538 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3541 w
->macaddr
= *macaddr
;
3543 w
->vtep_ip
= vtep_ip
;
3545 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3546 zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__
,
3549 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3553 * Enqueue remote VTEP address for processing
3555 int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id
, vni_t vni
,
3556 struct in_addr vtep_ip
, int flood_control
)
3558 struct wq_evpn_wrapper
*w
;
3560 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3562 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3566 w
->vtep_ip
= vtep_ip
;
3567 w
->flags
= flood_control
;
3569 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3570 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3573 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3576 int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id
, vni_t vni
,
3577 struct in_addr vtep_ip
)
3579 struct wq_evpn_wrapper
*w
;
3581 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3583 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3587 w
->vtep_ip
= vtep_ip
;
3589 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3590 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3593 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3596 /* Create new meta queue.
3597 A destructor function doesn't seem to be necessary here.
3599 static struct meta_queue
*meta_queue_new(void)
3601 struct meta_queue
*new;
3604 new = XCALLOC(MTYPE_WORK_QUEUE
, sizeof(struct meta_queue
));
3606 for (i
= 0; i
< MQ_SIZE
; i
++) {
3607 new->subq
[i
] = list_new();
3608 assert(new->subq
[i
]);
3614 /* Clean up the EVPN meta-queue list */
3615 static void evpn_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3616 struct zebra_vrf
*zvrf
)
3618 struct listnode
*node
, *nnode
;
3619 struct wq_evpn_wrapper
*w
;
3621 /* Free the node wrapper object, and the struct it wraps */
3622 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3624 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3626 if (w
->vrf_id
!= vrf_id
)
3632 XFREE(MTYPE_WQ_WRAPPER
, w
);
3634 list_delete_node(l
, node
);
3639 /* Clean up the nhg meta-queue list */
3640 static void nhg_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3641 struct zebra_vrf
*zvrf
)
3643 struct wq_nhg_wrapper
*w
;
3644 struct listnode
*node
, *nnode
;
3646 /* Free the node wrapper object, and the struct it wraps */
3647 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3649 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3651 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
&&
3652 w
->u
.ctx
->vrf_id
!= vrf_id
)
3654 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
&&
3655 w
->u
.nhe
->vrf_id
!= vrf_id
)
3658 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
)
3659 nhg_ctx_free(&w
->u
.ctx
);
3660 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
)
3661 zebra_nhg_free(w
->u
.nhe
);
3664 XFREE(MTYPE_WQ_WRAPPER
, w
);
3666 list_delete_node(l
, node
);
3671 static void early_label_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3672 struct zebra_vrf
*zvrf
)
3674 struct wq_label_wrapper
*w
;
3675 struct listnode
*node
, *nnode
;
3677 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3678 if (zvrf
&& zvrf
->vrf
->vrf_id
!= w
->vrf_id
)
3682 case WQ_LABEL_FTN_UNINSTALL
:
3683 case WQ_LABEL_LABELS_PROCESS
:
3688 XFREE(MTYPE_WQ_WRAPPER
, w
);
3689 list_delete_node(l
, node
);
3694 static void rib_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3695 struct zebra_vrf
*zvrf
)
3697 struct route_node
*rnode
;
3698 struct listnode
*node
, *nnode
;
3700 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, rnode
)) {
3701 rib_dest_t
*dest
= rib_dest_from_rnode(rnode
);
3703 if (dest
&& rib_dest_vrf(dest
) != zvrf
)
3706 route_unlock_node(rnode
);
3708 list_delete_node(l
, node
);
3713 static void early_route_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3714 struct zebra_vrf
*zvrf
)
3716 struct zebra_early_route
*ere
;
3717 struct listnode
*node
, *nnode
;
3719 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, ere
)) {
3720 if (zvrf
&& ere
->re
->vrf_id
!= zvrf
->vrf
->vrf_id
)
3723 early_route_memory_free(ere
);
3725 list_delete_node(l
, node
);
3730 void meta_queue_free(struct meta_queue
*mq
, struct zebra_vrf
*zvrf
)
3732 enum meta_queue_indexes i
;
3734 for (i
= 0; i
< MQ_SIZE
; i
++) {
3735 /* Some subqueues may need cleanup - nhgs for example */
3737 case META_QUEUE_NHG
:
3738 nhg_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3740 case META_QUEUE_EVPN
:
3741 evpn_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3743 case META_QUEUE_EARLY_ROUTE
:
3744 early_route_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3746 case META_QUEUE_EARLY_LABEL
:
3747 early_label_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3749 case META_QUEUE_CONNECTED
:
3750 case META_QUEUE_KERNEL
:
3751 case META_QUEUE_STATIC
:
3752 case META_QUEUE_NOTBGP
:
3753 case META_QUEUE_BGP
:
3754 case META_QUEUE_OTHER
:
3755 rib_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3759 list_delete(&mq
->subq
[i
]);
3763 XFREE(MTYPE_WORK_QUEUE
, mq
);
3766 /* initialise zebra rib work queue */
3767 static void rib_queue_init(void)
3769 if (!(zrouter
.ribq
= work_queue_new(zrouter
.master
,
3770 "route_node processing"))) {
3771 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3772 "%s: could not initialise work queue!", __func__
);
3776 /* fill in the work queue spec */
3777 zrouter
.ribq
->spec
.workfunc
= &meta_queue_process
;
3778 zrouter
.ribq
->spec
.completion_func
= NULL
;
3779 /* XXX: TODO: These should be runtime configurable via vty */
3780 zrouter
.ribq
->spec
.max_retries
= 3;
3781 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3782 zrouter
.ribq
->spec
.retry
= ZEBRA_RIB_PROCESS_RETRY_TIME
;
3784 if (!(zrouter
.mq
= meta_queue_new())) {
3785 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3786 "%s: could not initialise meta queue!", __func__
);
3792 rib_dest_t
*zebra_rib_create_dest(struct route_node
*rn
)
3796 dest
= XCALLOC(MTYPE_RIB_DEST
, sizeof(rib_dest_t
));
3797 rnh_list_init(&dest
->nht
);
3798 re_list_init(&dest
->routes
);
3799 route_lock_node(rn
); /* rn route table reference */
3806 /* RIB updates are processed via a queue of pointers to route_nodes.
3808 * The queue length is bounded by the maximal size of the routing table,
3809 * as a route_node will not be requeued, if already queued.
3811 * REs are submitted via rib_addnode or rib_delnode which set minimal
3812 * state, or static_install_route (when an existing RE is updated)
3813 * and then submit route_node to queue for best-path selection later.
3814 * Order of add/delete state changes are preserved for any given RE.
3816 * Deleted REs are reaped during best-path selection.
3819 * |-> rib_link or unset ROUTE_ENTRY_REMOVE |->Update kernel with
3820 * |-------->| | best RE, if required
3822 * static_install->|->rib_addqueue...... -> rib_process
3824 * |-------->| |-> rib_unlink
3825 * |-> set ROUTE_ENTRY_REMOVE |
3826 * rib_delnode (RE freed)
3828 * The 'info' pointer of a route_node points to a rib_dest_t
3829 * ('dest'). Queueing state for a route_node is kept on the dest. The
3830 * dest is created on-demand by rib_link() and is kept around at least
3831 * as long as there are ribs hanging off it (@see rib_gc_dest()).
3833 * Refcounting (aka "locking" throughout the Zebra and FRR code):
3835 * - route_nodes: refcounted by:
3836 * - dest attached to route_node:
3837 * - managed by: rib_link/rib_gc_dest
3838 * - route_node processing queue
3839 * - managed by: rib_addqueue, rib_process.
3843 /* Add RE to head of the route node. */
3844 static void rib_link(struct route_node
*rn
, struct route_entry
*re
, int process
)
3848 const char *rmap_name
;
3852 dest
= rib_dest_from_rnode(rn
);
3854 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3855 rnode_debug(rn
, re
->vrf_id
, "rn %p adding dest", rn
);
3857 dest
= zebra_rib_create_dest(rn
);
3860 re_list_add_head(&dest
->routes
, re
);
3862 afi
= (rn
->p
.family
== AF_INET
)
3864 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3865 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3866 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3868 rmap_name
= zebra_get_import_table_route_map(afi
, re
->table
);
3869 zebra_add_import_table_entry(zvrf
, rn
, re
, rmap_name
);
3876 static void rib_addnode(struct route_node
*rn
,
3877 struct route_entry
*re
, int process
)
3879 /* RE node has been un-removed before route-node is processed.
3880 * route_node must hence already be on the queue for processing..
3882 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
3883 if (IS_ZEBRA_DEBUG_RIB
)
3884 rnode_debug(rn
, re
->vrf_id
, "rn %p, un-removed re %p",
3885 (void *)rn
, (void *)re
);
3887 UNSET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3890 rib_link(rn
, re
, process
);
3896 * Detach a rib structure from a route_node.
3898 * Note that a call to rib_unlink() should be followed by a call to
3899 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
3900 * longer required to be deleted.
3902 void rib_unlink(struct route_node
*rn
, struct route_entry
*re
)
3908 if (IS_ZEBRA_DEBUG_RIB
)
3909 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p", (void *)rn
,
3912 dest
= rib_dest_from_rnode(rn
);
3914 re_list_del(&dest
->routes
, re
);
3916 if (dest
->selected_fib
== re
)
3917 dest
->selected_fib
= NULL
;
3919 rib_re_nhg_free(re
);
3921 zapi_re_opaque_free(re
->opaque
);
3923 XFREE(MTYPE_RE
, re
);
3926 void rib_delnode(struct route_node
*rn
, struct route_entry
*re
)
3930 if (IS_ZEBRA_DEBUG_RIB
)
3931 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p, removing",
3932 (void *)rn
, (void *)re
);
3933 SET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3935 afi
= (rn
->p
.family
== AF_INET
)
3937 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3938 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3939 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3941 zebra_del_import_table_entry(zvrf
, rn
, re
);
3942 /* Just clean up if non main table */
3943 if (IS_ZEBRA_DEBUG_RIB
)
3944 zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)",
3945 vrf_id_to_name(re
->vrf_id
), re
->vrf_id
, rn
,
3946 rn
, re
, zebra_route_string(re
->type
));
3953 * Helper that debugs a single nexthop within a route-entry
3955 static void _route_entry_dump_nh(const struct route_entry
*re
,
3956 const char *straddr
,
3957 const struct nexthop
*nexthop
)
3959 char nhname
[PREFIX_STRLEN
];
3960 char backup_str
[50];
3963 char label_str
[MPLS_LABEL_STRLEN
];
3965 struct interface
*ifp
;
3966 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
3968 switch (nexthop
->type
) {
3969 case NEXTHOP_TYPE_BLACKHOLE
:
3970 snprintf(nhname
, sizeof(nhname
), "Blackhole");
3972 case NEXTHOP_TYPE_IFINDEX
:
3973 ifp
= if_lookup_by_index(nexthop
->ifindex
, nexthop
->vrf_id
);
3974 snprintf(nhname
, sizeof(nhname
), "%s",
3975 ifp
? ifp
->name
: "Unknown");
3977 case NEXTHOP_TYPE_IPV4
:
3979 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3980 inet_ntop(AF_INET
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
3982 case NEXTHOP_TYPE_IPV6
:
3983 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3984 inet_ntop(AF_INET6
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
3989 label_str
[0] = '\0';
3990 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
> 0) {
3991 mpls_label2str(nexthop
->nh_label
->num_labels
,
3992 nexthop
->nh_label
->label
, label_str
,
3993 sizeof(label_str
), nexthop
->nh_label_type
,
3995 strlcat(label_str
, ", ", sizeof(label_str
));
3998 backup_str
[0] = '\0';
3999 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
4000 snprintf(backup_str
, sizeof(backup_str
), "backup ");
4001 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
4002 snprintf(temp_str
, sizeof(temp_str
), "%d, ",
4003 nexthop
->backup_idx
[i
]);
4004 strlcat(backup_str
, temp_str
, sizeof(backup_str
));
4009 if (nexthop
->weight
)
4010 snprintf(wgt_str
, sizeof(wgt_str
), "wgt %d,", nexthop
->weight
);
4012 zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s%s",
4013 straddr
, (nexthop
->rparent
? " NH" : "NH"), nhname
,
4014 nexthop
->ifindex
, label_str
, vrf
? vrf
->name
: "Unknown",
4016 wgt_str
, backup_str
,
4017 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
)
4020 (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)
4023 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
4026 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
)
4029 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
4032 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RNH_FILTERED
)
4033 ? "FILTERED " : ""),
4034 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)
4036 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_SRTE
)
4038 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_EVPN
)
4043 /* This function dumps the contents of a given RE entry into
4044 * standard debug log. Calling function name and IP prefix in
4045 * question are passed as 1st and 2nd arguments.
4047 void _route_entry_dump(const char *func
, union prefixconstptr pp
,
4048 union prefixconstptr src_pp
,
4049 const struct route_entry
*re
)
4051 const struct prefix
*src_p
= src_pp
.p
;
4052 bool is_srcdst
= src_p
&& src_p
->prefixlen
;
4053 char straddr
[PREFIX_STRLEN
];
4054 char srcaddr
[PREFIX_STRLEN
];
4055 char flags_buf
[128];
4056 char status_buf
[128];
4057 struct nexthop
*nexthop
;
4058 struct vrf
*vrf
= vrf_lookup_by_id(re
->vrf_id
);
4059 struct nexthop_group
*nhg
;
4061 prefix2str(pp
, straddr
, sizeof(straddr
));
4063 zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %s(%u)", func
,
4064 (const void *)re
, straddr
,
4065 is_srcdst
? " from " : "",
4066 is_srcdst
? prefix2str(src_pp
, srcaddr
, sizeof(srcaddr
))
4068 VRF_LOGNAME(vrf
), re
->vrf_id
);
4069 zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
4070 straddr
, (unsigned long)re
->uptime
, re
->type
, re
->instance
,
4073 "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s",
4074 straddr
, re
->metric
, re
->mtu
, re
->distance
,
4075 zclient_dump_route_flags(re
->flags
, flags_buf
,
4077 _dump_re_status(re
, status_buf
, sizeof(status_buf
)));
4078 zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr
,
4079 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)),
4080 nexthop_group_active_nexthop_num(&(re
->nhe
->nhg
)));
4083 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4084 _route_entry_dump_nh(re
, straddr
, nexthop
);
4086 if (zebra_nhg_get_backup_nhg(re
->nhe
)) {
4087 zlog_debug("%s: backup nexthops:", straddr
);
4089 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
4090 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
))
4091 _route_entry_dump_nh(re
, straddr
, nexthop
);
4094 zlog_debug("%s: dump complete", straddr
);
4097 static int rib_meta_queue_early_route_add(struct meta_queue
*mq
, void *data
)
4099 struct zebra_early_route
*ere
= data
;
4101 listnode_add(mq
->subq
[META_QUEUE_EARLY_ROUTE
], data
);
4104 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
4106 "Route %pFX(%u) queued for processing into sub-queue %s",
4107 &ere
->p
, ere
->re
->vrf_id
,
4108 subqueue2str(META_QUEUE_EARLY_ROUTE
));
4113 struct route_entry
*zebra_rib_route_entry_new(vrf_id_t vrf_id
, int type
,
4114 uint8_t instance
, uint32_t flags
,
4117 uint32_t metric
, uint32_t mtu
,
4118 uint8_t distance
, route_tag_t tag
)
4120 struct route_entry
*re
;
4122 re
= XCALLOC(MTYPE_RE
, sizeof(struct route_entry
));
4124 re
->instance
= instance
;
4125 re
->distance
= distance
;
4127 re
->metric
= metric
;
4129 re
->table
= table_id
;
4130 re
->vrf_id
= vrf_id
;
4131 re
->uptime
= monotime(NULL
);
4133 re
->nhe_id
= nhe_id
;
4138 * Internal route-add implementation; there are a couple of different public
4139 * signatures. Callers in this path are responsible for the memory they
4140 * allocate: if they allocate a nexthop_group or backup nexthop info, they
4141 * must free those objects. If this returns < 0, an error has occurred and the
4142 * route_entry 're' has not been captured; the caller should free that also.
4148 int rib_add_multipath_nhe(afi_t afi
, safi_t safi
, struct prefix
*p
,
4149 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4150 struct nhg_hash_entry
*re_nhe
, bool startup
)
4152 struct zebra_early_route
*ere
;
4157 assert(!src_p
|| !src_p
->prefixlen
|| afi
== AFI_IP6
);
4159 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4164 ere
->src_p
= *src_p
;
4165 ere
->src_p_provided
= !!src_p
;
4167 ere
->re_nhe
= re_nhe
;
4168 ere
->startup
= startup
;
4170 return mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4174 * Add a single route.
4176 int rib_add_multipath(afi_t afi
, safi_t safi
, struct prefix
*p
,
4177 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4178 struct nexthop_group
*ng
, bool startup
)
4181 struct nhg_hash_entry nhe
, *n
;
4186 /* We either need nexthop(s) or an existing nexthop id */
4187 if (ng
== NULL
&& re
->nhe_id
== 0)
4191 * Use a temporary nhe to convey info to the common/main api.
4193 zebra_nhe_init(&nhe
, afi
, (ng
? ng
->nexthop
: NULL
));
4195 nhe
.nhg
.nexthop
= ng
->nexthop
;
4196 else if (re
->nhe_id
> 0)
4197 nhe
.id
= re
->nhe_id
;
4199 n
= zebra_nhe_copy(&nhe
, 0);
4200 ret
= rib_add_multipath_nhe(afi
, safi
, p
, src_p
, re
, n
, startup
);
4202 /* In error cases, free the route also */
4204 XFREE(MTYPE_RE
, re
);
4209 void rib_delete(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4210 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4211 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4212 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
,
4213 uint8_t distance
, bool fromkernel
)
4215 struct zebra_early_route
*ere
;
4216 struct route_entry
*re
= NULL
;
4217 struct nhg_hash_entry
*nhe
= NULL
;
4219 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4220 table_id
, metric
, 0, distance
, 0);
4223 nhe
= zebra_nhg_alloc();
4224 nhe
->nhg
.nexthop
= nexthop_dup(nh
, NULL
);
4227 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4232 ere
->src_p
= *src_p
;
4233 ere
->src_p_provided
= !!src_p
;
4236 ere
->startup
= false;
4237 ere
->deletion
= true;
4238 ere
->fromkernel
= fromkernel
;
4240 mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4244 int rib_add(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4245 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4246 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4247 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
, uint32_t mtu
,
4248 uint8_t distance
, route_tag_t tag
, bool startup
)
4250 struct route_entry
*re
= NULL
;
4251 struct nexthop nexthop
= {};
4252 struct nexthop_group ng
= {};
4254 /* Allocate new route_entry structure. */
4255 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4256 table_id
, metric
, mtu
, distance
, tag
);
4258 /* If the owner of the route supplies a shared nexthop-group id,
4259 * we'll use that. Otherwise, pass the nexthop along directly.
4264 nexthop_group_add_sorted(&ng
, &nexthop
);
4267 return rib_add_multipath(afi
, safi
, p
, src_p
, re
, &ng
, startup
);
4270 static const char *rib_update_event2str(enum rib_update_event event
)
4272 const char *ret
= "UNKNOWN";
4275 case RIB_UPDATE_KERNEL
:
4276 ret
= "RIB_UPDATE_KERNEL";
4278 case RIB_UPDATE_RMAP_CHANGE
:
4279 ret
= "RIB_UPDATE_RMAP_CHANGE";
4281 case RIB_UPDATE_OTHER
:
4282 ret
= "RIB_UPDATE_OTHER";
4284 case RIB_UPDATE_MAX
:
4292 /* Schedule route nodes to be processed if they match the type */
4293 static void rib_update_route_node(struct route_node
*rn
, int type
)
4295 struct route_entry
*re
, *next
;
4296 bool re_changed
= false;
4298 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4299 if (type
== ZEBRA_ROUTE_ALL
|| type
== re
->type
) {
4300 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
4309 /* Schedule routes of a particular table (address-family) based on event. */
4310 void rib_update_table(struct route_table
*table
, enum rib_update_event event
,
4313 struct route_node
*rn
;
4315 if (IS_ZEBRA_DEBUG_EVENT
) {
4316 struct zebra_vrf
*zvrf
;
4320 ? ((struct rib_table_info
*)table
->info
)->zvrf
4322 vrf
= zvrf
? zvrf
->vrf
: NULL
;
4324 zlog_debug("%s: %s VRF %s Table %u event %s Route type: %s", __func__
,
4325 table
->info
? afi2str(
4326 ((struct rib_table_info
*)table
->info
)->afi
)
4328 VRF_LOGNAME(vrf
), zvrf
? zvrf
->table_id
: 0,
4329 rib_update_event2str(event
), zebra_route_string(rtype
));
4332 /* Walk all routes and queue for processing, if appropriate for
4333 * the trigger event.
4335 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4337 * If we are looking at a route node and the node
4338 * has already been queued we don't
4339 * need to queue it up again
4342 && CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
4343 RIB_ROUTE_ANY_QUEUED
))
4347 case RIB_UPDATE_KERNEL
:
4348 rib_update_route_node(rn
, ZEBRA_ROUTE_KERNEL
);
4350 case RIB_UPDATE_RMAP_CHANGE
:
4351 case RIB_UPDATE_OTHER
:
4352 rib_update_route_node(rn
, rtype
);
4354 case RIB_UPDATE_MAX
:
4360 static void rib_update_handle_vrf_all(enum rib_update_event event
, int rtype
)
4362 struct zebra_router_table
*zrt
;
4364 if (IS_ZEBRA_DEBUG_EVENT
)
4365 zlog_debug("%s: Handling VRF (ALL) event %s", __func__
,
4366 rib_update_event2str(event
));
4368 /* Just iterate over all the route tables, rather than vrf lookups */
4369 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
)
4370 rib_update_table(zrt
->table
, event
, rtype
);
4373 struct rib_update_ctx
{
4374 enum rib_update_event event
;
4378 static struct rib_update_ctx
*rib_update_ctx_init(vrf_id_t vrf_id
,
4379 enum rib_update_event event
)
4381 struct rib_update_ctx
*ctx
;
4383 ctx
= XCALLOC(MTYPE_RIB_UPDATE_CTX
, sizeof(struct rib_update_ctx
));
4386 ctx
->vrf_id
= vrf_id
;
4391 static void rib_update_ctx_fini(struct rib_update_ctx
**ctx
)
4393 XFREE(MTYPE_RIB_UPDATE_CTX
, *ctx
);
4396 static void rib_update_handler(struct event
*thread
)
4398 struct rib_update_ctx
*ctx
;
4400 ctx
= EVENT_ARG(thread
);
4402 rib_update_handle_vrf_all(ctx
->event
, ZEBRA_ROUTE_ALL
);
4404 rib_update_ctx_fini(&ctx
);
4408 * Thread list to ensure we don't schedule a ton of events
4409 * if interfaces are flapping for instance.
4411 static struct event
*t_rib_update_threads
[RIB_UPDATE_MAX
];
4413 /* Schedule a RIB update event for all vrfs */
4414 void rib_update(enum rib_update_event event
)
4416 struct rib_update_ctx
*ctx
;
4418 if (event_is_scheduled(t_rib_update_threads
[event
]))
4421 ctx
= rib_update_ctx_init(0, event
);
4423 event_add_event(zrouter
.master
, rib_update_handler
, ctx
, 0,
4424 &t_rib_update_threads
[event
]);
4426 if (IS_ZEBRA_DEBUG_EVENT
)
4427 zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__
,
4428 rib_update_event2str(event
));
4431 /* Delete self installed routes after zebra is relaunched. */
4432 void rib_sweep_table(struct route_table
*table
)
4434 struct route_node
*rn
;
4435 struct route_entry
*re
;
4436 struct route_entry
*next
;
4437 struct nexthop
*nexthop
;
4442 if (IS_ZEBRA_DEBUG_RIB
)
4443 zlog_debug("%s: starting", __func__
);
4445 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4446 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4448 if (IS_ZEBRA_DEBUG_RIB
)
4449 route_entry_dump(&rn
->p
, NULL
, re
);
4451 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4454 if (!CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
))
4458 * If routes are older than startup_time then
4459 * we know we read them in from the kernel.
4460 * As such we can safely remove them.
4462 if (zrouter
.startup_time
< re
->uptime
)
4466 * So we are starting up and have received
4467 * routes from the kernel that we have installed
4468 * from a previous run of zebra but not cleaned
4469 * up ( say a kill -9 )
4470 * But since we haven't actually installed
4471 * them yet( we received them from the kernel )
4472 * we don't think they are active.
4473 * So let's pretend they are active to actually
4475 * In all honesty I'm not sure if we should
4476 * mark them as active when we receive them
4477 * This is startup only so probably ok.
4479 * If we ever decide to move rib_sweep_table
4480 * to a different spot (ie startup )
4481 * this decision needs to be revisited
4483 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
4484 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4485 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
4487 rib_uninstall_kernel(rn
, re
);
4488 rib_delnode(rn
, re
);
4492 if (IS_ZEBRA_DEBUG_RIB
)
4493 zlog_debug("%s: ends", __func__
);
4496 /* Sweep all RIB tables. */
4497 void rib_sweep_route(struct event
*t
)
4500 struct zebra_vrf
*zvrf
;
4502 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4503 if ((zvrf
= vrf
->info
) == NULL
)
4506 rib_sweep_table(zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
4507 rib_sweep_table(zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4510 zebra_router_sweep_route();
4511 zebra_router_sweep_nhgs();
4514 /* Remove specific by protocol routes from 'table'. */
4515 unsigned long rib_score_proto_table(uint8_t proto
, unsigned short instance
,
4516 struct route_table
*table
)
4518 struct route_node
*rn
;
4519 struct route_entry
*re
;
4520 struct route_entry
*next
;
4521 unsigned long n
= 0;
4524 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
4525 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4526 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4528 if (re
->type
== proto
4529 && re
->instance
== instance
) {
4530 rib_delnode(rn
, re
);
4537 /* Remove specific by protocol routes. */
4538 unsigned long rib_score_proto(uint8_t proto
, unsigned short instance
)
4541 struct zebra_vrf
*zvrf
;
4542 struct other_route_table
*ort
;
4543 unsigned long cnt
= 0;
4545 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4550 cnt
+= rib_score_proto_table(proto
, instance
,
4551 zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
4552 + rib_score_proto_table(
4554 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4556 frr_each(otable
, &zvrf
->other_tables
, ort
) cnt
+=
4557 rib_score_proto_table(proto
, instance
, ort
->table
);
4563 /* Close RIB and clean up kernel routes. */
4564 void rib_close_table(struct route_table
*table
)
4566 struct route_node
*rn
;
4572 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4573 dest
= rib_dest_from_rnode(rn
);
4575 if (dest
&& dest
->selected_fib
) {
4576 rib_uninstall_kernel(rn
, dest
->selected_fib
);
4577 dest
->selected_fib
= NULL
;
4583 * Handler for async dataplane results after a pseudowire installation
4585 static void handle_pw_result(struct zebra_dplane_ctx
*ctx
)
4587 struct zebra_pw
*pw
;
4588 struct zebra_vrf
*vrf
;
4590 /* The pseudowire code assumes success - we act on an error
4591 * result for installation attempts here.
4593 if (dplane_ctx_get_op(ctx
) != DPLANE_OP_PW_INSTALL
)
4596 if (dplane_ctx_get_status(ctx
) != ZEBRA_DPLANE_REQUEST_SUCCESS
) {
4597 vrf
= zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
4598 pw
= zebra_pw_find(vrf
, dplane_ctx_get_ifname(ctx
));
4600 zebra_pw_install_failure(pw
,
4601 dplane_ctx_get_pw_status(ctx
));
4606 * Handle results from the dataplane system. Dequeue update context
4607 * structs, dispatch to appropriate internal handlers.
4609 static void rib_process_dplane_results(struct event
*thread
)
4611 struct zebra_dplane_ctx
*ctx
;
4612 struct dplane_ctx_list_head ctxlist
;
4613 bool shut_p
= false;
4615 /* Dequeue a list of completed updates with one lock/unlock cycle */
4618 dplane_ctx_q_init(&ctxlist
);
4620 /* Take lock controlling queue of results */
4621 frr_with_mutex (&dplane_mutex
) {
4622 /* Dequeue list of context structs */
4623 dplane_ctx_list_append(&ctxlist
, &rib_dplane_q
);
4626 /* Dequeue context block */
4627 ctx
= dplane_ctx_dequeue(&ctxlist
);
4629 /* If we've emptied the results queue, we're done */
4633 /* If zebra is shutting down, avoid processing results,
4634 * just drain the results queue.
4636 shut_p
= atomic_load_explicit(&zrouter
.in_shutdown
,
4637 memory_order_relaxed
);
4640 dplane_ctx_fini(&ctx
);
4642 ctx
= dplane_ctx_dequeue(&ctxlist
);
4648 #ifdef HAVE_SCRIPTING
4649 char *script_name
= frrscript_names_get_script_name(
4650 ZEBRA_ON_RIB_PROCESS_HOOK_CALL
);
4653 struct frrscript
*fs
;
4656 fs
= frrscript_new(script_name
);
4658 ret
= frrscript_load(
4659 fs
, ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4662 #endif /* HAVE_SCRIPTING */
4666 #ifdef HAVE_SCRIPTING
4669 ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4671 #endif /* HAVE_SCRIPTING */
4673 switch (dplane_ctx_get_op(ctx
)) {
4674 case DPLANE_OP_ROUTE_INSTALL
:
4675 case DPLANE_OP_ROUTE_UPDATE
:
4676 case DPLANE_OP_ROUTE_DELETE
:
4677 /* Bit of special case for route updates
4678 * that were generated by async notifications:
4679 * we don't want to continue processing these
4682 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4683 rib_process_result(ctx
);
4686 case DPLANE_OP_ROUTE_NOTIFY
:
4687 rib_process_dplane_notify(ctx
);
4690 case DPLANE_OP_NH_INSTALL
:
4691 case DPLANE_OP_NH_UPDATE
:
4692 case DPLANE_OP_NH_DELETE
:
4693 zebra_nhg_dplane_result(ctx
);
4696 case DPLANE_OP_LSP_INSTALL
:
4697 case DPLANE_OP_LSP_UPDATE
:
4698 case DPLANE_OP_LSP_DELETE
:
4699 /* Bit of special case for LSP updates
4700 * that were generated by async notifications:
4701 * we don't want to continue processing these.
4703 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4704 zebra_mpls_lsp_dplane_result(ctx
);
4707 case DPLANE_OP_LSP_NOTIFY
:
4708 zebra_mpls_process_dplane_notify(ctx
);
4711 case DPLANE_OP_PW_INSTALL
:
4712 case DPLANE_OP_PW_UNINSTALL
:
4713 handle_pw_result(ctx
);
4716 case DPLANE_OP_SYS_ROUTE_ADD
:
4717 case DPLANE_OP_SYS_ROUTE_DELETE
:
4720 case DPLANE_OP_MAC_INSTALL
:
4721 case DPLANE_OP_MAC_DELETE
:
4722 zebra_vxlan_handle_result(ctx
);
4725 case DPLANE_OP_RULE_ADD
:
4726 case DPLANE_OP_RULE_DELETE
:
4727 case DPLANE_OP_RULE_UPDATE
:
4728 case DPLANE_OP_IPTABLE_ADD
:
4729 case DPLANE_OP_IPTABLE_DELETE
:
4730 case DPLANE_OP_IPSET_ADD
:
4731 case DPLANE_OP_IPSET_DELETE
:
4732 case DPLANE_OP_IPSET_ENTRY_ADD
:
4733 case DPLANE_OP_IPSET_ENTRY_DELETE
:
4734 zebra_pbr_dplane_result(ctx
);
4737 case DPLANE_OP_INTF_ADDR_ADD
:
4738 case DPLANE_OP_INTF_ADDR_DEL
:
4739 case DPLANE_OP_INTF_INSTALL
:
4740 case DPLANE_OP_INTF_UPDATE
:
4741 case DPLANE_OP_INTF_DELETE
:
4742 case DPLANE_OP_INTF_NETCONFIG
:
4743 zebra_if_dplane_result(ctx
);
4746 case DPLANE_OP_TC_QDISC_INSTALL
:
4747 case DPLANE_OP_TC_QDISC_UNINSTALL
:
4748 case DPLANE_OP_TC_CLASS_ADD
:
4749 case DPLANE_OP_TC_CLASS_DELETE
:
4750 case DPLANE_OP_TC_CLASS_UPDATE
:
4751 case DPLANE_OP_TC_FILTER_ADD
:
4752 case DPLANE_OP_TC_FILTER_DELETE
:
4753 case DPLANE_OP_TC_FILTER_UPDATE
:
4756 /* Some op codes not handled here */
4757 case DPLANE_OP_ADDR_INSTALL
:
4758 case DPLANE_OP_ADDR_UNINSTALL
:
4759 case DPLANE_OP_NEIGH_INSTALL
:
4760 case DPLANE_OP_NEIGH_UPDATE
:
4761 case DPLANE_OP_NEIGH_DELETE
:
4762 case DPLANE_OP_NEIGH_IP_INSTALL
:
4763 case DPLANE_OP_NEIGH_IP_DELETE
:
4764 case DPLANE_OP_VTEP_ADD
:
4765 case DPLANE_OP_VTEP_DELETE
:
4766 case DPLANE_OP_NEIGH_DISCOVER
:
4767 case DPLANE_OP_BR_PORT_UPDATE
:
4768 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
4769 case DPLANE_OP_GRE_SET
:
4770 case DPLANE_OP_NONE
:
4773 } /* Dispatch by op code */
4775 dplane_ctx_fini(&ctx
);
4776 ctx
= dplane_ctx_dequeue(&ctxlist
);
4783 * Results are returned from the dataplane subsystem, in the context of
4784 * the dataplane pthread. We enqueue the results here for processing by
4785 * the main thread later.
4787 static int rib_dplane_results(struct dplane_ctx_list_head
*ctxlist
)
4789 /* Take lock controlling queue of results */
4790 frr_with_mutex (&dplane_mutex
) {
4791 /* Enqueue context blocks */
4792 dplane_ctx_list_append(&rib_dplane_q
, ctxlist
);
4795 /* Ensure event is signalled to zebra main pthread */
4796 event_add_event(zrouter
.master
, rib_process_dplane_results
, NULL
, 0,
4803 * Ensure there are no empty slots in the route_info array.
4804 * Every route type in zebra should be present there.
4806 static void check_route_info(void)
4808 int len
= array_size(route_info
);
4811 * ZEBRA_ROUTE_SYSTEM is special cased since
4812 * its key is 0 anyway.
4814 * ZEBRA_ROUTE_ALL is also ignored.
4816 for (int i
= 0; i
< len
; i
++) {
4817 assert(route_info
[i
].key
>= ZEBRA_ROUTE_SYSTEM
&&
4818 route_info
[i
].key
< ZEBRA_ROUTE_MAX
);
4819 assert(route_info
[i
].meta_q_map
< MQ_SIZE
);
4823 /* Routing information base initialize. */
4830 /* Init dataplane, and register for results */
4831 pthread_mutex_init(&dplane_mutex
, NULL
);
4832 dplane_ctx_q_init(&rib_dplane_q
);
4833 zebra_dplane_init(rib_dplane_results
);
4839 * Get the first vrf id that is greater than the given vrf id if any.
4841 * Returns true if a vrf id was found, false otherwise.
4843 static inline int vrf_id_get_next(vrf_id_t vrf_id
, vrf_id_t
*next_id_p
)
4847 vrf
= vrf_lookup_by_id(vrf_id
);
4849 vrf
= RB_NEXT(vrf_id_head
, vrf
);
4851 *next_id_p
= vrf
->vrf_id
;
4860 * rib_tables_iter_next
4862 * Returns the next table in the iteration.
4864 struct route_table
*rib_tables_iter_next(rib_tables_iter_t
*iter
)
4866 struct route_table
*table
;
4869 * Array that helps us go over all AFI/SAFI combinations via one
4872 static const struct {
4876 {AFI_IP
, SAFI_UNICAST
}, {AFI_IP
, SAFI_MULTICAST
},
4877 {AFI_IP
, SAFI_LABELED_UNICAST
}, {AFI_IP6
, SAFI_UNICAST
},
4878 {AFI_IP6
, SAFI_MULTICAST
}, {AFI_IP6
, SAFI_LABELED_UNICAST
},
4883 switch (iter
->state
) {
4885 case RIB_TABLES_ITER_S_INIT
:
4886 iter
->vrf_id
= VRF_DEFAULT
;
4887 iter
->afi_safi_ix
= -1;
4891 case RIB_TABLES_ITER_S_ITERATING
:
4892 iter
->afi_safi_ix
++;
4895 while (iter
->afi_safi_ix
4896 < (int)array_size(afi_safis
)) {
4897 table
= zebra_vrf_table(
4898 afi_safis
[iter
->afi_safi_ix
].afi
,
4899 afi_safis
[iter
->afi_safi_ix
].safi
,
4904 iter
->afi_safi_ix
++;
4908 * Found another table in this vrf.
4914 * Done with all tables in the current vrf, go to the
4918 if (!vrf_id_get_next(iter
->vrf_id
, &iter
->vrf_id
))
4921 iter
->afi_safi_ix
= 0;
4926 case RIB_TABLES_ITER_S_DONE
:
4931 iter
->state
= RIB_TABLES_ITER_S_ITERATING
;
4933 iter
->state
= RIB_TABLES_ITER_S_DONE
;