]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_rib.c
Merge pull request #12006 from opensourcerouting/fix/doc_for_rfc9072
[mirror_frr.git] / zebra / zebra_rib.c
1 /* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "if.h"
25 #include "linklist.h"
26 #include "log.h"
27 #include "memory.h"
28 #include "mpls.h"
29 #include "nexthop.h"
30 #include "prefix.h"
31 #include "prefix.h"
32 #include "routemap.h"
33 #include "sockunion.h"
34 #include "srcdest_table.h"
35 #include "table.h"
36 #include "thread.h"
37 #include "vrf.h"
38 #include "workqueue.h"
39 #include "nexthop_group_private.h"
40 #include "frr_pthread.h"
41 #include "printfrr.h"
42 #include "frrscript.h"
43
44 #include "zebra/zebra_router.h"
45 #include "zebra/connected.h"
46 #include "zebra/debug.h"
47 #include "zebra/interface.h"
48 #include "zebra/redistribute.h"
49 #include "zebra/rib.h"
50 #include "zebra/rt.h"
51 #include "zebra/zapi_msg.h"
52 #include "zebra/zebra_errors.h"
53 #include "zebra/zebra_ns.h"
54 #include "zebra/zebra_rnh.h"
55 #include "zebra/zebra_routemap.h"
56 #include "zebra/zebra_vrf.h"
57 #include "zebra/zebra_vxlan.h"
58 #include "zebra/zapi_msg.h"
59 #include "zebra/zebra_dplane.h"
60 #include "zebra/zebra_evpn_mh.h"
61 #include "zebra/zebra_script.h"
62
63 DEFINE_MGROUP(ZEBRA, "zebra");
64
65 DEFINE_MTYPE(ZEBRA, RE, "Route Entry");
66 DEFINE_MTYPE_STATIC(ZEBRA, RIB_DEST, "RIB destination");
67 DEFINE_MTYPE_STATIC(ZEBRA, RIB_UPDATE_CTX, "Rib update context object");
68 DEFINE_MTYPE_STATIC(ZEBRA, WQ_WRAPPER, "WQ wrapper");
69
70 /*
71 * Event, list, and mutex for delivery of dataplane results
72 */
73 static pthread_mutex_t dplane_mutex;
74 static struct thread *t_dplane;
75 static struct dplane_ctx_q rib_dplane_q;
76
77 DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
78 (rn, reason));
79 DEFINE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
80
81
82 /* Meta Q's specific names */
83 enum meta_queue_indexes {
84 META_QUEUE_NHG,
85 META_QUEUE_EVPN,
86 META_QUEUE_EARLY_ROUTE,
87 META_QUEUE_EARLY_LABEL,
88 META_QUEUE_CONNECTED,
89 META_QUEUE_KERNEL,
90 META_QUEUE_STATIC,
91 META_QUEUE_NOTBGP,
92 META_QUEUE_BGP,
93 META_QUEUE_OTHER,
94 };
95
96 /* Each route type's string and default distance value. */
97 static const struct {
98 int key;
99 uint8_t distance;
100 enum meta_queue_indexes meta_q_map;
101 } route_info[ZEBRA_ROUTE_MAX] = {
102 [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */,
103 META_QUEUE_NHG},
104 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, META_QUEUE_KERNEL},
105 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, META_QUEUE_KERNEL},
106 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, META_QUEUE_CONNECTED},
107 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, META_QUEUE_STATIC},
108 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, META_QUEUE_NOTBGP},
109 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, META_QUEUE_NOTBGP},
110 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, META_QUEUE_NOTBGP},
111 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, META_QUEUE_NOTBGP},
112 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, META_QUEUE_NOTBGP},
113 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */,
114 META_QUEUE_BGP},
115 [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, META_QUEUE_OTHER},
116 [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, META_QUEUE_NOTBGP},
117 [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, META_QUEUE_NOTBGP},
118 [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, META_QUEUE_OTHER},
119 [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, META_QUEUE_OTHER},
120 [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, META_QUEUE_STATIC},
121 [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, META_QUEUE_OTHER},
122 [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, META_QUEUE_BGP},
123 [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, META_QUEUE_BGP},
124 [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20,
125 META_QUEUE_BGP},
126 [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, META_QUEUE_BGP},
127 [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20,
128 META_QUEUE_BGP},
129 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, META_QUEUE_NOTBGP},
130 [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, META_QUEUE_OTHER},
131 [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, META_QUEUE_OTHER},
132 [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, META_QUEUE_OTHER},
133 [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115,
134 META_QUEUE_NOTBGP},
135 [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, META_QUEUE_OTHER},
136 [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, META_QUEUE_OTHER},
137 [ZEBRA_ROUTE_ALL] = {ZEBRA_ROUTE_ALL, 255, META_QUEUE_OTHER},
138 /* Any new route type added to zebra, should be mirrored here */
139
140 /* no entry/default: 150 */
141 };
142
143 /* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
144 * from the OS, and an 'nhe' is a nhe update.
145 */
146 struct wq_nhg_wrapper {
147 int type;
148 union {
149 struct nhg_ctx *ctx;
150 struct nhg_hash_entry *nhe;
151 } u;
152 };
153
154 #define WQ_NHG_WRAPPER_TYPE_CTX 0x01
155 #define WQ_NHG_WRAPPER_TYPE_NHG 0x02
156
157 /* Wrapper structs for evpn/vxlan workqueue items. */
158 struct wq_evpn_wrapper {
159 int type;
160 bool add_p;
161 vrf_id_t vrf_id;
162 bool esr_rxed;
163 uint8_t df_alg;
164 uint16_t df_pref;
165 uint32_t flags;
166 uint32_t seq;
167 esi_t esi;
168 vni_t vni;
169 struct ipaddr ip;
170 struct ethaddr macaddr;
171 struct prefix prefix;
172 struct in_addr vtep_ip;
173 };
174
175 #define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01
176 #define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02
177 #define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03
178 #define WQ_EVPN_WRAPPER_TYPE_REM_VTEP 0x04
179
180 enum wq_label_types {
181 WQ_LABEL_FTN_UNINSTALL,
182 WQ_LABEL_LABELS_PROCESS,
183 };
184
185 struct wq_label_wrapper {
186 enum wq_label_types type;
187 vrf_id_t vrf_id;
188
189 struct prefix p;
190 enum lsp_types_t ltype;
191 uint8_t route_type;
192 uint8_t route_instance;
193
194 bool add_p;
195 struct zapi_labels zl;
196
197 int afi;
198 };
199
200 static void rib_addnode(struct route_node *rn, struct route_entry *re,
201 int process);
202
203 /* %pRN is already a printer for route_nodes that just prints the prefix */
204 #ifdef _FRR_ATTRIBUTE_PRINTFRR
205 #pragma FRR printfrr_ext "%pZN" (struct route_node *)
206 #endif
207
208 static const char *subqueue2str(enum meta_queue_indexes index)
209 {
210 switch (index) {
211 case META_QUEUE_NHG:
212 return "NHG Objects";
213 case META_QUEUE_EVPN:
214 return "EVPN/VxLan Objects";
215 case META_QUEUE_EARLY_ROUTE:
216 return "Early Route Processing";
217 case META_QUEUE_EARLY_LABEL:
218 return "Early Label Handling";
219 case META_QUEUE_CONNECTED:
220 return "Connected Routes";
221 case META_QUEUE_KERNEL:
222 return "Kernel Routes";
223 case META_QUEUE_STATIC:
224 return "Static Routes";
225 case META_QUEUE_NOTBGP:
226 return "RIP/OSPF/ISIS/EIGRP/NHRP Routes";
227 case META_QUEUE_BGP:
228 return "BGP Routes";
229 case META_QUEUE_OTHER:
230 return "Other Routes";
231 }
232
233 return "Unknown";
234 }
235
236 printfrr_ext_autoreg_p("ZN", printfrr_zebra_node);
237 static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea,
238 const void *ptr)
239 {
240 struct route_node *rn = (struct route_node *)ptr;
241 ssize_t rv = 0;
242
243 /* just the table number? */
244 if (ea->fmt[0] == 't') {
245 rib_dest_t *dest;
246 struct route_entry *re = NULL;
247
248 ea->fmt++;
249
250 if (!rn)
251 return bputch(buf, '!');
252
253 dest = rib_dest_from_rnode(rn);
254 if (dest)
255 re = re_list_first(&dest->routes);
256 if (re)
257 rv += bprintfrr(buf, "%u", re->table);
258 else
259 rv += bputch(buf, '?');
260
261 } else {
262 char cbuf[PREFIX_STRLEN * 2 + 6];
263 struct rib_table_info *info;
264
265 if (!rn)
266 return bputs(buf, "{(route_node *) NULL}");
267
268 srcdest_rnode2str(rn, cbuf, sizeof(cbuf));
269 rv += bputs(buf, cbuf);
270
271 info = srcdest_rnode_table_info(rn);
272 if (info->safi == SAFI_MULTICAST)
273 rv += bputs(buf, " (MRIB)");
274 }
275 return rv;
276 }
277
278 #define rnode_debug(node, vrf_id, msg, ...) \
279 zlog_debug("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
280 ##__VA_ARGS__)
281
282 #define rnode_info(node, vrf_id, msg, ...) \
283 zlog_info("%s: (%u:%pZNt):%pZN: " msg, __func__, vrf_id, node, node, \
284 ##__VA_ARGS__)
285
286 static char *_dump_re_status(const struct route_entry *re, char *buf,
287 size_t len)
288 {
289 if (re->status == 0) {
290 snprintfrr(buf, len, "None ");
291 return buf;
292 }
293
294 snprintfrr(
295 buf, len, "%s%s%s%s%s%s%s",
296 CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED) ? "Removed " : "",
297 CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) ? "Changed " : "",
298 CHECK_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED)
299 ? "Label Changed "
300 : "",
301 CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED) ? "Queued " : "",
302 CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) ? "Installed "
303 : "",
304 CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED) ? "Failed " : "",
305 CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG) ? "Fib NHG "
306 : "");
307 return buf;
308 }
309
310 uint8_t route_distance(int type)
311 {
312 uint8_t distance;
313
314 if ((unsigned)type >= array_size(route_info))
315 distance = 150;
316 else
317 distance = route_info[type].distance;
318
319 return distance;
320 }
321
322 int is_zebra_valid_kernel_table(uint32_t table_id)
323 {
324 #ifdef linux
325 if ((table_id == RT_TABLE_UNSPEC) || (table_id == RT_TABLE_LOCAL)
326 || (table_id == RT_TABLE_COMPAT))
327 return 0;
328 #endif
329
330 return 1;
331 }
332
333 int is_zebra_main_routing_table(uint32_t table_id)
334 {
335 if (table_id == RT_TABLE_MAIN)
336 return 1;
337 return 0;
338 }
339
340 int zebra_check_addr(const struct prefix *p)
341 {
342 if (p->family == AF_INET) {
343 uint32_t addr;
344
345 addr = p->u.prefix4.s_addr;
346 addr = ntohl(addr);
347
348 if (IPV4_NET127(addr) || IN_CLASSD(addr)
349 || IPV4_LINKLOCAL(addr))
350 return 0;
351 }
352 if (p->family == AF_INET6) {
353 if (IN6_IS_ADDR_LOOPBACK(&p->u.prefix6))
354 return 0;
355 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
356 return 0;
357 }
358 return 1;
359 }
360
361 static void route_entry_attach_ref(struct route_entry *re,
362 struct nhg_hash_entry *new)
363 {
364 re->nhe = new;
365 re->nhe_id = new->id;
366 re->nhe_installed_id = 0;
367
368 zebra_nhg_increment_ref(new);
369 }
370
371 /* Replace (if 'new_nhghe') or clear (if that's NULL) an re's nhe. */
372 int route_entry_update_nhe(struct route_entry *re,
373 struct nhg_hash_entry *new_nhghe)
374 {
375 int ret = 0;
376 struct nhg_hash_entry *old_nhg = NULL;
377
378 if (new_nhghe == NULL) {
379 old_nhg = re->nhe;
380
381 re->nhe_id = 0;
382 re->nhe_installed_id = 0;
383 re->nhe = NULL;
384 goto done;
385 }
386
387 if ((re->nhe_id != 0) && re->nhe && (re->nhe != new_nhghe)) {
388 /* Capture previous nhg, if any */
389 old_nhg = re->nhe;
390
391 route_entry_attach_ref(re, new_nhghe);
392 } else if (!re->nhe)
393 /* This is the first time it's being attached */
394 route_entry_attach_ref(re, new_nhghe);
395
396 done:
397 /* Detach / deref previous nhg */
398 if (old_nhg)
399 zebra_nhg_decrement_ref(old_nhg);
400
401 return ret;
402 }
403
404 void rib_handle_nhg_replace(struct nhg_hash_entry *old_entry,
405 struct nhg_hash_entry *new_entry)
406 {
407 struct zebra_router_table *zrt;
408 struct route_node *rn;
409 struct route_entry *re, *next;
410
411 if (IS_ZEBRA_DEBUG_RIB_DETAILED || IS_ZEBRA_DEBUG_NHG_DETAIL)
412 zlog_debug("%s: replacing routes nhe (%u) OLD %p NEW %p",
413 __func__, new_entry->id, new_entry, old_entry);
414
415 /* We have to do them ALL */
416 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
417 for (rn = route_top(zrt->table); rn;
418 rn = srcdest_route_next(rn)) {
419 RNODE_FOREACH_RE_SAFE (rn, re, next) {
420 if (re->nhe && re->nhe == old_entry)
421 route_entry_update_nhe(re, new_entry);
422 }
423 }
424 }
425 }
426
427 struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
428 const union g_addr *addr,
429 struct route_node **rn_out)
430 {
431 struct prefix p;
432 struct route_table *table;
433 struct route_node *rn;
434 struct route_entry *match = NULL;
435
436 /* Lookup table. */
437 table = zebra_vrf_table(afi, safi, vrf_id);
438 if (!table)
439 return 0;
440
441 memset(&p, 0, sizeof(p));
442 p.family = afi;
443 if (afi == AFI_IP) {
444 p.u.prefix4 = addr->ipv4;
445 p.prefixlen = IPV4_MAX_BITLEN;
446 } else {
447 p.u.prefix6 = addr->ipv6;
448 p.prefixlen = IPV6_MAX_BITLEN;
449 }
450
451 rn = route_node_match(table, &p);
452
453 while (rn) {
454 rib_dest_t *dest;
455
456 route_unlock_node(rn);
457
458 dest = rib_dest_from_rnode(rn);
459 if (dest && dest->selected_fib
460 && !CHECK_FLAG(dest->selected_fib->status,
461 ROUTE_ENTRY_REMOVED))
462 match = dest->selected_fib;
463
464 /* If there is no selected route or matched route is EGP, go up
465 tree. */
466 if (!match) {
467 do {
468 rn = rn->parent;
469 } while (rn && rn->info == NULL);
470 if (rn)
471 route_lock_node(rn);
472 } else {
473 if (match->type != ZEBRA_ROUTE_CONNECT) {
474 if (!CHECK_FLAG(match->status,
475 ROUTE_ENTRY_INSTALLED))
476 return NULL;
477 }
478
479 if (rn_out)
480 *rn_out = rn;
481 return match;
482 }
483 }
484 return NULL;
485 }
486
487 struct route_entry *rib_match_ipv4_multicast(vrf_id_t vrf_id,
488 struct in_addr addr,
489 struct route_node **rn_out)
490 {
491 struct route_entry *re = NULL, *mre = NULL, *ure = NULL;
492 struct route_node *m_rn = NULL, *u_rn = NULL;
493 union g_addr gaddr = {.ipv4 = addr};
494
495 switch (zrouter.ipv4_multicast_mode) {
496 case MCAST_MRIB_ONLY:
497 return rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr,
498 rn_out);
499 case MCAST_URIB_ONLY:
500 return rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, rn_out);
501 case MCAST_NO_CONFIG:
502 case MCAST_MIX_MRIB_FIRST:
503 re = mre = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr,
504 &m_rn);
505 if (!mre)
506 re = ure = rib_match(AFI_IP, SAFI_UNICAST, vrf_id,
507 &gaddr, &u_rn);
508 break;
509 case MCAST_MIX_DISTANCE:
510 mre = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
511 ure = rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
512 if (mre && ure)
513 re = ure->distance < mre->distance ? ure : mre;
514 else if (mre)
515 re = mre;
516 else if (ure)
517 re = ure;
518 break;
519 case MCAST_MIX_PFXLEN:
520 mre = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
521 ure = rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
522 if (mre && ure)
523 re = u_rn->p.prefixlen > m_rn->p.prefixlen ? ure : mre;
524 else if (mre)
525 re = mre;
526 else if (ure)
527 re = ure;
528 break;
529 }
530
531 if (rn_out)
532 *rn_out = (re == mre) ? m_rn : u_rn;
533
534 if (IS_ZEBRA_DEBUG_RIB) {
535 char buf[BUFSIZ];
536 inet_ntop(AF_INET, &addr, buf, BUFSIZ);
537
538 zlog_debug("%s: %s: vrf: %s(%u) found %s, using %s", __func__,
539 buf, vrf_id_to_name(vrf_id), vrf_id,
540 mre ? (ure ? "MRIB+URIB" : "MRIB")
541 : ure ? "URIB" : "nothing",
542 re == ure ? "URIB" : re == mre ? "MRIB" : "none");
543 }
544 return re;
545 }
546
547 struct route_entry *rib_match_ipv6_multicast(vrf_id_t vrf_id,
548 struct in6_addr addr,
549 struct route_node **rn_out)
550 {
551 struct route_entry *re = NULL, *mre = NULL, *ure = NULL;
552 struct route_node *m_rn = NULL, *u_rn = NULL;
553 union g_addr gaddr = {.ipv6 = addr};
554
555 switch (zrouter.ipv4_multicast_mode) {
556 case MCAST_MRIB_ONLY:
557 return rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr,
558 rn_out);
559 case MCAST_URIB_ONLY:
560 return rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, rn_out);
561 case MCAST_NO_CONFIG:
562 case MCAST_MIX_MRIB_FIRST:
563 re = mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr,
564 &m_rn);
565 if (!mre)
566 re = ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id,
567 &gaddr, &u_rn);
568 break;
569 case MCAST_MIX_DISTANCE:
570 mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
571 ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
572 if (mre && ure)
573 re = ure->distance < mre->distance ? ure : mre;
574 else if (mre)
575 re = mre;
576 else if (ure)
577 re = ure;
578 break;
579 case MCAST_MIX_PFXLEN:
580 mre = rib_match(AFI_IP6, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn);
581 ure = rib_match(AFI_IP6, SAFI_UNICAST, vrf_id, &gaddr, &u_rn);
582 if (mre && ure)
583 re = u_rn->p.prefixlen > m_rn->p.prefixlen ? ure : mre;
584 else if (mre)
585 re = mre;
586 else if (ure)
587 re = ure;
588 break;
589 }
590
591 if (rn_out)
592 *rn_out = (re == mre) ? m_rn : u_rn;
593
594 if (IS_ZEBRA_DEBUG_RIB)
595 zlog_debug("%s: %pI6: vrf: %s(%u) found %s, using %s", __func__,
596 &addr, vrf_id_to_name(vrf_id), vrf_id,
597 mre ? (ure ? "MRIB+URIB" : "MRIB")
598 : ure ? "URIB" : "nothing",
599 re == ure ? "URIB" : re == mre ? "MRIB" : "none");
600 return re;
601 }
602
603 struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
604 {
605 struct route_table *table;
606 struct route_node *rn;
607 struct route_entry *match = NULL;
608 rib_dest_t *dest;
609
610 /* Lookup table. */
611 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
612 if (!table)
613 return 0;
614
615 rn = route_node_lookup(table, (struct prefix *)p);
616
617 /* No route for this prefix. */
618 if (!rn)
619 return NULL;
620
621 /* Unlock node. */
622 route_unlock_node(rn);
623 dest = rib_dest_from_rnode(rn);
624
625 if (dest && dest->selected_fib
626 && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
627 match = dest->selected_fib;
628
629 if (!match)
630 return NULL;
631
632 if (match->type == ZEBRA_ROUTE_CONNECT)
633 return match;
634
635 if (CHECK_FLAG(match->status, ROUTE_ENTRY_INSTALLED))
636 return match;
637
638 return NULL;
639 }
640
641 /*
642 * Is this RIB labeled-unicast? It must be of type BGP and all paths
643 * (nexthops) must have a label.
644 */
645 int zebra_rib_labeled_unicast(struct route_entry *re)
646 {
647 struct nexthop *nexthop = NULL;
648
649 if (re->type != ZEBRA_ROUTE_BGP)
650 return 0;
651
652 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
653 if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
654 return 0;
655
656 return 1;
657 }
658
659 /* Update flag indicates whether this is a "replace" or not. Currently, this
660 * is only used for IPv4.
661 */
662 void rib_install_kernel(struct route_node *rn, struct route_entry *re,
663 struct route_entry *old)
664 {
665 struct nexthop *nexthop;
666 struct rib_table_info *info = srcdest_rnode_table_info(rn);
667 struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
668 const struct prefix *p, *src_p;
669 enum zebra_dplane_result ret;
670
671 rib_dest_t *dest = rib_dest_from_rnode(rn);
672
673 srcdest_rnode_prefixes(rn, &p, &src_p);
674
675 if (info->safi != SAFI_UNICAST) {
676 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
677 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
678 return;
679 }
680
681
682 /*
683 * Install the resolved nexthop object first.
684 */
685 zebra_nhg_install_kernel(re->nhe);
686
687 /*
688 * If this is a replace to a new RE let the originator of the RE
689 * know that they've lost
690 */
691 if (old && (old != re) && (old->type != re->type))
692 zsend_route_notify_owner(rn, old, ZAPI_ROUTE_BETTER_ADMIN_WON,
693 info->afi, info->safi);
694
695 /* Update fib selection */
696 dest->selected_fib = re;
697
698 /*
699 * Make sure we update the FPM any time we send new information to
700 * the kernel.
701 */
702 hook_call(rib_update, rn, "installing in kernel");
703
704 /* Send add or update */
705 if (old)
706 ret = dplane_route_update(rn, re, old);
707 else
708 ret = dplane_route_add(rn, re);
709
710 switch (ret) {
711 case ZEBRA_DPLANE_REQUEST_QUEUED:
712 SET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
713
714 if (old) {
715 SET_FLAG(old->status, ROUTE_ENTRY_QUEUED);
716
717 /* Free old FIB nexthop group */
718 UNSET_FLAG(old->status, ROUTE_ENTRY_USE_FIB_NHG);
719 if (old->fib_ng.nexthop) {
720 nexthops_free(old->fib_ng.nexthop);
721 old->fib_ng.nexthop = NULL;
722 }
723 }
724
725 if (zvrf)
726 zvrf->installs_queued++;
727 break;
728 case ZEBRA_DPLANE_REQUEST_FAILURE:
729 {
730 flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
731 "%u:%u:%pRN: Failed to enqueue dataplane install",
732 re->vrf_id, re->table, rn);
733 break;
734 }
735 case ZEBRA_DPLANE_REQUEST_SUCCESS:
736 if (zvrf)
737 zvrf->installs++;
738 break;
739 }
740
741 return;
742 }
743
744 /* Uninstall the route from kernel. */
745 void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
746 {
747 struct nexthop *nexthop;
748 struct rib_table_info *info = srcdest_rnode_table_info(rn);
749 struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
750
751 if (info->safi != SAFI_UNICAST) {
752 UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
753 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
754 UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
755 return;
756 }
757
758 /*
759 * Make sure we update the FPM any time we send new information to
760 * the dataplane.
761 */
762 hook_call(rib_update, rn, "uninstalling from kernel");
763
764 switch (dplane_route_delete(rn, re)) {
765 case ZEBRA_DPLANE_REQUEST_QUEUED:
766 if (zvrf)
767 zvrf->removals_queued++;
768 break;
769 case ZEBRA_DPLANE_REQUEST_FAILURE:
770 flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
771 "%u:%pRN: Failed to enqueue dataplane uninstall",
772 re->vrf_id, rn);
773 break;
774 case ZEBRA_DPLANE_REQUEST_SUCCESS:
775 if (zvrf)
776 zvrf->removals++;
777 break;
778 }
779
780 return;
781 }
782
783 /*
784 * rib_can_delete_dest
785 *
786 * Returns true if the given dest can be deleted from the table.
787 */
788 static int rib_can_delete_dest(rib_dest_t *dest)
789 {
790 if (re_list_first(&dest->routes)) {
791 return 0;
792 }
793
794 /*
795 * Unresolved rnh's are stored on the default route's list
796 *
797 * dest->rnode can also be the source prefix node in an
798 * ipv6 sourcedest table. Fortunately the prefix of a
799 * source prefix node can never be the default prefix.
800 */
801 if (is_default_prefix(&dest->rnode->p))
802 return 0;
803
804 /*
805 * Don't delete the dest if we have to update the FPM about this
806 * prefix.
807 */
808 if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)
809 || CHECK_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM))
810 return 0;
811
812 return 1;
813 }
814
815 void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
816 bool rt_delete)
817 {
818 rib_dest_t *dest = rib_dest_from_rnode(rn);
819 struct rnh *rnh;
820
821 /*
822 * We are storing the rnh's associated withb
823 * the tracked nexthop as a list of the rn's.
824 * Unresolved rnh's are placed at the top
825 * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
826 * As such for each rn we need to walk up the tree
827 * and see if any rnh's need to see if they
828 * would match a more specific route
829 */
830 while (rn) {
831 if (IS_ZEBRA_DEBUG_NHT_DETAILED)
832 zlog_debug(
833 "%s: %pRN Being examined for Nexthop Tracking Count: %zd",
834 __func__, rn,
835 dest ? rnh_list_count(&dest->nht) : 0);
836
837 if (rt_delete && (!dest || !rnh_list_count(&dest->nht))) {
838 if (IS_ZEBRA_DEBUG_NHT_DETAILED)
839 zlog_debug("%pRN has no tracking NHTs. Bailing",
840 rn);
841 break;
842 }
843 if (!dest) {
844 rn = rn->parent;
845 if (rn)
846 dest = rib_dest_from_rnode(rn);
847 continue;
848 }
849 /*
850 * If we have any rnh's stored in the nht list
851 * then we know that this route node was used for
852 * nht resolution and as such we need to call the
853 * nexthop tracking evaluation code
854 */
855 frr_each_safe(rnh_list, &dest->nht, rnh) {
856 struct zebra_vrf *zvrf =
857 zebra_vrf_lookup_by_id(rnh->vrf_id);
858 struct prefix *p = &rnh->node->p;
859
860 if (IS_ZEBRA_DEBUG_NHT_DETAILED)
861 zlog_debug(
862 "%s(%u):%pRN has Nexthop(%pRN) depending on it, evaluating %u:%u",
863 zvrf_name(zvrf), zvrf_id(zvrf), rn,
864 rnh->node, seq, rnh->seqno);
865
866 /*
867 * If we have evaluated this node on this pass
868 * already, due to following the tree up
869 * then we know that we can move onto the next
870 * rnh to process.
871 *
872 * Additionally we call zebra_evaluate_rnh
873 * when we gc the dest. In this case we know
874 * that there must be no other re's where
875 * we were originally as such we know that
876 * that sequence number is ok to respect.
877 */
878 if (rnh->seqno == seq) {
879 if (IS_ZEBRA_DEBUG_NHT_DETAILED)
880 zlog_debug(
881 " Node processed and moved already");
882 continue;
883 }
884
885 rnh->seqno = seq;
886 zebra_evaluate_rnh(zvrf, family2afi(p->family), 0, p,
887 rnh->safi);
888 }
889
890 rn = rn->parent;
891 if (rn)
892 dest = rib_dest_from_rnode(rn);
893 }
894 }
895
896 /*
897 * rib_gc_dest
898 *
899 * Garbage collect the rib dest corresponding to the given route node
900 * if appropriate.
901 *
902 * Returns true if the dest was deleted, false otherwise.
903 */
904 int rib_gc_dest(struct route_node *rn)
905 {
906 rib_dest_t *dest;
907
908 dest = rib_dest_from_rnode(rn);
909 if (!dest)
910 return 0;
911
912 if (!rib_can_delete_dest(dest))
913 return 0;
914
915 if (IS_ZEBRA_DEBUG_RIB) {
916 struct zebra_vrf *zvrf;
917
918 zvrf = rib_dest_vrf(dest);
919 rnode_debug(rn, zvrf_id(zvrf), "removing dest from table");
920 }
921
922 zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence(),
923 true);
924
925 dest->rnode = NULL;
926 rnh_list_fini(&dest->nht);
927 XFREE(MTYPE_RIB_DEST, dest);
928 rn->info = NULL;
929
930 /*
931 * Release the one reference that we keep on the route node.
932 */
933 route_unlock_node(rn);
934 return 1;
935 }
936
937 void zebra_rtable_node_cleanup(struct route_table *table,
938 struct route_node *node)
939 {
940 struct route_entry *re, *next;
941
942 RNODE_FOREACH_RE_SAFE (node, re, next) {
943 rib_unlink(node, re);
944 }
945
946 if (node->info) {
947 rib_dest_t *dest = node->info;
948
949 /* Remove from update queue of FPM module */
950 hook_call(rib_shutdown, node);
951
952 rnh_list_fini(&dest->nht);
953 XFREE(MTYPE_RIB_DEST, node->info);
954 }
955 }
956
957 static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
958 struct route_entry *new)
959 {
960 hook_call(rib_update, rn, "new route selected");
961
962 /* Update real nexthop. This may actually determine if nexthop is active
963 * or not. */
964 if (!nexthop_group_active_nexthop_num(&(new->nhe->nhg))) {
965 UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
966 return;
967 }
968
969 if (IS_ZEBRA_DEBUG_RIB)
970 zlog_debug("%s(%u:%u):%pRN: Adding route rn %p, re %p (%s)",
971 zvrf_name(zvrf), zvrf_id(zvrf), new->table, rn, rn,
972 new, zebra_route_string(new->type));
973
974 /* If labeled-unicast route, install transit LSP. */
975 if (zebra_rib_labeled_unicast(new))
976 zebra_mpls_lsp_install(zvrf, rn, new);
977
978 rib_install_kernel(rn, new, NULL);
979
980 UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
981 }
982
983 static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
984 struct route_entry *old)
985 {
986 hook_call(rib_update, rn, "removing existing route");
987
988 /* Uninstall from kernel. */
989 if (IS_ZEBRA_DEBUG_RIB)
990 zlog_debug("%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s)",
991 zvrf_name(zvrf), zvrf_id(zvrf), old->table, rn, rn,
992 old, zebra_route_string(old->type));
993
994 /* If labeled-unicast route, uninstall transit LSP. */
995 if (zebra_rib_labeled_unicast(old))
996 zebra_mpls_lsp_uninstall(zvrf, rn, old);
997
998 rib_uninstall_kernel(rn, old);
999
1000 /* Update nexthop for route, reset changed flag. */
1001 /* Note: this code also handles the Linux case when an interface goes
1002 * down, causing the kernel to delete routes without sending DELROUTE
1003 * notifications
1004 */
1005 if (RIB_KERNEL_ROUTE(old))
1006 SET_FLAG(old->status, ROUTE_ENTRY_REMOVED);
1007 else
1008 UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
1009 }
1010
1011 static void rib_process_update_fib(struct zebra_vrf *zvrf,
1012 struct route_node *rn,
1013 struct route_entry *old,
1014 struct route_entry *new)
1015 {
1016 int nh_active = 0;
1017
1018 /*
1019 * We have to install or update if a new route has been selected or
1020 * something has changed.
1021 */
1022 if (new != old || CHECK_FLAG(new->status, ROUTE_ENTRY_CHANGED)) {
1023 hook_call(rib_update, rn, "updating existing route");
1024
1025 /* Update the nexthop; we could determine here that nexthop is
1026 * inactive. */
1027 if (nexthop_group_active_nexthop_num(&(new->nhe->nhg)))
1028 nh_active = 1;
1029
1030 /* If nexthop is active, install the selected route, if
1031 * appropriate. If
1032 * the install succeeds, cleanup flags for prior route, if
1033 * different from
1034 * newly selected.
1035 */
1036 if (nh_active) {
1037 if (IS_ZEBRA_DEBUG_RIB) {
1038 if (new != old)
1039 zlog_debug(
1040 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s) old %p (%s)",
1041 zvrf_name(zvrf), zvrf_id(zvrf),
1042 new->table, rn, rn, new,
1043 zebra_route_string(new->type),
1044 old,
1045 zebra_route_string(old->type));
1046 else
1047 zlog_debug(
1048 "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s)",
1049 zvrf_name(zvrf), zvrf_id(zvrf),
1050 new->table, rn, rn, new,
1051 zebra_route_string(new->type));
1052 }
1053
1054 /* If labeled-unicast route, uninstall transit LSP. */
1055 if (zebra_rib_labeled_unicast(old))
1056 zebra_mpls_lsp_uninstall(zvrf, rn, old);
1057
1058 /*
1059 * Non-system route should be installed.
1060 * If labeled-unicast route, install transit
1061 * LSP.
1062 */
1063 if (zebra_rib_labeled_unicast(new))
1064 zebra_mpls_lsp_install(zvrf, rn, new);
1065
1066 rib_install_kernel(rn, new, old);
1067 }
1068
1069 /*
1070 * If nexthop for selected route is not active or install
1071 * failed, we
1072 * may need to uninstall and delete for redistribution.
1073 */
1074 if (!nh_active) {
1075 if (IS_ZEBRA_DEBUG_RIB) {
1076 if (new != old)
1077 zlog_debug(
1078 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
1079 zvrf_name(zvrf), zvrf_id(zvrf),
1080 new->table, rn, rn, new,
1081 zebra_route_string(new->type),
1082 old,
1083 zebra_route_string(old->type));
1084 else
1085 zlog_debug(
1086 "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) - nexthop inactive",
1087 zvrf_name(zvrf), zvrf_id(zvrf),
1088 new->table, rn, rn, new,
1089 zebra_route_string(new->type));
1090 }
1091
1092 /*
1093 * When we have gotten to this point
1094 * the new route entry has no nexthops
1095 * that are usable and as such we need
1096 * to remove the old route, but only
1097 * if we were the one who installed
1098 * the old route
1099 */
1100 if (!RIB_SYSTEM_ROUTE(old)) {
1101 /* If labeled-unicast route, uninstall transit
1102 * LSP. */
1103 if (zebra_rib_labeled_unicast(old))
1104 zebra_mpls_lsp_uninstall(zvrf, rn, old);
1105
1106 rib_uninstall_kernel(rn, old);
1107 }
1108 }
1109 } else {
1110 /*
1111 * Same route selected; check if in the FIB and if not,
1112 * re-install. This is housekeeping code to deal with
1113 * race conditions in kernel with linux netlink reporting
1114 * interface up before IPv4 or IPv6 protocol is ready
1115 * to add routes.
1116 */
1117 if (!CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED) ||
1118 RIB_SYSTEM_ROUTE(new))
1119 rib_install_kernel(rn, new, NULL);
1120 }
1121
1122 /* Update prior route. */
1123 if (new != old)
1124 UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
1125
1126 /* Clear changed flag. */
1127 UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
1128 }
1129
1130 /* Check if 'alternate' RIB entry is better than 'current'. */
1131 static struct route_entry *rib_choose_best(struct route_entry *current,
1132 struct route_entry *alternate)
1133 {
1134 if (current == NULL)
1135 return alternate;
1136
1137 /* filter route selection in following order:
1138 * - connected beats other types
1139 * - if both connected, loopback or vrf wins
1140 * - lower distance beats higher
1141 * - lower metric beats higher for equal distance
1142 * - last, hence oldest, route wins tie break.
1143 */
1144
1145 /* Connected routes. Check to see if either are a vrf
1146 * or loopback interface. If not, pick the last connected
1147 * route of the set of lowest metric connected routes.
1148 */
1149 if (alternate->type == ZEBRA_ROUTE_CONNECT) {
1150 if (current->type != ZEBRA_ROUTE_CONNECT)
1151 return alternate;
1152
1153 /* both are connected. are either loop or vrf? */
1154 struct nexthop *nexthop = NULL;
1155
1156 for (ALL_NEXTHOPS(alternate->nhe->nhg, nexthop)) {
1157 struct interface *ifp = if_lookup_by_index(
1158 nexthop->ifindex, alternate->vrf_id);
1159
1160 if (ifp && if_is_loopback(ifp))
1161 return alternate;
1162 }
1163
1164 for (ALL_NEXTHOPS(current->nhe->nhg, nexthop)) {
1165 struct interface *ifp = if_lookup_by_index(
1166 nexthop->ifindex, current->vrf_id);
1167
1168 if (ifp && if_is_loopback(ifp))
1169 return current;
1170 }
1171
1172 /* Neither are loop or vrf so pick best metric */
1173 if (alternate->metric <= current->metric)
1174 return alternate;
1175
1176 return current;
1177 }
1178
1179 if (current->type == ZEBRA_ROUTE_CONNECT)
1180 return current;
1181
1182 /* higher distance loses */
1183 if (alternate->distance < current->distance)
1184 return alternate;
1185 if (current->distance < alternate->distance)
1186 return current;
1187
1188 /* metric tie-breaks equal distance */
1189 if (alternate->metric <= current->metric)
1190 return alternate;
1191
1192 return current;
1193 }
1194
1195 /* Core function for processing routing information base. */
1196 static void rib_process(struct route_node *rn)
1197 {
1198 struct route_entry *re;
1199 struct route_entry *next;
1200 struct route_entry *old_selected = NULL;
1201 struct route_entry *new_selected = NULL;
1202 struct route_entry *old_fib = NULL;
1203 struct route_entry *new_fib = NULL;
1204 struct route_entry *best = NULL;
1205 rib_dest_t *dest;
1206 struct zebra_vrf *zvrf = NULL;
1207 struct vrf *vrf;
1208
1209 vrf_id_t vrf_id = VRF_UNKNOWN;
1210
1211 assert(rn);
1212
1213 dest = rib_dest_from_rnode(rn);
1214 /*
1215 * We have an enqueued node with nothing to process here
1216 * let's just finish up and return;
1217 */
1218 if (!dest)
1219 return;
1220
1221 zvrf = rib_dest_vrf(dest);
1222 vrf_id = zvrf_id(zvrf);
1223
1224 vrf = vrf_lookup_by_id(vrf_id);
1225
1226 /*
1227 * we can have rn's that have a NULL info pointer
1228 * (dest). As such let's not let the deref happen
1229 * additionally we know RNODE_FOREACH_RE_SAFE
1230 * will not iterate so we are ok.
1231 */
1232 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
1233 struct route_entry *re = re_list_first(&dest->routes);
1234
1235 zlog_debug("%s(%u:%u):%pRN: Processing rn %p",
1236 VRF_LOGNAME(vrf), vrf_id, re->table, rn,
1237 rn);
1238 }
1239
1240 old_fib = dest->selected_fib;
1241
1242 RNODE_FOREACH_RE_SAFE (rn, re, next) {
1243 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
1244 char flags_buf[128];
1245 char status_buf[128];
1246
1247 zlog_debug(
1248 "%s(%u:%u):%pRN: Examine re %p (%s) status: %sflags: %sdist %d metric %d",
1249 VRF_LOGNAME(vrf), vrf_id, re->table, rn, re,
1250 zebra_route_string(re->type),
1251 _dump_re_status(re, status_buf,
1252 sizeof(status_buf)),
1253 zclient_dump_route_flags(re->flags, flags_buf,
1254 sizeof(flags_buf)),
1255 re->distance, re->metric);
1256 }
1257
1258 /* Currently selected re. */
1259 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1260 assert(old_selected == NULL);
1261 old_selected = re;
1262 }
1263
1264 /* Skip deleted entries from selection */
1265 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
1266 continue;
1267
1268 /*
1269 * If the route entry has changed, verify/resolve
1270 * the nexthops associated with the entry.
1271 *
1272 * In any event if we have nexthops that are not active
1273 * then we cannot use this particular route entry so
1274 * skip it.
1275 */
1276 if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) {
1277 if (!nexthop_active_update(rn, re)) {
1278 const struct prefix *p;
1279 struct rib_table_info *info;
1280
1281 if (re->type == ZEBRA_ROUTE_TABLE) {
1282 /* XXX: HERE BE DRAGONS!!!!!
1283 * In all honesty, I have not yet
1284 * figured out what this part does or
1285 * why the ROUTE_ENTRY_CHANGED test
1286 * above is correct or why we need to
1287 * delete a route here, and also not
1288 * whether this concerns both selected
1289 * and fib route, or only selected
1290 * or only fib
1291 *
1292 * This entry was denied by the 'ip
1293 * protocol
1294 * table' route-map, we need to delete
1295 * it */
1296 if (re != old_selected) {
1297 if (IS_ZEBRA_DEBUG_RIB)
1298 zlog_debug(
1299 "%s: %s(%u):%pRN: imported via import-table but denied by the ip protocol table route-map",
1300 __func__,
1301 VRF_LOGNAME(
1302 vrf),
1303 vrf_id, rn);
1304 rib_unlink(rn, re);
1305 } else
1306 SET_FLAG(re->status,
1307 ROUTE_ENTRY_REMOVED);
1308 }
1309
1310 info = srcdest_rnode_table_info(rn);
1311 srcdest_rnode_prefixes(rn, &p, NULL);
1312 zsend_route_notify_owner(
1313 rn, re, ZAPI_ROUTE_FAIL_INSTALL,
1314 info->afi, info->safi);
1315 continue;
1316 }
1317 } else {
1318 /*
1319 * If the re has not changed and the nhg we have is
1320 * not usable, then we cannot use this route entry
1321 * for consideration, as that the route will just
1322 * not install if it is selected.
1323 */
1324 if (!nexthop_group_active_nexthop_num(&re->nhe->nhg))
1325 continue;
1326 }
1327
1328 /* Infinite distance. */
1329 if (re->distance == DISTANCE_INFINITY &&
1330 re->type != ZEBRA_ROUTE_KERNEL) {
1331 UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
1332 continue;
1333 }
1334
1335 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_FIB_OVERRIDE)) {
1336 best = rib_choose_best(new_fib, re);
1337 if (new_fib && best != new_fib)
1338 UNSET_FLAG(new_fib->status,
1339 ROUTE_ENTRY_CHANGED);
1340 new_fib = best;
1341 } else {
1342 best = rib_choose_best(new_selected, re);
1343 if (new_selected && best != new_selected)
1344 UNSET_FLAG(new_selected->status,
1345 ROUTE_ENTRY_CHANGED);
1346 new_selected = best;
1347 }
1348 if (best != re)
1349 UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
1350 } /* RNODE_FOREACH_RE */
1351
1352 /* If no FIB override route, use the selected route also for FIB */
1353 if (new_fib == NULL)
1354 new_fib = new_selected;
1355
1356 /* After the cycle is finished, the following pointers will be set:
1357 * old_selected --- RE entry currently having SELECTED
1358 * new_selected --- RE entry that is newly SELECTED
1359 * old_fib --- RE entry currently in kernel FIB
1360 * new_fib --- RE entry that is newly to be in kernel FIB
1361 *
1362 * new_selected will get SELECTED flag, and is going to be redistributed
1363 * the zclients. new_fib (which can be new_selected) will be installed
1364 * in kernel.
1365 */
1366
1367 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
1368 struct route_entry *entry;
1369
1370 entry = old_selected
1371 ? old_selected
1372 : new_selected
1373 ? new_selected
1374 : old_fib ? old_fib
1375 : new_fib ? new_fib : NULL;
1376
1377 zlog_debug(
1378 "%s(%u:%u):%pRN: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
1379 VRF_LOGNAME(vrf), vrf_id, entry ? entry->table : 0, rn,
1380 (void *)old_selected, (void *)new_selected,
1381 (void *)old_fib, (void *)new_fib);
1382 }
1383
1384 /* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
1385 * fib == selected */
1386 bool selected_changed = new_selected && CHECK_FLAG(new_selected->status,
1387 ROUTE_ENTRY_CHANGED);
1388
1389 /* Update SELECTED entry */
1390 if (old_selected != new_selected || selected_changed) {
1391
1392 if (new_selected && new_selected != new_fib)
1393 UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED);
1394
1395 if (new_selected)
1396 SET_FLAG(new_selected->flags, ZEBRA_FLAG_SELECTED);
1397
1398 if (old_selected) {
1399 /*
1400 * If we're removing the old entry, we should tell
1401 * redist subscribers about that *if* they aren't
1402 * going to see a redist for the new entry.
1403 */
1404 if (!new_selected || CHECK_FLAG(old_selected->status,
1405 ROUTE_ENTRY_REMOVED))
1406 redistribute_delete(rn, old_selected,
1407 new_selected);
1408
1409 if (old_selected != new_selected)
1410 UNSET_FLAG(old_selected->flags,
1411 ZEBRA_FLAG_SELECTED);
1412 }
1413 }
1414
1415 /* Update fib according to selection results */
1416 if (new_fib && old_fib)
1417 rib_process_update_fib(zvrf, rn, old_fib, new_fib);
1418 else if (new_fib)
1419 rib_process_add_fib(zvrf, rn, new_fib);
1420 else if (old_fib)
1421 rib_process_del_fib(zvrf, rn, old_fib);
1422
1423 /* Remove all RE entries queued for removal */
1424 RNODE_FOREACH_RE_SAFE (rn, re, next) {
1425 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
1426 if (IS_ZEBRA_DEBUG_RIB) {
1427 rnode_debug(rn, vrf_id, "rn %p, removing re %p",
1428 (void *)rn, (void *)re);
1429 }
1430 rib_unlink(rn, re);
1431 }
1432 }
1433
1434 /*
1435 * Check if the dest can be deleted now.
1436 */
1437 rib_gc_dest(rn);
1438 }
1439
1440 static void zebra_rib_evaluate_mpls(struct route_node *rn)
1441 {
1442 rib_dest_t *dest = rib_dest_from_rnode(rn);
1443 struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
1444
1445 if (!dest)
1446 return;
1447
1448 if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS)) {
1449 if (IS_ZEBRA_DEBUG_MPLS)
1450 zlog_debug(
1451 "%s(%u): Scheduling all LSPs upon RIB completion",
1452 zvrf_name(zvrf), zvrf_id(zvrf));
1453 zebra_mpls_lsp_schedule(zvrf);
1454 mpls_unmark_lsps_for_processing(rn);
1455 }
1456 }
1457
1458 /*
1459 * Utility to match route with dplane context data
1460 */
1461 static bool rib_route_match_ctx(const struct route_entry *re,
1462 const struct zebra_dplane_ctx *ctx,
1463 bool is_update)
1464 {
1465 bool result = false;
1466
1467 if (is_update) {
1468 /*
1469 * In 'update' case, we test info about the 'previous' or
1470 * 'old' route
1471 */
1472 if ((re->type == dplane_ctx_get_old_type(ctx)) &&
1473 (re->instance == dplane_ctx_get_old_instance(ctx))) {
1474 result = true;
1475
1476 /* We use an extra test for statics, and another for
1477 * kernel routes.
1478 */
1479 if (re->type == ZEBRA_ROUTE_STATIC &&
1480 (re->distance != dplane_ctx_get_old_distance(ctx) ||
1481 re->tag != dplane_ctx_get_old_tag(ctx))) {
1482 result = false;
1483 } else if (re->type == ZEBRA_ROUTE_KERNEL &&
1484 re->metric !=
1485 dplane_ctx_get_old_metric(ctx)) {
1486 result = false;
1487 }
1488 }
1489
1490 } else {
1491 /*
1492 * Ordinary, single-route case using primary context info
1493 */
1494 if ((dplane_ctx_get_op(ctx) != DPLANE_OP_ROUTE_DELETE) &&
1495 CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
1496 /* Skip route that's been deleted */
1497 goto done;
1498 }
1499
1500 if ((re->type == dplane_ctx_get_type(ctx)) &&
1501 (re->instance == dplane_ctx_get_instance(ctx))) {
1502 result = true;
1503
1504 /* We use an extra test for statics, and another for
1505 * kernel routes.
1506 */
1507 if (re->type == ZEBRA_ROUTE_STATIC &&
1508 (re->distance != dplane_ctx_get_distance(ctx) ||
1509 re->tag != dplane_ctx_get_tag(ctx))) {
1510 result = false;
1511 } else if (re->type == ZEBRA_ROUTE_KERNEL &&
1512 re->metric != dplane_ctx_get_metric(ctx)) {
1513 result = false;
1514 } else if (re->type == ZEBRA_ROUTE_CONNECT) {
1515 result = nexthop_group_equal_no_recurse(
1516 &re->nhe->nhg, dplane_ctx_get_ng(ctx));
1517 }
1518 }
1519 }
1520
1521 done:
1522
1523 return (result);
1524 }
1525
1526 static void zebra_rib_fixup_system(struct route_node *rn)
1527 {
1528 struct route_entry *re;
1529
1530 RNODE_FOREACH_RE(rn, re) {
1531 struct nexthop *nhop;
1532
1533 if (!RIB_SYSTEM_ROUTE(re))
1534 continue;
1535
1536 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
1537 continue;
1538
1539 SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
1540 UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
1541
1542 for (ALL_NEXTHOPS(re->nhe->nhg, nhop)) {
1543 if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
1544 continue;
1545
1546 SET_FLAG(nhop->flags, NEXTHOP_FLAG_FIB);
1547 }
1548 }
1549 }
1550
1551 /* Route comparison logic, with various special cases. */
1552 static bool rib_compare_routes(const struct route_entry *re1,
1553 const struct route_entry *re2)
1554 {
1555 if (re1->type != re2->type)
1556 return false;
1557
1558 if (re1->instance != re2->instance)
1559 return false;
1560
1561 if (re1->type == ZEBRA_ROUTE_KERNEL && re1->metric != re2->metric)
1562 return false;
1563
1564 if (CHECK_FLAG(re1->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
1565 re1->distance != re2->distance)
1566 return false;
1567
1568 /* We support multiple connected routes: this supports multiple
1569 * v6 link-locals, and we also support multiple addresses in the same
1570 * subnet on a single interface.
1571 */
1572 if (re1->type != ZEBRA_ROUTE_CONNECT)
1573 return true;
1574
1575 return false;
1576 }
1577
1578 /*
1579 * Compare nexthop lists from a route and a dplane context; test whether
1580 * the list installed in the FIB matches the route's list.
1581 * Set 'changed_p' to 'true' if there were changes to the route's
1582 * installed nexthops.
1583 *
1584 * Return 'false' if any ACTIVE route nexthops are not mentioned in the FIB
1585 * list.
1586 */
1587 static bool rib_update_nhg_from_ctx(struct nexthop_group *re_nhg,
1588 const struct nexthop_group *ctx_nhg,
1589 bool *changed_p)
1590 {
1591 bool matched_p = true;
1592 struct nexthop *nexthop, *ctx_nexthop;
1593
1594 /* Get the first `installed` one to check against.
1595 * If the dataplane doesn't set these to be what was actually installed,
1596 * it will just be whatever was in re->nhe->nhg?
1597 */
1598 ctx_nexthop = ctx_nhg->nexthop;
1599
1600 if (CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
1601 || !CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1602 ctx_nexthop = nexthop_next_active_resolved(ctx_nexthop);
1603
1604 for (ALL_NEXTHOPS_PTR(re_nhg, nexthop)) {
1605
1606 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1607 continue;
1608
1609 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1610 continue;
1611
1612 /* Check for a FIB nexthop corresponding to the RIB nexthop */
1613 if (!nexthop_same(ctx_nexthop, nexthop)) {
1614 /* If the FIB doesn't know about the nexthop,
1615 * it's not installed
1616 */
1617 if (IS_ZEBRA_DEBUG_RIB_DETAILED ||
1618 IS_ZEBRA_DEBUG_NHG_DETAIL) {
1619 zlog_debug("%s: no ctx match for rib nh %pNHv %s",
1620 __func__, nexthop,
1621 (CHECK_FLAG(nexthop->flags,
1622 NEXTHOP_FLAG_FIB) ?
1623 "(FIB)":""));
1624 }
1625 matched_p = false;
1626
1627 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
1628 *changed_p = true;
1629
1630 UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
1631
1632 /* Keep checking nexthops */
1633 continue;
1634 }
1635
1636 if (CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_FIB)) {
1637 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
1638 if (IS_ZEBRA_DEBUG_NHG_DETAIL)
1639 zlog_debug("%s: rib nh %pNHv -> installed",
1640 __func__, nexthop);
1641
1642 *changed_p = true;
1643 }
1644
1645 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
1646 } else {
1647 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
1648 if (IS_ZEBRA_DEBUG_NHG_DETAIL)
1649 zlog_debug("%s: rib nh %pNHv -> uninstalled",
1650 __func__, nexthop);
1651
1652 *changed_p = true;
1653 }
1654
1655 UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
1656 }
1657
1658 ctx_nexthop = nexthop_next_active_resolved(ctx_nexthop);
1659 }
1660
1661 return matched_p;
1662 }
1663
1664 /*
1665 * Update a route from a dplane context. This consolidates common code
1666 * that can be used in processing of results from FIB updates, and in
1667 * async notification processing.
1668 * The return is 'true' if the installed nexthops changed; 'false' otherwise.
1669 */
1670 static bool rib_update_re_from_ctx(struct route_entry *re,
1671 struct route_node *rn,
1672 struct zebra_dplane_ctx *ctx)
1673 {
1674 struct nexthop *nexthop;
1675 bool matched;
1676 const struct nexthop_group *ctxnhg;
1677 struct nexthop_group *re_nhg;
1678 bool is_selected = false; /* Is 're' currently the selected re? */
1679 bool changed_p = false; /* Change to nexthops? */
1680 rib_dest_t *dest;
1681 struct vrf *vrf;
1682
1683 vrf = vrf_lookup_by_id(re->vrf_id);
1684
1685 dest = rib_dest_from_rnode(rn);
1686 if (dest)
1687 is_selected = (re == dest->selected_fib);
1688
1689 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1690 zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p",
1691 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
1692 (is_selected ? "" : "NOT "), re);
1693
1694 /* Update zebra's nexthop FIB flag for each nexthop that was installed.
1695 * If the installed set differs from the set requested by the rib/owner,
1696 * we use the fib-specific nexthop-group to record the actual FIB
1697 * status.
1698 */
1699 matched = false;
1700 ctxnhg = dplane_ctx_get_ng(ctx);
1701
1702 /* Check route's fib group and incoming notif group for equivalence.
1703 *
1704 * Let's assume the nexthops are ordered here to save time.
1705 */
1706 /* TODO -- this isn't testing or comparing the FIB flags; we should
1707 * do a more explicit loop, checking the incoming notification's flags.
1708 */
1709 if (re->fib_ng.nexthop && ctxnhg->nexthop &&
1710 nexthop_group_equal(&re->fib_ng, ctxnhg))
1711 matched = true;
1712
1713 /* If the new FIB set matches the existing FIB set, we're done. */
1714 if (matched) {
1715 if (IS_ZEBRA_DEBUG_RIB)
1716 zlog_debug(
1717 "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change",
1718 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
1719 goto check_backups;
1720
1721 } else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) {
1722 /*
1723 * Free stale fib list and move on to check the rib nhg.
1724 */
1725 if (IS_ZEBRA_DEBUG_RIB)
1726 zlog_debug(
1727 "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg",
1728 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
1729 nexthops_free(re->fib_ng.nexthop);
1730 re->fib_ng.nexthop = NULL;
1731
1732 UNSET_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG);
1733
1734 /* Note that the installed nexthops have changed */
1735 changed_p = true;
1736 } else {
1737 if (IS_ZEBRA_DEBUG_RIB)
1738 zlog_debug(
1739 "%s(%u:%u):%pRN update_from_ctx(): no fib nhg",
1740 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
1741 }
1742
1743 /*
1744 * Compare with the rib nexthop group. The comparison here is different:
1745 * the RIB group may be a superset of the list installed in the FIB. We
1746 * walk the RIB group, looking for the 'installable' candidate
1747 * nexthops, and then check those against the set
1748 * that is actually installed.
1749 *
1750 * Assume nexthops are ordered here as well.
1751 */
1752
1753 /* If nothing is installed, we can skip some of the checking/comparison
1754 * of nexthops.
1755 */
1756 if (ctxnhg->nexthop == NULL) {
1757 changed_p = true;
1758 goto no_nexthops;
1759 }
1760
1761 matched = rib_update_nhg_from_ctx(&(re->nhe->nhg), ctxnhg, &changed_p);
1762
1763 /* If all nexthops were processed, we're done */
1764 if (matched) {
1765 if (IS_ZEBRA_DEBUG_RIB)
1766 zlog_debug(
1767 "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'",
1768 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
1769 (changed_p ? "true" : "false"));
1770 goto check_backups;
1771 }
1772
1773 no_nexthops:
1774
1775 /* FIB nexthop set differs from the RIB set:
1776 * create a fib-specific nexthop-group
1777 */
1778 if (IS_ZEBRA_DEBUG_RIB)
1779 zlog_debug(
1780 "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s",
1781 VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
1782 (changed_p ? "true" : "false"),
1783 ctxnhg->nexthop != NULL ? "" : " (empty)");
1784
1785 /* Set the flag about the dedicated fib list */
1786 SET_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG);
1787 if (ctxnhg->nexthop)
1788 copy_nexthops(&(re->fib_ng.nexthop), ctxnhg->nexthop, NULL);
1789
1790 check_backups:
1791
1792 /*
1793 * Check the status of the route's backup nexthops, if any.
1794 * The logic for backups is somewhat different: if any backup is
1795 * installed, a new fib nhg will be attached to the route.
1796 */
1797 re_nhg = zebra_nhg_get_backup_nhg(re->nhe);
1798 if (re_nhg == NULL)
1799 goto done; /* No backup nexthops */
1800
1801 /* First check the route's 'fib' list of backups, if it's present
1802 * from some previous event.
1803 */
1804 re_nhg = &re->fib_backup_ng;
1805 ctxnhg = dplane_ctx_get_backup_ng(ctx);
1806
1807 matched = false;
1808 if (re_nhg->nexthop && ctxnhg && nexthop_group_equal(re_nhg, ctxnhg))
1809 matched = true;
1810
1811 /* If the new FIB set matches an existing FIB set, we're done. */
1812 if (matched) {
1813 if (IS_ZEBRA_DEBUG_RIB)
1814 zlog_debug(
1815 "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change",
1816 VRF_LOGNAME(vrf), re->vrf_id, rn);
1817 goto done;
1818
1819 } else if (re->fib_backup_ng.nexthop) {
1820 /*
1821 * Free stale fib backup list and move on to check
1822 * the route's backups.
1823 */
1824 if (IS_ZEBRA_DEBUG_RIB)
1825 zlog_debug(
1826 "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg",
1827 VRF_LOGNAME(vrf), re->vrf_id, rn);
1828 nexthops_free(re->fib_backup_ng.nexthop);
1829 re->fib_backup_ng.nexthop = NULL;
1830
1831 /* Note that the installed nexthops have changed */
1832 changed_p = true;
1833 } else {
1834 if (IS_ZEBRA_DEBUG_RIB)
1835 zlog_debug(
1836 "%s(%u):%pRN update_from_ctx(): no fib backup nhg",
1837 VRF_LOGNAME(vrf), re->vrf_id, rn);
1838 }
1839
1840 /*
1841 * If a FIB backup nexthop set exists, attach a copy
1842 * to the route if any backup is installed
1843 */
1844 if (ctxnhg && ctxnhg->nexthop) {
1845
1846 for (ALL_NEXTHOPS_PTR(ctxnhg, nexthop)) {
1847 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
1848 break;
1849 }
1850
1851 /* If no installed backups, we're done */
1852 if (nexthop == NULL)
1853 goto done;
1854
1855 if (IS_ZEBRA_DEBUG_RIB)
1856 zlog_debug(
1857 "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg",
1858 VRF_LOGNAME(vrf), re->vrf_id, rn,
1859 (changed_p ? "true" : "false"));
1860
1861 copy_nexthops(&(re->fib_backup_ng.nexthop), ctxnhg->nexthop,
1862 NULL);
1863 }
1864
1865 done:
1866
1867 return changed_p;
1868 }
1869
1870 /*
1871 * Helper to locate a zebra route-node from a dplane context. This is used
1872 * when processing dplane results, e.g. Note well: the route-node is returned
1873 * with a ref held - route_unlock_node() must be called eventually.
1874 */
1875 struct route_node *rib_find_rn_from_ctx(const struct zebra_dplane_ctx *ctx)
1876 {
1877 struct route_table *table = NULL;
1878 struct route_node *rn = NULL;
1879 const struct prefix *dest_pfx, *src_pfx;
1880
1881 /* Locate rn and re(s) from ctx */
1882
1883 table = zebra_vrf_lookup_table_with_table_id(
1884 dplane_ctx_get_afi(ctx), dplane_ctx_get_safi(ctx),
1885 dplane_ctx_get_vrf(ctx), dplane_ctx_get_table(ctx));
1886 if (table == NULL) {
1887 if (IS_ZEBRA_DEBUG_DPLANE) {
1888 zlog_debug(
1889 "Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u)",
1890 dplane_ctx_get_afi(ctx),
1891 dplane_ctx_get_safi(ctx),
1892 vrf_id_to_name(dplane_ctx_get_vrf(ctx)),
1893 dplane_ctx_get_vrf(ctx));
1894 }
1895 goto done;
1896 }
1897
1898 dest_pfx = dplane_ctx_get_dest(ctx);
1899 src_pfx = dplane_ctx_get_src(ctx);
1900
1901 rn = srcdest_rnode_get(table, dest_pfx,
1902 src_pfx ? (struct prefix_ipv6 *)src_pfx : NULL);
1903
1904 done:
1905 return rn;
1906 }
1907
1908
1909
1910 /*
1911 * Route-update results processing after async dataplane update.
1912 */
1913 static void rib_process_result(struct zebra_dplane_ctx *ctx)
1914 {
1915 struct zebra_vrf *zvrf = NULL;
1916 struct vrf *vrf;
1917 struct route_node *rn = NULL;
1918 struct route_entry *re = NULL, *old_re = NULL, *rib;
1919 bool is_update = false;
1920 enum dplane_op_e op;
1921 enum zebra_dplane_result status;
1922 uint32_t seq;
1923 rib_dest_t *dest;
1924 bool fib_changed = false;
1925 struct rib_table_info *info;
1926 bool rt_delete = false;
1927
1928 zvrf = vrf_info_lookup(dplane_ctx_get_vrf(ctx));
1929 vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
1930
1931 /* Locate rn and re(s) from ctx */
1932 rn = rib_find_rn_from_ctx(ctx);
1933 if (rn == NULL) {
1934 if (IS_ZEBRA_DEBUG_DPLANE) {
1935 zlog_debug(
1936 "Failed to process dplane results: no route for %s(%u):%pRN",
1937 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), rn);
1938 }
1939 goto done;
1940 }
1941
1942 dest = rib_dest_from_rnode(rn);
1943 info = srcdest_rnode_table_info(rn);
1944
1945 op = dplane_ctx_get_op(ctx);
1946 status = dplane_ctx_get_status(ctx);
1947
1948 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
1949 zlog_debug(
1950 "%s(%u:%u):%pRN Processing dplane result ctx %p, op %s result %s",
1951 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
1952 dplane_ctx_get_table(ctx), rn, ctx, dplane_op2str(op),
1953 dplane_res2str(status));
1954
1955 /*
1956 * Update is a bit of a special case, where we may have both old and new
1957 * routes to post-process.
1958 */
1959 is_update = dplane_ctx_is_update(ctx);
1960
1961 /*
1962 * Take a pass through the routes, look for matches with the context
1963 * info.
1964 */
1965 RNODE_FOREACH_RE(rn, rib) {
1966
1967 if (re == NULL) {
1968 if (rib_route_match_ctx(rib, ctx, false))
1969 re = rib;
1970 }
1971
1972 /* Check for old route match */
1973 if (is_update && (old_re == NULL)) {
1974 if (rib_route_match_ctx(rib, ctx, true /*is_update*/))
1975 old_re = rib;
1976 }
1977
1978 /* Have we found the routes we need to work on? */
1979 if (re && ((!is_update || old_re)))
1980 break;
1981 }
1982
1983 seq = dplane_ctx_get_seq(ctx);
1984
1985 /*
1986 * Check sequence number(s) to detect stale results before continuing
1987 */
1988 if (re) {
1989 if (re->dplane_sequence != seq) {
1990 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
1991 zlog_debug(
1992 "%s(%u):%pRN Stale dplane result for re %p",
1993 VRF_LOGNAME(vrf),
1994 dplane_ctx_get_vrf(ctx), rn, re);
1995 } else {
1996 if (!zrouter.asic_offloaded ||
1997 (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED) ||
1998 CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED)))
1999 UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
2000 }
2001 }
2002
2003 if (old_re) {
2004 if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) {
2005 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
2006 zlog_debug(
2007 "%s(%u:%u):%pRN Stale dplane result for old_re %p",
2008 VRF_LOGNAME(vrf),
2009 dplane_ctx_get_vrf(ctx), old_re->table,
2010 rn, old_re);
2011 } else
2012 UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
2013 }
2014
2015 switch (op) {
2016 case DPLANE_OP_ROUTE_INSTALL:
2017 case DPLANE_OP_ROUTE_UPDATE:
2018 if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
2019 if (re) {
2020 UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED);
2021 SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2022 }
2023 /*
2024 * On an update operation from the same route type
2025 * context retrieval currently has no way to know
2026 * which was the old and which was the new.
2027 * So don't unset our flags that we just set.
2028 * We know redistribution is ok because the
2029 * old_re in this case is used for nothing
2030 * more than knowing whom to contact if necessary.
2031 */
2032 if (old_re && old_re != re) {
2033 UNSET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
2034 UNSET_FLAG(old_re->status,
2035 ROUTE_ENTRY_INSTALLED);
2036 }
2037
2038 /* Update zebra route based on the results in
2039 * the context struct.
2040 */
2041 if (re) {
2042 fib_changed =
2043 rib_update_re_from_ctx(re, rn, ctx);
2044
2045 if (!fib_changed) {
2046 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
2047 zlog_debug(
2048 "%s(%u:%u):%pRN no fib change for re",
2049 VRF_LOGNAME(vrf),
2050 dplane_ctx_get_vrf(ctx),
2051 dplane_ctx_get_table(
2052 ctx),
2053 rn);
2054 }
2055
2056 /* Redistribute if this is the selected re */
2057 if (dest && re == dest->selected_fib)
2058 redistribute_update(rn, re, old_re);
2059 }
2060
2061 /*
2062 * System routes are weird in that they
2063 * allow multiple to be installed that match
2064 * to the same prefix, so after we get the
2065 * result we need to clean them up so that
2066 * we can actually use them.
2067 */
2068 if ((re && RIB_SYSTEM_ROUTE(re)) ||
2069 (old_re && RIB_SYSTEM_ROUTE(old_re)))
2070 zebra_rib_fixup_system(rn);
2071
2072 if (zvrf)
2073 zvrf->installs++;
2074
2075 /* Notify route owner */
2076 if (zebra_router_notify_on_ack())
2077 zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
2078 else {
2079 if (re) {
2080 if (CHECK_FLAG(re->flags,
2081 ZEBRA_FLAG_OFFLOADED))
2082 zsend_route_notify_owner_ctx(
2083 ctx,
2084 ZAPI_ROUTE_INSTALLED);
2085 if (CHECK_FLAG(
2086 re->flags,
2087 ZEBRA_FLAG_OFFLOAD_FAILED))
2088 zsend_route_notify_owner_ctx(
2089 ctx,
2090 ZAPI_ROUTE_FAIL_INSTALL);
2091 }
2092 }
2093 } else {
2094 if (re) {
2095 SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
2096 UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2097 } if (old_re)
2098 SET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
2099 if (re)
2100 zsend_route_notify_owner(
2101 rn, re, ZAPI_ROUTE_FAIL_INSTALL,
2102 info->afi, info->safi);
2103
2104 zlog_warn("%s(%u:%u):%pRN: Route install failed",
2105 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2106 dplane_ctx_get_table(ctx), rn);
2107 }
2108 break;
2109 case DPLANE_OP_ROUTE_DELETE:
2110 rt_delete = true;
2111 if (re)
2112 SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
2113 /*
2114 * In the delete case, the zebra core datastructs were
2115 * updated (or removed) at the time the delete was issued,
2116 * so we're just notifying the route owner.
2117 */
2118 if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
2119 if (re) {
2120 UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2121 UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED);
2122 }
2123 zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_REMOVED);
2124
2125 if (zvrf)
2126 zvrf->removals++;
2127 } else {
2128 if (re)
2129 SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
2130 zsend_route_notify_owner_ctx(ctx,
2131 ZAPI_ROUTE_REMOVE_FAIL);
2132
2133 zlog_warn("%s(%u:%u):%pRN: Route Deletion failure",
2134 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2135 dplane_ctx_get_table(ctx), rn);
2136 }
2137
2138 /*
2139 * System routes are weird in that they
2140 * allow multiple to be installed that match
2141 * to the same prefix, so after we get the
2142 * result we need to clean them up so that
2143 * we can actually use them.
2144 */
2145 if ((re && RIB_SYSTEM_ROUTE(re)) ||
2146 (old_re && RIB_SYSTEM_ROUTE(old_re)))
2147 zebra_rib_fixup_system(rn);
2148 break;
2149 default:
2150 break;
2151 }
2152
2153 zebra_rib_evaluate_rn_nexthops(rn, seq, rt_delete);
2154 zebra_rib_evaluate_mpls(rn);
2155 done:
2156
2157 if (rn)
2158 route_unlock_node(rn);
2159 }
2160
2161 /*
2162 * Count installed/FIB nexthops
2163 */
2164 static int rib_count_installed_nh(struct route_entry *re)
2165 {
2166 int count = 0;
2167 struct nexthop *nexthop;
2168 struct nexthop_group *nhg;
2169
2170 nhg = rib_get_fib_nhg(re);
2171
2172 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
2173 /* The meaningful flag depends on where the installed
2174 * nexthops reside.
2175 */
2176 if (nhg == &(re->fib_ng)) {
2177 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
2178 count++;
2179 } else {
2180 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
2181 count++;
2182 }
2183 }
2184
2185 nhg = rib_get_fib_backup_nhg(re);
2186 if (nhg) {
2187 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
2188 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
2189 count++;
2190 }
2191 }
2192
2193 return count;
2194 }
2195
2196 /*
2197 * Handle notification from async dataplane: the dataplane has detected
2198 * some change to a route, and notifies zebra so that the control plane
2199 * can reflect that change.
2200 */
2201 static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
2202 {
2203 struct route_node *rn = NULL;
2204 struct route_entry *re = NULL;
2205 struct vrf *vrf;
2206 struct nexthop *nexthop;
2207 rib_dest_t *dest;
2208 bool fib_changed = false;
2209 bool debug_p = IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_RIB;
2210 int start_count, end_count;
2211
2212 vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
2213
2214 /* Locate rn and re(s) from ctx */
2215 rn = rib_find_rn_from_ctx(ctx);
2216 if (rn == NULL) {
2217 if (debug_p) {
2218 zlog_debug(
2219 "Failed to process dplane notification: no routes for %s(%u:%u):%pRN",
2220 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2221 dplane_ctx_get_table(ctx), rn);
2222 }
2223 goto done;
2224 }
2225
2226 dest = rib_dest_from_rnode(rn);
2227
2228 if (debug_p)
2229 zlog_debug("%s(%u:%u):%pRN Processing dplane notif ctx %p",
2230 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2231 dplane_ctx_get_table(ctx), rn, ctx);
2232
2233 /*
2234 * Take a pass through the routes, look for matches with the context
2235 * info.
2236 */
2237 RNODE_FOREACH_RE(rn, re) {
2238 if (rib_route_match_ctx(re, ctx, false /*!update*/))
2239 break;
2240 }
2241
2242 /* No match? Nothing we can do */
2243 if (re == NULL) {
2244 if (debug_p)
2245 zlog_debug(
2246 "%s(%u:%u):%pRN Unable to process dplane notification: no entry for type %s",
2247 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2248 dplane_ctx_get_table(ctx), rn,
2249 zebra_route_string(dplane_ctx_get_type(ctx)));
2250
2251 goto done;
2252 }
2253
2254 /* Ensure we clear the QUEUED flag */
2255 if (!zrouter.asic_offloaded)
2256 UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
2257
2258 /* Is this a notification that ... matters? We mostly care about
2259 * the route that is currently selected for installation; we may also
2260 * get an un-install notification, and handle that too.
2261 */
2262 if (re != dest->selected_fib) {
2263 /*
2264 * If we need to, clean up after a delete that was part of
2265 * an update operation.
2266 */
2267 end_count = 0;
2268 for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
2269 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
2270 end_count++;
2271 }
2272
2273 /* If no nexthops or none installed, ensure that this re
2274 * gets its 'installed' flag cleared.
2275 */
2276 if (end_count == 0) {
2277 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
2278 UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2279 if (debug_p)
2280 zlog_debug(
2281 "%s(%u:%u):%pRN dplane notif, uninstalled type %s route",
2282 VRF_LOGNAME(vrf),
2283 dplane_ctx_get_vrf(ctx),
2284 dplane_ctx_get_table(ctx), rn,
2285 zebra_route_string(
2286 dplane_ctx_get_type(ctx)));
2287 } else {
2288 /* At least report on the event. */
2289 if (debug_p)
2290 zlog_debug(
2291 "%s(%u:%u):%pRN dplane notif, but type %s not selected_fib",
2292 VRF_LOGNAME(vrf),
2293 dplane_ctx_get_vrf(ctx),
2294 dplane_ctx_get_table(ctx), rn,
2295 zebra_route_string(
2296 dplane_ctx_get_type(ctx)));
2297 }
2298 goto done;
2299 }
2300
2301 /* We'll want to determine whether the installation status of the
2302 * route has changed: we'll check the status before processing,
2303 * and then again if there's been a change.
2304 */
2305 start_count = 0;
2306
2307 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
2308 start_count = rib_count_installed_nh(re);
2309
2310 /* Update zebra's nexthop FIB flags based on the context struct's
2311 * nexthops.
2312 */
2313 fib_changed = rib_update_re_from_ctx(re, rn, ctx);
2314
2315 if (!fib_changed) {
2316 if (debug_p)
2317 zlog_debug(
2318 "%s(%u:%u):%pRN dplane notification: rib_update returns FALSE",
2319 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2320 dplane_ctx_get_table(ctx), rn);
2321 }
2322
2323 /*
2324 * Perform follow-up work if the actual status of the prefix
2325 * changed.
2326 */
2327 end_count = rib_count_installed_nh(re);
2328
2329 /* Various fib transitions: changed nexthops; from installed to
2330 * not-installed; or not-installed to installed.
2331 */
2332 if (start_count > 0 && end_count > 0) {
2333 if (debug_p)
2334 zlog_debug(
2335 "%s(%u:%u):%pRN applied nexthop changes from dplane notification",
2336 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2337 dplane_ctx_get_table(ctx), rn);
2338
2339 /* Changed nexthops - update kernel/others */
2340 dplane_route_notif_update(rn, re,
2341 DPLANE_OP_ROUTE_UPDATE, ctx);
2342
2343 } else if (start_count == 0 && end_count > 0) {
2344 if (debug_p)
2345 zlog_debug(
2346 "%s(%u:%u):%pRN installed transition from dplane notification",
2347 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2348 dplane_ctx_get_table(ctx), rn);
2349
2350 /* We expect this to be the selected route, so we want
2351 * to tell others about this transition.
2352 */
2353 SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2354
2355 /* Changed nexthops - update kernel/others */
2356 dplane_route_notif_update(rn, re, DPLANE_OP_ROUTE_UPDATE, ctx);
2357
2358 /* Redistribute, lsp, and nht update */
2359 redistribute_update(rn, re, NULL);
2360
2361 } else if (start_count > 0 && end_count == 0) {
2362 if (debug_p)
2363 zlog_debug(
2364 "%s(%u:%u):%pRN un-installed transition from dplane notification",
2365 VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
2366 dplane_ctx_get_table(ctx), rn);
2367
2368 /* Transition from _something_ installed to _nothing_
2369 * installed.
2370 */
2371 /* We expect this to be the selected route, so we want
2372 * to tell others about this transistion.
2373 */
2374 UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
2375
2376 /* Changed nexthops - update kernel/others */
2377 dplane_route_notif_update(rn, re, DPLANE_OP_ROUTE_DELETE, ctx);
2378
2379 /* Redistribute, lsp, and nht update */
2380 redistribute_delete(rn, re, NULL);
2381 }
2382
2383 /* Make any changes visible for lsp and nexthop-tracking processing */
2384 zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence(),
2385 false);
2386
2387 zebra_rib_evaluate_mpls(rn);
2388
2389 done:
2390 if (rn)
2391 route_unlock_node(rn);
2392 }
2393
2394 /*
2395 * Process a node from the EVPN/VXLAN subqueue.
2396 */
2397 static void process_subq_evpn(struct listnode *lnode)
2398 {
2399 struct wq_evpn_wrapper *w;
2400
2401 /* In general, the list node points to a wrapper object
2402 * holding the info necessary to make some update.
2403 */
2404 w = listgetdata(lnode);
2405 if (!w)
2406 return;
2407
2408 if (w->type == WQ_EVPN_WRAPPER_TYPE_VRFROUTE) {
2409 if (w->add_p)
2410 zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->macaddr,
2411 &w->ip, &w->prefix);
2412 else
2413 zebra_vxlan_evpn_vrf_route_del(w->vrf_id, &w->ip,
2414 &w->prefix);
2415 } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_ES) {
2416 if (w->add_p)
2417 zebra_evpn_remote_es_add(&w->esi, w->ip.ipaddr_v4,
2418 w->esr_rxed, w->df_alg,
2419 w->df_pref);
2420 else
2421 zebra_evpn_remote_es_del(&w->esi, w->ip.ipaddr_v4);
2422 } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_MACIP) {
2423 uint16_t ipa_len = 0;
2424
2425 if (w->ip.ipa_type == IPADDR_V4)
2426 ipa_len = IPV4_MAX_BYTELEN;
2427 else if (w->ip.ipa_type == IPADDR_V6)
2428 ipa_len = IPV6_MAX_BYTELEN;
2429
2430 if (w->add_p)
2431 zebra_evpn_rem_macip_add(w->vni, &w->macaddr, ipa_len,
2432 &w->ip, w->flags, w->seq,
2433 w->vtep_ip, &w->esi);
2434 else
2435 zebra_evpn_rem_macip_del(w->vni, &w->macaddr, ipa_len,
2436 &w->ip, w->vtep_ip);
2437 } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_VTEP) {
2438 if (w->add_p)
2439 zebra_vxlan_remote_vtep_add(w->vrf_id, w->vni,
2440 w->vtep_ip, w->flags);
2441 else
2442 zebra_vxlan_remote_vtep_del(w->vrf_id, w->vni,
2443 w->vtep_ip);
2444 }
2445
2446
2447 XFREE(MTYPE_WQ_WRAPPER, w);
2448 }
2449
2450 /*
2451 * Process the nexthop-group workqueue subqueue
2452 */
2453 static void process_subq_nhg(struct listnode *lnode)
2454 {
2455 struct nhg_ctx *ctx;
2456 struct nhg_hash_entry *nhe, *newnhe;
2457 struct wq_nhg_wrapper *w;
2458 uint8_t qindex = META_QUEUE_NHG;
2459
2460 w = listgetdata(lnode);
2461
2462 if (!w)
2463 return;
2464
2465 /* Two types of object - an update from the local kernel, or
2466 * an nhg update from a daemon.
2467 */
2468 if (w->type == WQ_NHG_WRAPPER_TYPE_CTX) {
2469 ctx = w->u.ctx;
2470
2471 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2472 zlog_debug(
2473 "NHG Context id=%u dequeued from sub-queue %s",
2474 ctx->id, subqueue2str(qindex));
2475
2476
2477 /* Process nexthop group updates coming 'up' from the OS */
2478 nhg_ctx_process(ctx);
2479
2480 } else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG) {
2481 nhe = w->u.nhe;
2482
2483 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2484 zlog_debug("NHG %u dequeued from sub-queue %s", nhe->id,
2485 subqueue2str(qindex));
2486
2487 /* Process incoming nhg update, probably from a proto daemon */
2488 newnhe = zebra_nhg_proto_add(nhe->id, nhe->type,
2489 nhe->zapi_instance,
2490 nhe->zapi_session, &nhe->nhg, 0);
2491
2492 /* Report error to daemon via ZAPI */
2493 if (newnhe == NULL)
2494 zsend_nhg_notify(nhe->type, nhe->zapi_instance,
2495 nhe->zapi_session, nhe->id,
2496 ZAPI_NHG_FAIL_INSTALL);
2497
2498 /* Free temp nhe - we own that memory. */
2499 zebra_nhg_free(nhe);
2500 }
2501
2502 XFREE(MTYPE_WQ_WRAPPER, w);
2503 }
2504
2505 static void process_subq_early_label(struct listnode *lnode)
2506 {
2507 struct wq_label_wrapper *w = listgetdata(lnode);
2508 struct zebra_vrf *zvrf;
2509
2510 if (!w)
2511 return;
2512
2513 zvrf = vrf_info_lookup(w->vrf_id);
2514 if (!zvrf) {
2515 XFREE(MTYPE_WQ_WRAPPER, w);
2516 return;
2517 }
2518
2519 switch (w->type) {
2520 case WQ_LABEL_FTN_UNINSTALL:
2521 zebra_mpls_ftn_uninstall(zvrf, w->ltype, &w->p, w->route_type,
2522 w->route_instance);
2523 break;
2524 case WQ_LABEL_LABELS_PROCESS:
2525 zebra_mpls_zapi_labels_process(w->add_p, zvrf, &w->zl);
2526 break;
2527 }
2528
2529 XFREE(MTYPE_WQ_WRAPPER, w);
2530 }
2531
2532 static void process_subq_route(struct listnode *lnode, uint8_t qindex)
2533 {
2534 struct route_node *rnode = NULL;
2535 rib_dest_t *dest = NULL;
2536 struct zebra_vrf *zvrf = NULL;
2537
2538 rnode = listgetdata(lnode);
2539 dest = rib_dest_from_rnode(rnode);
2540 assert(dest);
2541
2542 zvrf = rib_dest_vrf(dest);
2543
2544 rib_process(rnode);
2545
2546 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
2547 struct route_entry *re = NULL;
2548
2549 /*
2550 * rib_process may have freed the dest
2551 * as part of the garbage collection. Let's
2552 * prevent stupidity from happening.
2553 */
2554 dest = rib_dest_from_rnode(rnode);
2555 if (dest)
2556 re = re_list_first(&dest->routes);
2557
2558 zlog_debug("%s(%u:%u):%pRN rn %p dequeued from sub-queue %s",
2559 zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0,
2560 rnode, rnode, subqueue2str(qindex));
2561 }
2562
2563 if (rnode->info)
2564 UNSET_FLAG(rib_dest_from_rnode(rnode)->flags,
2565 RIB_ROUTE_QUEUED(qindex));
2566
2567 route_unlock_node(rnode);
2568 }
2569
2570 static void rib_re_nhg_free(struct route_entry *re)
2571 {
2572 if (re->nhe && re->nhe_id) {
2573 assert(re->nhe->id == re->nhe_id);
2574 route_entry_update_nhe(re, NULL);
2575 } else if (re->nhe && re->nhe->nhg.nexthop)
2576 nexthops_free(re->nhe->nhg.nexthop);
2577
2578 nexthops_free(re->fib_ng.nexthop);
2579 }
2580
2581 struct zebra_early_route {
2582 afi_t afi;
2583 safi_t safi;
2584 struct prefix p;
2585 struct prefix_ipv6 src_p;
2586 bool src_p_provided;
2587 struct route_entry *re;
2588 struct nhg_hash_entry *re_nhe;
2589 bool startup;
2590 bool deletion;
2591 bool fromkernel;
2592 };
2593
2594 static void early_route_memory_free(struct zebra_early_route *ere)
2595 {
2596 if (ere->re_nhe)
2597 zebra_nhg_free(ere->re_nhe);
2598
2599 XFREE(MTYPE_RE, ere->re);
2600 XFREE(MTYPE_WQ_WRAPPER, ere);
2601 }
2602
2603 static void process_subq_early_route_add(struct zebra_early_route *ere)
2604 {
2605 struct route_entry *re = ere->re;
2606 struct route_table *table;
2607 struct nhg_hash_entry *nhe = NULL;
2608 struct route_node *rn;
2609 struct route_entry *same = NULL, *first_same = NULL;
2610 int same_count = 0;
2611 rib_dest_t *dest;
2612
2613 /* Lookup table. */
2614 table = zebra_vrf_get_table_with_table_id(ere->afi, ere->safi,
2615 re->vrf_id, re->table);
2616 if (!table) {
2617 early_route_memory_free(ere);
2618 return;
2619 }
2620
2621 if (re->nhe_id > 0) {
2622 nhe = zebra_nhg_lookup_id(re->nhe_id);
2623
2624 if (!nhe) {
2625 /*
2626 * We've received from the kernel a nexthop id
2627 * that we don't have saved yet. More than likely
2628 * it has not been processed and is on the
2629 * queue to be processed. Let's stop what we
2630 * are doing and cause the meta q to be processed
2631 * storing this for later.
2632 *
2633 * This is being done this way because zebra
2634 * runs with the assumption t
2635 */
2636 flog_err(
2637 EC_ZEBRA_TABLE_LOOKUP_FAILED,
2638 "Zebra failed to find the nexthop hash entry for id=%u in a route entry %pFX",
2639 re->nhe_id, &ere->p);
2640
2641 early_route_memory_free(ere);
2642 return;
2643 }
2644 } else {
2645 /* Lookup nhe from route information */
2646 nhe = zebra_nhg_rib_find_nhe(ere->re_nhe, ere->afi);
2647 if (!nhe) {
2648 char buf2[PREFIX_STRLEN] = "";
2649
2650 flog_err(
2651 EC_ZEBRA_TABLE_LOOKUP_FAILED,
2652 "Zebra failed to find or create a nexthop hash entry for %pFX%s%s",
2653 &ere->p, ere->src_p_provided ? " from " : "",
2654 ere->src_p_provided
2655 ? prefix2str(&ere->src_p, buf2,
2656 sizeof(buf2))
2657 : "");
2658
2659 early_route_memory_free(ere);
2660 return;
2661 }
2662 }
2663
2664 /*
2665 * Attach the re to the nhe's nexthop group.
2666 *
2667 * TODO: This will need to change when we start getting IDs from upper
2668 * level protocols, as the refcnt might be wrong, since it checks
2669 * if old_id != new_id.
2670 */
2671 route_entry_update_nhe(re, nhe);
2672
2673 /* Make it sure prefixlen is applied to the prefix. */
2674 apply_mask(&ere->p);
2675 if (ere->src_p_provided)
2676 apply_mask_ipv6(&ere->src_p);
2677
2678 /* Set default distance by route type. */
2679 if (re->distance == 0)
2680 re->distance = route_distance(re->type);
2681
2682 /* Lookup route node.*/
2683 rn = srcdest_rnode_get(table, &ere->p,
2684 ere->src_p_provided ? &ere->src_p : NULL);
2685
2686 /*
2687 * If same type of route are installed, treat it as a implicit
2688 * withdraw. If the user has specified the No route replace semantics
2689 * for the install don't do a route replace.
2690 */
2691 RNODE_FOREACH_RE (rn, same) {
2692 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) {
2693 same_count++;
2694 continue;
2695 }
2696
2697 /* Compare various route_entry properties */
2698 if (rib_compare_routes(re, same)) {
2699 same_count++;
2700
2701 if (first_same == NULL)
2702 first_same = same;
2703 }
2704 }
2705
2706 same = first_same;
2707
2708 if (!ere->startup && (re->flags & ZEBRA_FLAG_SELFROUTE) &&
2709 zrouter.asic_offloaded) {
2710 if (!same) {
2711 if (IS_ZEBRA_DEBUG_RIB)
2712 zlog_debug(
2713 "prefix: %pRN is a self route where we do not have an entry for it. Dropping this update, it's useless",
2714 rn);
2715 /*
2716 * We are not on startup, this is a self route
2717 * and we have asic offload. Which means
2718 * we are getting a callback for a entry
2719 * that was already deleted to the kernel
2720 * but an earlier response was just handed
2721 * back. Drop it on the floor
2722 */
2723 early_route_memory_free(ere);
2724 return;
2725 }
2726 }
2727
2728 /* If this route is kernel/connected route, notify the dataplane. */
2729 if (RIB_SYSTEM_ROUTE(re)) {
2730 /* Notify dataplane */
2731 dplane_sys_route_add(rn, re);
2732 }
2733
2734 /* Link new re to node.*/
2735 if (IS_ZEBRA_DEBUG_RIB) {
2736 rnode_debug(
2737 rn, re->vrf_id,
2738 "Inserting route rn %p, re %p (%s) existing %p, same_count %d",
2739 rn, re, zebra_route_string(re->type), same, same_count);
2740
2741 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2742 route_entry_dump(
2743 &ere->p,
2744 ere->src_p_provided ? &ere->src_p : NULL, re);
2745 }
2746
2747 SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
2748 rib_addnode(rn, re, 1);
2749
2750 /* Free implicit route.*/
2751 if (same)
2752 rib_delnode(rn, same);
2753
2754 /* See if we can remove some RE entries that are queued for
2755 * removal, but won't be considered in rib processing.
2756 */
2757 dest = rib_dest_from_rnode(rn);
2758 RNODE_FOREACH_RE_SAFE (rn, re, same) {
2759 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
2760 /* If the route was used earlier, must retain it. */
2761 if (dest && re == dest->selected_fib)
2762 continue;
2763
2764 if (IS_ZEBRA_DEBUG_RIB)
2765 rnode_debug(rn, re->vrf_id,
2766 "rn %p, removing unneeded re %p",
2767 rn, re);
2768
2769 rib_unlink(rn, re);
2770 }
2771 }
2772
2773 route_unlock_node(rn);
2774 if (ere->re_nhe)
2775 zebra_nhg_free(ere->re_nhe);
2776 XFREE(MTYPE_WQ_WRAPPER, ere);
2777 }
2778
2779 static void process_subq_early_route_delete(struct zebra_early_route *ere)
2780 {
2781 struct route_table *table;
2782 struct route_node *rn;
2783 struct route_entry *re;
2784 struct route_entry *fib = NULL;
2785 struct route_entry *same = NULL;
2786 struct nexthop *rtnh;
2787 char buf2[INET6_ADDRSTRLEN];
2788 rib_dest_t *dest;
2789
2790 if (ere->src_p_provided)
2791 assert(!ere->src_p.prefixlen || ere->afi == AFI_IP6);
2792
2793 /* Lookup table. */
2794 table = zebra_vrf_lookup_table_with_table_id(
2795 ere->afi, ere->safi, ere->re->vrf_id, ere->re->table);
2796 if (!table) {
2797 early_route_memory_free(ere);
2798 return;
2799 }
2800
2801 /* Apply mask. */
2802 apply_mask(&ere->p);
2803 if (ere->src_p_provided)
2804 apply_mask_ipv6(&ere->src_p);
2805
2806 /* Lookup route node. */
2807 rn = srcdest_rnode_lookup(table, &ere->p,
2808 ere->src_p_provided ? &ere->src_p : NULL);
2809 if (!rn) {
2810 if (IS_ZEBRA_DEBUG_RIB) {
2811 char src_buf[PREFIX_STRLEN];
2812 struct vrf *vrf = vrf_lookup_by_id(ere->re->vrf_id);
2813
2814 if (ere->src_p_provided && ere->src_p.prefixlen)
2815 prefix2str(&ere->src_p, src_buf,
2816 sizeof(src_buf));
2817 else
2818 src_buf[0] = '\0';
2819
2820 zlog_debug("%s[%d]:%pRN%s%s doesn't exist in rib",
2821 vrf->name, ere->re->table, rn,
2822 (src_buf[0] != '\0') ? " from " : "",
2823 src_buf);
2824 }
2825 early_route_memory_free(ere);
2826 return;
2827 }
2828
2829 dest = rib_dest_from_rnode(rn);
2830 fib = dest->selected_fib;
2831
2832 struct nexthop *nh = NULL;
2833
2834 if (ere->re->nhe)
2835 nh = ere->re->nhe->nhg.nexthop;
2836
2837 /* Lookup same type route. */
2838 RNODE_FOREACH_RE (rn, re) {
2839 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
2840 continue;
2841
2842 if (re->type != ere->re->type)
2843 continue;
2844 if (re->instance != ere->re->instance)
2845 continue;
2846 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
2847 ere->re->distance != re->distance)
2848 continue;
2849
2850 if (re->type == ZEBRA_ROUTE_KERNEL &&
2851 re->metric != ere->re->metric)
2852 continue;
2853 if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = nh) &&
2854 rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
2855 if (rtnh->ifindex != nh->ifindex)
2856 continue;
2857 same = re;
2858 break;
2859 }
2860
2861 /* Make sure that the route found has the same gateway. */
2862 if (ere->re->nhe_id && re->nhe_id == ere->re->nhe_id) {
2863 same = re;
2864 break;
2865 }
2866
2867 if (nh == NULL) {
2868 same = re;
2869 break;
2870 }
2871 for (ALL_NEXTHOPS(re->nhe->nhg, rtnh)) {
2872 /*
2873 * No guarantee all kernel send nh with labels
2874 * on delete.
2875 */
2876 if (nexthop_same_no_labels(rtnh, nh)) {
2877 same = re;
2878 break;
2879 }
2880 }
2881
2882 if (same)
2883 break;
2884 }
2885 /*
2886 * If same type of route can't be found and this message is from
2887 * kernel.
2888 */
2889 if (!same) {
2890 /*
2891 * In the past(HA!) we could get here because
2892 * we were receiving a route delete from the
2893 * kernel and we're not marking the proto
2894 * as coming from it's appropriate originator.
2895 * Now that we are properly noticing the fact
2896 * that the kernel has deleted our route we
2897 * are not going to get called in this path
2898 * I am going to leave this here because
2899 * this might still work this way on non-linux
2900 * platforms as well as some weird state I have
2901 * not properly thought of yet.
2902 * If we can show that this code path is
2903 * dead then we can remove it.
2904 */
2905 if (fib && CHECK_FLAG(ere->re->flags, ZEBRA_FLAG_SELFROUTE)) {
2906 if (IS_ZEBRA_DEBUG_RIB) {
2907 rnode_debug(
2908 rn, ere->re->vrf_id,
2909 "rn %p, re %p (%s) was deleted from kernel, adding",
2910 rn, fib, zebra_route_string(fib->type));
2911 }
2912 if (zrouter.allow_delete ||
2913 CHECK_FLAG(dest->flags, RIB_ROUTE_ANY_QUEUED)) {
2914 UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
2915 /* Unset flags. */
2916 for (rtnh = fib->nhe->nhg.nexthop; rtnh;
2917 rtnh = rtnh->next)
2918 UNSET_FLAG(rtnh->flags,
2919 NEXTHOP_FLAG_FIB);
2920
2921 /*
2922 * This is a non FRR route
2923 * as such we should mark
2924 * it as deleted
2925 */
2926 dest->selected_fib = NULL;
2927 } else {
2928 /*
2929 * This means someone else, other than Zebra,
2930 * has deleted a Zebra router from the kernel.
2931 * We will add it back
2932 */
2933 rib_install_kernel(rn, fib, NULL);
2934 }
2935 } else {
2936 if (IS_ZEBRA_DEBUG_RIB) {
2937 if (nh)
2938 rnode_debug(
2939 rn, ere->re->vrf_id,
2940 "via %s ifindex %d type %d doesn't exist in rib",
2941 inet_ntop(afi2family(ere->afi),
2942 &nh->gate, buf2,
2943 sizeof(buf2)),
2944 nh->ifindex, ere->re->type);
2945 else
2946 rnode_debug(
2947 rn, ere->re->vrf_id,
2948 "type %d doesn't exist in rib",
2949 ere->re->type);
2950 }
2951 route_unlock_node(rn);
2952 early_route_memory_free(ere);
2953 return;
2954 }
2955 }
2956
2957 if (same) {
2958 struct nexthop *tmp_nh;
2959
2960 if (ere->fromkernel &&
2961 CHECK_FLAG(ere->re->flags, ZEBRA_FLAG_SELFROUTE) &&
2962 !zrouter.allow_delete) {
2963 rib_install_kernel(rn, same, NULL);
2964 route_unlock_node(rn);
2965
2966 early_route_memory_free(ere);
2967 return;
2968 }
2969
2970 /* Special handling for IPv4 or IPv6 routes sourced from
2971 * EVPN - the nexthop (and associated MAC) need to be
2972 * uninstalled if no more refs.
2973 */
2974 for (ALL_NEXTHOPS(re->nhe->nhg, tmp_nh)) {
2975 struct ipaddr vtep_ip;
2976
2977 if (CHECK_FLAG(tmp_nh->flags, NEXTHOP_FLAG_EVPN)) {
2978 memset(&vtep_ip, 0, sizeof(struct ipaddr));
2979 if (ere->afi == AFI_IP) {
2980 vtep_ip.ipa_type = IPADDR_V4;
2981 memcpy(&(vtep_ip.ipaddr_v4),
2982 &(tmp_nh->gate.ipv4),
2983 sizeof(struct in_addr));
2984 } else {
2985 vtep_ip.ipa_type = IPADDR_V6;
2986 memcpy(&(vtep_ip.ipaddr_v6),
2987 &(tmp_nh->gate.ipv6),
2988 sizeof(struct in6_addr));
2989 }
2990 zebra_rib_queue_evpn_route_del(
2991 re->vrf_id, &vtep_ip, &ere->p);
2992 }
2993 }
2994
2995 /* Notify dplane if system route changes */
2996 if (RIB_SYSTEM_ROUTE(re))
2997 dplane_sys_route_del(rn, same);
2998
2999 rib_delnode(rn, same);
3000 }
3001
3002 route_unlock_node(rn);
3003
3004 early_route_memory_free(ere);
3005 }
3006
3007 /*
3008 * When FRR receives a route we need to match the route up to
3009 * nexthop groups. That we also may have just received
3010 * place the data on this queue so that this work of finding
3011 * the nexthop group entries for the route entry is always
3012 * done after the nexthop group has had a chance to be processed
3013 */
3014 static void process_subq_early_route(struct listnode *lnode)
3015 {
3016 struct zebra_early_route *ere = listgetdata(lnode);
3017
3018 if (ere->deletion)
3019 process_subq_early_route_delete(ere);
3020 else
3021 process_subq_early_route_add(ere);
3022 }
3023
3024 /*
3025 * Examine the specified subqueue; process one entry and return 1 if
3026 * there is a node, return 0 otherwise.
3027 */
3028 static unsigned int process_subq(struct list *subq,
3029 enum meta_queue_indexes qindex)
3030 {
3031 struct listnode *lnode = listhead(subq);
3032
3033 if (!lnode)
3034 return 0;
3035
3036 switch (qindex) {
3037 case META_QUEUE_EVPN:
3038 process_subq_evpn(lnode);
3039 break;
3040 case META_QUEUE_NHG:
3041 process_subq_nhg(lnode);
3042 break;
3043 case META_QUEUE_EARLY_ROUTE:
3044 process_subq_early_route(lnode);
3045 break;
3046 case META_QUEUE_EARLY_LABEL:
3047 process_subq_early_label(lnode);
3048 break;
3049 case META_QUEUE_CONNECTED:
3050 case META_QUEUE_KERNEL:
3051 case META_QUEUE_STATIC:
3052 case META_QUEUE_NOTBGP:
3053 case META_QUEUE_BGP:
3054 case META_QUEUE_OTHER:
3055 process_subq_route(lnode, qindex);
3056 break;
3057 }
3058
3059 list_delete_node(subq, lnode);
3060
3061 return 1;
3062 }
3063
3064 /* Dispatch the meta queue by picking and processing the next node from
3065 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
3066 * data is pointed to the meta queue structure.
3067 */
3068 static wq_item_status meta_queue_process(struct work_queue *dummy, void *data)
3069 {
3070 struct meta_queue *mq = data;
3071 unsigned i;
3072 uint32_t queue_len, queue_limit;
3073
3074 /* Ensure there's room for more dataplane updates */
3075 queue_limit = dplane_get_in_queue_limit();
3076 queue_len = dplane_get_in_queue_len();
3077 if (queue_len > queue_limit) {
3078 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3079 zlog_debug(
3080 "rib queue: dplane queue len %u, limit %u, retrying",
3081 queue_len, queue_limit);
3082
3083 /* Ensure that the meta-queue is actually enqueued */
3084 if (work_queue_empty(zrouter.ribq))
3085 work_queue_add(zrouter.ribq, zrouter.mq);
3086
3087 return WQ_QUEUE_BLOCKED;
3088 }
3089
3090 for (i = 0; i < MQ_SIZE; i++)
3091 if (process_subq(mq->subq[i], i)) {
3092 mq->size--;
3093 break;
3094 }
3095 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
3096 }
3097
3098
3099 /*
3100 * Look into the RN and queue it into the highest priority queue
3101 * at this point in time for processing.
3102 *
3103 * We will enqueue a route node only once per invocation.
3104 *
3105 * There are two possibilities here that should be kept in mind.
3106 * If the original invocation has not been pulled off for processing
3107 * yet, A subsuquent invocation can have a route entry with a better
3108 * meta queue index value and we can have a situation where
3109 * we might have the same node enqueued 2 times. Not necessarily
3110 * an optimal situation but it should be ok.
3111 *
3112 * The other possibility is that the original invocation has not
3113 * been pulled off for processing yet, A subsusquent invocation
3114 * doesn't have a route_entry with a better meta-queue and the
3115 * original metaqueue index value will win and we'll end up with
3116 * the route node enqueued once.
3117 */
3118 static int rib_meta_queue_add(struct meta_queue *mq, void *data)
3119 {
3120 struct route_node *rn = NULL;
3121 struct route_entry *re = NULL, *curr_re = NULL;
3122 uint8_t qindex = MQ_SIZE, curr_qindex = MQ_SIZE;
3123
3124 rn = (struct route_node *)data;
3125
3126 RNODE_FOREACH_RE (rn, curr_re) {
3127 curr_qindex = route_info[curr_re->type].meta_q_map;
3128
3129 if (curr_qindex <= qindex) {
3130 re = curr_re;
3131 qindex = curr_qindex;
3132 }
3133 }
3134
3135 if (!re)
3136 return -1;
3137
3138 /* Invariant: at this point we always have rn->info set. */
3139 if (CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
3140 RIB_ROUTE_QUEUED(qindex))) {
3141 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3142 rnode_debug(rn, re->vrf_id,
3143 "rn %p is already queued in sub-queue %s",
3144 (void *)rn, subqueue2str(qindex));
3145 return -1;
3146 }
3147
3148 SET_FLAG(rib_dest_from_rnode(rn)->flags, RIB_ROUTE_QUEUED(qindex));
3149 listnode_add(mq->subq[qindex], rn);
3150 route_lock_node(rn);
3151 mq->size++;
3152
3153 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3154 rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s",
3155 (void *)rn, subqueue2str(qindex));
3156
3157 return 0;
3158 }
3159
3160 static int early_label_meta_queue_add(struct meta_queue *mq, void *data)
3161 {
3162 listnode_add(mq->subq[META_QUEUE_EARLY_LABEL], data);
3163 mq->size++;
3164 return 0;
3165 }
3166
3167 static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
3168 {
3169 struct nhg_ctx *ctx = NULL;
3170 uint8_t qindex = META_QUEUE_NHG;
3171 struct wq_nhg_wrapper *w;
3172
3173 ctx = (struct nhg_ctx *)data;
3174
3175 if (!ctx)
3176 return -1;
3177
3178 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper));
3179
3180 w->type = WQ_NHG_WRAPPER_TYPE_CTX;
3181 w->u.ctx = ctx;
3182
3183 listnode_add(mq->subq[qindex], w);
3184 mq->size++;
3185
3186 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3187 zlog_debug("NHG Context id=%u queued into sub-queue %s",
3188 ctx->id, subqueue2str(qindex));
3189
3190 return 0;
3191 }
3192
3193 static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data)
3194 {
3195 struct nhg_hash_entry *nhe = NULL;
3196 uint8_t qindex = META_QUEUE_NHG;
3197 struct wq_nhg_wrapper *w;
3198
3199 nhe = (struct nhg_hash_entry *)data;
3200
3201 if (!nhe)
3202 return -1;
3203
3204 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper));
3205
3206 w->type = WQ_NHG_WRAPPER_TYPE_NHG;
3207 w->u.nhe = nhe;
3208
3209 listnode_add(mq->subq[qindex], w);
3210 mq->size++;
3211
3212 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3213 zlog_debug("NHG id=%u queued into sub-queue %s", nhe->id,
3214 subqueue2str(qindex));
3215
3216 return 0;
3217 }
3218
3219 static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data)
3220 {
3221 listnode_add(mq->subq[META_QUEUE_EVPN], data);
3222 mq->size++;
3223
3224 return 0;
3225 }
3226
3227 static int mq_add_handler(void *data,
3228 int (*mq_add_func)(struct meta_queue *mq, void *data))
3229 {
3230 if (zrouter.ribq == NULL) {
3231 flog_err(EC_ZEBRA_WQ_NONEXISTENT,
3232 "%s: work_queue does not exist!", __func__);
3233 return -1;
3234 }
3235
3236 /*
3237 * The RIB queue should normally be either empty or holding the only
3238 * work_queue_item element. In the latter case this element would
3239 * hold a pointer to the meta queue structure, which must be used to
3240 * actually queue the route nodes to process. So create the MQ
3241 * holder, if necessary, then push the work into it in any case.
3242 * This semantics was introduced after 0.99.9 release.
3243 */
3244 if (work_queue_empty(zrouter.ribq))
3245 work_queue_add(zrouter.ribq, zrouter.mq);
3246
3247 return mq_add_func(zrouter.mq, data);
3248 }
3249
3250 void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
3251 struct prefix *prefix, uint8_t route_type,
3252 uint8_t route_instance)
3253 {
3254 struct wq_label_wrapper *w;
3255
3256 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_label_wrapper));
3257
3258 w->type = WQ_LABEL_FTN_UNINSTALL;
3259 w->vrf_id = zvrf->vrf->vrf_id;
3260 w->p = *prefix;
3261 w->ltype = type;
3262 w->route_type = route_type;
3263 w->route_instance = route_instance;
3264
3265 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3266 zlog_debug("Early Label Handling for %pFX", prefix);
3267
3268 mq_add_handler(w, early_label_meta_queue_add);
3269 }
3270
3271 void mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
3272 const struct zapi_labels *zl)
3273 {
3274 struct wq_label_wrapper *w;
3275
3276 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_label_wrapper));
3277 w->type = WQ_LABEL_LABELS_PROCESS;
3278 w->vrf_id = zvrf->vrf->vrf_id;
3279 w->add_p = add_p;
3280 w->zl = *zl;
3281
3282 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3283 zlog_debug("Early Label Handling: Labels Process");
3284
3285 mq_add_handler(w, early_label_meta_queue_add);
3286 }
3287
3288 /* Add route_node to work queue and schedule processing */
3289 int rib_queue_add(struct route_node *rn)
3290 {
3291 assert(rn);
3292
3293 /* Pointless to queue a route_node with no RIB entries to add or remove
3294 */
3295 if (!rnode_to_ribs(rn)) {
3296 zlog_debug("%s: called for route_node (%p, %u) with no ribs",
3297 __func__, (void *)rn, route_node_get_lock_count(rn));
3298 zlog_backtrace(LOG_DEBUG);
3299 return -1;
3300 }
3301
3302 return mq_add_handler(rn, rib_meta_queue_add);
3303 }
3304
3305 /*
3306 * Enqueue incoming nhg info from OS for processing
3307 */
3308 int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx)
3309 {
3310 assert(ctx);
3311
3312 return mq_add_handler(ctx, rib_meta_queue_nhg_ctx_add);
3313 }
3314
3315 /*
3316 * Enqueue incoming nhg from proto daemon for processing
3317 */
3318 int rib_queue_nhe_add(struct nhg_hash_entry *nhe)
3319 {
3320 if (nhe == NULL)
3321 return -1;
3322
3323 return mq_add_handler(nhe, rib_meta_queue_nhg_add);
3324 }
3325
3326 /*
3327 * Enqueue evpn route for processing
3328 */
3329 int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
3330 const struct ipaddr *vtep_ip,
3331 const struct prefix *host_prefix)
3332 {
3333 struct wq_evpn_wrapper *w;
3334
3335 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3336
3337 w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE;
3338 w->add_p = true;
3339 w->vrf_id = vrf_id;
3340 w->macaddr = *rmac;
3341 w->ip = *vtep_ip;
3342 w->prefix = *host_prefix;
3343
3344 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3345 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__,
3346 vrf_id, vtep_ip, host_prefix);
3347
3348 return mq_add_handler(w, rib_meta_queue_evpn_add);
3349 }
3350
3351 int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id,
3352 const struct ipaddr *vtep_ip,
3353 const struct prefix *host_prefix)
3354 {
3355 struct wq_evpn_wrapper *w;
3356
3357 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3358
3359 w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE;
3360 w->add_p = false;
3361 w->vrf_id = vrf_id;
3362 w->ip = *vtep_ip;
3363 w->prefix = *host_prefix;
3364
3365 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3366 zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__,
3367 vrf_id, vtep_ip, host_prefix);
3368
3369 return mq_add_handler(w, rib_meta_queue_evpn_add);
3370 }
3371
3372 /* Enqueue EVPN remote ES for processing */
3373 int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi,
3374 const struct in_addr *vtep_ip,
3375 bool esr_rxed, uint8_t df_alg,
3376 uint16_t df_pref)
3377 {
3378 struct wq_evpn_wrapper *w;
3379 char buf[ESI_STR_LEN];
3380
3381 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3382
3383 w->type = WQ_EVPN_WRAPPER_TYPE_REM_ES;
3384 w->add_p = true;
3385 w->esi = *esi;
3386 w->ip.ipa_type = IPADDR_V4;
3387 w->ip.ipaddr_v4 = *vtep_ip;
3388 w->esr_rxed = esr_rxed;
3389 w->df_alg = df_alg;
3390 w->df_pref = df_pref;
3391
3392 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3393 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__, vtep_ip,
3394 esi_to_str(esi, buf, sizeof(buf)));
3395
3396 return mq_add_handler(w, rib_meta_queue_evpn_add);
3397 }
3398
3399 int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
3400 const struct in_addr *vtep_ip)
3401 {
3402 struct wq_evpn_wrapper *w;
3403 char buf[ESI_STR_LEN];
3404
3405 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3406
3407 w->type = WQ_EVPN_WRAPPER_TYPE_REM_ES;
3408 w->add_p = false;
3409 w->esi = *esi;
3410 w->ip.ipa_type = IPADDR_V4;
3411 w->ip.ipaddr_v4 = *vtep_ip;
3412
3413 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
3414 if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0)
3415 esi_to_str(esi, buf, sizeof(buf));
3416 else
3417 strlcpy(buf, "-", sizeof(buf));
3418
3419 zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__, vtep_ip,
3420 buf);
3421 }
3422
3423 return mq_add_handler(w, rib_meta_queue_evpn_add);
3424 }
3425
3426 /*
3427 * Enqueue EVPN remote macip update for processing
3428 */
3429 int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
3430 const struct ipaddr *ipaddr,
3431 uint8_t flags, uint32_t seq,
3432 struct in_addr vtep_ip, const esi_t *esi)
3433 {
3434 struct wq_evpn_wrapper *w;
3435 char buf[ESI_STR_LEN];
3436
3437 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3438
3439 w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
3440 w->add_p = true;
3441 w->vni = vni;
3442 w->macaddr = *macaddr;
3443 w->ip = *ipaddr;
3444 w->flags = flags;
3445 w->seq = seq;
3446 w->vtep_ip = vtep_ip;
3447 w->esi = *esi;
3448
3449 if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
3450 if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0)
3451 esi_to_str(esi, buf, sizeof(buf));
3452 else
3453 strlcpy(buf, "-", sizeof(buf));
3454
3455 zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__,
3456 macaddr, &vtep_ip, buf);
3457 }
3458
3459 return mq_add_handler(w, rib_meta_queue_evpn_add);
3460 }
3461
3462 int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
3463 const struct ipaddr *ip,
3464 struct in_addr vtep_ip)
3465 {
3466 struct wq_evpn_wrapper *w;
3467
3468 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3469
3470 w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
3471 w->add_p = false;
3472 w->vni = vni;
3473 w->macaddr = *macaddr;
3474 w->ip = *ip;
3475 w->vtep_ip = vtep_ip;
3476
3477 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3478 zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__,
3479 macaddr, &vtep_ip);
3480
3481 return mq_add_handler(w, rib_meta_queue_evpn_add);
3482 }
3483
3484 /*
3485 * Enqueue remote VTEP address for processing
3486 */
3487 int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
3488 struct in_addr vtep_ip, int flood_control)
3489 {
3490 struct wq_evpn_wrapper *w;
3491
3492 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3493
3494 w->type = WQ_EVPN_WRAPPER_TYPE_REM_VTEP;
3495 w->add_p = true;
3496 w->vrf_id = vrf_id;
3497 w->vni = vni;
3498 w->vtep_ip = vtep_ip;
3499 w->flags = flood_control;
3500
3501 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3502 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id,
3503 &vtep_ip);
3504
3505 return mq_add_handler(w, rib_meta_queue_evpn_add);
3506 }
3507
3508 int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
3509 struct in_addr vtep_ip)
3510 {
3511 struct wq_evpn_wrapper *w;
3512
3513 w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
3514
3515 w->type = WQ_EVPN_WRAPPER_TYPE_REM_VTEP;
3516 w->add_p = false;
3517 w->vrf_id = vrf_id;
3518 w->vni = vni;
3519 w->vtep_ip = vtep_ip;
3520
3521 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3522 zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id,
3523 &vtep_ip);
3524
3525 return mq_add_handler(w, rib_meta_queue_evpn_add);
3526 }
3527
3528 /* Create new meta queue.
3529 A destructor function doesn't seem to be necessary here.
3530 */
3531 static struct meta_queue *meta_queue_new(void)
3532 {
3533 struct meta_queue *new;
3534 unsigned i;
3535
3536 new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
3537
3538 for (i = 0; i < MQ_SIZE; i++) {
3539 new->subq[i] = list_new();
3540 assert(new->subq[i]);
3541 }
3542
3543 return new;
3544 }
3545
3546 /* Clean up the EVPN meta-queue list */
3547 static void evpn_meta_queue_free(struct meta_queue *mq, struct list *l,
3548 struct zebra_vrf *zvrf)
3549 {
3550 struct listnode *node, *nnode;
3551 struct wq_evpn_wrapper *w;
3552
3553 /* Free the node wrapper object, and the struct it wraps */
3554 for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
3555 if (zvrf) {
3556 vrf_id_t vrf_id = zvrf->vrf->vrf_id;
3557
3558 if (w->vrf_id != vrf_id)
3559 continue;
3560 }
3561
3562 node->data = NULL;
3563
3564 XFREE(MTYPE_WQ_WRAPPER, w);
3565
3566 list_delete_node(l, node);
3567 mq->size--;
3568 }
3569 }
3570
3571 /* Clean up the nhg meta-queue list */
3572 static void nhg_meta_queue_free(struct meta_queue *mq, struct list *l,
3573 struct zebra_vrf *zvrf)
3574 {
3575 struct wq_nhg_wrapper *w;
3576 struct listnode *node, *nnode;
3577
3578 /* Free the node wrapper object, and the struct it wraps */
3579 for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
3580 if (zvrf) {
3581 vrf_id_t vrf_id = zvrf->vrf->vrf_id;
3582
3583 if (w->type == WQ_NHG_WRAPPER_TYPE_CTX &&
3584 w->u.ctx->vrf_id != vrf_id)
3585 continue;
3586 else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG &&
3587 w->u.nhe->vrf_id != vrf_id)
3588 continue;
3589 }
3590 if (w->type == WQ_NHG_WRAPPER_TYPE_CTX)
3591 nhg_ctx_free(&w->u.ctx);
3592 else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG)
3593 zebra_nhg_free(w->u.nhe);
3594
3595 node->data = NULL;
3596 XFREE(MTYPE_WQ_WRAPPER, w);
3597
3598 list_delete_node(l, node);
3599 mq->size--;
3600 }
3601 }
3602
3603 static void early_label_meta_queue_free(struct meta_queue *mq, struct list *l,
3604 struct zebra_vrf *zvrf)
3605 {
3606 struct wq_label_wrapper *w;
3607 struct listnode *node, *nnode;
3608
3609 for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
3610 if (zvrf && zvrf->vrf->vrf_id != w->vrf_id)
3611 continue;
3612
3613 switch (w->type) {
3614 case WQ_LABEL_FTN_UNINSTALL:
3615 case WQ_LABEL_LABELS_PROCESS:
3616 break;
3617 }
3618
3619 node->data = NULL;
3620 XFREE(MTYPE_WQ_WRAPPER, w);
3621 list_delete_node(l, node);
3622 mq->size--;
3623 }
3624 }
3625
3626 static void rib_meta_queue_free(struct meta_queue *mq, struct list *l,
3627 struct zebra_vrf *zvrf)
3628 {
3629 struct route_node *rnode;
3630 struct listnode *node, *nnode;
3631
3632 for (ALL_LIST_ELEMENTS(l, node, nnode, rnode)) {
3633 rib_dest_t *dest = rib_dest_from_rnode(rnode);
3634
3635 if (dest && rib_dest_vrf(dest) != zvrf)
3636 continue;
3637
3638 route_unlock_node(rnode);
3639 node->data = NULL;
3640 list_delete_node(l, node);
3641 mq->size--;
3642 }
3643 }
3644
3645 static void early_route_meta_queue_free(struct meta_queue *mq, struct list *l,
3646 struct zebra_vrf *zvrf)
3647 {
3648 struct zebra_early_route *zer;
3649 struct listnode *node, *nnode;
3650
3651 for (ALL_LIST_ELEMENTS(l, node, nnode, zer)) {
3652 if (zvrf && zer->re->vrf_id != zvrf->vrf->vrf_id)
3653 continue;
3654
3655 XFREE(MTYPE_RE, zer);
3656 node->data = NULL;
3657 list_delete_node(l, node);
3658 mq->size--;
3659 }
3660 }
3661
3662 void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
3663 {
3664 enum meta_queue_indexes i;
3665
3666 for (i = 0; i < MQ_SIZE; i++) {
3667 /* Some subqueues may need cleanup - nhgs for example */
3668 switch (i) {
3669 case META_QUEUE_NHG:
3670 nhg_meta_queue_free(mq, mq->subq[i], zvrf);
3671 break;
3672 case META_QUEUE_EVPN:
3673 evpn_meta_queue_free(mq, mq->subq[i], zvrf);
3674 break;
3675 case META_QUEUE_EARLY_ROUTE:
3676 early_route_meta_queue_free(mq, mq->subq[i], zvrf);
3677 break;
3678 case META_QUEUE_EARLY_LABEL:
3679 early_label_meta_queue_free(mq, mq->subq[i], zvrf);
3680 break;
3681 case META_QUEUE_CONNECTED:
3682 case META_QUEUE_KERNEL:
3683 case META_QUEUE_STATIC:
3684 case META_QUEUE_NOTBGP:
3685 case META_QUEUE_BGP:
3686 case META_QUEUE_OTHER:
3687 rib_meta_queue_free(mq, mq->subq[i], zvrf);
3688 break;
3689 }
3690 if (!zvrf)
3691 list_delete(&mq->subq[i]);
3692 }
3693
3694 if (!zvrf)
3695 XFREE(MTYPE_WORK_QUEUE, mq);
3696 }
3697
3698 /* initialise zebra rib work queue */
3699 static void rib_queue_init(void)
3700 {
3701 if (!(zrouter.ribq = work_queue_new(zrouter.master,
3702 "route_node processing"))) {
3703 flog_err(EC_ZEBRA_WQ_NONEXISTENT,
3704 "%s: could not initialise work queue!", __func__);
3705 return;
3706 }
3707
3708 /* fill in the work queue spec */
3709 zrouter.ribq->spec.workfunc = &meta_queue_process;
3710 zrouter.ribq->spec.errorfunc = NULL;
3711 zrouter.ribq->spec.completion_func = NULL;
3712 /* XXX: TODO: These should be runtime configurable via vty */
3713 zrouter.ribq->spec.max_retries = 3;
3714 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3715 zrouter.ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
3716
3717 if (!(zrouter.mq = meta_queue_new())) {
3718 flog_err(EC_ZEBRA_WQ_NONEXISTENT,
3719 "%s: could not initialise meta queue!", __func__);
3720 return;
3721 }
3722 return;
3723 }
3724
3725 rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
3726 {
3727 rib_dest_t *dest;
3728
3729 dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
3730 rnh_list_init(&dest->nht);
3731 re_list_init(&dest->routes);
3732 route_lock_node(rn); /* rn route table reference */
3733 rn->info = dest;
3734 dest->rnode = rn;
3735
3736 return dest;
3737 }
3738
3739 /* RIB updates are processed via a queue of pointers to route_nodes.
3740 *
3741 * The queue length is bounded by the maximal size of the routing table,
3742 * as a route_node will not be requeued, if already queued.
3743 *
3744 * REs are submitted via rib_addnode or rib_delnode which set minimal
3745 * state, or static_install_route (when an existing RE is updated)
3746 * and then submit route_node to queue for best-path selection later.
3747 * Order of add/delete state changes are preserved for any given RE.
3748 *
3749 * Deleted REs are reaped during best-path selection.
3750 *
3751 * rib_addnode
3752 * |-> rib_link or unset ROUTE_ENTRY_REMOVE |->Update kernel with
3753 * |-------->| | best RE, if required
3754 * | |
3755 * static_install->|->rib_addqueue...... -> rib_process
3756 * | |
3757 * |-------->| |-> rib_unlink
3758 * |-> set ROUTE_ENTRY_REMOVE |
3759 * rib_delnode (RE freed)
3760 *
3761 * The 'info' pointer of a route_node points to a rib_dest_t
3762 * ('dest'). Queueing state for a route_node is kept on the dest. The
3763 * dest is created on-demand by rib_link() and is kept around at least
3764 * as long as there are ribs hanging off it (@see rib_gc_dest()).
3765 *
3766 * Refcounting (aka "locking" throughout the Zebra and FRR code):
3767 *
3768 * - route_nodes: refcounted by:
3769 * - dest attached to route_node:
3770 * - managed by: rib_link/rib_gc_dest
3771 * - route_node processing queue
3772 * - managed by: rib_addqueue, rib_process.
3773 *
3774 */
3775
3776 /* Add RE to head of the route node. */
3777 static void rib_link(struct route_node *rn, struct route_entry *re, int process)
3778 {
3779 rib_dest_t *dest;
3780 afi_t afi;
3781 const char *rmap_name;
3782
3783 assert(re && rn);
3784
3785 dest = rib_dest_from_rnode(rn);
3786 if (!dest) {
3787 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3788 rnode_debug(rn, re->vrf_id, "rn %p adding dest", rn);
3789
3790 dest = zebra_rib_create_dest(rn);
3791 }
3792
3793 re_list_add_head(&dest->routes, re);
3794
3795 afi = (rn->p.family == AF_INET)
3796 ? AFI_IP
3797 : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
3798 if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) {
3799 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
3800
3801 rmap_name = zebra_get_import_table_route_map(afi, re->table);
3802 zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
3803 } else if (process)
3804 rib_queue_add(rn);
3805 }
3806
3807 static void rib_addnode(struct route_node *rn,
3808 struct route_entry *re, int process)
3809 {
3810 /* RE node has been un-removed before route-node is processed.
3811 * route_node must hence already be on the queue for processing..
3812 */
3813 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
3814 if (IS_ZEBRA_DEBUG_RIB)
3815 rnode_debug(rn, re->vrf_id, "rn %p, un-removed re %p",
3816 (void *)rn, (void *)re);
3817
3818 UNSET_FLAG(re->status, ROUTE_ENTRY_REMOVED);
3819 return;
3820 }
3821 rib_link(rn, re, process);
3822 }
3823
3824 /*
3825 * rib_unlink
3826 *
3827 * Detach a rib structure from a route_node.
3828 *
3829 * Note that a call to rib_unlink() should be followed by a call to
3830 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
3831 * longer required to be deleted.
3832 */
3833 void rib_unlink(struct route_node *rn, struct route_entry *re)
3834 {
3835 rib_dest_t *dest;
3836
3837 assert(rn && re);
3838
3839 if (IS_ZEBRA_DEBUG_RIB)
3840 rnode_debug(rn, re->vrf_id, "rn %p, re %p", (void *)rn,
3841 (void *)re);
3842
3843 dest = rib_dest_from_rnode(rn);
3844
3845 re_list_del(&dest->routes, re);
3846
3847 if (dest->selected_fib == re)
3848 dest->selected_fib = NULL;
3849
3850 rib_re_nhg_free(re);
3851
3852 zapi_re_opaque_free(re->opaque);
3853
3854 XFREE(MTYPE_RE, re);
3855 }
3856
3857 void rib_delnode(struct route_node *rn, struct route_entry *re)
3858 {
3859 afi_t afi;
3860
3861 if (IS_ZEBRA_DEBUG_RIB)
3862 rnode_debug(rn, re->vrf_id, "rn %p, re %p, removing",
3863 (void *)rn, (void *)re);
3864 SET_FLAG(re->status, ROUTE_ENTRY_REMOVED);
3865
3866 afi = (rn->p.family == AF_INET)
3867 ? AFI_IP
3868 : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
3869 if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) {
3870 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
3871
3872 zebra_del_import_table_entry(zvrf, rn, re);
3873 /* Just clean up if non main table */
3874 if (IS_ZEBRA_DEBUG_RIB)
3875 zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)",
3876 vrf_id_to_name(re->vrf_id), re->vrf_id, rn,
3877 rn, re, zebra_route_string(re->type));
3878
3879 rib_unlink(rn, re);
3880 } else {
3881 rib_queue_add(rn);
3882 }
3883 }
3884
3885 /*
3886 * Helper that debugs a single nexthop within a route-entry
3887 */
3888 static void _route_entry_dump_nh(const struct route_entry *re,
3889 const char *straddr,
3890 const struct nexthop *nexthop)
3891 {
3892 char nhname[PREFIX_STRLEN];
3893 char backup_str[50];
3894 char wgt_str[50];
3895 char temp_str[10];
3896 char label_str[MPLS_LABEL_STRLEN];
3897 int i;
3898 struct interface *ifp;
3899 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
3900
3901 switch (nexthop->type) {
3902 case NEXTHOP_TYPE_BLACKHOLE:
3903 snprintf(nhname, sizeof(nhname), "Blackhole");
3904 break;
3905 case NEXTHOP_TYPE_IFINDEX:
3906 ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
3907 snprintf(nhname, sizeof(nhname), "%s",
3908 ifp ? ifp->name : "Unknown");
3909 break;
3910 case NEXTHOP_TYPE_IPV4:
3911 /* fallthrough */
3912 case NEXTHOP_TYPE_IPV4_IFINDEX:
3913 inet_ntop(AF_INET, &nexthop->gate, nhname, INET6_ADDRSTRLEN);
3914 break;
3915 case NEXTHOP_TYPE_IPV6:
3916 case NEXTHOP_TYPE_IPV6_IFINDEX:
3917 inet_ntop(AF_INET6, &nexthop->gate, nhname, INET6_ADDRSTRLEN);
3918 break;
3919 }
3920
3921 /* Label stack */
3922 label_str[0] = '\0';
3923 if (nexthop->nh_label && nexthop->nh_label->num_labels > 0) {
3924 mpls_label2str(nexthop->nh_label->num_labels,
3925 nexthop->nh_label->label, label_str,
3926 sizeof(label_str), 0 /*pretty*/);
3927 strlcat(label_str, ", ", sizeof(label_str));
3928 }
3929
3930 backup_str[0] = '\0';
3931 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
3932 snprintf(backup_str, sizeof(backup_str), "backup ");
3933 for (i = 0; i < nexthop->backup_num; i++) {
3934 snprintf(temp_str, sizeof(temp_str), "%d, ",
3935 nexthop->backup_idx[i]);
3936 strlcat(backup_str, temp_str, sizeof(backup_str));
3937 }
3938 }
3939
3940 wgt_str[0] = '\0';
3941 if (nexthop->weight)
3942 snprintf(wgt_str, sizeof(wgt_str), "wgt %d,", nexthop->weight);
3943
3944 zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s%s",
3945 straddr, (nexthop->rparent ? " NH" : "NH"), nhname,
3946 nexthop->ifindex, label_str, vrf ? vrf->name : "Unknown",
3947 nexthop->vrf_id,
3948 wgt_str, backup_str,
3949 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
3950 ? "ACTIVE "
3951 : ""),
3952 (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
3953 ? "FIB "
3954 : ""),
3955 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
3956 ? "RECURSIVE "
3957 : ""),
3958 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)
3959 ? "ONLINK "
3960 : ""),
3961 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
3962 ? "DUPLICATE "
3963 : ""),
3964 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RNH_FILTERED)
3965 ? "FILTERED " : ""),
3966 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)
3967 ? "BACKUP " : ""),
3968 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE)
3969 ? "SRTE " : ""),
3970 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN)
3971 ? "EVPN " : ""));
3972
3973 }
3974
3975 /* This function dumps the contents of a given RE entry into
3976 * standard debug log. Calling function name and IP prefix in
3977 * question are passed as 1st and 2nd arguments.
3978 */
3979 void _route_entry_dump(const char *func, union prefixconstptr pp,
3980 union prefixconstptr src_pp,
3981 const struct route_entry *re)
3982 {
3983 const struct prefix *src_p = src_pp.p;
3984 bool is_srcdst = src_p && src_p->prefixlen;
3985 char straddr[PREFIX_STRLEN];
3986 char srcaddr[PREFIX_STRLEN];
3987 char flags_buf[128];
3988 char status_buf[128];
3989 struct nexthop *nexthop;
3990 struct vrf *vrf = vrf_lookup_by_id(re->vrf_id);
3991 struct nexthop_group *nhg;
3992
3993 prefix2str(pp, straddr, sizeof(straddr));
3994
3995 zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %s(%u)", func,
3996 (const void *)re, straddr,
3997 is_srcdst ? " from " : "",
3998 is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr))
3999 : "",
4000 VRF_LOGNAME(vrf), re->vrf_id);
4001 zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
4002 straddr, (unsigned long)re->uptime, re->type, re->instance,
4003 re->table);
4004 zlog_debug(
4005 "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s",
4006 straddr, re->metric, re->mtu, re->distance,
4007 zclient_dump_route_flags(re->flags, flags_buf,
4008 sizeof(flags_buf)),
4009 _dump_re_status(re, status_buf, sizeof(status_buf)));
4010 zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
4011 nexthop_group_nexthop_num(&(re->nhe->nhg)),
4012 nexthop_group_active_nexthop_num(&(re->nhe->nhg)));
4013
4014 /* Dump nexthops */
4015 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
4016 _route_entry_dump_nh(re, straddr, nexthop);
4017
4018 if (zebra_nhg_get_backup_nhg(re->nhe)) {
4019 zlog_debug("%s: backup nexthops:", straddr);
4020
4021 nhg = zebra_nhg_get_backup_nhg(re->nhe);
4022 for (ALL_NEXTHOPS_PTR(nhg, nexthop))
4023 _route_entry_dump_nh(re, straddr, nexthop);
4024 }
4025
4026 zlog_debug("%s: dump complete", straddr);
4027 }
4028
4029 static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data)
4030 {
4031 struct zebra_early_route *ere = data;
4032
4033 listnode_add(mq->subq[META_QUEUE_EARLY_ROUTE], data);
4034 mq->size++;
4035
4036 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
4037 zlog_debug(
4038 "Route %pFX(%u) queued for processing into sub-queue %s",
4039 &ere->p, ere->re->vrf_id,
4040 subqueue2str(META_QUEUE_EARLY_ROUTE));
4041
4042 return 0;
4043 }
4044
4045 struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type,
4046 uint8_t instance, uint32_t flags,
4047 uint32_t nhe_id,
4048 uint32_t table_id,
4049 uint32_t metric, uint32_t mtu,
4050 uint8_t distance, route_tag_t tag)
4051 {
4052 struct route_entry *re;
4053
4054 re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
4055 re->type = type;
4056 re->instance = instance;
4057 re->distance = distance;
4058 re->flags = flags;
4059 re->metric = metric;
4060 re->mtu = mtu;
4061 re->table = table_id;
4062 re->vrf_id = vrf_id;
4063 re->uptime = monotime(NULL);
4064 re->tag = tag;
4065 re->nhe_id = nhe_id;
4066
4067 return re;
4068 }
4069 /*
4070 * Internal route-add implementation; there are a couple of different public
4071 * signatures. Callers in this path are responsible for the memory they
4072 * allocate: if they allocate a nexthop_group or backup nexthop info, they
4073 * must free those objects. If this returns < 0, an error has occurred and the
4074 * route_entry 're' has not been captured; the caller should free that also.
4075 *
4076 * -1 -> error
4077 * 0 -> Add
4078 * 1 -> update
4079 */
4080 int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
4081 struct prefix_ipv6 *src_p, struct route_entry *re,
4082 struct nhg_hash_entry *re_nhe, bool startup)
4083 {
4084 struct zebra_early_route *ere;
4085
4086 if (!re)
4087 return -1;
4088
4089 assert(!src_p || !src_p->prefixlen || afi == AFI_IP6);
4090
4091 ere = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(*ere));
4092 ere->afi = afi;
4093 ere->safi = safi;
4094 ere->p = *p;
4095 if (src_p)
4096 ere->src_p = *src_p;
4097 ere->src_p_provided = !!src_p;
4098 ere->re = re;
4099 ere->re_nhe = re_nhe;
4100 ere->startup = startup;
4101
4102 return mq_add_handler(ere, rib_meta_queue_early_route_add);
4103 }
4104
4105 /*
4106 * Add a single route.
4107 */
4108 int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
4109 struct prefix_ipv6 *src_p, struct route_entry *re,
4110 struct nexthop_group *ng, bool startup)
4111 {
4112 int ret;
4113 struct nhg_hash_entry nhe, *n;
4114
4115 if (!re)
4116 return -1;
4117
4118 /* We either need nexthop(s) or an existing nexthop id */
4119 if (ng == NULL && re->nhe_id == 0)
4120 return -1;
4121
4122 /*
4123 * Use a temporary nhe to convey info to the common/main api.
4124 */
4125 zebra_nhe_init(&nhe, afi, (ng ? ng->nexthop : NULL));
4126 if (ng)
4127 nhe.nhg.nexthop = ng->nexthop;
4128 else if (re->nhe_id > 0)
4129 nhe.id = re->nhe_id;
4130
4131 n = zebra_nhe_copy(&nhe, 0);
4132 ret = rib_add_multipath_nhe(afi, safi, p, src_p, re, n, startup);
4133
4134 /* In error cases, free the route also */
4135 if (ret < 0)
4136 XFREE(MTYPE_RE, re);
4137
4138 return ret;
4139 }
4140
4141 void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
4142 unsigned short instance, uint32_t flags, struct prefix *p,
4143 struct prefix_ipv6 *src_p, const struct nexthop *nh,
4144 uint32_t nhe_id, uint32_t table_id, uint32_t metric,
4145 uint8_t distance, bool fromkernel)
4146 {
4147 struct zebra_early_route *ere;
4148 struct route_entry *re = NULL;
4149 struct nhg_hash_entry *nhe = NULL;
4150
4151 re = zebra_rib_route_entry_new(vrf_id, type, instance, flags, nhe_id,
4152 table_id, metric, 0, distance, 0);
4153
4154 if (nh) {
4155 nhe = zebra_nhg_alloc();
4156 nhe->nhg.nexthop = nexthop_dup(nh, NULL);
4157 }
4158
4159 ere = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(*ere));
4160 ere->afi = afi;
4161 ere->safi = safi;
4162 ere->p = *p;
4163 if (src_p)
4164 ere->src_p = *src_p;
4165 ere->src_p_provided = !!src_p;
4166 ere->re = re;
4167 ere->re_nhe = nhe;
4168 ere->startup = false;
4169 ere->deletion = true;
4170 ere->fromkernel = fromkernel;
4171
4172 mq_add_handler(ere, rib_meta_queue_early_route_add);
4173 }
4174
4175
4176 int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
4177 unsigned short instance, uint32_t flags, struct prefix *p,
4178 struct prefix_ipv6 *src_p, const struct nexthop *nh,
4179 uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu,
4180 uint8_t distance, route_tag_t tag, bool startup)
4181 {
4182 struct route_entry *re = NULL;
4183 struct nexthop nexthop = {};
4184 struct nexthop_group ng = {};
4185
4186 /* Allocate new route_entry structure. */
4187 re = zebra_rib_route_entry_new(vrf_id, type, instance, flags, nhe_id,
4188 table_id, metric, mtu, distance, tag);
4189
4190 /* If the owner of the route supplies a shared nexthop-group id,
4191 * we'll use that. Otherwise, pass the nexthop along directly.
4192 */
4193 if (!nhe_id) {
4194 /* Add nexthop. */
4195 nexthop = *nh;
4196 nexthop_group_add_sorted(&ng, &nexthop);
4197 }
4198
4199 return rib_add_multipath(afi, safi, p, src_p, re, &ng, startup);
4200 }
4201
4202 static const char *rib_update_event2str(enum rib_update_event event)
4203 {
4204 const char *ret = "UNKNOWN";
4205
4206 switch (event) {
4207 case RIB_UPDATE_KERNEL:
4208 ret = "RIB_UPDATE_KERNEL";
4209 break;
4210 case RIB_UPDATE_RMAP_CHANGE:
4211 ret = "RIB_UPDATE_RMAP_CHANGE";
4212 break;
4213 case RIB_UPDATE_OTHER:
4214 ret = "RIB_UPDATE_OTHER";
4215 break;
4216 case RIB_UPDATE_MAX:
4217 break;
4218 }
4219
4220 return ret;
4221 }
4222
4223
4224 /* Schedule route nodes to be processed if they match the type */
4225 static void rib_update_route_node(struct route_node *rn, int type)
4226 {
4227 struct route_entry *re, *next;
4228 bool re_changed = false;
4229
4230 RNODE_FOREACH_RE_SAFE (rn, re, next) {
4231 if (type == ZEBRA_ROUTE_ALL || type == re->type) {
4232 SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
4233 re_changed = true;
4234 }
4235 }
4236
4237 if (re_changed)
4238 rib_queue_add(rn);
4239 }
4240
4241 /* Schedule routes of a particular table (address-family) based on event. */
4242 void rib_update_table(struct route_table *table, enum rib_update_event event,
4243 int rtype)
4244 {
4245 struct route_node *rn;
4246
4247 if (IS_ZEBRA_DEBUG_EVENT) {
4248 struct zebra_vrf *zvrf;
4249 struct vrf *vrf;
4250
4251 zvrf = table->info
4252 ? ((struct rib_table_info *)table->info)->zvrf
4253 : NULL;
4254 vrf = zvrf ? zvrf->vrf : NULL;
4255
4256 zlog_debug("%s: %s VRF %s Table %u event %s Route type: %s", __func__,
4257 table->info ? afi2str(
4258 ((struct rib_table_info *)table->info)->afi)
4259 : "Unknown",
4260 VRF_LOGNAME(vrf), zvrf ? zvrf->table_id : 0,
4261 rib_update_event2str(event), zebra_route_string(rtype));
4262 }
4263
4264 /* Walk all routes and queue for processing, if appropriate for
4265 * the trigger event.
4266 */
4267 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
4268 /*
4269 * If we are looking at a route node and the node
4270 * has already been queued we don't
4271 * need to queue it up again
4272 */
4273 if (rn->info
4274 && CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
4275 RIB_ROUTE_ANY_QUEUED))
4276 continue;
4277
4278 switch (event) {
4279 case RIB_UPDATE_KERNEL:
4280 rib_update_route_node(rn, ZEBRA_ROUTE_KERNEL);
4281 break;
4282 case RIB_UPDATE_RMAP_CHANGE:
4283 case RIB_UPDATE_OTHER:
4284 rib_update_route_node(rn, rtype);
4285 break;
4286 default:
4287 break;
4288 }
4289 }
4290 }
4291
4292 static void rib_update_handle_vrf(vrf_id_t vrf_id, enum rib_update_event event,
4293 int rtype)
4294 {
4295 struct route_table *table;
4296
4297 if (IS_ZEBRA_DEBUG_EVENT)
4298 zlog_debug("%s: Handling VRF %s event %s", __func__,
4299 vrf_id_to_name(vrf_id), rib_update_event2str(event));
4300
4301 /* Process routes of interested address-families. */
4302 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
4303 if (table)
4304 rib_update_table(table, event, rtype);
4305
4306 table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
4307 if (table)
4308 rib_update_table(table, event, rtype);
4309 }
4310
4311 static void rib_update_handle_vrf_all(enum rib_update_event event, int rtype)
4312 {
4313 struct zebra_router_table *zrt;
4314
4315 if (IS_ZEBRA_DEBUG_EVENT)
4316 zlog_debug("%s: Handling VRF (ALL) event %s", __func__,
4317 rib_update_event2str(event));
4318
4319 /* Just iterate over all the route tables, rather than vrf lookups */
4320 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables)
4321 rib_update_table(zrt->table, event, rtype);
4322 }
4323
4324 struct rib_update_ctx {
4325 enum rib_update_event event;
4326 bool vrf_all;
4327 vrf_id_t vrf_id;
4328 };
4329
4330 static struct rib_update_ctx *rib_update_ctx_init(vrf_id_t vrf_id,
4331 enum rib_update_event event)
4332 {
4333 struct rib_update_ctx *ctx;
4334
4335 ctx = XCALLOC(MTYPE_RIB_UPDATE_CTX, sizeof(struct rib_update_ctx));
4336
4337 ctx->event = event;
4338 ctx->vrf_id = vrf_id;
4339
4340 return ctx;
4341 }
4342
4343 static void rib_update_ctx_fini(struct rib_update_ctx **ctx)
4344 {
4345 XFREE(MTYPE_RIB_UPDATE_CTX, *ctx);
4346 }
4347
4348 static void rib_update_handler(struct thread *thread)
4349 {
4350 struct rib_update_ctx *ctx;
4351
4352 ctx = THREAD_ARG(thread);
4353
4354 if (ctx->vrf_all)
4355 rib_update_handle_vrf_all(ctx->event, ZEBRA_ROUTE_ALL);
4356 else
4357 rib_update_handle_vrf(ctx->vrf_id, ctx->event, ZEBRA_ROUTE_ALL);
4358
4359 rib_update_ctx_fini(&ctx);
4360 }
4361
4362 /*
4363 * Thread list to ensure we don't schedule a ton of events
4364 * if interfaces are flapping for instance.
4365 */
4366 static struct thread *t_rib_update_threads[RIB_UPDATE_MAX];
4367
4368 /* Schedule a RIB update event for all vrfs */
4369 void rib_update(enum rib_update_event event)
4370 {
4371 struct rib_update_ctx *ctx;
4372
4373 if (thread_is_scheduled(t_rib_update_threads[event]))
4374 return;
4375
4376 ctx = rib_update_ctx_init(0, event);
4377 ctx->vrf_all = true;
4378
4379 thread_add_event(zrouter.master, rib_update_handler, ctx, 0,
4380 &t_rib_update_threads[event]);
4381
4382 if (IS_ZEBRA_DEBUG_EVENT)
4383 zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__,
4384 rib_update_event2str(event));
4385 }
4386
4387 /* Delete self installed routes after zebra is relaunched. */
4388 void rib_sweep_table(struct route_table *table)
4389 {
4390 struct route_node *rn;
4391 struct route_entry *re;
4392 struct route_entry *next;
4393 struct nexthop *nexthop;
4394
4395 if (!table)
4396 return;
4397
4398 if (IS_ZEBRA_DEBUG_RIB)
4399 zlog_debug("%s: starting", __func__);
4400
4401 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
4402 RNODE_FOREACH_RE_SAFE (rn, re, next) {
4403
4404 if (IS_ZEBRA_DEBUG_RIB)
4405 route_entry_dump(&rn->p, NULL, re);
4406
4407 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
4408 continue;
4409
4410 if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE))
4411 continue;
4412
4413 /*
4414 * If routes are older than startup_time then
4415 * we know we read them in from the kernel.
4416 * As such we can safely remove them.
4417 */
4418 if (zrouter.startup_time < re->uptime)
4419 continue;
4420
4421 /*
4422 * So we are starting up and have received
4423 * routes from the kernel that we have installed
4424 * from a previous run of zebra but not cleaned
4425 * up ( say a kill -9 )
4426 * But since we haven't actually installed
4427 * them yet( we received them from the kernel )
4428 * we don't think they are active.
4429 * So let's pretend they are active to actually
4430 * remove them.
4431 * In all honesty I'm not sure if we should
4432 * mark them as active when we receive them
4433 * This is startup only so probably ok.
4434 *
4435 * If we ever decide to move rib_sweep_table
4436 * to a different spot (ie startup )
4437 * this decision needs to be revisited
4438 */
4439 SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
4440 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
4441 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
4442
4443 rib_uninstall_kernel(rn, re);
4444 rib_delnode(rn, re);
4445 }
4446 }
4447
4448 if (IS_ZEBRA_DEBUG_RIB)
4449 zlog_debug("%s: ends", __func__);
4450 }
4451
4452 /* Sweep all RIB tables. */
4453 void rib_sweep_route(struct thread *t)
4454 {
4455 struct vrf *vrf;
4456 struct zebra_vrf *zvrf;
4457
4458 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
4459 if ((zvrf = vrf->info) == NULL)
4460 continue;
4461
4462 rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
4463 rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
4464 }
4465
4466 zebra_router_sweep_route();
4467 zebra_router_sweep_nhgs();
4468 }
4469
4470 /* Remove specific by protocol routes from 'table'. */
4471 unsigned long rib_score_proto_table(uint8_t proto, unsigned short instance,
4472 struct route_table *table)
4473 {
4474 struct route_node *rn;
4475 struct route_entry *re;
4476 struct route_entry *next;
4477 unsigned long n = 0;
4478
4479 if (table)
4480 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
4481 RNODE_FOREACH_RE_SAFE (rn, re, next) {
4482 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
4483 continue;
4484 if (re->type == proto
4485 && re->instance == instance) {
4486 rib_delnode(rn, re);
4487 n++;
4488 }
4489 }
4490 return n;
4491 }
4492
4493 /* Remove specific by protocol routes. */
4494 unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
4495 {
4496 struct vrf *vrf;
4497 struct zebra_vrf *zvrf;
4498 struct other_route_table *ort;
4499 unsigned long cnt = 0;
4500
4501 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
4502 zvrf = vrf->info;
4503 if (!zvrf)
4504 continue;
4505
4506 cnt += rib_score_proto_table(proto, instance,
4507 zvrf->table[AFI_IP][SAFI_UNICAST])
4508 + rib_score_proto_table(
4509 proto, instance,
4510 zvrf->table[AFI_IP6][SAFI_UNICAST]);
4511
4512 frr_each(otable, &zvrf->other_tables, ort) cnt +=
4513 rib_score_proto_table(proto, instance, ort->table);
4514 }
4515
4516 return cnt;
4517 }
4518
4519 /* Close RIB and clean up kernel routes. */
4520 void rib_close_table(struct route_table *table)
4521 {
4522 struct route_node *rn;
4523 rib_dest_t *dest;
4524
4525 if (!table)
4526 return;
4527
4528 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
4529 dest = rib_dest_from_rnode(rn);
4530
4531 if (dest && dest->selected_fib) {
4532 rib_uninstall_kernel(rn, dest->selected_fib);
4533 dest->selected_fib = NULL;
4534 }
4535 }
4536 }
4537
4538 /*
4539 * Handler for async dataplane results after a pseudowire installation
4540 */
4541 static void handle_pw_result(struct zebra_dplane_ctx *ctx)
4542 {
4543 struct zebra_pw *pw;
4544 struct zebra_vrf *vrf;
4545
4546 /* The pseudowire code assumes success - we act on an error
4547 * result for installation attempts here.
4548 */
4549 if (dplane_ctx_get_op(ctx) != DPLANE_OP_PW_INSTALL)
4550 return;
4551
4552 if (dplane_ctx_get_status(ctx) != ZEBRA_DPLANE_REQUEST_SUCCESS) {
4553 vrf = zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
4554 pw = zebra_pw_find(vrf, dplane_ctx_get_ifname(ctx));
4555 if (pw)
4556 zebra_pw_install_failure(pw,
4557 dplane_ctx_get_pw_status(ctx));
4558 }
4559 }
4560
4561 /*
4562 * Handle results from the dataplane system. Dequeue update context
4563 * structs, dispatch to appropriate internal handlers.
4564 */
4565 static void rib_process_dplane_results(struct thread *thread)
4566 {
4567 struct zebra_dplane_ctx *ctx;
4568 struct dplane_ctx_q ctxlist;
4569 bool shut_p = false;
4570
4571 /* Dequeue a list of completed updates with one lock/unlock cycle */
4572
4573 do {
4574 TAILQ_INIT(&ctxlist);
4575
4576 /* Take lock controlling queue of results */
4577 frr_with_mutex (&dplane_mutex) {
4578 /* Dequeue list of context structs */
4579 dplane_ctx_list_append(&ctxlist, &rib_dplane_q);
4580 }
4581
4582 /* Dequeue context block */
4583 ctx = dplane_ctx_dequeue(&ctxlist);
4584
4585 /* If we've emptied the results queue, we're done */
4586 if (ctx == NULL)
4587 break;
4588
4589 /* If zebra is shutting down, avoid processing results,
4590 * just drain the results queue.
4591 */
4592 shut_p = atomic_load_explicit(&zrouter.in_shutdown,
4593 memory_order_relaxed);
4594 if (shut_p) {
4595 while (ctx) {
4596 dplane_ctx_fini(&ctx);
4597
4598 ctx = dplane_ctx_dequeue(&ctxlist);
4599 }
4600
4601 continue;
4602 }
4603
4604 #ifdef HAVE_SCRIPTING
4605 char *script_name = frrscript_names_get_script_name(
4606 ZEBRA_ON_RIB_PROCESS_HOOK_CALL);
4607
4608 int ret = 1;
4609 struct frrscript *fs;
4610
4611 if (script_name) {
4612 fs = frrscript_new(script_name);
4613 if (fs)
4614 ret = frrscript_load(
4615 fs, ZEBRA_ON_RIB_PROCESS_HOOK_CALL,
4616 NULL);
4617 }
4618 #endif /* HAVE_SCRIPTING */
4619
4620 while (ctx) {
4621
4622 #ifdef HAVE_SCRIPTING
4623 if (ret == 0)
4624 frrscript_call(fs,
4625 ZEBRA_ON_RIB_PROCESS_HOOK_CALL,
4626 ("ctx", ctx));
4627 #endif /* HAVE_SCRIPTING */
4628
4629 switch (dplane_ctx_get_op(ctx)) {
4630 case DPLANE_OP_ROUTE_INSTALL:
4631 case DPLANE_OP_ROUTE_UPDATE:
4632 case DPLANE_OP_ROUTE_DELETE:
4633 /* Bit of special case for route updates
4634 * that were generated by async notifications:
4635 * we don't want to continue processing these
4636 * in the rib.
4637 */
4638 if (dplane_ctx_get_notif_provider(ctx) == 0)
4639 rib_process_result(ctx);
4640 break;
4641
4642 case DPLANE_OP_ROUTE_NOTIFY:
4643 rib_process_dplane_notify(ctx);
4644 break;
4645
4646 case DPLANE_OP_NH_INSTALL:
4647 case DPLANE_OP_NH_UPDATE:
4648 case DPLANE_OP_NH_DELETE:
4649 zebra_nhg_dplane_result(ctx);
4650 break;
4651
4652 case DPLANE_OP_LSP_INSTALL:
4653 case DPLANE_OP_LSP_UPDATE:
4654 case DPLANE_OP_LSP_DELETE:
4655 /* Bit of special case for LSP updates
4656 * that were generated by async notifications:
4657 * we don't want to continue processing these.
4658 */
4659 if (dplane_ctx_get_notif_provider(ctx) == 0)
4660 zebra_mpls_lsp_dplane_result(ctx);
4661 break;
4662
4663 case DPLANE_OP_LSP_NOTIFY:
4664 zebra_mpls_process_dplane_notify(ctx);
4665 break;
4666
4667 case DPLANE_OP_PW_INSTALL:
4668 case DPLANE_OP_PW_UNINSTALL:
4669 handle_pw_result(ctx);
4670 break;
4671
4672 case DPLANE_OP_SYS_ROUTE_ADD:
4673 case DPLANE_OP_SYS_ROUTE_DELETE:
4674 break;
4675
4676 case DPLANE_OP_MAC_INSTALL:
4677 case DPLANE_OP_MAC_DELETE:
4678 zebra_vxlan_handle_result(ctx);
4679 break;
4680
4681 case DPLANE_OP_RULE_ADD:
4682 case DPLANE_OP_RULE_DELETE:
4683 case DPLANE_OP_RULE_UPDATE:
4684 case DPLANE_OP_IPTABLE_ADD:
4685 case DPLANE_OP_IPTABLE_DELETE:
4686 case DPLANE_OP_IPSET_ADD:
4687 case DPLANE_OP_IPSET_DELETE:
4688 case DPLANE_OP_IPSET_ENTRY_ADD:
4689 case DPLANE_OP_IPSET_ENTRY_DELETE:
4690 zebra_pbr_dplane_result(ctx);
4691 break;
4692
4693 case DPLANE_OP_INTF_ADDR_ADD:
4694 case DPLANE_OP_INTF_ADDR_DEL:
4695 case DPLANE_OP_INTF_INSTALL:
4696 case DPLANE_OP_INTF_UPDATE:
4697 case DPLANE_OP_INTF_DELETE:
4698 case DPLANE_OP_INTF_NETCONFIG:
4699 zebra_if_dplane_result(ctx);
4700 break;
4701
4702 case DPLANE_OP_TC_INSTALL:
4703 case DPLANE_OP_TC_UPDATE:
4704 case DPLANE_OP_TC_DELETE:
4705 break;
4706
4707 /* Some op codes not handled here */
4708 case DPLANE_OP_ADDR_INSTALL:
4709 case DPLANE_OP_ADDR_UNINSTALL:
4710 case DPLANE_OP_NEIGH_INSTALL:
4711 case DPLANE_OP_NEIGH_UPDATE:
4712 case DPLANE_OP_NEIGH_DELETE:
4713 case DPLANE_OP_NEIGH_IP_INSTALL:
4714 case DPLANE_OP_NEIGH_IP_DELETE:
4715 case DPLANE_OP_VTEP_ADD:
4716 case DPLANE_OP_VTEP_DELETE:
4717 case DPLANE_OP_NEIGH_DISCOVER:
4718 case DPLANE_OP_BR_PORT_UPDATE:
4719 case DPLANE_OP_NEIGH_TABLE_UPDATE:
4720 case DPLANE_OP_GRE_SET:
4721 case DPLANE_OP_NONE:
4722 break;
4723
4724 } /* Dispatch by op code */
4725
4726 dplane_ctx_fini(&ctx);
4727 ctx = dplane_ctx_dequeue(&ctxlist);
4728 }
4729
4730 } while (1);
4731 }
4732
4733 /*
4734 * Results are returned from the dataplane subsystem, in the context of
4735 * the dataplane pthread. We enqueue the results here for processing by
4736 * the main thread later.
4737 */
4738 static int rib_dplane_results(struct dplane_ctx_q *ctxlist)
4739 {
4740 /* Take lock controlling queue of results */
4741 frr_with_mutex (&dplane_mutex) {
4742 /* Enqueue context blocks */
4743 dplane_ctx_list_append(&rib_dplane_q, ctxlist);
4744 }
4745
4746 /* Ensure event is signalled to zebra main pthread */
4747 thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
4748 &t_dplane);
4749
4750 return 0;
4751 }
4752
4753 /*
4754 * Ensure there are no empty slots in the route_info array.
4755 * Every route type in zebra should be present there.
4756 */
4757 static void check_route_info(void)
4758 {
4759 int len = array_size(route_info);
4760
4761 /*
4762 * ZEBRA_ROUTE_SYSTEM is special cased since
4763 * its key is 0 anyway.
4764 *
4765 * ZEBRA_ROUTE_ALL is also ignored.
4766 */
4767 for (int i = 0; i < len; i++) {
4768 assert(route_info[i].key >= ZEBRA_ROUTE_SYSTEM &&
4769 route_info[i].key < ZEBRA_ROUTE_MAX);
4770 assert(route_info[i].meta_q_map < MQ_SIZE);
4771 }
4772 }
4773
4774 /* Routing information base initialize. */
4775 void rib_init(void)
4776 {
4777 check_route_info();
4778
4779 rib_queue_init();
4780
4781 /* Init dataplane, and register for results */
4782 pthread_mutex_init(&dplane_mutex, NULL);
4783 TAILQ_INIT(&rib_dplane_q);
4784 zebra_dplane_init(rib_dplane_results);
4785 }
4786
4787 /*
4788 * vrf_id_get_next
4789 *
4790 * Get the first vrf id that is greater than the given vrf id if any.
4791 *
4792 * Returns true if a vrf id was found, false otherwise.
4793 */
4794 static inline int vrf_id_get_next(vrf_id_t vrf_id, vrf_id_t *next_id_p)
4795 {
4796 struct vrf *vrf;
4797
4798 vrf = vrf_lookup_by_id(vrf_id);
4799 if (vrf) {
4800 vrf = RB_NEXT(vrf_id_head, vrf);
4801 if (vrf) {
4802 *next_id_p = vrf->vrf_id;
4803 return 1;
4804 }
4805 }
4806
4807 return 0;
4808 }
4809
4810 /*
4811 * rib_tables_iter_next
4812 *
4813 * Returns the next table in the iteration.
4814 */
4815 struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter)
4816 {
4817 struct route_table *table;
4818
4819 /*
4820 * Array that helps us go over all AFI/SAFI combinations via one
4821 * index.
4822 */
4823 static const struct {
4824 afi_t afi;
4825 safi_t safi;
4826 } afi_safis[] = {
4827 {AFI_IP, SAFI_UNICAST}, {AFI_IP, SAFI_MULTICAST},
4828 {AFI_IP, SAFI_LABELED_UNICAST}, {AFI_IP6, SAFI_UNICAST},
4829 {AFI_IP6, SAFI_MULTICAST}, {AFI_IP6, SAFI_LABELED_UNICAST},
4830 };
4831
4832 table = NULL;
4833
4834 switch (iter->state) {
4835
4836 case RIB_TABLES_ITER_S_INIT:
4837 iter->vrf_id = VRF_DEFAULT;
4838 iter->afi_safi_ix = -1;
4839
4840 /* Fall through */
4841
4842 case RIB_TABLES_ITER_S_ITERATING:
4843 iter->afi_safi_ix++;
4844 while (1) {
4845
4846 while (iter->afi_safi_ix
4847 < (int)array_size(afi_safis)) {
4848 table = zebra_vrf_table(
4849 afi_safis[iter->afi_safi_ix].afi,
4850 afi_safis[iter->afi_safi_ix].safi,
4851 iter->vrf_id);
4852 if (table)
4853 break;
4854
4855 iter->afi_safi_ix++;
4856 }
4857
4858 /*
4859 * Found another table in this vrf.
4860 */
4861 if (table)
4862 break;
4863
4864 /*
4865 * Done with all tables in the current vrf, go to the
4866 * next
4867 * one.
4868 */
4869 if (!vrf_id_get_next(iter->vrf_id, &iter->vrf_id))
4870 break;
4871
4872 iter->afi_safi_ix = 0;
4873 }
4874
4875 break;
4876
4877 case RIB_TABLES_ITER_S_DONE:
4878 return NULL;
4879 }
4880
4881 if (table)
4882 iter->state = RIB_TABLES_ITER_S_ITERATING;
4883 else
4884 iter->state = RIB_TABLES_ITER_S_DONE;
4885
4886 return table;
4887 }