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