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