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