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