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