]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #5281 from bisdhdh/bgpv4-over-v6-1
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "prefix.h"
27 #include "linklist.h"
28 #include "memory.h"
29 #include "command.h"
30 #include "stream.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "routemap.h"
34 #include "buffer.h"
35 #include "sockunion.h"
36 #include "plist.h"
37 #include "thread.h"
38 #include "workqueue.h"
39 #include "queue.h"
40 #include "memory.h"
41 #include "lib/json.h"
42 #include "lib_errors.h"
43
44 #include "bgpd/bgpd.h"
45 #include "bgpd/bgp_table.h"
46 #include "bgpd/bgp_route.h"
47 #include "bgpd/bgp_attr.h"
48 #include "bgpd/bgp_debug.h"
49 #include "bgpd/bgp_errors.h"
50 #include "bgpd/bgp_aspath.h"
51 #include "bgpd/bgp_regex.h"
52 #include "bgpd/bgp_community.h"
53 #include "bgpd/bgp_ecommunity.h"
54 #include "bgpd/bgp_lcommunity.h"
55 #include "bgpd/bgp_clist.h"
56 #include "bgpd/bgp_packet.h"
57 #include "bgpd/bgp_filter.h"
58 #include "bgpd/bgp_fsm.h"
59 #include "bgpd/bgp_mplsvpn.h"
60 #include "bgpd/bgp_nexthop.h"
61 #include "bgpd/bgp_damp.h"
62 #include "bgpd/bgp_advertise.h"
63 #include "bgpd/bgp_zebra.h"
64 #include "bgpd/bgp_vty.h"
65 #include "bgpd/bgp_mpath.h"
66 #include "bgpd/bgp_nht.h"
67 #include "bgpd/bgp_updgrp.h"
68 #include "bgpd/bgp_label.h"
69 #include "bgpd/bgp_addpath.h"
70 #include "bgpd/bgp_mac.h"
71
72 #if ENABLE_BGP_VNC
73 #include "bgpd/rfapi/rfapi_backend.h"
74 #include "bgpd/rfapi/vnc_import_bgp.h"
75 #include "bgpd/rfapi/vnc_export_bgp.h"
76 #endif
77 #include "bgpd/bgp_encap_types.h"
78 #include "bgpd/bgp_encap_tlv.h"
79 #include "bgpd/bgp_evpn.h"
80 #include "bgpd/bgp_evpn_vty.h"
81 #include "bgpd/bgp_flowspec.h"
82 #include "bgpd/bgp_flowspec_util.h"
83 #include "bgpd/bgp_pbr.h"
84
85 #ifndef VTYSH_EXTRACT_PL
86 #include "bgpd/bgp_route_clippy.c"
87 #endif
88
89 /* Extern from bgp_dump.c */
90 extern const char *bgp_origin_str[];
91 extern const char *bgp_origin_long_str[];
92
93 /* PMSI strings. */
94 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
95 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
96 static const struct message bgp_pmsi_tnltype_str[] = {
97 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
98 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
99 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
100 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
101 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
102 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
103 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
104 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
105 {0}
106 };
107
108 #define VRFID_NONE_STR "-"
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp *bgp, afi_t afi, safi_t safi,
112 struct bgp_node *bn, struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw))
114
115
116 struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
117 safi_t safi, struct prefix *p,
118 struct prefix_rd *prd)
119 {
120 struct bgp_node *rn;
121 struct bgp_node *prn = NULL;
122
123 assert(table);
124 if (!table)
125 return NULL;
126
127 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
128 || (safi == SAFI_EVPN)) {
129 prn = bgp_node_get(table, (struct prefix *)prd);
130
131 if (!bgp_node_has_bgp_path_info_data(prn))
132 bgp_node_set_bgp_table_info(
133 prn, bgp_table_init(table->bgp, afi, safi));
134 else
135 bgp_unlock_node(prn);
136 table = bgp_node_get_bgp_table_info(prn);
137 }
138
139 rn = bgp_node_get(table, p);
140
141 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
142 || (safi == SAFI_EVPN))
143 rn->prn = prn;
144
145 return rn;
146 }
147
148 struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
149 safi_t safi, struct prefix *p,
150 struct prefix_rd *prd)
151 {
152 struct bgp_node *rn;
153 struct bgp_node *prn = NULL;
154
155 if (!table)
156 return NULL;
157
158 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
159 || (safi == SAFI_EVPN)) {
160 prn = bgp_node_lookup(table, (struct prefix *)prd);
161 if (!prn)
162 return NULL;
163
164 if (!bgp_node_has_bgp_path_info_data(prn)) {
165 bgp_unlock_node(prn);
166 return NULL;
167 }
168
169 table = bgp_node_get_bgp_table_info(prn);
170 }
171
172 rn = bgp_node_lookup(table, p);
173
174 return rn;
175 }
176
177 /* Allocate bgp_path_info_extra */
178 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
179 {
180 struct bgp_path_info_extra *new;
181 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
182 sizeof(struct bgp_path_info_extra));
183 new->label[0] = MPLS_INVALID_LABEL;
184 new->num_labels = 0;
185 new->bgp_fs_pbr = NULL;
186 new->bgp_fs_iprule = NULL;
187 return new;
188 }
189
190 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
191 {
192 struct bgp_path_info_extra *e;
193
194 if (!extra || !*extra)
195 return;
196
197 e = *extra;
198 if (e->damp_info)
199 bgp_damp_info_free(e->damp_info, 0);
200
201 e->damp_info = NULL;
202 if (e->parent) {
203 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
204
205 if (bpi->net) {
206 /* FIXME: since multiple e may have the same e->parent
207 * and e->parent->net is holding a refcount for each
208 * of them, we need to do some fudging here.
209 *
210 * WARNING: if bpi->net->lock drops to 0, bpi may be
211 * freed as well (because bpi->net was holding the
212 * last reference to bpi) => write after free!
213 */
214 unsigned refcount;
215
216 bpi = bgp_path_info_lock(bpi);
217 refcount = bpi->net->lock - 1;
218 bgp_unlock_node((struct bgp_node *)bpi->net);
219 if (!refcount)
220 bpi->net = NULL;
221 bgp_path_info_unlock(bpi);
222 }
223 bgp_path_info_unlock(e->parent);
224 e->parent = NULL;
225 }
226
227 if (e->bgp_orig)
228 bgp_unlock(e->bgp_orig);
229
230 if ((*extra)->bgp_fs_iprule)
231 list_delete(&((*extra)->bgp_fs_iprule));
232 if ((*extra)->bgp_fs_pbr)
233 list_delete(&((*extra)->bgp_fs_pbr));
234 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
235
236 *extra = NULL;
237 }
238
239 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
240 * allocated if required.
241 */
242 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
243 {
244 if (!pi->extra)
245 pi->extra = bgp_path_info_extra_new();
246 return pi->extra;
247 }
248
249 /* Free bgp route information. */
250 static void bgp_path_info_free(struct bgp_path_info *path)
251 {
252 bgp_attr_unintern(&path->attr);
253
254 bgp_unlink_nexthop(path);
255 bgp_path_info_extra_free(&path->extra);
256 bgp_path_info_mpath_free(&path->mpath);
257 if (path->net)
258 bgp_addpath_free_info_data(&path->tx_addpath,
259 &path->net->tx_addpath);
260
261 peer_unlock(path->peer); /* bgp_path_info peer reference */
262
263 XFREE(MTYPE_BGP_ROUTE, path);
264 }
265
266 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
267 {
268 path->lock++;
269 return path;
270 }
271
272 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
273 {
274 assert(path && path->lock > 0);
275 path->lock--;
276
277 if (path->lock == 0) {
278 #if 0
279 zlog_debug ("%s: unlocked and freeing", __func__);
280 zlog_backtrace (LOG_DEBUG);
281 #endif
282 bgp_path_info_free(path);
283 return NULL;
284 }
285
286 #if 0
287 if (path->lock == 1)
288 {
289 zlog_debug ("%s: unlocked to 1", __func__);
290 zlog_backtrace (LOG_DEBUG);
291 }
292 #endif
293
294 return path;
295 }
296
297 void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi)
298 {
299 struct bgp_path_info *top;
300
301 top = bgp_node_get_bgp_path_info(rn);
302
303 pi->next = top;
304 pi->prev = NULL;
305 if (top)
306 top->prev = pi;
307 bgp_node_set_bgp_path_info(rn, pi);
308
309 bgp_path_info_lock(pi);
310 bgp_lock_node(rn);
311 peer_lock(pi->peer); /* bgp_path_info peer reference */
312 }
313
314 /* Do the actual removal of info from RIB, for use by bgp_process
315 completion callback *only* */
316 void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi)
317 {
318 if (pi->next)
319 pi->next->prev = pi->prev;
320 if (pi->prev)
321 pi->prev->next = pi->next;
322 else
323 bgp_node_set_bgp_path_info(rn, pi->next);
324
325 bgp_path_info_mpath_dequeue(pi);
326 bgp_path_info_unlock(pi);
327 bgp_unlock_node(rn);
328 }
329
330 void bgp_path_info_delete(struct bgp_node *rn, struct bgp_path_info *pi)
331 {
332 bgp_path_info_set_flag(rn, pi, BGP_PATH_REMOVED);
333 /* set of previous already took care of pcount */
334 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
335 }
336
337 /* undo the effects of a previous call to bgp_path_info_delete; typically
338 called when a route is deleted and then quickly re-added before the
339 deletion has been processed */
340 void bgp_path_info_restore(struct bgp_node *rn, struct bgp_path_info *pi)
341 {
342 bgp_path_info_unset_flag(rn, pi, BGP_PATH_REMOVED);
343 /* unset of previous already took care of pcount */
344 SET_FLAG(pi->flags, BGP_PATH_VALID);
345 }
346
347 /* Adjust pcount as required */
348 static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_path_info *pi)
349 {
350 struct bgp_table *table;
351
352 assert(rn && bgp_node_table(rn));
353 assert(pi && pi->peer && pi->peer->bgp);
354
355 table = bgp_node_table(rn);
356
357 if (pi->peer == pi->peer->bgp->peer_self)
358 return;
359
360 if (!BGP_PATH_COUNTABLE(pi)
361 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
362
363 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
364
365 /* slight hack, but more robust against errors. */
366 if (pi->peer->pcount[table->afi][table->safi])
367 pi->peer->pcount[table->afi][table->safi]--;
368 else
369 flog_err(EC_LIB_DEVELOPMENT,
370 "Asked to decrement 0 prefix count for peer");
371 } else if (BGP_PATH_COUNTABLE(pi)
372 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
373 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
374 pi->peer->pcount[table->afi][table->safi]++;
375 }
376 }
377
378 static int bgp_label_index_differs(struct bgp_path_info *pi1,
379 struct bgp_path_info *pi2)
380 {
381 return (!(pi1->attr->label_index == pi2->attr->label_index));
382 }
383
384 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
385 * This is here primarily to keep prefix-count in check.
386 */
387 void bgp_path_info_set_flag(struct bgp_node *rn, struct bgp_path_info *pi,
388 uint32_t flag)
389 {
390 SET_FLAG(pi->flags, flag);
391
392 /* early bath if we know it's not a flag that changes countability state
393 */
394 if (!CHECK_FLAG(flag,
395 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
396 return;
397
398 bgp_pcount_adjust(rn, pi);
399 }
400
401 void bgp_path_info_unset_flag(struct bgp_node *rn, struct bgp_path_info *pi,
402 uint32_t flag)
403 {
404 UNSET_FLAG(pi->flags, flag);
405
406 /* early bath if we know it's not a flag that changes countability state
407 */
408 if (!CHECK_FLAG(flag,
409 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
410 return;
411
412 bgp_pcount_adjust(rn, pi);
413 }
414
415 /* Get MED value. If MED value is missing and "bgp bestpath
416 missing-as-worst" is specified, treat it as the worst value. */
417 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
418 {
419 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
420 return attr->med;
421 else {
422 if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
423 return BGP_MED_MAX;
424 else
425 return 0;
426 }
427 }
428
429 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
430 {
431 if (pi->addpath_rx_id)
432 sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
433 pi->addpath_rx_id);
434 else
435 sprintf(buf, "path %s", pi->peer->host);
436 }
437
438 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
439 */
440 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
441 struct bgp_path_info *exist, int *paths_eq,
442 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
443 char *pfx_buf, afi_t afi, safi_t safi,
444 enum bgp_path_selection_reason *reason)
445 {
446 struct attr *newattr, *existattr;
447 bgp_peer_sort_t new_sort;
448 bgp_peer_sort_t exist_sort;
449 uint32_t new_pref;
450 uint32_t exist_pref;
451 uint32_t new_med;
452 uint32_t exist_med;
453 uint32_t new_weight;
454 uint32_t exist_weight;
455 uint32_t newm, existm;
456 struct in_addr new_id;
457 struct in_addr exist_id;
458 int new_cluster;
459 int exist_cluster;
460 int internal_as_route;
461 int confed_as_route;
462 int ret = 0;
463 char new_buf[PATH_ADDPATH_STR_BUFFER];
464 char exist_buf[PATH_ADDPATH_STR_BUFFER];
465 uint32_t new_mm_seq;
466 uint32_t exist_mm_seq;
467 int nh_cmp;
468
469 *paths_eq = 0;
470
471 /* 0. Null check. */
472 if (new == NULL) {
473 *reason = bgp_path_selection_none;
474 if (debug)
475 zlog_debug("%s: new is NULL", pfx_buf);
476 return 0;
477 }
478
479 if (debug)
480 bgp_path_info_path_with_addpath_rx_str(new, new_buf);
481
482 if (exist == NULL) {
483 *reason = bgp_path_selection_first;
484 if (debug)
485 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
486 new_buf);
487 return 1;
488 }
489
490 if (debug) {
491 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
492 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
493 pfx_buf, new_buf, new->flags, exist_buf,
494 exist->flags);
495 }
496
497 newattr = new->attr;
498 existattr = exist->attr;
499
500 /* For EVPN routes, we cannot just go by local vs remote, we have to
501 * look at the MAC mobility sequence number, if present.
502 */
503 if (safi == SAFI_EVPN) {
504 /* This is an error condition described in RFC 7432 Section
505 * 15.2. The RFC
506 * states that in this scenario "the PE MUST alert the operator"
507 * but it
508 * does not state what other action to take. In order to provide
509 * some
510 * consistency in this scenario we are going to prefer the path
511 * with the
512 * sticky flag.
513 */
514 if (newattr->sticky != existattr->sticky) {
515 if (!debug) {
516 prefix2str(&new->net->p, pfx_buf,
517 sizeof(*pfx_buf)
518 * PREFIX2STR_BUFFER);
519 bgp_path_info_path_with_addpath_rx_str(new,
520 new_buf);
521 bgp_path_info_path_with_addpath_rx_str(
522 exist, exist_buf);
523 }
524
525 if (newattr->sticky && !existattr->sticky) {
526 *reason = bgp_path_selection_evpn_sticky_mac;
527 if (debug)
528 zlog_debug(
529 "%s: %s wins over %s due to sticky MAC flag",
530 pfx_buf, new_buf, exist_buf);
531 return 1;
532 }
533
534 if (!newattr->sticky && existattr->sticky) {
535 *reason = bgp_path_selection_evpn_sticky_mac;
536 if (debug)
537 zlog_debug(
538 "%s: %s loses to %s due to sticky MAC flag",
539 pfx_buf, new_buf, exist_buf);
540 return 0;
541 }
542 }
543
544 new_mm_seq = mac_mobility_seqnum(newattr);
545 exist_mm_seq = mac_mobility_seqnum(existattr);
546
547 if (new_mm_seq > exist_mm_seq) {
548 *reason = bgp_path_selection_evpn_seq;
549 if (debug)
550 zlog_debug(
551 "%s: %s wins over %s due to MM seq %u > %u",
552 pfx_buf, new_buf, exist_buf, new_mm_seq,
553 exist_mm_seq);
554 return 1;
555 }
556
557 if (new_mm_seq < exist_mm_seq) {
558 *reason = bgp_path_selection_evpn_seq;
559 if (debug)
560 zlog_debug(
561 "%s: %s loses to %s due to MM seq %u < %u",
562 pfx_buf, new_buf, exist_buf, new_mm_seq,
563 exist_mm_seq);
564 return 0;
565 }
566
567 /*
568 * if sequence numbers are the same path with the lowest IP
569 * wins
570 */
571 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
572 if (nh_cmp < 0) {
573 *reason = bgp_path_selection_evpn_lower_ip;
574 if (debug)
575 zlog_debug(
576 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
577 pfx_buf, new_buf, exist_buf, new_mm_seq,
578 inet_ntoa(new->attr->nexthop));
579 return 1;
580 }
581 if (nh_cmp > 0) {
582 *reason = bgp_path_selection_evpn_lower_ip;
583 if (debug)
584 zlog_debug(
585 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
586 pfx_buf, new_buf, exist_buf, new_mm_seq,
587 inet_ntoa(new->attr->nexthop));
588 return 0;
589 }
590 }
591
592 /* 1. Weight check. */
593 new_weight = newattr->weight;
594 exist_weight = existattr->weight;
595
596 if (new_weight > exist_weight) {
597 *reason = bgp_path_selection_weight;
598 if (debug)
599 zlog_debug("%s: %s wins over %s due to weight %d > %d",
600 pfx_buf, new_buf, exist_buf, new_weight,
601 exist_weight);
602 return 1;
603 }
604
605 if (new_weight < exist_weight) {
606 *reason = bgp_path_selection_weight;
607 if (debug)
608 zlog_debug("%s: %s loses to %s due to weight %d < %d",
609 pfx_buf, new_buf, exist_buf, new_weight,
610 exist_weight);
611 return 0;
612 }
613
614 /* 2. Local preference check. */
615 new_pref = exist_pref = bgp->default_local_pref;
616
617 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
618 new_pref = newattr->local_pref;
619 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
620 exist_pref = existattr->local_pref;
621
622 if (new_pref > exist_pref) {
623 *reason = bgp_path_selection_local_pref;
624 if (debug)
625 zlog_debug(
626 "%s: %s wins over %s due to localpref %d > %d",
627 pfx_buf, new_buf, exist_buf, new_pref,
628 exist_pref);
629 return 1;
630 }
631
632 if (new_pref < exist_pref) {
633 *reason = bgp_path_selection_local_pref;
634 if (debug)
635 zlog_debug(
636 "%s: %s loses to %s due to localpref %d < %d",
637 pfx_buf, new_buf, exist_buf, new_pref,
638 exist_pref);
639 return 0;
640 }
641
642 /* 3. Local route check. We prefer:
643 * - BGP_ROUTE_STATIC
644 * - BGP_ROUTE_AGGREGATE
645 * - BGP_ROUTE_REDISTRIBUTE
646 */
647 if (!(new->sub_type == BGP_ROUTE_NORMAL ||
648 new->sub_type == BGP_ROUTE_IMPORTED)) {
649 *reason = bgp_path_selection_local_route;
650 if (debug)
651 zlog_debug(
652 "%s: %s wins over %s due to preferred BGP_ROUTE type",
653 pfx_buf, new_buf, exist_buf);
654 return 1;
655 }
656
657 if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
658 exist->sub_type == BGP_ROUTE_IMPORTED)) {
659 *reason = bgp_path_selection_local_route;
660 if (debug)
661 zlog_debug(
662 "%s: %s loses to %s due to preferred BGP_ROUTE type",
663 pfx_buf, new_buf, exist_buf);
664 return 0;
665 }
666
667 /* 4. AS path length check. */
668 if (!bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) {
669 int exist_hops = aspath_count_hops(existattr->aspath);
670 int exist_confeds = aspath_count_confeds(existattr->aspath);
671
672 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) {
673 int aspath_hops;
674
675 aspath_hops = aspath_count_hops(newattr->aspath);
676 aspath_hops += aspath_count_confeds(newattr->aspath);
677
678 if (aspath_hops < (exist_hops + exist_confeds)) {
679 *reason = bgp_path_selection_confed_as_path;
680 if (debug)
681 zlog_debug(
682 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
683 pfx_buf, new_buf, exist_buf,
684 aspath_hops,
685 (exist_hops + exist_confeds));
686 return 1;
687 }
688
689 if (aspath_hops > (exist_hops + exist_confeds)) {
690 *reason = bgp_path_selection_confed_as_path;
691 if (debug)
692 zlog_debug(
693 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
694 pfx_buf, new_buf, exist_buf,
695 aspath_hops,
696 (exist_hops + exist_confeds));
697 return 0;
698 }
699 } else {
700 int newhops = aspath_count_hops(newattr->aspath);
701
702 if (newhops < exist_hops) {
703 *reason = bgp_path_selection_as_path;
704 if (debug)
705 zlog_debug(
706 "%s: %s wins over %s due to aspath hopcount %d < %d",
707 pfx_buf, new_buf, exist_buf,
708 newhops, exist_hops);
709 return 1;
710 }
711
712 if (newhops > exist_hops) {
713 *reason = bgp_path_selection_as_path;
714 if (debug)
715 zlog_debug(
716 "%s: %s loses to %s due to aspath hopcount %d > %d",
717 pfx_buf, new_buf, exist_buf,
718 newhops, exist_hops);
719 return 0;
720 }
721 }
722 }
723
724 /* 5. Origin check. */
725 if (newattr->origin < existattr->origin) {
726 *reason = bgp_path_selection_origin;
727 if (debug)
728 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
729 pfx_buf, new_buf, exist_buf,
730 bgp_origin_long_str[newattr->origin],
731 bgp_origin_long_str[existattr->origin]);
732 return 1;
733 }
734
735 if (newattr->origin > existattr->origin) {
736 *reason = bgp_path_selection_origin;
737 if (debug)
738 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
739 pfx_buf, new_buf, exist_buf,
740 bgp_origin_long_str[newattr->origin],
741 bgp_origin_long_str[existattr->origin]);
742 return 0;
743 }
744
745 /* 6. MED check. */
746 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
747 && aspath_count_hops(existattr->aspath) == 0);
748 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
749 && aspath_count_confeds(existattr->aspath) > 0
750 && aspath_count_hops(newattr->aspath) == 0
751 && aspath_count_hops(existattr->aspath) == 0);
752
753 if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
754 || (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) && confed_as_route)
755 || aspath_cmp_left(newattr->aspath, existattr->aspath)
756 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
757 || internal_as_route) {
758 new_med = bgp_med_value(new->attr, bgp);
759 exist_med = bgp_med_value(exist->attr, bgp);
760
761 if (new_med < exist_med) {
762 *reason = bgp_path_selection_med;
763 if (debug)
764 zlog_debug(
765 "%s: %s wins over %s due to MED %d < %d",
766 pfx_buf, new_buf, exist_buf, new_med,
767 exist_med);
768 return 1;
769 }
770
771 if (new_med > exist_med) {
772 *reason = bgp_path_selection_med;
773 if (debug)
774 zlog_debug(
775 "%s: %s loses to %s due to MED %d > %d",
776 pfx_buf, new_buf, exist_buf, new_med,
777 exist_med);
778 return 0;
779 }
780 }
781
782 /* 7. Peer type check. */
783 new_sort = new->peer->sort;
784 exist_sort = exist->peer->sort;
785
786 if (new_sort == BGP_PEER_EBGP
787 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
788 *reason = bgp_path_selection_peer;
789 if (debug)
790 zlog_debug(
791 "%s: %s wins over %s due to eBGP peer > iBGP peer",
792 pfx_buf, new_buf, exist_buf);
793 return 1;
794 }
795
796 if (exist_sort == BGP_PEER_EBGP
797 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
798 *reason = bgp_path_selection_peer;
799 if (debug)
800 zlog_debug(
801 "%s: %s loses to %s due to iBGP peer < eBGP peer",
802 pfx_buf, new_buf, exist_buf);
803 return 0;
804 }
805
806 /* 8. IGP metric check. */
807 newm = existm = 0;
808
809 if (new->extra)
810 newm = new->extra->igpmetric;
811 if (exist->extra)
812 existm = exist->extra->igpmetric;
813
814 if (newm < existm) {
815 if (debug)
816 zlog_debug(
817 "%s: %s wins over %s due to IGP metric %d < %d",
818 pfx_buf, new_buf, exist_buf, newm, existm);
819 ret = 1;
820 }
821
822 if (newm > existm) {
823 if (debug)
824 zlog_debug(
825 "%s: %s loses to %s due to IGP metric %d > %d",
826 pfx_buf, new_buf, exist_buf, newm, existm);
827 ret = 0;
828 }
829
830 /* 9. Same IGP metric. Compare the cluster list length as
831 representative of IGP hops metric. Rewrite the metric value
832 pair (newm, existm) with the cluster list length. Prefer the
833 path with smaller cluster list length. */
834 if (newm == existm) {
835 if (peer_sort(new->peer) == BGP_PEER_IBGP
836 && peer_sort(exist->peer) == BGP_PEER_IBGP
837 && (mpath_cfg == NULL
838 || CHECK_FLAG(
839 mpath_cfg->ibgp_flags,
840 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
841 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
842 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
843
844 if (newm < existm) {
845 if (debug)
846 zlog_debug(
847 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
848 pfx_buf, new_buf, exist_buf,
849 newm, existm);
850 ret = 1;
851 }
852
853 if (newm > existm) {
854 if (debug)
855 zlog_debug(
856 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
857 pfx_buf, new_buf, exist_buf,
858 newm, existm);
859 ret = 0;
860 }
861 }
862 }
863
864 /* 10. confed-external vs. confed-internal */
865 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
866 if (new_sort == BGP_PEER_CONFED
867 && exist_sort == BGP_PEER_IBGP) {
868 *reason = bgp_path_selection_confed;
869 if (debug)
870 zlog_debug(
871 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
872 pfx_buf, new_buf, exist_buf);
873 return 1;
874 }
875
876 if (exist_sort == BGP_PEER_CONFED
877 && new_sort == BGP_PEER_IBGP) {
878 *reason = bgp_path_selection_confed;
879 if (debug)
880 zlog_debug(
881 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
882 pfx_buf, new_buf, exist_buf);
883 return 0;
884 }
885 }
886
887 /* 11. Maximum path check. */
888 if (newm == existm) {
889 /* If one path has a label but the other does not, do not treat
890 * them as equals for multipath
891 */
892 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
893 != (exist->extra
894 && bgp_is_valid_label(&exist->extra->label[0]))) {
895 if (debug)
896 zlog_debug(
897 "%s: %s and %s cannot be multipath, one has a label while the other does not",
898 pfx_buf, new_buf, exist_buf);
899 } else if (bgp_flag_check(bgp,
900 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
901
902 /*
903 * For the two paths, all comparison steps till IGP
904 * metric
905 * have succeeded - including AS_PATH hop count. Since
906 * 'bgp
907 * bestpath as-path multipath-relax' knob is on, we
908 * don't need
909 * an exact match of AS_PATH. Thus, mark the paths are
910 * equal.
911 * That will trigger both these paths to get into the
912 * multipath
913 * array.
914 */
915 *paths_eq = 1;
916
917 if (debug)
918 zlog_debug(
919 "%s: %s and %s are equal via multipath-relax",
920 pfx_buf, new_buf, exist_buf);
921 } else if (new->peer->sort == BGP_PEER_IBGP) {
922 if (aspath_cmp(new->attr->aspath,
923 exist->attr->aspath)) {
924 *paths_eq = 1;
925
926 if (debug)
927 zlog_debug(
928 "%s: %s and %s are equal via matching aspaths",
929 pfx_buf, new_buf, exist_buf);
930 }
931 } else if (new->peer->as == exist->peer->as) {
932 *paths_eq = 1;
933
934 if (debug)
935 zlog_debug(
936 "%s: %s and %s are equal via same remote-as",
937 pfx_buf, new_buf, exist_buf);
938 }
939 } else {
940 /*
941 * TODO: If unequal cost ibgp multipath is enabled we can
942 * mark the paths as equal here instead of returning
943 */
944 if (debug) {
945 if (ret == 1)
946 zlog_debug(
947 "%s: %s wins over %s after IGP metric comparison",
948 pfx_buf, new_buf, exist_buf);
949 else
950 zlog_debug(
951 "%s: %s loses to %s after IGP metric comparison",
952 pfx_buf, new_buf, exist_buf);
953 }
954 *reason = bgp_path_selection_igp_metric;
955 return ret;
956 }
957
958 /* 12. If both paths are external, prefer the path that was received
959 first (the oldest one). This step minimizes route-flap, since a
960 newer path won't displace an older one, even if it was the
961 preferred route based on the additional decision criteria below. */
962 if (!bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)
963 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
964 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
965 *reason = bgp_path_selection_older;
966 if (debug)
967 zlog_debug(
968 "%s: %s wins over %s due to oldest external",
969 pfx_buf, new_buf, exist_buf);
970 return 1;
971 }
972
973 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
974 *reason = bgp_path_selection_older;
975 if (debug)
976 zlog_debug(
977 "%s: %s loses to %s due to oldest external",
978 pfx_buf, new_buf, exist_buf);
979 return 0;
980 }
981 }
982
983 /* 13. Router-ID comparision. */
984 /* If one of the paths is "stale", the corresponding peer router-id will
985 * be 0 and would always win over the other path. If originator id is
986 * used for the comparision, it will decide which path is better.
987 */
988 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
989 new_id.s_addr = newattr->originator_id.s_addr;
990 else
991 new_id.s_addr = new->peer->remote_id.s_addr;
992 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
993 exist_id.s_addr = existattr->originator_id.s_addr;
994 else
995 exist_id.s_addr = exist->peer->remote_id.s_addr;
996
997 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
998 *reason = bgp_path_selection_router_id;
999 if (debug)
1000 zlog_debug(
1001 "%s: %s wins over %s due to Router-ID comparison",
1002 pfx_buf, new_buf, exist_buf);
1003 return 1;
1004 }
1005
1006 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1007 *reason = bgp_path_selection_router_id;
1008 if (debug)
1009 zlog_debug(
1010 "%s: %s loses to %s due to Router-ID comparison",
1011 pfx_buf, new_buf, exist_buf);
1012 return 0;
1013 }
1014
1015 /* 14. Cluster length comparision. */
1016 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1017 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1018
1019 if (new_cluster < exist_cluster) {
1020 *reason = bgp_path_selection_cluster_length;
1021 if (debug)
1022 zlog_debug(
1023 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1024 pfx_buf, new_buf, exist_buf, new_cluster,
1025 exist_cluster);
1026 return 1;
1027 }
1028
1029 if (new_cluster > exist_cluster) {
1030 *reason = bgp_path_selection_cluster_length;
1031 if (debug)
1032 zlog_debug(
1033 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1034 pfx_buf, new_buf, exist_buf, new_cluster,
1035 exist_cluster);
1036 return 0;
1037 }
1038
1039 /* 15. Neighbor address comparision. */
1040 /* Do this only if neither path is "stale" as stale paths do not have
1041 * valid peer information (as the connection may or may not be up).
1042 */
1043 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1044 *reason = bgp_path_selection_stale;
1045 if (debug)
1046 zlog_debug(
1047 "%s: %s wins over %s due to latter path being STALE",
1048 pfx_buf, new_buf, exist_buf);
1049 return 1;
1050 }
1051
1052 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1053 *reason = bgp_path_selection_stale;
1054 if (debug)
1055 zlog_debug(
1056 "%s: %s loses to %s due to former path being STALE",
1057 pfx_buf, new_buf, exist_buf);
1058 return 0;
1059 }
1060
1061 /* locally configured routes to advertise do not have su_remote */
1062 if (new->peer->su_remote == NULL) {
1063 *reason = bgp_path_selection_local_configured;
1064 return 0;
1065 }
1066 if (exist->peer->su_remote == NULL) {
1067 *reason = bgp_path_selection_local_configured;
1068 return 1;
1069 }
1070
1071 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1072
1073 if (ret == 1) {
1074 *reason = bgp_path_selection_neighbor_ip;
1075 if (debug)
1076 zlog_debug(
1077 "%s: %s loses to %s due to Neighor IP comparison",
1078 pfx_buf, new_buf, exist_buf);
1079 return 0;
1080 }
1081
1082 if (ret == -1) {
1083 *reason = bgp_path_selection_neighbor_ip;
1084 if (debug)
1085 zlog_debug(
1086 "%s: %s wins over %s due to Neighor IP comparison",
1087 pfx_buf, new_buf, exist_buf);
1088 return 1;
1089 }
1090
1091 *reason = bgp_path_selection_default;
1092 if (debug)
1093 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1094 pfx_buf, new_buf, exist_buf);
1095
1096 return 1;
1097 }
1098
1099 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1100 * is preferred, or 0 if they are the same (usually will only occur if
1101 * multipath is enabled
1102 * This version is compatible with */
1103 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1104 struct bgp_path_info *exist, char *pfx_buf,
1105 afi_t afi, safi_t safi,
1106 enum bgp_path_selection_reason *reason)
1107 {
1108 int paths_eq;
1109 int ret;
1110 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1111 afi, safi, reason);
1112
1113 if (paths_eq)
1114 ret = 0;
1115 else {
1116 if (ret == 1)
1117 ret = -1;
1118 else
1119 ret = 1;
1120 }
1121 return ret;
1122 }
1123
1124 static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p,
1125 struct attr *attr, afi_t afi,
1126 safi_t safi)
1127 {
1128 struct bgp_filter *filter;
1129
1130 filter = &peer->filter[afi][safi];
1131
1132 #define FILTER_EXIST_WARN(F, f, filter) \
1133 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1134 zlog_debug("%s: Could not find configured input %s-list %s!", \
1135 peer->host, #f, F##_IN_NAME(filter));
1136
1137 if (DISTRIBUTE_IN_NAME(filter)) {
1138 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1139
1140 if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
1141 return FILTER_DENY;
1142 }
1143
1144 if (PREFIX_LIST_IN_NAME(filter)) {
1145 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1146
1147 if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
1148 return FILTER_DENY;
1149 }
1150
1151 if (FILTER_LIST_IN_NAME(filter)) {
1152 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1153
1154 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1155 == AS_FILTER_DENY)
1156 return FILTER_DENY;
1157 }
1158
1159 return FILTER_PERMIT;
1160 #undef FILTER_EXIST_WARN
1161 }
1162
1163 static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p,
1164 struct attr *attr, afi_t afi,
1165 safi_t safi)
1166 {
1167 struct bgp_filter *filter;
1168
1169 filter = &peer->filter[afi][safi];
1170
1171 #define FILTER_EXIST_WARN(F, f, filter) \
1172 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1173 zlog_debug("%s: Could not find configured output %s-list %s!", \
1174 peer->host, #f, F##_OUT_NAME(filter));
1175
1176 if (DISTRIBUTE_OUT_NAME(filter)) {
1177 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1178
1179 if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
1180 return FILTER_DENY;
1181 }
1182
1183 if (PREFIX_LIST_OUT_NAME(filter)) {
1184 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1185
1186 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1187 == PREFIX_DENY)
1188 return FILTER_DENY;
1189 }
1190
1191 if (FILTER_LIST_OUT_NAME(filter)) {
1192 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1193
1194 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1195 == AS_FILTER_DENY)
1196 return FILTER_DENY;
1197 }
1198
1199 return FILTER_PERMIT;
1200 #undef FILTER_EXIST_WARN
1201 }
1202
1203 /* If community attribute includes no_export then return 1. */
1204 static int bgp_community_filter(struct peer *peer, struct attr *attr)
1205 {
1206 if (attr->community) {
1207 /* NO_ADVERTISE check. */
1208 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1209 return 1;
1210
1211 /* NO_EXPORT check. */
1212 if (peer->sort == BGP_PEER_EBGP
1213 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1214 return 1;
1215
1216 /* NO_EXPORT_SUBCONFED check. */
1217 if (peer->sort == BGP_PEER_EBGP
1218 || peer->sort == BGP_PEER_CONFED)
1219 if (community_include(attr->community,
1220 COMMUNITY_NO_EXPORT_SUBCONFED))
1221 return 1;
1222 }
1223 return 0;
1224 }
1225
1226 /* Route reflection loop check. */
1227 static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
1228 {
1229 struct in_addr cluster_id;
1230
1231 if (attr->cluster) {
1232 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1233 cluster_id = peer->bgp->cluster_id;
1234 else
1235 cluster_id = peer->bgp->router_id;
1236
1237 if (cluster_loop_check(attr->cluster, cluster_id))
1238 return 1;
1239 }
1240 return 0;
1241 }
1242
1243 static int bgp_input_modifier(struct peer *peer, struct prefix *p,
1244 struct attr *attr, afi_t afi, safi_t safi,
1245 const char *rmap_name, mpls_label_t *label,
1246 uint32_t num_labels)
1247 {
1248 struct bgp_filter *filter;
1249 struct bgp_path_info rmap_path = { 0 };
1250 struct bgp_path_info_extra extra = { 0 };
1251 route_map_result_t ret;
1252 struct route_map *rmap = NULL;
1253
1254 filter = &peer->filter[afi][safi];
1255
1256 /* Apply default weight value. */
1257 if (peer->weight[afi][safi])
1258 attr->weight = peer->weight[afi][safi];
1259
1260 if (rmap_name) {
1261 rmap = route_map_lookup_by_name(rmap_name);
1262
1263 if (rmap == NULL)
1264 return RMAP_DENY;
1265 } else {
1266 if (ROUTE_MAP_IN_NAME(filter)) {
1267 rmap = ROUTE_MAP_IN(filter);
1268
1269 if (rmap == NULL)
1270 return RMAP_DENY;
1271 }
1272 }
1273
1274 /* Route map apply. */
1275 if (rmap) {
1276 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1277 /* Duplicate current value to new strucutre for modification. */
1278 rmap_path.peer = peer;
1279 rmap_path.attr = attr;
1280 rmap_path.extra = &extra;
1281 extra.num_labels = num_labels;
1282 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1283 memcpy(extra.label, label,
1284 num_labels * sizeof(mpls_label_t));
1285
1286 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1287
1288 /* Apply BGP route map to the attribute. */
1289 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1290
1291 peer->rmap_type = 0;
1292
1293 if (ret == RMAP_DENYMATCH)
1294 return RMAP_DENY;
1295 }
1296 return RMAP_PERMIT;
1297 }
1298
1299 static int bgp_output_modifier(struct peer *peer, struct prefix *p,
1300 struct attr *attr, afi_t afi, safi_t safi,
1301 const char *rmap_name)
1302 {
1303 struct bgp_path_info rmap_path;
1304 route_map_result_t ret;
1305 struct route_map *rmap = NULL;
1306 uint8_t rmap_type;
1307
1308 /*
1309 * So if we get to this point and have no rmap_name
1310 * we want to just show the output as it currently
1311 * exists.
1312 */
1313 if (!rmap_name)
1314 return RMAP_PERMIT;
1315
1316 /* Apply default weight value. */
1317 if (peer->weight[afi][safi])
1318 attr->weight = peer->weight[afi][safi];
1319
1320 rmap = route_map_lookup_by_name(rmap_name);
1321
1322 /*
1323 * If we have a route map name and we do not find
1324 * the routemap that means we have an implicit
1325 * deny.
1326 */
1327 if (rmap == NULL)
1328 return RMAP_DENY;
1329
1330 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1331 /* Route map apply. */
1332 /* Duplicate current value to new strucutre for modification. */
1333 rmap_path.peer = peer;
1334 rmap_path.attr = attr;
1335
1336 rmap_type = peer->rmap_type;
1337 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1338
1339 /* Apply BGP route map to the attribute. */
1340 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1341
1342 peer->rmap_type = rmap_type;
1343
1344 if (ret == RMAP_DENYMATCH)
1345 /*
1346 * caller has multiple error paths with bgp_attr_flush()
1347 */
1348 return RMAP_DENY;
1349
1350 return RMAP_PERMIT;
1351 }
1352
1353 /* If this is an EBGP peer with remove-private-AS */
1354 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1355 struct peer *peer, struct attr *attr)
1356 {
1357 if (peer->sort == BGP_PEER_EBGP
1358 && (peer_af_flag_check(peer, afi, safi,
1359 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1360 || peer_af_flag_check(peer, afi, safi,
1361 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1362 || peer_af_flag_check(peer, afi, safi,
1363 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1364 || peer_af_flag_check(peer, afi, safi,
1365 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1366 // Take action on the entire aspath
1367 if (peer_af_flag_check(peer, afi, safi,
1368 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1369 || peer_af_flag_check(peer, afi, safi,
1370 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1371 if (peer_af_flag_check(
1372 peer, afi, safi,
1373 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1374 attr->aspath = aspath_replace_private_asns(
1375 attr->aspath, bgp->as, peer->as);
1376
1377 // The entire aspath consists of private ASNs so create
1378 // an empty aspath
1379 else if (aspath_private_as_check(attr->aspath))
1380 attr->aspath = aspath_empty_get();
1381
1382 // There are some public and some private ASNs, remove
1383 // the private ASNs
1384 else
1385 attr->aspath = aspath_remove_private_asns(
1386 attr->aspath, peer->as);
1387 }
1388
1389 // 'all' was not specified so the entire aspath must be private
1390 // ASNs
1391 // for us to do anything
1392 else if (aspath_private_as_check(attr->aspath)) {
1393 if (peer_af_flag_check(
1394 peer, afi, safi,
1395 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1396 attr->aspath = aspath_replace_private_asns(
1397 attr->aspath, bgp->as, peer->as);
1398 else
1399 attr->aspath = aspath_empty_get();
1400 }
1401 }
1402 }
1403
1404 /* If this is an EBGP peer with as-override */
1405 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1406 struct peer *peer, struct attr *attr)
1407 {
1408 if (peer->sort == BGP_PEER_EBGP
1409 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1410 if (aspath_single_asn_check(attr->aspath, peer->as))
1411 attr->aspath = aspath_replace_specific_asn(
1412 attr->aspath, peer->as, bgp->as);
1413 }
1414 }
1415
1416 void bgp_attr_add_gshut_community(struct attr *attr)
1417 {
1418 struct community *old;
1419 struct community *new;
1420 struct community *merge;
1421 struct community *gshut;
1422
1423 old = attr->community;
1424 gshut = community_str2com("graceful-shutdown");
1425
1426 assert(gshut);
1427
1428 if (old) {
1429 merge = community_merge(community_dup(old), gshut);
1430
1431 if (old->refcnt == 0)
1432 community_free(&old);
1433
1434 new = community_uniq_sort(merge);
1435 community_free(&merge);
1436 } else {
1437 new = community_dup(gshut);
1438 }
1439
1440 community_free(&gshut);
1441 attr->community = new;
1442 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1443
1444 /* When we add the graceful-shutdown community we must also
1445 * lower the local-preference */
1446 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1447 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1448 }
1449
1450
1451 static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1452 {
1453 if (family == AF_INET) {
1454 attr->nexthop.s_addr = 0;
1455 attr->mp_nexthop_global_in.s_addr = 0;
1456 }
1457 if (family == AF_INET6)
1458 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1459 if (family == AF_EVPN)
1460 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1461 }
1462
1463 int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
1464 struct update_subgroup *subgrp, struct prefix *p,
1465 struct attr *attr)
1466 {
1467 struct bgp_filter *filter;
1468 struct peer *from;
1469 struct peer *peer;
1470 struct peer *onlypeer;
1471 struct bgp *bgp;
1472 struct attr *piattr;
1473 char buf[PREFIX_STRLEN];
1474 route_map_result_t ret;
1475 int transparent;
1476 int reflect;
1477 afi_t afi;
1478 safi_t safi;
1479 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1480
1481 if (DISABLE_BGP_ANNOUNCE)
1482 return 0;
1483
1484 afi = SUBGRP_AFI(subgrp);
1485 safi = SUBGRP_SAFI(subgrp);
1486 peer = SUBGRP_PEER(subgrp);
1487 onlypeer = NULL;
1488 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1489 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1490
1491 from = pi->peer;
1492 filter = &peer->filter[afi][safi];
1493 bgp = SUBGRP_INST(subgrp);
1494 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1495 : pi->attr;
1496
1497 #if ENABLE_BGP_VNC
1498 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1499 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1500 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1501
1502 /*
1503 * direct and direct_ext type routes originate internally even
1504 * though they can have peer pointers that reference other
1505 * systems
1506 */
1507 prefix2str(p, buf, PREFIX_STRLEN);
1508 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1509 __func__, buf);
1510 samepeer_safe = 1;
1511 }
1512 #endif
1513
1514 if (((afi == AFI_IP) || (afi == AFI_IP6))
1515 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1516 && (pi->type == ZEBRA_ROUTE_BGP)
1517 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1518
1519 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1520
1521 samepeer_safe = 1;
1522 }
1523
1524 /* With addpath we may be asked to TX all kinds of paths so make sure
1525 * pi is valid */
1526 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1527 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1528 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1529 return 0;
1530 }
1531
1532 /* If this is not the bestpath then check to see if there is an enabled
1533 * addpath
1534 * feature that requires us to advertise it */
1535 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1536 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1537 return 0;
1538 }
1539 }
1540
1541 /* Aggregate-address suppress check. */
1542 if (pi->extra && pi->extra->suppress)
1543 if (!UNSUPPRESS_MAP_NAME(filter)) {
1544 return 0;
1545 }
1546
1547 /*
1548 * If we are doing VRF 2 VRF leaking via the import
1549 * statement, we want to prevent the route going
1550 * off box as that the RT and RD created are localy
1551 * significant and globaly useless.
1552 */
1553 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1554 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1555 return 0;
1556
1557 /* If it's labeled safi, make sure the route has a valid label. */
1558 if (safi == SAFI_LABELED_UNICAST) {
1559 mpls_label_t label = bgp_adv_label(rn, pi, peer, afi, safi);
1560 if (!bgp_is_valid_label(&label)) {
1561 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1562 zlog_debug("u%" PRIu64 ":s%" PRIu64
1563 " %s/%d is filtered - no label (%p)",
1564 subgrp->update_group->id, subgrp->id,
1565 inet_ntop(p->family, &p->u.prefix,
1566 buf, SU_ADDRSTRLEN),
1567 p->prefixlen, &label);
1568 return 0;
1569 }
1570 }
1571
1572 /* Do not send back route to sender. */
1573 if (onlypeer && from == onlypeer) {
1574 return 0;
1575 }
1576
1577 /* Do not send the default route in the BGP table if the neighbor is
1578 * configured for default-originate */
1579 if (CHECK_FLAG(peer->af_flags[afi][safi],
1580 PEER_FLAG_DEFAULT_ORIGINATE)) {
1581 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1582 return 0;
1583 else if (p->family == AF_INET6 && p->prefixlen == 0)
1584 return 0;
1585 }
1586
1587 /* Transparency check. */
1588 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1589 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1590 transparent = 1;
1591 else
1592 transparent = 0;
1593
1594 /* If community is not disabled check the no-export and local. */
1595 if (!transparent && bgp_community_filter(peer, piattr)) {
1596 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1597 zlog_debug(
1598 "subgrpannouncecheck: community filter check fail");
1599 return 0;
1600 }
1601
1602 /* If the attribute has originator-id and it is same as remote
1603 peer's id. */
1604 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1605 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1606 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1607 zlog_debug(
1608 "%s [Update:SEND] %s originator-id is same as "
1609 "remote router-id",
1610 onlypeer->host,
1611 prefix2str(p, buf, sizeof(buf)));
1612 return 0;
1613 }
1614
1615 /* ORF prefix-list filter check */
1616 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1617 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1618 || CHECK_FLAG(peer->af_cap[afi][safi],
1619 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1620 if (peer->orf_plist[afi][safi]) {
1621 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1622 == PREFIX_DENY) {
1623 if (bgp_debug_update(NULL, p,
1624 subgrp->update_group, 0))
1625 zlog_debug(
1626 "%s [Update:SEND] %s is filtered via ORF",
1627 peer->host,
1628 prefix2str(p, buf,
1629 sizeof(buf)));
1630 return 0;
1631 }
1632 }
1633
1634 /* Output filter check. */
1635 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1636 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1637 zlog_debug("%s [Update:SEND] %s is filtered",
1638 peer->host, prefix2str(p, buf, sizeof(buf)));
1639 return 0;
1640 }
1641
1642 /* AS path loop check. */
1643 if (onlypeer && onlypeer->as_path_loop_detection
1644 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1645 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1646 zlog_debug(
1647 "%s [Update:SEND] suppress announcement to peer AS %u "
1648 "that is part of AS path.",
1649 onlypeer->host, onlypeer->as);
1650 return 0;
1651 }
1652
1653 /* If we're a CONFED we need to loop check the CONFED ID too */
1654 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1655 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1656 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1657 zlog_debug(
1658 "%s [Update:SEND] suppress announcement to peer AS %u"
1659 " is AS path.",
1660 peer->host, bgp->confed_id);
1661 return 0;
1662 }
1663 }
1664
1665 /* Route-Reflect check. */
1666 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1667 reflect = 1;
1668 else
1669 reflect = 0;
1670
1671 /* IBGP reflection check. */
1672 if (reflect && !samepeer_safe) {
1673 /* A route from a Client peer. */
1674 if (CHECK_FLAG(from->af_flags[afi][safi],
1675 PEER_FLAG_REFLECTOR_CLIENT)) {
1676 /* Reflect to all the Non-Client peers and also to the
1677 Client peers other than the originator. Originator
1678 check
1679 is already done. So there is noting to do. */
1680 /* no bgp client-to-client reflection check. */
1681 if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
1682 if (CHECK_FLAG(peer->af_flags[afi][safi],
1683 PEER_FLAG_REFLECTOR_CLIENT))
1684 return 0;
1685 } else {
1686 /* A route from a Non-client peer. Reflect to all other
1687 clients. */
1688 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1689 PEER_FLAG_REFLECTOR_CLIENT))
1690 return 0;
1691 }
1692 }
1693
1694 /* For modify attribute, copy it to temporary structure. */
1695 bgp_attr_dup(attr, piattr);
1696
1697 /* If local-preference is not set. */
1698 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1699 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1700 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1701 attr->local_pref = bgp->default_local_pref;
1702 }
1703
1704 /* If originator-id is not set and the route is to be reflected,
1705 set the originator id */
1706 if (reflect
1707 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1708 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1709 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1710 }
1711
1712 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1713 */
1714 if (peer->sort == BGP_PEER_EBGP
1715 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1716 if (from != bgp->peer_self && !transparent
1717 && !CHECK_FLAG(peer->af_flags[afi][safi],
1718 PEER_FLAG_MED_UNCHANGED))
1719 attr->flag &=
1720 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1721 }
1722
1723 /* Since the nexthop attribute can vary per peer, it is not explicitly
1724 * set
1725 * in announce check, only certain flags and length (or number of
1726 * nexthops
1727 * -- for IPv6/MP_REACH) are set here in order to guide the update
1728 * formation
1729 * code in setting the nexthop(s) on a per peer basis in
1730 * reformat_peer().
1731 * Typically, the source nexthop in the attribute is preserved but in
1732 * the
1733 * scenarios where we know it will always be overwritten, we reset the
1734 * nexthop to "0" in an attempt to achieve better Update packing. An
1735 * example of this is when a prefix from each of 2 IBGP peers needs to
1736 * be
1737 * announced to an EBGP peer (and they have the same attributes barring
1738 * their nexthop).
1739 */
1740 if (reflect)
1741 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1742
1743 #define NEXTHOP_IS_V6 \
1744 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1745 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1746 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1747 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1748
1749 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1750 * if
1751 * the peer (group) is configured to receive link-local nexthop
1752 * unchanged
1753 * and it is available in the prefix OR we're not reflecting the route,
1754 * link-local nexthop address is valid and
1755 * the peer (group) to whom we're going to announce is on a shared
1756 * network
1757 * and this is either a self-originated route or the peer is EBGP.
1758 * By checking if nexthop LL address is valid we are sure that
1759 * we do not announce LL address as `::`.
1760 */
1761 if (NEXTHOP_IS_V6) {
1762 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1763 if ((CHECK_FLAG(peer->af_flags[afi][safi],
1764 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
1765 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
1766 || (!reflect
1767 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
1768 && peer->shared_network
1769 && (from == bgp->peer_self
1770 || peer->sort == BGP_PEER_EBGP))) {
1771 attr->mp_nexthop_len =
1772 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1773 }
1774
1775 /* Clear off link-local nexthop in source, whenever it is not
1776 * needed to
1777 * ensure more prefixes share the same attribute for
1778 * announcement.
1779 */
1780 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
1781 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1782 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1783 }
1784
1785 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1786 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1787
1788 /* Route map & unsuppress-map apply. */
1789 if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
1790 struct bgp_path_info rmap_path = {0};
1791 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
1792 struct attr dummy_attr = {0};
1793
1794 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1795 rmap_path.peer = peer;
1796 rmap_path.attr = attr;
1797
1798 if (pi->extra) {
1799 memcpy(&dummy_rmap_path_extra, pi->extra,
1800 sizeof(struct bgp_path_info_extra));
1801 rmap_path.extra = &dummy_rmap_path_extra;
1802 }
1803
1804 /* don't confuse inbound and outbound setting */
1805 RESET_FLAG(attr->rmap_change_flags);
1806
1807 /*
1808 * The route reflector is not allowed to modify the attributes
1809 * of the reflected IBGP routes unless explicitly allowed.
1810 */
1811 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1812 && !bgp_flag_check(bgp,
1813 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
1814 bgp_attr_dup(&dummy_attr, attr);
1815 rmap_path.attr = &dummy_attr;
1816 }
1817
1818 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1819
1820 if (pi->extra && pi->extra->suppress)
1821 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
1822 RMAP_BGP, &rmap_path);
1823 else
1824 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
1825 RMAP_BGP, &rmap_path);
1826
1827 peer->rmap_type = 0;
1828
1829 if (ret == RMAP_DENYMATCH) {
1830 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1831 zlog_debug("%s [Update:SEND] %s is filtered by route-map",
1832 peer->host, prefix2str(p, buf, sizeof(buf)));
1833
1834 bgp_attr_flush(attr);
1835 return 0;
1836 }
1837 }
1838
1839 /* RFC 8212 to prevent route leaks.
1840 * This specification intends to improve this situation by requiring the
1841 * explicit configuration of both BGP Import and Export Policies for any
1842 * External BGP (EBGP) session such as customers, peers, or
1843 * confederation boundaries for all enabled address families. Through
1844 * codification of the aforementioned requirement, operators will
1845 * benefit from consistent behavior across different BGP
1846 * implementations.
1847 */
1848 if (peer->bgp->ebgp_requires_policy
1849 == DEFAULT_EBGP_POLICY_ENABLED)
1850 if (!bgp_outbound_policy_exists(peer, filter))
1851 return 0;
1852
1853 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
1854 if (peer->sort == BGP_PEER_IBGP
1855 || peer->sort == BGP_PEER_CONFED) {
1856 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1857 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1858 } else {
1859 bgp_attr_add_gshut_community(attr);
1860 }
1861 }
1862
1863 /* After route-map has been applied, we check to see if the nexthop to
1864 * be carried in the attribute (that is used for the announcement) can
1865 * be cleared off or not. We do this in all cases where we would be
1866 * setting the nexthop to "ourselves". For IPv6, we only need to
1867 * consider
1868 * the global nexthop here; the link-local nexthop would have been
1869 * cleared
1870 * already, and if not, it is required by the update formation code.
1871 * Also see earlier comments in this function.
1872 */
1873 /*
1874 * If route-map has performed some operation on the nexthop or the peer
1875 * configuration says to pass it unchanged, we cannot reset the nexthop
1876 * here, so only attempt to do it if these aren't true. Note that the
1877 * route-map handler itself might have cleared the nexthop, if for
1878 * example,
1879 * it is configured as 'peer-address'.
1880 */
1881 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
1882 piattr->rmap_change_flags)
1883 && !transparent
1884 && !CHECK_FLAG(peer->af_flags[afi][safi],
1885 PEER_FLAG_NEXTHOP_UNCHANGED)) {
1886 /* We can reset the nexthop, if setting (or forcing) it to
1887 * 'self' */
1888 if (CHECK_FLAG(peer->af_flags[afi][safi],
1889 PEER_FLAG_NEXTHOP_SELF)
1890 || CHECK_FLAG(peer->af_flags[afi][safi],
1891 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
1892 if (!reflect
1893 || CHECK_FLAG(peer->af_flags[afi][safi],
1894 PEER_FLAG_FORCE_NEXTHOP_SELF))
1895 subgroup_announce_reset_nhop(
1896 (peer_cap_enhe(peer, afi, safi)
1897 ? AF_INET6
1898 : p->family),
1899 attr);
1900 } else if (peer->sort == BGP_PEER_EBGP) {
1901 /* Can also reset the nexthop if announcing to EBGP, but
1902 * only if
1903 * no peer in the subgroup is on a shared subnet.
1904 * Note: 3rd party nexthop currently implemented for
1905 * IPv4 only.
1906 */
1907 if ((p->family == AF_INET) &&
1908 (!bgp_subgrp_multiaccess_check_v4(
1909 piattr->nexthop,
1910 subgrp)))
1911 subgroup_announce_reset_nhop(
1912 (peer_cap_enhe(peer, afi, safi)
1913 ? AF_INET6
1914 : p->family),
1915 attr);
1916
1917 if ((p->family == AF_INET6) &&
1918 (!bgp_subgrp_multiaccess_check_v6(
1919 piattr->mp_nexthop_global,
1920 subgrp)))
1921 subgroup_announce_reset_nhop(
1922 (peer_cap_enhe(peer, afi, safi)
1923 ? AF_INET6
1924 : p->family),
1925 attr);
1926
1927
1928
1929 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
1930 /*
1931 * This flag is used for leaked vpn-vrf routes
1932 */
1933 int family = p->family;
1934
1935 if (peer_cap_enhe(peer, afi, safi))
1936 family = AF_INET6;
1937
1938 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1939 zlog_debug(
1940 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
1941 __func__, family2str(family));
1942 subgroup_announce_reset_nhop(family, attr);
1943 }
1944 }
1945
1946 /* If IPv6/MP and nexthop does not have any override and happens
1947 * to
1948 * be a link-local address, reset it so that we don't pass along
1949 * the
1950 * source's link-local IPv6 address to recipients who may not be
1951 * on
1952 * the same interface.
1953 */
1954 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
1955 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
1956 subgroup_announce_reset_nhop(AF_INET6, attr);
1957 }
1958
1959 return 1;
1960 }
1961
1962 void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
1963 struct bgp_maxpaths_cfg *mpath_cfg,
1964 struct bgp_path_info_pair *result, afi_t afi,
1965 safi_t safi)
1966 {
1967 struct bgp_path_info *new_select;
1968 struct bgp_path_info *old_select;
1969 struct bgp_path_info *pi;
1970 struct bgp_path_info *pi1;
1971 struct bgp_path_info *pi2;
1972 struct bgp_path_info *nextpi = NULL;
1973 int paths_eq, do_mpath, debug;
1974 struct list mp_list;
1975 char pfx_buf[PREFIX2STR_BUFFER];
1976 char path_buf[PATH_ADDPATH_STR_BUFFER];
1977
1978 bgp_mp_list_init(&mp_list);
1979 do_mpath =
1980 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
1981
1982 debug = bgp_debug_bestpath(&rn->p);
1983
1984 if (debug)
1985 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
1986
1987 /* bgp deterministic-med */
1988 new_select = NULL;
1989 if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
1990
1991 /* Clear BGP_PATH_DMED_SELECTED for all paths */
1992 for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
1993 pi1 = pi1->next)
1994 bgp_path_info_unset_flag(rn, pi1,
1995 BGP_PATH_DMED_SELECTED);
1996
1997 for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
1998 pi1 = pi1->next) {
1999 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2000 continue;
2001 if (BGP_PATH_HOLDDOWN(pi1))
2002 continue;
2003 if (pi1->peer != bgp->peer_self)
2004 if (pi1->peer->status != Established)
2005 continue;
2006
2007 new_select = pi1;
2008 if (pi1->next) {
2009 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2010 if (CHECK_FLAG(pi2->flags,
2011 BGP_PATH_DMED_CHECK))
2012 continue;
2013 if (BGP_PATH_HOLDDOWN(pi2))
2014 continue;
2015 if (pi2->peer != bgp->peer_self
2016 && !CHECK_FLAG(
2017 pi2->peer->sflags,
2018 PEER_STATUS_NSF_WAIT))
2019 if (pi2->peer->status
2020 != Established)
2021 continue;
2022
2023 if (!aspath_cmp_left(pi1->attr->aspath,
2024 pi2->attr->aspath)
2025 && !aspath_cmp_left_confed(
2026 pi1->attr->aspath,
2027 pi2->attr->aspath))
2028 continue;
2029
2030 if (bgp_path_info_cmp(
2031 bgp, pi2, new_select,
2032 &paths_eq, mpath_cfg, debug,
2033 pfx_buf, afi, safi,
2034 &rn->reason)) {
2035 bgp_path_info_unset_flag(
2036 rn, new_select,
2037 BGP_PATH_DMED_SELECTED);
2038 new_select = pi2;
2039 }
2040
2041 bgp_path_info_set_flag(
2042 rn, pi2, BGP_PATH_DMED_CHECK);
2043 }
2044 }
2045 bgp_path_info_set_flag(rn, new_select,
2046 BGP_PATH_DMED_CHECK);
2047 bgp_path_info_set_flag(rn, new_select,
2048 BGP_PATH_DMED_SELECTED);
2049
2050 if (debug) {
2051 bgp_path_info_path_with_addpath_rx_str(
2052 new_select, path_buf);
2053 zlog_debug("%s: %s is the bestpath from AS %u",
2054 pfx_buf, path_buf,
2055 aspath_get_first_as(
2056 new_select->attr->aspath));
2057 }
2058 }
2059 }
2060
2061 /* Check old selected route and new selected route. */
2062 old_select = NULL;
2063 new_select = NULL;
2064 for (pi = bgp_node_get_bgp_path_info(rn);
2065 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2066 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2067 old_select = pi;
2068
2069 if (BGP_PATH_HOLDDOWN(pi)) {
2070 /* reap REMOVED routes, if needs be
2071 * selected route must stay for a while longer though
2072 */
2073 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2074 && (pi != old_select))
2075 bgp_path_info_reap(rn, pi);
2076
2077 if (debug)
2078 zlog_debug("%s: pi %p in holddown", __func__,
2079 pi);
2080
2081 continue;
2082 }
2083
2084 if (pi->peer && pi->peer != bgp->peer_self
2085 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2086 if (pi->peer->status != Established) {
2087
2088 if (debug)
2089 zlog_debug(
2090 "%s: pi %p non self peer %s not estab state",
2091 __func__, pi, pi->peer->host);
2092
2093 continue;
2094 }
2095
2096 if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
2097 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2098 bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
2099 if (debug)
2100 zlog_debug("%s: pi %p dmed", __func__, pi);
2101 continue;
2102 }
2103
2104 bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
2105
2106 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2107 debug, pfx_buf, afi, safi, &rn->reason)) {
2108 new_select = pi;
2109 }
2110 }
2111
2112 /* Now that we know which path is the bestpath see if any of the other
2113 * paths
2114 * qualify as multipaths
2115 */
2116 if (debug) {
2117 if (new_select)
2118 bgp_path_info_path_with_addpath_rx_str(new_select,
2119 path_buf);
2120 else
2121 sprintf(path_buf, "NONE");
2122 zlog_debug(
2123 "%s: After path selection, newbest is %s oldbest was %s",
2124 pfx_buf, path_buf,
2125 old_select ? old_select->peer->host : "NONE");
2126 }
2127
2128 if (do_mpath && new_select) {
2129 for (pi = bgp_node_get_bgp_path_info(rn);
2130 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2131
2132 if (debug)
2133 bgp_path_info_path_with_addpath_rx_str(
2134 pi, path_buf);
2135
2136 if (pi == new_select) {
2137 if (debug)
2138 zlog_debug(
2139 "%s: %s is the bestpath, add to the multipath list",
2140 pfx_buf, path_buf);
2141 bgp_mp_list_add(&mp_list, pi);
2142 continue;
2143 }
2144
2145 if (BGP_PATH_HOLDDOWN(pi))
2146 continue;
2147
2148 if (pi->peer && pi->peer != bgp->peer_self
2149 && !CHECK_FLAG(pi->peer->sflags,
2150 PEER_STATUS_NSF_WAIT))
2151 if (pi->peer->status != Established)
2152 continue;
2153
2154 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2155 if (debug)
2156 zlog_debug(
2157 "%s: %s has the same nexthop as the bestpath, skip it",
2158 pfx_buf, path_buf);
2159 continue;
2160 }
2161
2162 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2163 mpath_cfg, debug, pfx_buf, afi, safi,
2164 &rn->reason);
2165
2166 if (paths_eq) {
2167 if (debug)
2168 zlog_debug(
2169 "%s: %s is equivalent to the bestpath, add to the multipath list",
2170 pfx_buf, path_buf);
2171 bgp_mp_list_add(&mp_list, pi);
2172 }
2173 }
2174 }
2175
2176 bgp_path_info_mpath_update(rn, new_select, old_select, &mp_list,
2177 mpath_cfg);
2178 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2179 bgp_mp_list_clear(&mp_list);
2180
2181 bgp_addpath_update_ids(bgp, rn, afi, safi);
2182
2183 result->old = old_select;
2184 result->new = new_select;
2185
2186 return;
2187 }
2188
2189 /*
2190 * A new route/change in bestpath of an existing route. Evaluate the path
2191 * for advertisement to the subgroup.
2192 */
2193 int subgroup_process_announce_selected(struct update_subgroup *subgrp,
2194 struct bgp_path_info *selected,
2195 struct bgp_node *rn,
2196 uint32_t addpath_tx_id)
2197 {
2198 struct prefix *p;
2199 struct peer *onlypeer;
2200 struct attr attr;
2201 afi_t afi;
2202 safi_t safi;
2203
2204 p = &rn->p;
2205 afi = SUBGRP_AFI(subgrp);
2206 safi = SUBGRP_SAFI(subgrp);
2207 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2208 : NULL);
2209
2210 if (BGP_DEBUG(update, UPDATE_OUT)) {
2211 char buf_prefix[PREFIX_STRLEN];
2212 prefix2str(p, buf_prefix, sizeof(buf_prefix));
2213 zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
2214 selected);
2215 }
2216
2217 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2218 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2219 PEER_STATUS_ORF_WAIT_REFRESH))
2220 return 0;
2221
2222 memset(&attr, 0, sizeof(struct attr));
2223 /* It's initialized in bgp_announce_check() */
2224
2225 /* Announcement to the subgroup. If the route is filtered withdraw it.
2226 */
2227 if (selected) {
2228 if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
2229 bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
2230 else
2231 bgp_adj_out_unset_subgroup(rn, subgrp, 1,
2232 addpath_tx_id);
2233 }
2234
2235 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2236 else {
2237 bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
2238 }
2239
2240 return 0;
2241 }
2242
2243 /*
2244 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2245 * This is called at the end of route processing.
2246 */
2247 void bgp_zebra_clear_route_change_flags(struct bgp_node *rn)
2248 {
2249 struct bgp_path_info *pi;
2250
2251 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
2252 if (BGP_PATH_HOLDDOWN(pi))
2253 continue;
2254 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2255 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2256 }
2257 }
2258
2259 /*
2260 * Has the route changed from the RIB's perspective? This is invoked only
2261 * if the route selection returns the same best route as earlier - to
2262 * determine if we need to update zebra or not.
2263 */
2264 int bgp_zebra_has_route_changed(struct bgp_node *rn,
2265 struct bgp_path_info *selected)
2266 {
2267 struct bgp_path_info *mpinfo;
2268
2269 /* If this is multipath, check all selected paths for any nexthop
2270 * change or attribute change. Some attribute changes (e.g., community)
2271 * aren't of relevance to the RIB, but we'll update zebra to ensure
2272 * we handle the case of BGP nexthop change. This is the behavior
2273 * when the best path has an attribute change anyway.
2274 */
2275 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2276 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG))
2277 return 1;
2278
2279 /*
2280 * If this is multipath, check all selected paths for any nexthop change
2281 */
2282 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2283 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2284 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2285 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2286 return 1;
2287 }
2288
2289 /* Nothing has changed from the RIB's perspective. */
2290 return 0;
2291 }
2292
2293 struct bgp_process_queue {
2294 struct bgp *bgp;
2295 STAILQ_HEAD(, bgp_node) pqueue;
2296 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2297 unsigned int flags;
2298 unsigned int queued;
2299 };
2300
2301 /*
2302 * old_select = The old best path
2303 * new_select = the new best path
2304 *
2305 * if (!old_select && new_select)
2306 * We are sending new information on.
2307 *
2308 * if (old_select && new_select) {
2309 * if (new_select != old_select)
2310 * We have a new best path send a change
2311 * else
2312 * We've received a update with new attributes that needs
2313 * to be passed on.
2314 * }
2315 *
2316 * if (old_select && !new_select)
2317 * We have no eligible route that we can announce or the rn
2318 * is being removed.
2319 */
2320 static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
2321 afi_t afi, safi_t safi)
2322 {
2323 struct bgp_path_info *new_select;
2324 struct bgp_path_info *old_select;
2325 struct bgp_path_info_pair old_and_new;
2326 char pfx_buf[PREFIX2STR_BUFFER];
2327 int debug = 0;
2328
2329 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS)) {
2330 if (rn)
2331 debug = bgp_debug_bestpath(&rn->p);
2332 if (debug) {
2333 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2334 zlog_debug(
2335 "%s: bgp delete in progress, ignoring event, p=%s",
2336 __func__, pfx_buf);
2337 }
2338 return;
2339 }
2340 /* Is it end of initial update? (after startup) */
2341 if (!rn) {
2342 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2343 sizeof(bgp->update_delay_zebra_resume_time));
2344
2345 bgp->main_zebra_update_hold = 0;
2346 FOREACH_AFI_SAFI (afi, safi) {
2347 if (bgp_fibupd_safi(safi))
2348 bgp_zebra_announce_table(bgp, afi, safi);
2349 }
2350 bgp->main_peers_update_hold = 0;
2351
2352 bgp_start_routeadv(bgp);
2353 return;
2354 }
2355
2356 struct prefix *p = &rn->p;
2357
2358 debug = bgp_debug_bestpath(&rn->p);
2359 if (debug) {
2360 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2361 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__, pfx_buf,
2362 afi2str(afi), safi2str(safi));
2363 }
2364
2365 /* Best path selection. */
2366 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
2367 afi, safi);
2368 old_select = old_and_new.old;
2369 new_select = old_and_new.new;
2370
2371 /* Do we need to allocate or free labels?
2372 * Right now, since we only deal with per-prefix labels, it is not
2373 * necessary to do this upon changes to best path. Exceptions:
2374 * - label index has changed -> recalculate resulting label
2375 * - path_info sub_type changed -> switch to/from implicit-null
2376 * - no valid label (due to removed static label binding) -> get new one
2377 */
2378 if (bgp->allocate_mpls_labels[afi][safi]) {
2379 if (new_select) {
2380 if (!old_select
2381 || bgp_label_index_differs(new_select, old_select)
2382 || new_select->sub_type != old_select->sub_type
2383 || !bgp_is_valid_label(&rn->local_label)) {
2384 /* Enforced penultimate hop popping:
2385 * implicit-null for local routes, aggregate
2386 * and redistributed routes
2387 */
2388 if (new_select->sub_type == BGP_ROUTE_STATIC
2389 || new_select->sub_type
2390 == BGP_ROUTE_AGGREGATE
2391 || new_select->sub_type
2392 == BGP_ROUTE_REDISTRIBUTE) {
2393 if (CHECK_FLAG(
2394 rn->flags,
2395 BGP_NODE_REGISTERED_FOR_LABEL))
2396 bgp_unregister_for_label(rn);
2397 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2398 &rn->local_label);
2399 bgp_set_valid_label(&rn->local_label);
2400 } else
2401 bgp_register_for_label(rn, new_select);
2402 }
2403 } else if (CHECK_FLAG(rn->flags,
2404 BGP_NODE_REGISTERED_FOR_LABEL)) {
2405 bgp_unregister_for_label(rn);
2406 }
2407 } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
2408 bgp_unregister_for_label(rn);
2409 }
2410
2411 if (debug) {
2412 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2413 zlog_debug(
2414 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2415 __func__, pfx_buf, afi2str(afi), safi2str(safi),
2416 old_select, new_select);
2417 }
2418
2419 /* If best route remains the same and this is not due to user-initiated
2420 * clear, see exactly what needs to be done.
2421 */
2422 if (old_select && old_select == new_select
2423 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
2424 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2425 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2426 if (bgp_zebra_has_route_changed(rn, old_select)) {
2427 #if ENABLE_BGP_VNC
2428 vnc_import_bgp_add_route(bgp, p, old_select);
2429 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2430 #endif
2431 if (bgp_fibupd_safi(safi)
2432 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2433
2434 if (new_select->type == ZEBRA_ROUTE_BGP
2435 && (new_select->sub_type == BGP_ROUTE_NORMAL
2436 || new_select->sub_type
2437 == BGP_ROUTE_IMPORTED))
2438
2439 bgp_zebra_announce(rn, p, old_select,
2440 bgp, afi, safi);
2441 }
2442 }
2443 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2444 bgp_zebra_clear_route_change_flags(rn);
2445
2446 /* If there is a change of interest to peers, reannounce the
2447 * route. */
2448 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2449 || CHECK_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED)) {
2450 group_announce_route(bgp, afi, safi, rn, new_select);
2451
2452 /* unicast routes must also be annouced to
2453 * labeled-unicast update-groups */
2454 if (safi == SAFI_UNICAST)
2455 group_announce_route(bgp, afi,
2456 SAFI_LABELED_UNICAST, rn,
2457 new_select);
2458
2459 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2460 UNSET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
2461 }
2462
2463 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2464 return;
2465 }
2466
2467 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2468 */
2469 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
2470
2471 /* bestpath has changed; bump version */
2472 if (old_select || new_select) {
2473 bgp_bump_version(rn);
2474
2475 if (!bgp->t_rmap_def_originate_eval) {
2476 bgp_lock(bgp);
2477 thread_add_timer(
2478 bm->master,
2479 update_group_refresh_default_originate_route_map,
2480 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2481 &bgp->t_rmap_def_originate_eval);
2482 }
2483 }
2484
2485 if (old_select)
2486 bgp_path_info_unset_flag(rn, old_select, BGP_PATH_SELECTED);
2487 if (new_select) {
2488 if (debug)
2489 zlog_debug("%s: setting SELECTED flag", __func__);
2490 bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
2491 bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
2492 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2493 }
2494
2495 #if ENABLE_BGP_VNC
2496 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2497 if (old_select != new_select) {
2498 if (old_select) {
2499 vnc_import_bgp_exterior_del_route(bgp, p,
2500 old_select);
2501 vnc_import_bgp_del_route(bgp, p, old_select);
2502 }
2503 if (new_select) {
2504 vnc_import_bgp_exterior_add_route(bgp, p,
2505 new_select);
2506 vnc_import_bgp_add_route(bgp, p, new_select);
2507 }
2508 }
2509 }
2510 #endif
2511
2512 group_announce_route(bgp, afi, safi, rn, new_select);
2513
2514 /* unicast routes must also be annouced to labeled-unicast update-groups
2515 */
2516 if (safi == SAFI_UNICAST)
2517 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, rn,
2518 new_select);
2519
2520 /* FIB update. */
2521 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2522 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2523 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2524 && (new_select->sub_type == BGP_ROUTE_NORMAL
2525 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2526 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2527
2528 /* if this is an evpn imported type-5 prefix,
2529 * we need to withdraw the route first to clear
2530 * the nh neigh and the RMAC entry.
2531 */
2532 if (old_select &&
2533 is_route_parent_evpn(old_select))
2534 bgp_zebra_withdraw(p, old_select, bgp, safi);
2535
2536 bgp_zebra_announce(rn, p, new_select, bgp, afi, safi);
2537 } else {
2538 /* Withdraw the route from the kernel. */
2539 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2540 && (old_select->sub_type == BGP_ROUTE_NORMAL
2541 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2542 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2543
2544 bgp_zebra_withdraw(p, old_select, bgp, safi);
2545 }
2546 }
2547
2548 /* advertise/withdraw type-5 routes */
2549 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2550 if (advertise_type5_routes(bgp, afi) &&
2551 new_select &&
2552 is_route_injectable_into_evpn(new_select)) {
2553
2554 /* apply the route-map */
2555 if (bgp->adv_cmd_rmap[afi][safi].map) {
2556 route_map_result_t ret;
2557
2558 ret = route_map_apply(
2559 bgp->adv_cmd_rmap[afi][safi].map,
2560 &rn->p, RMAP_BGP, new_select);
2561 if (ret == RMAP_PERMITMATCH)
2562 bgp_evpn_advertise_type5_route(
2563 bgp, &rn->p, new_select->attr,
2564 afi, safi);
2565 else
2566 bgp_evpn_withdraw_type5_route(
2567 bgp, &rn->p, afi, safi);
2568 } else {
2569 bgp_evpn_advertise_type5_route(bgp,
2570 &rn->p,
2571 new_select->attr,
2572 afi, safi);
2573
2574 }
2575 } else if (advertise_type5_routes(bgp, afi) &&
2576 old_select &&
2577 is_route_injectable_into_evpn(old_select))
2578 bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
2579 }
2580
2581 /* Clear any route change flags. */
2582 bgp_zebra_clear_route_change_flags(rn);
2583
2584 /* Reap old select bgp_path_info, if it has been removed */
2585 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2586 bgp_path_info_reap(rn, old_select);
2587
2588 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2589 return;
2590 }
2591
2592 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
2593 {
2594 struct bgp_process_queue *pqnode = data;
2595 struct bgp *bgp = pqnode->bgp;
2596 struct bgp_table *table;
2597 struct bgp_node *rn;
2598
2599 /* eoiu marker */
2600 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
2601 bgp_process_main_one(bgp, NULL, 0, 0);
2602 /* should always have dedicated wq call */
2603 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
2604 return WQ_SUCCESS;
2605 }
2606
2607 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
2608 rn = STAILQ_FIRST(&pqnode->pqueue);
2609 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
2610 STAILQ_NEXT(rn, pq) = NULL; /* complete unlink */
2611 table = bgp_node_table(rn);
2612 /* note, new RNs may be added as part of processing */
2613 bgp_process_main_one(bgp, rn, table->afi, table->safi);
2614
2615 bgp_unlock_node(rn);
2616 bgp_table_unlock(table);
2617 }
2618
2619 return WQ_SUCCESS;
2620 }
2621
2622 static void bgp_processq_del(struct work_queue *wq, void *data)
2623 {
2624 struct bgp_process_queue *pqnode = data;
2625
2626 bgp_unlock(pqnode->bgp);
2627
2628 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
2629 }
2630
2631 void bgp_process_queue_init(void)
2632 {
2633 if (!bm->process_main_queue)
2634 bm->process_main_queue =
2635 work_queue_new(bm->master, "process_main_queue");
2636
2637 bm->process_main_queue->spec.workfunc = &bgp_process_wq;
2638 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2639 bm->process_main_queue->spec.max_retries = 0;
2640 bm->process_main_queue->spec.hold = 50;
2641 /* Use a higher yield value of 50ms for main queue processing */
2642 bm->process_main_queue->spec.yield = 50 * 1000L;
2643 }
2644
2645 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
2646 {
2647 struct bgp_process_queue *pqnode;
2648
2649 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2650 sizeof(struct bgp_process_queue));
2651
2652 /* unlocked in bgp_processq_del */
2653 pqnode->bgp = bgp_lock(bgp);
2654 STAILQ_INIT(&pqnode->pqueue);
2655
2656 return pqnode;
2657 }
2658
2659 void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
2660 {
2661 #define ARBITRARY_PROCESS_QLEN 10000
2662 struct work_queue *wq = bm->process_main_queue;
2663 struct bgp_process_queue *pqnode;
2664 int pqnode_reuse = 0;
2665
2666 /* already scheduled for processing? */
2667 if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED))
2668 return;
2669
2670 if (wq == NULL)
2671 return;
2672
2673 /* Add route nodes to an existing work queue item until reaching the
2674 limit only if is from the same BGP view and it's not an EOIU marker
2675 */
2676 if (work_queue_item_count(wq)) {
2677 struct work_queue_item *item = work_queue_last_item(wq);
2678 pqnode = item->data;
2679
2680 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
2681 || pqnode->bgp != bgp
2682 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
2683 pqnode = bgp_processq_alloc(bgp);
2684 else
2685 pqnode_reuse = 1;
2686 } else
2687 pqnode = bgp_processq_alloc(bgp);
2688 /* all unlocked in bgp_process_wq */
2689 bgp_table_lock(bgp_node_table(rn));
2690
2691 SET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2692 bgp_lock_node(rn);
2693
2694 /* can't be enqueued twice */
2695 assert(STAILQ_NEXT(rn, pq) == NULL);
2696 STAILQ_INSERT_TAIL(&pqnode->pqueue, rn, pq);
2697 pqnode->queued++;
2698
2699 if (!pqnode_reuse)
2700 work_queue_add(wq, pqnode);
2701
2702 return;
2703 }
2704
2705 void bgp_add_eoiu_mark(struct bgp *bgp)
2706 {
2707 struct bgp_process_queue *pqnode;
2708
2709 if (bm->process_main_queue == NULL)
2710 return;
2711
2712 pqnode = bgp_processq_alloc(bgp);
2713
2714 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
2715 work_queue_add(bm->process_main_queue, pqnode);
2716 }
2717
2718 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
2719 {
2720 struct peer *peer;
2721
2722 peer = THREAD_ARG(thread);
2723 peer->t_pmax_restart = NULL;
2724
2725 if (bgp_debug_neighbor_events(peer))
2726 zlog_debug(
2727 "%s Maximum-prefix restart timer expired, restore peering",
2728 peer->host);
2729
2730 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
2731 zlog_debug("%s: %s peer_clear failed",
2732 __PRETTY_FUNCTION__, peer->host);
2733
2734 return 0;
2735 }
2736
2737 int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
2738 int always)
2739 {
2740 iana_afi_t pkt_afi;
2741 iana_safi_t pkt_safi;
2742
2743 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
2744 return 0;
2745
2746 if (peer->pcount[afi][safi] > peer->pmax[afi][safi]) {
2747 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2748 PEER_STATUS_PREFIX_LIMIT)
2749 && !always)
2750 return 0;
2751
2752 zlog_info(
2753 "%%MAXPFXEXCEED: No. of %s prefix received from %s %" PRIu32
2754 " exceed, limit %" PRIu32,
2755 get_afi_safi_str(afi, safi, false), peer->host,
2756 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2757 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2758
2759 if (CHECK_FLAG(peer->af_flags[afi][safi],
2760 PEER_FLAG_MAX_PREFIX_WARNING))
2761 return 0;
2762
2763 /* Convert AFI, SAFI to values for packet. */
2764 pkt_afi = afi_int2iana(afi);
2765 pkt_safi = safi_int2iana(safi);
2766 {
2767 uint8_t ndata[7];
2768
2769 ndata[0] = (pkt_afi >> 8);
2770 ndata[1] = pkt_afi;
2771 ndata[2] = pkt_safi;
2772 ndata[3] = (peer->pmax[afi][safi] >> 24);
2773 ndata[4] = (peer->pmax[afi][safi] >> 16);
2774 ndata[5] = (peer->pmax[afi][safi] >> 8);
2775 ndata[6] = (peer->pmax[afi][safi]);
2776
2777 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2778 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
2779 BGP_NOTIFY_CEASE_MAX_PREFIX,
2780 ndata, 7);
2781 }
2782
2783 /* Dynamic peers will just close their connection. */
2784 if (peer_dynamic_neighbor(peer))
2785 return 1;
2786
2787 /* restart timer start */
2788 if (peer->pmax_restart[afi][safi]) {
2789 peer->v_pmax_restart =
2790 peer->pmax_restart[afi][safi] * 60;
2791
2792 if (bgp_debug_neighbor_events(peer))
2793 zlog_debug(
2794 "%s Maximum-prefix restart timer started for %d secs",
2795 peer->host, peer->v_pmax_restart);
2796
2797 BGP_TIMER_ON(peer->t_pmax_restart,
2798 bgp_maximum_prefix_restart_timer,
2799 peer->v_pmax_restart);
2800 }
2801
2802 return 1;
2803 } else
2804 UNSET_FLAG(peer->af_sflags[afi][safi],
2805 PEER_STATUS_PREFIX_LIMIT);
2806
2807 if (peer->pcount[afi][safi]
2808 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
2809 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2810 PEER_STATUS_PREFIX_THRESHOLD)
2811 && !always)
2812 return 0;
2813
2814 zlog_info(
2815 "%%MAXPFX: No. of %s prefix received from %s reaches %" PRIu32
2816 ", max %" PRIu32,
2817 get_afi_safi_str(afi, safi, false), peer->host,
2818 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2819 SET_FLAG(peer->af_sflags[afi][safi],
2820 PEER_STATUS_PREFIX_THRESHOLD);
2821 } else
2822 UNSET_FLAG(peer->af_sflags[afi][safi],
2823 PEER_STATUS_PREFIX_THRESHOLD);
2824 return 0;
2825 }
2826
2827 /* Unconditionally remove the route from the RIB, without taking
2828 * damping into consideration (eg, because the session went down)
2829 */
2830 void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
2831 struct peer *peer, afi_t afi, safi_t safi)
2832 {
2833 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi, safi);
2834
2835 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
2836 bgp_path_info_delete(rn, pi); /* keep historical info */
2837
2838 hook_call(bgp_process, peer->bgp, afi, safi, rn, peer, true);
2839
2840 bgp_process(peer->bgp, rn, afi, safi);
2841 }
2842
2843 static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_path_info *pi,
2844 struct peer *peer, afi_t afi, safi_t safi,
2845 struct prefix_rd *prd)
2846 {
2847 /* apply dampening, if result is suppressed, we'll be retaining
2848 * the bgp_path_info in the RIB for historical reference.
2849 */
2850 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2851 && peer->sort == BGP_PEER_EBGP)
2852 if ((bgp_damp_withdraw(pi, rn, afi, safi, 0))
2853 == BGP_DAMP_SUPPRESSED) {
2854 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi,
2855 safi);
2856 return;
2857 }
2858
2859 #if ENABLE_BGP_VNC
2860 if (safi == SAFI_MPLS_VPN) {
2861 struct bgp_node *prn = NULL;
2862 struct bgp_table *table = NULL;
2863
2864 prn = bgp_node_get(peer->bgp->rib[afi][safi],
2865 (struct prefix *)prd);
2866 if (bgp_node_has_bgp_path_info_data(prn)) {
2867 table = bgp_node_get_bgp_table_info(prn);
2868
2869 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2870 peer->bgp, prd, table, &rn->p, pi);
2871 }
2872 bgp_unlock_node(prn);
2873 }
2874 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2875 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
2876
2877 vnc_import_bgp_del_route(peer->bgp, &rn->p, pi);
2878 vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p,
2879 pi);
2880 }
2881 }
2882 #endif
2883
2884 /* If this is an EVPN route, process for un-import. */
2885 if (safi == SAFI_EVPN)
2886 bgp_evpn_unimport_route(peer->bgp, afi, safi, &rn->p, pi);
2887
2888 bgp_rib_remove(rn, pi, peer, afi, safi);
2889 }
2890
2891 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
2892 struct peer *peer, struct attr *attr,
2893 struct bgp_node *rn)
2894 {
2895 struct bgp_path_info *new;
2896
2897 /* Make new BGP info. */
2898 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
2899 new->type = type;
2900 new->instance = instance;
2901 new->sub_type = sub_type;
2902 new->peer = peer;
2903 new->attr = attr;
2904 new->uptime = bgp_clock();
2905 new->net = rn;
2906 return new;
2907 }
2908
2909 static void overlay_index_update(struct attr *attr,
2910 struct eth_segment_id *eth_s_id,
2911 union gw_addr *gw_ip)
2912 {
2913 if (!attr)
2914 return;
2915
2916 if (eth_s_id == NULL) {
2917 memset(&(attr->evpn_overlay.eth_s_id), 0,
2918 sizeof(struct eth_segment_id));
2919 } else {
2920 memcpy(&(attr->evpn_overlay.eth_s_id), eth_s_id,
2921 sizeof(struct eth_segment_id));
2922 }
2923 if (gw_ip == NULL) {
2924 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
2925 } else {
2926 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
2927 sizeof(union gw_addr));
2928 }
2929 }
2930
2931 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
2932 struct eth_segment_id *eth_s_id,
2933 union gw_addr *gw_ip)
2934 {
2935 struct eth_segment_id *path_eth_s_id, *path_eth_s_id_remote;
2936 union gw_addr *path_gw_ip, *path_gw_ip_remote;
2937 union {
2938 struct eth_segment_id esi;
2939 union gw_addr ip;
2940 } temp;
2941
2942 if (afi != AFI_L2VPN)
2943 return true;
2944
2945 path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id);
2946 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
2947
2948 if (gw_ip == NULL) {
2949 memset(&temp, 0, sizeof(temp));
2950 path_gw_ip_remote = &temp.ip;
2951 } else
2952 path_gw_ip_remote = gw_ip;
2953
2954 if (eth_s_id == NULL) {
2955 memset(&temp, 0, sizeof(temp));
2956 path_eth_s_id_remote = &temp.esi;
2957 } else
2958 path_eth_s_id_remote = eth_s_id;
2959
2960 if (!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)))
2961 return false;
2962
2963 return !memcmp(path_eth_s_id, path_eth_s_id_remote,
2964 sizeof(struct eth_segment_id));
2965 }
2966
2967 /* Check if received nexthop is valid or not. */
2968 static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
2969 struct attr *attr)
2970 {
2971 int ret = 0;
2972
2973 /* Only validated for unicast and multicast currently. */
2974 /* Also valid for EVPN where the nexthop is an IP address. */
2975 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN)
2976 return 0;
2977
2978 /* If NEXT_HOP is present, validate it. */
2979 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
2980 if (attr->nexthop.s_addr == 0
2981 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
2982 || bgp_nexthop_self(bgp, attr->nexthop))
2983 return 1;
2984 }
2985
2986 /* If MP_NEXTHOP is present, validate it. */
2987 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2988 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2989 * it is not an IPv6 link-local address.
2990 */
2991 if (attr->mp_nexthop_len) {
2992 switch (attr->mp_nexthop_len) {
2993 case BGP_ATTR_NHLEN_IPV4:
2994 case BGP_ATTR_NHLEN_VPNV4:
2995 ret = (attr->mp_nexthop_global_in.s_addr == 0
2996 || IPV4_CLASS_DE(ntohl(
2997 attr->mp_nexthop_global_in.s_addr))
2998 || bgp_nexthop_self(bgp,
2999 attr->mp_nexthop_global_in));
3000 break;
3001
3002 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3003 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3004 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3005 ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global)
3006 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3007 || IN6_IS_ADDR_MULTICAST(
3008 &attr->mp_nexthop_global));
3009 break;
3010
3011 default:
3012 ret = 1;
3013 break;
3014 }
3015 }
3016
3017 return ret;
3018 }
3019
3020 int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
3021 struct attr *attr, afi_t afi, safi_t safi, int type,
3022 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3023 uint32_t num_labels, int soft_reconfig,
3024 struct bgp_route_evpn *evpn)
3025 {
3026 int ret;
3027 int aspath_loop_count = 0;
3028 struct bgp_node *rn;
3029 struct bgp *bgp;
3030 struct attr new_attr;
3031 struct attr *attr_new;
3032 struct bgp_path_info *pi;
3033 struct bgp_path_info *new;
3034 struct bgp_path_info_extra *extra;
3035 const char *reason;
3036 char pfx_buf[BGP_PRD_PATH_STRLEN];
3037 int connected = 0;
3038 int do_loop_check = 1;
3039 int has_valid_label = 0;
3040 #if ENABLE_BGP_VNC
3041 int vnc_implicit_withdraw = 0;
3042 #endif
3043 int same_attr = 0;
3044
3045 memset(&new_attr, 0, sizeof(struct attr));
3046 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3047 new_attr.label = MPLS_INVALID_LABEL;
3048
3049 bgp = peer->bgp;
3050 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3051 /* TODO: Check to see if we can get rid of "is_valid_label" */
3052 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3053 has_valid_label = (num_labels > 0) ? 1 : 0;
3054 else
3055 has_valid_label = bgp_is_valid_label(label);
3056
3057 /* When peer's soft reconfiguration enabled. Record input packet in
3058 Adj-RIBs-In. */
3059 if (!soft_reconfig
3060 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3061 && peer != bgp->peer_self)
3062 bgp_adj_in_set(rn, peer, attr, addpath_id);
3063
3064 /* Check previously received route. */
3065 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
3066 if (pi->peer == peer && pi->type == type
3067 && pi->sub_type == sub_type
3068 && pi->addpath_rx_id == addpath_id)
3069 break;
3070
3071 /* AS path local-as loop check. */
3072 if (peer->change_local_as) {
3073 if (peer->allowas_in[afi][safi])
3074 aspath_loop_count = peer->allowas_in[afi][safi];
3075 else if (!CHECK_FLAG(peer->flags,
3076 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3077 aspath_loop_count = 1;
3078
3079 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3080 > aspath_loop_count) {
3081 peer->stat_pfx_aspath_loop++;
3082 reason = "as-path contains our own AS;";
3083 goto filtered;
3084 }
3085 }
3086
3087 /* If the peer is configured for "allowas-in origin" and the last ASN in
3088 * the
3089 * as-path is our ASN then we do not need to call aspath_loop_check
3090 */
3091 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3092 if (aspath_get_last_as(attr->aspath) == bgp->as)
3093 do_loop_check = 0;
3094
3095 /* AS path loop check. */
3096 if (do_loop_check) {
3097 if (aspath_loop_check(attr->aspath, bgp->as)
3098 > peer->allowas_in[afi][safi]
3099 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3100 && aspath_loop_check(attr->aspath, bgp->confed_id)
3101 > peer->allowas_in[afi][safi])) {
3102 peer->stat_pfx_aspath_loop++;
3103 reason = "as-path contains our own AS;";
3104 goto filtered;
3105 }
3106 }
3107
3108 /* Route reflector originator ID check. */
3109 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3110 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3111 peer->stat_pfx_originator_loop++;
3112 reason = "originator is us;";
3113 goto filtered;
3114 }
3115
3116 /* Route reflector cluster ID check. */
3117 if (bgp_cluster_filter(peer, attr)) {
3118 peer->stat_pfx_cluster_loop++;
3119 reason = "reflected from the same cluster;";
3120 goto filtered;
3121 }
3122
3123 /* Apply incoming filter. */
3124 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3125 peer->stat_pfx_filter++;
3126 reason = "filter;";
3127 goto filtered;
3128 }
3129
3130 /* RFC 8212 to prevent route leaks.
3131 * This specification intends to improve this situation by requiring the
3132 * explicit configuration of both BGP Import and Export Policies for any
3133 * External BGP (EBGP) session such as customers, peers, or
3134 * confederation boundaries for all enabled address families. Through
3135 * codification of the aforementioned requirement, operators will
3136 * benefit from consistent behavior across different BGP
3137 * implementations.
3138 */
3139 if (peer->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED)
3140 if (!bgp_inbound_policy_exists(peer,
3141 &peer->filter[afi][safi])) {
3142 reason = "inbound policy missing";
3143 goto filtered;
3144 }
3145
3146 bgp_attr_dup(&new_attr, attr);
3147
3148 /* Apply incoming route-map.
3149 * NB: new_attr may now contain newly allocated values from route-map
3150 * "set"
3151 * commands, so we need bgp_attr_flush in the error paths, until we
3152 * intern
3153 * the attr (which takes over the memory references) */
3154 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
3155 label, num_labels) == RMAP_DENY) {
3156 peer->stat_pfx_filter++;
3157 reason = "route-map;";
3158 bgp_attr_flush(&new_attr);
3159 goto filtered;
3160 }
3161
3162 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3163 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3164 /* remove from RIB previous entry */
3165 bgp_zebra_withdraw(p, pi, bgp, safi);
3166 }
3167
3168 if (peer->sort == BGP_PEER_EBGP) {
3169
3170 /* If we receive the graceful-shutdown community from an eBGP
3171 * peer we must lower local-preference */
3172 if (new_attr.community
3173 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3174 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3175 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3176
3177 /* If graceful-shutdown is configured then add the GSHUT
3178 * community to all paths received from eBGP peers */
3179 } else if (bgp_flag_check(peer->bgp,
3180 BGP_FLAG_GRACEFUL_SHUTDOWN)) {
3181 bgp_attr_add_gshut_community(&new_attr);
3182 }
3183 }
3184
3185 /* next hop check. */
3186 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3187 && bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) {
3188 peer->stat_pfx_nh_invalid++;
3189 reason = "martian or self next-hop;";
3190 bgp_attr_flush(&new_attr);
3191 goto filtered;
3192 }
3193
3194 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3195 peer->stat_pfx_nh_invalid++;
3196 reason = "self mac;";
3197 goto filtered;
3198 }
3199
3200 attr_new = bgp_attr_intern(&new_attr);
3201
3202 /* If the update is implicit withdraw. */
3203 if (pi) {
3204 pi->uptime = bgp_clock();
3205 same_attr = attrhash_cmp(pi->attr, attr_new);
3206
3207 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3208
3209 /* Same attribute comes in. */
3210 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3211 && attrhash_cmp(pi->attr, attr_new)
3212 && (!has_valid_label
3213 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3214 num_labels * sizeof(mpls_label_t))
3215 == 0)
3216 && (overlay_index_equal(
3217 afi, pi, evpn == NULL ? NULL : &evpn->eth_s_id,
3218 evpn == NULL ? NULL : &evpn->gw_ip))) {
3219 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3220 BGP_CONFIG_DAMPENING)
3221 && peer->sort == BGP_PEER_EBGP
3222 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3223 if (bgp_debug_update(peer, p, NULL, 1)) {
3224 bgp_debug_rdpfxpath2str(
3225 afi, safi, prd, p, label,
3226 num_labels, addpath_id ? 1 : 0,
3227 addpath_id, pfx_buf,
3228 sizeof(pfx_buf));
3229 zlog_debug("%s rcvd %s", peer->host,
3230 pfx_buf);
3231 }
3232
3233 if (bgp_damp_update(pi, rn, afi, safi)
3234 != BGP_DAMP_SUPPRESSED) {
3235 bgp_aggregate_increment(bgp, p, pi, afi,
3236 safi);
3237 bgp_process(bgp, rn, afi, safi);
3238 }
3239 } else /* Duplicate - odd */
3240 {
3241 if (bgp_debug_update(peer, p, NULL, 1)) {
3242 if (!peer->rcvd_attr_printed) {
3243 zlog_debug(
3244 "%s rcvd UPDATE w/ attr: %s",
3245 peer->host,
3246 peer->rcvd_attr_str);
3247 peer->rcvd_attr_printed = 1;
3248 }
3249
3250 bgp_debug_rdpfxpath2str(
3251 afi, safi, prd, p, label,
3252 num_labels, addpath_id ? 1 : 0,
3253 addpath_id, pfx_buf,
3254 sizeof(pfx_buf));
3255 zlog_debug(
3256 "%s rcvd %s...duplicate ignored",
3257 peer->host, pfx_buf);
3258 }
3259
3260 /* graceful restart STALE flag unset. */
3261 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3262 bgp_path_info_unset_flag(
3263 rn, pi, BGP_PATH_STALE);
3264 bgp_process(bgp, rn, afi, safi);
3265 }
3266 }
3267
3268 bgp_unlock_node(rn);
3269 bgp_attr_unintern(&attr_new);
3270
3271 return 0;
3272 }
3273
3274 /* Withdraw/Announce before we fully processed the withdraw */
3275 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3276 if (bgp_debug_update(peer, p, NULL, 1)) {
3277 bgp_debug_rdpfxpath2str(
3278 afi, safi, prd, p, label, num_labels,
3279 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3280 sizeof(pfx_buf));
3281 zlog_debug(
3282 "%s rcvd %s, flapped quicker than processing",
3283 peer->host, pfx_buf);
3284 }
3285
3286 bgp_path_info_restore(rn, pi);
3287 }
3288
3289 /* Received Logging. */
3290 if (bgp_debug_update(peer, p, NULL, 1)) {
3291 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3292 num_labels, addpath_id ? 1 : 0,
3293 addpath_id, pfx_buf,
3294 sizeof(pfx_buf));
3295 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3296 }
3297
3298 /* graceful restart STALE flag unset. */
3299 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
3300 bgp_path_info_unset_flag(rn, pi, BGP_PATH_STALE);
3301
3302 /* The attribute is changed. */
3303 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
3304
3305 /* implicit withdraw, decrement aggregate and pcount here.
3306 * only if update is accepted, they'll increment below.
3307 */
3308 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3309
3310 /* Update bgp route dampening information. */
3311 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3312 && peer->sort == BGP_PEER_EBGP) {
3313 /* This is implicit withdraw so we should update
3314 dampening
3315 information. */
3316 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3317 bgp_damp_withdraw(pi, rn, afi, safi, 1);
3318 }
3319 #if ENABLE_BGP_VNC
3320 if (safi == SAFI_MPLS_VPN) {
3321 struct bgp_node *prn = NULL;
3322 struct bgp_table *table = NULL;
3323
3324 prn = bgp_node_get(bgp->rib[afi][safi],
3325 (struct prefix *)prd);
3326 if (bgp_node_has_bgp_path_info_data(prn)) {
3327 table = bgp_node_get_bgp_table_info(prn);
3328
3329 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3330 bgp, prd, table, p, pi);
3331 }
3332 bgp_unlock_node(prn);
3333 }
3334 if ((afi == AFI_IP || afi == AFI_IP6)
3335 && (safi == SAFI_UNICAST)) {
3336 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3337 /*
3338 * Implicit withdraw case.
3339 */
3340 ++vnc_implicit_withdraw;
3341 vnc_import_bgp_del_route(bgp, p, pi);
3342 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3343 }
3344 }
3345 #endif
3346
3347 /* Special handling for EVPN update of an existing route. If the
3348 * extended community attribute has changed, we need to
3349 * un-import
3350 * the route using its existing extended community. It will be
3351 * subsequently processed for import with the new extended
3352 * community.
3353 */
3354 if (safi == SAFI_EVPN && !same_attr) {
3355 if ((pi->attr->flag
3356 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3357 && (attr_new->flag
3358 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3359 int cmp;
3360
3361 cmp = ecommunity_cmp(pi->attr->ecommunity,
3362 attr_new->ecommunity);
3363 if (!cmp) {
3364 if (bgp_debug_update(peer, p, NULL, 1))
3365 zlog_debug(
3366 "Change in EXT-COMM, existing %s new %s",
3367 ecommunity_str(
3368 pi->attr->ecommunity),
3369 ecommunity_str(
3370 attr_new->ecommunity));
3371 bgp_evpn_unimport_route(bgp, afi, safi,
3372 p, pi);
3373 }
3374 }
3375 }
3376
3377 /* Update to new attribute. */
3378 bgp_attr_unintern(&pi->attr);
3379 pi->attr = attr_new;
3380
3381 /* Update MPLS label */
3382 if (has_valid_label) {
3383 extra = bgp_path_info_extra_get(pi);
3384 if (extra->label != label) {
3385 memcpy(&extra->label, label,
3386 num_labels * sizeof(mpls_label_t));
3387 extra->num_labels = num_labels;
3388 }
3389 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3390 bgp_set_valid_label(&extra->label[0]);
3391 }
3392
3393 #if ENABLE_BGP_VNC
3394 if ((afi == AFI_IP || afi == AFI_IP6)
3395 && (safi == SAFI_UNICAST)) {
3396 if (vnc_implicit_withdraw) {
3397 /*
3398 * Add back the route with its new attributes
3399 * (e.g., nexthop).
3400 * The route is still selected, until the route
3401 * selection
3402 * queued by bgp_process actually runs. We have
3403 * to make this
3404 * update to the VNC side immediately to avoid
3405 * racing against
3406 * configuration changes (e.g., route-map
3407 * changes) which
3408 * trigger re-importation of the entire RIB.
3409 */
3410 vnc_import_bgp_add_route(bgp, p, pi);
3411 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3412 }
3413 }
3414 #endif
3415 /* Update Overlay Index */
3416 if (afi == AFI_L2VPN) {
3417 overlay_index_update(
3418 pi->attr, evpn == NULL ? NULL : &evpn->eth_s_id,
3419 evpn == NULL ? NULL : &evpn->gw_ip);
3420 }
3421
3422 /* Update bgp route dampening information. */
3423 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3424 && peer->sort == BGP_PEER_EBGP) {
3425 /* Now we do normal update dampening. */
3426 ret = bgp_damp_update(pi, rn, afi, safi);
3427 if (ret == BGP_DAMP_SUPPRESSED) {
3428 bgp_unlock_node(rn);
3429 return 0;
3430 }
3431 }
3432
3433 /* Nexthop reachability check - for unicast and
3434 * labeled-unicast.. */
3435 if ((afi == AFI_IP || afi == AFI_IP6)
3436 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
3437 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
3438 && !CHECK_FLAG(peer->flags,
3439 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3440 && !bgp_flag_check(
3441 bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3442 connected = 1;
3443 else
3444 connected = 0;
3445
3446 struct bgp *bgp_nexthop = bgp;
3447
3448 if (pi->extra && pi->extra->bgp_orig)
3449 bgp_nexthop = pi->extra->bgp_orig;
3450
3451 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, pi,
3452 NULL, connected)
3453 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3454 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3455 else {
3456 if (BGP_DEBUG(nht, NHT)) {
3457 char buf1[INET6_ADDRSTRLEN];
3458 inet_ntop(AF_INET,
3459 (const void *)&attr_new
3460 ->nexthop,
3461 buf1, INET6_ADDRSTRLEN);
3462 zlog_debug("%s(%s): NH unresolved",
3463 __FUNCTION__, buf1);
3464 }
3465 bgp_path_info_unset_flag(rn, pi,
3466 BGP_PATH_VALID);
3467 }
3468 } else
3469 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3470
3471 #if ENABLE_BGP_VNC
3472 if (safi == SAFI_MPLS_VPN) {
3473 struct bgp_node *prn = NULL;
3474 struct bgp_table *table = NULL;
3475
3476 prn = bgp_node_get(bgp->rib[afi][safi],
3477 (struct prefix *)prd);
3478 if (bgp_node_has_bgp_path_info_data(prn)) {
3479 table = bgp_node_get_bgp_table_info(prn);
3480
3481 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3482 bgp, prd, table, p, pi);
3483 }
3484 bgp_unlock_node(prn);
3485 }
3486 #endif
3487
3488 /* If this is an EVPN route and some attribute has changed,
3489 * process
3490 * route for import. If the extended community has changed, we
3491 * would
3492 * have done the un-import earlier and the import would result
3493 * in the
3494 * route getting injected into appropriate L2 VNIs. If it is
3495 * just
3496 * some other attribute change, the import will result in
3497 * updating
3498 * the attributes for the route in the VNI(s).
3499 */
3500 if (safi == SAFI_EVPN && !same_attr)
3501 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3502
3503 /* Process change. */
3504 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3505
3506 bgp_process(bgp, rn, afi, safi);
3507 bgp_unlock_node(rn);
3508
3509 if (SAFI_UNICAST == safi
3510 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3511 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3512
3513 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3514 }
3515 if ((SAFI_MPLS_VPN == safi)
3516 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3517
3518 vpn_leak_to_vrf_update(bgp, pi);
3519 }
3520
3521 #if ENABLE_BGP_VNC
3522 if (SAFI_MPLS_VPN == safi) {
3523 mpls_label_t label_decoded = decode_label(label);
3524
3525 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3526 type, sub_type, &label_decoded);
3527 }
3528 if (SAFI_ENCAP == safi) {
3529 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3530 type, sub_type, NULL);
3531 }
3532 #endif
3533
3534 return 0;
3535 } // End of implicit withdraw
3536
3537 /* Received Logging. */
3538 if (bgp_debug_update(peer, p, NULL, 1)) {
3539 if (!peer->rcvd_attr_printed) {
3540 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3541 peer->rcvd_attr_str);
3542 peer->rcvd_attr_printed = 1;
3543 }
3544
3545 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3546 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3547 sizeof(pfx_buf));
3548 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3549 }
3550
3551 /* Make new BGP info. */
3552 new = info_make(type, sub_type, 0, peer, attr_new, rn);
3553
3554 /* Update MPLS label */
3555 if (has_valid_label) {
3556 extra = bgp_path_info_extra_get(new);
3557 if (extra->label != label) {
3558 memcpy(&extra->label, label,
3559 num_labels * sizeof(mpls_label_t));
3560 extra->num_labels = num_labels;
3561 }
3562 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3563 bgp_set_valid_label(&extra->label[0]);
3564 }
3565
3566 /* Update Overlay Index */
3567 if (afi == AFI_L2VPN) {
3568 overlay_index_update(new->attr,
3569 evpn == NULL ? NULL : &evpn->eth_s_id,
3570 evpn == NULL ? NULL : &evpn->gw_ip);
3571 }
3572 /* Nexthop reachability check. */
3573 if ((afi == AFI_IP || afi == AFI_IP6)
3574 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
3575 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
3576 && !CHECK_FLAG(peer->flags,
3577 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3578 && !bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3579 connected = 1;
3580 else
3581 connected = 0;
3582
3583 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, connected)
3584 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3585 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3586 else {
3587 if (BGP_DEBUG(nht, NHT)) {
3588 char buf1[INET6_ADDRSTRLEN];
3589 inet_ntop(AF_INET,
3590 (const void *)&attr_new->nexthop,
3591 buf1, INET6_ADDRSTRLEN);
3592 zlog_debug("%s(%s): NH unresolved",
3593 __FUNCTION__, buf1);
3594 }
3595 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
3596 }
3597 } else
3598 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3599
3600 /* Addpath ID */
3601 new->addpath_rx_id = addpath_id;
3602
3603 /* Increment prefix */
3604 bgp_aggregate_increment(bgp, p, new, afi, safi);
3605
3606 /* Register new BGP information. */
3607 bgp_path_info_add(rn, new);
3608
3609 /* route_node_get lock */
3610 bgp_unlock_node(rn);
3611
3612 #if ENABLE_BGP_VNC
3613 if (safi == SAFI_MPLS_VPN) {
3614 struct bgp_node *prn = NULL;
3615 struct bgp_table *table = NULL;
3616
3617 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
3618 if (bgp_node_has_bgp_path_info_data(prn)) {
3619 table = bgp_node_get_bgp_table_info(prn);
3620
3621 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3622 bgp, prd, table, p, new);
3623 }
3624 bgp_unlock_node(prn);
3625 }
3626 #endif
3627
3628 /* If maximum prefix count is configured and current prefix
3629 count exeed it. */
3630 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3631 return -1;
3632
3633 /* If this is an EVPN route, process for import. */
3634 if (safi == SAFI_EVPN)
3635 bgp_evpn_import_route(bgp, afi, safi, p, new);
3636
3637 hook_call(bgp_process, bgp, afi, safi, rn, peer, false);
3638
3639 /* Process change. */
3640 bgp_process(bgp, rn, afi, safi);
3641
3642 if (SAFI_UNICAST == safi
3643 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3644 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3645 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
3646 }
3647 if ((SAFI_MPLS_VPN == safi)
3648 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3649
3650 vpn_leak_to_vrf_update(bgp, new);
3651 }
3652 #if ENABLE_BGP_VNC
3653 if (SAFI_MPLS_VPN == safi) {
3654 mpls_label_t label_decoded = decode_label(label);
3655
3656 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3657 sub_type, &label_decoded);
3658 }
3659 if (SAFI_ENCAP == safi) {
3660 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3661 sub_type, NULL);
3662 }
3663 #endif
3664
3665 return 0;
3666
3667 /* This BGP update is filtered. Log the reason then update BGP
3668 entry. */
3669 filtered:
3670 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3671
3672 if (bgp_debug_update(peer, p, NULL, 1)) {
3673 if (!peer->rcvd_attr_printed) {
3674 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3675 peer->rcvd_attr_str);
3676 peer->rcvd_attr_printed = 1;
3677 }
3678
3679 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3680 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3681 sizeof(pfx_buf));
3682 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3683 peer->host, pfx_buf, reason);
3684 }
3685
3686 if (pi) {
3687 /* If this is an EVPN route, un-import it as it is now filtered.
3688 */
3689 if (safi == SAFI_EVPN)
3690 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
3691
3692 if (SAFI_UNICAST == safi
3693 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3694 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3695
3696 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
3697 }
3698 if ((SAFI_MPLS_VPN == safi)
3699 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3700
3701 vpn_leak_to_vrf_withdraw(bgp, pi);
3702 }
3703
3704 bgp_rib_remove(rn, pi, peer, afi, safi);
3705 }
3706
3707 bgp_unlock_node(rn);
3708
3709 #if ENABLE_BGP_VNC
3710 /*
3711 * Filtered update is treated as an implicit withdrawal (see
3712 * bgp_rib_remove()
3713 * a few lines above)
3714 */
3715 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
3716 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
3717 0);
3718 }
3719 #endif
3720
3721 return 0;
3722 }
3723
3724 int bgp_withdraw(struct peer *peer, struct prefix *p, uint32_t addpath_id,
3725 struct attr *attr, afi_t afi, safi_t safi, int type,
3726 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3727 uint32_t num_labels, struct bgp_route_evpn *evpn)
3728 {
3729 struct bgp *bgp;
3730 char pfx_buf[BGP_PRD_PATH_STRLEN];
3731 struct bgp_node *rn;
3732 struct bgp_path_info *pi;
3733
3734 #if ENABLE_BGP_VNC
3735 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
3736 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
3737 0);
3738 }
3739 #endif
3740
3741 bgp = peer->bgp;
3742
3743 /* Lookup node. */
3744 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3745
3746 /* If peer is soft reconfiguration enabled. Record input packet for
3747 * further calculation.
3748 *
3749 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3750 * routes that are filtered. This tanks out Quagga RS pretty badly due
3751 * to
3752 * the iteration over all RS clients.
3753 * Since we need to remove the entry from adj_in anyway, do that first
3754 * and
3755 * if there was no entry, we don't need to do anything more.
3756 */
3757 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3758 && peer != bgp->peer_self)
3759 if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
3760 peer->stat_pfx_dup_withdraw++;
3761
3762 if (bgp_debug_update(peer, p, NULL, 1)) {
3763 bgp_debug_rdpfxpath2str(
3764 afi, safi, prd, p, label, num_labels,
3765 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3766 sizeof(pfx_buf));
3767 zlog_debug(
3768 "%s withdrawing route %s not in adj-in",
3769 peer->host, pfx_buf);
3770 }
3771 bgp_unlock_node(rn);
3772 return 0;
3773 }
3774
3775 /* Lookup withdrawn route. */
3776 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
3777 if (pi->peer == peer && pi->type == type
3778 && pi->sub_type == sub_type
3779 && pi->addpath_rx_id == addpath_id)
3780 break;
3781
3782 /* Logging. */
3783 if (bgp_debug_update(peer, p, NULL, 1)) {
3784 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3785 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3786 sizeof(pfx_buf));
3787 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
3788 pfx_buf);
3789 }
3790
3791 /* Withdraw specified route from routing table. */
3792 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3793 bgp_rib_withdraw(rn, pi, peer, afi, safi, prd);
3794 if (SAFI_UNICAST == safi
3795 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3796 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3797 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
3798 }
3799 if ((SAFI_MPLS_VPN == safi)
3800 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3801
3802 vpn_leak_to_vrf_withdraw(bgp, pi);
3803 }
3804 } else if (bgp_debug_update(peer, p, NULL, 1)) {
3805 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3806 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3807 sizeof(pfx_buf));
3808 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
3809 }
3810
3811 /* Unlock bgp_node_get() lock. */
3812 bgp_unlock_node(rn);
3813
3814 return 0;
3815 }
3816
3817 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
3818 int withdraw)
3819 {
3820 struct update_subgroup *subgrp;
3821 subgrp = peer_subgroup(peer, afi, safi);
3822 subgroup_default_originate(subgrp, withdraw);
3823 }
3824
3825
3826 /*
3827 * bgp_stop_announce_route_timer
3828 */
3829 void bgp_stop_announce_route_timer(struct peer_af *paf)
3830 {
3831 if (!paf->t_announce_route)
3832 return;
3833
3834 THREAD_TIMER_OFF(paf->t_announce_route);
3835 }
3836
3837 /*
3838 * bgp_announce_route_timer_expired
3839 *
3840 * Callback that is invoked when the route announcement timer for a
3841 * peer_af expires.
3842 */
3843 static int bgp_announce_route_timer_expired(struct thread *t)
3844 {
3845 struct peer_af *paf;
3846 struct peer *peer;
3847
3848 paf = THREAD_ARG(t);
3849 peer = paf->peer;
3850
3851 if (peer->status != Established)
3852 return 0;
3853
3854 if (!peer->afc_nego[paf->afi][paf->safi])
3855 return 0;
3856
3857 peer_af_announce_route(paf, 1);
3858 return 0;
3859 }
3860
3861 /*
3862 * bgp_announce_route
3863 *
3864 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3865 */
3866 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
3867 {
3868 struct peer_af *paf;
3869 struct update_subgroup *subgrp;
3870
3871 paf = peer_af_find(peer, afi, safi);
3872 if (!paf)
3873 return;
3874 subgrp = PAF_SUBGRP(paf);
3875
3876 /*
3877 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3878 * or a refresh has already been triggered.
3879 */
3880 if (!subgrp || paf->t_announce_route)
3881 return;
3882
3883 /*
3884 * Start a timer to stagger/delay the announce. This serves
3885 * two purposes - announcement can potentially be combined for
3886 * multiple peers and the announcement doesn't happen in the
3887 * vty context.
3888 */
3889 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
3890 (subgrp->peer_count == 1)
3891 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3892 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
3893 &paf->t_announce_route);
3894 }
3895
3896 /*
3897 * Announce routes from all AF tables to a peer.
3898 *
3899 * This should ONLY be called when there is a need to refresh the
3900 * routes to the peer based on a policy change for this peer alone
3901 * or a route refresh request received from the peer.
3902 * The operation will result in splitting the peer from its existing
3903 * subgroups and putting it in new subgroups.
3904 */
3905 void bgp_announce_route_all(struct peer *peer)
3906 {
3907 afi_t afi;
3908 safi_t safi;
3909
3910 FOREACH_AFI_SAFI (afi, safi)
3911 bgp_announce_route(peer, afi, safi);
3912 }
3913
3914 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
3915 struct bgp_table *table,
3916 struct prefix_rd *prd)
3917 {
3918 int ret;
3919 struct bgp_node *rn;
3920 struct bgp_adj_in *ain;
3921
3922 if (!table)
3923 table = peer->bgp->rib[afi][safi];
3924
3925 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
3926 for (ain = rn->adj_in; ain; ain = ain->next) {
3927 if (ain->peer != peer)
3928 continue;
3929
3930 struct bgp_path_info *pi;
3931 uint32_t num_labels = 0;
3932 mpls_label_t *label_pnt = NULL;
3933 struct bgp_route_evpn evpn;
3934
3935 for (pi = bgp_node_get_bgp_path_info(rn); pi;
3936 pi = pi->next)
3937 if (pi->peer == peer)
3938 break;
3939
3940 if (pi && pi->extra)
3941 num_labels = pi->extra->num_labels;
3942 if (num_labels)
3943 label_pnt = &pi->extra->label[0];
3944 if (pi)
3945 memcpy(&evpn, &pi->attr->evpn_overlay,
3946 sizeof(evpn));
3947 else
3948 memset(&evpn, 0, sizeof(evpn));
3949
3950 ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
3951 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
3952 BGP_ROUTE_NORMAL, prd, label_pnt,
3953 num_labels, 1, &evpn);
3954
3955 if (ret < 0) {
3956 bgp_unlock_node(rn);
3957 return;
3958 }
3959 }
3960 }
3961
3962 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
3963 {
3964 struct bgp_node *rn;
3965 struct bgp_table *table;
3966
3967 if (peer->status != Established)
3968 return;
3969
3970 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
3971 && (safi != SAFI_EVPN))
3972 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
3973 else
3974 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
3975 rn = bgp_route_next(rn)) {
3976 table = bgp_node_get_bgp_table_info(rn);
3977 if (table != NULL) {
3978 struct prefix_rd prd;
3979
3980 prd.family = AF_UNSPEC;
3981 prd.prefixlen = 64;
3982 memcpy(&prd.val, rn->p.u.val, 8);
3983
3984 bgp_soft_reconfig_table(peer, afi, safi, table,
3985 &prd);
3986 }
3987 }
3988 }
3989
3990
3991 struct bgp_clear_node_queue {
3992 struct bgp_node *rn;
3993 };
3994
3995 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
3996 {
3997 struct bgp_clear_node_queue *cnq = data;
3998 struct bgp_node *rn = cnq->rn;
3999 struct peer *peer = wq->spec.data;
4000 struct bgp_path_info *pi;
4001 struct bgp *bgp;
4002 afi_t afi = bgp_node_table(rn)->afi;
4003 safi_t safi = bgp_node_table(rn)->safi;
4004
4005 assert(rn && peer);
4006 bgp = peer->bgp;
4007
4008 /* It is possible that we have multiple paths for a prefix from a peer
4009 * if that peer is using AddPath.
4010 */
4011 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
4012 if (pi->peer != peer)
4013 continue;
4014
4015 /* graceful restart STALE flag set. */
4016 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4017 && peer->nsf[afi][safi]
4018 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4019 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4020 bgp_path_info_set_flag(rn, pi, BGP_PATH_STALE);
4021 else {
4022 /* If this is an EVPN route, process for
4023 * un-import. */
4024 if (safi == SAFI_EVPN)
4025 bgp_evpn_unimport_route(bgp, afi, safi, &rn->p,
4026 pi);
4027 /* Handle withdraw for VRF route-leaking and L3VPN */
4028 if (SAFI_UNICAST == safi
4029 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4030 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4031 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4032 bgp, pi);
4033 }
4034 if (SAFI_MPLS_VPN == safi &&
4035 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4036 vpn_leak_to_vrf_withdraw(bgp, pi);
4037 }
4038
4039 bgp_rib_remove(rn, pi, peer, afi, safi);
4040 }
4041 }
4042 return WQ_SUCCESS;
4043 }
4044
4045 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4046 {
4047 struct bgp_clear_node_queue *cnq = data;
4048 struct bgp_node *rn = cnq->rn;
4049 struct bgp_table *table = bgp_node_table(rn);
4050
4051 bgp_unlock_node(rn);
4052 bgp_table_unlock(table);
4053 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4054 }
4055
4056 static void bgp_clear_node_complete(struct work_queue *wq)
4057 {
4058 struct peer *peer = wq->spec.data;
4059
4060 /* Tickle FSM to start moving again */
4061 BGP_EVENT_ADD(peer, Clearing_Completed);
4062
4063 peer_unlock(peer); /* bgp_clear_route */
4064 }
4065
4066 static void bgp_clear_node_queue_init(struct peer *peer)
4067 {
4068 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4069
4070 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4071 #undef CLEAR_QUEUE_NAME_LEN
4072
4073 peer->clear_node_queue = work_queue_new(bm->master, wname);
4074 peer->clear_node_queue->spec.hold = 10;
4075 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4076 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4077 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4078 peer->clear_node_queue->spec.max_retries = 0;
4079
4080 /* we only 'lock' this peer reference when the queue is actually active
4081 */
4082 peer->clear_node_queue->spec.data = peer;
4083 }
4084
4085 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4086 struct bgp_table *table)
4087 {
4088 struct bgp_node *rn;
4089 int force = bm->process_main_queue ? 0 : 1;
4090
4091 if (!table)
4092 table = peer->bgp->rib[afi][safi];
4093
4094 /* If still no table => afi/safi isn't configured at all or smth. */
4095 if (!table)
4096 return;
4097
4098 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4099 struct bgp_path_info *pi, *next;
4100 struct bgp_adj_in *ain;
4101 struct bgp_adj_in *ain_next;
4102
4103 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4104 * queued for every clearing peer, regardless of whether it is
4105 * relevant to the peer at hand.
4106 *
4107 * Overview: There are 3 different indices which need to be
4108 * scrubbed, potentially, when a peer is removed:
4109 *
4110 * 1 peer's routes visible via the RIB (ie accepted routes)
4111 * 2 peer's routes visible by the (optional) peer's adj-in index
4112 * 3 other routes visible by the peer's adj-out index
4113 *
4114 * 3 there is no hurry in scrubbing, once the struct peer is
4115 * removed from bgp->peer, we could just GC such deleted peer's
4116 * adj-outs at our leisure.
4117 *
4118 * 1 and 2 must be 'scrubbed' in some way, at least made
4119 * invisible via RIB index before peer session is allowed to be
4120 * brought back up. So one needs to know when such a 'search' is
4121 * complete.
4122 *
4123 * Ideally:
4124 *
4125 * - there'd be a single global queue or a single RIB walker
4126 * - rather than tracking which route_nodes still need to be
4127 * examined on a peer basis, we'd track which peers still
4128 * aren't cleared
4129 *
4130 * Given that our per-peer prefix-counts now should be reliable,
4131 * this may actually be achievable. It doesn't seem to be a huge
4132 * problem at this time,
4133 *
4134 * It is possible that we have multiple paths for a prefix from
4135 * a peer
4136 * if that peer is using AddPath.
4137 */
4138 ain = rn->adj_in;
4139 while (ain) {
4140 ain_next = ain->next;
4141
4142 if (ain->peer == peer) {
4143 bgp_adj_in_remove(rn, ain);
4144 bgp_unlock_node(rn);
4145 }
4146
4147 ain = ain_next;
4148 }
4149
4150 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4151 next = pi->next;
4152 if (pi->peer != peer)
4153 continue;
4154
4155 if (force)
4156 bgp_path_info_reap(rn, pi);
4157 else {
4158 struct bgp_clear_node_queue *cnq;
4159
4160 /* both unlocked in bgp_clear_node_queue_del */
4161 bgp_table_lock(bgp_node_table(rn));
4162 bgp_lock_node(rn);
4163 cnq = XCALLOC(
4164 MTYPE_BGP_CLEAR_NODE_QUEUE,
4165 sizeof(struct bgp_clear_node_queue));
4166 cnq->rn = rn;
4167 work_queue_add(peer->clear_node_queue, cnq);
4168 break;
4169 }
4170 }
4171 }
4172 return;
4173 }
4174
4175 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4176 {
4177 struct bgp_node *rn;
4178 struct bgp_table *table;
4179
4180 if (peer->clear_node_queue == NULL)
4181 bgp_clear_node_queue_init(peer);
4182
4183 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4184 * Idle until it receives a Clearing_Completed event. This protects
4185 * against peers which flap faster than we can we clear, which could
4186 * lead to:
4187 *
4188 * a) race with routes from the new session being installed before
4189 * clear_route_node visits the node (to delete the route of that
4190 * peer)
4191 * b) resource exhaustion, clear_route_node likely leads to an entry
4192 * on the process_main queue. Fast-flapping could cause that queue
4193 * to grow and grow.
4194 */
4195
4196 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4197 * the unlock will happen upon work-queue completion; other wise, the
4198 * unlock happens at the end of this function.
4199 */
4200 if (!peer->clear_node_queue->thread)
4201 peer_lock(peer);
4202
4203 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4204 bgp_clear_route_table(peer, afi, safi, NULL);
4205 else
4206 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4207 rn = bgp_route_next(rn)) {
4208 table = bgp_node_get_bgp_table_info(rn);
4209 if (!table)
4210 continue;
4211
4212 bgp_clear_route_table(peer, afi, safi, table);
4213 }
4214
4215 /* unlock if no nodes got added to the clear-node-queue. */
4216 if (!peer->clear_node_queue->thread)
4217 peer_unlock(peer);
4218 }
4219
4220 void bgp_clear_route_all(struct peer *peer)
4221 {
4222 afi_t afi;
4223 safi_t safi;
4224
4225 FOREACH_AFI_SAFI (afi, safi)
4226 bgp_clear_route(peer, afi, safi);
4227
4228 #if ENABLE_BGP_VNC
4229 rfapiProcessPeerDown(peer);
4230 #endif
4231 }
4232
4233 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4234 {
4235 struct bgp_table *table;
4236 struct bgp_node *rn;
4237 struct bgp_adj_in *ain;
4238 struct bgp_adj_in *ain_next;
4239
4240 table = peer->bgp->rib[afi][safi];
4241
4242 /* It is possible that we have multiple paths for a prefix from a peer
4243 * if that peer is using AddPath.
4244 */
4245 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4246 ain = rn->adj_in;
4247
4248 while (ain) {
4249 ain_next = ain->next;
4250
4251 if (ain->peer == peer) {
4252 bgp_adj_in_remove(rn, ain);
4253 bgp_unlock_node(rn);
4254 }
4255
4256 ain = ain_next;
4257 }
4258 }
4259 }
4260
4261 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4262 {
4263 struct bgp_node *rn;
4264 struct bgp_path_info *pi;
4265 struct bgp_table *table;
4266
4267 if (safi == SAFI_MPLS_VPN) {
4268 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4269 rn = bgp_route_next(rn)) {
4270 struct bgp_node *rm;
4271
4272 /* look for neighbor in tables */
4273 table = bgp_node_get_bgp_table_info(rn);
4274 if (!table)
4275 continue;
4276
4277 for (rm = bgp_table_top(table); rm;
4278 rm = bgp_route_next(rm))
4279 for (pi = bgp_node_get_bgp_path_info(rm); pi;
4280 pi = pi->next) {
4281 if (pi->peer != peer)
4282 continue;
4283 if (!CHECK_FLAG(pi->flags,
4284 BGP_PATH_STALE))
4285 break;
4286
4287 bgp_rib_remove(rm, pi, peer, afi, safi);
4288 break;
4289 }
4290 }
4291 } else {
4292 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4293 rn = bgp_route_next(rn))
4294 for (pi = bgp_node_get_bgp_path_info(rn); pi;
4295 pi = pi->next) {
4296 if (pi->peer != peer)
4297 continue;
4298 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4299 break;
4300 bgp_rib_remove(rn, pi, peer, afi, safi);
4301 break;
4302 }
4303 }
4304 }
4305
4306 int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4307 {
4308 if (peer->sort == BGP_PEER_EBGP
4309 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4310 || FILTER_LIST_OUT_NAME(filter)
4311 || DISTRIBUTE_OUT_NAME(filter)))
4312 return 1;
4313 return 0;
4314 }
4315
4316 int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4317 {
4318 if (peer->sort == BGP_PEER_EBGP
4319 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4320 || FILTER_LIST_IN_NAME(filter)
4321 || DISTRIBUTE_IN_NAME(filter)))
4322 return 1;
4323 return 0;
4324 }
4325
4326 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4327 safi_t safi)
4328 {
4329 struct bgp_node *rn;
4330 struct bgp_path_info *pi;
4331 struct bgp_path_info *next;
4332
4333 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4334 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4335 next = pi->next;
4336
4337 /* Unimport EVPN routes from VRFs */
4338 if (safi == SAFI_EVPN)
4339 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4340 SAFI_EVPN,
4341 &rn->p, pi);
4342
4343 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4344 && pi->type == ZEBRA_ROUTE_BGP
4345 && (pi->sub_type == BGP_ROUTE_NORMAL
4346 || pi->sub_type == BGP_ROUTE_AGGREGATE
4347 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4348
4349 if (bgp_fibupd_safi(safi))
4350 bgp_zebra_withdraw(&rn->p, pi, bgp,
4351 safi);
4352 bgp_path_info_reap(rn, pi);
4353 }
4354 }
4355 }
4356
4357 /* Delete all kernel routes. */
4358 void bgp_cleanup_routes(struct bgp *bgp)
4359 {
4360 afi_t afi;
4361 struct bgp_node *rn;
4362 struct bgp_table *table;
4363
4364 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4365 if (afi == AFI_L2VPN)
4366 continue;
4367 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4368 SAFI_UNICAST);
4369 /*
4370 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4371 */
4372 if (afi != AFI_L2VPN) {
4373 safi_t safi;
4374 safi = SAFI_MPLS_VPN;
4375 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4376 rn = bgp_route_next(rn)) {
4377 table = bgp_node_get_bgp_table_info(rn);
4378 if (table != NULL) {
4379 bgp_cleanup_table(bgp, table, safi);
4380 bgp_table_finish(&table);
4381 bgp_node_set_bgp_table_info(rn, NULL);
4382 bgp_unlock_node(rn);
4383 }
4384 }
4385 safi = SAFI_ENCAP;
4386 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4387 rn = bgp_route_next(rn)) {
4388 table = bgp_node_get_bgp_table_info(rn);
4389 if (table != NULL) {
4390 bgp_cleanup_table(bgp, table, safi);
4391 bgp_table_finish(&table);
4392 bgp_node_set_bgp_table_info(rn, NULL);
4393 bgp_unlock_node(rn);
4394 }
4395 }
4396 }
4397 }
4398 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
4399 rn = bgp_route_next(rn)) {
4400 table = bgp_node_get_bgp_table_info(rn);
4401 if (table != NULL) {
4402 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4403 bgp_table_finish(&table);
4404 bgp_node_set_bgp_table_info(rn, NULL);
4405 bgp_unlock_node(rn);
4406 }
4407 }
4408 }
4409
4410 void bgp_reset(void)
4411 {
4412 vty_reset();
4413 bgp_zclient_reset();
4414 access_list_reset();
4415 prefix_list_reset();
4416 }
4417
4418 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4419 {
4420 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4421 && CHECK_FLAG(peer->af_cap[afi][safi],
4422 PEER_CAP_ADDPATH_AF_TX_RCV));
4423 }
4424
4425 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4426 value. */
4427 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4428 struct bgp_nlri *packet)
4429 {
4430 uint8_t *pnt;
4431 uint8_t *lim;
4432 struct prefix p;
4433 int psize;
4434 int ret;
4435 afi_t afi;
4436 safi_t safi;
4437 int addpath_encoded;
4438 uint32_t addpath_id;
4439
4440 pnt = packet->nlri;
4441 lim = pnt + packet->length;
4442 afi = packet->afi;
4443 safi = packet->safi;
4444 addpath_id = 0;
4445 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4446
4447 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4448 syntactic validity. If the field is syntactically incorrect,
4449 then the Error Subcode is set to Invalid Network Field. */
4450 for (; pnt < lim; pnt += psize) {
4451 /* Clear prefix structure. */
4452 memset(&p, 0, sizeof(struct prefix));
4453
4454 if (addpath_encoded) {
4455
4456 /* When packet overflow occurs return immediately. */
4457 if (pnt + BGP_ADDPATH_ID_LEN > lim)
4458 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4459
4460 addpath_id = ntohl(*((uint32_t *)pnt));
4461 pnt += BGP_ADDPATH_ID_LEN;
4462 }
4463
4464 /* Fetch prefix length. */
4465 p.prefixlen = *pnt++;
4466 /* afi/safi validity already verified by caller,
4467 * bgp_update_receive */
4468 p.family = afi2family(afi);
4469
4470 /* Prefix length check. */
4471 if (p.prefixlen > prefix_blen(&p) * 8) {
4472 flog_err(
4473 EC_BGP_UPDATE_RCV,
4474 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4475 peer->host, p.prefixlen, packet->afi);
4476 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4477 }
4478
4479 /* Packet size overflow check. */
4480 psize = PSIZE(p.prefixlen);
4481
4482 /* When packet overflow occur return immediately. */
4483 if (pnt + psize > lim) {
4484 flog_err(
4485 EC_BGP_UPDATE_RCV,
4486 "%s [Error] Update packet error (prefix length %d overflows packet)",
4487 peer->host, p.prefixlen);
4488 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4489 }
4490
4491 /* Defensive coding, double-check the psize fits in a struct
4492 * prefix */
4493 if (psize > (ssize_t)sizeof(p.u)) {
4494 flog_err(
4495 EC_BGP_UPDATE_RCV,
4496 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4497 peer->host, p.prefixlen, sizeof(p.u));
4498 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4499 }
4500
4501 /* Fetch prefix from NLRI packet. */
4502 memcpy(p.u.val, pnt, psize);
4503
4504 /* Check address. */
4505 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4506 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4507 /* From RFC4271 Section 6.3:
4508 *
4509 * If a prefix in the NLRI field is semantically
4510 * incorrect
4511 * (e.g., an unexpected multicast IP address),
4512 * an error SHOULD
4513 * be logged locally, and the prefix SHOULD be
4514 * ignored.
4515 */
4516 flog_err(
4517 EC_BGP_UPDATE_RCV,
4518 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4519 peer->host, inet_ntoa(p.u.prefix4));
4520 continue;
4521 }
4522 }
4523
4524 /* Check address. */
4525 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4526 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4527 char buf[BUFSIZ];
4528
4529 flog_err(
4530 EC_BGP_UPDATE_RCV,
4531 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4532 peer->host,
4533 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4534 BUFSIZ));
4535
4536 continue;
4537 }
4538 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
4539 char buf[BUFSIZ];
4540
4541 flog_err(
4542 EC_BGP_UPDATE_RCV,
4543 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4544 peer->host,
4545 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4546 BUFSIZ));
4547
4548 continue;
4549 }
4550 }
4551
4552 /* Normal process. */
4553 if (attr)
4554 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
4555 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
4556 NULL, NULL, 0, 0, NULL);
4557 else
4558 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
4559 safi, ZEBRA_ROUTE_BGP,
4560 BGP_ROUTE_NORMAL, NULL, NULL, 0,
4561 NULL);
4562
4563 /* Do not send BGP notification twice when maximum-prefix count
4564 * overflow. */
4565 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4566 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
4567
4568 /* Address family configuration mismatch. */
4569 if (ret < 0)
4570 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
4571 }
4572
4573 /* Packet length consistency check. */
4574 if (pnt != lim) {
4575 flog_err(
4576 EC_BGP_UPDATE_RCV,
4577 "%s [Error] Update packet error (prefix length mismatch with total length)",
4578 peer->host);
4579 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4580 }
4581
4582 return BGP_NLRI_PARSE_OK;
4583 }
4584
4585 static struct bgp_static *bgp_static_new(void)
4586 {
4587 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
4588 }
4589
4590 static void bgp_static_free(struct bgp_static *bgp_static)
4591 {
4592 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4593 route_map_counter_decrement(bgp_static->rmap.map);
4594
4595 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4596 XFREE(MTYPE_BGP_STATIC, bgp_static);
4597 }
4598
4599 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4600 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4601 {
4602 struct bgp_node *rn;
4603 struct bgp_path_info *pi;
4604 struct bgp_path_info *new;
4605 struct bgp_path_info rmap_path;
4606 struct attr attr;
4607 struct attr *attr_new;
4608 route_map_result_t ret;
4609 #if ENABLE_BGP_VNC
4610 int vnc_implicit_withdraw = 0;
4611 #endif
4612
4613 assert(bgp_static);
4614 if (!bgp_static)
4615 return;
4616
4617 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4618
4619 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4620
4621 attr.nexthop = bgp_static->igpnexthop;
4622 attr.med = bgp_static->igpmetric;
4623 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4624
4625 if (bgp_static->atomic)
4626 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4627
4628 /* Store label index, if required. */
4629 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4630 attr.label_index = bgp_static->label_index;
4631 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4632 }
4633
4634 /* Apply route-map. */
4635 if (bgp_static->rmap.name) {
4636 struct attr attr_tmp = attr;
4637
4638 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4639 rmap_path.peer = bgp->peer_self;
4640 rmap_path.attr = &attr_tmp;
4641
4642 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4643
4644 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4645 &rmap_path);
4646
4647 bgp->peer_self->rmap_type = 0;
4648
4649 if (ret == RMAP_DENYMATCH) {
4650 /* Free uninterned attribute. */
4651 bgp_attr_flush(&attr_tmp);
4652
4653 /* Unintern original. */
4654 aspath_unintern(&attr.aspath);
4655 bgp_static_withdraw(bgp, p, afi, safi);
4656 return;
4657 }
4658
4659 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4660 bgp_attr_add_gshut_community(&attr_tmp);
4661
4662 attr_new = bgp_attr_intern(&attr_tmp);
4663 } else {
4664
4665 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4666 bgp_attr_add_gshut_community(&attr);
4667
4668 attr_new = bgp_attr_intern(&attr);
4669 }
4670
4671 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4672 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4673 && pi->sub_type == BGP_ROUTE_STATIC)
4674 break;
4675
4676 if (pi) {
4677 if (attrhash_cmp(pi->attr, attr_new)
4678 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4679 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4680 bgp_unlock_node(rn);
4681 bgp_attr_unintern(&attr_new);
4682 aspath_unintern(&attr.aspath);
4683 return;
4684 } else {
4685 /* The attribute is changed. */
4686 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4687
4688 /* Rewrite BGP route information. */
4689 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4690 bgp_path_info_restore(rn, pi);
4691 else
4692 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4693 #if ENABLE_BGP_VNC
4694 if ((afi == AFI_IP || afi == AFI_IP6)
4695 && (safi == SAFI_UNICAST)) {
4696 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4697 /*
4698 * Implicit withdraw case.
4699 * We have to do this before pi is
4700 * changed
4701 */
4702 ++vnc_implicit_withdraw;
4703 vnc_import_bgp_del_route(bgp, p, pi);
4704 vnc_import_bgp_exterior_del_route(
4705 bgp, p, pi);
4706 }
4707 }
4708 #endif
4709 bgp_attr_unintern(&pi->attr);
4710 pi->attr = attr_new;
4711 pi->uptime = bgp_clock();
4712 #if ENABLE_BGP_VNC
4713 if ((afi == AFI_IP || afi == AFI_IP6)
4714 && (safi == SAFI_UNICAST)) {
4715 if (vnc_implicit_withdraw) {
4716 vnc_import_bgp_add_route(bgp, p, pi);
4717 vnc_import_bgp_exterior_add_route(
4718 bgp, p, pi);
4719 }
4720 }
4721 #endif
4722
4723 /* Nexthop reachability check. */
4724 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4725 && (safi == SAFI_UNICAST
4726 || safi == SAFI_LABELED_UNICAST)) {
4727
4728 struct bgp *bgp_nexthop = bgp;
4729
4730 if (pi->extra && pi->extra->bgp_orig)
4731 bgp_nexthop = pi->extra->bgp_orig;
4732
4733 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
4734 afi, pi, NULL, 0))
4735 bgp_path_info_set_flag(rn, pi,
4736 BGP_PATH_VALID);
4737 else {
4738 if (BGP_DEBUG(nht, NHT)) {
4739 char buf1[INET6_ADDRSTRLEN];
4740 inet_ntop(p->family,
4741 &p->u.prefix, buf1,
4742 INET6_ADDRSTRLEN);
4743 zlog_debug(
4744 "%s(%s): Route not in table, not advertising",
4745 __FUNCTION__, buf1);
4746 }
4747 bgp_path_info_unset_flag(
4748 rn, pi, BGP_PATH_VALID);
4749 }
4750 } else {
4751 /* Delete the NHT structure if any, if we're
4752 * toggling between
4753 * enabling/disabling import check. We
4754 * deregister the route
4755 * from NHT to avoid overloading NHT and the
4756 * process interaction
4757 */
4758 bgp_unlink_nexthop(pi);
4759 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
4760 }
4761 /* Process change. */
4762 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4763 bgp_process(bgp, rn, afi, safi);
4764
4765 if (SAFI_UNICAST == safi
4766 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4767 || bgp->inst_type
4768 == BGP_INSTANCE_TYPE_DEFAULT)) {
4769 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
4770 pi);
4771 }
4772
4773 bgp_unlock_node(rn);
4774 aspath_unintern(&attr.aspath);
4775 return;
4776 }
4777 }
4778
4779 /* Make new BGP info. */
4780 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4781 attr_new, rn);
4782 /* Nexthop reachability check. */
4783 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4784 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4785 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
4786 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4787 else {
4788 if (BGP_DEBUG(nht, NHT)) {
4789 char buf1[INET6_ADDRSTRLEN];
4790 inet_ntop(p->family, &p->u.prefix, buf1,
4791 INET6_ADDRSTRLEN);
4792 zlog_debug(
4793 "%s(%s): Route not in table, not advertising",
4794 __FUNCTION__, buf1);
4795 }
4796 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
4797 }
4798 } else {
4799 /* Delete the NHT structure if any, if we're toggling between
4800 * enabling/disabling import check. We deregister the route
4801 * from NHT to avoid overloading NHT and the process interaction
4802 */
4803 bgp_unlink_nexthop(new);
4804
4805 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4806 }
4807
4808 /* Aggregate address increment. */
4809 bgp_aggregate_increment(bgp, p, new, afi, safi);
4810
4811 /* Register new BGP information. */
4812 bgp_path_info_add(rn, new);
4813
4814 /* route_node_get lock */
4815 bgp_unlock_node(rn);
4816
4817 /* Process change. */
4818 bgp_process(bgp, rn, afi, safi);
4819
4820 if (SAFI_UNICAST == safi
4821 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4822 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4823 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4824 }
4825
4826 /* Unintern original. */
4827 aspath_unintern(&attr.aspath);
4828 }
4829
4830 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4831 safi_t safi)
4832 {
4833 struct bgp_node *rn;
4834 struct bgp_path_info *pi;
4835
4836 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4837
4838 /* Check selected route and self inserted route. */
4839 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4840 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4841 && pi->sub_type == BGP_ROUTE_STATIC)
4842 break;
4843
4844 /* Withdraw static BGP route from routing table. */
4845 if (pi) {
4846 if (SAFI_UNICAST == safi
4847 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4848 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4849 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4850 }
4851 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4852 bgp_unlink_nexthop(pi);
4853 bgp_path_info_delete(rn, pi);
4854 bgp_process(bgp, rn, afi, safi);
4855 }
4856
4857 /* Unlock bgp_node_lookup. */
4858 bgp_unlock_node(rn);
4859 }
4860
4861 /*
4862 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4863 */
4864 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4865 afi_t afi, safi_t safi,
4866 struct prefix_rd *prd)
4867 {
4868 struct bgp_node *rn;
4869 struct bgp_path_info *pi;
4870
4871 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4872
4873 /* Check selected route and self inserted route. */
4874 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4875 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4876 && pi->sub_type == BGP_ROUTE_STATIC)
4877 break;
4878
4879 /* Withdraw static BGP route from routing table. */
4880 if (pi) {
4881 #if ENABLE_BGP_VNC
4882 rfapiProcessWithdraw(
4883 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
4884 1); /* Kill, since it is an administrative change */
4885 #endif
4886 if (SAFI_MPLS_VPN == safi
4887 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4888 vpn_leak_to_vrf_withdraw(bgp, pi);
4889 }
4890 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4891 bgp_path_info_delete(rn, pi);
4892 bgp_process(bgp, rn, afi, safi);
4893 }
4894
4895 /* Unlock bgp_node_lookup. */
4896 bgp_unlock_node(rn);
4897 }
4898
4899 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4900 struct bgp_static *bgp_static, afi_t afi,
4901 safi_t safi)
4902 {
4903 struct bgp_node *rn;
4904 struct bgp_path_info *new;
4905 struct attr *attr_new;
4906 struct attr attr = {0};
4907 struct bgp_path_info *pi;
4908 #if ENABLE_BGP_VNC
4909 mpls_label_t label = 0;
4910 #endif
4911 uint32_t num_labels = 0;
4912 union gw_addr add;
4913
4914 assert(bgp_static);
4915
4916 if (bgp_static->label != MPLS_INVALID_LABEL)
4917 num_labels = 1;
4918 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4919 &bgp_static->prd);
4920
4921 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4922
4923 attr.nexthop = bgp_static->igpnexthop;
4924 attr.med = bgp_static->igpmetric;
4925 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4926
4927 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4928 || (safi == SAFI_ENCAP)) {
4929 if (afi == AFI_IP) {
4930 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4931 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4932 }
4933 }
4934 if (afi == AFI_L2VPN) {
4935 if (bgp_static->gatewayIp.family == AF_INET)
4936 add.ipv4.s_addr =
4937 bgp_static->gatewayIp.u.prefix4.s_addr;
4938 else if (bgp_static->gatewayIp.family == AF_INET6)
4939 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4940 sizeof(struct in6_addr));
4941 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4942 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
4943 struct bgp_encap_type_vxlan bet;
4944 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4945 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
4946 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4947 }
4948 if (bgp_static->router_mac) {
4949 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
4950 }
4951 }
4952 /* Apply route-map. */
4953 if (bgp_static->rmap.name) {
4954 struct attr attr_tmp = attr;
4955 struct bgp_path_info rmap_path;
4956 route_map_result_t ret;
4957
4958 rmap_path.peer = bgp->peer_self;
4959 rmap_path.attr = &attr_tmp;
4960
4961 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4962
4963 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4964 &rmap_path);
4965
4966 bgp->peer_self->rmap_type = 0;
4967
4968 if (ret == RMAP_DENYMATCH) {
4969 /* Free uninterned attribute. */
4970 bgp_attr_flush(&attr_tmp);
4971
4972 /* Unintern original. */
4973 aspath_unintern(&attr.aspath);
4974 bgp_static_withdraw_safi(bgp, p, afi, safi,
4975 &bgp_static->prd);
4976 return;
4977 }
4978
4979 attr_new = bgp_attr_intern(&attr_tmp);
4980 } else {
4981 attr_new = bgp_attr_intern(&attr);
4982 }
4983
4984 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4985 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4986 && pi->sub_type == BGP_ROUTE_STATIC)
4987 break;
4988
4989 if (pi) {
4990 memset(&add, 0, sizeof(union gw_addr));
4991 if (attrhash_cmp(pi->attr, attr_new)
4992 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
4993 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4994 bgp_unlock_node(rn);
4995 bgp_attr_unintern(&attr_new);
4996 aspath_unintern(&attr.aspath);
4997 return;
4998 } else {
4999 /* The attribute is changed. */
5000 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
5001
5002 /* Rewrite BGP route information. */
5003 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5004 bgp_path_info_restore(rn, pi);
5005 else
5006 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5007 bgp_attr_unintern(&pi->attr);
5008 pi->attr = attr_new;
5009 pi->uptime = bgp_clock();
5010 #if ENABLE_BGP_VNC
5011 if (pi->extra)
5012 label = decode_label(&pi->extra->label[0]);
5013 #endif
5014
5015 /* Process change. */
5016 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5017 bgp_process(bgp, rn, afi, safi);
5018
5019 if (SAFI_MPLS_VPN == safi
5020 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5021 vpn_leak_to_vrf_update(bgp, pi);
5022 }
5023 #if ENABLE_BGP_VNC
5024 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5025 pi->attr, afi, safi, pi->type,
5026 pi->sub_type, &label);
5027 #endif
5028 bgp_unlock_node(rn);
5029 aspath_unintern(&attr.aspath);
5030 return;
5031 }
5032 }
5033
5034
5035 /* Make new BGP info. */
5036 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5037 attr_new, rn);
5038 SET_FLAG(new->flags, BGP_PATH_VALID);
5039 new->extra = bgp_path_info_extra_new();
5040 if (num_labels) {
5041 new->extra->label[0] = bgp_static->label;
5042 new->extra->num_labels = num_labels;
5043 }
5044 #if ENABLE_BGP_VNC
5045 label = decode_label(&bgp_static->label);
5046 #endif
5047
5048 /* Aggregate address increment. */
5049 bgp_aggregate_increment(bgp, p, new, afi, safi);
5050
5051 /* Register new BGP information. */
5052 bgp_path_info_add(rn, new);
5053 /* route_node_get lock */
5054 bgp_unlock_node(rn);
5055
5056 /* Process change. */
5057 bgp_process(bgp, rn, afi, safi);
5058
5059 if (SAFI_MPLS_VPN == safi
5060 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5061 vpn_leak_to_vrf_update(bgp, new);
5062 }
5063 #if ENABLE_BGP_VNC
5064 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5065 safi, new->type, new->sub_type, &label);
5066 #endif
5067
5068 /* Unintern original. */
5069 aspath_unintern(&attr.aspath);
5070 }
5071
5072 /* Configure static BGP network. When user don't run zebra, static
5073 route should be installed as valid. */
5074 static int bgp_static_set(struct vty *vty, const char *negate,
5075 const char *ip_str, afi_t afi, safi_t safi,
5076 const char *rmap, int backdoor, uint32_t label_index)
5077 {
5078 VTY_DECLVAR_CONTEXT(bgp, bgp);
5079 int ret;
5080 struct prefix p;
5081 struct bgp_static *bgp_static;
5082 struct bgp_node *rn;
5083 uint8_t need_update = 0;
5084
5085 /* Convert IP prefix string to struct prefix. */
5086 ret = str2prefix(ip_str, &p);
5087 if (!ret) {
5088 vty_out(vty, "%% Malformed prefix\n");
5089 return CMD_WARNING_CONFIG_FAILED;
5090 }
5091 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5092 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5093 return CMD_WARNING_CONFIG_FAILED;
5094 }
5095
5096 apply_mask(&p);
5097
5098 if (negate) {
5099
5100 /* Set BGP static route configuration. */
5101 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
5102
5103 if (!rn) {
5104 vty_out(vty, "%% Can't find static route specified\n");
5105 return CMD_WARNING_CONFIG_FAILED;
5106 }
5107
5108 bgp_static = bgp_node_get_bgp_static_info(rn);
5109
5110 if ((label_index != BGP_INVALID_LABEL_INDEX)
5111 && (label_index != bgp_static->label_index)) {
5112 vty_out(vty,
5113 "%% label-index doesn't match static route\n");
5114 return CMD_WARNING_CONFIG_FAILED;
5115 }
5116
5117 if ((rmap && bgp_static->rmap.name)
5118 && strcmp(rmap, bgp_static->rmap.name)) {
5119 vty_out(vty,
5120 "%% route-map name doesn't match static route\n");
5121 return CMD_WARNING_CONFIG_FAILED;
5122 }
5123
5124 /* Update BGP RIB. */
5125 if (!bgp_static->backdoor)
5126 bgp_static_withdraw(bgp, &p, afi, safi);
5127
5128 /* Clear configuration. */
5129 bgp_static_free(bgp_static);
5130 bgp_node_set_bgp_static_info(rn, NULL);
5131 bgp_unlock_node(rn);
5132 bgp_unlock_node(rn);
5133 } else {
5134
5135 /* Set BGP static route configuration. */
5136 rn = bgp_node_get(bgp->route[afi][safi], &p);
5137
5138 bgp_static = bgp_node_get_bgp_static_info(rn);
5139 if (bgp_static) {
5140 /* Configuration change. */
5141 /* Label index cannot be changed. */
5142 if (bgp_static->label_index != label_index) {
5143 vty_out(vty, "%% cannot change label-index\n");
5144 return CMD_WARNING_CONFIG_FAILED;
5145 }
5146
5147 /* Check previous routes are installed into BGP. */
5148 if (bgp_static->valid
5149 && bgp_static->backdoor != backdoor)
5150 need_update = 1;
5151
5152 bgp_static->backdoor = backdoor;
5153
5154 if (rmap) {
5155 XFREE(MTYPE_ROUTE_MAP_NAME,
5156 bgp_static->rmap.name);
5157 route_map_counter_decrement(
5158 bgp_static->rmap.map);
5159 bgp_static->rmap.name =
5160 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5161 bgp_static->rmap.map =
5162 route_map_lookup_by_name(rmap);
5163 route_map_counter_increment(
5164 bgp_static->rmap.map);
5165 } else {
5166 XFREE(MTYPE_ROUTE_MAP_NAME,
5167 bgp_static->rmap.name);
5168 route_map_counter_decrement(
5169 bgp_static->rmap.map);
5170 bgp_static->rmap.name = NULL;
5171 bgp_static->rmap.map = NULL;
5172 bgp_static->valid = 0;
5173 }
5174 bgp_unlock_node(rn);
5175 } else {
5176 /* New configuration. */
5177 bgp_static = bgp_static_new();
5178 bgp_static->backdoor = backdoor;
5179 bgp_static->valid = 0;
5180 bgp_static->igpmetric = 0;
5181 bgp_static->igpnexthop.s_addr = 0;
5182 bgp_static->label_index = label_index;
5183
5184 if (rmap) {
5185 XFREE(MTYPE_ROUTE_MAP_NAME,
5186 bgp_static->rmap.name);
5187 route_map_counter_decrement(
5188 bgp_static->rmap.map);
5189 bgp_static->rmap.name =
5190 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5191 bgp_static->rmap.map =
5192 route_map_lookup_by_name(rmap);
5193 route_map_counter_increment(
5194 bgp_static->rmap.map);
5195 }
5196 bgp_node_set_bgp_static_info(rn, bgp_static);
5197 }
5198
5199 bgp_static->valid = 1;
5200 if (need_update)
5201 bgp_static_withdraw(bgp, &p, afi, safi);
5202
5203 if (!bgp_static->backdoor)
5204 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5205 }
5206
5207 return CMD_SUCCESS;
5208 }
5209
5210 void bgp_static_add(struct bgp *bgp)
5211 {
5212 afi_t afi;
5213 safi_t safi;
5214 struct bgp_node *rn;
5215 struct bgp_node *rm;
5216 struct bgp_table *table;
5217 struct bgp_static *bgp_static;
5218
5219 FOREACH_AFI_SAFI (afi, safi)
5220 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5221 rn = bgp_route_next(rn)) {
5222 if (!bgp_node_has_bgp_path_info_data(rn))
5223 continue;
5224
5225 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5226 || (safi == SAFI_EVPN)) {
5227 table = bgp_node_get_bgp_table_info(rn);
5228
5229 for (rm = bgp_table_top(table); rm;
5230 rm = bgp_route_next(rm)) {
5231 bgp_static =
5232 bgp_node_get_bgp_static_info(
5233 rm);
5234 bgp_static_update_safi(bgp, &rm->p,
5235 bgp_static, afi,
5236 safi);
5237 }
5238 } else {
5239 bgp_static_update(
5240 bgp, &rn->p,
5241 bgp_node_get_bgp_static_info(rn), afi,
5242 safi);
5243 }
5244 }
5245 }
5246
5247 /* Called from bgp_delete(). Delete all static routes from the BGP
5248 instance. */
5249 void bgp_static_delete(struct bgp *bgp)
5250 {
5251 afi_t afi;
5252 safi_t safi;
5253 struct bgp_node *rn;
5254 struct bgp_node *rm;
5255 struct bgp_table *table;
5256 struct bgp_static *bgp_static;
5257
5258 FOREACH_AFI_SAFI (afi, safi)
5259 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5260 rn = bgp_route_next(rn)) {
5261 if (!bgp_node_has_bgp_path_info_data(rn))
5262 continue;
5263
5264 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5265 || (safi == SAFI_EVPN)) {
5266 table = bgp_node_get_bgp_table_info(rn);
5267
5268 for (rm = bgp_table_top(table); rm;
5269 rm = bgp_route_next(rm)) {
5270 bgp_static =
5271 bgp_node_get_bgp_static_info(
5272 rm);
5273 if (!bgp_static)
5274 continue;
5275
5276 bgp_static_withdraw_safi(
5277 bgp, &rm->p, AFI_IP, safi,
5278 (struct prefix_rd *)&rn->p);
5279 bgp_static_free(bgp_static);
5280 bgp_node_set_bgp_static_info(rn, NULL);
5281 bgp_unlock_node(rn);
5282 }
5283 } else {
5284 bgp_static = bgp_node_get_bgp_static_info(rn);
5285 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5286 bgp_static_free(bgp_static);
5287 bgp_node_set_bgp_static_info(rn, NULL);
5288 bgp_unlock_node(rn);
5289 }
5290 }
5291 }
5292
5293 void bgp_static_redo_import_check(struct bgp *bgp)
5294 {
5295 afi_t afi;
5296 safi_t safi;
5297 struct bgp_node *rn;
5298 struct bgp_node *rm;
5299 struct bgp_table *table;
5300 struct bgp_static *bgp_static;
5301
5302 /* Use this flag to force reprocessing of the route */
5303 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5304 FOREACH_AFI_SAFI (afi, safi) {
5305 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5306 rn = bgp_route_next(rn)) {
5307 if (!bgp_node_has_bgp_path_info_data(rn))
5308 continue;
5309
5310 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5311 || (safi == SAFI_EVPN)) {
5312 table = bgp_node_get_bgp_table_info(rn);
5313
5314 for (rm = bgp_table_top(table); rm;
5315 rm = bgp_route_next(rm)) {
5316 bgp_static =
5317 bgp_node_get_bgp_static_info(
5318 rm);
5319 bgp_static_update_safi(bgp, &rm->p,
5320 bgp_static, afi,
5321 safi);
5322 }
5323 } else {
5324 bgp_static = bgp_node_get_bgp_static_info(rn);
5325 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5326 safi);
5327 }
5328 }
5329 }
5330 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5331 }
5332
5333 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5334 safi_t safi)
5335 {
5336 struct bgp_table *table;
5337 struct bgp_node *rn;
5338 struct bgp_path_info *pi;
5339
5340 /* Do not install the aggregate route if BGP is in the
5341 * process of termination.
5342 */
5343 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
5344 (bgp->peer_self == NULL))
5345 return;
5346
5347 table = bgp->rib[afi][safi];
5348 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5349 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5350 if (pi->peer == bgp->peer_self
5351 && ((pi->type == ZEBRA_ROUTE_BGP
5352 && pi->sub_type == BGP_ROUTE_STATIC)
5353 || (pi->type != ZEBRA_ROUTE_BGP
5354 && pi->sub_type
5355 == BGP_ROUTE_REDISTRIBUTE))) {
5356 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5357 safi);
5358 bgp_unlink_nexthop(pi);
5359 bgp_path_info_delete(rn, pi);
5360 bgp_process(bgp, rn, afi, safi);
5361 }
5362 }
5363 }
5364 }
5365
5366 /*
5367 * Purge all networks and redistributed routes from routing table.
5368 * Invoked upon the instance going down.
5369 */
5370 void bgp_purge_static_redist_routes(struct bgp *bgp)
5371 {
5372 afi_t afi;
5373 safi_t safi;
5374
5375 FOREACH_AFI_SAFI (afi, safi)
5376 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5377 }
5378
5379 /*
5380 * gpz 110624
5381 * Currently this is used to set static routes for VPN and ENCAP.
5382 * I think it can probably be factored with bgp_static_set.
5383 */
5384 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5385 const char *ip_str, const char *rd_str,
5386 const char *label_str, const char *rmap_str,
5387 int evpn_type, const char *esi, const char *gwip,
5388 const char *ethtag, const char *routermac)
5389 {
5390 VTY_DECLVAR_CONTEXT(bgp, bgp);
5391 int ret;
5392 struct prefix p;
5393 struct prefix_rd prd;
5394 struct bgp_node *prn;
5395 struct bgp_node *rn;
5396 struct bgp_table *table;
5397 struct bgp_static *bgp_static;
5398 mpls_label_t label = MPLS_INVALID_LABEL;
5399 struct prefix gw_ip;
5400
5401 /* validate ip prefix */
5402 ret = str2prefix(ip_str, &p);
5403 if (!ret) {
5404 vty_out(vty, "%% Malformed prefix\n");
5405 return CMD_WARNING_CONFIG_FAILED;
5406 }
5407 apply_mask(&p);
5408 if ((afi == AFI_L2VPN)
5409 && (bgp_build_evpn_prefix(evpn_type,
5410 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5411 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5412 return CMD_WARNING_CONFIG_FAILED;
5413 }
5414
5415 ret = str2prefix_rd(rd_str, &prd);
5416 if (!ret) {
5417 vty_out(vty, "%% Malformed rd\n");
5418 return CMD_WARNING_CONFIG_FAILED;
5419 }
5420
5421 if (label_str) {
5422 unsigned long label_val;
5423 label_val = strtoul(label_str, NULL, 10);
5424 encode_label(label_val, &label);
5425 }
5426
5427 if (safi == SAFI_EVPN) {
5428 if (esi && str2esi(esi, NULL) == 0) {
5429 vty_out(vty, "%% Malformed ESI\n");
5430 return CMD_WARNING_CONFIG_FAILED;
5431 }
5432 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5433 vty_out(vty, "%% Malformed Router MAC\n");
5434 return CMD_WARNING_CONFIG_FAILED;
5435 }
5436 if (gwip) {
5437 memset(&gw_ip, 0, sizeof(struct prefix));
5438 ret = str2prefix(gwip, &gw_ip);
5439 if (!ret) {
5440 vty_out(vty, "%% Malformed GatewayIp\n");
5441 return CMD_WARNING_CONFIG_FAILED;
5442 }
5443 if ((gw_ip.family == AF_INET
5444 && is_evpn_prefix_ipaddr_v6(
5445 (struct prefix_evpn *)&p))
5446 || (gw_ip.family == AF_INET6
5447 && is_evpn_prefix_ipaddr_v4(
5448 (struct prefix_evpn *)&p))) {
5449 vty_out(vty,
5450 "%% GatewayIp family differs with IP prefix\n");
5451 return CMD_WARNING_CONFIG_FAILED;
5452 }
5453 }
5454 }
5455 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5456 if (!bgp_node_has_bgp_path_info_data(prn))
5457 bgp_node_set_bgp_table_info(prn,
5458 bgp_table_init(bgp, afi, safi));
5459 table = bgp_node_get_bgp_table_info(prn);
5460
5461 rn = bgp_node_get(table, &p);
5462
5463 if (bgp_node_has_bgp_path_info_data(rn)) {
5464 vty_out(vty, "%% Same network configuration exists\n");
5465 bgp_unlock_node(rn);
5466 } else {
5467 /* New configuration. */
5468 bgp_static = bgp_static_new();
5469 bgp_static->backdoor = 0;
5470 bgp_static->valid = 0;
5471 bgp_static->igpmetric = 0;
5472 bgp_static->igpnexthop.s_addr = 0;
5473 bgp_static->label = label;
5474 bgp_static->prd = prd;
5475
5476 if (rmap_str) {
5477 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5478 route_map_counter_decrement(bgp_static->rmap.map);
5479 bgp_static->rmap.name =
5480 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5481 bgp_static->rmap.map =
5482 route_map_lookup_by_name(rmap_str);
5483 route_map_counter_increment(bgp_static->rmap.map);
5484 }
5485
5486 if (safi == SAFI_EVPN) {
5487 if (esi) {
5488 bgp_static->eth_s_id =
5489 XCALLOC(MTYPE_ATTR,
5490 sizeof(struct eth_segment_id));
5491 str2esi(esi, bgp_static->eth_s_id);
5492 }
5493 if (routermac) {
5494 bgp_static->router_mac =
5495 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5496 (void)prefix_str2mac(routermac,
5497 bgp_static->router_mac);
5498 }
5499 if (gwip)
5500 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5501 }
5502 bgp_node_set_bgp_static_info(rn, bgp_static);
5503
5504 bgp_static->valid = 1;
5505 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5506 }
5507
5508 return CMD_SUCCESS;
5509 }
5510
5511 /* Configure static BGP network. */
5512 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5513 const char *ip_str, const char *rd_str,
5514 const char *label_str, int evpn_type, const char *esi,
5515 const char *gwip, const char *ethtag)
5516 {
5517 VTY_DECLVAR_CONTEXT(bgp, bgp);
5518 int ret;
5519 struct prefix p;
5520 struct prefix_rd prd;
5521 struct bgp_node *prn;
5522 struct bgp_node *rn;
5523 struct bgp_table *table;
5524 struct bgp_static *bgp_static;
5525 mpls_label_t label = MPLS_INVALID_LABEL;
5526
5527 /* Convert IP prefix string to struct prefix. */
5528 ret = str2prefix(ip_str, &p);
5529 if (!ret) {
5530 vty_out(vty, "%% Malformed prefix\n");
5531 return CMD_WARNING_CONFIG_FAILED;
5532 }
5533 apply_mask(&p);
5534 if ((afi == AFI_L2VPN)
5535 && (bgp_build_evpn_prefix(evpn_type,
5536 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5537 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5538 return CMD_WARNING_CONFIG_FAILED;
5539 }
5540 ret = str2prefix_rd(rd_str, &prd);
5541 if (!ret) {
5542 vty_out(vty, "%% Malformed rd\n");
5543 return CMD_WARNING_CONFIG_FAILED;
5544 }
5545
5546 if (label_str) {
5547 unsigned long label_val;
5548 label_val = strtoul(label_str, NULL, 10);
5549 encode_label(label_val, &label);
5550 }
5551
5552 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5553 if (!bgp_node_has_bgp_path_info_data(prn))
5554 bgp_node_set_bgp_table_info(prn,
5555 bgp_table_init(bgp, afi, safi));
5556 else
5557 bgp_unlock_node(prn);
5558 table = bgp_node_get_bgp_table_info(prn);
5559
5560 rn = bgp_node_lookup(table, &p);
5561
5562 if (rn) {
5563 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5564
5565 bgp_static = bgp_node_get_bgp_static_info(rn);
5566 bgp_static_free(bgp_static);
5567 bgp_node_set_bgp_static_info(rn, NULL);
5568 bgp_unlock_node(rn);
5569 bgp_unlock_node(rn);
5570 } else
5571 vty_out(vty, "%% Can't find the route\n");
5572
5573 return CMD_SUCCESS;
5574 }
5575
5576 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5577 const char *rmap_name)
5578 {
5579 VTY_DECLVAR_CONTEXT(bgp, bgp);
5580 struct bgp_rmap *rmap;
5581
5582 rmap = &bgp->table_map[afi][safi];
5583 if (rmap_name) {
5584 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5585 route_map_counter_decrement(rmap->map);
5586 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5587 rmap->map = route_map_lookup_by_name(rmap_name);
5588 route_map_counter_increment(rmap->map);
5589 } else {
5590 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5591 route_map_counter_decrement(rmap->map);
5592 rmap->name = NULL;
5593 rmap->map = NULL;
5594 }
5595
5596 if (bgp_fibupd_safi(safi))
5597 bgp_zebra_announce_table(bgp, afi, safi);
5598
5599 return CMD_SUCCESS;
5600 }
5601
5602 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5603 const char *rmap_name)
5604 {
5605 VTY_DECLVAR_CONTEXT(bgp, bgp);
5606 struct bgp_rmap *rmap;
5607
5608 rmap = &bgp->table_map[afi][safi];
5609 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5610 route_map_counter_decrement(rmap->map);
5611 rmap->name = NULL;
5612 rmap->map = NULL;
5613
5614 if (bgp_fibupd_safi(safi))
5615 bgp_zebra_announce_table(bgp, afi, safi);
5616
5617 return CMD_SUCCESS;
5618 }
5619
5620 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5621 safi_t safi)
5622 {
5623 if (bgp->table_map[afi][safi].name) {
5624 vty_out(vty, " table-map %s\n",
5625 bgp->table_map[afi][safi].name);
5626 }
5627 }
5628
5629 DEFUN (bgp_table_map,
5630 bgp_table_map_cmd,
5631 "table-map WORD",
5632 "BGP table to RIB route download filter\n"
5633 "Name of the route map\n")
5634 {
5635 int idx_word = 1;
5636 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5637 argv[idx_word]->arg);
5638 }
5639 DEFUN (no_bgp_table_map,
5640 no_bgp_table_map_cmd,
5641 "no table-map WORD",
5642 NO_STR
5643 "BGP table to RIB route download filter\n"
5644 "Name of the route map\n")
5645 {
5646 int idx_word = 2;
5647 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5648 argv[idx_word]->arg);
5649 }
5650
5651 DEFPY(bgp_network,
5652 bgp_network_cmd,
5653 "[no] network \
5654 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5655 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5656 backdoor$backdoor}]",
5657 NO_STR
5658 "Specify a network to announce via BGP\n"
5659 "IPv4 prefix\n"
5660 "Network number\n"
5661 "Network mask\n"
5662 "Network mask\n"
5663 "Route-map to modify the attributes\n"
5664 "Name of the route map\n"
5665 "Label index to associate with the prefix\n"
5666 "Label index value\n"
5667 "Specify a BGP backdoor route\n")
5668 {
5669 char addr_prefix_str[BUFSIZ];
5670
5671 if (address_str) {
5672 int ret;
5673
5674 ret = netmask_str2prefix_str(address_str, netmask_str,
5675 addr_prefix_str);
5676 if (!ret) {
5677 vty_out(vty, "%% Inconsistent address and mask\n");
5678 return CMD_WARNING_CONFIG_FAILED;
5679 }
5680 }
5681
5682 return bgp_static_set(
5683 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5684 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5685 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5686 }
5687
5688 DEFPY(ipv6_bgp_network,
5689 ipv6_bgp_network_cmd,
5690 "[no] network X:X::X:X/M$prefix \
5691 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5692 NO_STR
5693 "Specify a network to announce via BGP\n"
5694 "IPv6 prefix\n"
5695 "Route-map to modify the attributes\n"
5696 "Name of the route map\n"
5697 "Label index to associate with the prefix\n"
5698 "Label index value\n")
5699 {
5700 return bgp_static_set(
5701 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5702 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5703 }
5704
5705 static struct bgp_aggregate *bgp_aggregate_new(void)
5706 {
5707 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5708 }
5709
5710 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5711 {
5712 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
5713 route_map_counter_decrement(aggregate->rmap.map);
5714 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5715 }
5716
5717 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
5718 struct aspath *aspath,
5719 struct community *comm,
5720 struct ecommunity *ecomm,
5721 struct lcommunity *lcomm)
5722 {
5723 static struct aspath *ae = NULL;
5724
5725 if (!ae)
5726 ae = aspath_empty();
5727
5728 if (!pi)
5729 return 0;
5730
5731 if (origin != pi->attr->origin)
5732 return 0;
5733
5734 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
5735 return 0;
5736
5737 if (!community_cmp(pi->attr->community, comm))
5738 return 0;
5739
5740 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
5741 return 0;
5742
5743 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
5744 return 0;
5745
5746 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
5747 return 0;
5748
5749 return 1;
5750 }
5751
5752 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
5753 struct prefix *p, uint8_t origin,
5754 struct aspath *aspath,
5755 struct community *community,
5756 struct ecommunity *ecommunity,
5757 struct lcommunity *lcommunity,
5758 uint8_t atomic_aggregate,
5759 struct bgp_aggregate *aggregate)
5760 {
5761 struct bgp_node *rn;
5762 struct bgp_table *table;
5763 struct bgp_path_info *pi, *orig, *new;
5764 struct attr *attr;
5765
5766 table = bgp->rib[afi][safi];
5767
5768 rn = bgp_node_get(table, p);
5769
5770 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5771 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5772 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5773 break;
5774
5775 if (aggregate->count > 0) {
5776 /*
5777 * If the aggregate information has not changed
5778 * no need to re-install it again.
5779 */
5780 if (bgp_aggregate_info_same(orig, origin, aspath, community,
5781 ecommunity, lcommunity)) {
5782 bgp_unlock_node(rn);
5783
5784 if (aspath)
5785 aspath_free(aspath);
5786 if (community)
5787 community_free(&community);
5788 if (ecommunity)
5789 ecommunity_free(&ecommunity);
5790 if (lcommunity)
5791 lcommunity_free(&lcommunity);
5792
5793 return;
5794 }
5795
5796 /*
5797 * Mark the old as unusable
5798 */
5799 if (pi)
5800 bgp_path_info_delete(rn, pi);
5801
5802 attr = bgp_attr_aggregate_intern(
5803 bgp, origin, aspath, community, ecommunity, lcommunity,
5804 aggregate, atomic_aggregate, p);
5805
5806 if (!attr) {
5807 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
5808 return;
5809 }
5810
5811 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
5812 bgp->peer_self, attr, rn);
5813
5814 SET_FLAG(new->flags, BGP_PATH_VALID);
5815
5816 bgp_path_info_add(rn, new);
5817 bgp_process(bgp, rn, afi, safi);
5818 } else {
5819 for (pi = orig; pi; pi = pi->next)
5820 if (pi->peer == bgp->peer_self
5821 && pi->type == ZEBRA_ROUTE_BGP
5822 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5823 break;
5824
5825 /* Withdraw static BGP route from routing table. */
5826 if (pi) {
5827 bgp_path_info_delete(rn, pi);
5828 bgp_process(bgp, rn, afi, safi);
5829 }
5830 }
5831
5832 bgp_unlock_node(rn);
5833 }
5834
5835 /* Update an aggregate as routes are added/removed from the BGP table */
5836 void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5837 afi_t afi, safi_t safi,
5838 struct bgp_aggregate *aggregate)
5839 {
5840 struct bgp_table *table;
5841 struct bgp_node *top;
5842 struct bgp_node *rn;
5843 uint8_t origin;
5844 struct aspath *aspath = NULL;
5845 struct community *community = NULL;
5846 struct ecommunity *ecommunity = NULL;
5847 struct lcommunity *lcommunity = NULL;
5848 struct bgp_path_info *pi;
5849 unsigned long match = 0;
5850 uint8_t atomic_aggregate = 0;
5851
5852 /* If the bgp instance is being deleted or self peer is deleted
5853 * then do not create aggregate route
5854 */
5855 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
5856 (bgp->peer_self == NULL))
5857 return;
5858
5859 /* ORIGIN attribute: If at least one route among routes that are
5860 aggregated has ORIGIN with the value INCOMPLETE, then the
5861 aggregated route must have the ORIGIN attribute with the value
5862 INCOMPLETE. Otherwise, if at least one route among routes that
5863 are aggregated has ORIGIN with the value EGP, then the aggregated
5864 route must have the origin attribute with the value EGP. In all
5865 other case the value of the ORIGIN attribute of the aggregated
5866 route is INTERNAL. */
5867 origin = BGP_ORIGIN_IGP;
5868
5869 table = bgp->rib[afi][safi];
5870
5871 top = bgp_node_get(table, p);
5872 for (rn = bgp_node_get(table, p); rn;
5873 rn = bgp_route_next_until(rn, top)) {
5874 if (rn->p.prefixlen <= p->prefixlen)
5875 continue;
5876
5877 match = 0;
5878
5879 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5880 if (BGP_PATH_HOLDDOWN(pi))
5881 continue;
5882
5883 if (pi->attr->flag
5884 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5885 atomic_aggregate = 1;
5886
5887 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5888 continue;
5889
5890 /*
5891 * summary-only aggregate route suppress
5892 * aggregated route announcements.
5893 */
5894 if (aggregate->summary_only) {
5895 (bgp_path_info_extra_get(pi))->suppress++;
5896 bgp_path_info_set_flag(rn, pi,
5897 BGP_PATH_ATTR_CHANGED);
5898 match++;
5899 }
5900
5901 aggregate->count++;
5902
5903 /*
5904 * If at least one route among routes that are
5905 * aggregated has ORIGIN with the value INCOMPLETE,
5906 * then the aggregated route MUST have the ORIGIN
5907 * attribute with the value INCOMPLETE. Otherwise, if
5908 * at least one route among routes that are aggregated
5909 * has ORIGIN with the value EGP, then the aggregated
5910 * route MUST have the ORIGIN attribute with the value
5911 * EGP.
5912 */
5913 switch (pi->attr->origin) {
5914 case BGP_ORIGIN_INCOMPLETE:
5915 aggregate->incomplete_origin_count++;
5916 break;
5917 case BGP_ORIGIN_EGP:
5918 aggregate->egp_origin_count++;
5919 break;
5920 default:
5921 /*Do nothing.
5922 */
5923 break;
5924 }
5925
5926 if (!aggregate->as_set)
5927 continue;
5928
5929 /*
5930 * as-set aggregate route generate origin, as path,
5931 * and community aggregation.
5932 */
5933 /* Compute aggregate route's as-path.
5934 */
5935 bgp_compute_aggregate_aspath_hash(aggregate,
5936 pi->attr->aspath);
5937
5938 /* Compute aggregate route's community.
5939 */
5940 if (pi->attr->community)
5941 bgp_compute_aggregate_community_hash(
5942 aggregate,
5943 pi->attr->community);
5944
5945 /* Compute aggregate route's extended community.
5946 */
5947 if (pi->attr->ecommunity)
5948 bgp_compute_aggregate_ecommunity_hash(
5949 aggregate,
5950 pi->attr->ecommunity);
5951
5952 /* Compute aggregate route's large community.
5953 */
5954 if (pi->attr->lcommunity)
5955 bgp_compute_aggregate_lcommunity_hash(
5956 aggregate,
5957 pi->attr->lcommunity);
5958 }
5959 if (match)
5960 bgp_process(bgp, rn, afi, safi);
5961 }
5962 if (aggregate->as_set) {
5963 bgp_compute_aggregate_aspath_val(aggregate);
5964 bgp_compute_aggregate_community_val(aggregate);
5965 bgp_compute_aggregate_ecommunity_val(aggregate);
5966 bgp_compute_aggregate_lcommunity_val(aggregate);
5967 }
5968
5969
5970 bgp_unlock_node(top);
5971
5972
5973 if (aggregate->incomplete_origin_count > 0)
5974 origin = BGP_ORIGIN_INCOMPLETE;
5975 else if (aggregate->egp_origin_count > 0)
5976 origin = BGP_ORIGIN_EGP;
5977
5978 if (aggregate->as_set) {
5979 if (aggregate->aspath)
5980 /* Retrieve aggregate route's as-path.
5981 */
5982 aspath = aspath_dup(aggregate->aspath);
5983
5984 if (aggregate->community)
5985 /* Retrieve aggregate route's community.
5986 */
5987 community = community_dup(aggregate->community);
5988
5989 if (aggregate->ecommunity)
5990 /* Retrieve aggregate route's ecommunity.
5991 */
5992 ecommunity = ecommunity_dup(aggregate->ecommunity);
5993
5994 if (aggregate->lcommunity)
5995 /* Retrieve aggregate route's lcommunity.
5996 */
5997 lcommunity = lcommunity_dup(aggregate->lcommunity);
5998 }
5999
6000 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6001 ecommunity, lcommunity, atomic_aggregate,
6002 aggregate);
6003 }
6004
6005 void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
6006 safi_t safi, struct bgp_aggregate *aggregate)
6007 {
6008 struct bgp_table *table;
6009 struct bgp_node *top;
6010 struct bgp_node *rn;
6011 struct bgp_path_info *pi;
6012 unsigned long match;
6013
6014 table = bgp->rib[afi][safi];
6015
6016 /* If routes exists below this node, generate aggregate routes. */
6017 top = bgp_node_get(table, p);
6018 for (rn = bgp_node_get(table, p); rn;
6019 rn = bgp_route_next_until(rn, top)) {
6020 if (rn->p.prefixlen <= p->prefixlen)
6021 continue;
6022 match = 0;
6023
6024 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6025 if (BGP_PATH_HOLDDOWN(pi))
6026 continue;
6027
6028 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6029 continue;
6030
6031 if (aggregate->summary_only && pi->extra) {
6032 pi->extra->suppress--;
6033
6034 if (pi->extra->suppress == 0) {
6035 bgp_path_info_set_flag(
6036 rn, pi, BGP_PATH_ATTR_CHANGED);
6037 match++;
6038 }
6039 }
6040 aggregate->count--;
6041
6042 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6043 aggregate->incomplete_origin_count--;
6044 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6045 aggregate->egp_origin_count--;
6046
6047 if (aggregate->as_set) {
6048 /* Remove as-path from aggregate.
6049 */
6050 bgp_remove_aspath_from_aggregate_hash(
6051 aggregate,
6052 pi->attr->aspath);
6053
6054 if (pi->attr->community)
6055 /* Remove community from aggregate.
6056 */
6057 bgp_remove_comm_from_aggregate_hash(
6058 aggregate,
6059 pi->attr->community);
6060
6061 if (pi->attr->ecommunity)
6062 /* Remove ecommunity from aggregate.
6063 */
6064 bgp_remove_ecomm_from_aggregate_hash(
6065 aggregate,
6066 pi->attr->ecommunity);
6067
6068 if (pi->attr->lcommunity)
6069 /* Remove lcommunity from aggregate.
6070 */
6071 bgp_remove_lcomm_from_aggregate_hash(
6072 aggregate,
6073 pi->attr->lcommunity);
6074 }
6075
6076 }
6077
6078 /* If this node was suppressed, process the change. */
6079 if (match)
6080 bgp_process(bgp, rn, afi, safi);
6081 }
6082 if (aggregate->as_set) {
6083 aspath_free(aggregate->aspath);
6084 aggregate->aspath = NULL;
6085 if (aggregate->community)
6086 community_free(&aggregate->community);
6087 if (aggregate->ecommunity)
6088 ecommunity_free(&aggregate->ecommunity);
6089 if (aggregate->lcommunity)
6090 lcommunity_free(&aggregate->lcommunity);
6091 }
6092
6093 bgp_unlock_node(top);
6094 }
6095
6096 static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
6097 struct bgp_path_info *pinew, afi_t afi,
6098 safi_t safi,
6099 struct bgp_aggregate *aggregate)
6100 {
6101 uint8_t origin;
6102 struct aspath *aspath = NULL;
6103 uint8_t atomic_aggregate = 0;
6104 struct community *community = NULL;
6105 struct ecommunity *ecommunity = NULL;
6106 struct lcommunity *lcommunity = NULL;
6107
6108 /* ORIGIN attribute: If at least one route among routes that are
6109 * aggregated has ORIGIN with the value INCOMPLETE, then the
6110 * aggregated route must have the ORIGIN attribute with the value
6111 * INCOMPLETE. Otherwise, if at least one route among routes that
6112 * are aggregated has ORIGIN with the value EGP, then the aggregated
6113 * route must have the origin attribute with the value EGP. In all
6114 * other case the value of the ORIGIN attribute of the aggregated
6115 * route is INTERNAL.
6116 */
6117 origin = BGP_ORIGIN_IGP;
6118
6119 aggregate->count++;
6120
6121 if (aggregate->summary_only)
6122 (bgp_path_info_extra_get(pinew))->suppress++;
6123
6124 switch (pinew->attr->origin) {
6125 case BGP_ORIGIN_INCOMPLETE:
6126 aggregate->incomplete_origin_count++;
6127 break;
6128 case BGP_ORIGIN_EGP:
6129 aggregate->egp_origin_count++;
6130 break;
6131 default:
6132 /* Do nothing.
6133 */
6134 break;
6135 }
6136
6137 if (aggregate->incomplete_origin_count > 0)
6138 origin = BGP_ORIGIN_INCOMPLETE;
6139 else if (aggregate->egp_origin_count > 0)
6140 origin = BGP_ORIGIN_EGP;
6141
6142 if (aggregate->as_set) {
6143 /* Compute aggregate route's as-path.
6144 */
6145 bgp_compute_aggregate_aspath(aggregate,
6146 pinew->attr->aspath);
6147
6148 /* Compute aggregate route's community.
6149 */
6150 if (pinew->attr->community)
6151 bgp_compute_aggregate_community(
6152 aggregate,
6153 pinew->attr->community);
6154
6155 /* Compute aggregate route's extended community.
6156 */
6157 if (pinew->attr->ecommunity)
6158 bgp_compute_aggregate_ecommunity(
6159 aggregate,
6160 pinew->attr->ecommunity);
6161
6162 /* Compute aggregate route's large community.
6163 */
6164 if (pinew->attr->lcommunity)
6165 bgp_compute_aggregate_lcommunity(
6166 aggregate,
6167 pinew->attr->lcommunity);
6168
6169 /* Retrieve aggregate route's as-path.
6170 */
6171 if (aggregate->aspath)
6172 aspath = aspath_dup(aggregate->aspath);
6173
6174 /* Retrieve aggregate route's community.
6175 */
6176 if (aggregate->community)
6177 community = community_dup(aggregate->community);
6178
6179 /* Retrieve aggregate route's ecommunity.
6180 */
6181 if (aggregate->ecommunity)
6182 ecommunity = ecommunity_dup(aggregate->ecommunity);
6183
6184 /* Retrieve aggregate route's lcommunity.
6185 */
6186 if (aggregate->lcommunity)
6187 lcommunity = lcommunity_dup(aggregate->lcommunity);
6188 }
6189
6190 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6191 aspath, community, ecommunity,
6192 lcommunity, atomic_aggregate, aggregate);
6193 }
6194
6195 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6196 safi_t safi,
6197 struct bgp_path_info *pi,
6198 struct bgp_aggregate *aggregate,
6199 struct prefix *aggr_p)
6200 {
6201 uint8_t origin;
6202 struct aspath *aspath = NULL;
6203 uint8_t atomic_aggregate = 0;
6204 struct community *community = NULL;
6205 struct ecommunity *ecommunity = NULL;
6206 struct lcommunity *lcommunity = NULL;
6207 unsigned long match = 0;
6208
6209 if (BGP_PATH_HOLDDOWN(pi))
6210 return;
6211
6212 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6213 return;
6214
6215 if (aggregate->summary_only
6216 && pi->extra
6217 && pi->extra->suppress > 0) {
6218 pi->extra->suppress--;
6219
6220 if (pi->extra->suppress == 0) {
6221 bgp_path_info_set_flag(pi->net, pi,
6222 BGP_PATH_ATTR_CHANGED);
6223 match++;
6224 }
6225 }
6226
6227 if (aggregate->count > 0)
6228 aggregate->count--;
6229
6230 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6231 aggregate->incomplete_origin_count--;
6232 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6233 aggregate->egp_origin_count--;
6234
6235 if (aggregate->as_set) {
6236 /* Remove as-path from aggregate.
6237 */
6238 bgp_remove_aspath_from_aggregate(aggregate,
6239 pi->attr->aspath);
6240
6241 if (pi->attr->community)
6242 /* Remove community from aggregate.
6243 */
6244 bgp_remove_community_from_aggregate(
6245 aggregate,
6246 pi->attr->community);
6247
6248 if (pi->attr->ecommunity)
6249 /* Remove ecommunity from aggregate.
6250 */
6251 bgp_remove_ecommunity_from_aggregate(
6252 aggregate,
6253 pi->attr->ecommunity);
6254
6255 if (pi->attr->lcommunity)
6256 /* Remove lcommunity from aggregate.
6257 */
6258 bgp_remove_lcommunity_from_aggregate(
6259 aggregate,
6260 pi->attr->lcommunity);
6261 }
6262
6263 /* If this node was suppressed, process the change. */
6264 if (match)
6265 bgp_process(bgp, pi->net, afi, safi);
6266
6267 origin = BGP_ORIGIN_IGP;
6268 if (aggregate->incomplete_origin_count > 0)
6269 origin = BGP_ORIGIN_INCOMPLETE;
6270 else if (aggregate->egp_origin_count > 0)
6271 origin = BGP_ORIGIN_EGP;
6272
6273 if (aggregate->as_set) {
6274 /* Retrieve aggregate route's as-path.
6275 */
6276 if (aggregate->aspath)
6277 aspath = aspath_dup(aggregate->aspath);
6278
6279 /* Retrieve aggregate route's community.
6280 */
6281 if (aggregate->community)
6282 community = community_dup(aggregate->community);
6283
6284 /* Retrieve aggregate route's ecommunity.
6285 */
6286 if (aggregate->ecommunity)
6287 ecommunity = ecommunity_dup(aggregate->ecommunity);
6288
6289 /* Retrieve aggregate route's lcommunity.
6290 */
6291 if (aggregate->lcommunity)
6292 lcommunity = lcommunity_dup(aggregate->lcommunity);
6293 }
6294
6295 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6296 aspath, community, ecommunity,
6297 lcommunity, atomic_aggregate, aggregate);
6298 }
6299
6300 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
6301 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6302 {
6303 struct bgp_node *child;
6304 struct bgp_node *rn;
6305 struct bgp_aggregate *aggregate;
6306 struct bgp_table *table;
6307
6308 table = bgp->aggregate[afi][safi];
6309
6310 /* No aggregates configured. */
6311 if (bgp_table_top_nolock(table) == NULL)
6312 return;
6313
6314 if (p->prefixlen == 0)
6315 return;
6316
6317 if (BGP_PATH_HOLDDOWN(pi))
6318 return;
6319
6320 child = bgp_node_get(table, p);
6321
6322 /* Aggregate address configuration check. */
6323 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6324 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6325 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6326 bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
6327 safi, aggregate);
6328 }
6329 }
6330 bgp_unlock_node(child);
6331 }
6332
6333 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6334 struct bgp_path_info *del, afi_t afi, safi_t safi)
6335 {
6336 struct bgp_node *child;
6337 struct bgp_node *rn;
6338 struct bgp_aggregate *aggregate;
6339 struct bgp_table *table;
6340
6341 table = bgp->aggregate[afi][safi];
6342
6343 /* No aggregates configured. */
6344 if (bgp_table_top_nolock(table) == NULL)
6345 return;
6346
6347 if (p->prefixlen == 0)
6348 return;
6349
6350 child = bgp_node_get(table, p);
6351
6352 /* Aggregate address configuration check. */
6353 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6354 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6355 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6356 bgp_remove_route_from_aggregate(bgp, afi, safi,
6357 del, aggregate, &rn->p);
6358 }
6359 }
6360 bgp_unlock_node(child);
6361 }
6362
6363 /* Aggregate route attribute. */
6364 #define AGGREGATE_SUMMARY_ONLY 1
6365 #define AGGREGATE_AS_SET 1
6366
6367 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6368 afi_t afi, safi_t safi)
6369 {
6370 VTY_DECLVAR_CONTEXT(bgp, bgp);
6371 int ret;
6372 struct prefix p;
6373 struct bgp_node *rn;
6374 struct bgp_aggregate *aggregate;
6375
6376 /* Convert string to prefix structure. */
6377 ret = str2prefix(prefix_str, &p);
6378 if (!ret) {
6379 vty_out(vty, "Malformed prefix\n");
6380 return CMD_WARNING_CONFIG_FAILED;
6381 }
6382 apply_mask(&p);
6383
6384 /* Old configuration check. */
6385 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6386 if (!rn) {
6387 vty_out(vty,
6388 "%% There is no aggregate-address configuration.\n");
6389 return CMD_WARNING_CONFIG_FAILED;
6390 }
6391
6392 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6393 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6394 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6395 NULL, NULL, 0, aggregate);
6396
6397 /* Unlock aggregate address configuration. */
6398 bgp_node_set_bgp_aggregate_info(rn, NULL);
6399
6400 if (aggregate->community)
6401 community_free(&aggregate->community);
6402
6403 if (aggregate->community_hash) {
6404 /* Delete all communities in the hash.
6405 */
6406 hash_clean(aggregate->community_hash,
6407 bgp_aggr_community_remove);
6408 /* Free up the community_hash.
6409 */
6410 hash_free(aggregate->community_hash);
6411 }
6412
6413 if (aggregate->ecommunity)
6414 ecommunity_free(&aggregate->ecommunity);
6415
6416 if (aggregate->ecommunity_hash) {
6417 /* Delete all ecommunities in the hash.
6418 */
6419 hash_clean(aggregate->ecommunity_hash,
6420 bgp_aggr_ecommunity_remove);
6421 /* Free up the ecommunity_hash.
6422 */
6423 hash_free(aggregate->ecommunity_hash);
6424 }
6425
6426 if (aggregate->lcommunity)
6427 lcommunity_free(&aggregate->lcommunity);
6428
6429 if (aggregate->lcommunity_hash) {
6430 /* Delete all lcommunities in the hash.
6431 */
6432 hash_clean(aggregate->lcommunity_hash,
6433 bgp_aggr_lcommunity_remove);
6434 /* Free up the lcommunity_hash.
6435 */
6436 hash_free(aggregate->lcommunity_hash);
6437 }
6438
6439 if (aggregate->aspath)
6440 aspath_free(aggregate->aspath);
6441
6442 if (aggregate->aspath_hash) {
6443 /* Delete all as-paths in the hash.
6444 */
6445 hash_clean(aggregate->aspath_hash,
6446 bgp_aggr_aspath_remove);
6447 /* Free up the aspath_hash.
6448 */
6449 hash_free(aggregate->aspath_hash);
6450 }
6451
6452 bgp_aggregate_free(aggregate);
6453 bgp_unlock_node(rn);
6454 bgp_unlock_node(rn);
6455
6456 return CMD_SUCCESS;
6457 }
6458
6459 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6460 safi_t safi, const char *rmap, uint8_t summary_only,
6461 uint8_t as_set)
6462 {
6463 VTY_DECLVAR_CONTEXT(bgp, bgp);
6464 int ret;
6465 struct prefix p;
6466 struct bgp_node *rn;
6467 struct bgp_aggregate *aggregate;
6468
6469 /* Convert string to prefix structure. */
6470 ret = str2prefix(prefix_str, &p);
6471 if (!ret) {
6472 vty_out(vty, "Malformed prefix\n");
6473 return CMD_WARNING_CONFIG_FAILED;
6474 }
6475 apply_mask(&p);
6476
6477 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6478 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6479 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6480 prefix_str);
6481 return CMD_WARNING_CONFIG_FAILED;
6482 }
6483
6484 /* Old configuration check. */
6485 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6486 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6487
6488 if (aggregate) {
6489 vty_out(vty, "There is already same aggregate network.\n");
6490 /* try to remove the old entry */
6491 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6492 if (ret) {
6493 vty_out(vty, "Error deleting aggregate.\n");
6494 bgp_unlock_node(rn);
6495 return CMD_WARNING_CONFIG_FAILED;
6496 }
6497 }
6498
6499 /* Make aggregate address structure. */
6500 aggregate = bgp_aggregate_new();
6501 aggregate->summary_only = summary_only;
6502 aggregate->as_set = as_set;
6503 aggregate->safi = safi;
6504
6505 if (rmap) {
6506 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6507 route_map_counter_decrement(aggregate->rmap.map);
6508 aggregate->rmap.name =
6509 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6510 aggregate->rmap.map = route_map_lookup_by_name(rmap);
6511 route_map_counter_increment(aggregate->rmap.map);
6512 }
6513 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6514
6515 /* Aggregate address insert into BGP routing table. */
6516 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
6517
6518 return CMD_SUCCESS;
6519 }
6520
6521 DEFUN (aggregate_address,
6522 aggregate_address_cmd,
6523 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6524 "Configure BGP aggregate entries\n"
6525 "Aggregate prefix\n"
6526 "Generate AS set path information\n"
6527 "Filter more specific routes from updates\n"
6528 "Filter more specific routes from updates\n"
6529 "Generate AS set path information\n"
6530 "Apply route map to aggregate network\n"
6531 "Name of route map\n")
6532 {
6533 int idx = 0;
6534 argv_find(argv, argc, "A.B.C.D/M", &idx);
6535 char *prefix = argv[idx]->arg;
6536 char *rmap = NULL;
6537 int as_set =
6538 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6539 idx = 0;
6540 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6541 ? AGGREGATE_SUMMARY_ONLY
6542 : 0;
6543
6544 idx = 0;
6545 argv_find(argv, argc, "WORD", &idx);
6546 if (idx)
6547 rmap = argv[idx]->arg;
6548
6549 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6550 rmap, summary_only, as_set);
6551 }
6552
6553 DEFUN (aggregate_address_mask,
6554 aggregate_address_mask_cmd,
6555 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6556 "Configure BGP aggregate entries\n"
6557 "Aggregate address\n"
6558 "Aggregate mask\n"
6559 "Generate AS set path information\n"
6560 "Filter more specific routes from updates\n"
6561 "Filter more specific routes from updates\n"
6562 "Generate AS set path information\n"
6563 "Apply route map to aggregate network\n"
6564 "Name of route map\n")
6565 {
6566 int idx = 0;
6567 argv_find(argv, argc, "A.B.C.D", &idx);
6568 char *prefix = argv[idx]->arg;
6569 char *mask = argv[idx + 1]->arg;
6570 bool rmap_found;
6571 char *rmap = NULL;
6572 int as_set =
6573 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6574 idx = 0;
6575 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6576 ? AGGREGATE_SUMMARY_ONLY
6577 : 0;
6578
6579 rmap_found = argv_find(argv, argc, "WORD", &idx);
6580 if (rmap_found)
6581 rmap = argv[idx]->arg;
6582
6583 char prefix_str[BUFSIZ];
6584 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6585
6586 if (!ret) {
6587 vty_out(vty, "%% Inconsistent address and mask\n");
6588 return CMD_WARNING_CONFIG_FAILED;
6589 }
6590
6591 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6592 rmap, summary_only, as_set);
6593 }
6594
6595 DEFUN (no_aggregate_address,
6596 no_aggregate_address_cmd,
6597 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6598 NO_STR
6599 "Configure BGP aggregate entries\n"
6600 "Aggregate prefix\n"
6601 "Generate AS set path information\n"
6602 "Filter more specific routes from updates\n"
6603 "Filter more specific routes from updates\n"
6604 "Generate AS set path information\n"
6605 "Apply route map to aggregate network\n"
6606 "Name of route map\n")
6607 {
6608 int idx = 0;
6609 argv_find(argv, argc, "A.B.C.D/M", &idx);
6610 char *prefix = argv[idx]->arg;
6611 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6612 }
6613
6614 DEFUN (no_aggregate_address_mask,
6615 no_aggregate_address_mask_cmd,
6616 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6617 NO_STR
6618 "Configure BGP aggregate entries\n"
6619 "Aggregate address\n"
6620 "Aggregate mask\n"
6621 "Generate AS set path information\n"
6622 "Filter more specific routes from updates\n"
6623 "Filter more specific routes from updates\n"
6624 "Generate AS set path information\n"
6625 "Apply route map to aggregate network\n"
6626 "Name of route map\n")
6627 {
6628 int idx = 0;
6629 argv_find(argv, argc, "A.B.C.D", &idx);
6630 char *prefix = argv[idx]->arg;
6631 char *mask = argv[idx + 1]->arg;
6632
6633 char prefix_str[BUFSIZ];
6634 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6635
6636 if (!ret) {
6637 vty_out(vty, "%% Inconsistent address and mask\n");
6638 return CMD_WARNING_CONFIG_FAILED;
6639 }
6640
6641 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6642 }
6643
6644 DEFUN (ipv6_aggregate_address,
6645 ipv6_aggregate_address_cmd,
6646 "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6647 "Configure BGP aggregate entries\n"
6648 "Aggregate prefix\n"
6649 "Generate AS set path information\n"
6650 "Filter more specific routes from updates\n"
6651 "Filter more specific routes from updates\n"
6652 "Generate AS set path information\n"
6653 "Apply route map to aggregate network\n"
6654 "Name of route map\n")
6655 {
6656 int idx = 0;
6657 argv_find(argv, argc, "X:X::X:X/M", &idx);
6658 char *prefix = argv[idx]->arg;
6659 char *rmap = NULL;
6660 bool rmap_found;
6661 int as_set =
6662 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6663
6664 idx = 0;
6665 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6666 ? AGGREGATE_SUMMARY_ONLY
6667 : 0;
6668
6669 rmap_found = argv_find(argv, argc, "WORD", &idx);
6670 if (rmap_found)
6671 rmap = argv[idx]->arg;
6672
6673 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
6674 sum_only, as_set);
6675 }
6676
6677 DEFUN (no_ipv6_aggregate_address,
6678 no_ipv6_aggregate_address_cmd,
6679 "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6680 NO_STR
6681 "Configure BGP aggregate entries\n"
6682 "Aggregate prefix\n"
6683 "Generate AS set path information\n"
6684 "Filter more specific routes from updates\n"
6685 "Filter more specific routes from updates\n"
6686 "Generate AS set path information\n"
6687 "Apply route map to aggregate network\n"
6688 "Name of route map\n")
6689 {
6690 int idx = 0;
6691 argv_find(argv, argc, "X:X::X:X/M", &idx);
6692 char *prefix = argv[idx]->arg;
6693 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6694 }
6695
6696 /* Redistribute route treatment. */
6697 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6698 const union g_addr *nexthop, ifindex_t ifindex,
6699 enum nexthop_types_t nhtype, uint32_t metric,
6700 uint8_t type, unsigned short instance,
6701 route_tag_t tag)
6702 {
6703 struct bgp_path_info *new;
6704 struct bgp_path_info *bpi;
6705 struct bgp_path_info rmap_path;
6706 struct bgp_node *bn;
6707 struct attr attr;
6708 struct attr *new_attr;
6709 afi_t afi;
6710 route_map_result_t ret;
6711 struct bgp_redist *red;
6712
6713 /* Make default attribute. */
6714 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6715 /*
6716 * This must not be NULL to satisfy Coverity SA
6717 */
6718 assert(attr.aspath);
6719
6720 switch (nhtype) {
6721 case NEXTHOP_TYPE_IFINDEX:
6722 break;
6723 case NEXTHOP_TYPE_IPV4:
6724 case NEXTHOP_TYPE_IPV4_IFINDEX:
6725 attr.nexthop = nexthop->ipv4;
6726 break;
6727 case NEXTHOP_TYPE_IPV6:
6728 case NEXTHOP_TYPE_IPV6_IFINDEX:
6729 attr.mp_nexthop_global = nexthop->ipv6;
6730 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6731 break;
6732 case NEXTHOP_TYPE_BLACKHOLE:
6733 switch (p->family) {
6734 case AF_INET:
6735 attr.nexthop.s_addr = INADDR_ANY;
6736 break;
6737 case AF_INET6:
6738 memset(&attr.mp_nexthop_global, 0,
6739 sizeof(attr.mp_nexthop_global));
6740 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6741 break;
6742 }
6743 break;
6744 }
6745 attr.nh_ifindex = ifindex;
6746
6747 attr.med = metric;
6748 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6749 attr.tag = tag;
6750
6751 afi = family2afi(p->family);
6752
6753 red = bgp_redist_lookup(bgp, afi, type, instance);
6754 if (red) {
6755 struct attr attr_new;
6756
6757 /* Copy attribute for modification. */
6758 bgp_attr_dup(&attr_new, &attr);
6759
6760 if (red->redist_metric_flag)
6761 attr_new.med = red->redist_metric;
6762
6763 /* Apply route-map. */
6764 if (red->rmap.name) {
6765 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
6766 rmap_path.peer = bgp->peer_self;
6767 rmap_path.attr = &attr_new;
6768
6769 SET_FLAG(bgp->peer_self->rmap_type,
6770 PEER_RMAP_TYPE_REDISTRIBUTE);
6771
6772 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6773 &rmap_path);
6774
6775 bgp->peer_self->rmap_type = 0;
6776
6777 if (ret == RMAP_DENYMATCH) {
6778 /* Free uninterned attribute. */
6779 bgp_attr_flush(&attr_new);
6780
6781 /* Unintern original. */
6782 aspath_unintern(&attr.aspath);
6783 bgp_redistribute_delete(bgp, p, type, instance);
6784 return;
6785 }
6786 }
6787
6788 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
6789 bgp_attr_add_gshut_community(&attr_new);
6790
6791 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6792 SAFI_UNICAST, p, NULL);
6793
6794 new_attr = bgp_attr_intern(&attr_new);
6795
6796 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
6797 bpi = bpi->next)
6798 if (bpi->peer == bgp->peer_self
6799 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6800 break;
6801
6802 if (bpi) {
6803 /* Ensure the (source route) type is updated. */
6804 bpi->type = type;
6805 if (attrhash_cmp(bpi->attr, new_attr)
6806 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
6807 bgp_attr_unintern(&new_attr);
6808 aspath_unintern(&attr.aspath);
6809 bgp_unlock_node(bn);
6810 return;
6811 } else {
6812 /* The attribute is changed. */
6813 bgp_path_info_set_flag(bn, bpi,
6814 BGP_PATH_ATTR_CHANGED);
6815
6816 /* Rewrite BGP route information. */
6817 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
6818 bgp_path_info_restore(bn, bpi);
6819 else
6820 bgp_aggregate_decrement(
6821 bgp, p, bpi, afi, SAFI_UNICAST);
6822 bgp_attr_unintern(&bpi->attr);
6823 bpi->attr = new_attr;
6824 bpi->uptime = bgp_clock();
6825
6826 /* Process change. */
6827 bgp_aggregate_increment(bgp, p, bpi, afi,
6828 SAFI_UNICAST);
6829 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6830 bgp_unlock_node(bn);
6831 aspath_unintern(&attr.aspath);
6832
6833 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6834 || (bgp->inst_type
6835 == BGP_INSTANCE_TYPE_DEFAULT)) {
6836
6837 vpn_leak_from_vrf_update(
6838 bgp_get_default(), bgp, bpi);
6839 }
6840 return;
6841 }
6842 }
6843
6844 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6845 bgp->peer_self, new_attr, bn);
6846 SET_FLAG(new->flags, BGP_PATH_VALID);
6847
6848 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6849 bgp_path_info_add(bn, new);
6850 bgp_unlock_node(bn);
6851 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6852
6853 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6854 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6855
6856 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6857 }
6858 }
6859
6860 /* Unintern original. */
6861 aspath_unintern(&attr.aspath);
6862 }
6863
6864 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
6865 unsigned short instance)
6866 {
6867 afi_t afi;
6868 struct bgp_node *rn;
6869 struct bgp_path_info *pi;
6870 struct bgp_redist *red;
6871
6872 afi = family2afi(p->family);
6873
6874 red = bgp_redist_lookup(bgp, afi, type, instance);
6875 if (red) {
6876 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6877 SAFI_UNICAST, p, NULL);
6878
6879 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6880 if (pi->peer == bgp->peer_self && pi->type == type)
6881 break;
6882
6883 if (pi) {
6884 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6885 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6886
6887 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6888 bgp, pi);
6889 }
6890 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
6891 bgp_path_info_delete(rn, pi);
6892 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6893 }
6894 bgp_unlock_node(rn);
6895 }
6896 }
6897
6898 /* Withdraw specified route type's route. */
6899 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6900 unsigned short instance)
6901 {
6902 struct bgp_node *rn;
6903 struct bgp_path_info *pi;
6904 struct bgp_table *table;
6905
6906 table = bgp->rib[afi][SAFI_UNICAST];
6907
6908 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6909 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6910 if (pi->peer == bgp->peer_self && pi->type == type
6911 && pi->instance == instance)
6912 break;
6913
6914 if (pi) {
6915 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6916 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6917
6918 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6919 bgp, pi);
6920 }
6921 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
6922 SAFI_UNICAST);
6923 bgp_path_info_delete(rn, pi);
6924 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6925 }
6926 }
6927 }
6928
6929 /* Static function to display route. */
6930 static void route_vty_out_route(struct prefix *p, struct vty *vty,
6931 json_object *json)
6932 {
6933 int len = 0;
6934 char buf[BUFSIZ];
6935 char buf2[BUFSIZ];
6936
6937 if (p->family == AF_INET) {
6938 if (!json) {
6939 len = vty_out(
6940 vty, "%s/%d",
6941 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6942 p->prefixlen);
6943 } else {
6944 json_object_string_add(json, "prefix",
6945 inet_ntop(p->family,
6946 &p->u.prefix, buf,
6947 BUFSIZ));
6948 json_object_int_add(json, "prefixLen", p->prefixlen);
6949 prefix2str(p, buf2, PREFIX_STRLEN);
6950 json_object_string_add(json, "network", buf2);
6951 }
6952 } else if (p->family == AF_ETHERNET) {
6953 prefix2str(p, buf, PREFIX_STRLEN);
6954 len = vty_out(vty, "%s", buf);
6955 } else if (p->family == AF_EVPN) {
6956 if (!json)
6957 len = vty_out(
6958 vty, "%s",
6959 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
6960 BUFSIZ));
6961 else
6962 bgp_evpn_route2json((struct prefix_evpn *)p, json);
6963 } else if (p->family == AF_FLOWSPEC) {
6964 route_vty_out_flowspec(vty, p, NULL,
6965 json ?
6966 NLRI_STRING_FORMAT_JSON_SIMPLE :
6967 NLRI_STRING_FORMAT_MIN, json);
6968 } else {
6969 if (!json)
6970 len = vty_out(
6971 vty, "%s/%d",
6972 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6973 p->prefixlen);
6974 else {
6975 json_object_string_add(json, "prefix",
6976 inet_ntop(p->family,
6977 &p->u.prefix, buf,
6978 BUFSIZ));
6979 json_object_int_add(json, "prefixLen", p->prefixlen);
6980 prefix2str(p, buf2, PREFIX_STRLEN);
6981 json_object_string_add(json, "network", buf2);
6982 }
6983 }
6984
6985 if (!json) {
6986 len = 17 - len;
6987 if (len < 1)
6988 vty_out(vty, "\n%*s", 20, " ");
6989 else
6990 vty_out(vty, "%*s", len, " ");
6991 }
6992 }
6993
6994 enum bgp_display_type {
6995 normal_list,
6996 };
6997
6998 /* Print the short form route status for a bgp_path_info */
6999 static void route_vty_short_status_out(struct vty *vty,
7000 struct bgp_path_info *path,
7001 json_object *json_path)
7002 {
7003 if (json_path) {
7004
7005 /* Route status display. */
7006 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7007 json_object_boolean_true_add(json_path, "removed");
7008
7009 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7010 json_object_boolean_true_add(json_path, "stale");
7011
7012 if (path->extra && path->extra->suppress)
7013 json_object_boolean_true_add(json_path, "suppressed");
7014
7015 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7016 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7017 json_object_boolean_true_add(json_path, "valid");
7018
7019 /* Selected */
7020 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7021 json_object_boolean_true_add(json_path, "history");
7022
7023 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7024 json_object_boolean_true_add(json_path, "damped");
7025
7026 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7027 json_object_boolean_true_add(json_path, "bestpath");
7028
7029 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7030 json_object_boolean_true_add(json_path, "multipath");
7031
7032 /* Internal route. */
7033 if ((path->peer->as)
7034 && (path->peer->as == path->peer->local_as))
7035 json_object_string_add(json_path, "pathFrom",
7036 "internal");
7037 else
7038 json_object_string_add(json_path, "pathFrom",
7039 "external");
7040
7041 return;
7042 }
7043
7044 /* Route status display. */
7045 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7046 vty_out(vty, "R");
7047 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7048 vty_out(vty, "S");
7049 else if (path->extra && path->extra->suppress)
7050 vty_out(vty, "s");
7051 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7052 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7053 vty_out(vty, "*");
7054 else
7055 vty_out(vty, " ");
7056
7057 /* Selected */
7058 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7059 vty_out(vty, "h");
7060 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7061 vty_out(vty, "d");
7062 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7063 vty_out(vty, ">");
7064 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7065 vty_out(vty, "=");
7066 else
7067 vty_out(vty, " ");
7068
7069 /* Internal route. */
7070 if (path->peer && (path->peer->as)
7071 && (path->peer->as == path->peer->local_as))
7072 vty_out(vty, "i");
7073 else
7074 vty_out(vty, " ");
7075 }
7076
7077 static char *bgp_nexthop_fqdn(struct peer *peer)
7078 {
7079 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7080 return peer->hostname;
7081 return NULL;
7082 }
7083
7084 /* called from terminal list command */
7085 void route_vty_out(struct vty *vty, struct prefix *p,
7086 struct bgp_path_info *path, int display, safi_t safi,
7087 json_object *json_paths)
7088 {
7089 struct attr *attr;
7090 json_object *json_path = NULL;
7091 json_object *json_nexthops = NULL;
7092 json_object *json_nexthop_global = NULL;
7093 json_object *json_nexthop_ll = NULL;
7094 json_object *json_ext_community = NULL;
7095 char vrf_id_str[VRF_NAMSIZ] = {0};
7096 bool nexthop_self =
7097 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7098 bool nexthop_othervrf = false;
7099 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7100 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7101 char *nexthop_fqdn = bgp_nexthop_fqdn(path->peer);
7102
7103 if (json_paths)
7104 json_path = json_object_new_object();
7105
7106 /* short status lead text */
7107 route_vty_short_status_out(vty, path, json_path);
7108
7109 if (!json_paths) {
7110 /* print prefix and mask */
7111 if (!display)
7112 route_vty_out_route(p, vty, json_path);
7113 else
7114 vty_out(vty, "%*s", 17, " ");
7115 } else {
7116 route_vty_out_route(p, vty, json_path);
7117 }
7118
7119 /* Print attribute */
7120 attr = path->attr;
7121
7122 /*
7123 * If vrf id of nexthop is different from that of prefix,
7124 * set up printable string to append
7125 */
7126 if (path->extra && path->extra->bgp_orig) {
7127 const char *self = "";
7128
7129 if (nexthop_self)
7130 self = "<";
7131
7132 nexthop_othervrf = true;
7133 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7134
7135 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7136 snprintf(vrf_id_str, sizeof(vrf_id_str),
7137 "@%s%s", VRFID_NONE_STR, self);
7138 else
7139 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7140 path->extra->bgp_orig->vrf_id, self);
7141
7142 if (path->extra->bgp_orig->inst_type
7143 != BGP_INSTANCE_TYPE_DEFAULT)
7144
7145 nexthop_vrfname = path->extra->bgp_orig->name;
7146 } else {
7147 const char *self = "";
7148
7149 if (nexthop_self)
7150 self = "<";
7151
7152 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7153 }
7154
7155 /*
7156 * For ENCAP and EVPN routes, nexthop address family is not
7157 * neccessarily the same as the prefix address family.
7158 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7159 * EVPN routes are also exchanged with a MP nexthop. Currently,
7160 * this
7161 * is only IPv4, the value will be present in either
7162 * attr->nexthop or
7163 * attr->mp_nexthop_global_in
7164 */
7165 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7166 char buf[BUFSIZ];
7167 char nexthop[128];
7168 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7169
7170 switch (af) {
7171 case AF_INET:
7172 sprintf(nexthop, "%s",
7173 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7174 BUFSIZ));
7175 break;
7176 case AF_INET6:
7177 sprintf(nexthop, "%s",
7178 inet_ntop(af, &attr->mp_nexthop_global, buf,
7179 BUFSIZ));
7180 break;
7181 default:
7182 sprintf(nexthop, "?");
7183 break;
7184 }
7185
7186 if (json_paths) {
7187 json_nexthop_global = json_object_new_object();
7188
7189 json_object_string_add(
7190 json_nexthop_global, "afi",
7191 nexthop_fqdn ? "fqdn"
7192 : (af == AF_INET) ? "ip" : "ipv6");
7193 json_object_string_add(
7194 json_nexthop_global,
7195 nexthop_fqdn ? "fqdn"
7196 : (af == AF_INET) ? "ip" : "ipv6",
7197 nexthop_fqdn ? nexthop_fqdn : nexthop);
7198 json_object_boolean_true_add(json_nexthop_global,
7199 "used");
7200 } else
7201 vty_out(vty, "%s%s",
7202 nexthop_fqdn ? nexthop_fqdn : nexthop,
7203 vrf_id_str);
7204 } else if (safi == SAFI_EVPN) {
7205 if (json_paths) {
7206 json_nexthop_global = json_object_new_object();
7207
7208 json_object_string_add(
7209 json_nexthop_global,
7210 nexthop_fqdn ? "fqdn" : "ip",
7211 nexthop_fqdn ? nexthop_fqdn
7212 : inet_ntoa(attr->nexthop));
7213 json_object_string_add(json_nexthop_global, "afi",
7214 "ipv4");
7215 json_object_boolean_true_add(json_nexthop_global,
7216 "used");
7217 } else
7218 vty_out(vty, "%-16s%s",
7219 nexthop_fqdn ?: inet_ntoa(attr->nexthop),
7220 vrf_id_str);
7221 } else if (safi == SAFI_FLOWSPEC) {
7222 if (attr->nexthop.s_addr != 0) {
7223 if (json_paths) {
7224 json_nexthop_global = json_object_new_object();
7225 json_object_string_add(
7226 json_nexthop_global,
7227 nexthop_fqdn ? "fqdn" : "ip",
7228 nexthop_fqdn
7229 ? nexthop_fqdn
7230 : inet_ntoa(attr->nexthop));
7231 json_object_string_add(json_nexthop_global,
7232 "afi", "ipv4");
7233 json_object_boolean_true_add(
7234 json_nexthop_global,
7235 "used");
7236 } else {
7237 vty_out(vty, "%-16s",
7238 nexthop_fqdn
7239 ? nexthop_fqdn
7240 : inet_ntoa(attr->nexthop));
7241 }
7242 }
7243 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7244 if (json_paths) {
7245 json_nexthop_global = json_object_new_object();
7246
7247 json_object_string_add(json_nexthop_global,
7248 nexthop_fqdn ? "fqdn" : "ip",
7249 nexthop_fqdn
7250 ? nexthop_fqdn
7251 : inet_ntoa(attr->nexthop));
7252
7253 json_object_string_add(json_nexthop_global, "afi",
7254 "ipv4");
7255 json_object_boolean_true_add(json_nexthop_global,
7256 "used");
7257 } else {
7258 char buf[BUFSIZ];
7259
7260 snprintf(buf, sizeof(buf), "%s%s",
7261 nexthop_fqdn ? nexthop_fqdn
7262 : inet_ntoa(attr->nexthop),
7263 vrf_id_str);
7264 vty_out(vty, "%-16s", buf);
7265 }
7266 }
7267
7268 /* IPv6 Next Hop */
7269 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7270 int len;
7271 char buf[BUFSIZ];
7272
7273 if (json_paths) {
7274 json_nexthop_global = json_object_new_object();
7275 json_object_string_add(
7276 json_nexthop_global,
7277 nexthop_fqdn ? "fqdn" : "ip",
7278 nexthop_fqdn
7279 ? nexthop_fqdn
7280 : inet_ntop(AF_INET6,
7281 &attr->mp_nexthop_global,
7282 buf, BUFSIZ));
7283 json_object_string_add(json_nexthop_global, "afi",
7284 "ipv6");
7285 json_object_string_add(json_nexthop_global, "scope",
7286 "global");
7287
7288 /* We display both LL & GL if both have been
7289 * received */
7290 if ((attr->mp_nexthop_len
7291 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7292 || (path->peer->conf_if)) {
7293 json_nexthop_ll = json_object_new_object();
7294 json_object_string_add(
7295 json_nexthop_ll,
7296 nexthop_fqdn ? "fqdn" : "ip",
7297 nexthop_fqdn
7298 ? nexthop_fqdn
7299 : inet_ntop(
7300 AF_INET6,
7301 &attr->mp_nexthop_local,
7302 buf, BUFSIZ));
7303 json_object_string_add(json_nexthop_ll, "afi",
7304 "ipv6");
7305 json_object_string_add(json_nexthop_ll, "scope",
7306 "link-local");
7307
7308 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7309 &attr->mp_nexthop_local)
7310 != 0)
7311 && !attr->mp_nexthop_prefer_global)
7312 json_object_boolean_true_add(
7313 json_nexthop_ll, "used");
7314 else
7315 json_object_boolean_true_add(
7316 json_nexthop_global, "used");
7317 } else
7318 json_object_boolean_true_add(
7319 json_nexthop_global, "used");
7320 } else {
7321 /* Display LL if LL/Global both in table unless
7322 * prefer-global is set */
7323 if (((attr->mp_nexthop_len
7324 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7325 && !attr->mp_nexthop_prefer_global)
7326 || (path->peer->conf_if)) {
7327 if (path->peer->conf_if) {
7328 len = vty_out(vty, "%s",
7329 path->peer->conf_if);
7330 len = 16 - len; /* len of IPv6
7331 addr + max
7332 len of def
7333 ifname */
7334
7335 if (len < 1)
7336 vty_out(vty, "\n%*s", 36, " ");
7337 else
7338 vty_out(vty, "%*s", len, " ");
7339 } else {
7340 len = vty_out(
7341 vty, "%s%s",
7342 nexthop_fqdn
7343 ? nexthop_fqdn
7344 : inet_ntop(
7345 AF_INET6,
7346 &attr->mp_nexthop_local,
7347 buf, BUFSIZ),
7348 vrf_id_str);
7349 len = 16 - len;
7350
7351 if (len < 1)
7352 vty_out(vty, "\n%*s", 36, " ");
7353 else
7354 vty_out(vty, "%*s", len, " ");
7355 }
7356 } else {
7357 len = vty_out(
7358 vty, "%s%s",
7359 nexthop_fqdn
7360 ? nexthop_fqdn
7361 : inet_ntop(
7362 AF_INET6,
7363 &attr->mp_nexthop_global,
7364 buf, BUFSIZ),
7365 vrf_id_str);
7366 len = 16 - len;
7367
7368 if (len < 1)
7369 vty_out(vty, "\n%*s", 36, " ");
7370 else
7371 vty_out(vty, "%*s", len, " ");
7372 }
7373 }
7374 }
7375
7376 /* MED/Metric */
7377 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7378 if (json_paths) {
7379
7380 /*
7381 * Adding "metric" field to match with corresponding
7382 * CLI. "med" will be deprecated in future.
7383 */
7384 json_object_int_add(json_path, "med", attr->med);
7385 json_object_int_add(json_path, "metric", attr->med);
7386 } else
7387 vty_out(vty, "%10u", attr->med);
7388 else if (!json_paths)
7389 vty_out(vty, " ");
7390
7391 /* Local Pref */
7392 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7393 if (json_paths) {
7394
7395 /*
7396 * Adding "locPrf" field to match with corresponding
7397 * CLI. "localPref" will be deprecated in future.
7398 */
7399 json_object_int_add(json_path, "localpref",
7400 attr->local_pref);
7401 json_object_int_add(json_path, "locPrf",
7402 attr->local_pref);
7403 } else
7404 vty_out(vty, "%7u", attr->local_pref);
7405 else if (!json_paths)
7406 vty_out(vty, " ");
7407
7408 if (json_paths)
7409 json_object_int_add(json_path, "weight", attr->weight);
7410 else
7411 vty_out(vty, "%7u ", attr->weight);
7412
7413 if (json_paths) {
7414 char buf[BUFSIZ];
7415 json_object_string_add(
7416 json_path, "peerId",
7417 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7418 }
7419
7420 /* Print aspath */
7421 if (attr->aspath) {
7422 if (json_paths) {
7423
7424 /*
7425 * Adding "path" field to match with corresponding
7426 * CLI. "aspath" will be deprecated in future.
7427 */
7428 json_object_string_add(json_path, "aspath",
7429 attr->aspath->str);
7430 json_object_string_add(json_path, "path",
7431 attr->aspath->str);
7432 } else
7433 aspath_print_vty(vty, "%s", attr->aspath, " ");
7434 }
7435
7436 /* Print origin */
7437 if (json_paths)
7438 json_object_string_add(json_path, "origin",
7439 bgp_origin_long_str[attr->origin]);
7440 else
7441 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7442
7443 if (json_paths) {
7444 if (safi == SAFI_EVPN &&
7445 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7446 json_ext_community = json_object_new_object();
7447 json_object_string_add(json_ext_community,
7448 "string",
7449 attr->ecommunity->str);
7450 json_object_object_add(json_path,
7451 "extendedCommunity",
7452 json_ext_community);
7453 }
7454
7455 if (nexthop_self)
7456 json_object_boolean_true_add(json_path,
7457 "announceNexthopSelf");
7458 if (nexthop_othervrf) {
7459 json_object_string_add(json_path, "nhVrfName",
7460 nexthop_vrfname);
7461
7462 json_object_int_add(json_path, "nhVrfId",
7463 ((nexthop_vrfid == VRF_UNKNOWN)
7464 ? -1
7465 : (int)nexthop_vrfid));
7466 }
7467 }
7468
7469 if (json_paths) {
7470 if (json_nexthop_global || json_nexthop_ll) {
7471 json_nexthops = json_object_new_array();
7472
7473 if (json_nexthop_global)
7474 json_object_array_add(json_nexthops,
7475 json_nexthop_global);
7476
7477 if (json_nexthop_ll)
7478 json_object_array_add(json_nexthops,
7479 json_nexthop_ll);
7480
7481 json_object_object_add(json_path, "nexthops",
7482 json_nexthops);
7483 }
7484
7485 json_object_array_add(json_paths, json_path);
7486 } else {
7487 vty_out(vty, "\n");
7488
7489 if (safi == SAFI_EVPN &&
7490 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7491 vty_out(vty, "%*s", 20, " ");
7492 vty_out(vty, "%s\n", attr->ecommunity->str);
7493 }
7494
7495 #if ENABLE_BGP_VNC
7496 /* prints an additional line, indented, with VNC info, if
7497 * present */
7498 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7499 rfapi_vty_out_vncinfo(vty, p, path, safi);
7500 #endif
7501 }
7502 }
7503
7504 /* called from terminal list command */
7505 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7506 safi_t safi, bool use_json, json_object *json_ar)
7507 {
7508 json_object *json_status = NULL;
7509 json_object *json_net = NULL;
7510 char buff[BUFSIZ];
7511
7512 /* Route status display. */
7513 if (use_json) {
7514 json_status = json_object_new_object();
7515 json_net = json_object_new_object();
7516 } else {
7517 vty_out(vty, "*");
7518 vty_out(vty, ">");
7519 vty_out(vty, " ");
7520 }
7521
7522 /* print prefix and mask */
7523 if (use_json) {
7524 if (safi == SAFI_EVPN)
7525 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
7526 else if (p->family == AF_INET || p->family == AF_INET6) {
7527 json_object_string_add(
7528 json_net, "addrPrefix",
7529 inet_ntop(p->family, &p->u.prefix, buff,
7530 BUFSIZ));
7531 json_object_int_add(json_net, "prefixLen",
7532 p->prefixlen);
7533 prefix2str(p, buff, PREFIX_STRLEN);
7534 json_object_string_add(json_net, "network", buff);
7535 }
7536 } else
7537 route_vty_out_route(p, vty, NULL);
7538
7539 /* Print attribute */
7540 if (attr) {
7541 if (use_json) {
7542 if (p->family == AF_INET
7543 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7544 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7545 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
7546 json_object_string_add(
7547 json_net, "nextHop",
7548 inet_ntoa(
7549 attr->mp_nexthop_global_in));
7550 else
7551 json_object_string_add(
7552 json_net, "nextHop",
7553 inet_ntoa(attr->nexthop));
7554 } else if (p->family == AF_INET6
7555 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7556 char buf[BUFSIZ];
7557
7558 json_object_string_add(
7559 json_net, "nextHopGlobal",
7560 inet_ntop(AF_INET6,
7561 &attr->mp_nexthop_global, buf,
7562 BUFSIZ));
7563 } else if (p->family == AF_EVPN &&
7564 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7565 json_object_string_add(json_net,
7566 "nextHop", inet_ntoa(
7567 attr->mp_nexthop_global_in));
7568
7569 if (attr->flag
7570 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7571 json_object_int_add(json_net, "metric",
7572 attr->med);
7573
7574 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7575
7576 /*
7577 * Adding "locPrf" field to match with
7578 * corresponding CLI. "localPref" will be
7579 * deprecated in future.
7580 */
7581 json_object_int_add(json_net, "localPref",
7582 attr->local_pref);
7583 json_object_int_add(json_net, "locPrf",
7584 attr->local_pref);
7585 }
7586
7587 json_object_int_add(json_net, "weight", attr->weight);
7588
7589 /* Print aspath */
7590 if (attr->aspath) {
7591
7592 /*
7593 * Adding "path" field to match with
7594 * corresponding CLI. "localPref" will be
7595 * deprecated in future.
7596 */
7597 json_object_string_add(json_net, "asPath",
7598 attr->aspath->str);
7599 json_object_string_add(json_net, "path",
7600 attr->aspath->str);
7601 }
7602
7603 /* Print origin */
7604 json_object_string_add(json_net, "bgpOriginCode",
7605 bgp_origin_str[attr->origin]);
7606 } else {
7607 if (p->family == AF_INET
7608 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7609 || safi == SAFI_EVPN
7610 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7611 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7612 || safi == SAFI_EVPN)
7613 vty_out(vty, "%-16s",
7614 inet_ntoa(
7615 attr->mp_nexthop_global_in));
7616 else
7617 vty_out(vty, "%-16s",
7618 inet_ntoa(attr->nexthop));
7619 } else if (p->family == AF_INET6
7620 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7621 int len;
7622 char buf[BUFSIZ];
7623
7624 len = vty_out(
7625 vty, "%s",
7626 inet_ntop(AF_INET6,
7627 &attr->mp_nexthop_global, buf,
7628 BUFSIZ));
7629 len = 16 - len;
7630 if (len < 1)
7631 vty_out(vty, "\n%*s", 36, " ");
7632 else
7633 vty_out(vty, "%*s", len, " ");
7634 }
7635 if (attr->flag
7636 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7637 vty_out(vty, "%10u", attr->med);
7638 else
7639 vty_out(vty, " ");
7640
7641 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7642 vty_out(vty, "%7u", attr->local_pref);
7643 else
7644 vty_out(vty, " ");
7645
7646 vty_out(vty, "%7u ", attr->weight);
7647
7648 /* Print aspath */
7649 if (attr->aspath)
7650 aspath_print_vty(vty, "%s", attr->aspath, " ");
7651
7652 /* Print origin */
7653 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7654 }
7655 }
7656 if (use_json) {
7657 json_object_boolean_true_add(json_status, "*");
7658 json_object_boolean_true_add(json_status, ">");
7659 json_object_object_add(json_net, "appliedStatusSymbols",
7660 json_status);
7661
7662 prefix2str(p, buff, PREFIX_STRLEN);
7663 json_object_object_add(json_ar, buff, json_net);
7664 } else
7665 vty_out(vty, "\n");
7666 }
7667
7668 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7669 struct bgp_path_info *path, int display, safi_t safi,
7670 json_object *json)
7671 {
7672 json_object *json_out = NULL;
7673 struct attr *attr;
7674 mpls_label_t label = MPLS_INVALID_LABEL;
7675
7676 if (!path->extra)
7677 return;
7678
7679 if (json)
7680 json_out = json_object_new_object();
7681
7682 /* short status lead text */
7683 route_vty_short_status_out(vty, path, json_out);
7684
7685 /* print prefix and mask */
7686 if (json == NULL) {
7687 if (!display)
7688 route_vty_out_route(p, vty, NULL);
7689 else
7690 vty_out(vty, "%*s", 17, " ");
7691 }
7692
7693 /* Print attribute */
7694 attr = path->attr;
7695 if (((p->family == AF_INET)
7696 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7697 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7698 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7699 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7700 || safi == SAFI_EVPN) {
7701 if (json)
7702 json_object_string_add(
7703 json_out, "mpNexthopGlobalIn",
7704 inet_ntoa(attr->mp_nexthop_global_in));
7705 else
7706 vty_out(vty, "%-16s",
7707 inet_ntoa(attr->mp_nexthop_global_in));
7708 } else {
7709 if (json)
7710 json_object_string_add(
7711 json_out, "nexthop",
7712 inet_ntoa(attr->nexthop));
7713 else
7714 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
7715 }
7716 } else if (((p->family == AF_INET6)
7717 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7718 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7719 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7720 char buf_a[512];
7721
7722 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
7723 if (json)
7724 json_object_string_add(
7725 json_out, "mpNexthopGlobalIn",
7726 inet_ntop(AF_INET6,
7727 &attr->mp_nexthop_global,
7728 buf_a, sizeof(buf_a)));
7729 else
7730 vty_out(vty, "%s",
7731 inet_ntop(AF_INET6,
7732 &attr->mp_nexthop_global,
7733 buf_a, sizeof(buf_a)));
7734 } else if (attr->mp_nexthop_len
7735 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7736 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
7737 &attr->mp_nexthop_global,
7738 &attr->mp_nexthop_local);
7739 if (json)
7740 json_object_string_add(json_out,
7741 "mpNexthopGlobalLocal",
7742 buf_a);
7743 else
7744 vty_out(vty, "%s", buf_a);
7745 }
7746 }
7747
7748 label = decode_label(&path->extra->label[0]);
7749
7750 if (bgp_is_valid_label(&label)) {
7751 if (json) {
7752 json_object_int_add(json_out, "notag", label);
7753 json_object_array_add(json, json_out);
7754 } else {
7755 vty_out(vty, "notag/%d", label);
7756 vty_out(vty, "\n");
7757 }
7758 }
7759 }
7760
7761 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7762 struct bgp_path_info *path, int display,
7763 json_object *json_paths)
7764 {
7765 struct attr *attr;
7766 char buf[BUFSIZ] = {0};
7767 json_object *json_path = NULL;
7768 json_object *json_nexthop = NULL;
7769 json_object *json_overlay = NULL;
7770
7771 if (!path->extra)
7772 return;
7773
7774 if (json_paths) {
7775 json_path = json_object_new_object();
7776 json_overlay = json_object_new_object();
7777 json_nexthop = json_object_new_object();
7778 }
7779
7780 /* short status lead text */
7781 route_vty_short_status_out(vty, path, json_path);
7782
7783 /* print prefix and mask */
7784 if (!display)
7785 route_vty_out_route(p, vty, json_path);
7786 else
7787 vty_out(vty, "%*s", 17, " ");
7788
7789 /* Print attribute */
7790 attr = path->attr;
7791 char buf1[BUFSIZ];
7792 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7793
7794 switch (af) {
7795 case AF_INET:
7796 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
7797 if (!json_path) {
7798 vty_out(vty, "%-16s", buf);
7799 } else {
7800 json_object_string_add(json_nexthop, "ip", buf);
7801
7802 json_object_string_add(json_nexthop, "afi", "ipv4");
7803
7804 json_object_object_add(json_path, "nexthop",
7805 json_nexthop);
7806 }
7807 break;
7808 case AF_INET6:
7809 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
7810 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
7811 if (!json_path) {
7812 vty_out(vty, "%s(%s)", buf, buf1);
7813 } else {
7814 json_object_string_add(json_nexthop, "ipv6Global", buf);
7815
7816 json_object_string_add(json_nexthop, "ipv6LinkLocal",
7817 buf1);
7818
7819 json_object_string_add(json_nexthop, "afi", "ipv6");
7820
7821 json_object_object_add(json_path, "nexthop",
7822 json_nexthop);
7823 }
7824 break;
7825 default:
7826 if (!json_path) {
7827 vty_out(vty, "?");
7828 } else {
7829 json_object_string_add(json_nexthop, "Error",
7830 "Unsupported address-family");
7831 }
7832 }
7833
7834 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7835
7836 if (!json_path)
7837 vty_out(vty, "%s", str);
7838 else
7839 json_object_string_add(json_overlay, "esi", str);
7840
7841 XFREE(MTYPE_TMP, str);
7842
7843 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7844 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
7845 BUFSIZ);
7846 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7847 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
7848 BUFSIZ);
7849 }
7850
7851 if (!json_path)
7852 vty_out(vty, "/%s", buf);
7853 else
7854 json_object_string_add(json_overlay, "gw", buf);
7855
7856 if (attr->ecommunity) {
7857 char *mac = NULL;
7858 struct ecommunity_val *routermac = ecommunity_lookup(
7859 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7860 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7861
7862 if (routermac)
7863 mac = ecom_mac2str((char *)routermac->val);
7864 if (mac) {
7865 if (!json_path) {
7866 vty_out(vty, "/%s", (char *)mac);
7867 } else {
7868 json_object_string_add(json_overlay, "rmac",
7869 mac);
7870 }
7871 XFREE(MTYPE_TMP, mac);
7872 }
7873 }
7874
7875 if (!json_path) {
7876 vty_out(vty, "\n");
7877 } else {
7878 json_object_object_add(json_path, "overlay", json_overlay);
7879
7880 json_object_array_add(json_paths, json_path);
7881 }
7882 }
7883
7884 /* dampening route */
7885 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7886 struct bgp_path_info *path, int display,
7887 safi_t safi, bool use_json, json_object *json)
7888 {
7889 struct attr *attr;
7890 int len;
7891 char timebuf[BGP_UPTIME_LEN];
7892
7893 /* short status lead text */
7894 route_vty_short_status_out(vty, path, json);
7895
7896 /* print prefix and mask */
7897 if (!use_json) {
7898 if (!display)
7899 route_vty_out_route(p, vty, NULL);
7900 else
7901 vty_out(vty, "%*s", 17, " ");
7902 }
7903
7904 len = vty_out(vty, "%s", path->peer->host);
7905 len = 17 - len;
7906 if (len < 1) {
7907 if (!use_json)
7908 vty_out(vty, "\n%*s", 34, " ");
7909 } else {
7910 if (use_json)
7911 json_object_int_add(json, "peerHost", len);
7912 else
7913 vty_out(vty, "%*s", len, " ");
7914 }
7915
7916 if (use_json)
7917 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN,
7918 use_json, json);
7919 else
7920 vty_out(vty, "%s ",
7921 bgp_damp_reuse_time_vty(vty, path, timebuf,
7922 BGP_UPTIME_LEN, use_json,
7923 json));
7924
7925 /* Print attribute */
7926 attr = path->attr;
7927
7928 /* Print aspath */
7929 if (attr->aspath) {
7930 if (use_json)
7931 json_object_string_add(json, "asPath",
7932 attr->aspath->str);
7933 else
7934 aspath_print_vty(vty, "%s", attr->aspath, " ");
7935 }
7936
7937 /* Print origin */
7938 if (use_json)
7939 json_object_string_add(json, "origin",
7940 bgp_origin_str[attr->origin]);
7941 else
7942 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7943
7944 if (!use_json)
7945 vty_out(vty, "\n");
7946 }
7947
7948 /* flap route */
7949 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7950 struct bgp_path_info *path, int display,
7951 safi_t safi, bool use_json, json_object *json)
7952 {
7953 struct attr *attr;
7954 struct bgp_damp_info *bdi;
7955 char timebuf[BGP_UPTIME_LEN];
7956 int len;
7957
7958 if (!path->extra)
7959 return;
7960
7961 bdi = path->extra->damp_info;
7962
7963 /* short status lead text */
7964 route_vty_short_status_out(vty, path, json);
7965
7966 /* print prefix and mask */
7967 if (!use_json) {
7968 if (!display)
7969 route_vty_out_route(p, vty, NULL);
7970 else
7971 vty_out(vty, "%*s", 17, " ");
7972 }
7973
7974 len = vty_out(vty, "%s", path->peer->host);
7975 len = 16 - len;
7976 if (len < 1) {
7977 if (!use_json)
7978 vty_out(vty, "\n%*s", 33, " ");
7979 } else {
7980 if (use_json)
7981 json_object_int_add(json, "peerHost", len);
7982 else
7983 vty_out(vty, "%*s", len, " ");
7984 }
7985
7986 len = vty_out(vty, "%d", bdi->flap);
7987 len = 5 - len;
7988 if (len < 1) {
7989 if (!use_json)
7990 vty_out(vty, " ");
7991 } else {
7992 if (use_json)
7993 json_object_int_add(json, "bdiFlap", len);
7994 else
7995 vty_out(vty, "%*s", len, " ");
7996 }
7997
7998 if (use_json)
7999 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8000 json);
8001 else
8002 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8003 BGP_UPTIME_LEN, 0, NULL));
8004
8005 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8006 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8007 if (use_json)
8008 bgp_damp_reuse_time_vty(vty, path, timebuf,
8009 BGP_UPTIME_LEN, use_json, json);
8010 else
8011 vty_out(vty, "%s ",
8012 bgp_damp_reuse_time_vty(vty, path, timebuf,
8013 BGP_UPTIME_LEN,
8014 use_json, json));
8015 } else {
8016 if (!use_json)
8017 vty_out(vty, "%*s ", 8, " ");
8018 }
8019
8020 /* Print attribute */
8021 attr = path->attr;
8022
8023 /* Print aspath */
8024 if (attr->aspath) {
8025 if (use_json)
8026 json_object_string_add(json, "asPath",
8027 attr->aspath->str);
8028 else
8029 aspath_print_vty(vty, "%s", attr->aspath, " ");
8030 }
8031
8032 /* Print origin */
8033 if (use_json)
8034 json_object_string_add(json, "origin",
8035 bgp_origin_str[attr->origin]);
8036 else
8037 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8038
8039 if (!use_json)
8040 vty_out(vty, "\n");
8041 }
8042
8043 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8044 int *first, const char *header,
8045 json_object *json_adv_to)
8046 {
8047 char buf1[INET6_ADDRSTRLEN];
8048 json_object *json_peer = NULL;
8049
8050 if (json_adv_to) {
8051 /* 'advertised-to' is a dictionary of peers we have advertised
8052 * this
8053 * prefix too. The key is the peer's IP or swpX, the value is
8054 * the
8055 * hostname if we know it and "" if not.
8056 */
8057 json_peer = json_object_new_object();
8058
8059 if (peer->hostname)
8060 json_object_string_add(json_peer, "hostname",
8061 peer->hostname);
8062
8063 if (peer->conf_if)
8064 json_object_object_add(json_adv_to, peer->conf_if,
8065 json_peer);
8066 else
8067 json_object_object_add(
8068 json_adv_to,
8069 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8070 json_peer);
8071 } else {
8072 if (*first) {
8073 vty_out(vty, "%s", header);
8074 *first = 0;
8075 }
8076
8077 if (peer->hostname
8078 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
8079 if (peer->conf_if)
8080 vty_out(vty, " %s(%s)", peer->hostname,
8081 peer->conf_if);
8082 else
8083 vty_out(vty, " %s(%s)", peer->hostname,
8084 sockunion2str(&peer->su, buf1,
8085 SU_ADDRSTRLEN));
8086 } else {
8087 if (peer->conf_if)
8088 vty_out(vty, " %s", peer->conf_if);
8089 else
8090 vty_out(vty, " %s",
8091 sockunion2str(&peer->su, buf1,
8092 SU_ADDRSTRLEN));
8093 }
8094 }
8095 }
8096
8097 static void route_vty_out_tx_ids(struct vty *vty,
8098 struct bgp_addpath_info_data *d)
8099 {
8100 int i;
8101
8102 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8103 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8104 d->addpath_tx_id[i],
8105 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8106 }
8107 }
8108
8109 static const char *bgp_path_selection_reason2str(
8110 enum bgp_path_selection_reason reason)
8111 {
8112 switch (reason) {
8113 case bgp_path_selection_none:
8114 return "Nothing to Select";
8115 break;
8116 case bgp_path_selection_first:
8117 return "First path received";
8118 break;
8119 case bgp_path_selection_evpn_sticky_mac:
8120 return "EVPN Sticky Mac";
8121 break;
8122 case bgp_path_selection_evpn_seq:
8123 return "EVPN sequence number";
8124 break;
8125 case bgp_path_selection_evpn_lower_ip:
8126 return "EVPN lower IP";
8127 break;
8128 case bgp_path_selection_weight:
8129 return "Weight";
8130 break;
8131 case bgp_path_selection_local_pref:
8132 return "Local Pref";
8133 break;
8134 case bgp_path_selection_local_route:
8135 return "Local Route";
8136 break;
8137 case bgp_path_selection_confed_as_path:
8138 return "Confederation based AS Path";
8139 break;
8140 case bgp_path_selection_as_path:
8141 return "AS Path";
8142 break;
8143 case bgp_path_selection_origin:
8144 return "Origin";
8145 break;
8146 case bgp_path_selection_med:
8147 return "MED";
8148 break;
8149 case bgp_path_selection_peer:
8150 return "Peer Type";
8151 break;
8152 case bgp_path_selection_confed:
8153 return "Confed Peer Type";
8154 break;
8155 case bgp_path_selection_igp_metric:
8156 return "IGP Metric";
8157 break;
8158 case bgp_path_selection_older:
8159 return "Older Path";
8160 break;
8161 case bgp_path_selection_router_id:
8162 return "Router ID";
8163 break;
8164 case bgp_path_selection_cluster_length:
8165 return "Cluser length";
8166 break;
8167 case bgp_path_selection_stale:
8168 return "Path Staleness";
8169 break;
8170 case bgp_path_selection_local_configured:
8171 return "Locally configured route";
8172 break;
8173 case bgp_path_selection_neighbor_ip:
8174 return "Neighbor IP";
8175 break;
8176 case bgp_path_selection_default:
8177 return "Nothing left to compare";
8178 break;
8179 }
8180 return "Invalid (internal error)";
8181 }
8182
8183 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8184 struct bgp_node *bn, struct bgp_path_info *path,
8185 afi_t afi, safi_t safi, json_object *json_paths)
8186 {
8187 char buf[INET6_ADDRSTRLEN];
8188 char buf1[BUFSIZ];
8189 char buf2[EVPN_ROUTE_STRLEN];
8190 struct attr *attr;
8191 int sockunion_vty_out(struct vty *, union sockunion *);
8192 time_t tbuf;
8193 json_object *json_bestpath = NULL;
8194 json_object *json_cluster_list = NULL;
8195 json_object *json_cluster_list_list = NULL;
8196 json_object *json_ext_community = NULL;
8197 json_object *json_last_update = NULL;
8198 json_object *json_pmsi = NULL;
8199 json_object *json_nexthop_global = NULL;
8200 json_object *json_nexthop_ll = NULL;
8201 json_object *json_nexthops = NULL;
8202 json_object *json_path = NULL;
8203 json_object *json_peer = NULL;
8204 json_object *json_string = NULL;
8205 json_object *json_adv_to = NULL;
8206 int first = 0;
8207 struct listnode *node, *nnode;
8208 struct peer *peer;
8209 int addpath_capable;
8210 int has_adj;
8211 unsigned int first_as;
8212 bool nexthop_self =
8213 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8214 int i;
8215 char *nexthop_fqdn = bgp_nexthop_fqdn(path->peer);
8216
8217 if (json_paths) {
8218 json_path = json_object_new_object();
8219 json_peer = json_object_new_object();
8220 json_nexthop_global = json_object_new_object();
8221 }
8222
8223 if (path->extra) {
8224 char tag_buf[30];
8225
8226 buf2[0] = '\0';
8227 tag_buf[0] = '\0';
8228 if (path->extra && path->extra->num_labels) {
8229 bgp_evpn_label2str(path->extra->label,
8230 path->extra->num_labels, tag_buf,
8231 sizeof(tag_buf));
8232 }
8233 if (safi == SAFI_EVPN) {
8234 if (!json_paths) {
8235 bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
8236 buf2, sizeof(buf2));
8237 vty_out(vty, " Route %s", buf2);
8238 if (tag_buf[0] != '\0')
8239 vty_out(vty, " VNI %s", tag_buf);
8240 vty_out(vty, "\n");
8241 } else {
8242 if (tag_buf[0])
8243 json_object_string_add(json_path, "VNI",
8244 tag_buf);
8245 }
8246 }
8247
8248 if (path->extra && path->extra->parent && !json_paths) {
8249 struct bgp_path_info *parent_ri;
8250 struct bgp_node *rn, *prn;
8251
8252 parent_ri = (struct bgp_path_info *)path->extra->parent;
8253 rn = parent_ri->net;
8254 if (rn && rn->prn) {
8255 prn = rn->prn;
8256 prefix_rd2str((struct prefix_rd *)&prn->p,
8257 buf1, sizeof(buf1));
8258 if (is_pi_family_evpn(parent_ri)) {
8259 bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
8260 buf2, sizeof(buf2));
8261 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8262 } else
8263 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8264 }
8265 }
8266 }
8267
8268 attr = path->attr;
8269
8270 /* Line1 display AS-path, Aggregator */
8271 if (attr->aspath) {
8272 if (json_paths) {
8273 if (!attr->aspath->json)
8274 aspath_str_update(attr->aspath, true);
8275 json_object_lock(attr->aspath->json);
8276 json_object_object_add(json_path, "aspath",
8277 attr->aspath->json);
8278 } else {
8279 if (attr->aspath->segments)
8280 aspath_print_vty(vty, " %s", attr->aspath, "");
8281 else
8282 vty_out(vty, " Local");
8283 }
8284 }
8285
8286 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8287 if (json_paths)
8288 json_object_boolean_true_add(json_path, "removed");
8289 else
8290 vty_out(vty, ", (removed)");
8291 }
8292
8293 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8294 if (json_paths)
8295 json_object_boolean_true_add(json_path, "stale");
8296 else
8297 vty_out(vty, ", (stale)");
8298 }
8299
8300 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8301 if (json_paths) {
8302 json_object_int_add(json_path, "aggregatorAs",
8303 attr->aggregator_as);
8304 json_object_string_add(
8305 json_path, "aggregatorId",
8306 inet_ntoa(attr->aggregator_addr));
8307 } else {
8308 vty_out(vty, ", (aggregated by %u %s)",
8309 attr->aggregator_as,
8310 inet_ntoa(attr->aggregator_addr));
8311 }
8312 }
8313
8314 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8315 PEER_FLAG_REFLECTOR_CLIENT)) {
8316 if (json_paths)
8317 json_object_boolean_true_add(json_path,
8318 "rxedFromRrClient");
8319 else
8320 vty_out(vty, ", (Received from a RR-client)");
8321 }
8322
8323 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8324 PEER_FLAG_RSERVER_CLIENT)) {
8325 if (json_paths)
8326 json_object_boolean_true_add(json_path,
8327 "rxedFromRsClient");
8328 else
8329 vty_out(vty, ", (Received from a RS-client)");
8330 }
8331
8332 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8333 if (json_paths)
8334 json_object_boolean_true_add(json_path,
8335 "dampeningHistoryEntry");
8336 else
8337 vty_out(vty, ", (history entry)");
8338 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8339 if (json_paths)
8340 json_object_boolean_true_add(json_path,
8341 "dampeningSuppressed");
8342 else
8343 vty_out(vty, ", (suppressed due to dampening)");
8344 }
8345
8346 if (!json_paths)
8347 vty_out(vty, "\n");
8348
8349 /* Line2 display Next-hop, Neighbor, Router-id */
8350 /* Display the nexthop */
8351 if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
8352 || bn->p.family == AF_EVPN)
8353 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8354 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8355 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8356 || safi == SAFI_EVPN) {
8357 if (json_paths)
8358 json_object_string_add(
8359 json_nexthop_global,
8360 nexthop_fqdn ? "fqdn" : "ip",
8361 nexthop_fqdn
8362 ? nexthop_fqdn
8363 : inet_ntoa(
8364 attr->mp_nexthop_global_in));
8365 else
8366 vty_out(vty, " %s",
8367 nexthop_fqdn
8368 ? nexthop_fqdn
8369 : inet_ntoa(
8370 attr->mp_nexthop_global_in));
8371 } else {
8372 if (json_paths)
8373 json_object_string_add(
8374 json_nexthop_global,
8375 nexthop_fqdn ? "fqdn" : "ip",
8376 nexthop_fqdn
8377 ? nexthop_fqdn
8378 : inet_ntoa(attr->nexthop));
8379 else
8380 vty_out(vty, " %s",
8381 nexthop_fqdn
8382 ? nexthop_fqdn
8383 : inet_ntoa(attr->nexthop));
8384 }
8385
8386 if (json_paths)
8387 json_object_string_add(json_nexthop_global, "afi",
8388 "ipv4");
8389 } else {
8390 if (json_paths) {
8391 json_object_string_add(
8392 json_nexthop_global,
8393 nexthop_fqdn ? "fqdn" : "ip",
8394 nexthop_fqdn
8395 ? nexthop_fqdn
8396 : inet_ntop(AF_INET6,
8397 &attr->mp_nexthop_global,
8398 buf, INET6_ADDRSTRLEN));
8399 json_object_string_add(json_nexthop_global, "afi",
8400 "ipv6");
8401 json_object_string_add(json_nexthop_global, "scope",
8402 "global");
8403 } else {
8404 vty_out(vty, " %s",
8405 nexthop_fqdn
8406 ? nexthop_fqdn
8407 : inet_ntop(AF_INET6,
8408 &attr->mp_nexthop_global,
8409 buf, INET6_ADDRSTRLEN));
8410 }
8411 }
8412
8413 /* Display the IGP cost or 'inaccessible' */
8414 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8415 if (json_paths)
8416 json_object_boolean_false_add(json_nexthop_global,
8417 "accessible");
8418 else
8419 vty_out(vty, " (inaccessible)");
8420 } else {
8421 if (path->extra && path->extra->igpmetric) {
8422 if (json_paths)
8423 json_object_int_add(json_nexthop_global,
8424 "metric",
8425 path->extra->igpmetric);
8426 else
8427 vty_out(vty, " (metric %u)",
8428 path->extra->igpmetric);
8429 }
8430
8431 /* IGP cost is 0, display this only for json */
8432 else {
8433 if (json_paths)
8434 json_object_int_add(json_nexthop_global,
8435 "metric", 0);
8436 }
8437
8438 if (json_paths)
8439 json_object_boolean_true_add(json_nexthop_global,
8440 "accessible");
8441 }
8442
8443 /* Display peer "from" output */
8444 /* This path was originated locally */
8445 if (path->peer == bgp->peer_self) {
8446
8447 if (safi == SAFI_EVPN
8448 || (bn->p.family == AF_INET
8449 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8450 if (json_paths)
8451 json_object_string_add(json_peer, "peerId",
8452 "0.0.0.0");
8453 else
8454 vty_out(vty, " from 0.0.0.0 ");
8455 } else {
8456 if (json_paths)
8457 json_object_string_add(json_peer, "peerId",
8458 "::");
8459 else
8460 vty_out(vty, " from :: ");
8461 }
8462
8463 if (json_paths)
8464 json_object_string_add(json_peer, "routerId",
8465 inet_ntoa(bgp->router_id));
8466 else
8467 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8468 }
8469
8470 /* We RXed this path from one of our peers */
8471 else {
8472
8473 if (json_paths) {
8474 json_object_string_add(json_peer, "peerId",
8475 sockunion2str(&path->peer->su,
8476 buf,
8477 SU_ADDRSTRLEN));
8478 json_object_string_add(json_peer, "routerId",
8479 inet_ntop(AF_INET,
8480 &path->peer->remote_id,
8481 buf1, sizeof(buf1)));
8482
8483 if (path->peer->hostname)
8484 json_object_string_add(json_peer, "hostname",
8485 path->peer->hostname);
8486
8487 if (path->peer->domainname)
8488 json_object_string_add(json_peer, "domainname",
8489 path->peer->domainname);
8490
8491 if (path->peer->conf_if)
8492 json_object_string_add(json_peer, "interface",
8493 path->peer->conf_if);
8494 } else {
8495 if (path->peer->conf_if) {
8496 if (path->peer->hostname
8497 && bgp_flag_check(path->peer->bgp,
8498 BGP_FLAG_SHOW_HOSTNAME))
8499 vty_out(vty, " from %s(%s)",
8500 path->peer->hostname,
8501 path->peer->conf_if);
8502 else
8503 vty_out(vty, " from %s",
8504 path->peer->conf_if);
8505 } else {
8506 if (path->peer->hostname
8507 && bgp_flag_check(path->peer->bgp,
8508 BGP_FLAG_SHOW_HOSTNAME))
8509 vty_out(vty, " from %s(%s)",
8510 path->peer->hostname,
8511 path->peer->host);
8512 else
8513 vty_out(vty, " from %s",
8514 sockunion2str(&path->peer->su,
8515 buf,
8516 SU_ADDRSTRLEN));
8517 }
8518
8519 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8520 vty_out(vty, " (%s)",
8521 inet_ntoa(attr->originator_id));
8522 else
8523 vty_out(vty, " (%s)",
8524 inet_ntop(AF_INET,
8525 &path->peer->remote_id, buf1,
8526 sizeof(buf1)));
8527 }
8528 }
8529
8530 /*
8531 * Note when vrfid of nexthop is different from that of prefix
8532 */
8533 if (path->extra && path->extra->bgp_orig) {
8534 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8535
8536 if (json_paths) {
8537 const char *vn;
8538
8539 if (path->extra->bgp_orig->inst_type
8540 == BGP_INSTANCE_TYPE_DEFAULT)
8541 vn = VRF_DEFAULT_NAME;
8542 else
8543 vn = path->extra->bgp_orig->name;
8544
8545 json_object_string_add(json_path, "nhVrfName", vn);
8546
8547 if (nexthop_vrfid == VRF_UNKNOWN) {
8548 json_object_int_add(json_path, "nhVrfId", -1);
8549 } else {
8550 json_object_int_add(json_path, "nhVrfId",
8551 (int)nexthop_vrfid);
8552 }
8553 } else {
8554 if (nexthop_vrfid == VRF_UNKNOWN)
8555 vty_out(vty, " vrf ?");
8556 else
8557 vty_out(vty, " vrf %u", nexthop_vrfid);
8558 }
8559 }
8560
8561 if (nexthop_self) {
8562 if (json_paths) {
8563 json_object_boolean_true_add(json_path,
8564 "announceNexthopSelf");
8565 } else {
8566 vty_out(vty, " announce-nh-self");
8567 }
8568 }
8569
8570 if (!json_paths)
8571 vty_out(vty, "\n");
8572
8573 /* display the link-local nexthop */
8574 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8575 if (json_paths) {
8576 json_nexthop_ll = json_object_new_object();
8577 json_object_string_add(
8578 json_nexthop_ll, nexthop_fqdn ? "fqdn" : "ip",
8579 nexthop_fqdn
8580 ? nexthop_fqdn
8581 : inet_ntop(AF_INET6,
8582 &attr->mp_nexthop_local,
8583 buf, INET6_ADDRSTRLEN));
8584 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
8585 json_object_string_add(json_nexthop_ll, "scope",
8586 "link-local");
8587
8588 json_object_boolean_true_add(json_nexthop_ll,
8589 "accessible");
8590
8591 if (!attr->mp_nexthop_prefer_global)
8592 json_object_boolean_true_add(json_nexthop_ll,
8593 "used");
8594 else
8595 json_object_boolean_true_add(
8596 json_nexthop_global, "used");
8597 } else {
8598 vty_out(vty, " (%s) %s\n",
8599 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8600 buf, INET6_ADDRSTRLEN),
8601 attr->mp_nexthop_prefer_global
8602 ? "(prefer-global)"
8603 : "(used)");
8604 }
8605 }
8606 /* If we do not have a link-local nexthop then we must flag the
8607 global as "used" */
8608 else {
8609 if (json_paths)
8610 json_object_boolean_true_add(json_nexthop_global,
8611 "used");
8612 }
8613
8614 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8615 * Int/Ext/Local, Atomic, best */
8616 if (json_paths)
8617 json_object_string_add(json_path, "origin",
8618 bgp_origin_long_str[attr->origin]);
8619 else
8620 vty_out(vty, " Origin %s",
8621 bgp_origin_long_str[attr->origin]);
8622
8623 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8624 if (json_paths) {
8625 /*
8626 * Adding "metric" field to match with
8627 * corresponding CLI. "med" will be
8628 * deprecated in future.
8629 */
8630 json_object_int_add(json_path, "med", attr->med);
8631 json_object_int_add(json_path, "metric", attr->med);
8632 } else
8633 vty_out(vty, ", metric %u", attr->med);
8634 }
8635
8636 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8637 if (json_paths)
8638 json_object_int_add(json_path, "localpref",
8639 attr->local_pref);
8640 else
8641 vty_out(vty, ", localpref %u", attr->local_pref);
8642 }
8643
8644 if (attr->weight != 0) {
8645 if (json_paths)
8646 json_object_int_add(json_path, "weight", attr->weight);
8647 else
8648 vty_out(vty, ", weight %u", attr->weight);
8649 }
8650
8651 if (attr->tag != 0) {
8652 if (json_paths)
8653 json_object_int_add(json_path, "tag", attr->tag);
8654 else
8655 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
8656 }
8657
8658 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8659 if (json_paths)
8660 json_object_boolean_false_add(json_path, "valid");
8661 else
8662 vty_out(vty, ", invalid");
8663 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8664 if (json_paths)
8665 json_object_boolean_true_add(json_path, "valid");
8666 else
8667 vty_out(vty, ", valid");
8668 }
8669
8670 if (path->peer != bgp->peer_self) {
8671 if (path->peer->as == path->peer->local_as) {
8672 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
8673 if (json_paths)
8674 json_object_string_add(
8675 json_peer, "type",
8676 "confed-internal");
8677 else
8678 vty_out(vty, ", confed-internal");
8679 } else {
8680 if (json_paths)
8681 json_object_string_add(
8682 json_peer, "type", "internal");
8683 else
8684 vty_out(vty, ", internal");
8685 }
8686 } else {
8687 if (bgp_confederation_peers_check(bgp,
8688 path->peer->as)) {
8689 if (json_paths)
8690 json_object_string_add(
8691 json_peer, "type",
8692 "confed-external");
8693 else
8694 vty_out(vty, ", confed-external");
8695 } else {
8696 if (json_paths)
8697 json_object_string_add(
8698 json_peer, "type", "external");
8699 else
8700 vty_out(vty, ", external");
8701 }
8702 }
8703 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
8704 if (json_paths) {
8705 json_object_boolean_true_add(json_path, "aggregated");
8706 json_object_boolean_true_add(json_path, "local");
8707 } else {
8708 vty_out(vty, ", aggregated, local");
8709 }
8710 } else if (path->type != ZEBRA_ROUTE_BGP) {
8711 if (json_paths)
8712 json_object_boolean_true_add(json_path, "sourced");
8713 else
8714 vty_out(vty, ", sourced");
8715 } else {
8716 if (json_paths) {
8717 json_object_boolean_true_add(json_path, "sourced");
8718 json_object_boolean_true_add(json_path, "local");
8719 } else {
8720 vty_out(vty, ", sourced, local");
8721 }
8722 }
8723
8724 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
8725 if (json_paths)
8726 json_object_boolean_true_add(json_path,
8727 "atomicAggregate");
8728 else
8729 vty_out(vty, ", atomic-aggregate");
8730 }
8731
8732 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
8733 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
8734 && bgp_path_info_mpath_count(path))) {
8735 if (json_paths)
8736 json_object_boolean_true_add(json_path, "multipath");
8737 else
8738 vty_out(vty, ", multipath");
8739 }
8740
8741 // Mark the bestpath(s)
8742 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
8743 first_as = aspath_get_first_as(attr->aspath);
8744
8745 if (json_paths) {
8746 if (!json_bestpath)
8747 json_bestpath = json_object_new_object();
8748 json_object_int_add(json_bestpath, "bestpathFromAs",
8749 first_as);
8750 } else {
8751 if (first_as)
8752 vty_out(vty, ", bestpath-from-AS %u", first_as);
8753 else
8754 vty_out(vty, ", bestpath-from-AS Local");
8755 }
8756 }
8757
8758 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8759 if (json_paths) {
8760 if (!json_bestpath)
8761 json_bestpath = json_object_new_object();
8762 json_object_boolean_true_add(json_bestpath, "overall");
8763 json_object_string_add(
8764 json_bestpath, "selectionReason",
8765 bgp_path_selection_reason2str(bn->reason));
8766 } else {
8767 vty_out(vty, ", best");
8768 vty_out(vty, " (%s)",
8769 bgp_path_selection_reason2str(bn->reason));
8770 }
8771 }
8772
8773 if (json_bestpath)
8774 json_object_object_add(json_path, "bestpath", json_bestpath);
8775
8776 if (!json_paths)
8777 vty_out(vty, "\n");
8778
8779 /* Line 4 display Community */
8780 if (attr->community) {
8781 if (json_paths) {
8782 if (!attr->community->json)
8783 community_str(attr->community, true);
8784 json_object_lock(attr->community->json);
8785 json_object_object_add(json_path, "community",
8786 attr->community->json);
8787 } else {
8788 vty_out(vty, " Community: %s\n",
8789 attr->community->str);
8790 }
8791 }
8792
8793 /* Line 5 display Extended-community */
8794 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8795 if (json_paths) {
8796 json_ext_community = json_object_new_object();
8797 json_object_string_add(json_ext_community, "string",
8798 attr->ecommunity->str);
8799 json_object_object_add(json_path, "extendedCommunity",
8800 json_ext_community);
8801 } else {
8802 vty_out(vty, " Extended Community: %s\n",
8803 attr->ecommunity->str);
8804 }
8805 }
8806
8807 /* Line 6 display Large community */
8808 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
8809 if (json_paths) {
8810 if (!attr->lcommunity->json)
8811 lcommunity_str(attr->lcommunity, true);
8812 json_object_lock(attr->lcommunity->json);
8813 json_object_object_add(json_path, "largeCommunity",
8814 attr->lcommunity->json);
8815 } else {
8816 vty_out(vty, " Large Community: %s\n",
8817 attr->lcommunity->str);
8818 }
8819 }
8820
8821 /* Line 7 display Originator, Cluster-id */
8822 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8823 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
8824 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
8825 if (json_paths)
8826 json_object_string_add(
8827 json_path, "originatorId",
8828 inet_ntoa(attr->originator_id));
8829 else
8830 vty_out(vty, " Originator: %s",
8831 inet_ntoa(attr->originator_id));
8832 }
8833
8834 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
8835 int i;
8836
8837 if (json_paths) {
8838 json_cluster_list = json_object_new_object();
8839 json_cluster_list_list =
8840 json_object_new_array();
8841
8842 for (i = 0; i < attr->cluster->length / 4;
8843 i++) {
8844 json_string = json_object_new_string(
8845 inet_ntoa(attr->cluster
8846 ->list[i]));
8847 json_object_array_add(
8848 json_cluster_list_list,
8849 json_string);
8850 }
8851
8852 /*
8853 * struct cluster_list does not have
8854 * "str" variable like aspath and community
8855 * do. Add this someday if someone asks
8856 * for it.
8857 * json_object_string_add(json_cluster_list,
8858 * "string", attr->cluster->str);
8859 */
8860 json_object_object_add(json_cluster_list,
8861 "list",
8862 json_cluster_list_list);
8863 json_object_object_add(json_path, "clusterList",
8864 json_cluster_list);
8865 } else {
8866 vty_out(vty, ", Cluster list: ");
8867
8868 for (i = 0; i < attr->cluster->length / 4;
8869 i++) {
8870 vty_out(vty, "%s ",
8871 inet_ntoa(attr->cluster
8872 ->list[i]));
8873 }
8874 }
8875 }
8876
8877 if (!json_paths)
8878 vty_out(vty, "\n");
8879 }
8880
8881 if (path->extra && path->extra->damp_info)
8882 bgp_damp_info_vty(vty, path, json_path);
8883
8884 /* Remote Label */
8885 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
8886 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
8887 mpls_label_t label = label_pton(&path->extra->label[0]);
8888
8889 if (json_paths)
8890 json_object_int_add(json_path, "remoteLabel", label);
8891 else
8892 vty_out(vty, " Remote label: %d\n", label);
8893 }
8894
8895 /* Label Index */
8896 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8897 if (json_paths)
8898 json_object_int_add(json_path, "labelIndex",
8899 attr->label_index);
8900 else
8901 vty_out(vty, " Label Index: %d\n",
8902 attr->label_index);
8903 }
8904
8905 /* Line 8 display Addpath IDs */
8906 if (path->addpath_rx_id
8907 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
8908 if (json_paths) {
8909 json_object_int_add(json_path, "addpathRxId",
8910 path->addpath_rx_id);
8911
8912 /* Keep backwards compatibility with the old API
8913 * by putting TX All's ID in the old field
8914 */
8915 json_object_int_add(
8916 json_path, "addpathTxId",
8917 path->tx_addpath
8918 .addpath_tx_id[BGP_ADDPATH_ALL]);
8919
8920 /* ... but create a specific field for each
8921 * strategy
8922 */
8923 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8924 json_object_int_add(
8925 json_path,
8926 bgp_addpath_names(i)->id_json_name,
8927 path->tx_addpath.addpath_tx_id[i]);
8928 }
8929 } else {
8930 vty_out(vty, " AddPath ID: RX %u, ",
8931 path->addpath_rx_id);
8932
8933 route_vty_out_tx_ids(vty, &path->tx_addpath);
8934 }
8935 }
8936
8937 /* If we used addpath to TX a non-bestpath we need to display
8938 * "Advertised to" on a path-by-path basis
8939 */
8940 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
8941 first = 1;
8942
8943 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8944 addpath_capable =
8945 bgp_addpath_encode_tx(peer, afi, safi);
8946 has_adj = bgp_adj_out_lookup(
8947 peer, path->net,
8948 bgp_addpath_id_for_peer(peer, afi, safi,
8949 &path->tx_addpath));
8950
8951 if ((addpath_capable && has_adj)
8952 || (!addpath_capable && has_adj
8953 && CHECK_FLAG(path->flags,
8954 BGP_PATH_SELECTED))) {
8955 if (json_path && !json_adv_to)
8956 json_adv_to = json_object_new_object();
8957
8958 route_vty_out_advertised_to(
8959 vty, peer, &first,
8960 " Advertised to:", json_adv_to);
8961 }
8962 }
8963
8964 if (json_path) {
8965 if (json_adv_to) {
8966 json_object_object_add(
8967 json_path, "advertisedTo", json_adv_to);
8968 }
8969 } else {
8970 if (!first) {
8971 vty_out(vty, "\n");
8972 }
8973 }
8974 }
8975
8976 /* Line 9 display Uptime */
8977 tbuf = time(NULL) - (bgp_clock() - path->uptime);
8978 if (json_paths) {
8979 json_last_update = json_object_new_object();
8980 json_object_int_add(json_last_update, "epoch", tbuf);
8981 json_object_string_add(json_last_update, "string",
8982 ctime(&tbuf));
8983 json_object_object_add(json_path, "lastUpdate",
8984 json_last_update);
8985 } else
8986 vty_out(vty, " Last update: %s", ctime(&tbuf));
8987
8988 /* Line 10 display PMSI tunnel attribute, if present */
8989 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
8990 const char *str =
8991 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
8992 PMSI_TNLTYPE_STR_DEFAULT);
8993
8994 if (json_paths) {
8995 json_pmsi = json_object_new_object();
8996 json_object_string_add(json_pmsi, "tunnelType", str);
8997 json_object_int_add(json_pmsi, "label",
8998 label2vni(&attr->label));
8999 json_object_object_add(json_path, "pmsi", json_pmsi);
9000 } else
9001 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9002 str, label2vni(&attr->label));
9003 }
9004
9005 /* We've constructed the json object for this path, add it to the json
9006 * array of paths
9007 */
9008 if (json_paths) {
9009 if (json_nexthop_global || json_nexthop_ll) {
9010 json_nexthops = json_object_new_array();
9011
9012 if (json_nexthop_global)
9013 json_object_array_add(json_nexthops,
9014 json_nexthop_global);
9015
9016 if (json_nexthop_ll)
9017 json_object_array_add(json_nexthops,
9018 json_nexthop_ll);
9019
9020 json_object_object_add(json_path, "nexthops",
9021 json_nexthops);
9022 }
9023
9024 json_object_object_add(json_path, "peer", json_peer);
9025 json_object_array_add(json_paths, json_path);
9026 }
9027 }
9028
9029 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9030 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9031 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9032
9033 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9034 const char *prefix_list_str, afi_t afi,
9035 safi_t safi, enum bgp_show_type type);
9036 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9037 const char *filter, afi_t afi, safi_t safi,
9038 enum bgp_show_type type);
9039 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9040 const char *rmap_str, afi_t afi, safi_t safi,
9041 enum bgp_show_type type);
9042 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9043 const char *com, int exact, afi_t afi,
9044 safi_t safi);
9045 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9046 const char *prefix, afi_t afi, safi_t safi,
9047 enum bgp_show_type type);
9048 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9049 afi_t afi, safi_t safi, enum bgp_show_type type);
9050 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9051 const char *comstr, int exact, afi_t afi,
9052 safi_t safi, bool use_json);
9053
9054
9055 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9056 struct bgp_table *table, enum bgp_show_type type,
9057 void *output_arg, bool use_json, char *rd,
9058 int is_last, unsigned long *output_cum,
9059 unsigned long *total_cum,
9060 unsigned long *json_header_depth)
9061 {
9062 struct bgp_path_info *pi;
9063 struct bgp_node *rn;
9064 int header = 1;
9065 int display;
9066 unsigned long output_count = 0;
9067 unsigned long total_count = 0;
9068 struct prefix *p;
9069 char buf2[BUFSIZ];
9070 json_object *json_paths = NULL;
9071 int first = 1;
9072
9073 if (output_cum && *output_cum != 0)
9074 header = 0;
9075
9076 if (use_json && !*json_header_depth) {
9077 vty_out(vty,
9078 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9079 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9080 " \"localAS\": %u,\n \"routes\": { ",
9081 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9082 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9083 ? VRF_DEFAULT_NAME
9084 : bgp->name,
9085 table->version, inet_ntoa(bgp->router_id),
9086 bgp->default_local_pref, bgp->as);
9087 *json_header_depth = 2;
9088 if (rd) {
9089 vty_out(vty, " \"routeDistinguishers\" : {");
9090 ++*json_header_depth;
9091 }
9092 }
9093
9094 if (use_json && rd) {
9095 vty_out(vty, " \"%s\" : { ", rd);
9096 }
9097
9098 /* Start processing of routes. */
9099 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9100 pi = bgp_node_get_bgp_path_info(rn);
9101 if (pi == NULL)
9102 continue;
9103
9104 display = 0;
9105 if (use_json)
9106 json_paths = json_object_new_array();
9107 else
9108 json_paths = NULL;
9109
9110 for (; pi; pi = pi->next) {
9111 total_count++;
9112 if (type == bgp_show_type_flap_statistics
9113 || type == bgp_show_type_flap_neighbor
9114 || type == bgp_show_type_dampend_paths
9115 || type == bgp_show_type_damp_neighbor) {
9116 if (!(pi->extra && pi->extra->damp_info))
9117 continue;
9118 }
9119 if (type == bgp_show_type_regexp) {
9120 regex_t *regex = output_arg;
9121
9122 if (bgp_regexec(regex, pi->attr->aspath)
9123 == REG_NOMATCH)
9124 continue;
9125 }
9126 if (type == bgp_show_type_prefix_list) {
9127 struct prefix_list *plist = output_arg;
9128
9129 if (prefix_list_apply(plist, &rn->p)
9130 != PREFIX_PERMIT)
9131 continue;
9132 }
9133 if (type == bgp_show_type_filter_list) {
9134 struct as_list *as_list = output_arg;
9135
9136 if (as_list_apply(as_list, pi->attr->aspath)
9137 != AS_FILTER_PERMIT)
9138 continue;
9139 }
9140 if (type == bgp_show_type_route_map) {
9141 struct route_map *rmap = output_arg;
9142 struct bgp_path_info path;
9143 struct attr dummy_attr;
9144 route_map_result_t ret;
9145
9146 bgp_attr_dup(&dummy_attr, pi->attr);
9147
9148 path.peer = pi->peer;
9149 path.attr = &dummy_attr;
9150
9151 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
9152 &path);
9153 if (ret == RMAP_DENYMATCH)
9154 continue;
9155 }
9156 if (type == bgp_show_type_neighbor
9157 || type == bgp_show_type_flap_neighbor
9158 || type == bgp_show_type_damp_neighbor) {
9159 union sockunion *su = output_arg;
9160
9161 if (pi->peer == NULL
9162 || pi->peer->su_remote == NULL
9163 || !sockunion_same(pi->peer->su_remote, su))
9164 continue;
9165 }
9166 if (type == bgp_show_type_cidr_only) {
9167 uint32_t destination;
9168
9169 destination = ntohl(rn->p.u.prefix4.s_addr);
9170 if (IN_CLASSC(destination)
9171 && rn->p.prefixlen == 24)
9172 continue;
9173 if (IN_CLASSB(destination)
9174 && rn->p.prefixlen == 16)
9175 continue;
9176 if (IN_CLASSA(destination)
9177 && rn->p.prefixlen == 8)
9178 continue;
9179 }
9180 if (type == bgp_show_type_prefix_longer) {
9181 p = output_arg;
9182 if (!prefix_match(p, &rn->p))
9183 continue;
9184 }
9185 if (type == bgp_show_type_community_all) {
9186 if (!pi->attr->community)
9187 continue;
9188 }
9189 if (type == bgp_show_type_community) {
9190 struct community *com = output_arg;
9191
9192 if (!pi->attr->community
9193 || !community_match(pi->attr->community,
9194 com))
9195 continue;
9196 }
9197 if (type == bgp_show_type_community_exact) {
9198 struct community *com = output_arg;
9199
9200 if (!pi->attr->community
9201 || !community_cmp(pi->attr->community, com))
9202 continue;
9203 }
9204 if (type == bgp_show_type_community_list) {
9205 struct community_list *list = output_arg;
9206
9207 if (!community_list_match(pi->attr->community,
9208 list))
9209 continue;
9210 }
9211 if (type == bgp_show_type_community_list_exact) {
9212 struct community_list *list = output_arg;
9213
9214 if (!community_list_exact_match(
9215 pi->attr->community, list))
9216 continue;
9217 }
9218 if (type == bgp_show_type_lcommunity) {
9219 struct lcommunity *lcom = output_arg;
9220
9221 if (!pi->attr->lcommunity
9222 || !lcommunity_match(pi->attr->lcommunity,
9223 lcom))
9224 continue;
9225 }
9226
9227 if (type == bgp_show_type_lcommunity_exact) {
9228 struct lcommunity *lcom = output_arg;
9229
9230 if (!pi->attr->lcommunity
9231 || !lcommunity_cmp(pi->attr->lcommunity,
9232 lcom))
9233 continue;
9234 }
9235 if (type == bgp_show_type_lcommunity_list) {
9236 struct community_list *list = output_arg;
9237
9238 if (!lcommunity_list_match(pi->attr->lcommunity,
9239 list))
9240 continue;
9241 }
9242 if (type
9243 == bgp_show_type_lcommunity_list_exact) {
9244 struct community_list *list = output_arg;
9245
9246 if (!lcommunity_list_exact_match(
9247 pi->attr->lcommunity, list))
9248 continue;
9249 }
9250 if (type == bgp_show_type_lcommunity_all) {
9251 if (!pi->attr->lcommunity)
9252 continue;
9253 }
9254 if (type == bgp_show_type_dampend_paths
9255 || type == bgp_show_type_damp_neighbor) {
9256 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9257 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9258 continue;
9259 }
9260
9261 if (!use_json && header) {
9262 vty_out(vty, "BGP table version is %" PRIu64
9263 ", local router ID is %s, vrf id ",
9264 table->version,
9265 inet_ntoa(bgp->router_id));
9266 if (bgp->vrf_id == VRF_UNKNOWN)
9267 vty_out(vty, "%s", VRFID_NONE_STR);
9268 else
9269 vty_out(vty, "%u", bgp->vrf_id);
9270 vty_out(vty, "\n");
9271 vty_out(vty, "Default local pref %u, ",
9272 bgp->default_local_pref);
9273 vty_out(vty, "local AS %u\n", bgp->as);
9274 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9275 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9276 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9277 if (type == bgp_show_type_dampend_paths
9278 || type == bgp_show_type_damp_neighbor)
9279 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9280 else if (type == bgp_show_type_flap_statistics
9281 || type == bgp_show_type_flap_neighbor)
9282 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9283 else
9284 vty_out(vty, BGP_SHOW_HEADER);
9285 header = 0;
9286 }
9287 if (rd != NULL && !display && !output_count) {
9288 if (!use_json)
9289 vty_out(vty,
9290 "Route Distinguisher: %s\n",
9291 rd);
9292 }
9293 if (type == bgp_show_type_dampend_paths
9294 || type == bgp_show_type_damp_neighbor)
9295 damp_route_vty_out(vty, &rn->p, pi, display,
9296 safi, use_json, json_paths);
9297 else if (type == bgp_show_type_flap_statistics
9298 || type == bgp_show_type_flap_neighbor)
9299 flap_route_vty_out(vty, &rn->p, pi, display,
9300 safi, use_json, json_paths);
9301 else
9302 route_vty_out(vty, &rn->p, pi, display, safi,
9303 json_paths);
9304 display++;
9305 }
9306
9307 if (display) {
9308 output_count++;
9309 if (!use_json)
9310 continue;
9311
9312 p = &rn->p;
9313 /* encode prefix */
9314 if (p->family == AF_FLOWSPEC) {
9315 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9316
9317 bgp_fs_nlri_get_string((unsigned char *)
9318 p->u.prefix_flowspec.ptr,
9319 p->u.prefix_flowspec
9320 .prefixlen,
9321 retstr,
9322 NLRI_STRING_FORMAT_MIN,
9323 NULL);
9324 if (first)
9325 vty_out(vty, "\"%s/%d\": ",
9326 retstr,
9327 p->u.prefix_flowspec.prefixlen);
9328 else
9329 vty_out(vty, ",\"%s/%d\": ",
9330 retstr,
9331 p->u.prefix_flowspec.prefixlen);
9332 } else {
9333 prefix2str(p, buf2, sizeof(buf2));
9334 if (first)
9335 vty_out(vty, "\"%s\": ", buf2);
9336 else
9337 vty_out(vty, ",\"%s\": ", buf2);
9338 }
9339 vty_out(vty, "%s",
9340 json_object_to_json_string(json_paths));
9341 json_object_free(json_paths);
9342 json_paths = NULL;
9343 first = 0;
9344 }
9345 }
9346
9347 if (output_cum) {
9348 output_count += *output_cum;
9349 *output_cum = output_count;
9350 }
9351 if (total_cum) {
9352 total_count += *total_cum;
9353 *total_cum = total_count;
9354 }
9355 if (use_json) {
9356 if (rd) {
9357 vty_out(vty, " }%s ", (is_last ? "" : ","));
9358 }
9359 if (is_last) {
9360 unsigned long i;
9361 for (i = 0; i < *json_header_depth; ++i)
9362 vty_out(vty, " } ");
9363 vty_out(vty, "\n");
9364 }
9365 } else {
9366 if (is_last) {
9367 /* No route is displayed */
9368 if (output_count == 0) {
9369 if (type == bgp_show_type_normal)
9370 vty_out(vty,
9371 "No BGP prefixes displayed, %ld exist\n",
9372 total_count);
9373 } else
9374 vty_out(vty,
9375 "\nDisplayed %ld routes and %ld total paths\n",
9376 output_count, total_count);
9377 }
9378 }
9379
9380 return CMD_SUCCESS;
9381 }
9382
9383 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9384 struct bgp_table *table, struct prefix_rd *prd_match,
9385 enum bgp_show_type type, void *output_arg, bool use_json)
9386 {
9387 struct bgp_node *rn, *next;
9388 unsigned long output_cum = 0;
9389 unsigned long total_cum = 0;
9390 unsigned long json_header_depth = 0;
9391 struct bgp_table *itable;
9392 bool show_msg;
9393
9394 show_msg = (!use_json && type == bgp_show_type_normal);
9395
9396 for (rn = bgp_table_top(table); rn; rn = next) {
9397 next = bgp_route_next(rn);
9398 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
9399 continue;
9400
9401 itable = bgp_node_get_bgp_table_info(rn);
9402 if (itable != NULL) {
9403 struct prefix_rd prd;
9404 char rd[RD_ADDRSTRLEN];
9405
9406 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
9407 prefix_rd2str(&prd, rd, sizeof(rd));
9408 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
9409 use_json, rd, next == NULL, &output_cum,
9410 &total_cum, &json_header_depth);
9411 if (next == NULL)
9412 show_msg = false;
9413 }
9414 }
9415 if (show_msg) {
9416 if (output_cum == 0)
9417 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
9418 total_cum);
9419 else
9420 vty_out(vty,
9421 "\nDisplayed %ld routes and %ld total paths\n",
9422 output_cum, total_cum);
9423 }
9424 return CMD_SUCCESS;
9425 }
9426 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9427 enum bgp_show_type type, void *output_arg, bool use_json)
9428 {
9429 struct bgp_table *table;
9430 unsigned long json_header_depth = 0;
9431
9432 if (bgp == NULL) {
9433 bgp = bgp_get_default();
9434 }
9435
9436 if (bgp == NULL) {
9437 if (!use_json)
9438 vty_out(vty, "No BGP process is configured\n");
9439 else
9440 vty_out(vty, "{}\n");
9441 return CMD_WARNING;
9442 }
9443
9444 table = bgp->rib[afi][safi];
9445 /* use MPLS and ENCAP specific shows until they are merged */
9446 if (safi == SAFI_MPLS_VPN) {
9447 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9448 output_arg, use_json);
9449 }
9450
9451 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9452 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9453 output_arg, use_json,
9454 1, NULL, NULL);
9455 }
9456 /* labeled-unicast routes live in the unicast table */
9457 else if (safi == SAFI_LABELED_UNICAST)
9458 safi = SAFI_UNICAST;
9459
9460 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9461 NULL, 1, NULL, NULL, &json_header_depth);
9462 }
9463
9464 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9465 safi_t safi, bool use_json)
9466 {
9467 struct listnode *node, *nnode;
9468 struct bgp *bgp;
9469 int is_first = 1;
9470 bool route_output = false;
9471
9472 if (use_json)
9473 vty_out(vty, "{\n");
9474
9475 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9476 route_output = true;
9477 if (use_json) {
9478 if (!is_first)
9479 vty_out(vty, ",\n");
9480 else
9481 is_first = 0;
9482
9483 vty_out(vty, "\"%s\":",
9484 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9485 ? VRF_DEFAULT_NAME
9486 : bgp->name);
9487 } else {
9488 vty_out(vty, "\nInstance %s:\n",
9489 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9490 ? VRF_DEFAULT_NAME
9491 : bgp->name);
9492 }
9493 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9494 use_json);
9495 }
9496
9497 if (use_json)
9498 vty_out(vty, "}\n");
9499 else if (!route_output)
9500 vty_out(vty, "%% BGP instance not found\n");
9501 }
9502
9503 /* Header of detailed BGP route information */
9504 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9505 struct bgp_node *rn, struct prefix_rd *prd,
9506 afi_t afi, safi_t safi, json_object *json)
9507 {
9508 struct bgp_path_info *pi;
9509 struct prefix *p;
9510 struct peer *peer;
9511 struct listnode *node, *nnode;
9512 char buf1[RD_ADDRSTRLEN];
9513 char buf2[INET6_ADDRSTRLEN];
9514 char buf3[EVPN_ROUTE_STRLEN];
9515 char prefix_str[BUFSIZ];
9516 int count = 0;
9517 int best = 0;
9518 int suppress = 0;
9519 int accept_own = 0;
9520 int route_filter_translated_v4 = 0;
9521 int route_filter_v4 = 0;
9522 int route_filter_translated_v6 = 0;
9523 int route_filter_v6 = 0;
9524 int llgr_stale = 0;
9525 int no_llgr = 0;
9526 int accept_own_nexthop = 0;
9527 int blackhole = 0;
9528 int no_export = 0;
9529 int no_advertise = 0;
9530 int local_as = 0;
9531 int no_peer = 0;
9532 int first = 1;
9533 int has_valid_label = 0;
9534 mpls_label_t label = 0;
9535 json_object *json_adv_to = NULL;
9536
9537 p = &rn->p;
9538 has_valid_label = bgp_is_valid_label(&rn->local_label);
9539
9540 if (has_valid_label)
9541 label = label_pton(&rn->local_label);
9542
9543 if (safi == SAFI_EVPN) {
9544
9545 if (!json) {
9546 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9547 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9548 : "", prd ? ":" : "",
9549 bgp_evpn_route2str((struct prefix_evpn *)p,
9550 buf3, sizeof(buf3)));
9551 } else {
9552 json_object_string_add(json, "rd",
9553 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
9554 "");
9555 bgp_evpn_route2json((struct prefix_evpn *)p, json);
9556 }
9557 } else {
9558 if (!json) {
9559 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9560 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9561 ? prefix_rd2str(prd, buf1,
9562 sizeof(buf1))
9563 : ""),
9564 safi == SAFI_MPLS_VPN ? ":" : "",
9565 inet_ntop(p->family, &p->u.prefix, buf2,
9566 INET6_ADDRSTRLEN),
9567 p->prefixlen);
9568
9569 } else
9570 json_object_string_add(json, "prefix",
9571 prefix2str(p, prefix_str, sizeof(prefix_str)));
9572 }
9573
9574 if (has_valid_label) {
9575 if (json)
9576 json_object_int_add(json, "localLabel", label);
9577 else
9578 vty_out(vty, "Local label: %d\n", label);
9579 }
9580
9581 if (!json)
9582 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9583 vty_out(vty, "not allocated\n");
9584
9585 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9586 count++;
9587 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9588 best = count;
9589 if (pi->extra && pi->extra->suppress)
9590 suppress = 1;
9591
9592 if (pi->attr->community == NULL)
9593 continue;
9594
9595 no_advertise += community_include(
9596 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9597 no_export += community_include(pi->attr->community,
9598 COMMUNITY_NO_EXPORT);
9599 local_as += community_include(pi->attr->community,
9600 COMMUNITY_LOCAL_AS);
9601 accept_own += community_include(pi->attr->community,
9602 COMMUNITY_ACCEPT_OWN);
9603 route_filter_translated_v4 += community_include(
9604 pi->attr->community,
9605 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9606 route_filter_translated_v6 += community_include(
9607 pi->attr->community,
9608 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9609 route_filter_v4 += community_include(
9610 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9611 route_filter_v6 += community_include(
9612 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9613 llgr_stale += community_include(pi->attr->community,
9614 COMMUNITY_LLGR_STALE);
9615 no_llgr += community_include(pi->attr->community,
9616 COMMUNITY_NO_LLGR);
9617 accept_own_nexthop +=
9618 community_include(pi->attr->community,
9619 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9620 blackhole += community_include(pi->attr->community,
9621 COMMUNITY_BLACKHOLE);
9622 no_peer += community_include(pi->attr->community,
9623 COMMUNITY_NO_PEER);
9624 }
9625 }
9626
9627 if (!json) {
9628 vty_out(vty, "Paths: (%d available", count);
9629 if (best) {
9630 vty_out(vty, ", best #%d", best);
9631 if (safi == SAFI_UNICAST) {
9632 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9633 vty_out(vty, ", table %s",
9634 VRF_DEFAULT_NAME);
9635 else
9636 vty_out(vty, ", vrf %s",
9637 bgp->name);
9638 }
9639 } else
9640 vty_out(vty, ", no best path");
9641
9642 if (accept_own)
9643 vty_out(vty,
9644 ", accept own local route exported and imported in different VRF");
9645 else if (route_filter_translated_v4)
9646 vty_out(vty,
9647 ", mark translated RTs for VPNv4 route filtering");
9648 else if (route_filter_v4)
9649 vty_out(vty,
9650 ", attach RT as-is for VPNv4 route filtering");
9651 else if (route_filter_translated_v6)
9652 vty_out(vty,
9653 ", mark translated RTs for VPNv6 route filtering");
9654 else if (route_filter_v6)
9655 vty_out(vty,
9656 ", attach RT as-is for VPNv6 route filtering");
9657 else if (llgr_stale)
9658 vty_out(vty,
9659 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9660 else if (no_llgr)
9661 vty_out(vty,
9662 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9663 else if (accept_own_nexthop)
9664 vty_out(vty,
9665 ", accept local nexthop");
9666 else if (blackhole)
9667 vty_out(vty, ", inform peer to blackhole prefix");
9668 else if (no_export)
9669 vty_out(vty, ", not advertised to EBGP peer");
9670 else if (no_advertise)
9671 vty_out(vty, ", not advertised to any peer");
9672 else if (local_as)
9673 vty_out(vty, ", not advertised outside local AS");
9674 else if (no_peer)
9675 vty_out(vty,
9676 ", inform EBGP peer not to advertise to their EBGP peers");
9677
9678 if (suppress)
9679 vty_out(vty,
9680 ", Advertisements suppressed by an aggregate.");
9681 vty_out(vty, ")\n");
9682 }
9683
9684 /* If we are not using addpath then we can display Advertised to and
9685 * that will
9686 * show what peers we advertised the bestpath to. If we are using
9687 * addpath
9688 * though then we must display Advertised to on a path-by-path basis. */
9689 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9690 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9691 if (bgp_adj_out_lookup(peer, rn, 0)) {
9692 if (json && !json_adv_to)
9693 json_adv_to = json_object_new_object();
9694
9695 route_vty_out_advertised_to(
9696 vty, peer, &first,
9697 " Advertised to non peer-group peers:\n ",
9698 json_adv_to);
9699 }
9700 }
9701
9702 if (json) {
9703 if (json_adv_to) {
9704 json_object_object_add(json, "advertisedTo",
9705 json_adv_to);
9706 }
9707 } else {
9708 if (first)
9709 vty_out(vty, " Not advertised to any peer");
9710 vty_out(vty, "\n");
9711 }
9712 }
9713 }
9714
9715 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
9716 struct bgp_node *bgp_node, struct vty *vty,
9717 struct bgp *bgp, afi_t afi,
9718 safi_t safi, json_object *json,
9719 enum bgp_path_type pathtype, int *display)
9720 {
9721 struct bgp_path_info *pi;
9722 int header = 1;
9723 char rdbuf[RD_ADDRSTRLEN];
9724 json_object *json_header = NULL;
9725 json_object *json_paths = NULL;
9726
9727 for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
9728 pi = pi->next) {
9729
9730 if (json && !json_paths) {
9731 /* Instantiate json_paths only if path is valid */
9732 json_paths = json_object_new_array();
9733 if (pfx_rd) {
9734 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
9735 json_header = json_object_new_object();
9736 } else
9737 json_header = json;
9738 }
9739
9740 if (header) {
9741 route_vty_out_detail_header(
9742 vty, bgp, bgp_node, pfx_rd,
9743 AFI_IP, safi, json_header);
9744 header = 0;
9745 }
9746 (*display)++;
9747
9748 if (pathtype == BGP_PATH_SHOW_ALL
9749 || (pathtype == BGP_PATH_SHOW_BESTPATH
9750 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
9751 || (pathtype == BGP_PATH_SHOW_MULTIPATH
9752 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
9753 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
9754 route_vty_out_detail(vty, bgp, bgp_node,
9755 pi, AFI_IP, safi,
9756 json_paths);
9757 }
9758
9759 if (json && json_paths) {
9760 json_object_object_add(json_header, "paths", json_paths);
9761
9762 if (pfx_rd)
9763 json_object_object_add(json, rdbuf, json_header);
9764 }
9765 }
9766
9767 /* Display specified route of BGP table. */
9768 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
9769 struct bgp_table *rib, const char *ip_str,
9770 afi_t afi, safi_t safi,
9771 struct prefix_rd *prd, int prefix_check,
9772 enum bgp_path_type pathtype, bool use_json)
9773 {
9774 int ret;
9775 int display = 0;
9776 struct prefix match;
9777 struct bgp_node *rn;
9778 struct bgp_node *rm;
9779 struct bgp_table *table;
9780 json_object *json = NULL;
9781 json_object *json_paths = NULL;
9782
9783 /* Check IP address argument. */
9784 ret = str2prefix(ip_str, &match);
9785 if (!ret) {
9786 vty_out(vty, "address is malformed\n");
9787 return CMD_WARNING;
9788 }
9789
9790 match.family = afi2family(afi);
9791
9792 if (use_json)
9793 json = json_object_new_object();
9794
9795 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
9796 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9797 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9798 continue;
9799 table = bgp_node_get_bgp_table_info(rn);
9800 if (!table)
9801 continue;
9802
9803 if ((rm = bgp_node_match(table, &match)) == NULL)
9804 continue;
9805
9806 if (prefix_check
9807 && rm->p.prefixlen != match.prefixlen) {
9808 bgp_unlock_node(rm);
9809 continue;
9810 }
9811
9812 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9813 vty, bgp, afi, safi, json,
9814 pathtype, &display);
9815
9816 bgp_unlock_node(rm);
9817 }
9818 } else if (safi == SAFI_EVPN) {
9819 struct bgp_node *longest_pfx;
9820 bool is_exact_pfxlen_match = FALSE;
9821
9822 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9823 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9824 continue;
9825 table = bgp_node_get_bgp_table_info(rn);
9826 if (!table)
9827 continue;
9828
9829 longest_pfx = NULL;
9830 is_exact_pfxlen_match = FALSE;
9831 /*
9832 * Search through all the prefixes for a match. The
9833 * pfx's are enumerated in ascending order of pfxlens.
9834 * So, the last pfx match is the longest match. Set
9835 * is_exact_pfxlen_match when we get exact pfxlen match
9836 */
9837 for (rm = bgp_table_top(table); rm;
9838 rm = bgp_route_next(rm)) {
9839 /*
9840 * Get prefixlen of the ip-prefix within type5
9841 * evpn route
9842 */
9843 if (evpn_type5_prefix_match(&rm->p,
9844 &match) && rm->info) {
9845 longest_pfx = rm;
9846 int type5_pfxlen =
9847 bgp_evpn_get_type5_prefixlen(&rm->p);
9848 if (type5_pfxlen == match.prefixlen) {
9849 is_exact_pfxlen_match = TRUE;
9850 bgp_unlock_node(rm);
9851 break;
9852 }
9853 }
9854 }
9855
9856 if (!longest_pfx)
9857 continue;
9858
9859 if (prefix_check && !is_exact_pfxlen_match)
9860 continue;
9861
9862 rm = longest_pfx;
9863 bgp_lock_node(rm);
9864
9865 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9866 vty, bgp, afi, safi, json,
9867 pathtype, &display);
9868
9869 bgp_unlock_node(rm);
9870 }
9871 } else if (safi == SAFI_FLOWSPEC) {
9872 if (use_json)
9873 json_paths = json_object_new_array();
9874
9875 display = bgp_flowspec_display_match_per_ip(afi, rib,
9876 &match, prefix_check,
9877 vty,
9878 use_json,
9879 json_paths);
9880 if (use_json && display)
9881 json_object_object_add(json, "paths", json_paths);
9882 } else {
9883 if ((rn = bgp_node_match(rib, &match)) != NULL) {
9884 if (!prefix_check
9885 || rn->p.prefixlen == match.prefixlen) {
9886 bgp_show_path_info(NULL, rn, vty, bgp, afi,
9887 safi, json,
9888 pathtype, &display);
9889 }
9890
9891 bgp_unlock_node(rn);
9892 }
9893 }
9894
9895 if (use_json) {
9896 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9897 json, JSON_C_TO_STRING_PRETTY |
9898 JSON_C_TO_STRING_NOSLASHESCAPE));
9899 json_object_free(json);
9900 } else {
9901 if (!display) {
9902 vty_out(vty, "%% Network not in table\n");
9903 return CMD_WARNING;
9904 }
9905 }
9906
9907 return CMD_SUCCESS;
9908 }
9909
9910 /* Display specified route of Main RIB */
9911 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
9912 afi_t afi, safi_t safi, struct prefix_rd *prd,
9913 int prefix_check, enum bgp_path_type pathtype,
9914 bool use_json)
9915 {
9916 if (!bgp) {
9917 bgp = bgp_get_default();
9918 if (!bgp) {
9919 if (!use_json)
9920 vty_out(vty, "No BGP process is configured\n");
9921 else
9922 vty_out(vty, "{}\n");
9923 return CMD_WARNING;
9924 }
9925 }
9926
9927 /* labeled-unicast routes live in the unicast table */
9928 if (safi == SAFI_LABELED_UNICAST)
9929 safi = SAFI_UNICAST;
9930
9931 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
9932 afi, safi, prd, prefix_check, pathtype,
9933 use_json);
9934 }
9935
9936 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
9937 struct cmd_token **argv, bool exact, afi_t afi,
9938 safi_t safi, bool uj)
9939 {
9940 struct lcommunity *lcom;
9941 struct buffer *b;
9942 int i;
9943 char *str;
9944 int first = 0;
9945
9946 b = buffer_new(1024);
9947 for (i = 0; i < argc; i++) {
9948 if (first)
9949 buffer_putc(b, ' ');
9950 else {
9951 if (strmatch(argv[i]->text, "AA:BB:CC")) {
9952 first = 1;
9953 buffer_putstr(b, argv[i]->arg);
9954 }
9955 }
9956 }
9957 buffer_putc(b, '\0');
9958
9959 str = buffer_getstr(b);
9960 buffer_free(b);
9961
9962 lcom = lcommunity_str2com(str);
9963 XFREE(MTYPE_TMP, str);
9964 if (!lcom) {
9965 vty_out(vty, "%% Large-community malformed\n");
9966 return CMD_WARNING;
9967 }
9968
9969 return bgp_show(vty, bgp, afi, safi,
9970 (exact ? bgp_show_type_lcommunity_exact
9971 : bgp_show_type_lcommunity),
9972 lcom, uj);
9973 }
9974
9975 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
9976 const char *lcom, bool exact, afi_t afi,
9977 safi_t safi, bool uj)
9978 {
9979 struct community_list *list;
9980
9981 list = community_list_lookup(bgp_clist, lcom, 0,
9982 LARGE_COMMUNITY_LIST_MASTER);
9983 if (list == NULL) {
9984 vty_out(vty, "%% %s is not a valid large-community-list name\n",
9985 lcom);
9986 return CMD_WARNING;
9987 }
9988
9989 return bgp_show(vty, bgp, afi, safi,
9990 (exact ? bgp_show_type_lcommunity_list_exact
9991 : bgp_show_type_lcommunity_list),
9992 list, uj);
9993 }
9994
9995 DEFUN (show_ip_bgp_large_community_list,
9996 show_ip_bgp_large_community_list_cmd,
9997 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [exact-match] [json]",
9998 SHOW_STR
9999 IP_STR
10000 BGP_STR
10001 BGP_INSTANCE_HELP_STR
10002 BGP_AFI_HELP_STR
10003 BGP_SAFI_WITH_LABEL_HELP_STR
10004 "Display routes matching the large-community-list\n"
10005 "large-community-list number\n"
10006 "large-community-list name\n"
10007 "Exact match of the large-communities\n"
10008 JSON_STR)
10009 {
10010 char *vrf = NULL;
10011 afi_t afi = AFI_IP6;
10012 safi_t safi = SAFI_UNICAST;
10013 int idx = 0;
10014 bool exact_match = 0;
10015
10016 if (argv_find(argv, argc, "ip", &idx))
10017 afi = AFI_IP;
10018 if (argv_find(argv, argc, "view", &idx)
10019 || argv_find(argv, argc, "vrf", &idx))
10020 vrf = argv[++idx]->arg;
10021 if (argv_find(argv, argc, "ipv4", &idx)
10022 || argv_find(argv, argc, "ipv6", &idx)) {
10023 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10024 if (argv_find(argv, argc, "unicast", &idx)
10025 || argv_find(argv, argc, "multicast", &idx))
10026 safi = bgp_vty_safi_from_str(argv[idx]->text);
10027 }
10028
10029 bool uj = use_json(argc, argv);
10030
10031 struct bgp *bgp = bgp_lookup_by_name(vrf);
10032 if (bgp == NULL) {
10033 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10034 return CMD_WARNING;
10035 }
10036
10037 argv_find(argv, argc, "large-community-list", &idx);
10038
10039 const char *clist_number_or_name = argv[++idx]->arg;
10040
10041 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10042 exact_match = 1;
10043
10044 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10045 exact_match, afi, safi, uj);
10046 }
10047 DEFUN (show_ip_bgp_large_community,
10048 show_ip_bgp_large_community_cmd,
10049 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10050 SHOW_STR
10051 IP_STR
10052 BGP_STR
10053 BGP_INSTANCE_HELP_STR
10054 BGP_AFI_HELP_STR
10055 BGP_SAFI_WITH_LABEL_HELP_STR
10056 "Display routes matching the large-communities\n"
10057 "List of large-community numbers\n"
10058 "Exact match of the large-communities\n"
10059 JSON_STR)
10060 {
10061 char *vrf = NULL;
10062 afi_t afi = AFI_IP6;
10063 safi_t safi = SAFI_UNICAST;
10064 int idx = 0;
10065 bool exact_match = 0;
10066
10067 if (argv_find(argv, argc, "ip", &idx))
10068 afi = AFI_IP;
10069 if (argv_find(argv, argc, "view", &idx)
10070 || argv_find(argv, argc, "vrf", &idx))
10071 vrf = argv[++idx]->arg;
10072 if (argv_find(argv, argc, "ipv4", &idx)
10073 || argv_find(argv, argc, "ipv6", &idx)) {
10074 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10075 if (argv_find(argv, argc, "unicast", &idx)
10076 || argv_find(argv, argc, "multicast", &idx))
10077 safi = bgp_vty_safi_from_str(argv[idx]->text);
10078 }
10079
10080 bool uj = use_json(argc, argv);
10081
10082 struct bgp *bgp = bgp_lookup_by_name(vrf);
10083 if (bgp == NULL) {
10084 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10085 return CMD_WARNING;
10086 }
10087
10088 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10089 if (argv_find(argv, argc, "exact-match", &idx))
10090 exact_match = 1;
10091 return bgp_show_lcommunity(vty, bgp, argc, argv,
10092 exact_match, afi, safi, uj);
10093 } else
10094 return bgp_show(vty, bgp, afi, safi,
10095 bgp_show_type_lcommunity_all, NULL, uj);
10096 }
10097
10098 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10099 safi_t safi);
10100
10101
10102 /* BGP route print out function without JSON */
10103 DEFUN (show_ip_bgp,
10104 show_ip_bgp_cmd,
10105 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10106 <dampening <parameters>\
10107 |route-map WORD\
10108 |prefix-list WORD\
10109 |filter-list WORD\
10110 |statistics\
10111 |community-list <(1-500)|WORD> [exact-match]\
10112 |A.B.C.D/M longer-prefixes\
10113 |X:X::X:X/M longer-prefixes\
10114 >",
10115 SHOW_STR
10116 IP_STR
10117 BGP_STR
10118 BGP_INSTANCE_HELP_STR
10119 BGP_AFI_HELP_STR
10120 BGP_SAFI_WITH_LABEL_HELP_STR
10121 "Display detailed information about dampening\n"
10122 "Display detail of configured dampening parameters\n"
10123 "Display routes matching the route-map\n"
10124 "A route-map to match on\n"
10125 "Display routes conforming to the prefix-list\n"
10126 "Prefix-list name\n"
10127 "Display routes conforming to the filter-list\n"
10128 "Regular expression access list name\n"
10129 "BGP RIB advertisement statistics\n"
10130 "Display routes matching the community-list\n"
10131 "community-list number\n"
10132 "community-list name\n"
10133 "Exact match of the communities\n"
10134 "IPv4 prefix\n"
10135 "Display route and more specific routes\n"
10136 "IPv6 prefix\n"
10137 "Display route and more specific routes\n")
10138 {
10139 afi_t afi = AFI_IP6;
10140 safi_t safi = SAFI_UNICAST;
10141 int exact_match = 0;
10142 struct bgp *bgp = NULL;
10143 int idx = 0;
10144
10145 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10146 &bgp, false);
10147 if (!idx)
10148 return CMD_WARNING;
10149
10150 if (argv_find(argv, argc, "dampening", &idx)) {
10151 if (argv_find(argv, argc, "parameters", &idx))
10152 return bgp_show_dampening_parameters(vty, afi, safi);
10153 }
10154
10155 if (argv_find(argv, argc, "prefix-list", &idx))
10156 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10157 safi, bgp_show_type_prefix_list);
10158
10159 if (argv_find(argv, argc, "filter-list", &idx))
10160 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10161 safi, bgp_show_type_filter_list);
10162
10163 if (argv_find(argv, argc, "statistics", &idx))
10164 return bgp_table_stats(vty, bgp, afi, safi);
10165
10166 if (argv_find(argv, argc, "route-map", &idx))
10167 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10168 safi, bgp_show_type_route_map);
10169
10170 if (argv_find(argv, argc, "community-list", &idx)) {
10171 const char *clist_number_or_name = argv[++idx]->arg;
10172 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10173 exact_match = 1;
10174 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10175 exact_match, afi, safi);
10176 }
10177 /* prefix-longer */
10178 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10179 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10180 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10181 safi,
10182 bgp_show_type_prefix_longer);
10183
10184 return CMD_WARNING;
10185 }
10186
10187 /* BGP route print out function with JSON */
10188 DEFUN (show_ip_bgp_json,
10189 show_ip_bgp_json_cmd,
10190 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10191 [cidr-only\
10192 |dampening <flap-statistics|dampened-paths>\
10193 |community [AA:NN|local-AS|no-advertise|no-export\
10194 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10195 |accept-own|accept-own-nexthop|route-filter-v6\
10196 |route-filter-v4|route-filter-translated-v6\
10197 |route-filter-translated-v4] [exact-match]\
10198 ] [json]",
10199 SHOW_STR
10200 IP_STR
10201 BGP_STR
10202 BGP_INSTANCE_HELP_STR
10203 BGP_AFI_HELP_STR
10204 BGP_SAFI_WITH_LABEL_HELP_STR
10205 "Display only routes with non-natural netmasks\n"
10206 "Display detailed information about dampening\n"
10207 "Display flap statistics of routes\n"
10208 "Display paths suppressed due to dampening\n"
10209 "Display routes matching the communities\n"
10210 COMMUNITY_AANN_STR
10211 "Do not send outside local AS (well-known community)\n"
10212 "Do not advertise to any peer (well-known community)\n"
10213 "Do not export to next AS (well-known community)\n"
10214 "Graceful shutdown (well-known community)\n"
10215 "Do not export to any peer (well-known community)\n"
10216 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10217 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10218 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10219 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10220 "Should accept VPN route with local nexthop (well-known community)\n"
10221 "RT VPNv6 route filtering (well-known community)\n"
10222 "RT VPNv4 route filtering (well-known community)\n"
10223 "RT translated VPNv6 route filtering (well-known community)\n"
10224 "RT translated VPNv4 route filtering (well-known community)\n"
10225 "Exact match of the communities\n"
10226 JSON_STR)
10227 {
10228 afi_t afi = AFI_IP6;
10229 safi_t safi = SAFI_UNICAST;
10230 enum bgp_show_type sh_type = bgp_show_type_normal;
10231 struct bgp *bgp = NULL;
10232 int idx = 0;
10233 int exact_match = 0;
10234 bool uj = use_json(argc, argv);
10235
10236 if (uj)
10237 argc--;
10238
10239 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10240 &bgp, uj);
10241 if (!idx)
10242 return CMD_WARNING;
10243
10244 if (argv_find(argv, argc, "cidr-only", &idx))
10245 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
10246 NULL, uj);
10247
10248 if (argv_find(argv, argc, "dampening", &idx)) {
10249 if (argv_find(argv, argc, "dampened-paths", &idx))
10250 return bgp_show(vty, bgp, afi, safi,
10251 bgp_show_type_dampend_paths, NULL, uj);
10252 else if (argv_find(argv, argc, "flap-statistics", &idx))
10253 return bgp_show(vty, bgp, afi, safi,
10254 bgp_show_type_flap_statistics, NULL,
10255 uj);
10256 }
10257
10258 if (argv_find(argv, argc, "community", &idx)) {
10259 char *maybecomm = NULL;
10260 char *community = NULL;
10261
10262 if (idx + 1 < argc) {
10263 if (argv[idx + 1]->type == VARIABLE_TKN)
10264 maybecomm = argv[idx + 1]->arg;
10265 else
10266 maybecomm = argv[idx + 1]->text;
10267 }
10268
10269 if (maybecomm && !strmatch(maybecomm, "json")
10270 && !strmatch(maybecomm, "exact-match"))
10271 community = maybecomm;
10272
10273 if (argv_find(argv, argc, "exact-match", &idx))
10274 exact_match = 1;
10275
10276 if (community)
10277 return bgp_show_community(vty, bgp, community,
10278 exact_match, afi, safi, uj);
10279 else
10280 return (bgp_show(vty, bgp, afi, safi,
10281 bgp_show_type_community_all, NULL,
10282 uj));
10283 }
10284
10285 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
10286 }
10287
10288 DEFUN (show_ip_bgp_route,
10289 show_ip_bgp_route_cmd,
10290 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
10291 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10292 SHOW_STR
10293 IP_STR
10294 BGP_STR
10295 BGP_INSTANCE_HELP_STR
10296 BGP_AFI_HELP_STR
10297 BGP_SAFI_WITH_LABEL_HELP_STR
10298 "Network in the BGP routing table to display\n"
10299 "IPv4 prefix\n"
10300 "Network in the BGP routing table to display\n"
10301 "IPv6 prefix\n"
10302 "Display only the bestpath\n"
10303 "Display only multipaths\n"
10304 JSON_STR)
10305 {
10306 int prefix_check = 0;
10307
10308 afi_t afi = AFI_IP6;
10309 safi_t safi = SAFI_UNICAST;
10310 char *prefix = NULL;
10311 struct bgp *bgp = NULL;
10312 enum bgp_path_type path_type;
10313 bool uj = use_json(argc, argv);
10314
10315 int idx = 0;
10316
10317 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10318 &bgp, uj);
10319 if (!idx)
10320 return CMD_WARNING;
10321
10322 if (!bgp) {
10323 vty_out(vty,
10324 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10325 return CMD_WARNING;
10326 }
10327
10328 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10329 if (argv_find(argv, argc, "A.B.C.D", &idx)
10330 || argv_find(argv, argc, "X:X::X:X", &idx))
10331 prefix_check = 0;
10332 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10333 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10334 prefix_check = 1;
10335
10336 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
10337 && afi != AFI_IP6) {
10338 vty_out(vty,
10339 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10340 return CMD_WARNING;
10341 }
10342 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
10343 && afi != AFI_IP) {
10344 vty_out(vty,
10345 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10346 return CMD_WARNING;
10347 }
10348
10349 prefix = argv[idx]->arg;
10350
10351 /* [<bestpath|multipath>] */
10352 if (argv_find(argv, argc, "bestpath", &idx))
10353 path_type = BGP_PATH_SHOW_BESTPATH;
10354 else if (argv_find(argv, argc, "multipath", &idx))
10355 path_type = BGP_PATH_SHOW_MULTIPATH;
10356 else
10357 path_type = BGP_PATH_SHOW_ALL;
10358
10359 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
10360 path_type, uj);
10361 }
10362
10363 DEFUN (show_ip_bgp_regexp,
10364 show_ip_bgp_regexp_cmd,
10365 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
10366 SHOW_STR
10367 IP_STR
10368 BGP_STR
10369 BGP_INSTANCE_HELP_STR
10370 BGP_AFI_HELP_STR
10371 BGP_SAFI_WITH_LABEL_HELP_STR
10372 "Display routes matching the AS path regular expression\n"
10373 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
10374 {
10375 afi_t afi = AFI_IP6;
10376 safi_t safi = SAFI_UNICAST;
10377 struct bgp *bgp = NULL;
10378
10379 int idx = 0;
10380 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10381 &bgp, false);
10382 if (!idx)
10383 return CMD_WARNING;
10384
10385 // get index of regex
10386 argv_find(argv, argc, "regexp", &idx);
10387 idx++;
10388
10389 char *regstr = argv_concat(argv, argc, idx);
10390 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
10391 bgp_show_type_regexp);
10392 XFREE(MTYPE_TMP, regstr);
10393 return rc;
10394 }
10395
10396 DEFUN (show_ip_bgp_instance_all,
10397 show_ip_bgp_instance_all_cmd,
10398 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
10399 SHOW_STR
10400 IP_STR
10401 BGP_STR
10402 BGP_INSTANCE_ALL_HELP_STR
10403 BGP_AFI_HELP_STR
10404 BGP_SAFI_WITH_LABEL_HELP_STR
10405 JSON_STR)
10406 {
10407 afi_t afi = AFI_IP;
10408 safi_t safi = SAFI_UNICAST;
10409 struct bgp *bgp = NULL;
10410 int idx = 0;
10411 bool uj = use_json(argc, argv);
10412
10413 if (uj)
10414 argc--;
10415
10416 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10417 &bgp, uj);
10418 if (!idx)
10419 return CMD_WARNING;
10420
10421 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
10422 return CMD_SUCCESS;
10423 }
10424
10425 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10426 afi_t afi, safi_t safi, enum bgp_show_type type)
10427 {
10428 regex_t *regex;
10429 int rc;
10430
10431 if (!config_bgp_aspath_validate(regstr)) {
10432 vty_out(vty, "Invalid character in as-path access-list %s\n",
10433 regstr);
10434 return CMD_WARNING_CONFIG_FAILED;
10435 }
10436
10437 regex = bgp_regcomp(regstr);
10438 if (!regex) {
10439 vty_out(vty, "Can't compile regexp %s\n", regstr);
10440 return CMD_WARNING;
10441 }
10442
10443 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
10444 bgp_regex_free(regex);
10445 return rc;
10446 }
10447
10448 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10449 const char *prefix_list_str, afi_t afi,
10450 safi_t safi, enum bgp_show_type type)
10451 {
10452 struct prefix_list *plist;
10453
10454 plist = prefix_list_lookup(afi, prefix_list_str);
10455 if (plist == NULL) {
10456 vty_out(vty, "%% %s is not a valid prefix-list name\n",
10457 prefix_list_str);
10458 return CMD_WARNING;
10459 }
10460
10461 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
10462 }
10463
10464 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10465 const char *filter, afi_t afi, safi_t safi,
10466 enum bgp_show_type type)
10467 {
10468 struct as_list *as_list;
10469
10470 as_list = as_list_lookup(filter);
10471 if (as_list == NULL) {
10472 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
10473 filter);
10474 return CMD_WARNING;
10475 }
10476
10477 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
10478 }
10479
10480 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10481 const char *rmap_str, afi_t afi, safi_t safi,
10482 enum bgp_show_type type)
10483 {
10484 struct route_map *rmap;
10485
10486 rmap = route_map_lookup_by_name(rmap_str);
10487 if (!rmap) {
10488 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
10489 return CMD_WARNING;
10490 }
10491
10492 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
10493 }
10494
10495 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10496 const char *comstr, int exact, afi_t afi,
10497 safi_t safi, bool use_json)
10498 {
10499 struct community *com;
10500 int ret = 0;
10501
10502 com = community_str2com(comstr);
10503 if (!com) {
10504 vty_out(vty, "%% Community malformed: %s\n", comstr);
10505 return CMD_WARNING;
10506 }
10507
10508 ret = bgp_show(vty, bgp, afi, safi,
10509 (exact ? bgp_show_type_community_exact
10510 : bgp_show_type_community),
10511 com, use_json);
10512 community_free(&com);
10513
10514 return ret;
10515 }
10516
10517 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10518 const char *com, int exact, afi_t afi,
10519 safi_t safi)
10520 {
10521 struct community_list *list;
10522
10523 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10524 if (list == NULL) {
10525 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10526 return CMD_WARNING;
10527 }
10528
10529 return bgp_show(vty, bgp, afi, safi,
10530 (exact ? bgp_show_type_community_list_exact
10531 : bgp_show_type_community_list),
10532 list, 0);
10533 }
10534
10535 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10536 const char *prefix, afi_t afi, safi_t safi,
10537 enum bgp_show_type type)
10538 {
10539 int ret;
10540 struct prefix *p;
10541
10542 p = prefix_new();
10543
10544 ret = str2prefix(prefix, p);
10545 if (!ret) {
10546 vty_out(vty, "%% Malformed Prefix\n");
10547 return CMD_WARNING;
10548 }
10549
10550 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10551 prefix_free(&p);
10552 return ret;
10553 }
10554
10555 enum bgp_stats {
10556 BGP_STATS_MAXBITLEN = 0,
10557 BGP_STATS_RIB,
10558 BGP_STATS_PREFIXES,
10559 BGP_STATS_TOTPLEN,
10560 BGP_STATS_UNAGGREGATEABLE,
10561 BGP_STATS_MAX_AGGREGATEABLE,
10562 BGP_STATS_AGGREGATES,
10563 BGP_STATS_SPACE,
10564 BGP_STATS_ASPATH_COUNT,
10565 BGP_STATS_ASPATH_MAXHOPS,
10566 BGP_STATS_ASPATH_TOTHOPS,
10567 BGP_STATS_ASPATH_MAXSIZE,
10568 BGP_STATS_ASPATH_TOTSIZE,
10569 BGP_STATS_ASN_HIGHEST,
10570 BGP_STATS_MAX,
10571 };
10572
10573 static const char *table_stats_strs[] = {
10574 [BGP_STATS_PREFIXES] = "Total Prefixes",
10575 [BGP_STATS_TOTPLEN] = "Average prefix length",
10576 [BGP_STATS_RIB] = "Total Advertisements",
10577 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10578 [BGP_STATS_MAX_AGGREGATEABLE] =
10579 "Maximum aggregateable prefixes",
10580 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10581 [BGP_STATS_SPACE] = "Address space advertised",
10582 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10583 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10584 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10585 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10586 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10587 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10588 [BGP_STATS_MAX] = NULL,
10589 };
10590
10591 struct bgp_table_stats {
10592 struct bgp_table *table;
10593 unsigned long long counts[BGP_STATS_MAX];
10594 double total_space;
10595 };
10596
10597 #if 0
10598 #define TALLY_SIGFIG 100000
10599 static unsigned long
10600 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10601 {
10602 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10603 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10604 unsigned long ret = newtot / count;
10605
10606 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10607 return ret + 1;
10608 else
10609 return ret;
10610 }
10611 #endif
10612
10613 static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
10614 struct bgp_table_stats *ts, unsigned int space)
10615 {
10616 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10617 struct bgp_path_info *pi;
10618
10619 if (rn == top)
10620 return;
10621
10622 if (!bgp_node_has_bgp_path_info_data(rn))
10623 return;
10624
10625 ts->counts[BGP_STATS_PREFIXES]++;
10626 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10627
10628 #if 0
10629 ts->counts[BGP_STATS_AVGPLEN]
10630 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10631 ts->counts[BGP_STATS_AVGPLEN],
10632 rn->p.prefixlen);
10633 #endif
10634
10635 /* check if the prefix is included by any other announcements */
10636 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10637 prn = bgp_node_parent_nolock(prn);
10638
10639 if (prn == NULL || prn == top) {
10640 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10641 /* announced address space */
10642 if (space)
10643 ts->total_space += pow(2.0, space - rn->p.prefixlen);
10644 } else if (bgp_node_has_bgp_path_info_data(prn))
10645 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10646
10647
10648 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10649 ts->counts[BGP_STATS_RIB]++;
10650
10651 if (CHECK_FLAG(pi->attr->flag,
10652 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
10653 ts->counts[BGP_STATS_AGGREGATES]++;
10654
10655 /* as-path stats */
10656 if (pi->attr->aspath) {
10657 unsigned int hops = aspath_count_hops(pi->attr->aspath);
10658 unsigned int size = aspath_size(pi->attr->aspath);
10659 as_t highest = aspath_highest(pi->attr->aspath);
10660
10661 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10662
10663 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10664 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
10665
10666 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10667 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
10668
10669 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10670 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10671 #if 0
10672 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10673 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10674 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10675 hops);
10676 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10677 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10678 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
10679 size);
10680 #endif
10681 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
10682 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
10683 }
10684 }
10685 }
10686
10687 static int bgp_table_stats_walker(struct thread *t)
10688 {
10689 struct bgp_node *rn, *nrn;
10690 struct bgp_node *top;
10691 struct bgp_table_stats *ts = THREAD_ARG(t);
10692 unsigned int space = 0;
10693
10694 if (!(top = bgp_table_top(ts->table)))
10695 return 0;
10696
10697 switch (ts->table->afi) {
10698 case AFI_IP:
10699 space = IPV4_MAX_BITLEN;
10700 break;
10701 case AFI_IP6:
10702 space = IPV6_MAX_BITLEN;
10703 break;
10704 default:
10705 return 0;
10706 }
10707
10708 ts->counts[BGP_STATS_MAXBITLEN] = space;
10709
10710 for (rn = top; rn; rn = bgp_route_next(rn)) {
10711 if (ts->table->safi == SAFI_MPLS_VPN) {
10712 struct bgp_table *table;
10713
10714 table = bgp_node_get_bgp_table_info(rn);
10715 if (!table)
10716 continue;
10717
10718 top = bgp_table_top(table);
10719 for (nrn = bgp_table_top(table); nrn;
10720 nrn = bgp_route_next(nrn))
10721 bgp_table_stats_rn(nrn, top, ts, space);
10722 } else {
10723 bgp_table_stats_rn(rn, top, ts, space);
10724 }
10725 }
10726
10727 return 0;
10728 }
10729
10730 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10731 safi_t safi)
10732 {
10733 struct bgp_table_stats ts;
10734 unsigned int i;
10735
10736 if (!bgp->rib[afi][safi]) {
10737 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10738 afi, safi);
10739 return CMD_WARNING;
10740 }
10741
10742 vty_out(vty, "BGP %s RIB statistics\n", get_afi_safi_str(afi, safi, false));
10743
10744 /* labeled-unicast routes live in the unicast table */
10745 if (safi == SAFI_LABELED_UNICAST)
10746 safi = SAFI_UNICAST;
10747
10748 memset(&ts, 0, sizeof(ts));
10749 ts.table = bgp->rib[afi][safi];
10750 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
10751
10752 for (i = 0; i < BGP_STATS_MAX; i++) {
10753 if (!table_stats_strs[i])
10754 continue;
10755
10756 switch (i) {
10757 #if 0
10758 case BGP_STATS_ASPATH_AVGHOPS:
10759 case BGP_STATS_ASPATH_AVGSIZE:
10760 case BGP_STATS_AVGPLEN:
10761 vty_out (vty, "%-30s: ", table_stats_strs[i]);
10762 vty_out (vty, "%12.2f",
10763 (float)ts.counts[i] / (float)TALLY_SIGFIG);
10764 break;
10765 #endif
10766 case BGP_STATS_ASPATH_TOTHOPS:
10767 case BGP_STATS_ASPATH_TOTSIZE:
10768 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10769 vty_out(vty, "%12.2f",
10770 ts.counts[i]
10771 ? (float)ts.counts[i]
10772 / (float)ts.counts
10773 [BGP_STATS_ASPATH_COUNT]
10774 : 0);
10775 break;
10776 case BGP_STATS_TOTPLEN:
10777 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10778 vty_out(vty, "%12.2f",
10779 ts.counts[i]
10780 ? (float)ts.counts[i]
10781 / (float)ts.counts
10782 [BGP_STATS_PREFIXES]
10783 : 0);
10784 break;
10785 case BGP_STATS_SPACE:
10786 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10787 vty_out(vty, "%12g\n", ts.total_space);
10788
10789 if (afi == AFI_IP6) {
10790 vty_out(vty, "%30s: ", "/32 equivalent ");
10791 vty_out(vty, "%12g\n",
10792 ts.total_space * pow(2.0, -128 + 32));
10793 vty_out(vty, "%30s: ", "/48 equivalent ");
10794 vty_out(vty, "%12g\n",
10795 ts.total_space * pow(2.0, -128 + 48));
10796 } else {
10797 vty_out(vty, "%30s: ", "% announced ");
10798 vty_out(vty, "%12.2f\n",
10799 ts.total_space * 100. * pow(2.0, -32));
10800 vty_out(vty, "%30s: ", "/8 equivalent ");
10801 vty_out(vty, "%12.2f\n",
10802 ts.total_space * pow(2.0, -32 + 8));
10803 vty_out(vty, "%30s: ", "/24 equivalent ");
10804 vty_out(vty, "%12.2f\n",
10805 ts.total_space * pow(2.0, -32 + 24));
10806 }
10807 break;
10808 default:
10809 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10810 vty_out(vty, "%12llu", ts.counts[i]);
10811 }
10812
10813 vty_out(vty, "\n");
10814 }
10815 return CMD_SUCCESS;
10816 }
10817
10818 enum bgp_pcounts {
10819 PCOUNT_ADJ_IN = 0,
10820 PCOUNT_DAMPED,
10821 PCOUNT_REMOVED,
10822 PCOUNT_HISTORY,
10823 PCOUNT_STALE,
10824 PCOUNT_VALID,
10825 PCOUNT_ALL,
10826 PCOUNT_COUNTED,
10827 PCOUNT_PFCNT, /* the figure we display to users */
10828 PCOUNT_MAX,
10829 };
10830
10831 static const char *pcount_strs[] = {
10832 [PCOUNT_ADJ_IN] = "Adj-in",
10833 [PCOUNT_DAMPED] = "Damped",
10834 [PCOUNT_REMOVED] = "Removed",
10835 [PCOUNT_HISTORY] = "History",
10836 [PCOUNT_STALE] = "Stale",
10837 [PCOUNT_VALID] = "Valid",
10838 [PCOUNT_ALL] = "All RIB",
10839 [PCOUNT_COUNTED] = "PfxCt counted",
10840 [PCOUNT_PFCNT] = "Useable",
10841 [PCOUNT_MAX] = NULL,
10842 };
10843
10844 struct peer_pcounts {
10845 unsigned int count[PCOUNT_MAX];
10846 const struct peer *peer;
10847 const struct bgp_table *table;
10848 };
10849
10850 static int bgp_peer_count_walker(struct thread *t)
10851 {
10852 struct bgp_node *rn;
10853 struct peer_pcounts *pc = THREAD_ARG(t);
10854 const struct peer *peer = pc->peer;
10855
10856 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
10857 struct bgp_adj_in *ain;
10858 struct bgp_path_info *pi;
10859
10860 for (ain = rn->adj_in; ain; ain = ain->next)
10861 if (ain->peer == peer)
10862 pc->count[PCOUNT_ADJ_IN]++;
10863
10864 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10865
10866 if (pi->peer != peer)
10867 continue;
10868
10869 pc->count[PCOUNT_ALL]++;
10870
10871 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
10872 pc->count[PCOUNT_DAMPED]++;
10873 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10874 pc->count[PCOUNT_HISTORY]++;
10875 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
10876 pc->count[PCOUNT_REMOVED]++;
10877 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
10878 pc->count[PCOUNT_STALE]++;
10879 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
10880 pc->count[PCOUNT_VALID]++;
10881 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10882 pc->count[PCOUNT_PFCNT]++;
10883
10884 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
10885 pc->count[PCOUNT_COUNTED]++;
10886 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10887 flog_err(
10888 EC_LIB_DEVELOPMENT,
10889 "Attempting to count but flags say it is unusable");
10890 } else {
10891 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10892 flog_err(
10893 EC_LIB_DEVELOPMENT,
10894 "Not counted but flags say we should");
10895 }
10896 }
10897 }
10898 return 0;
10899 }
10900
10901 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
10902 safi_t safi, bool use_json)
10903 {
10904 struct peer_pcounts pcounts = {.peer = peer};
10905 unsigned int i;
10906 json_object *json = NULL;
10907 json_object *json_loop = NULL;
10908
10909 if (use_json) {
10910 json = json_object_new_object();
10911 json_loop = json_object_new_object();
10912 }
10913
10914 if (!peer || !peer->bgp || !peer->afc[afi][safi]
10915 || !peer->bgp->rib[afi][safi]) {
10916 if (use_json) {
10917 json_object_string_add(
10918 json, "warning",
10919 "No such neighbor or address family");
10920 vty_out(vty, "%s\n", json_object_to_json_string(json));
10921 json_object_free(json);
10922 } else
10923 vty_out(vty, "%% No such neighbor or address family\n");
10924
10925 return CMD_WARNING;
10926 }
10927
10928 memset(&pcounts, 0, sizeof(pcounts));
10929 pcounts.peer = peer;
10930 pcounts.table = peer->bgp->rib[afi][safi];
10931
10932 /* in-place call via thread subsystem so as to record execution time
10933 * stats for the thread-walk (i.e. ensure this can't be blamed on
10934 * on just vty_read()).
10935 */
10936 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
10937
10938 if (use_json) {
10939 json_object_string_add(json, "prefixCountsFor", peer->host);
10940 json_object_string_add(json, "multiProtocol",
10941 get_afi_safi_str(afi, safi, true));
10942 json_object_int_add(json, "pfxCounter",
10943 peer->pcount[afi][safi]);
10944
10945 for (i = 0; i < PCOUNT_MAX; i++)
10946 json_object_int_add(json_loop, pcount_strs[i],
10947 pcounts.count[i]);
10948
10949 json_object_object_add(json, "ribTableWalkCounters", json_loop);
10950
10951 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10952 json_object_string_add(json, "pfxctDriftFor",
10953 peer->host);
10954 json_object_string_add(
10955 json, "recommended",
10956 "Please report this bug, with the above command output");
10957 }
10958 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10959 json, JSON_C_TO_STRING_PRETTY));
10960 json_object_free(json);
10961 } else {
10962
10963 if (peer->hostname
10964 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
10965 vty_out(vty, "Prefix counts for %s/%s, %s\n",
10966 peer->hostname, peer->host,
10967 get_afi_safi_str(afi, safi, false));
10968 } else {
10969 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
10970 get_afi_safi_str(afi, safi, false));
10971 }
10972
10973 vty_out(vty, "PfxCt: %" PRIu32 "\n", peer->pcount[afi][safi]);
10974 vty_out(vty, "\nCounts from RIB table walk:\n\n");
10975
10976 for (i = 0; i < PCOUNT_MAX; i++)
10977 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
10978 pcounts.count[i]);
10979
10980 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10981 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
10982 vty_out(vty,
10983 "Please report this bug, with the above command output\n");
10984 }
10985 }
10986
10987 return CMD_SUCCESS;
10988 }
10989
10990 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
10991 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
10992 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
10993 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10994 SHOW_STR
10995 IP_STR
10996 BGP_STR
10997 BGP_INSTANCE_HELP_STR
10998 BGP_AFI_HELP_STR
10999 BGP_SAFI_HELP_STR
11000 "Detailed information on TCP and BGP neighbor connections\n"
11001 "Neighbor to display information about\n"
11002 "Neighbor to display information about\n"
11003 "Neighbor on BGP configured interface\n"
11004 "Display detailed prefix count information\n"
11005 JSON_STR)
11006 {
11007 afi_t afi = AFI_IP6;
11008 safi_t safi = SAFI_UNICAST;
11009 struct peer *peer;
11010 int idx = 0;
11011 struct bgp *bgp = NULL;
11012 bool uj = use_json(argc, argv);
11013
11014 if (uj)
11015 argc--;
11016
11017 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11018 &bgp, uj);
11019 if (!idx)
11020 return CMD_WARNING;
11021
11022 argv_find(argv, argc, "neighbors", &idx);
11023 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
11024 if (!peer)
11025 return CMD_WARNING;
11026
11027 return bgp_peer_counts(vty, peer, afi, safi, uj);
11028 }
11029
11030 #ifdef KEEP_OLD_VPN_COMMANDS
11031 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
11032 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
11033 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11034 SHOW_STR
11035 IP_STR
11036 BGP_STR
11037 BGP_VPNVX_HELP_STR
11038 "Display information about all VPNv4 NLRIs\n"
11039 "Detailed information on TCP and BGP neighbor connections\n"
11040 "Neighbor to display information about\n"
11041 "Neighbor to display information about\n"
11042 "Neighbor on BGP configured interface\n"
11043 "Display detailed prefix count information\n"
11044 JSON_STR)
11045 {
11046 int idx_peer = 6;
11047 struct peer *peer;
11048 bool uj = use_json(argc, argv);
11049
11050 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
11051 if (!peer)
11052 return CMD_WARNING;
11053
11054 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
11055 }
11056
11057 DEFUN (show_ip_bgp_vpn_all_route_prefix,
11058 show_ip_bgp_vpn_all_route_prefix_cmd,
11059 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
11060 SHOW_STR
11061 IP_STR
11062 BGP_STR
11063 BGP_VPNVX_HELP_STR
11064 "Display information about all VPNv4 NLRIs\n"
11065 "Network in the BGP routing table to display\n"
11066 "Network in the BGP routing table to display\n"
11067 JSON_STR)
11068 {
11069 int idx = 0;
11070 char *network = NULL;
11071 struct bgp *bgp = bgp_get_default();
11072 if (!bgp) {
11073 vty_out(vty, "Can't find default instance\n");
11074 return CMD_WARNING;
11075 }
11076
11077 if (argv_find(argv, argc, "A.B.C.D", &idx))
11078 network = argv[idx]->arg;
11079 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
11080 network = argv[idx]->arg;
11081 else {
11082 vty_out(vty, "Unable to figure out Network\n");
11083 return CMD_WARNING;
11084 }
11085
11086 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
11087 BGP_PATH_SHOW_ALL, use_json(argc, argv));
11088 }
11089 #endif /* KEEP_OLD_VPN_COMMANDS */
11090
11091 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
11092 show_bgp_l2vpn_evpn_route_prefix_cmd,
11093 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
11094 SHOW_STR
11095 BGP_STR
11096 L2VPN_HELP_STR
11097 EVPN_HELP_STR
11098 "Network in the BGP routing table to display\n"
11099 "Network in the BGP routing table to display\n"
11100 "Network in the BGP routing table to display\n"
11101 "Network in the BGP routing table to display\n"
11102 JSON_STR)
11103 {
11104 int idx = 0;
11105 char *network = NULL;
11106 int prefix_check = 0;
11107
11108 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
11109 argv_find(argv, argc, "X:X::X:X", &idx))
11110 network = argv[idx]->arg;
11111 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
11112 argv_find(argv, argc, "A.B.C.D/M", &idx)) {
11113 network = argv[idx]->arg;
11114 prefix_check = 1;
11115 } else {
11116 vty_out(vty, "Unable to figure out Network\n");
11117 return CMD_WARNING;
11118 }
11119 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
11120 prefix_check, BGP_PATH_SHOW_ALL,
11121 use_json(argc, argv));
11122 }
11123
11124 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
11125 safi_t safi, enum bgp_show_adj_route_type type,
11126 const char *rmap_name, bool use_json,
11127 json_object *json)
11128 {
11129 struct bgp_table *table;
11130 struct bgp_adj_in *ain;
11131 struct bgp_adj_out *adj;
11132 unsigned long output_count;
11133 unsigned long filtered_count;
11134 struct bgp_node *rn;
11135 int header1 = 1;
11136 struct bgp *bgp;
11137 int header2 = 1;
11138 struct attr attr;
11139 int ret;
11140 struct update_subgroup *subgrp;
11141 json_object *json_scode = NULL;
11142 json_object *json_ocode = NULL;
11143 json_object *json_ar = NULL;
11144 struct peer_af *paf;
11145 bool route_filtered;
11146
11147 if (use_json) {
11148 json_scode = json_object_new_object();
11149 json_ocode = json_object_new_object();
11150 json_ar = json_object_new_object();
11151
11152 json_object_string_add(json_scode, "suppressed", "s");
11153 json_object_string_add(json_scode, "damped", "d");
11154 json_object_string_add(json_scode, "history", "h");
11155 json_object_string_add(json_scode, "valid", "*");
11156 json_object_string_add(json_scode, "best", ">");
11157 json_object_string_add(json_scode, "multipath", "=");
11158 json_object_string_add(json_scode, "internal", "i");
11159 json_object_string_add(json_scode, "ribFailure", "r");
11160 json_object_string_add(json_scode, "stale", "S");
11161 json_object_string_add(json_scode, "removed", "R");
11162
11163 json_object_string_add(json_ocode, "igp", "i");
11164 json_object_string_add(json_ocode, "egp", "e");
11165 json_object_string_add(json_ocode, "incomplete", "?");
11166 }
11167
11168 bgp = peer->bgp;
11169
11170 if (!bgp) {
11171 if (use_json) {
11172 json_object_string_add(json, "alert", "no BGP");
11173 vty_out(vty, "%s\n", json_object_to_json_string(json));
11174 json_object_free(json);
11175 } else
11176 vty_out(vty, "%% No bgp\n");
11177 return;
11178 }
11179
11180 /* labeled-unicast routes live in the unicast table */
11181 if (safi == SAFI_LABELED_UNICAST)
11182 table = bgp->rib[afi][SAFI_UNICAST];
11183 else
11184 table = bgp->rib[afi][safi];
11185
11186 output_count = filtered_count = 0;
11187 subgrp = peer_subgroup(peer, afi, safi);
11188
11189 if (type == bgp_show_adj_route_advertised && subgrp
11190 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
11191 if (use_json) {
11192 json_object_int_add(json, "bgpTableVersion",
11193 table->version);
11194 json_object_string_add(json, "bgpLocalRouterId",
11195 inet_ntoa(bgp->router_id));
11196 json_object_int_add(json, "defaultLocPrf",
11197 bgp->default_local_pref);
11198 json_object_int_add(json, "localAS", bgp->as);
11199 json_object_object_add(json, "bgpStatusCodes",
11200 json_scode);
11201 json_object_object_add(json, "bgpOriginCodes",
11202 json_ocode);
11203 json_object_string_add(
11204 json, "bgpOriginatingDefaultNetwork",
11205 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11206 } else {
11207 vty_out(vty, "BGP table version is %" PRIu64
11208 ", local router ID is %s, vrf id ",
11209 table->version, inet_ntoa(bgp->router_id));
11210 if (bgp->vrf_id == VRF_UNKNOWN)
11211 vty_out(vty, "%s", VRFID_NONE_STR);
11212 else
11213 vty_out(vty, "%u", bgp->vrf_id);
11214 vty_out(vty, "\n");
11215 vty_out(vty, "Default local pref %u, ",
11216 bgp->default_local_pref);
11217 vty_out(vty, "local AS %u\n", bgp->as);
11218 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11219 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11220 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11221
11222 vty_out(vty, "Originating default network %s\n\n",
11223 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11224 }
11225 header1 = 0;
11226 }
11227
11228 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11229 if (type == bgp_show_adj_route_received
11230 || type == bgp_show_adj_route_filtered) {
11231 for (ain = rn->adj_in; ain; ain = ain->next) {
11232 if (ain->peer != peer)
11233 continue;
11234
11235 if (header1) {
11236 if (use_json) {
11237 json_object_int_add(
11238 json, "bgpTableVersion",
11239 0);
11240 json_object_string_add(
11241 json,
11242 "bgpLocalRouterId",
11243 inet_ntoa(
11244 bgp->router_id));
11245 json_object_int_add(json,
11246 "defaultLocPrf",
11247 bgp->default_local_pref);
11248 json_object_int_add(json,
11249 "localAS", bgp->as);
11250 json_object_object_add(
11251 json, "bgpStatusCodes",
11252 json_scode);
11253 json_object_object_add(
11254 json, "bgpOriginCodes",
11255 json_ocode);
11256 } else {
11257 vty_out(vty,
11258 "BGP table version is 0, local router ID is %s, vrf id ",
11259 inet_ntoa(
11260 bgp->router_id));
11261 if (bgp->vrf_id == VRF_UNKNOWN)
11262 vty_out(vty, "%s",
11263 VRFID_NONE_STR);
11264 else
11265 vty_out(vty, "%u",
11266 bgp->vrf_id);
11267 vty_out(vty, "\n");
11268 vty_out(vty,
11269 "Default local pref %u, ",
11270 bgp->default_local_pref);
11271 vty_out(vty, "local AS %u\n",
11272 bgp->as);
11273 vty_out(vty,
11274 BGP_SHOW_SCODE_HEADER);
11275 vty_out(vty,
11276 BGP_SHOW_NCODE_HEADER);
11277 vty_out(vty,
11278 BGP_SHOW_OCODE_HEADER);
11279 }
11280 header1 = 0;
11281 }
11282 if (header2) {
11283 if (!use_json)
11284 vty_out(vty, BGP_SHOW_HEADER);
11285 header2 = 0;
11286 }
11287
11288 bgp_attr_dup(&attr, ain->attr);
11289 route_filtered = false;
11290
11291 /* Filter prefix using distribute list,
11292 * filter list or prefix list
11293 */
11294 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
11295 safi)) == FILTER_DENY)
11296 route_filtered = true;
11297
11298 /* Filter prefix using route-map */
11299 ret = bgp_input_modifier(peer, &rn->p, &attr,
11300 afi, safi, rmap_name, NULL, 0);
11301
11302 if (type == bgp_show_adj_route_filtered &&
11303 !route_filtered && ret != RMAP_DENY) {
11304 bgp_attr_undup(&attr, ain->attr);
11305 continue;
11306 }
11307
11308 if (type == bgp_show_adj_route_received &&
11309 (route_filtered || ret == RMAP_DENY))
11310 filtered_count++;
11311
11312 route_vty_out_tmp(vty, &rn->p, &attr, safi,
11313 use_json, json_ar);
11314 bgp_attr_undup(&attr, ain->attr);
11315 output_count++;
11316 }
11317 } else if (type == bgp_show_adj_route_advertised) {
11318 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
11319 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
11320 if (paf->peer != peer || !adj->attr)
11321 continue;
11322
11323 if (header1) {
11324 if (use_json) {
11325 json_object_int_add(
11326 json,
11327 "bgpTableVersion",
11328 table->version);
11329 json_object_string_add(
11330 json,
11331 "bgpLocalRouterId",
11332 inet_ntoa(
11333 bgp->router_id));
11334 json_object_int_add(
11335 json, "defaultLocPrf",
11336 bgp->default_local_pref
11337 );
11338 json_object_int_add(
11339 json, "localAS",
11340 bgp->as);
11341 json_object_object_add(
11342 json,
11343 "bgpStatusCodes",
11344 json_scode);
11345 json_object_object_add(
11346 json,
11347 "bgpOriginCodes",
11348 json_ocode);
11349 } else {
11350 vty_out(vty,
11351 "BGP table version is %" PRIu64
11352 ", local router ID is %s, vrf id ",
11353 table->version,
11354 inet_ntoa(
11355 bgp->router_id));
11356 if (bgp->vrf_id ==
11357 VRF_UNKNOWN)
11358 vty_out(vty,
11359 "%s",
11360 VRFID_NONE_STR);
11361 else
11362 vty_out(vty,
11363 "%u",
11364 bgp->vrf_id);
11365 vty_out(vty, "\n");
11366 vty_out(vty,
11367 "Default local pref %u, ",
11368 bgp->default_local_pref
11369 );
11370 vty_out(vty,
11371 "local AS %u\n",
11372 bgp->as);
11373 vty_out(vty,
11374 BGP_SHOW_SCODE_HEADER);
11375 vty_out(vty,
11376 BGP_SHOW_NCODE_HEADER);
11377 vty_out(vty,
11378 BGP_SHOW_OCODE_HEADER);
11379 }
11380 header1 = 0;
11381 }
11382 if (header2) {
11383 if (!use_json)
11384 vty_out(vty,
11385 BGP_SHOW_HEADER);
11386 header2 = 0;
11387 }
11388
11389 bgp_attr_dup(&attr, adj->attr);
11390 ret = bgp_output_modifier(
11391 peer, &rn->p, &attr, afi, safi,
11392 rmap_name);
11393
11394 if (ret != RMAP_DENY) {
11395 route_vty_out_tmp(vty, &rn->p,
11396 &attr, safi,
11397 use_json,
11398 json_ar);
11399 output_count++;
11400 } else {
11401 filtered_count++;
11402 }
11403
11404 bgp_attr_undup(&attr, adj->attr);
11405 }
11406 }
11407 }
11408
11409 if (use_json) {
11410 json_object_object_add(json, "advertisedRoutes", json_ar);
11411 json_object_int_add(json, "totalPrefixCounter", output_count);
11412 json_object_int_add(json, "filteredPrefixCounter",
11413 filtered_count);
11414
11415 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11416 json, JSON_C_TO_STRING_PRETTY));
11417 json_object_free(json);
11418 } else if (output_count > 0) {
11419 if (filtered_count > 0)
11420 vty_out(vty,
11421 "\nTotal number of prefixes %ld (%ld filtered)\n",
11422 output_count, filtered_count);
11423 else
11424 vty_out(vty, "\nTotal number of prefixes %ld\n",
11425 output_count);
11426 }
11427 }
11428
11429 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
11430 safi_t safi, enum bgp_show_adj_route_type type,
11431 const char *rmap_name, bool use_json)
11432 {
11433 json_object *json = NULL;
11434
11435 if (use_json)
11436 json = json_object_new_object();
11437
11438 if (!peer || !peer->afc[afi][safi]) {
11439 if (use_json) {
11440 json_object_string_add(
11441 json, "warning",
11442 "No such neighbor or address family");
11443 vty_out(vty, "%s\n", json_object_to_json_string(json));
11444 json_object_free(json);
11445 } else
11446 vty_out(vty, "%% No such neighbor or address family\n");
11447
11448 return CMD_WARNING;
11449 }
11450
11451 if ((type == bgp_show_adj_route_received
11452 || type == bgp_show_adj_route_filtered)
11453 && !CHECK_FLAG(peer->af_flags[afi][safi],
11454 PEER_FLAG_SOFT_RECONFIG)) {
11455 if (use_json) {
11456 json_object_string_add(
11457 json, "warning",
11458 "Inbound soft reconfiguration not enabled");
11459 vty_out(vty, "%s\n", json_object_to_json_string(json));
11460 json_object_free(json);
11461 } else
11462 vty_out(vty,
11463 "%% Inbound soft reconfiguration not enabled\n");
11464
11465 return CMD_WARNING;
11466 }
11467
11468 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
11469
11470 return CMD_SUCCESS;
11471 }
11472
11473 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11474 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11475 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11476 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11477 SHOW_STR
11478 IP_STR
11479 BGP_STR
11480 BGP_INSTANCE_HELP_STR
11481 BGP_AFI_HELP_STR
11482 BGP_SAFI_WITH_LABEL_HELP_STR
11483 "Detailed information on TCP and BGP neighbor connections\n"
11484 "Neighbor to display information about\n"
11485 "Neighbor to display information about\n"
11486 "Neighbor on BGP configured interface\n"
11487 "Display the routes advertised to a BGP neighbor\n"
11488 "Display the received routes from neighbor\n"
11489 "Display the filtered routes received from neighbor\n"
11490 "Route-map to modify the attributes\n"
11491 "Name of the route map\n"
11492 JSON_STR)
11493 {
11494 afi_t afi = AFI_IP6;
11495 safi_t safi = SAFI_UNICAST;
11496 char *rmap_name = NULL;
11497 char *peerstr = NULL;
11498 struct bgp *bgp = NULL;
11499 struct peer *peer;
11500 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11501 int idx = 0;
11502 bool uj = use_json(argc, argv);
11503
11504 if (uj)
11505 argc--;
11506
11507 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11508 &bgp, uj);
11509 if (!idx)
11510 return CMD_WARNING;
11511
11512 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11513 argv_find(argv, argc, "neighbors", &idx);
11514 peerstr = argv[++idx]->arg;
11515
11516 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11517 if (!peer)
11518 return CMD_WARNING;
11519
11520 if (argv_find(argv, argc, "advertised-routes", &idx))
11521 type = bgp_show_adj_route_advertised;
11522 else if (argv_find(argv, argc, "received-routes", &idx))
11523 type = bgp_show_adj_route_received;
11524 else if (argv_find(argv, argc, "filtered-routes", &idx))
11525 type = bgp_show_adj_route_filtered;
11526
11527 if (argv_find(argv, argc, "route-map", &idx))
11528 rmap_name = argv[++idx]->arg;
11529
11530 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11531 }
11532
11533 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11534 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11535 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11536 SHOW_STR
11537 IP_STR
11538 BGP_STR
11539 "Address Family\n"
11540 "Address Family\n"
11541 "Address Family modifier\n"
11542 "Detailed information on TCP and BGP neighbor connections\n"
11543 "Neighbor to display information about\n"
11544 "Neighbor to display information about\n"
11545 "Neighbor on BGP configured interface\n"
11546 "Display information received from a BGP neighbor\n"
11547 "Display the prefixlist filter\n"
11548 JSON_STR)
11549 {
11550 afi_t afi = AFI_IP6;
11551 safi_t safi = SAFI_UNICAST;
11552 char *peerstr = NULL;
11553
11554 char name[BUFSIZ];
11555 union sockunion su;
11556 struct peer *peer;
11557 int count, ret;
11558
11559 int idx = 0;
11560
11561 /* show [ip] bgp */
11562 if (argv_find(argv, argc, "ip", &idx))
11563 afi = AFI_IP;
11564 /* [<ipv4|ipv6> [unicast]] */
11565 if (argv_find(argv, argc, "ipv4", &idx))
11566 afi = AFI_IP;
11567 if (argv_find(argv, argc, "ipv6", &idx))
11568 afi = AFI_IP6;
11569 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11570 argv_find(argv, argc, "neighbors", &idx);
11571 peerstr = argv[++idx]->arg;
11572
11573 bool uj = use_json(argc, argv);
11574
11575 ret = str2sockunion(peerstr, &su);
11576 if (ret < 0) {
11577 peer = peer_lookup_by_conf_if(NULL, peerstr);
11578 if (!peer) {
11579 if (uj)
11580 vty_out(vty, "{}\n");
11581 else
11582 vty_out(vty,
11583 "%% Malformed address or name: %s\n",
11584 peerstr);
11585 return CMD_WARNING;
11586 }
11587 } else {
11588 peer = peer_lookup(NULL, &su);
11589 if (!peer) {
11590 if (uj)
11591 vty_out(vty, "{}\n");
11592 else
11593 vty_out(vty, "No peer\n");
11594 return CMD_WARNING;
11595 }
11596 }
11597
11598 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11599 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11600 if (count) {
11601 if (!uj)
11602 vty_out(vty, "Address Family: %s\n",
11603 get_afi_safi_str(afi, safi, false));
11604 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11605 } else {
11606 if (uj)
11607 vty_out(vty, "{}\n");
11608 else
11609 vty_out(vty, "No functional output\n");
11610 }
11611
11612 return CMD_SUCCESS;
11613 }
11614
11615 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11616 afi_t afi, safi_t safi,
11617 enum bgp_show_type type, bool use_json)
11618 {
11619 /* labeled-unicast routes live in the unicast table */
11620 if (safi == SAFI_LABELED_UNICAST)
11621 safi = SAFI_UNICAST;
11622
11623 if (!peer || !peer->afc[afi][safi]) {
11624 if (use_json) {
11625 json_object *json_no = NULL;
11626 json_no = json_object_new_object();
11627 json_object_string_add(
11628 json_no, "warning",
11629 "No such neighbor or address family");
11630 vty_out(vty, "%s\n",
11631 json_object_to_json_string(json_no));
11632 json_object_free(json_no);
11633 } else
11634 vty_out(vty, "%% No such neighbor or address family\n");
11635 return CMD_WARNING;
11636 }
11637
11638 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11639 }
11640
11641 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11642 show_ip_bgp_flowspec_routes_detailed_cmd,
11643 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11644 SHOW_STR
11645 IP_STR
11646 BGP_STR
11647 BGP_INSTANCE_HELP_STR
11648 BGP_AFI_HELP_STR
11649 "SAFI Flowspec\n"
11650 "Detailed information on flowspec entries\n"
11651 JSON_STR)
11652 {
11653 afi_t afi = AFI_IP;
11654 safi_t safi = SAFI_UNICAST;
11655 struct bgp *bgp = NULL;
11656 int idx = 0;
11657 bool uj = use_json(argc, argv);
11658
11659 if (uj)
11660 argc--;
11661
11662 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11663 &bgp, uj);
11664 if (!idx)
11665 return CMD_WARNING;
11666
11667 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
11668 }
11669
11670 DEFUN (show_ip_bgp_neighbor_routes,
11671 show_ip_bgp_neighbor_routes_cmd,
11672 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11673 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11674 SHOW_STR
11675 IP_STR
11676 BGP_STR
11677 BGP_INSTANCE_HELP_STR
11678 BGP_AFI_HELP_STR
11679 BGP_SAFI_WITH_LABEL_HELP_STR
11680 "Detailed information on TCP and BGP neighbor connections\n"
11681 "Neighbor to display information about\n"
11682 "Neighbor to display information about\n"
11683 "Neighbor on BGP configured interface\n"
11684 "Display flap statistics of the routes learned from neighbor\n"
11685 "Display the dampened routes received from neighbor\n"
11686 "Display routes learned from neighbor\n"
11687 JSON_STR)
11688 {
11689 char *peerstr = NULL;
11690 struct bgp *bgp = NULL;
11691 afi_t afi = AFI_IP6;
11692 safi_t safi = SAFI_UNICAST;
11693 struct peer *peer;
11694 enum bgp_show_type sh_type = bgp_show_type_neighbor;
11695 int idx = 0;
11696 bool uj = use_json(argc, argv);
11697
11698 if (uj)
11699 argc--;
11700
11701 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11702 &bgp, uj);
11703 if (!idx)
11704 return CMD_WARNING;
11705
11706 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11707 argv_find(argv, argc, "neighbors", &idx);
11708 peerstr = argv[++idx]->arg;
11709
11710 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11711 if (!peer)
11712 return CMD_WARNING;
11713
11714 if (argv_find(argv, argc, "flap-statistics", &idx))
11715 sh_type = bgp_show_type_flap_neighbor;
11716 else if (argv_find(argv, argc, "dampened-routes", &idx))
11717 sh_type = bgp_show_type_damp_neighbor;
11718 else if (argv_find(argv, argc, "routes", &idx))
11719 sh_type = bgp_show_type_neighbor;
11720
11721 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
11722 }
11723
11724 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
11725
11726 struct bgp_distance {
11727 /* Distance value for the IP source prefix. */
11728 uint8_t distance;
11729
11730 /* Name of the access-list to be matched. */
11731 char *access_list;
11732 };
11733
11734 DEFUN (show_bgp_afi_vpn_rd_route,
11735 show_bgp_afi_vpn_rd_route_cmd,
11736 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
11737 SHOW_STR
11738 BGP_STR
11739 BGP_AFI_HELP_STR
11740 "Address Family modifier\n"
11741 "Display information for a route distinguisher\n"
11742 "Route Distinguisher\n"
11743 "Network in the BGP routing table to display\n"
11744 "Network in the BGP routing table to display\n"
11745 JSON_STR)
11746 {
11747 int ret;
11748 struct prefix_rd prd;
11749 afi_t afi = AFI_MAX;
11750 int idx = 0;
11751
11752 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
11753 vty_out(vty, "%% Malformed Address Family\n");
11754 return CMD_WARNING;
11755 }
11756
11757 ret = str2prefix_rd(argv[5]->arg, &prd);
11758 if (!ret) {
11759 vty_out(vty, "%% Malformed Route Distinguisher\n");
11760 return CMD_WARNING;
11761 }
11762
11763 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
11764 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
11765 }
11766
11767 static struct bgp_distance *bgp_distance_new(void)
11768 {
11769 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
11770 }
11771
11772 static void bgp_distance_free(struct bgp_distance *bdistance)
11773 {
11774 XFREE(MTYPE_BGP_DISTANCE, bdistance);
11775 }
11776
11777 static int bgp_distance_set(struct vty *vty, const char *distance_str,
11778 const char *ip_str, const char *access_list_str)
11779 {
11780 int ret;
11781 afi_t afi;
11782 safi_t safi;
11783 struct prefix p;
11784 uint8_t distance;
11785 struct bgp_node *rn;
11786 struct bgp_distance *bdistance;
11787
11788 afi = bgp_node_afi(vty);
11789 safi = bgp_node_safi(vty);
11790
11791 ret = str2prefix(ip_str, &p);
11792 if (ret == 0) {
11793 vty_out(vty, "Malformed prefix\n");
11794 return CMD_WARNING_CONFIG_FAILED;
11795 }
11796
11797 distance = atoi(distance_str);
11798
11799 /* Get BGP distance node. */
11800 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
11801 bdistance = bgp_node_get_bgp_distance_info(rn);
11802 if (bdistance)
11803 bgp_unlock_node(rn);
11804 else {
11805 bdistance = bgp_distance_new();
11806 bgp_node_set_bgp_distance_info(rn, bdistance);
11807 }
11808
11809 /* Set distance value. */
11810 bdistance->distance = distance;
11811
11812 /* Reset access-list configuration. */
11813 if (bdistance->access_list) {
11814 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11815 bdistance->access_list = NULL;
11816 }
11817 if (access_list_str)
11818 bdistance->access_list =
11819 XSTRDUP(MTYPE_AS_LIST, access_list_str);
11820
11821 return CMD_SUCCESS;
11822 }
11823
11824 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
11825 const char *ip_str, const char *access_list_str)
11826 {
11827 int ret;
11828 afi_t afi;
11829 safi_t safi;
11830 struct prefix p;
11831 int distance;
11832 struct bgp_node *rn;
11833 struct bgp_distance *bdistance;
11834
11835 afi = bgp_node_afi(vty);
11836 safi = bgp_node_safi(vty);
11837
11838 ret = str2prefix(ip_str, &p);
11839 if (ret == 0) {
11840 vty_out(vty, "Malformed prefix\n");
11841 return CMD_WARNING_CONFIG_FAILED;
11842 }
11843
11844 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
11845 (struct prefix *)&p);
11846 if (!rn) {
11847 vty_out(vty, "Can't find specified prefix\n");
11848 return CMD_WARNING_CONFIG_FAILED;
11849 }
11850
11851 bdistance = bgp_node_get_bgp_distance_info(rn);
11852 distance = atoi(distance_str);
11853
11854 if (bdistance->distance != distance) {
11855 vty_out(vty, "Distance does not match configured\n");
11856 return CMD_WARNING_CONFIG_FAILED;
11857 }
11858
11859 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11860 bgp_distance_free(bdistance);
11861
11862 bgp_node_set_bgp_path_info(rn, NULL);
11863 bgp_unlock_node(rn);
11864 bgp_unlock_node(rn);
11865
11866 return CMD_SUCCESS;
11867 }
11868
11869 /* Apply BGP information to distance method. */
11870 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
11871 afi_t afi, safi_t safi, struct bgp *bgp)
11872 {
11873 struct bgp_node *rn;
11874 struct prefix q;
11875 struct peer *peer;
11876 struct bgp_distance *bdistance;
11877 struct access_list *alist;
11878 struct bgp_static *bgp_static;
11879
11880 if (!bgp)
11881 return 0;
11882
11883 peer = pinfo->peer;
11884
11885 if (pinfo->attr->distance)
11886 return pinfo->attr->distance;
11887
11888 /* Check source address. */
11889 sockunion2hostprefix(&peer->su, &q);
11890 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
11891 if (rn) {
11892 bdistance = bgp_node_get_bgp_distance_info(rn);
11893 bgp_unlock_node(rn);
11894
11895 if (bdistance->access_list) {
11896 alist = access_list_lookup(afi, bdistance->access_list);
11897 if (alist
11898 && access_list_apply(alist, p) == FILTER_PERMIT)
11899 return bdistance->distance;
11900 } else
11901 return bdistance->distance;
11902 }
11903
11904 /* Backdoor check. */
11905 rn = bgp_node_lookup(bgp->route[afi][safi], p);
11906 if (rn) {
11907 bgp_static = bgp_node_get_bgp_static_info(rn);
11908 bgp_unlock_node(rn);
11909
11910 if (bgp_static->backdoor) {
11911 if (bgp->distance_local[afi][safi])
11912 return bgp->distance_local[afi][safi];
11913 else
11914 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11915 }
11916 }
11917
11918 if (peer->sort == BGP_PEER_EBGP) {
11919 if (bgp->distance_ebgp[afi][safi])
11920 return bgp->distance_ebgp[afi][safi];
11921 return ZEBRA_EBGP_DISTANCE_DEFAULT;
11922 } else {
11923 if (bgp->distance_ibgp[afi][safi])
11924 return bgp->distance_ibgp[afi][safi];
11925 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11926 }
11927 }
11928
11929 DEFUN (bgp_distance,
11930 bgp_distance_cmd,
11931 "distance bgp (1-255) (1-255) (1-255)",
11932 "Define an administrative distance\n"
11933 "BGP distance\n"
11934 "Distance for routes external to the AS\n"
11935 "Distance for routes internal to the AS\n"
11936 "Distance for local routes\n")
11937 {
11938 VTY_DECLVAR_CONTEXT(bgp, bgp);
11939 int idx_number = 2;
11940 int idx_number_2 = 3;
11941 int idx_number_3 = 4;
11942 afi_t afi;
11943 safi_t safi;
11944
11945 afi = bgp_node_afi(vty);
11946 safi = bgp_node_safi(vty);
11947
11948 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
11949 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
11950 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
11951 return CMD_SUCCESS;
11952 }
11953
11954 DEFUN (no_bgp_distance,
11955 no_bgp_distance_cmd,
11956 "no distance bgp [(1-255) (1-255) (1-255)]",
11957 NO_STR
11958 "Define an administrative distance\n"
11959 "BGP distance\n"
11960 "Distance for routes external to the AS\n"
11961 "Distance for routes internal to the AS\n"
11962 "Distance for local routes\n")
11963 {
11964 VTY_DECLVAR_CONTEXT(bgp, bgp);
11965 afi_t afi;
11966 safi_t safi;
11967
11968 afi = bgp_node_afi(vty);
11969 safi = bgp_node_safi(vty);
11970
11971 bgp->distance_ebgp[afi][safi] = 0;
11972 bgp->distance_ibgp[afi][safi] = 0;
11973 bgp->distance_local[afi][safi] = 0;
11974 return CMD_SUCCESS;
11975 }
11976
11977
11978 DEFUN (bgp_distance_source,
11979 bgp_distance_source_cmd,
11980 "distance (1-255) A.B.C.D/M",
11981 "Define an administrative distance\n"
11982 "Administrative distance\n"
11983 "IP source prefix\n")
11984 {
11985 int idx_number = 1;
11986 int idx_ipv4_prefixlen = 2;
11987 bgp_distance_set(vty, argv[idx_number]->arg,
11988 argv[idx_ipv4_prefixlen]->arg, NULL);
11989 return CMD_SUCCESS;
11990 }
11991
11992 DEFUN (no_bgp_distance_source,
11993 no_bgp_distance_source_cmd,
11994 "no distance (1-255) A.B.C.D/M",
11995 NO_STR
11996 "Define an administrative distance\n"
11997 "Administrative distance\n"
11998 "IP source prefix\n")
11999 {
12000 int idx_number = 2;
12001 int idx_ipv4_prefixlen = 3;
12002 bgp_distance_unset(vty, argv[idx_number]->arg,
12003 argv[idx_ipv4_prefixlen]->arg, NULL);
12004 return CMD_SUCCESS;
12005 }
12006
12007 DEFUN (bgp_distance_source_access_list,
12008 bgp_distance_source_access_list_cmd,
12009 "distance (1-255) A.B.C.D/M WORD",
12010 "Define an administrative distance\n"
12011 "Administrative distance\n"
12012 "IP source prefix\n"
12013 "Access list name\n")
12014 {
12015 int idx_number = 1;
12016 int idx_ipv4_prefixlen = 2;
12017 int idx_word = 3;
12018 bgp_distance_set(vty, argv[idx_number]->arg,
12019 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12020 return CMD_SUCCESS;
12021 }
12022
12023 DEFUN (no_bgp_distance_source_access_list,
12024 no_bgp_distance_source_access_list_cmd,
12025 "no distance (1-255) A.B.C.D/M WORD",
12026 NO_STR
12027 "Define an administrative distance\n"
12028 "Administrative distance\n"
12029 "IP source prefix\n"
12030 "Access list name\n")
12031 {
12032 int idx_number = 2;
12033 int idx_ipv4_prefixlen = 3;
12034 int idx_word = 4;
12035 bgp_distance_unset(vty, argv[idx_number]->arg,
12036 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12037 return CMD_SUCCESS;
12038 }
12039
12040 DEFUN (ipv6_bgp_distance_source,
12041 ipv6_bgp_distance_source_cmd,
12042 "distance (1-255) X:X::X:X/M",
12043 "Define an administrative distance\n"
12044 "Administrative distance\n"
12045 "IP source prefix\n")
12046 {
12047 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
12048 return CMD_SUCCESS;
12049 }
12050
12051 DEFUN (no_ipv6_bgp_distance_source,
12052 no_ipv6_bgp_distance_source_cmd,
12053 "no distance (1-255) X:X::X:X/M",
12054 NO_STR
12055 "Define an administrative distance\n"
12056 "Administrative distance\n"
12057 "IP source prefix\n")
12058 {
12059 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
12060 return CMD_SUCCESS;
12061 }
12062
12063 DEFUN (ipv6_bgp_distance_source_access_list,
12064 ipv6_bgp_distance_source_access_list_cmd,
12065 "distance (1-255) X:X::X:X/M WORD",
12066 "Define an administrative distance\n"
12067 "Administrative distance\n"
12068 "IP source prefix\n"
12069 "Access list name\n")
12070 {
12071 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
12072 return CMD_SUCCESS;
12073 }
12074
12075 DEFUN (no_ipv6_bgp_distance_source_access_list,
12076 no_ipv6_bgp_distance_source_access_list_cmd,
12077 "no distance (1-255) X:X::X:X/M WORD",
12078 NO_STR
12079 "Define an administrative distance\n"
12080 "Administrative distance\n"
12081 "IP source prefix\n"
12082 "Access list name\n")
12083 {
12084 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
12085 return CMD_SUCCESS;
12086 }
12087
12088 DEFUN (bgp_damp_set,
12089 bgp_damp_set_cmd,
12090 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12091 "BGP Specific commands\n"
12092 "Enable route-flap dampening\n"
12093 "Half-life time for the penalty\n"
12094 "Value to start reusing a route\n"
12095 "Value to start suppressing a route\n"
12096 "Maximum duration to suppress a stable route\n")
12097 {
12098 VTY_DECLVAR_CONTEXT(bgp, bgp);
12099 int idx_half_life = 2;
12100 int idx_reuse = 3;
12101 int idx_suppress = 4;
12102 int idx_max_suppress = 5;
12103 int half = DEFAULT_HALF_LIFE * 60;
12104 int reuse = DEFAULT_REUSE;
12105 int suppress = DEFAULT_SUPPRESS;
12106 int max = 4 * half;
12107
12108 if (argc == 6) {
12109 half = atoi(argv[idx_half_life]->arg) * 60;
12110 reuse = atoi(argv[idx_reuse]->arg);
12111 suppress = atoi(argv[idx_suppress]->arg);
12112 max = atoi(argv[idx_max_suppress]->arg) * 60;
12113 } else if (argc == 3) {
12114 half = atoi(argv[idx_half_life]->arg) * 60;
12115 max = 4 * half;
12116 }
12117
12118 if (suppress < reuse) {
12119 vty_out(vty,
12120 "Suppress value cannot be less than reuse value \n");
12121 return 0;
12122 }
12123
12124 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
12125 reuse, suppress, max);
12126 }
12127
12128 DEFUN (bgp_damp_unset,
12129 bgp_damp_unset_cmd,
12130 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12131 NO_STR
12132 "BGP Specific commands\n"
12133 "Enable route-flap dampening\n"
12134 "Half-life time for the penalty\n"
12135 "Value to start reusing a route\n"
12136 "Value to start suppressing a route\n"
12137 "Maximum duration to suppress a stable route\n")
12138 {
12139 VTY_DECLVAR_CONTEXT(bgp, bgp);
12140 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
12141 }
12142
12143 /* Display specified route of BGP table. */
12144 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
12145 const char *ip_str, afi_t afi, safi_t safi,
12146 struct prefix_rd *prd, int prefix_check)
12147 {
12148 int ret;
12149 struct prefix match;
12150 struct bgp_node *rn;
12151 struct bgp_node *rm;
12152 struct bgp_path_info *pi;
12153 struct bgp_path_info *pi_temp;
12154 struct bgp *bgp;
12155 struct bgp_table *table;
12156
12157 /* BGP structure lookup. */
12158 if (view_name) {
12159 bgp = bgp_lookup_by_name(view_name);
12160 if (bgp == NULL) {
12161 vty_out(vty, "%% Can't find BGP instance %s\n",
12162 view_name);
12163 return CMD_WARNING;
12164 }
12165 } else {
12166 bgp = bgp_get_default();
12167 if (bgp == NULL) {
12168 vty_out(vty, "%% No BGP process is configured\n");
12169 return CMD_WARNING;
12170 }
12171 }
12172
12173 /* Check IP address argument. */
12174 ret = str2prefix(ip_str, &match);
12175 if (!ret) {
12176 vty_out(vty, "%% address is malformed\n");
12177 return CMD_WARNING;
12178 }
12179
12180 match.family = afi2family(afi);
12181
12182 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
12183 || (safi == SAFI_EVPN)) {
12184 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
12185 rn = bgp_route_next(rn)) {
12186 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
12187 continue;
12188 table = bgp_node_get_bgp_table_info(rn);
12189 if (!table)
12190 continue;
12191 if ((rm = bgp_node_match(table, &match)) == NULL)
12192 continue;
12193
12194 if (!prefix_check
12195 || rm->p.prefixlen == match.prefixlen) {
12196 pi = bgp_node_get_bgp_path_info(rm);
12197 while (pi) {
12198 if (pi->extra && pi->extra->damp_info) {
12199 pi_temp = pi->next;
12200 bgp_damp_info_free(
12201 pi->extra->damp_info,
12202 1);
12203 pi = pi_temp;
12204 } else
12205 pi = pi->next;
12206 }
12207 }
12208
12209 bgp_unlock_node(rm);
12210 }
12211 } else {
12212 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
12213 != NULL) {
12214 if (!prefix_check
12215 || rn->p.prefixlen == match.prefixlen) {
12216 pi = bgp_node_get_bgp_path_info(rn);
12217 while (pi) {
12218 if (pi->extra && pi->extra->damp_info) {
12219 pi_temp = pi->next;
12220 bgp_damp_info_free(
12221 pi->extra->damp_info,
12222 1);
12223 pi = pi_temp;
12224 } else
12225 pi = pi->next;
12226 }
12227 }
12228
12229 bgp_unlock_node(rn);
12230 }
12231 }
12232
12233 return CMD_SUCCESS;
12234 }
12235
12236 DEFUN (clear_ip_bgp_dampening,
12237 clear_ip_bgp_dampening_cmd,
12238 "clear ip bgp dampening",
12239 CLEAR_STR
12240 IP_STR
12241 BGP_STR
12242 "Clear route flap dampening information\n")
12243 {
12244 bgp_damp_info_clean();
12245 return CMD_SUCCESS;
12246 }
12247
12248 DEFUN (clear_ip_bgp_dampening_prefix,
12249 clear_ip_bgp_dampening_prefix_cmd,
12250 "clear ip bgp dampening A.B.C.D/M",
12251 CLEAR_STR
12252 IP_STR
12253 BGP_STR
12254 "Clear route flap dampening information\n"
12255 "IPv4 prefix\n")
12256 {
12257 int idx_ipv4_prefixlen = 4;
12258 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
12259 AFI_IP, SAFI_UNICAST, NULL, 1);
12260 }
12261
12262 DEFUN (clear_ip_bgp_dampening_address,
12263 clear_ip_bgp_dampening_address_cmd,
12264 "clear ip bgp dampening A.B.C.D",
12265 CLEAR_STR
12266 IP_STR
12267 BGP_STR
12268 "Clear route flap dampening information\n"
12269 "Network to clear damping information\n")
12270 {
12271 int idx_ipv4 = 4;
12272 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
12273 SAFI_UNICAST, NULL, 0);
12274 }
12275
12276 DEFUN (clear_ip_bgp_dampening_address_mask,
12277 clear_ip_bgp_dampening_address_mask_cmd,
12278 "clear ip bgp dampening A.B.C.D A.B.C.D",
12279 CLEAR_STR
12280 IP_STR
12281 BGP_STR
12282 "Clear route flap dampening information\n"
12283 "Network to clear damping information\n"
12284 "Network mask\n")
12285 {
12286 int idx_ipv4 = 4;
12287 int idx_ipv4_2 = 5;
12288 int ret;
12289 char prefix_str[BUFSIZ];
12290
12291 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
12292 prefix_str);
12293 if (!ret) {
12294 vty_out(vty, "%% Inconsistent address and mask\n");
12295 return CMD_WARNING;
12296 }
12297
12298 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
12299 NULL, 0);
12300 }
12301
12302 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
12303 {
12304 struct vty *vty = arg;
12305 struct peer *peer = bucket->data;
12306 char buf[SU_ADDRSTRLEN];
12307
12308 vty_out(vty, "\tPeer: %s %s\n", peer->host,
12309 sockunion2str(&peer->su, buf, sizeof(buf)));
12310 }
12311
12312 DEFUN (show_bgp_peerhash,
12313 show_bgp_peerhash_cmd,
12314 "show bgp peerhash",
12315 SHOW_STR
12316 BGP_STR
12317 "Display information about the BGP peerhash\n")
12318 {
12319 struct list *instances = bm->bgp;
12320 struct listnode *node;
12321 struct bgp *bgp;
12322
12323 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
12324 vty_out(vty, "BGP: %s\n", bgp->name);
12325 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
12326 vty);
12327 }
12328
12329 return CMD_SUCCESS;
12330 }
12331
12332 /* also used for encap safi */
12333 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
12334 afi_t afi, safi_t safi)
12335 {
12336 struct bgp_node *prn;
12337 struct bgp_node *rn;
12338 struct bgp_table *table;
12339 struct prefix *p;
12340 struct prefix_rd *prd;
12341 struct bgp_static *bgp_static;
12342 mpls_label_t label;
12343 char buf[SU_ADDRSTRLEN];
12344 char rdbuf[RD_ADDRSTRLEN];
12345
12346 /* Network configuration. */
12347 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12348 prn = bgp_route_next(prn)) {
12349 table = bgp_node_get_bgp_table_info(prn);
12350 if (!table)
12351 continue;
12352
12353 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12354 bgp_static = bgp_node_get_bgp_static_info(rn);
12355 if (bgp_static == NULL)
12356 continue;
12357
12358 p = &rn->p;
12359 prd = (struct prefix_rd *)&prn->p;
12360
12361 /* "network" configuration display. */
12362 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12363 label = decode_label(&bgp_static->label);
12364
12365 vty_out(vty, " network %s/%d rd %s",
12366 inet_ntop(p->family, &p->u.prefix, buf,
12367 SU_ADDRSTRLEN),
12368 p->prefixlen, rdbuf);
12369 if (safi == SAFI_MPLS_VPN)
12370 vty_out(vty, " label %u", label);
12371
12372 if (bgp_static->rmap.name)
12373 vty_out(vty, " route-map %s",
12374 bgp_static->rmap.name);
12375
12376 if (bgp_static->backdoor)
12377 vty_out(vty, " backdoor");
12378
12379 vty_out(vty, "\n");
12380 }
12381 }
12382 }
12383
12384 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
12385 afi_t afi, safi_t safi)
12386 {
12387 struct bgp_node *prn;
12388 struct bgp_node *rn;
12389 struct bgp_table *table;
12390 struct prefix *p;
12391 struct prefix_rd *prd;
12392 struct bgp_static *bgp_static;
12393 char buf[PREFIX_STRLEN * 2];
12394 char buf2[SU_ADDRSTRLEN];
12395 char rdbuf[RD_ADDRSTRLEN];
12396
12397 /* Network configuration. */
12398 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12399 prn = bgp_route_next(prn)) {
12400 table = bgp_node_get_bgp_table_info(prn);
12401 if (!table)
12402 continue;
12403
12404 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12405 bgp_static = bgp_node_get_bgp_static_info(rn);
12406 if (bgp_static == NULL)
12407 continue;
12408
12409 char *macrouter = NULL;
12410 char *esi = NULL;
12411
12412 if (bgp_static->router_mac)
12413 macrouter = prefix_mac2str(
12414 bgp_static->router_mac, NULL, 0);
12415 if (bgp_static->eth_s_id)
12416 esi = esi2str(bgp_static->eth_s_id);
12417 p = &rn->p;
12418 prd = (struct prefix_rd *)&prn->p;
12419
12420 /* "network" configuration display. */
12421 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12422 if (p->u.prefix_evpn.route_type == 5) {
12423 char local_buf[PREFIX_STRLEN];
12424 uint8_t family = is_evpn_prefix_ipaddr_v4((
12425 struct prefix_evpn *)p)
12426 ? AF_INET
12427 : AF_INET6;
12428 inet_ntop(family,
12429 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
12430 local_buf, PREFIX_STRLEN);
12431 sprintf(buf, "%s/%u", local_buf,
12432 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
12433 } else {
12434 prefix2str(p, buf, sizeof(buf));
12435 }
12436
12437 if (bgp_static->gatewayIp.family == AF_INET
12438 || bgp_static->gatewayIp.family == AF_INET6)
12439 inet_ntop(bgp_static->gatewayIp.family,
12440 &bgp_static->gatewayIp.u.prefix, buf2,
12441 sizeof(buf2));
12442 vty_out(vty,
12443 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12444 buf, rdbuf,
12445 p->u.prefix_evpn.prefix_addr.eth_tag,
12446 decode_label(&bgp_static->label), esi, buf2,
12447 macrouter);
12448
12449 XFREE(MTYPE_TMP, macrouter);
12450 XFREE(MTYPE_TMP, esi);
12451 }
12452 }
12453 }
12454
12455 /* Configuration of static route announcement and aggregate
12456 information. */
12457 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
12458 safi_t safi)
12459 {
12460 struct bgp_node *rn;
12461 struct prefix *p;
12462 struct bgp_static *bgp_static;
12463 struct bgp_aggregate *bgp_aggregate;
12464 char buf[SU_ADDRSTRLEN];
12465
12466 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
12467 bgp_config_write_network_vpn(vty, bgp, afi, safi);
12468 return;
12469 }
12470
12471 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12472 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12473 return;
12474 }
12475
12476 /* Network configuration. */
12477 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12478 rn = bgp_route_next(rn)) {
12479 bgp_static = bgp_node_get_bgp_static_info(rn);
12480 if (bgp_static == NULL)
12481 continue;
12482
12483 p = &rn->p;
12484
12485 vty_out(vty, " network %s/%d",
12486 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12487 p->prefixlen);
12488
12489 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12490 vty_out(vty, " label-index %u",
12491 bgp_static->label_index);
12492
12493 if (bgp_static->rmap.name)
12494 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12495
12496 if (bgp_static->backdoor)
12497 vty_out(vty, " backdoor");
12498
12499 vty_out(vty, "\n");
12500 }
12501
12502 /* Aggregate-address configuration. */
12503 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12504 rn = bgp_route_next(rn)) {
12505 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12506 if (bgp_aggregate == NULL)
12507 continue;
12508
12509 p = &rn->p;
12510
12511 vty_out(vty, " aggregate-address %s/%d",
12512 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12513 p->prefixlen);
12514
12515 if (bgp_aggregate->as_set)
12516 vty_out(vty, " as-set");
12517
12518 if (bgp_aggregate->summary_only)
12519 vty_out(vty, " summary-only");
12520
12521 if (bgp_aggregate->rmap.name)
12522 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
12523
12524 vty_out(vty, "\n");
12525 }
12526 }
12527
12528 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12529 safi_t safi)
12530 {
12531 struct bgp_node *rn;
12532 struct bgp_distance *bdistance;
12533
12534 /* Distance configuration. */
12535 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12536 && bgp->distance_local[afi][safi]
12537 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12538 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12539 || bgp->distance_local[afi][safi]
12540 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12541 vty_out(vty, " distance bgp %d %d %d\n",
12542 bgp->distance_ebgp[afi][safi],
12543 bgp->distance_ibgp[afi][safi],
12544 bgp->distance_local[afi][safi]);
12545 }
12546
12547 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12548 rn = bgp_route_next(rn)) {
12549 bdistance = bgp_node_get_bgp_distance_info(rn);
12550 if (bdistance != NULL) {
12551 char buf[PREFIX_STRLEN];
12552
12553 vty_out(vty, " distance %d %s %s\n",
12554 bdistance->distance,
12555 prefix2str(&rn->p, buf, sizeof(buf)),
12556 bdistance->access_list ? bdistance->access_list
12557 : "");
12558 }
12559 }
12560 }
12561
12562 /* Allocate routing table structure and install commands. */
12563 void bgp_route_init(void)
12564 {
12565 afi_t afi;
12566 safi_t safi;
12567
12568 /* Init BGP distance table. */
12569 FOREACH_AFI_SAFI (afi, safi)
12570 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12571
12572 /* IPv4 BGP commands. */
12573 install_element(BGP_NODE, &bgp_table_map_cmd);
12574 install_element(BGP_NODE, &bgp_network_cmd);
12575 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12576
12577 install_element(BGP_NODE, &aggregate_address_cmd);
12578 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12579 install_element(BGP_NODE, &no_aggregate_address_cmd);
12580 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12581
12582 /* IPv4 unicast configuration. */
12583 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12584 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12585 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12586
12587 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12588 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12589 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12590 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12591
12592 /* IPv4 multicast configuration. */
12593 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12594 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12595 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12596 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12597 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12598 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12599 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12600
12601 /* IPv4 labeled-unicast configuration. */
12602 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12603 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12604 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12605 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12606 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12607
12608 install_element(VIEW_NODE,
12609 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12610 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12611 install_element(VIEW_NODE,
12612 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
12613 #ifdef KEEP_OLD_VPN_COMMANDS
12614 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
12615 #endif /* KEEP_OLD_VPN_COMMANDS */
12616 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
12617 install_element(VIEW_NODE,
12618 &show_bgp_l2vpn_evpn_route_prefix_cmd);
12619
12620 /* BGP dampening clear commands */
12621 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
12622 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
12623
12624 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
12625 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
12626
12627 /* prefix count */
12628 install_element(ENABLE_NODE,
12629 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
12630 #ifdef KEEP_OLD_VPN_COMMANDS
12631 install_element(ENABLE_NODE,
12632 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
12633 #endif /* KEEP_OLD_VPN_COMMANDS */
12634
12635 /* New config IPv6 BGP commands. */
12636 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
12637 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
12638 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
12639
12640 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
12641 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
12642
12643 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
12644
12645 install_element(BGP_NODE, &bgp_distance_cmd);
12646 install_element(BGP_NODE, &no_bgp_distance_cmd);
12647 install_element(BGP_NODE, &bgp_distance_source_cmd);
12648 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
12649 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
12650 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
12651 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
12652 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
12653 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
12654 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
12655 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
12656 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
12657 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
12658 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
12659 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
12660 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
12661 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
12662 install_element(BGP_IPV4M_NODE,
12663 &no_bgp_distance_source_access_list_cmd);
12664 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
12665 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
12666 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
12667 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
12668 install_element(BGP_IPV6_NODE,
12669 &ipv6_bgp_distance_source_access_list_cmd);
12670 install_element(BGP_IPV6_NODE,
12671 &no_ipv6_bgp_distance_source_access_list_cmd);
12672 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
12673 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
12674 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
12675 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
12676 install_element(BGP_IPV6M_NODE,
12677 &ipv6_bgp_distance_source_access_list_cmd);
12678 install_element(BGP_IPV6M_NODE,
12679 &no_ipv6_bgp_distance_source_access_list_cmd);
12680
12681 install_element(BGP_NODE, &bgp_damp_set_cmd);
12682 install_element(BGP_NODE, &bgp_damp_unset_cmd);
12683 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
12684 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
12685
12686 /* IPv4 Multicast Mode */
12687 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
12688 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
12689
12690 /* Large Communities */
12691 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
12692 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
12693
12694 /* show bgp ipv4 flowspec detailed */
12695 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
12696
12697 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
12698 }
12699
12700 void bgp_route_finish(void)
12701 {
12702 afi_t afi;
12703 safi_t safi;
12704
12705 FOREACH_AFI_SAFI (afi, safi) {
12706 bgp_table_unlock(bgp_distance_table[afi][safi]);
12707 bgp_distance_table[afi][safi] = NULL;
12708 }
12709 }