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