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