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