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