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