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