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 thread
*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_ipv4_multicast(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
;
518 union g_addr gaddr
= {.ipv4
= addr
};
520 switch (zrouter
.ipv4_multicast_mode
) {
521 case MCAST_MRIB_ONLY
:
522 return rib_match(AFI_IP
, SAFI_MULTICAST
, vrf_id
, &gaddr
,
524 case MCAST_URIB_ONLY
:
525 return rib_match(AFI_IP
, SAFI_UNICAST
, vrf_id
, &gaddr
, rn_out
);
526 case MCAST_NO_CONFIG
:
527 case MCAST_MIX_MRIB_FIRST
:
528 re
= mre
= rib_match(AFI_IP
, SAFI_MULTICAST
, vrf_id
, &gaddr
,
531 re
= ure
= rib_match(AFI_IP
, SAFI_UNICAST
, vrf_id
,
534 case MCAST_MIX_DISTANCE
:
535 mre
= rib_match(AFI_IP
, SAFI_MULTICAST
, vrf_id
, &gaddr
, &m_rn
);
536 ure
= rib_match(AFI_IP
, SAFI_UNICAST
, vrf_id
, &gaddr
, &u_rn
);
538 re
= ure
->distance
< mre
->distance
? ure
: mre
;
544 case MCAST_MIX_PFXLEN
:
545 mre
= rib_match(AFI_IP
, SAFI_MULTICAST
, vrf_id
, &gaddr
, &m_rn
);
546 ure
= rib_match(AFI_IP
, SAFI_UNICAST
, vrf_id
, &gaddr
, &u_rn
);
548 re
= u_rn
->p
.prefixlen
> m_rn
->p
.prefixlen
? ure
: mre
;
557 *rn_out
= (re
== mre
) ? m_rn
: u_rn
;
559 if (IS_ZEBRA_DEBUG_RIB
) {
561 inet_ntop(AF_INET
, &addr
, buf
, BUFSIZ
);
563 zlog_debug("%s: %s: vrf: %s(%u) found %s, using %s", __func__
,
564 buf
, vrf_id_to_name(vrf_id
), vrf_id
,
565 mre
? (ure
? "MRIB+URIB" : "MRIB")
566 : ure
? "URIB" : "nothing",
567 re
== ure
? "URIB" : re
== mre
? "MRIB" : "none");
572 struct route_entry
*rib_match_ipv6_multicast(vrf_id_t vrf_id
,
573 struct in6_addr addr
,
574 struct route_node
**rn_out
)
576 struct route_entry
*re
= NULL
, *mre
= NULL
, *ure
= NULL
;
577 struct route_node
*m_rn
= NULL
, *u_rn
= NULL
;
578 union g_addr gaddr
= {.ipv6
= addr
};
580 switch (zrouter
.ipv4_multicast_mode
) {
581 case MCAST_MRIB_ONLY
:
582 return rib_match(AFI_IP6
, SAFI_MULTICAST
, vrf_id
, &gaddr
,
584 case MCAST_URIB_ONLY
:
585 return rib_match(AFI_IP6
, SAFI_UNICAST
, vrf_id
, &gaddr
, rn_out
);
586 case MCAST_NO_CONFIG
:
587 case MCAST_MIX_MRIB_FIRST
:
588 re
= mre
= rib_match(AFI_IP6
, SAFI_MULTICAST
, vrf_id
, &gaddr
,
591 re
= ure
= rib_match(AFI_IP6
, SAFI_UNICAST
, vrf_id
,
594 case MCAST_MIX_DISTANCE
:
595 mre
= rib_match(AFI_IP6
, SAFI_MULTICAST
, vrf_id
, &gaddr
, &m_rn
);
596 ure
= rib_match(AFI_IP6
, SAFI_UNICAST
, vrf_id
, &gaddr
, &u_rn
);
598 re
= ure
->distance
< mre
->distance
? ure
: mre
;
604 case MCAST_MIX_PFXLEN
:
605 mre
= rib_match(AFI_IP6
, SAFI_MULTICAST
, vrf_id
, &gaddr
, &m_rn
);
606 ure
= rib_match(AFI_IP6
, SAFI_UNICAST
, vrf_id
, &gaddr
, &u_rn
);
608 re
= u_rn
->p
.prefixlen
> m_rn
->p
.prefixlen
? ure
: mre
;
617 *rn_out
= (re
== mre
) ? m_rn
: u_rn
;
619 if (IS_ZEBRA_DEBUG_RIB
)
620 zlog_debug("%s: %pI6: vrf: %s(%u) found %s, using %s", __func__
,
621 &addr
, vrf_id_to_name(vrf_id
), vrf_id
,
622 mre
? (ure
? "MRIB+URIB" : "MRIB")
623 : ure
? "URIB" : "nothing",
624 re
== ure
? "URIB" : re
== mre
? "MRIB" : "none");
628 struct route_entry
*rib_lookup_ipv4(struct prefix_ipv4
*p
, vrf_id_t vrf_id
)
630 struct route_table
*table
;
631 struct route_node
*rn
;
632 struct route_entry
*match
= NULL
;
636 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
640 rn
= route_node_lookup(table
, (struct prefix
*)p
);
642 /* No route for this prefix. */
647 route_unlock_node(rn
);
648 dest
= rib_dest_from_rnode(rn
);
650 if (dest
&& dest
->selected_fib
651 && !CHECK_FLAG(dest
->selected_fib
->status
, ROUTE_ENTRY_REMOVED
))
652 match
= dest
->selected_fib
;
657 if (match
->type
== ZEBRA_ROUTE_CONNECT
)
660 if (CHECK_FLAG(match
->status
, ROUTE_ENTRY_INSTALLED
))
667 * Is this RIB labeled-unicast? It must be of type BGP and all paths
668 * (nexthops) must have a label.
670 int zebra_rib_labeled_unicast(struct route_entry
*re
)
672 struct nexthop
*nexthop
= NULL
;
674 if (re
->type
!= ZEBRA_ROUTE_BGP
)
677 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
678 if (!nexthop
->nh_label
|| !nexthop
->nh_label
->num_labels
)
684 /* Update flag indicates whether this is a "replace" or not. Currently, this
685 * is only used for IPv4.
687 void rib_install_kernel(struct route_node
*rn
, struct route_entry
*re
,
688 struct route_entry
*old
)
690 struct nexthop
*nexthop
;
691 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
692 struct zebra_vrf
*zvrf
= vrf_info_lookup(re
->vrf_id
);
693 const struct prefix
*p
, *src_p
;
694 enum zebra_dplane_result ret
;
696 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
698 srcdest_rnode_prefixes(rn
, &p
, &src_p
);
700 if (info
->safi
!= SAFI_UNICAST
) {
701 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
702 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
708 * Install the resolved nexthop object first.
710 zebra_nhg_install_kernel(re
->nhe
);
713 * If this is a replace to a new RE let the originator of the RE
714 * know that they've lost
716 if (old
&& (old
!= re
) && (old
->type
!= re
->type
))
717 zsend_route_notify_owner(rn
, old
, ZAPI_ROUTE_BETTER_ADMIN_WON
,
718 info
->afi
, info
->safi
);
720 /* Update fib selection */
721 dest
->selected_fib
= re
;
724 * Make sure we update the FPM any time we send new information to
727 hook_call(rib_update
, rn
, "installing in kernel");
729 /* Send add or update */
731 ret
= dplane_route_update(rn
, re
, old
);
733 ret
= dplane_route_add(rn
, re
);
736 case ZEBRA_DPLANE_REQUEST_QUEUED
:
737 SET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
740 SET_FLAG(old
->status
, ROUTE_ENTRY_QUEUED
);
741 SET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
743 /* Free old FIB nexthop group */
744 UNSET_FLAG(old
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
745 if (old
->fib_ng
.nexthop
) {
746 nexthops_free(old
->fib_ng
.nexthop
);
747 old
->fib_ng
.nexthop
= NULL
;
752 zvrf
->installs_queued
++;
754 case ZEBRA_DPLANE_REQUEST_FAILURE
:
756 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
757 "%u:%u:%pRN: Failed to enqueue dataplane install",
758 re
->vrf_id
, re
->table
, rn
);
761 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
770 /* Uninstall the route from kernel. */
771 void rib_uninstall_kernel(struct route_node
*rn
, struct route_entry
*re
)
773 struct nexthop
*nexthop
;
774 struct rib_table_info
*info
= srcdest_rnode_table_info(rn
);
775 struct zebra_vrf
*zvrf
= vrf_info_lookup(re
->vrf_id
);
777 if (info
->safi
!= SAFI_UNICAST
) {
778 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
779 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
780 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
785 * Make sure we update the FPM any time we send new information to
788 hook_call(rib_update
, rn
, "uninstalling from kernel");
790 switch (dplane_route_delete(rn
, re
)) {
791 case ZEBRA_DPLANE_REQUEST_QUEUED
:
793 zvrf
->removals_queued
++;
795 case ZEBRA_DPLANE_REQUEST_FAILURE
:
796 flog_err(EC_ZEBRA_DP_INSTALL_FAIL
,
797 "%u:%pRN: Failed to enqueue dataplane uninstall",
800 case ZEBRA_DPLANE_REQUEST_SUCCESS
:
810 * rib_can_delete_dest
812 * Returns true if the given dest can be deleted from the table.
814 static int rib_can_delete_dest(rib_dest_t
*dest
)
816 if (re_list_first(&dest
->routes
)) {
821 * Unresolved rnh's are stored on the default route's list
823 * dest->rnode can also be the source prefix node in an
824 * ipv6 sourcedest table. Fortunately the prefix of a
825 * source prefix node can never be the default prefix.
827 if (is_default_prefix(&dest
->rnode
->p
))
831 * Don't delete the dest if we have to update the FPM about this
834 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_FPM
)
835 || CHECK_FLAG(dest
->flags
, RIB_DEST_SENT_TO_FPM
))
841 void zebra_rib_evaluate_rn_nexthops(struct route_node
*rn
, uint32_t seq
,
844 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
848 * We are storing the rnh's associated withb
849 * the tracked nexthop as a list of the rn's.
850 * Unresolved rnh's are placed at the top
851 * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
852 * As such for each rn we need to walk up the tree
853 * and see if any rnh's need to see if they
854 * would match a more specific route
857 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
859 "%s: %pRN Being examined for Nexthop Tracking Count: %zd",
861 dest
? rnh_list_count(&dest
->nht
) : 0);
863 if (rt_delete
&& (!dest
|| !rnh_list_count(&dest
->nht
))) {
864 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
865 zlog_debug("%pRN has no tracking NHTs. Bailing",
872 dest
= rib_dest_from_rnode(rn
);
876 * If we have any rnh's stored in the nht list
877 * then we know that this route node was used for
878 * nht resolution and as such we need to call the
879 * nexthop tracking evaluation code
881 frr_each_safe(rnh_list
, &dest
->nht
, rnh
) {
882 struct zebra_vrf
*zvrf
=
883 zebra_vrf_lookup_by_id(rnh
->vrf_id
);
884 struct prefix
*p
= &rnh
->node
->p
;
886 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
888 "%s(%u):%pRN has Nexthop(%pRN) depending on it, evaluating %u:%u",
889 zvrf_name(zvrf
), zvrf_id(zvrf
), rn
,
890 rnh
->node
, seq
, rnh
->seqno
);
893 * If we have evaluated this node on this pass
894 * already, due to following the tree up
895 * then we know that we can move onto the next
898 * Additionally we call zebra_evaluate_rnh
899 * when we gc the dest. In this case we know
900 * that there must be no other re's where
901 * we were originally as such we know that
902 * that sequence number is ok to respect.
904 if (rnh
->seqno
== seq
) {
905 if (IS_ZEBRA_DEBUG_NHT_DETAILED
)
907 " Node processed and moved already");
912 zebra_evaluate_rnh(zvrf
, family2afi(p
->family
), 0, p
,
918 dest
= rib_dest_from_rnode(rn
);
925 * Garbage collect the rib dest corresponding to the given route node
928 * Returns true if the dest was deleted, false otherwise.
930 int rib_gc_dest(struct route_node
*rn
)
934 dest
= rib_dest_from_rnode(rn
);
938 if (!rib_can_delete_dest(dest
))
941 if (IS_ZEBRA_DEBUG_RIB
) {
942 struct zebra_vrf
*zvrf
;
944 zvrf
= rib_dest_vrf(dest
);
945 rnode_debug(rn
, zvrf_id(zvrf
), "removing dest from table");
948 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
952 rnh_list_fini(&dest
->nht
);
953 XFREE(MTYPE_RIB_DEST
, dest
);
957 * Release the one reference that we keep on the route node.
959 route_unlock_node(rn
);
963 void zebra_rtable_node_cleanup(struct route_table
*table
,
964 struct route_node
*node
)
966 struct route_entry
*re
, *next
;
968 RNODE_FOREACH_RE_SAFE (node
, re
, next
) {
969 rib_unlink(node
, re
);
973 rib_dest_t
*dest
= node
->info
;
975 /* Remove from update queue of FPM module */
976 hook_call(rib_shutdown
, node
);
978 rnh_list_fini(&dest
->nht
);
979 XFREE(MTYPE_RIB_DEST
, node
->info
);
983 static void rib_process_add_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
984 struct route_entry
*new)
986 hook_call(rib_update
, rn
, "new route selected");
988 /* Update real nexthop. This may actually determine if nexthop is active
990 if (!nexthop_group_active_nexthop_num(&(new->nhe
->nhg
))) {
991 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
995 if (IS_ZEBRA_DEBUG_RIB
)
996 zlog_debug("%s(%u:%u):%pRN: Adding route rn %p, re %p (%s)",
997 zvrf_name(zvrf
), zvrf_id(zvrf
), new->table
, rn
, rn
,
998 new, zebra_route_string(new->type
));
1000 /* If labeled-unicast route, install transit LSP. */
1001 if (zebra_rib_labeled_unicast(new))
1002 zebra_mpls_lsp_install(zvrf
, rn
, new);
1004 rib_install_kernel(rn
, new, NULL
);
1006 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
1009 static void rib_process_del_fib(struct zebra_vrf
*zvrf
, struct route_node
*rn
,
1010 struct route_entry
*old
)
1012 hook_call(rib_update
, rn
, "removing existing route");
1014 /* Uninstall from kernel. */
1015 if (IS_ZEBRA_DEBUG_RIB
)
1016 zlog_debug("%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s)",
1017 zvrf_name(zvrf
), zvrf_id(zvrf
), old
->table
, rn
, rn
,
1018 old
, zebra_route_string(old
->type
));
1020 /* If labeled-unicast route, uninstall transit LSP. */
1021 if (zebra_rib_labeled_unicast(old
))
1022 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1024 rib_uninstall_kernel(rn
, old
);
1026 /* Update nexthop for route, reset changed flag. */
1027 /* Note: this code also handles the Linux case when an interface goes
1028 * down, causing the kernel to delete routes without sending DELROUTE
1031 if (RIB_KERNEL_ROUTE(old
))
1032 SET_FLAG(old
->status
, ROUTE_ENTRY_REMOVED
);
1034 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
1037 static void rib_process_update_fib(struct zebra_vrf
*zvrf
,
1038 struct route_node
*rn
,
1039 struct route_entry
*old
,
1040 struct route_entry
*new)
1045 * We have to install or update if a new route has been selected or
1046 * something has changed.
1048 if (new != old
|| CHECK_FLAG(new->status
, ROUTE_ENTRY_CHANGED
)) {
1049 hook_call(rib_update
, rn
, "updating existing route");
1051 /* Update the nexthop; we could determine here that nexthop is
1053 if (nexthop_group_active_nexthop_num(&(new->nhe
->nhg
)))
1056 /* If nexthop is active, install the selected route, if
1058 * the install succeeds, cleanup flags for prior route, if
1063 if (IS_ZEBRA_DEBUG_RIB
) {
1066 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s) old %p (%s)",
1067 zvrf_name(zvrf
), zvrf_id(zvrf
),
1068 new->table
, rn
, rn
, new,
1069 zebra_route_string(new->type
),
1071 zebra_route_string(old
->type
));
1074 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s)",
1075 zvrf_name(zvrf
), zvrf_id(zvrf
),
1076 new->table
, rn
, rn
, new,
1077 zebra_route_string(new->type
));
1080 /* If labeled-unicast route, uninstall transit LSP. */
1081 if (zebra_rib_labeled_unicast(old
))
1082 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1085 * Non-system route should be installed.
1086 * If labeled-unicast route, install transit
1089 if (zebra_rib_labeled_unicast(new))
1090 zebra_mpls_lsp_install(zvrf
, rn
, new);
1092 rib_install_kernel(rn
, new, old
);
1096 * If nexthop for selected route is not active or install
1098 * may need to uninstall and delete for redistribution.
1101 if (IS_ZEBRA_DEBUG_RIB
) {
1104 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
1105 zvrf_name(zvrf
), zvrf_id(zvrf
),
1106 new->table
, rn
, rn
, new,
1107 zebra_route_string(new->type
),
1109 zebra_route_string(old
->type
));
1112 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) - nexthop inactive",
1113 zvrf_name(zvrf
), zvrf_id(zvrf
),
1114 new->table
, rn
, rn
, new,
1115 zebra_route_string(new->type
));
1119 * When we have gotten to this point
1120 * the new route entry has no nexthops
1121 * that are usable and as such we need
1122 * to remove the old route, but only
1123 * if we were the one who installed
1126 if (!RIB_SYSTEM_ROUTE(old
)) {
1127 /* If labeled-unicast route, uninstall transit
1129 if (zebra_rib_labeled_unicast(old
))
1130 zebra_mpls_lsp_uninstall(zvrf
, rn
, old
);
1132 rib_uninstall_kernel(rn
, old
);
1137 * Same route selected; check if in the FIB and if not,
1138 * re-install. This is housekeeping code to deal with
1139 * race conditions in kernel with linux netlink reporting
1140 * interface up before IPv4 or IPv6 protocol is ready
1143 if (!CHECK_FLAG(new->status
, ROUTE_ENTRY_INSTALLED
) ||
1144 RIB_SYSTEM_ROUTE(new))
1145 rib_install_kernel(rn
, new, NULL
);
1148 /* Update prior route. */
1150 UNSET_FLAG(old
->status
, ROUTE_ENTRY_CHANGED
);
1152 /* Clear changed flag. */
1153 UNSET_FLAG(new->status
, ROUTE_ENTRY_CHANGED
);
1156 /* Check if 'alternate' RIB entry is better than 'current'. */
1157 static struct route_entry
*rib_choose_best(struct route_entry
*current
,
1158 struct route_entry
*alternate
)
1160 if (current
== NULL
)
1163 /* filter route selection in following order:
1164 * - connected beats other types
1165 * - if both connected, loopback or vrf wins
1166 * - lower distance beats higher
1167 * - lower metric beats higher for equal distance
1168 * - last, hence oldest, route wins tie break.
1171 /* Connected routes. Check to see if either are a vrf
1172 * or loopback interface. If not, pick the last connected
1173 * route of the set of lowest metric connected routes.
1175 if (alternate
->type
== ZEBRA_ROUTE_CONNECT
) {
1176 if (current
->type
!= ZEBRA_ROUTE_CONNECT
)
1179 /* both are connected. are either loop or vrf? */
1180 struct nexthop
*nexthop
= NULL
;
1182 for (ALL_NEXTHOPS(alternate
->nhe
->nhg
, nexthop
)) {
1183 struct interface
*ifp
= if_lookup_by_index(
1184 nexthop
->ifindex
, alternate
->vrf_id
);
1186 if (ifp
&& if_is_loopback(ifp
))
1190 for (ALL_NEXTHOPS(current
->nhe
->nhg
, nexthop
)) {
1191 struct interface
*ifp
= if_lookup_by_index(
1192 nexthop
->ifindex
, current
->vrf_id
);
1194 if (ifp
&& if_is_loopback(ifp
))
1198 /* Neither are loop or vrf so pick best metric */
1199 if (alternate
->metric
<= current
->metric
)
1205 if (current
->type
== ZEBRA_ROUTE_CONNECT
)
1208 /* higher distance loses */
1209 if (alternate
->distance
< current
->distance
)
1211 if (current
->distance
< alternate
->distance
)
1214 /* metric tie-breaks equal distance */
1215 if (alternate
->metric
<= current
->metric
)
1221 /* Core function for processing routing information base. */
1222 static void rib_process(struct route_node
*rn
)
1224 struct route_entry
*re
;
1225 struct route_entry
*next
;
1226 struct route_entry
*old_selected
= NULL
;
1227 struct route_entry
*new_selected
= NULL
;
1228 struct route_entry
*old_fib
= NULL
;
1229 struct route_entry
*new_fib
= NULL
;
1230 struct route_entry
*best
= NULL
;
1232 struct zebra_vrf
*zvrf
= NULL
;
1235 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1239 dest
= rib_dest_from_rnode(rn
);
1241 * We have an enqueued node with nothing to process here
1242 * let's just finish up and return;
1247 zvrf
= rib_dest_vrf(dest
);
1248 vrf_id
= zvrf_id(zvrf
);
1250 vrf
= vrf_lookup_by_id(vrf_id
);
1253 * we can have rn's that have a NULL info pointer
1254 * (dest). As such let's not let the deref happen
1255 * additionally we know RNODE_FOREACH_RE_SAFE
1256 * will not iterate so we are ok.
1258 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1259 struct route_entry
*re
= re_list_first(&dest
->routes
);
1261 zlog_debug("%s(%u:%u):%pRN: Processing rn %p",
1262 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
,
1266 old_fib
= dest
->selected_fib
;
1268 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1269 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1270 char flags_buf
[128];
1271 char status_buf
[128];
1274 "%s(%u:%u):%pRN: Examine re %p (%s) status: %sflags: %sdist %d metric %d",
1275 VRF_LOGNAME(vrf
), vrf_id
, re
->table
, rn
, re
,
1276 zebra_route_string(re
->type
),
1277 _dump_re_status(re
, status_buf
,
1278 sizeof(status_buf
)),
1279 zclient_dump_route_flags(re
->flags
, flags_buf
,
1281 re
->distance
, re
->metric
);
1284 /* Currently selected re. */
1285 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1286 assert(old_selected
== NULL
);
1290 /* Skip deleted entries from selection */
1291 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1295 * If the route entry has changed, verify/resolve
1296 * the nexthops associated with the entry.
1298 * In any event if we have nexthops that are not active
1299 * then we cannot use this particular route entry so
1302 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
)) {
1303 if (!nexthop_active_update(rn
, re
)) {
1304 const struct prefix
*p
;
1305 struct rib_table_info
*info
;
1307 if (re
->type
== ZEBRA_ROUTE_TABLE
) {
1308 /* XXX: HERE BE DRAGONS!!!!!
1309 * In all honesty, I have not yet
1310 * figured out what this part does or
1311 * why the ROUTE_ENTRY_CHANGED test
1312 * above is correct or why we need to
1313 * delete a route here, and also not
1314 * whether this concerns both selected
1315 * and fib route, or only selected
1318 * This entry was denied by the 'ip
1320 * table' route-map, we need to delete
1322 if (re
!= old_selected
) {
1323 if (IS_ZEBRA_DEBUG_RIB
)
1325 "%s: %s(%u):%pRN: imported via import-table but denied by the ip protocol table route-map",
1333 SET_FLAG(re
->status
,
1334 ROUTE_ENTRY_REMOVED
);
1337 info
= srcdest_rnode_table_info(rn
);
1338 srcdest_rnode_prefixes(rn
, &p
, NULL
);
1339 zsend_route_notify_owner(
1340 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
1341 info
->afi
, info
->safi
);
1346 * If the re has not changed and the nhg we have is
1347 * not usable, then we cannot use this route entry
1348 * for consideration, as that the route will just
1349 * not install if it is selected.
1351 if (!nexthop_group_active_nexthop_num(&re
->nhe
->nhg
))
1355 /* Infinite distance. */
1356 if (re
->distance
== DISTANCE_INFINITY
&&
1357 re
->type
!= ZEBRA_ROUTE_KERNEL
) {
1358 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1362 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_FIB_OVERRIDE
)) {
1363 best
= rib_choose_best(new_fib
, re
);
1364 if (new_fib
&& best
!= new_fib
)
1365 UNSET_FLAG(new_fib
->status
,
1366 ROUTE_ENTRY_CHANGED
);
1369 best
= rib_choose_best(new_selected
, re
);
1370 if (new_selected
&& best
!= new_selected
)
1371 UNSET_FLAG(new_selected
->status
,
1372 ROUTE_ENTRY_CHANGED
);
1373 new_selected
= best
;
1376 UNSET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
1377 } /* RNODE_FOREACH_RE */
1379 /* If no FIB override route, use the selected route also for FIB */
1380 if (new_fib
== NULL
)
1381 new_fib
= new_selected
;
1383 /* After the cycle is finished, the following pointers will be set:
1384 * old_selected --- RE entry currently having SELECTED
1385 * new_selected --- RE entry that is newly SELECTED
1386 * old_fib --- RE entry currently in kernel FIB
1387 * new_fib --- RE entry that is newly to be in kernel FIB
1389 * new_selected will get SELECTED flag, and is going to be redistributed
1390 * the zclients. new_fib (which can be new_selected) will be installed
1394 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
1395 struct route_entry
*entry
;
1397 entry
= old_selected
1402 : new_fib
? new_fib
: NULL
;
1405 "%s(%u:%u):%pRN: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
1406 VRF_LOGNAME(vrf
), vrf_id
, entry
? entry
->table
: 0, rn
,
1407 (void *)old_selected
, (void *)new_selected
,
1408 (void *)old_fib
, (void *)new_fib
);
1411 /* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
1412 * fib == selected */
1413 bool selected_changed
= new_selected
&& CHECK_FLAG(new_selected
->status
,
1414 ROUTE_ENTRY_CHANGED
);
1416 /* Update SELECTED entry */
1417 if (old_selected
!= new_selected
|| selected_changed
) {
1419 if (new_selected
&& new_selected
!= new_fib
)
1420 UNSET_FLAG(new_selected
->status
, ROUTE_ENTRY_CHANGED
);
1423 SET_FLAG(new_selected
->flags
, ZEBRA_FLAG_SELECTED
);
1427 * If we're removing the old entry, we should tell
1428 * redist subscribers about that *if* they aren't
1429 * going to see a redist for the new entry.
1431 if (!new_selected
|| CHECK_FLAG(old_selected
->status
,
1432 ROUTE_ENTRY_REMOVED
))
1433 redistribute_delete(rn
, old_selected
,
1436 if (old_selected
!= new_selected
)
1437 UNSET_FLAG(old_selected
->flags
,
1438 ZEBRA_FLAG_SELECTED
);
1442 /* Update fib according to selection results */
1443 if (new_fib
&& old_fib
)
1444 rib_process_update_fib(zvrf
, rn
, old_fib
, new_fib
);
1446 rib_process_add_fib(zvrf
, rn
, new_fib
);
1448 rib_process_del_fib(zvrf
, rn
, old_fib
);
1450 /* Remove all RE entries queued for removal */
1451 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
1452 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1453 if (IS_ZEBRA_DEBUG_RIB
) {
1454 rnode_debug(rn
, vrf_id
, "rn %p, removing re %p",
1455 (void *)rn
, (void *)re
);
1462 * Check if the dest can be deleted now.
1467 static void zebra_rib_evaluate_mpls(struct route_node
*rn
)
1469 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
1470 struct zebra_vrf
*zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1475 if (CHECK_FLAG(dest
->flags
, RIB_DEST_UPDATE_LSPS
)) {
1476 if (IS_ZEBRA_DEBUG_MPLS
)
1478 "%s(%u): Scheduling all LSPs upon RIB completion",
1479 zvrf_name(zvrf
), zvrf_id(zvrf
));
1480 zebra_mpls_lsp_schedule(zvrf
);
1481 mpls_unmark_lsps_for_processing(rn
);
1486 * Utility to match route with dplane context data
1488 static bool rib_route_match_ctx(const struct route_entry
*re
,
1489 const struct zebra_dplane_ctx
*ctx
,
1492 bool result
= false;
1496 * In 'update' case, we test info about the 'previous' or
1499 if ((re
->type
== dplane_ctx_get_old_type(ctx
)) &&
1500 (re
->instance
== dplane_ctx_get_old_instance(ctx
))) {
1503 /* We use an extra test for statics, and another for
1506 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1507 (re
->distance
!= dplane_ctx_get_old_distance(ctx
) ||
1508 re
->tag
!= dplane_ctx_get_old_tag(ctx
))) {
1510 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1512 dplane_ctx_get_old_metric(ctx
)) {
1519 * Ordinary, single-route case using primary context info
1521 if ((dplane_ctx_get_op(ctx
) != DPLANE_OP_ROUTE_DELETE
) &&
1522 CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
1523 /* Skip route that's been deleted */
1527 if ((re
->type
== dplane_ctx_get_type(ctx
)) &&
1528 (re
->instance
== dplane_ctx_get_instance(ctx
))) {
1531 /* We use an extra test for statics, and another for
1534 if (re
->type
== ZEBRA_ROUTE_STATIC
&&
1535 (re
->distance
!= dplane_ctx_get_distance(ctx
) ||
1536 re
->tag
!= dplane_ctx_get_tag(ctx
))) {
1538 } else if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
1539 re
->metric
!= dplane_ctx_get_metric(ctx
)) {
1541 } else if (re
->type
== ZEBRA_ROUTE_CONNECT
) {
1542 result
= nexthop_group_equal_no_recurse(
1543 &re
->nhe
->nhg
, dplane_ctx_get_ng(ctx
));
1552 static void zebra_rib_fixup_system(struct route_node
*rn
)
1554 struct route_entry
*re
;
1556 RNODE_FOREACH_RE(rn
, re
) {
1557 struct nexthop
*nhop
;
1559 if (!RIB_SYSTEM_ROUTE(re
))
1562 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
1565 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
1566 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
1567 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
1569 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nhop
)) {
1570 if (CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1573 SET_FLAG(nhop
->flags
, NEXTHOP_FLAG_FIB
);
1578 /* Route comparison logic, with various special cases. */
1579 static bool rib_compare_routes(const struct route_entry
*re1
,
1580 const struct route_entry
*re2
)
1582 if (re1
->type
!= re2
->type
)
1585 if (re1
->instance
!= re2
->instance
)
1588 if (re1
->type
== ZEBRA_ROUTE_KERNEL
&& re1
->metric
!= re2
->metric
)
1591 if (CHECK_FLAG(re1
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
1592 re1
->distance
!= re2
->distance
)
1595 /* We support multiple connected routes: this supports multiple
1596 * v6 link-locals, and we also support multiple addresses in the same
1597 * subnet on a single interface.
1599 if (re1
->type
!= ZEBRA_ROUTE_CONNECT
)
1606 * Compare nexthop lists from a route and a dplane context; test whether
1607 * the list installed in the FIB matches the route's list.
1608 * Set 'changed_p' to 'true' if there were changes to the route's
1609 * installed nexthops.
1611 * Return 'false' if any ACTIVE route nexthops are not mentioned in the FIB
1614 static bool rib_update_nhg_from_ctx(struct nexthop_group
*re_nhg
,
1615 const struct nexthop_group
*ctx_nhg
,
1618 bool matched_p
= true;
1619 struct nexthop
*nexthop
, *ctx_nexthop
;
1621 /* Get the first `installed` one to check against.
1622 * If the dataplane doesn't set these to be what was actually installed,
1623 * it will just be whatever was in re->nhe->nhg?
1625 ctx_nexthop
= ctx_nhg
->nexthop
;
1627 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
1628 || !CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1629 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1631 for (ALL_NEXTHOPS_PTR(re_nhg
, nexthop
)) {
1633 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1636 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1639 /* Check for a FIB nexthop corresponding to the RIB nexthop */
1640 if (!nexthop_same(ctx_nexthop
, nexthop
)) {
1641 /* If the FIB doesn't know about the nexthop,
1642 * it's not installed
1644 if (IS_ZEBRA_DEBUG_RIB_DETAILED
||
1645 IS_ZEBRA_DEBUG_NHG_DETAIL
) {
1646 zlog_debug("%s: no ctx match for rib nh %pNHv %s",
1648 (CHECK_FLAG(nexthop
->flags
,
1654 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1657 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1659 /* Keep checking nexthops */
1663 if (CHECK_FLAG(ctx_nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1664 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1665 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1666 zlog_debug("%s: rib nh %pNHv -> installed",
1672 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1674 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)) {
1675 if (IS_ZEBRA_DEBUG_NHG_DETAIL
)
1676 zlog_debug("%s: rib nh %pNHv -> uninstalled",
1682 UNSET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1685 ctx_nexthop
= nexthop_next_active_resolved(ctx_nexthop
);
1692 * Update a route from a dplane context. This consolidates common code
1693 * that can be used in processing of results from FIB updates, and in
1694 * async notification processing.
1695 * The return is 'true' if the installed nexthops changed; 'false' otherwise.
1697 static bool rib_update_re_from_ctx(struct route_entry
*re
,
1698 struct route_node
*rn
,
1699 struct zebra_dplane_ctx
*ctx
)
1701 struct nexthop
*nexthop
;
1703 const struct nexthop_group
*ctxnhg
;
1704 struct nexthop_group
*re_nhg
;
1705 bool is_selected
= false; /* Is 're' currently the selected re? */
1706 bool changed_p
= false; /* Change to nexthops? */
1710 vrf
= vrf_lookup_by_id(re
->vrf_id
);
1712 dest
= rib_dest_from_rnode(rn
);
1714 is_selected
= (re
== dest
->selected_fib
);
1716 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1717 zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p",
1718 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1719 (is_selected
? "" : "NOT "), re
);
1721 /* Update zebra's nexthop FIB flag for each nexthop that was installed.
1722 * If the installed set differs from the set requested by the rib/owner,
1723 * we use the fib-specific nexthop-group to record the actual FIB
1727 ctxnhg
= dplane_ctx_get_ng(ctx
);
1729 /* Check route's fib group and incoming notif group for equivalence.
1731 * Let's assume the nexthops are ordered here to save time.
1733 /* TODO -- this isn't testing or comparing the FIB flags; we should
1734 * do a more explicit loop, checking the incoming notification's flags.
1736 if (re
->fib_ng
.nexthop
&& ctxnhg
->nexthop
&&
1737 nexthop_group_equal(&re
->fib_ng
, ctxnhg
))
1740 /* If the new FIB set matches the existing FIB set, we're done. */
1742 if (IS_ZEBRA_DEBUG_RIB
)
1744 "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change",
1745 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1748 } else if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
)) {
1750 * Free stale fib list and move on to check the rib nhg.
1752 if (IS_ZEBRA_DEBUG_RIB
)
1754 "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg",
1755 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1756 nexthops_free(re
->fib_ng
.nexthop
);
1757 re
->fib_ng
.nexthop
= NULL
;
1759 UNSET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1761 /* Note that the installed nexthops have changed */
1764 if (IS_ZEBRA_DEBUG_RIB
)
1766 "%s(%u:%u):%pRN update_from_ctx(): no fib nhg",
1767 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
);
1771 * Compare with the rib nexthop group. The comparison here is different:
1772 * the RIB group may be a superset of the list installed in the FIB. We
1773 * walk the RIB group, looking for the 'installable' candidate
1774 * nexthops, and then check those against the set
1775 * that is actually installed.
1777 * Assume nexthops are ordered here as well.
1780 /* If nothing is installed, we can skip some of the checking/comparison
1783 if (ctxnhg
->nexthop
== NULL
) {
1788 matched
= rib_update_nhg_from_ctx(&(re
->nhe
->nhg
), ctxnhg
, &changed_p
);
1790 /* If all nexthops were processed, we're done */
1792 if (IS_ZEBRA_DEBUG_RIB
)
1794 "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'",
1795 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1796 (changed_p
? "true" : "false"));
1802 /* FIB nexthop set differs from the RIB set:
1803 * create a fib-specific nexthop-group
1805 if (IS_ZEBRA_DEBUG_RIB
)
1807 "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s",
1808 VRF_LOGNAME(vrf
), re
->vrf_id
, re
->table
, rn
,
1809 (changed_p
? "true" : "false"),
1810 ctxnhg
->nexthop
!= NULL
? "" : " (empty)");
1812 /* Set the flag about the dedicated fib list */
1813 if (zrouter
.asic_notification_nexthop_control
) {
1814 SET_FLAG(re
->status
, ROUTE_ENTRY_USE_FIB_NHG
);
1815 if (ctxnhg
->nexthop
)
1816 copy_nexthops(&(re
->fib_ng
.nexthop
), ctxnhg
->nexthop
,
1823 * Check the status of the route's backup nexthops, if any.
1824 * The logic for backups is somewhat different: if any backup is
1825 * installed, a new fib nhg will be attached to the route.
1827 re_nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1829 goto done
; /* No backup nexthops */
1831 /* First check the route's 'fib' list of backups, if it's present
1832 * from some previous event.
1834 re_nhg
= &re
->fib_backup_ng
;
1835 ctxnhg
= dplane_ctx_get_backup_ng(ctx
);
1838 if (re_nhg
->nexthop
&& ctxnhg
&& nexthop_group_equal(re_nhg
, ctxnhg
))
1841 /* If the new FIB set matches an existing FIB set, we're done. */
1843 if (IS_ZEBRA_DEBUG_RIB
)
1845 "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change",
1846 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1849 } else if (re
->fib_backup_ng
.nexthop
) {
1851 * Free stale fib backup list and move on to check
1852 * the route's backups.
1854 if (IS_ZEBRA_DEBUG_RIB
)
1856 "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg",
1857 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1858 nexthops_free(re
->fib_backup_ng
.nexthop
);
1859 re
->fib_backup_ng
.nexthop
= NULL
;
1861 /* Note that the installed nexthops have changed */
1864 if (IS_ZEBRA_DEBUG_RIB
)
1866 "%s(%u):%pRN update_from_ctx(): no fib backup nhg",
1867 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
);
1871 * If a FIB backup nexthop set exists, attach a copy
1872 * to the route if any backup is installed
1874 if (ctxnhg
&& ctxnhg
->nexthop
) {
1876 for (ALL_NEXTHOPS_PTR(ctxnhg
, nexthop
)) {
1877 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1881 /* If no installed backups, we're done */
1882 if (nexthop
== NULL
)
1885 if (IS_ZEBRA_DEBUG_RIB
)
1887 "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg",
1888 VRF_LOGNAME(vrf
), re
->vrf_id
, rn
,
1889 (changed_p
? "true" : "false"));
1891 copy_nexthops(&(re
->fib_backup_ng
.nexthop
), ctxnhg
->nexthop
,
1901 * Helper to locate a zebra route-node from a dplane context. This is used
1902 * when processing dplane results, e.g. Note well: the route-node is returned
1903 * with a ref held - route_unlock_node() must be called eventually.
1905 struct route_node
*rib_find_rn_from_ctx(const struct zebra_dplane_ctx
*ctx
)
1907 struct route_table
*table
= NULL
;
1908 struct route_node
*rn
= NULL
;
1909 const struct prefix
*dest_pfx
, *src_pfx
;
1911 /* Locate rn and re(s) from ctx */
1913 table
= zebra_vrf_lookup_table_with_table_id(
1914 dplane_ctx_get_afi(ctx
), dplane_ctx_get_safi(ctx
),
1915 dplane_ctx_get_vrf(ctx
), dplane_ctx_get_table(ctx
));
1916 if (table
== NULL
) {
1917 if (IS_ZEBRA_DEBUG_DPLANE
) {
1919 "Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u)",
1920 dplane_ctx_get_afi(ctx
),
1921 dplane_ctx_get_safi(ctx
),
1922 vrf_id_to_name(dplane_ctx_get_vrf(ctx
)),
1923 dplane_ctx_get_vrf(ctx
));
1928 dest_pfx
= dplane_ctx_get_dest(ctx
);
1929 src_pfx
= dplane_ctx_get_src(ctx
);
1931 rn
= srcdest_rnode_get(table
, dest_pfx
,
1932 src_pfx
? (struct prefix_ipv6
*)src_pfx
: NULL
);
1941 * Route-update results processing after async dataplane update.
1943 static void rib_process_result(struct zebra_dplane_ctx
*ctx
)
1945 struct zebra_vrf
*zvrf
= NULL
;
1947 struct route_node
*rn
= NULL
;
1948 struct route_entry
*re
= NULL
, *old_re
= NULL
, *rib
;
1949 bool is_update
= false;
1950 enum dplane_op_e op
;
1951 enum zebra_dplane_result status
;
1954 bool fib_changed
= false;
1955 struct rib_table_info
*info
;
1956 bool rt_delete
= false;
1958 zvrf
= vrf_info_lookup(dplane_ctx_get_vrf(ctx
));
1959 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
1961 /* Locate rn and re(s) from ctx */
1962 rn
= rib_find_rn_from_ctx(ctx
);
1964 if (IS_ZEBRA_DEBUG_DPLANE
) {
1966 "Failed to process dplane results: no route for %s(%u):%pRN",
1967 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
), rn
);
1972 dest
= rib_dest_from_rnode(rn
);
1973 info
= srcdest_rnode_table_info(rn
);
1975 op
= dplane_ctx_get_op(ctx
);
1976 status
= dplane_ctx_get_status(ctx
);
1978 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
1980 "%s(%u:%u):%pRN Processing dplane result ctx %p, op %s result %s",
1981 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
1982 dplane_ctx_get_table(ctx
), rn
, ctx
, dplane_op2str(op
),
1983 dplane_res2str(status
));
1986 * Update is a bit of a special case, where we may have both old and new
1987 * routes to post-process.
1989 is_update
= dplane_ctx_is_update(ctx
);
1992 * Take a pass through the routes, look for matches with the context
1995 RNODE_FOREACH_RE(rn
, rib
) {
1998 if (rib_route_match_ctx(rib
, ctx
, false))
2002 /* Check for old route match */
2003 if (is_update
&& (old_re
== NULL
)) {
2004 if (rib_route_match_ctx(rib
, ctx
, true /*is_update*/))
2008 /* Have we found the routes we need to work on? */
2009 if (re
&& ((!is_update
|| old_re
)))
2013 seq
= dplane_ctx_get_seq(ctx
);
2016 * Check sequence number(s) to detect stale results before continuing
2019 if (re
->dplane_sequence
!= seq
) {
2020 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
2022 "%s(%u):%pRN Stale dplane result for re %p",
2024 dplane_ctx_get_vrf(ctx
), rn
, re
);
2026 if (!zrouter
.asic_offloaded
||
2027 (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
) ||
2028 CHECK_FLAG(re
->flags
,
2029 ZEBRA_FLAG_OFFLOAD_FAILED
))) {
2030 UNSET_FLAG(re
->status
,
2031 ROUTE_ENTRY_ROUTE_REPLACING
);
2032 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
2038 if (old_re
->dplane_sequence
!= dplane_ctx_get_old_seq(ctx
)) {
2039 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
2041 "%s(%u:%u):%pRN Stale dplane result for old_re %p",
2043 dplane_ctx_get_vrf(ctx
), old_re
->table
,
2046 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_QUEUED
);
2050 case DPLANE_OP_ROUTE_INSTALL
:
2051 case DPLANE_OP_ROUTE_UPDATE
:
2052 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
2054 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2055 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2058 * On an update operation from the same route type
2059 * context retrieval currently has no way to know
2060 * which was the old and which was the new.
2061 * So don't unset our flags that we just set.
2062 * We know redistribution is ok because the
2063 * old_re in this case is used for nothing
2064 * more than knowing whom to contact if necessary.
2066 if (old_re
&& old_re
!= re
) {
2067 UNSET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2068 UNSET_FLAG(old_re
->status
,
2069 ROUTE_ENTRY_INSTALLED
);
2072 /* Update zebra route based on the results in
2073 * the context struct.
2077 rib_update_re_from_ctx(re
, rn
, ctx
);
2080 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
)
2082 "%s(%u:%u):%pRN no fib change for re",
2084 dplane_ctx_get_vrf(ctx
),
2085 dplane_ctx_get_table(
2090 /* Redistribute if this is the selected re */
2091 if (dest
&& re
== dest
->selected_fib
)
2092 redistribute_update(rn
, re
, old_re
);
2096 * System routes are weird in that they
2097 * allow multiple to be installed that match
2098 * to the same prefix, so after we get the
2099 * result we need to clean them up so that
2100 * we can actually use them.
2102 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2103 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2104 zebra_rib_fixup_system(rn
);
2109 /* Notify route owner */
2110 if (zebra_router_notify_on_ack())
2111 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2114 if (CHECK_FLAG(re
->flags
,
2115 ZEBRA_FLAG_OFFLOADED
))
2116 zsend_route_notify_owner_ctx(
2118 ZAPI_ROUTE_INSTALLED
);
2121 ZEBRA_FLAG_OFFLOAD_FAILED
))
2122 zsend_route_notify_owner_ctx(
2124 ZAPI_ROUTE_FAIL_INSTALL
);
2129 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2130 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2132 SET_FLAG(old_re
->status
, ROUTE_ENTRY_FAILED
);
2134 zsend_route_notify_owner(
2135 rn
, re
, ZAPI_ROUTE_FAIL_INSTALL
,
2136 info
->afi
, info
->safi
);
2138 zlog_warn("%s(%u:%u):%pRN: Route install failed",
2139 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2140 dplane_ctx_get_table(ctx
), rn
);
2143 case DPLANE_OP_ROUTE_DELETE
:
2146 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2148 * In the delete case, the zebra core datastructs were
2149 * updated (or removed) at the time the delete was issued,
2150 * so we're just notifying the route owner.
2152 if (status
== ZEBRA_DPLANE_REQUEST_SUCCESS
) {
2154 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2155 UNSET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2157 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_REMOVED
);
2163 SET_FLAG(re
->status
, ROUTE_ENTRY_FAILED
);
2164 zsend_route_notify_owner_ctx(ctx
,
2165 ZAPI_ROUTE_REMOVE_FAIL
);
2167 zlog_warn("%s(%u:%u):%pRN: Route Deletion failure",
2168 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2169 dplane_ctx_get_table(ctx
), rn
);
2173 * System routes are weird in that they
2174 * allow multiple to be installed that match
2175 * to the same prefix, so after we get the
2176 * result we need to clean them up so that
2177 * we can actually use them.
2179 if ((re
&& RIB_SYSTEM_ROUTE(re
)) ||
2180 (old_re
&& RIB_SYSTEM_ROUTE(old_re
)))
2181 zebra_rib_fixup_system(rn
);
2184 case DPLANE_OP_NONE
:
2185 case DPLANE_OP_ROUTE_NOTIFY
:
2186 case DPLANE_OP_NH_INSTALL
:
2187 case DPLANE_OP_NH_UPDATE
:
2188 case DPLANE_OP_NH_DELETE
:
2189 case DPLANE_OP_LSP_INSTALL
:
2190 case DPLANE_OP_LSP_UPDATE
:
2191 case DPLANE_OP_LSP_DELETE
:
2192 case DPLANE_OP_LSP_NOTIFY
:
2193 case DPLANE_OP_PW_INSTALL
:
2194 case DPLANE_OP_PW_UNINSTALL
:
2195 case DPLANE_OP_SYS_ROUTE_ADD
:
2196 case DPLANE_OP_SYS_ROUTE_DELETE
:
2197 case DPLANE_OP_ADDR_INSTALL
:
2198 case DPLANE_OP_ADDR_UNINSTALL
:
2199 case DPLANE_OP_MAC_INSTALL
:
2200 case DPLANE_OP_MAC_DELETE
:
2201 case DPLANE_OP_NEIGH_INSTALL
:
2202 case DPLANE_OP_NEIGH_UPDATE
:
2203 case DPLANE_OP_NEIGH_DELETE
:
2204 case DPLANE_OP_VTEP_ADD
:
2205 case DPLANE_OP_VTEP_DELETE
:
2206 case DPLANE_OP_RULE_ADD
:
2207 case DPLANE_OP_RULE_DELETE
:
2208 case DPLANE_OP_RULE_UPDATE
:
2209 case DPLANE_OP_NEIGH_DISCOVER
:
2210 case DPLANE_OP_BR_PORT_UPDATE
:
2211 case DPLANE_OP_IPTABLE_ADD
:
2212 case DPLANE_OP_IPTABLE_DELETE
:
2213 case DPLANE_OP_IPSET_ADD
:
2214 case DPLANE_OP_IPSET_DELETE
:
2215 case DPLANE_OP_IPSET_ENTRY_ADD
:
2216 case DPLANE_OP_IPSET_ENTRY_DELETE
:
2217 case DPLANE_OP_NEIGH_IP_INSTALL
:
2218 case DPLANE_OP_NEIGH_IP_DELETE
:
2219 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
2220 case DPLANE_OP_GRE_SET
:
2221 case DPLANE_OP_INTF_ADDR_ADD
:
2222 case DPLANE_OP_INTF_ADDR_DEL
:
2223 case DPLANE_OP_INTF_NETCONFIG
:
2224 case DPLANE_OP_INTF_INSTALL
:
2225 case DPLANE_OP_INTF_UPDATE
:
2226 case DPLANE_OP_INTF_DELETE
:
2227 case DPLANE_OP_TC_QDISC_INSTALL
:
2228 case DPLANE_OP_TC_QDISC_UNINSTALL
:
2229 case DPLANE_OP_TC_CLASS_ADD
:
2230 case DPLANE_OP_TC_CLASS_DELETE
:
2231 case DPLANE_OP_TC_CLASS_UPDATE
:
2232 case DPLANE_OP_TC_FILTER_ADD
:
2233 case DPLANE_OP_TC_FILTER_DELETE
:
2234 case DPLANE_OP_TC_FILTER_UPDATE
:
2238 zebra_rib_evaluate_rn_nexthops(rn
, seq
, rt_delete
);
2239 zebra_rib_evaluate_mpls(rn
);
2243 route_unlock_node(rn
);
2247 * Count installed/FIB nexthops
2249 static int rib_count_installed_nh(struct route_entry
*re
)
2252 struct nexthop
*nexthop
;
2253 struct nexthop_group
*nhg
;
2255 nhg
= rib_get_fib_nhg(re
);
2257 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2258 /* The meaningful flag depends on where the installed
2261 if (nhg
== &(re
->fib_ng
)) {
2262 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2265 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2270 nhg
= rib_get_fib_backup_nhg(re
);
2272 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
2273 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2282 * Handle notification from async dataplane: the dataplane has detected
2283 * some change to a route, and notifies zebra so that the control plane
2284 * can reflect that change.
2286 static void rib_process_dplane_notify(struct zebra_dplane_ctx
*ctx
)
2288 struct route_node
*rn
= NULL
;
2289 struct route_entry
*re
= NULL
;
2291 struct nexthop
*nexthop
;
2293 bool fib_changed
= false;
2294 bool debug_p
= IS_ZEBRA_DEBUG_DPLANE
| IS_ZEBRA_DEBUG_RIB
;
2295 int start_count
, end_count
;
2297 vrf
= vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
2299 /* Locate rn and re(s) from ctx */
2300 rn
= rib_find_rn_from_ctx(ctx
);
2304 "Failed to process dplane notification: no routes for %s(%u:%u):%pRN",
2305 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2306 dplane_ctx_get_table(ctx
), rn
);
2311 dest
= rib_dest_from_rnode(rn
);
2314 zlog_debug("%s(%u:%u):%pRN Processing dplane notif ctx %p",
2315 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2316 dplane_ctx_get_table(ctx
), rn
, ctx
);
2319 * Take a pass through the routes, look for matches with the context
2322 RNODE_FOREACH_RE(rn
, re
) {
2323 if (rib_route_match_ctx(re
, ctx
, false /*!update*/))
2327 /* No match? Nothing we can do */
2331 "%s(%u:%u):%pRN Unable to process dplane notification: no entry for type %s",
2332 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2333 dplane_ctx_get_table(ctx
), rn
,
2334 zebra_route_string(dplane_ctx_get_type(ctx
)));
2339 /* Ensure we clear the QUEUED flag */
2340 UNSET_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
);
2341 UNSET_FLAG(re
->status
, ROUTE_ENTRY_ROUTE_REPLACING
);
2343 /* Is this a notification that ... matters? We mostly care about
2344 * the route that is currently selected for installation; we may also
2345 * get an un-install notification, and handle that too.
2347 if (re
!= dest
->selected_fib
) {
2349 * If we need to, clean up after a delete that was part of
2350 * an update operation.
2353 for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx
), nexthop
)) {
2354 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2358 /* If no nexthops or none installed, ensure that this re
2359 * gets its 'installed' flag cleared.
2361 if (end_count
== 0) {
2362 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2363 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2366 "%s(%u:%u):%pRN dplane notif, uninstalled type %s route",
2368 dplane_ctx_get_vrf(ctx
),
2369 dplane_ctx_get_table(ctx
), rn
,
2371 dplane_ctx_get_type(ctx
)));
2373 /* At least report on the event. */
2376 "%s(%u:%u):%pRN dplane notif, but type %s not selected_fib",
2378 dplane_ctx_get_vrf(ctx
),
2379 dplane_ctx_get_table(ctx
), rn
,
2381 dplane_ctx_get_type(ctx
)));
2385 uint32_t flags
= dplane_ctx_get_flags(ctx
);
2387 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOADED
)) {
2388 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2389 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2391 if (CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOAD_FAILED
)) {
2392 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
);
2393 SET_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
);
2395 if (CHECK_FLAG(flags
, ZEBRA_FLAG_TRAPPED
))
2396 SET_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
);
2399 /* We'll want to determine whether the installation status of the
2400 * route has changed: we'll check the status before processing,
2401 * and then again if there's been a change.
2405 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
2406 start_count
= rib_count_installed_nh(re
);
2408 /* Update zebra's nexthop FIB flags based on the context struct's
2411 fib_changed
= rib_update_re_from_ctx(re
, rn
, ctx
);
2416 "%s(%u:%u):%pRN dplane notification: rib_update returns FALSE",
2417 VRF_LOGNAME(vrf
), dplane_ctx_get_vrf(ctx
),
2418 dplane_ctx_get_table(ctx
), rn
);
2422 * Perform follow-up work if the actual status of the prefix
2425 end_count
= rib_count_installed_nh(re
);
2427 /* Various fib transitions: changed nexthops; from installed to
2428 * not-installed; or not-installed to installed.
2430 if (zrouter
.asic_notification_nexthop_control
) {
2431 if (start_count
> 0 && end_count
> 0) {
2434 "%s(%u:%u):%pRN applied nexthop changes from dplane notification",
2436 dplane_ctx_get_vrf(ctx
),
2437 dplane_ctx_get_table(ctx
), rn
);
2439 /* Changed nexthops - update kernel/others */
2440 dplane_route_notif_update(rn
, re
,
2441 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2443 } else if (start_count
== 0 && end_count
> 0) {
2446 "%s(%u:%u):%pRN installed transition from dplane notification",
2448 dplane_ctx_get_vrf(ctx
),
2449 dplane_ctx_get_table(ctx
), rn
);
2451 /* We expect this to be the selected route, so we want
2452 * to tell others about this transition.
2454 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2456 /* Changed nexthops - update kernel/others */
2457 dplane_route_notif_update(rn
, re
,
2458 DPLANE_OP_ROUTE_UPDATE
, ctx
);
2460 /* Redistribute, lsp, and nht update */
2461 redistribute_update(rn
, re
, NULL
);
2463 } else if (start_count
> 0 && end_count
== 0) {
2466 "%s(%u:%u):%pRN un-installed transition from dplane notification",
2468 dplane_ctx_get_vrf(ctx
),
2469 dplane_ctx_get_table(ctx
), rn
);
2471 /* Transition from _something_ installed to _nothing_
2474 /* We expect this to be the selected route, so we want
2475 * to tell others about this transistion.
2477 UNSET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
2479 /* Changed nexthops - update kernel/others */
2480 dplane_route_notif_update(rn
, re
,
2481 DPLANE_OP_ROUTE_DELETE
, ctx
);
2483 /* Redistribute, lsp, and nht update */
2484 redistribute_delete(rn
, re
, NULL
);
2488 if (!zebra_router_notify_on_ack()) {
2489 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
2490 zsend_route_notify_owner_ctx(ctx
, ZAPI_ROUTE_INSTALLED
);
2491 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
2492 zsend_route_notify_owner_ctx(ctx
,
2493 ZAPI_ROUTE_FAIL_INSTALL
);
2496 /* Make any changes visible for lsp and nexthop-tracking processing */
2497 zebra_rib_evaluate_rn_nexthops(rn
, zebra_router_get_next_sequence(),
2500 zebra_rib_evaluate_mpls(rn
);
2504 route_unlock_node(rn
);
2508 * Process a node from the EVPN/VXLAN subqueue.
2510 static void process_subq_evpn(struct listnode
*lnode
)
2512 struct wq_evpn_wrapper
*w
;
2514 /* In general, the list node points to a wrapper object
2515 * holding the info necessary to make some update.
2517 w
= listgetdata(lnode
);
2521 if (w
->type
== WQ_EVPN_WRAPPER_TYPE_VRFROUTE
) {
2523 zebra_vxlan_evpn_vrf_route_add(w
->vrf_id
, &w
->macaddr
,
2524 &w
->ip
, &w
->prefix
);
2526 zebra_vxlan_evpn_vrf_route_del(w
->vrf_id
, &w
->ip
,
2528 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_ES
) {
2530 zebra_evpn_remote_es_add(&w
->esi
, w
->ip
.ipaddr_v4
,
2531 w
->esr_rxed
, w
->df_alg
,
2534 zebra_evpn_remote_es_del(&w
->esi
, w
->ip
.ipaddr_v4
);
2535 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_MACIP
) {
2536 uint16_t ipa_len
= 0;
2538 if (w
->ip
.ipa_type
== IPADDR_V4
)
2539 ipa_len
= IPV4_MAX_BYTELEN
;
2540 else if (w
->ip
.ipa_type
== IPADDR_V6
)
2541 ipa_len
= IPV6_MAX_BYTELEN
;
2544 zebra_evpn_rem_macip_add(w
->vni
, &w
->macaddr
, ipa_len
,
2545 &w
->ip
, w
->flags
, w
->seq
,
2546 w
->vtep_ip
, &w
->esi
);
2548 zebra_evpn_rem_macip_del(w
->vni
, &w
->macaddr
, ipa_len
,
2549 &w
->ip
, w
->vtep_ip
);
2550 } else if (w
->type
== WQ_EVPN_WRAPPER_TYPE_REM_VTEP
) {
2552 zebra_vxlan_remote_vtep_add(w
->vrf_id
, w
->vni
,
2553 w
->vtep_ip
, w
->flags
);
2555 zebra_vxlan_remote_vtep_del(w
->vrf_id
, w
->vni
,
2560 XFREE(MTYPE_WQ_WRAPPER
, w
);
2564 * Process the nexthop-group workqueue subqueue
2566 static void process_subq_nhg(struct listnode
*lnode
)
2568 struct nhg_ctx
*ctx
;
2569 struct nhg_hash_entry
*nhe
, *newnhe
;
2570 struct wq_nhg_wrapper
*w
;
2571 uint8_t qindex
= META_QUEUE_NHG
;
2573 w
= listgetdata(lnode
);
2578 /* Two types of object - an update from the local kernel, or
2579 * an nhg update from a daemon.
2581 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
) {
2584 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2586 "NHG Context id=%u dequeued from sub-queue %s",
2587 ctx
->id
, subqueue2str(qindex
));
2590 /* Process nexthop group updates coming 'up' from the OS */
2591 nhg_ctx_process(ctx
);
2593 } else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
) {
2596 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2597 zlog_debug("NHG %u dequeued from sub-queue %s", nhe
->id
,
2598 subqueue2str(qindex
));
2600 /* Process incoming nhg update, probably from a proto daemon */
2601 newnhe
= zebra_nhg_proto_add(nhe
->id
, nhe
->type
,
2603 nhe
->zapi_session
, &nhe
->nhg
, 0);
2605 /* Report error to daemon via ZAPI */
2607 zsend_nhg_notify(nhe
->type
, nhe
->zapi_instance
,
2608 nhe
->zapi_session
, nhe
->id
,
2609 ZAPI_NHG_FAIL_INSTALL
);
2611 /* Free temp nhe - we own that memory. */
2612 zebra_nhg_free(nhe
);
2615 XFREE(MTYPE_WQ_WRAPPER
, w
);
2618 static void process_subq_early_label(struct listnode
*lnode
)
2620 struct wq_label_wrapper
*w
= listgetdata(lnode
);
2621 struct zebra_vrf
*zvrf
;
2626 zvrf
= vrf_info_lookup(w
->vrf_id
);
2628 XFREE(MTYPE_WQ_WRAPPER
, w
);
2633 case WQ_LABEL_FTN_UNINSTALL
:
2634 zebra_mpls_ftn_uninstall(zvrf
, w
->ltype
, &w
->p
, w
->route_type
,
2637 case WQ_LABEL_LABELS_PROCESS
:
2638 zebra_mpls_zapi_labels_process(w
->add_p
, zvrf
, &w
->zl
);
2642 XFREE(MTYPE_WQ_WRAPPER
, w
);
2645 static void process_subq_route(struct listnode
*lnode
, uint8_t qindex
)
2647 struct route_node
*rnode
= NULL
;
2648 rib_dest_t
*dest
= NULL
;
2649 struct zebra_vrf
*zvrf
= NULL
;
2651 rnode
= listgetdata(lnode
);
2652 dest
= rib_dest_from_rnode(rnode
);
2655 zvrf
= rib_dest_vrf(dest
);
2659 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
2660 struct route_entry
*re
= NULL
;
2663 * rib_process may have freed the dest
2664 * as part of the garbage collection. Let's
2665 * prevent stupidity from happening.
2667 dest
= rib_dest_from_rnode(rnode
);
2669 re
= re_list_first(&dest
->routes
);
2671 zlog_debug("%s(%u:%u):%pRN rn %p dequeued from sub-queue %s",
2672 zvrf_name(zvrf
), zvrf_id(zvrf
), re
? re
->table
: 0,
2673 rnode
, rnode
, subqueue2str(qindex
));
2677 UNSET_FLAG(rib_dest_from_rnode(rnode
)->flags
,
2678 RIB_ROUTE_QUEUED(qindex
));
2680 route_unlock_node(rnode
);
2683 static void rib_re_nhg_free(struct route_entry
*re
)
2685 if (re
->nhe
&& re
->nhe_id
) {
2686 assert(re
->nhe
->id
== re
->nhe_id
);
2687 route_entry_update_nhe(re
, NULL
);
2688 } else if (re
->nhe
&& re
->nhe
->nhg
.nexthop
)
2689 nexthops_free(re
->nhe
->nhg
.nexthop
);
2691 nexthops_free(re
->fib_ng
.nexthop
);
2694 struct zebra_early_route
{
2698 struct prefix_ipv6 src_p
;
2699 bool src_p_provided
;
2700 struct route_entry
*re
;
2701 struct nhg_hash_entry
*re_nhe
;
2707 static void early_route_memory_free(struct zebra_early_route
*ere
)
2710 zebra_nhg_free(ere
->re_nhe
);
2712 XFREE(MTYPE_RE
, ere
->re
);
2713 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2716 static void process_subq_early_route_add(struct zebra_early_route
*ere
)
2718 struct route_entry
*re
= ere
->re
;
2719 struct route_table
*table
;
2720 struct nhg_hash_entry
*nhe
= NULL
;
2721 struct route_node
*rn
;
2722 struct route_entry
*same
= NULL
, *first_same
= NULL
;
2727 table
= zebra_vrf_get_table_with_table_id(ere
->afi
, ere
->safi
,
2728 re
->vrf_id
, re
->table
);
2730 early_route_memory_free(ere
);
2734 if (re
->nhe_id
> 0) {
2735 nhe
= zebra_nhg_lookup_id(re
->nhe_id
);
2739 * We've received from the kernel a nexthop id
2740 * that we don't have saved yet. More than likely
2741 * it has not been processed and is on the
2742 * queue to be processed. Let's stop what we
2743 * are doing and cause the meta q to be processed
2744 * storing this for later.
2746 * This is being done this way because zebra
2747 * runs with the assumption t
2750 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2751 "Zebra failed to find the nexthop hash entry for id=%u in a route entry %pFX",
2752 re
->nhe_id
, &ere
->p
);
2754 early_route_memory_free(ere
);
2758 /* Lookup nhe from route information */
2759 nhe
= zebra_nhg_rib_find_nhe(ere
->re_nhe
, ere
->afi
);
2761 char buf2
[PREFIX_STRLEN
] = "";
2764 EC_ZEBRA_TABLE_LOOKUP_FAILED
,
2765 "Zebra failed to find or create a nexthop hash entry for %pFX%s%s",
2766 &ere
->p
, ere
->src_p_provided
? " from " : "",
2768 ? prefix2str(&ere
->src_p
, buf2
,
2772 early_route_memory_free(ere
);
2778 * Attach the re to the nhe's nexthop group.
2780 * TODO: This will need to change when we start getting IDs from upper
2781 * level protocols, as the refcnt might be wrong, since it checks
2782 * if old_id != new_id.
2784 route_entry_update_nhe(re
, nhe
);
2786 /* Make it sure prefixlen is applied to the prefix. */
2787 apply_mask(&ere
->p
);
2788 if (ere
->src_p_provided
)
2789 apply_mask_ipv6(&ere
->src_p
);
2791 /* Lookup route node.*/
2792 rn
= srcdest_rnode_get(table
, &ere
->p
,
2793 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2796 * If same type of route are installed, treat it as a implicit
2797 * withdraw. If the user has specified the No route replace semantics
2798 * for the install don't do a route replace.
2800 RNODE_FOREACH_RE (rn
, same
) {
2801 if (CHECK_FLAG(same
->status
, ROUTE_ENTRY_REMOVED
)) {
2806 /* Compare various route_entry properties */
2807 if (rib_compare_routes(re
, same
)) {
2810 if (first_same
== NULL
)
2817 if (!ere
->startup
&& (re
->flags
& ZEBRA_FLAG_SELFROUTE
) &&
2818 zrouter
.asic_offloaded
) {
2820 if (IS_ZEBRA_DEBUG_RIB
)
2822 "prefix: %pRN is a self route where we do not have an entry for it. Dropping this update, it's useless",
2825 * We are not on startup, this is a self route
2826 * and we have asic offload. Which means
2827 * we are getting a callback for a entry
2828 * that was already deleted to the kernel
2829 * but an earlier response was just handed
2830 * back. Drop it on the floor
2832 early_route_memory_free(ere
);
2837 /* Set default distance by route type. */
2838 if (re
->distance
== 0) {
2839 if (same
&& !zebra_router_notify_on_ack())
2840 re
->distance
= same
->distance
;
2842 re
->distance
= route_distance(re
->type
);
2845 if (re
->metric
== ROUTE_INSTALLATION_METRIC
&&
2846 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
2847 if (same
&& !zebra_router_notify_on_ack())
2848 re
->metric
= same
->metric
;
2853 /* If this route is kernel/connected route, notify the dataplane. */
2854 if (RIB_SYSTEM_ROUTE(re
)) {
2855 /* Notify dataplane */
2856 dplane_sys_route_add(rn
, re
);
2859 /* Link new re to node.*/
2860 if (IS_ZEBRA_DEBUG_RIB
) {
2863 "Inserting route rn %p, re %p (%s) existing %p, same_count %d",
2864 rn
, re
, zebra_route_string(re
->type
), same
, same_count
);
2866 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
2869 ere
->src_p_provided
? &ere
->src_p
: NULL
, re
);
2872 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
2873 rib_addnode(rn
, re
, 1);
2875 /* Free implicit route.*/
2877 rib_delnode(rn
, same
);
2879 /* See if we can remove some RE entries that are queued for
2880 * removal, but won't be considered in rib processing.
2882 dest
= rib_dest_from_rnode(rn
);
2883 RNODE_FOREACH_RE_SAFE (rn
, re
, same
) {
2884 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
2885 /* If the route was used earlier, must retain it. */
2886 if (dest
&& re
== dest
->selected_fib
)
2889 if (IS_ZEBRA_DEBUG_RIB
)
2890 rnode_debug(rn
, re
->vrf_id
,
2891 "rn %p, removing unneeded re %p",
2898 route_unlock_node(rn
);
2900 zebra_nhg_free(ere
->re_nhe
);
2901 XFREE(MTYPE_WQ_WRAPPER
, ere
);
2904 static void process_subq_early_route_delete(struct zebra_early_route
*ere
)
2906 struct route_table
*table
;
2907 struct route_node
*rn
;
2908 struct route_entry
*re
;
2909 struct route_entry
*fib
= NULL
;
2910 struct route_entry
*same
= NULL
;
2911 struct nexthop
*rtnh
;
2912 char buf2
[INET6_ADDRSTRLEN
];
2915 if (ere
->src_p_provided
)
2916 assert(!ere
->src_p
.prefixlen
|| ere
->afi
== AFI_IP6
);
2919 table
= zebra_vrf_lookup_table_with_table_id(
2920 ere
->afi
, ere
->safi
, ere
->re
->vrf_id
, ere
->re
->table
);
2922 early_route_memory_free(ere
);
2927 apply_mask(&ere
->p
);
2928 if (ere
->src_p_provided
)
2929 apply_mask_ipv6(&ere
->src_p
);
2931 /* Lookup route node. */
2932 rn
= srcdest_rnode_lookup(table
, &ere
->p
,
2933 ere
->src_p_provided
? &ere
->src_p
: NULL
);
2935 if (IS_ZEBRA_DEBUG_RIB
) {
2936 char src_buf
[PREFIX_STRLEN
];
2937 struct vrf
*vrf
= vrf_lookup_by_id(ere
->re
->vrf_id
);
2939 if (ere
->src_p_provided
&& ere
->src_p
.prefixlen
)
2940 prefix2str(&ere
->src_p
, src_buf
,
2945 zlog_debug("%s[%d]:%pRN%s%s doesn't exist in rib",
2946 vrf
->name
, ere
->re
->table
, rn
,
2947 (src_buf
[0] != '\0') ? " from " : "",
2950 early_route_memory_free(ere
);
2954 dest
= rib_dest_from_rnode(rn
);
2955 fib
= dest
->selected_fib
;
2957 struct nexthop
*nh
= NULL
;
2960 nh
= ere
->re
->nhe
->nhg
.nexthop
;
2962 /* Lookup same type route. */
2963 RNODE_FOREACH_RE (rn
, re
) {
2964 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
2967 if (re
->type
!= ere
->re
->type
)
2969 if (re
->instance
!= ere
->re
->instance
)
2971 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) &&
2972 ere
->re
->distance
!= re
->distance
)
2975 if (re
->type
== ZEBRA_ROUTE_KERNEL
&&
2976 re
->metric
!= ere
->re
->metric
)
2978 if (re
->type
== ZEBRA_ROUTE_CONNECT
&& (rtnh
= nh
) &&
2979 rtnh
->type
== NEXTHOP_TYPE_IFINDEX
&& nh
) {
2980 if (rtnh
->ifindex
!= nh
->ifindex
)
2986 /* Make sure that the route found has the same gateway. */
2987 if (ere
->re
->nhe_id
&& re
->nhe_id
== ere
->re
->nhe_id
) {
2996 for (ALL_NEXTHOPS(re
->nhe
->nhg
, rtnh
)) {
2998 * No guarantee all kernel send nh with labels
3001 if (nexthop_same_no_labels(rtnh
, nh
)) {
3011 * If same type of route can't be found and this message is from
3016 * In the past(HA!) we could get here because
3017 * we were receiving a route delete from the
3018 * kernel and we're not marking the proto
3019 * as coming from it's appropriate originator.
3020 * Now that we are properly noticing the fact
3021 * that the kernel has deleted our route we
3022 * are not going to get called in this path
3023 * I am going to leave this here because
3024 * this might still work this way on non-linux
3025 * platforms as well as some weird state I have
3026 * not properly thought of yet.
3027 * If we can show that this code path is
3028 * dead then we can remove it.
3030 if (fib
&& CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
)) {
3031 if (IS_ZEBRA_DEBUG_RIB
) {
3033 rn
, ere
->re
->vrf_id
,
3034 "rn %p, re %p (%s) was deleted from kernel, adding",
3035 rn
, fib
, zebra_route_string(fib
->type
));
3037 if (zrouter
.allow_delete
||
3038 CHECK_FLAG(dest
->flags
, RIB_ROUTE_ANY_QUEUED
)) {
3039 UNSET_FLAG(fib
->status
, ROUTE_ENTRY_INSTALLED
);
3041 for (rtnh
= fib
->nhe
->nhg
.nexthop
; rtnh
;
3043 UNSET_FLAG(rtnh
->flags
,
3047 * This is a non FRR route
3048 * as such we should mark
3051 dest
->selected_fib
= NULL
;
3054 * This means someone else, other than Zebra,
3055 * has deleted a Zebra router from the kernel.
3056 * We will add it back
3058 rib_install_kernel(rn
, fib
, NULL
);
3061 if (IS_ZEBRA_DEBUG_RIB
) {
3064 rn
, ere
->re
->vrf_id
,
3065 "via %s ifindex %d type %d doesn't exist in rib",
3066 inet_ntop(afi2family(ere
->afi
),
3069 nh
->ifindex
, ere
->re
->type
);
3072 rn
, ere
->re
->vrf_id
,
3073 "type %d doesn't exist in rib",
3076 route_unlock_node(rn
);
3077 early_route_memory_free(ere
);
3083 struct nexthop
*tmp_nh
;
3085 if (ere
->fromkernel
&&
3086 CHECK_FLAG(ere
->re
->flags
, ZEBRA_FLAG_SELFROUTE
) &&
3087 !zrouter
.allow_delete
) {
3088 rib_install_kernel(rn
, same
, NULL
);
3089 route_unlock_node(rn
);
3091 early_route_memory_free(ere
);
3095 /* Special handling for IPv4 or IPv6 routes sourced from
3096 * EVPN - the nexthop (and associated MAC) need to be
3097 * uninstalled if no more refs.
3099 for (ALL_NEXTHOPS(re
->nhe
->nhg
, tmp_nh
)) {
3100 struct ipaddr vtep_ip
;
3102 if (CHECK_FLAG(tmp_nh
->flags
, NEXTHOP_FLAG_EVPN
)) {
3103 memset(&vtep_ip
, 0, sizeof(struct ipaddr
));
3104 if (ere
->afi
== AFI_IP
) {
3105 vtep_ip
.ipa_type
= IPADDR_V4
;
3106 memcpy(&(vtep_ip
.ipaddr_v4
),
3107 &(tmp_nh
->gate
.ipv4
),
3108 sizeof(struct in_addr
));
3110 vtep_ip
.ipa_type
= IPADDR_V6
;
3111 memcpy(&(vtep_ip
.ipaddr_v6
),
3112 &(tmp_nh
->gate
.ipv6
),
3113 sizeof(struct in6_addr
));
3115 zebra_rib_queue_evpn_route_del(
3116 re
->vrf_id
, &vtep_ip
, &ere
->p
);
3120 /* Notify dplane if system route changes */
3121 if (RIB_SYSTEM_ROUTE(re
))
3122 dplane_sys_route_del(rn
, same
);
3124 rib_delnode(rn
, same
);
3127 route_unlock_node(rn
);
3129 early_route_memory_free(ere
);
3133 * When FRR receives a route we need to match the route up to
3134 * nexthop groups. That we also may have just received
3135 * place the data on this queue so that this work of finding
3136 * the nexthop group entries for the route entry is always
3137 * done after the nexthop group has had a chance to be processed
3139 static void process_subq_early_route(struct listnode
*lnode
)
3141 struct zebra_early_route
*ere
= listgetdata(lnode
);
3144 process_subq_early_route_delete(ere
);
3146 process_subq_early_route_add(ere
);
3150 * Examine the specified subqueue; process one entry and return 1 if
3151 * there is a node, return 0 otherwise.
3153 static unsigned int process_subq(struct list
*subq
,
3154 enum meta_queue_indexes qindex
)
3156 struct listnode
*lnode
= listhead(subq
);
3162 case META_QUEUE_EVPN
:
3163 process_subq_evpn(lnode
);
3165 case META_QUEUE_NHG
:
3166 process_subq_nhg(lnode
);
3168 case META_QUEUE_EARLY_ROUTE
:
3169 process_subq_early_route(lnode
);
3171 case META_QUEUE_EARLY_LABEL
:
3172 process_subq_early_label(lnode
);
3174 case META_QUEUE_CONNECTED
:
3175 case META_QUEUE_KERNEL
:
3176 case META_QUEUE_STATIC
:
3177 case META_QUEUE_NOTBGP
:
3178 case META_QUEUE_BGP
:
3179 case META_QUEUE_OTHER
:
3180 process_subq_route(lnode
, qindex
);
3184 list_delete_node(subq
, lnode
);
3189 /* Dispatch the meta queue by picking and processing the next node from
3190 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
3191 * data is pointed to the meta queue structure.
3193 static wq_item_status
meta_queue_process(struct work_queue
*dummy
, void *data
)
3195 struct meta_queue
*mq
= data
;
3197 uint32_t queue_len
, queue_limit
;
3199 /* Ensure there's room for more dataplane updates */
3200 queue_limit
= dplane_get_in_queue_limit();
3201 queue_len
= dplane_get_in_queue_len();
3202 if (queue_len
> queue_limit
) {
3203 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3205 "rib queue: dplane queue len %u, limit %u, retrying",
3206 queue_len
, queue_limit
);
3208 /* Ensure that the meta-queue is actually enqueued */
3209 if (work_queue_empty(zrouter
.ribq
))
3210 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3212 return WQ_QUEUE_BLOCKED
;
3215 for (i
= 0; i
< MQ_SIZE
; i
++)
3216 if (process_subq(mq
->subq
[i
], i
)) {
3220 return mq
->size
? WQ_REQUEUE
: WQ_SUCCESS
;
3225 * Look into the RN and queue it into the highest priority queue
3226 * at this point in time for processing.
3228 * We will enqueue a route node only once per invocation.
3230 * There are two possibilities here that should be kept in mind.
3231 * If the original invocation has not been pulled off for processing
3232 * yet, A subsuquent invocation can have a route entry with a better
3233 * meta queue index value and we can have a situation where
3234 * we might have the same node enqueued 2 times. Not necessarily
3235 * an optimal situation but it should be ok.
3237 * The other possibility is that the original invocation has not
3238 * been pulled off for processing yet, A subsusquent invocation
3239 * doesn't have a route_entry with a better meta-queue and the
3240 * original metaqueue index value will win and we'll end up with
3241 * the route node enqueued once.
3243 static int rib_meta_queue_add(struct meta_queue
*mq
, void *data
)
3245 struct route_node
*rn
= NULL
;
3246 struct route_entry
*re
= NULL
, *curr_re
= NULL
;
3247 uint8_t qindex
= MQ_SIZE
, curr_qindex
= MQ_SIZE
;
3249 rn
= (struct route_node
*)data
;
3251 RNODE_FOREACH_RE (rn
, curr_re
) {
3252 curr_qindex
= route_info
[curr_re
->type
].meta_q_map
;
3254 if (curr_qindex
<= qindex
) {
3256 qindex
= curr_qindex
;
3263 /* Invariant: at this point we always have rn->info set. */
3264 if (CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
3265 RIB_ROUTE_QUEUED(qindex
))) {
3266 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3267 rnode_debug(rn
, re
->vrf_id
,
3268 "rn %p is already queued in sub-queue %s",
3269 (void *)rn
, subqueue2str(qindex
));
3273 SET_FLAG(rib_dest_from_rnode(rn
)->flags
, RIB_ROUTE_QUEUED(qindex
));
3274 listnode_add(mq
->subq
[qindex
], rn
);
3275 route_lock_node(rn
);
3278 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3279 rnode_debug(rn
, re
->vrf_id
, "queued rn %p into sub-queue %s",
3280 (void *)rn
, subqueue2str(qindex
));
3285 static int early_label_meta_queue_add(struct meta_queue
*mq
, void *data
)
3287 listnode_add(mq
->subq
[META_QUEUE_EARLY_LABEL
], data
);
3292 static int rib_meta_queue_nhg_ctx_add(struct meta_queue
*mq
, void *data
)
3294 struct nhg_ctx
*ctx
= NULL
;
3295 uint8_t qindex
= META_QUEUE_NHG
;
3296 struct wq_nhg_wrapper
*w
;
3298 ctx
= (struct nhg_ctx
*)data
;
3303 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3305 w
->type
= WQ_NHG_WRAPPER_TYPE_CTX
;
3308 listnode_add(mq
->subq
[qindex
], w
);
3311 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3312 zlog_debug("NHG Context id=%u queued into sub-queue %s",
3313 ctx
->id
, subqueue2str(qindex
));
3318 static int rib_meta_queue_nhg_add(struct meta_queue
*mq
, void *data
)
3320 struct nhg_hash_entry
*nhe
= NULL
;
3321 uint8_t qindex
= META_QUEUE_NHG
;
3322 struct wq_nhg_wrapper
*w
;
3324 nhe
= (struct nhg_hash_entry
*)data
;
3329 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_nhg_wrapper
));
3331 w
->type
= WQ_NHG_WRAPPER_TYPE_NHG
;
3334 listnode_add(mq
->subq
[qindex
], w
);
3337 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3338 zlog_debug("NHG id=%u queued into sub-queue %s", nhe
->id
,
3339 subqueue2str(qindex
));
3344 static int rib_meta_queue_evpn_add(struct meta_queue
*mq
, void *data
)
3346 listnode_add(mq
->subq
[META_QUEUE_EVPN
], data
);
3352 static int mq_add_handler(void *data
,
3353 int (*mq_add_func
)(struct meta_queue
*mq
, void *data
))
3355 if (zrouter
.ribq
== NULL
) {
3356 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3357 "%s: work_queue does not exist!", __func__
);
3362 * The RIB queue should normally be either empty or holding the only
3363 * work_queue_item element. In the latter case this element would
3364 * hold a pointer to the meta queue structure, which must be used to
3365 * actually queue the route nodes to process. So create the MQ
3366 * holder, if necessary, then push the work into it in any case.
3367 * This semantics was introduced after 0.99.9 release.
3369 if (work_queue_empty(zrouter
.ribq
))
3370 work_queue_add(zrouter
.ribq
, zrouter
.mq
);
3372 return mq_add_func(zrouter
.mq
, data
);
3375 void mpls_ftn_uninstall(struct zebra_vrf
*zvrf
, enum lsp_types_t type
,
3376 struct prefix
*prefix
, uint8_t route_type
,
3377 uint8_t route_instance
)
3379 struct wq_label_wrapper
*w
;
3381 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3383 w
->type
= WQ_LABEL_FTN_UNINSTALL
;
3384 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3387 w
->route_type
= route_type
;
3388 w
->route_instance
= route_instance
;
3390 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3391 zlog_debug("Early Label Handling for %pFX", prefix
);
3393 mq_add_handler(w
, early_label_meta_queue_add
);
3396 void mpls_zapi_labels_process(bool add_p
, struct zebra_vrf
*zvrf
,
3397 const struct zapi_labels
*zl
)
3399 struct wq_label_wrapper
*w
;
3401 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_label_wrapper
));
3402 w
->type
= WQ_LABEL_LABELS_PROCESS
;
3403 w
->vrf_id
= zvrf
->vrf
->vrf_id
;
3407 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3408 zlog_debug("Early Label Handling: Labels Process");
3410 mq_add_handler(w
, early_label_meta_queue_add
);
3413 /* Add route_node to work queue and schedule processing */
3414 int rib_queue_add(struct route_node
*rn
)
3418 /* Pointless to queue a route_node with no RIB entries to add or remove
3420 if (!rnode_to_ribs(rn
)) {
3421 zlog_debug("%s: called for route_node (%p, %u) with no ribs",
3422 __func__
, (void *)rn
, route_node_get_lock_count(rn
));
3423 zlog_backtrace(LOG_DEBUG
);
3427 return mq_add_handler(rn
, rib_meta_queue_add
);
3431 * Enqueue incoming nhg info from OS for processing
3433 int rib_queue_nhg_ctx_add(struct nhg_ctx
*ctx
)
3437 return mq_add_handler(ctx
, rib_meta_queue_nhg_ctx_add
);
3441 * Enqueue incoming nhg from proto daemon for processing
3443 int rib_queue_nhe_add(struct nhg_hash_entry
*nhe
)
3448 return mq_add_handler(nhe
, rib_meta_queue_nhg_add
);
3452 * Enqueue evpn route for processing
3454 int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id
, const struct ethaddr
*rmac
,
3455 const struct ipaddr
*vtep_ip
,
3456 const struct prefix
*host_prefix
)
3458 struct wq_evpn_wrapper
*w
;
3460 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3462 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3467 w
->prefix
= *host_prefix
;
3469 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3470 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3471 vrf_id
, vtep_ip
, host_prefix
);
3473 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3476 int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id
,
3477 const struct ipaddr
*vtep_ip
,
3478 const struct prefix
*host_prefix
)
3480 struct wq_evpn_wrapper
*w
;
3482 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3484 w
->type
= WQ_EVPN_WRAPPER_TYPE_VRFROUTE
;
3488 w
->prefix
= *host_prefix
;
3490 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3491 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__
,
3492 vrf_id
, vtep_ip
, host_prefix
);
3494 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3497 /* Enqueue EVPN remote ES for processing */
3498 int zebra_rib_queue_evpn_rem_es_add(const esi_t
*esi
,
3499 const struct in_addr
*vtep_ip
,
3500 bool esr_rxed
, uint8_t df_alg
,
3503 struct wq_evpn_wrapper
*w
;
3504 char buf
[ESI_STR_LEN
];
3506 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3508 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3511 w
->ip
.ipa_type
= IPADDR_V4
;
3512 w
->ip
.ipaddr_v4
= *vtep_ip
;
3513 w
->esr_rxed
= esr_rxed
;
3515 w
->df_pref
= df_pref
;
3517 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3518 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3519 esi_to_str(esi
, buf
, sizeof(buf
)));
3521 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3524 int zebra_rib_queue_evpn_rem_es_del(const esi_t
*esi
,
3525 const struct in_addr
*vtep_ip
)
3527 struct wq_evpn_wrapper
*w
;
3528 char buf
[ESI_STR_LEN
];
3530 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3532 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_ES
;
3535 w
->ip
.ipa_type
= IPADDR_V4
;
3536 w
->ip
.ipaddr_v4
= *vtep_ip
;
3538 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3539 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3540 esi_to_str(esi
, buf
, sizeof(buf
));
3542 strlcpy(buf
, "-", sizeof(buf
));
3544 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__
, vtep_ip
,
3548 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3552 * Enqueue EVPN remote macip update for processing
3554 int zebra_rib_queue_evpn_rem_macip_add(vni_t vni
, const struct ethaddr
*macaddr
,
3555 const struct ipaddr
*ipaddr
,
3556 uint8_t flags
, uint32_t seq
,
3557 struct in_addr vtep_ip
, const esi_t
*esi
)
3559 struct wq_evpn_wrapper
*w
;
3560 char buf
[ESI_STR_LEN
];
3562 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3564 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3567 w
->macaddr
= *macaddr
;
3571 w
->vtep_ip
= vtep_ip
;
3574 if (IS_ZEBRA_DEBUG_RIB_DETAILED
) {
3575 if (memcmp(esi
, zero_esi
, sizeof(esi_t
)) != 0)
3576 esi_to_str(esi
, buf
, sizeof(buf
));
3578 strlcpy(buf
, "-", sizeof(buf
));
3580 zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__
,
3581 macaddr
, &vtep_ip
, buf
);
3584 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3587 int zebra_rib_queue_evpn_rem_macip_del(vni_t vni
, const struct ethaddr
*macaddr
,
3588 const struct ipaddr
*ip
,
3589 struct in_addr vtep_ip
)
3591 struct wq_evpn_wrapper
*w
;
3593 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3595 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_MACIP
;
3598 w
->macaddr
= *macaddr
;
3600 w
->vtep_ip
= vtep_ip
;
3602 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3603 zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__
,
3606 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3610 * Enqueue remote VTEP address for processing
3612 int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id
, vni_t vni
,
3613 struct in_addr vtep_ip
, int flood_control
)
3615 struct wq_evpn_wrapper
*w
;
3617 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3619 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3623 w
->vtep_ip
= vtep_ip
;
3624 w
->flags
= flood_control
;
3626 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3627 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3630 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3633 int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id
, vni_t vni
,
3634 struct in_addr vtep_ip
)
3636 struct wq_evpn_wrapper
*w
;
3638 w
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(struct wq_evpn_wrapper
));
3640 w
->type
= WQ_EVPN_WRAPPER_TYPE_REM_VTEP
;
3644 w
->vtep_ip
= vtep_ip
;
3646 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3647 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__
, vrf_id
,
3650 return mq_add_handler(w
, rib_meta_queue_evpn_add
);
3653 /* Create new meta queue.
3654 A destructor function doesn't seem to be necessary here.
3656 static struct meta_queue
*meta_queue_new(void)
3658 struct meta_queue
*new;
3661 new = XCALLOC(MTYPE_WORK_QUEUE
, sizeof(struct meta_queue
));
3663 for (i
= 0; i
< MQ_SIZE
; i
++) {
3664 new->subq
[i
] = list_new();
3665 assert(new->subq
[i
]);
3671 /* Clean up the EVPN meta-queue list */
3672 static void evpn_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3673 struct zebra_vrf
*zvrf
)
3675 struct listnode
*node
, *nnode
;
3676 struct wq_evpn_wrapper
*w
;
3678 /* Free the node wrapper object, and the struct it wraps */
3679 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3681 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3683 if (w
->vrf_id
!= vrf_id
)
3689 XFREE(MTYPE_WQ_WRAPPER
, w
);
3691 list_delete_node(l
, node
);
3696 /* Clean up the nhg meta-queue list */
3697 static void nhg_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3698 struct zebra_vrf
*zvrf
)
3700 struct wq_nhg_wrapper
*w
;
3701 struct listnode
*node
, *nnode
;
3703 /* Free the node wrapper object, and the struct it wraps */
3704 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3706 vrf_id_t vrf_id
= zvrf
->vrf
->vrf_id
;
3708 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
&&
3709 w
->u
.ctx
->vrf_id
!= vrf_id
)
3711 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
&&
3712 w
->u
.nhe
->vrf_id
!= vrf_id
)
3715 if (w
->type
== WQ_NHG_WRAPPER_TYPE_CTX
)
3716 nhg_ctx_free(&w
->u
.ctx
);
3717 else if (w
->type
== WQ_NHG_WRAPPER_TYPE_NHG
)
3718 zebra_nhg_free(w
->u
.nhe
);
3721 XFREE(MTYPE_WQ_WRAPPER
, w
);
3723 list_delete_node(l
, node
);
3728 static void early_label_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3729 struct zebra_vrf
*zvrf
)
3731 struct wq_label_wrapper
*w
;
3732 struct listnode
*node
, *nnode
;
3734 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, w
)) {
3735 if (zvrf
&& zvrf
->vrf
->vrf_id
!= w
->vrf_id
)
3739 case WQ_LABEL_FTN_UNINSTALL
:
3740 case WQ_LABEL_LABELS_PROCESS
:
3745 XFREE(MTYPE_WQ_WRAPPER
, w
);
3746 list_delete_node(l
, node
);
3751 static void rib_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3752 struct zebra_vrf
*zvrf
)
3754 struct route_node
*rnode
;
3755 struct listnode
*node
, *nnode
;
3757 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, rnode
)) {
3758 rib_dest_t
*dest
= rib_dest_from_rnode(rnode
);
3760 if (dest
&& rib_dest_vrf(dest
) != zvrf
)
3763 route_unlock_node(rnode
);
3765 list_delete_node(l
, node
);
3770 static void early_route_meta_queue_free(struct meta_queue
*mq
, struct list
*l
,
3771 struct zebra_vrf
*zvrf
)
3773 struct zebra_early_route
*ere
;
3774 struct listnode
*node
, *nnode
;
3776 for (ALL_LIST_ELEMENTS(l
, node
, nnode
, ere
)) {
3777 if (zvrf
&& ere
->re
->vrf_id
!= zvrf
->vrf
->vrf_id
)
3780 early_route_memory_free(ere
);
3782 list_delete_node(l
, node
);
3787 void meta_queue_free(struct meta_queue
*mq
, struct zebra_vrf
*zvrf
)
3789 enum meta_queue_indexes i
;
3791 for (i
= 0; i
< MQ_SIZE
; i
++) {
3792 /* Some subqueues may need cleanup - nhgs for example */
3794 case META_QUEUE_NHG
:
3795 nhg_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3797 case META_QUEUE_EVPN
:
3798 evpn_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3800 case META_QUEUE_EARLY_ROUTE
:
3801 early_route_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3803 case META_QUEUE_EARLY_LABEL
:
3804 early_label_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3806 case META_QUEUE_CONNECTED
:
3807 case META_QUEUE_KERNEL
:
3808 case META_QUEUE_STATIC
:
3809 case META_QUEUE_NOTBGP
:
3810 case META_QUEUE_BGP
:
3811 case META_QUEUE_OTHER
:
3812 rib_meta_queue_free(mq
, mq
->subq
[i
], zvrf
);
3816 list_delete(&mq
->subq
[i
]);
3820 XFREE(MTYPE_WORK_QUEUE
, mq
);
3823 /* initialise zebra rib work queue */
3824 static void rib_queue_init(void)
3826 if (!(zrouter
.ribq
= work_queue_new(zrouter
.master
,
3827 "route_node processing"))) {
3828 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3829 "%s: could not initialise work queue!", __func__
);
3833 /* fill in the work queue spec */
3834 zrouter
.ribq
->spec
.workfunc
= &meta_queue_process
;
3835 zrouter
.ribq
->spec
.completion_func
= NULL
;
3836 /* XXX: TODO: These should be runtime configurable via vty */
3837 zrouter
.ribq
->spec
.max_retries
= 3;
3838 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3839 zrouter
.ribq
->spec
.retry
= ZEBRA_RIB_PROCESS_RETRY_TIME
;
3841 if (!(zrouter
.mq
= meta_queue_new())) {
3842 flog_err(EC_ZEBRA_WQ_NONEXISTENT
,
3843 "%s: could not initialise meta queue!", __func__
);
3849 rib_dest_t
*zebra_rib_create_dest(struct route_node
*rn
)
3853 dest
= XCALLOC(MTYPE_RIB_DEST
, sizeof(rib_dest_t
));
3854 rnh_list_init(&dest
->nht
);
3855 re_list_init(&dest
->routes
);
3856 route_lock_node(rn
); /* rn route table reference */
3863 /* RIB updates are processed via a queue of pointers to route_nodes.
3865 * The queue length is bounded by the maximal size of the routing table,
3866 * as a route_node will not be requeued, if already queued.
3868 * REs are submitted via rib_addnode or rib_delnode which set minimal
3869 * state, or static_install_route (when an existing RE is updated)
3870 * and then submit route_node to queue for best-path selection later.
3871 * Order of add/delete state changes are preserved for any given RE.
3873 * Deleted REs are reaped during best-path selection.
3876 * |-> rib_link or unset ROUTE_ENTRY_REMOVE |->Update kernel with
3877 * |-------->| | best RE, if required
3879 * static_install->|->rib_addqueue...... -> rib_process
3881 * |-------->| |-> rib_unlink
3882 * |-> set ROUTE_ENTRY_REMOVE |
3883 * rib_delnode (RE freed)
3885 * The 'info' pointer of a route_node points to a rib_dest_t
3886 * ('dest'). Queueing state for a route_node is kept on the dest. The
3887 * dest is created on-demand by rib_link() and is kept around at least
3888 * as long as there are ribs hanging off it (@see rib_gc_dest()).
3890 * Refcounting (aka "locking" throughout the Zebra and FRR code):
3892 * - route_nodes: refcounted by:
3893 * - dest attached to route_node:
3894 * - managed by: rib_link/rib_gc_dest
3895 * - route_node processing queue
3896 * - managed by: rib_addqueue, rib_process.
3900 /* Add RE to head of the route node. */
3901 static void rib_link(struct route_node
*rn
, struct route_entry
*re
, int process
)
3905 const char *rmap_name
;
3909 dest
= rib_dest_from_rnode(rn
);
3911 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
3912 rnode_debug(rn
, re
->vrf_id
, "rn %p adding dest", rn
);
3914 dest
= zebra_rib_create_dest(rn
);
3917 re_list_add_head(&dest
->routes
, re
);
3919 afi
= (rn
->p
.family
== AF_INET
)
3921 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3922 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3923 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3925 rmap_name
= zebra_get_import_table_route_map(afi
, re
->table
);
3926 zebra_add_import_table_entry(zvrf
, rn
, re
, rmap_name
);
3931 static void rib_addnode(struct route_node
*rn
,
3932 struct route_entry
*re
, int process
)
3934 /* RE node has been un-removed before route-node is processed.
3935 * route_node must hence already be on the queue for processing..
3937 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
)) {
3938 if (IS_ZEBRA_DEBUG_RIB
)
3939 rnode_debug(rn
, re
->vrf_id
, "rn %p, un-removed re %p",
3940 (void *)rn
, (void *)re
);
3942 UNSET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3945 rib_link(rn
, re
, process
);
3951 * Detach a rib structure from a route_node.
3953 * Note that a call to rib_unlink() should be followed by a call to
3954 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
3955 * longer required to be deleted.
3957 void rib_unlink(struct route_node
*rn
, struct route_entry
*re
)
3963 if (IS_ZEBRA_DEBUG_RIB
)
3964 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p", (void *)rn
,
3967 dest
= rib_dest_from_rnode(rn
);
3969 re_list_del(&dest
->routes
, re
);
3971 if (dest
->selected_fib
== re
)
3972 dest
->selected_fib
= NULL
;
3974 rib_re_nhg_free(re
);
3976 zapi_re_opaque_free(re
->opaque
);
3978 XFREE(MTYPE_RE
, re
);
3981 void rib_delnode(struct route_node
*rn
, struct route_entry
*re
)
3985 if (IS_ZEBRA_DEBUG_RIB
)
3986 rnode_debug(rn
, re
->vrf_id
, "rn %p, re %p, removing",
3987 (void *)rn
, (void *)re
);
3988 SET_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
);
3990 afi
= (rn
->p
.family
== AF_INET
)
3992 : (rn
->p
.family
== AF_INET6
) ? AFI_IP6
: AFI_MAX
;
3993 if (is_zebra_import_table_enabled(afi
, re
->vrf_id
, re
->table
)) {
3994 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(re
->vrf_id
);
3996 zebra_del_import_table_entry(zvrf
, rn
, re
);
3997 /* Just clean up if non main table */
3998 if (IS_ZEBRA_DEBUG_RIB
)
3999 zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)",
4000 vrf_id_to_name(re
->vrf_id
), re
->vrf_id
, rn
,
4001 rn
, re
, zebra_route_string(re
->type
));
4010 * Helper that debugs a single nexthop within a route-entry
4012 static void _route_entry_dump_nh(const struct route_entry
*re
,
4013 const char *straddr
,
4014 const struct nexthop
*nexthop
)
4016 char nhname
[PREFIX_STRLEN
];
4017 char backup_str
[50];
4020 char label_str
[MPLS_LABEL_STRLEN
];
4022 struct interface
*ifp
;
4023 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
4025 switch (nexthop
->type
) {
4026 case NEXTHOP_TYPE_BLACKHOLE
:
4027 snprintf(nhname
, sizeof(nhname
), "Blackhole");
4029 case NEXTHOP_TYPE_IFINDEX
:
4030 ifp
= if_lookup_by_index(nexthop
->ifindex
, nexthop
->vrf_id
);
4031 snprintf(nhname
, sizeof(nhname
), "%s",
4032 ifp
? ifp
->name
: "Unknown");
4034 case NEXTHOP_TYPE_IPV4
:
4036 case NEXTHOP_TYPE_IPV4_IFINDEX
:
4037 inet_ntop(AF_INET
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
4039 case NEXTHOP_TYPE_IPV6
:
4040 case NEXTHOP_TYPE_IPV6_IFINDEX
:
4041 inet_ntop(AF_INET6
, &nexthop
->gate
, nhname
, INET6_ADDRSTRLEN
);
4046 label_str
[0] = '\0';
4047 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
> 0) {
4048 mpls_label2str(nexthop
->nh_label
->num_labels
,
4049 nexthop
->nh_label
->label
, label_str
,
4050 sizeof(label_str
), nexthop
->nh_label_type
,
4052 strlcat(label_str
, ", ", sizeof(label_str
));
4055 backup_str
[0] = '\0';
4056 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
4057 snprintf(backup_str
, sizeof(backup_str
), "backup ");
4058 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
4059 snprintf(temp_str
, sizeof(temp_str
), "%d, ",
4060 nexthop
->backup_idx
[i
]);
4061 strlcat(backup_str
, temp_str
, sizeof(backup_str
));
4066 if (nexthop
->weight
)
4067 snprintf(wgt_str
, sizeof(wgt_str
), "wgt %d,", nexthop
->weight
);
4069 zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s%s",
4070 straddr
, (nexthop
->rparent
? " NH" : "NH"), nhname
,
4071 nexthop
->ifindex
, label_str
, vrf
? vrf
->name
: "Unknown",
4073 wgt_str
, backup_str
,
4074 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
)
4077 (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)
4080 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
)
4083 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
)
4086 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
4089 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RNH_FILTERED
)
4090 ? "FILTERED " : ""),
4091 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)
4093 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_SRTE
)
4095 (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_EVPN
)
4100 /* This function dumps the contents of a given RE entry into
4101 * standard debug log. Calling function name and IP prefix in
4102 * question are passed as 1st and 2nd arguments.
4104 void _route_entry_dump(const char *func
, union prefixconstptr pp
,
4105 union prefixconstptr src_pp
,
4106 const struct route_entry
*re
)
4108 const struct prefix
*src_p
= src_pp
.p
;
4109 bool is_srcdst
= src_p
&& src_p
->prefixlen
;
4110 char straddr
[PREFIX_STRLEN
];
4111 char srcaddr
[PREFIX_STRLEN
];
4112 char flags_buf
[128];
4113 char status_buf
[128];
4114 struct nexthop
*nexthop
;
4115 struct vrf
*vrf
= vrf_lookup_by_id(re
->vrf_id
);
4116 struct nexthop_group
*nhg
;
4118 prefix2str(pp
, straddr
, sizeof(straddr
));
4120 zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %s(%u)", func
,
4121 (const void *)re
, straddr
,
4122 is_srcdst
? " from " : "",
4123 is_srcdst
? prefix2str(src_pp
, srcaddr
, sizeof(srcaddr
))
4125 VRF_LOGNAME(vrf
), re
->vrf_id
);
4126 zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
4127 straddr
, (unsigned long)re
->uptime
, re
->type
, re
->instance
,
4130 "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s",
4131 straddr
, re
->metric
, re
->mtu
, re
->distance
,
4132 zclient_dump_route_flags(re
->flags
, flags_buf
,
4134 _dump_re_status(re
, status_buf
, sizeof(status_buf
)));
4135 zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr
,
4136 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)),
4137 nexthop_group_active_nexthop_num(&(re
->nhe
->nhg
)));
4140 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4141 _route_entry_dump_nh(re
, straddr
, nexthop
);
4143 if (zebra_nhg_get_backup_nhg(re
->nhe
)) {
4144 zlog_debug("%s: backup nexthops:", straddr
);
4146 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
4147 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
))
4148 _route_entry_dump_nh(re
, straddr
, nexthop
);
4151 zlog_debug("%s: dump complete", straddr
);
4154 static int rib_meta_queue_early_route_add(struct meta_queue
*mq
, void *data
)
4156 struct zebra_early_route
*ere
= data
;
4158 listnode_add(mq
->subq
[META_QUEUE_EARLY_ROUTE
], data
);
4161 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
4163 "Route %pFX(%u) queued for processing into sub-queue %s",
4164 &ere
->p
, ere
->re
->vrf_id
,
4165 subqueue2str(META_QUEUE_EARLY_ROUTE
));
4170 struct route_entry
*zebra_rib_route_entry_new(vrf_id_t vrf_id
, int type
,
4171 uint8_t instance
, uint32_t flags
,
4174 uint32_t metric
, uint32_t mtu
,
4175 uint8_t distance
, route_tag_t tag
)
4177 struct route_entry
*re
;
4179 re
= XCALLOC(MTYPE_RE
, sizeof(struct route_entry
));
4181 re
->instance
= instance
;
4182 re
->distance
= distance
;
4184 re
->metric
= metric
;
4186 re
->table
= table_id
;
4187 re
->vrf_id
= vrf_id
;
4188 re
->uptime
= monotime(NULL
);
4190 re
->nhe_id
= nhe_id
;
4195 * Internal route-add implementation; there are a couple of different public
4196 * signatures. Callers in this path are responsible for the memory they
4197 * allocate: if they allocate a nexthop_group or backup nexthop info, they
4198 * must free those objects. If this returns < 0, an error has occurred and the
4199 * route_entry 're' has not been captured; the caller should free that also.
4205 int rib_add_multipath_nhe(afi_t afi
, safi_t safi
, struct prefix
*p
,
4206 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4207 struct nhg_hash_entry
*re_nhe
, bool startup
)
4209 struct zebra_early_route
*ere
;
4214 assert(!src_p
|| !src_p
->prefixlen
|| afi
== AFI_IP6
);
4216 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4221 ere
->src_p
= *src_p
;
4222 ere
->src_p_provided
= !!src_p
;
4224 ere
->re_nhe
= re_nhe
;
4225 ere
->startup
= startup
;
4227 return mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4231 * Add a single route.
4233 int rib_add_multipath(afi_t afi
, safi_t safi
, struct prefix
*p
,
4234 struct prefix_ipv6
*src_p
, struct route_entry
*re
,
4235 struct nexthop_group
*ng
, bool startup
)
4238 struct nhg_hash_entry nhe
, *n
;
4243 /* We either need nexthop(s) or an existing nexthop id */
4244 if (ng
== NULL
&& re
->nhe_id
== 0)
4248 * Use a temporary nhe to convey info to the common/main api.
4250 zebra_nhe_init(&nhe
, afi
, (ng
? ng
->nexthop
: NULL
));
4252 nhe
.nhg
.nexthop
= ng
->nexthop
;
4253 else if (re
->nhe_id
> 0)
4254 nhe
.id
= re
->nhe_id
;
4256 n
= zebra_nhe_copy(&nhe
, 0);
4257 ret
= rib_add_multipath_nhe(afi
, safi
, p
, src_p
, re
, n
, startup
);
4259 /* In error cases, free the route also */
4261 XFREE(MTYPE_RE
, re
);
4266 void rib_delete(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4267 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4268 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4269 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
,
4270 uint8_t distance
, bool fromkernel
)
4272 struct zebra_early_route
*ere
;
4273 struct route_entry
*re
= NULL
;
4274 struct nhg_hash_entry
*nhe
= NULL
;
4276 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4277 table_id
, metric
, 0, distance
, 0);
4280 nhe
= zebra_nhg_alloc();
4281 nhe
->nhg
.nexthop
= nexthop_dup(nh
, NULL
);
4284 ere
= XCALLOC(MTYPE_WQ_WRAPPER
, sizeof(*ere
));
4289 ere
->src_p
= *src_p
;
4290 ere
->src_p_provided
= !!src_p
;
4293 ere
->startup
= false;
4294 ere
->deletion
= true;
4295 ere
->fromkernel
= fromkernel
;
4297 mq_add_handler(ere
, rib_meta_queue_early_route_add
);
4301 int rib_add(afi_t afi
, safi_t safi
, vrf_id_t vrf_id
, int type
,
4302 unsigned short instance
, uint32_t flags
, struct prefix
*p
,
4303 struct prefix_ipv6
*src_p
, const struct nexthop
*nh
,
4304 uint32_t nhe_id
, uint32_t table_id
, uint32_t metric
, uint32_t mtu
,
4305 uint8_t distance
, route_tag_t tag
, bool startup
)
4307 struct route_entry
*re
= NULL
;
4308 struct nexthop nexthop
= {};
4309 struct nexthop_group ng
= {};
4311 /* Allocate new route_entry structure. */
4312 re
= zebra_rib_route_entry_new(vrf_id
, type
, instance
, flags
, nhe_id
,
4313 table_id
, metric
, mtu
, distance
, tag
);
4315 /* If the owner of the route supplies a shared nexthop-group id,
4316 * we'll use that. Otherwise, pass the nexthop along directly.
4321 nexthop_group_add_sorted(&ng
, &nexthop
);
4324 return rib_add_multipath(afi
, safi
, p
, src_p
, re
, &ng
, startup
);
4327 static const char *rib_update_event2str(enum rib_update_event event
)
4329 const char *ret
= "UNKNOWN";
4332 case RIB_UPDATE_KERNEL
:
4333 ret
= "RIB_UPDATE_KERNEL";
4335 case RIB_UPDATE_RMAP_CHANGE
:
4336 ret
= "RIB_UPDATE_RMAP_CHANGE";
4338 case RIB_UPDATE_OTHER
:
4339 ret
= "RIB_UPDATE_OTHER";
4341 case RIB_UPDATE_MAX
:
4349 /* Schedule route nodes to be processed if they match the type */
4350 static void rib_update_route_node(struct route_node
*rn
, int type
)
4352 struct route_entry
*re
, *next
;
4353 bool re_changed
= false;
4355 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4356 if (type
== ZEBRA_ROUTE_ALL
|| type
== re
->type
) {
4357 SET_FLAG(re
->status
, ROUTE_ENTRY_CHANGED
);
4366 /* Schedule routes of a particular table (address-family) based on event. */
4367 void rib_update_table(struct route_table
*table
, enum rib_update_event event
,
4370 struct route_node
*rn
;
4372 if (IS_ZEBRA_DEBUG_EVENT
) {
4373 struct zebra_vrf
*zvrf
;
4377 ? ((struct rib_table_info
*)table
->info
)->zvrf
4379 vrf
= zvrf
? zvrf
->vrf
: NULL
;
4381 zlog_debug("%s: %s VRF %s Table %u event %s Route type: %s", __func__
,
4382 table
->info
? afi2str(
4383 ((struct rib_table_info
*)table
->info
)->afi
)
4385 VRF_LOGNAME(vrf
), zvrf
? zvrf
->table_id
: 0,
4386 rib_update_event2str(event
), zebra_route_string(rtype
));
4389 /* Walk all routes and queue for processing, if appropriate for
4390 * the trigger event.
4392 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4394 * If we are looking at a route node and the node
4395 * has already been queued we don't
4396 * need to queue it up again
4399 && CHECK_FLAG(rib_dest_from_rnode(rn
)->flags
,
4400 RIB_ROUTE_ANY_QUEUED
))
4404 case RIB_UPDATE_KERNEL
:
4405 rib_update_route_node(rn
, ZEBRA_ROUTE_KERNEL
);
4407 case RIB_UPDATE_RMAP_CHANGE
:
4408 case RIB_UPDATE_OTHER
:
4409 rib_update_route_node(rn
, rtype
);
4411 case RIB_UPDATE_MAX
:
4417 static void rib_update_handle_vrf_all(enum rib_update_event event
, int rtype
)
4419 struct zebra_router_table
*zrt
;
4421 if (IS_ZEBRA_DEBUG_EVENT
)
4422 zlog_debug("%s: Handling VRF (ALL) event %s", __func__
,
4423 rib_update_event2str(event
));
4425 /* Just iterate over all the route tables, rather than vrf lookups */
4426 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
)
4427 rib_update_table(zrt
->table
, event
, rtype
);
4430 struct rib_update_ctx
{
4431 enum rib_update_event event
;
4435 static struct rib_update_ctx
*rib_update_ctx_init(vrf_id_t vrf_id
,
4436 enum rib_update_event event
)
4438 struct rib_update_ctx
*ctx
;
4440 ctx
= XCALLOC(MTYPE_RIB_UPDATE_CTX
, sizeof(struct rib_update_ctx
));
4443 ctx
->vrf_id
= vrf_id
;
4448 static void rib_update_ctx_fini(struct rib_update_ctx
**ctx
)
4450 XFREE(MTYPE_RIB_UPDATE_CTX
, *ctx
);
4453 static void rib_update_handler(struct thread
*thread
)
4455 struct rib_update_ctx
*ctx
;
4457 ctx
= THREAD_ARG(thread
);
4459 rib_update_handle_vrf_all(ctx
->event
, ZEBRA_ROUTE_ALL
);
4461 rib_update_ctx_fini(&ctx
);
4465 * Thread list to ensure we don't schedule a ton of events
4466 * if interfaces are flapping for instance.
4468 static struct thread
*t_rib_update_threads
[RIB_UPDATE_MAX
];
4470 /* Schedule a RIB update event for all vrfs */
4471 void rib_update(enum rib_update_event event
)
4473 struct rib_update_ctx
*ctx
;
4475 if (thread_is_scheduled(t_rib_update_threads
[event
]))
4478 ctx
= rib_update_ctx_init(0, event
);
4480 thread_add_event(zrouter
.master
, rib_update_handler
, ctx
, 0,
4481 &t_rib_update_threads
[event
]);
4483 if (IS_ZEBRA_DEBUG_EVENT
)
4484 zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__
,
4485 rib_update_event2str(event
));
4488 /* Delete self installed routes after zebra is relaunched. */
4489 void rib_sweep_table(struct route_table
*table
)
4491 struct route_node
*rn
;
4492 struct route_entry
*re
;
4493 struct route_entry
*next
;
4494 struct nexthop
*nexthop
;
4499 if (IS_ZEBRA_DEBUG_RIB
)
4500 zlog_debug("%s: starting", __func__
);
4502 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4503 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4505 if (IS_ZEBRA_DEBUG_RIB
)
4506 route_entry_dump(&rn
->p
, NULL
, re
);
4508 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4511 if (!CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELFROUTE
))
4515 * If routes are older than startup_time then
4516 * we know we read them in from the kernel.
4517 * As such we can safely remove them.
4519 if (zrouter
.startup_time
< re
->uptime
)
4523 * So we are starting up and have received
4524 * routes from the kernel that we have installed
4525 * from a previous run of zebra but not cleaned
4526 * up ( say a kill -9 )
4527 * But since we haven't actually installed
4528 * them yet( we received them from the kernel )
4529 * we don't think they are active.
4530 * So let's pretend they are active to actually
4532 * In all honesty I'm not sure if we should
4533 * mark them as active when we receive them
4534 * This is startup only so probably ok.
4536 * If we ever decide to move rib_sweep_table
4537 * to a different spot (ie startup )
4538 * this decision needs to be revisited
4540 SET_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
);
4541 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
))
4542 SET_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
4544 rib_uninstall_kernel(rn
, re
);
4545 rib_delnode(rn
, re
);
4549 if (IS_ZEBRA_DEBUG_RIB
)
4550 zlog_debug("%s: ends", __func__
);
4553 /* Sweep all RIB tables. */
4554 void rib_sweep_route(struct thread
*t
)
4557 struct zebra_vrf
*zvrf
;
4559 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4560 if ((zvrf
= vrf
->info
) == NULL
)
4563 rib_sweep_table(zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
4564 rib_sweep_table(zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4567 zebra_router_sweep_route();
4568 zebra_router_sweep_nhgs();
4571 /* Remove specific by protocol routes from 'table'. */
4572 unsigned long rib_score_proto_table(uint8_t proto
, unsigned short instance
,
4573 struct route_table
*table
)
4575 struct route_node
*rn
;
4576 struct route_entry
*re
;
4577 struct route_entry
*next
;
4578 unsigned long n
= 0;
4581 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
4582 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
4583 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
4585 if (re
->type
== proto
4586 && re
->instance
== instance
) {
4587 rib_delnode(rn
, re
);
4594 /* Remove specific by protocol routes. */
4595 unsigned long rib_score_proto(uint8_t proto
, unsigned short instance
)
4598 struct zebra_vrf
*zvrf
;
4599 struct other_route_table
*ort
;
4600 unsigned long cnt
= 0;
4602 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
4607 cnt
+= rib_score_proto_table(proto
, instance
,
4608 zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
4609 + rib_score_proto_table(
4611 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
4613 frr_each(otable
, &zvrf
->other_tables
, ort
) cnt
+=
4614 rib_score_proto_table(proto
, instance
, ort
->table
);
4620 /* Close RIB and clean up kernel routes. */
4621 void rib_close_table(struct route_table
*table
)
4623 struct route_node
*rn
;
4629 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
4630 dest
= rib_dest_from_rnode(rn
);
4632 if (dest
&& dest
->selected_fib
) {
4633 rib_uninstall_kernel(rn
, dest
->selected_fib
);
4634 dest
->selected_fib
= NULL
;
4640 * Handler for async dataplane results after a pseudowire installation
4642 static void handle_pw_result(struct zebra_dplane_ctx
*ctx
)
4644 struct zebra_pw
*pw
;
4645 struct zebra_vrf
*vrf
;
4647 /* The pseudowire code assumes success - we act on an error
4648 * result for installation attempts here.
4650 if (dplane_ctx_get_op(ctx
) != DPLANE_OP_PW_INSTALL
)
4653 if (dplane_ctx_get_status(ctx
) != ZEBRA_DPLANE_REQUEST_SUCCESS
) {
4654 vrf
= zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx
));
4655 pw
= zebra_pw_find(vrf
, dplane_ctx_get_ifname(ctx
));
4657 zebra_pw_install_failure(pw
,
4658 dplane_ctx_get_pw_status(ctx
));
4663 * Handle results from the dataplane system. Dequeue update context
4664 * structs, dispatch to appropriate internal handlers.
4666 static void rib_process_dplane_results(struct thread
*thread
)
4668 struct zebra_dplane_ctx
*ctx
;
4669 struct dplane_ctx_list_head ctxlist
;
4670 bool shut_p
= false;
4672 /* Dequeue a list of completed updates with one lock/unlock cycle */
4675 dplane_ctx_q_init(&ctxlist
);
4677 /* Take lock controlling queue of results */
4678 frr_with_mutex (&dplane_mutex
) {
4679 /* Dequeue list of context structs */
4680 dplane_ctx_list_append(&ctxlist
, &rib_dplane_q
);
4683 /* Dequeue context block */
4684 ctx
= dplane_ctx_dequeue(&ctxlist
);
4686 /* If we've emptied the results queue, we're done */
4690 /* If zebra is shutting down, avoid processing results,
4691 * just drain the results queue.
4693 shut_p
= atomic_load_explicit(&zrouter
.in_shutdown
,
4694 memory_order_relaxed
);
4697 dplane_ctx_fini(&ctx
);
4699 ctx
= dplane_ctx_dequeue(&ctxlist
);
4705 #ifdef HAVE_SCRIPTING
4706 char *script_name
= frrscript_names_get_script_name(
4707 ZEBRA_ON_RIB_PROCESS_HOOK_CALL
);
4710 struct frrscript
*fs
;
4713 fs
= frrscript_new(script_name
);
4715 ret
= frrscript_load(
4716 fs
, ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4719 #endif /* HAVE_SCRIPTING */
4723 #ifdef HAVE_SCRIPTING
4726 ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4728 #endif /* HAVE_SCRIPTING */
4730 switch (dplane_ctx_get_op(ctx
)) {
4731 case DPLANE_OP_ROUTE_INSTALL
:
4732 case DPLANE_OP_ROUTE_UPDATE
:
4733 case DPLANE_OP_ROUTE_DELETE
:
4734 /* Bit of special case for route updates
4735 * that were generated by async notifications:
4736 * we don't want to continue processing these
4739 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4740 rib_process_result(ctx
);
4743 case DPLANE_OP_ROUTE_NOTIFY
:
4744 rib_process_dplane_notify(ctx
);
4747 case DPLANE_OP_NH_INSTALL
:
4748 case DPLANE_OP_NH_UPDATE
:
4749 case DPLANE_OP_NH_DELETE
:
4750 zebra_nhg_dplane_result(ctx
);
4753 case DPLANE_OP_LSP_INSTALL
:
4754 case DPLANE_OP_LSP_UPDATE
:
4755 case DPLANE_OP_LSP_DELETE
:
4756 /* Bit of special case for LSP updates
4757 * that were generated by async notifications:
4758 * we don't want to continue processing these.
4760 if (dplane_ctx_get_notif_provider(ctx
) == 0)
4761 zebra_mpls_lsp_dplane_result(ctx
);
4764 case DPLANE_OP_LSP_NOTIFY
:
4765 zebra_mpls_process_dplane_notify(ctx
);
4768 case DPLANE_OP_PW_INSTALL
:
4769 case DPLANE_OP_PW_UNINSTALL
:
4770 handle_pw_result(ctx
);
4773 case DPLANE_OP_SYS_ROUTE_ADD
:
4774 case DPLANE_OP_SYS_ROUTE_DELETE
:
4777 case DPLANE_OP_MAC_INSTALL
:
4778 case DPLANE_OP_MAC_DELETE
:
4779 zebra_vxlan_handle_result(ctx
);
4782 case DPLANE_OP_RULE_ADD
:
4783 case DPLANE_OP_RULE_DELETE
:
4784 case DPLANE_OP_RULE_UPDATE
:
4785 case DPLANE_OP_IPTABLE_ADD
:
4786 case DPLANE_OP_IPTABLE_DELETE
:
4787 case DPLANE_OP_IPSET_ADD
:
4788 case DPLANE_OP_IPSET_DELETE
:
4789 case DPLANE_OP_IPSET_ENTRY_ADD
:
4790 case DPLANE_OP_IPSET_ENTRY_DELETE
:
4791 zebra_pbr_dplane_result(ctx
);
4794 case DPLANE_OP_INTF_ADDR_ADD
:
4795 case DPLANE_OP_INTF_ADDR_DEL
:
4796 case DPLANE_OP_INTF_INSTALL
:
4797 case DPLANE_OP_INTF_UPDATE
:
4798 case DPLANE_OP_INTF_DELETE
:
4799 case DPLANE_OP_INTF_NETCONFIG
:
4800 zebra_if_dplane_result(ctx
);
4803 case DPLANE_OP_TC_QDISC_INSTALL
:
4804 case DPLANE_OP_TC_QDISC_UNINSTALL
:
4805 case DPLANE_OP_TC_CLASS_ADD
:
4806 case DPLANE_OP_TC_CLASS_DELETE
:
4807 case DPLANE_OP_TC_CLASS_UPDATE
:
4808 case DPLANE_OP_TC_FILTER_ADD
:
4809 case DPLANE_OP_TC_FILTER_DELETE
:
4810 case DPLANE_OP_TC_FILTER_UPDATE
:
4813 /* Some op codes not handled here */
4814 case DPLANE_OP_ADDR_INSTALL
:
4815 case DPLANE_OP_ADDR_UNINSTALL
:
4816 case DPLANE_OP_NEIGH_INSTALL
:
4817 case DPLANE_OP_NEIGH_UPDATE
:
4818 case DPLANE_OP_NEIGH_DELETE
:
4819 case DPLANE_OP_NEIGH_IP_INSTALL
:
4820 case DPLANE_OP_NEIGH_IP_DELETE
:
4821 case DPLANE_OP_VTEP_ADD
:
4822 case DPLANE_OP_VTEP_DELETE
:
4823 case DPLANE_OP_NEIGH_DISCOVER
:
4824 case DPLANE_OP_BR_PORT_UPDATE
:
4825 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
4826 case DPLANE_OP_GRE_SET
:
4827 case DPLANE_OP_NONE
:
4830 } /* Dispatch by op code */
4832 dplane_ctx_fini(&ctx
);
4833 ctx
= dplane_ctx_dequeue(&ctxlist
);
4840 * Results are returned from the dataplane subsystem, in the context of
4841 * the dataplane pthread. We enqueue the results here for processing by
4842 * the main thread later.
4844 static int rib_dplane_results(struct dplane_ctx_list_head
*ctxlist
)
4846 /* Take lock controlling queue of results */
4847 frr_with_mutex (&dplane_mutex
) {
4848 /* Enqueue context blocks */
4849 dplane_ctx_list_append(&rib_dplane_q
, ctxlist
);
4852 /* Ensure event is signalled to zebra main pthread */
4853 thread_add_event(zrouter
.master
, rib_process_dplane_results
, NULL
, 0,
4860 * Ensure there are no empty slots in the route_info array.
4861 * Every route type in zebra should be present there.
4863 static void check_route_info(void)
4865 int len
= array_size(route_info
);
4868 * ZEBRA_ROUTE_SYSTEM is special cased since
4869 * its key is 0 anyway.
4871 * ZEBRA_ROUTE_ALL is also ignored.
4873 for (int i
= 0; i
< len
; i
++) {
4874 assert(route_info
[i
].key
>= ZEBRA_ROUTE_SYSTEM
&&
4875 route_info
[i
].key
< ZEBRA_ROUTE_MAX
);
4876 assert(route_info
[i
].meta_q_map
< MQ_SIZE
);
4880 /* Routing information base initialize. */
4887 /* Init dataplane, and register for results */
4888 pthread_mutex_init(&dplane_mutex
, NULL
);
4889 dplane_ctx_q_init(&rib_dplane_q
);
4890 zebra_dplane_init(rib_dplane_results
);
4896 * Get the first vrf id that is greater than the given vrf id if any.
4898 * Returns true if a vrf id was found, false otherwise.
4900 static inline int vrf_id_get_next(vrf_id_t vrf_id
, vrf_id_t
*next_id_p
)
4904 vrf
= vrf_lookup_by_id(vrf_id
);
4906 vrf
= RB_NEXT(vrf_id_head
, vrf
);
4908 *next_id_p
= vrf
->vrf_id
;
4917 * rib_tables_iter_next
4919 * Returns the next table in the iteration.
4921 struct route_table
*rib_tables_iter_next(rib_tables_iter_t
*iter
)
4923 struct route_table
*table
;
4926 * Array that helps us go over all AFI/SAFI combinations via one
4929 static const struct {
4933 {AFI_IP
, SAFI_UNICAST
}, {AFI_IP
, SAFI_MULTICAST
},
4934 {AFI_IP
, SAFI_LABELED_UNICAST
}, {AFI_IP6
, SAFI_UNICAST
},
4935 {AFI_IP6
, SAFI_MULTICAST
}, {AFI_IP6
, SAFI_LABELED_UNICAST
},
4940 switch (iter
->state
) {
4942 case RIB_TABLES_ITER_S_INIT
:
4943 iter
->vrf_id
= VRF_DEFAULT
;
4944 iter
->afi_safi_ix
= -1;
4948 case RIB_TABLES_ITER_S_ITERATING
:
4949 iter
->afi_safi_ix
++;
4952 while (iter
->afi_safi_ix
4953 < (int)array_size(afi_safis
)) {
4954 table
= zebra_vrf_table(
4955 afi_safis
[iter
->afi_safi_ix
].afi
,
4956 afi_safis
[iter
->afi_safi_ix
].safi
,
4961 iter
->afi_safi_ix
++;
4965 * Found another table in this vrf.
4971 * Done with all tables in the current vrf, go to the
4975 if (!vrf_id_get_next(iter
->vrf_id
, &iter
->vrf_id
))
4978 iter
->afi_safi_ix
= 0;
4983 case RIB_TABLES_ITER_S_DONE
:
4988 iter
->state
= RIB_TABLES_ITER_S_ITERATING
;
4990 iter
->state
= RIB_TABLES_ITER_S_DONE
;