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