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