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