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