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