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