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