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