]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #2057 from donaldsharp/fix_1916
[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 %u",
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 if (attr->nexthop.s_addr != 0) {
6549 if (json_paths) {
6550 json_nexthop_global = json_object_new_object();
6551 json_object_string_add(
6552 json_nexthop_global, "ip",
6553 inet_ntoa(attr->nexthop));
6554 json_object_string_add(json_nexthop_global,
6555 "afi", "ipv4");
6556 json_object_boolean_true_add(json_nexthop_global,
6557 "used");
6558 } else {
6559 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6560 }
6561 }
6562 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6563 if (json_paths) {
6564 json_nexthop_global = json_object_new_object();
6565
6566 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6567 json_object_string_add(
6568 json_nexthop_global, "ip",
6569 inet_ntoa(attr->mp_nexthop_global_in));
6570 else
6571 json_object_string_add(
6572 json_nexthop_global, "ip",
6573 inet_ntoa(attr->nexthop));
6574
6575 json_object_string_add(json_nexthop_global, "afi",
6576 "ipv4");
6577 json_object_boolean_true_add(json_nexthop_global,
6578 "used");
6579 } else {
6580 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6581 vty_out(vty, "%-16s",
6582 inet_ntoa(attr->mp_nexthop_global_in));
6583 else
6584 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6585 }
6586 }
6587
6588 /* IPv6 Next Hop */
6589 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6590 int len;
6591 char buf[BUFSIZ];
6592
6593 if (json_paths) {
6594 json_nexthop_global = json_object_new_object();
6595 json_object_string_add(
6596 json_nexthop_global, "ip",
6597 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
6598 buf, BUFSIZ));
6599 json_object_string_add(json_nexthop_global, "afi",
6600 "ipv6");
6601 json_object_string_add(json_nexthop_global, "scope",
6602 "global");
6603
6604 /* We display both LL & GL if both have been
6605 * received */
6606 if ((attr->mp_nexthop_len == 32)
6607 || (binfo->peer->conf_if)) {
6608 json_nexthop_ll = json_object_new_object();
6609 json_object_string_add(
6610 json_nexthop_ll, "ip",
6611 inet_ntop(AF_INET6,
6612 &attr->mp_nexthop_local, buf,
6613 BUFSIZ));
6614 json_object_string_add(json_nexthop_ll, "afi",
6615 "ipv6");
6616 json_object_string_add(json_nexthop_ll, "scope",
6617 "link-local");
6618
6619 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
6620 &attr->mp_nexthop_local)
6621 != 0)
6622 && !attr->mp_nexthop_prefer_global)
6623 json_object_boolean_true_add(
6624 json_nexthop_ll, "used");
6625 else
6626 json_object_boolean_true_add(
6627 json_nexthop_global, "used");
6628 } else
6629 json_object_boolean_true_add(
6630 json_nexthop_global, "used");
6631 } else {
6632 /* Display LL if LL/Global both in table unless
6633 * prefer-global is set */
6634 if (((attr->mp_nexthop_len == 32)
6635 && !attr->mp_nexthop_prefer_global)
6636 || (binfo->peer->conf_if)) {
6637 if (binfo->peer->conf_if) {
6638 len = vty_out(vty, "%s",
6639 binfo->peer->conf_if);
6640 len = 16 - len; /* len of IPv6
6641 addr + max
6642 len of def
6643 ifname */
6644
6645 if (len < 1)
6646 vty_out(vty, "\n%*s", 36, " ");
6647 else
6648 vty_out(vty, "%*s", len, " ");
6649 } else {
6650 len = vty_out(
6651 vty, "%s",
6652 inet_ntop(
6653 AF_INET6,
6654 &attr->mp_nexthop_local,
6655 buf, BUFSIZ));
6656 len = 16 - len;
6657
6658 if (len < 1)
6659 vty_out(vty, "\n%*s", 36, " ");
6660 else
6661 vty_out(vty, "%*s", len, " ");
6662 }
6663 } else {
6664 len = vty_out(
6665 vty, "%s",
6666 inet_ntop(AF_INET6,
6667 &attr->mp_nexthop_global, buf,
6668 BUFSIZ));
6669 len = 16 - len;
6670
6671 if (len < 1)
6672 vty_out(vty, "\n%*s", 36, " ");
6673 else
6674 vty_out(vty, "%*s", len, " ");
6675 }
6676 }
6677 }
6678
6679 /* MED/Metric */
6680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6681 if (json_paths)
6682 json_object_int_add(json_path, "med", attr->med);
6683 else
6684 vty_out(vty, "%10u", attr->med);
6685 else if (!json_paths)
6686 vty_out(vty, " ");
6687
6688 /* Local Pref */
6689 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6690 if (json_paths)
6691 json_object_int_add(json_path, "localpref",
6692 attr->local_pref);
6693 else
6694 vty_out(vty, "%7u", attr->local_pref);
6695 else if (!json_paths)
6696 vty_out(vty, " ");
6697
6698 if (json_paths)
6699 json_object_int_add(json_path, "weight", attr->weight);
6700 else
6701 vty_out(vty, "%7u ", attr->weight);
6702
6703 if (json_paths) {
6704 char buf[BUFSIZ];
6705 json_object_string_add(
6706 json_path, "peerId",
6707 sockunion2str(&binfo->peer->su, buf, SU_ADDRSTRLEN));
6708 }
6709
6710 /* Print aspath */
6711 if (attr->aspath) {
6712 if (json_paths)
6713 json_object_string_add(json_path, "aspath",
6714 attr->aspath->str);
6715 else
6716 aspath_print_vty(vty, "%s", attr->aspath, " ");
6717 }
6718
6719 /* Print origin */
6720 if (json_paths)
6721 json_object_string_add(json_path, "origin",
6722 bgp_origin_long_str[attr->origin]);
6723 else
6724 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6725
6726 if (json_paths) {
6727 if (json_nexthop_global || json_nexthop_ll) {
6728 json_nexthops = json_object_new_array();
6729
6730 if (json_nexthop_global)
6731 json_object_array_add(json_nexthops,
6732 json_nexthop_global);
6733
6734 if (json_nexthop_ll)
6735 json_object_array_add(json_nexthops,
6736 json_nexthop_ll);
6737
6738 json_object_object_add(json_path, "nexthops",
6739 json_nexthops);
6740 }
6741
6742 json_object_array_add(json_paths, json_path);
6743 } else {
6744 vty_out(vty, "\n");
6745 #if ENABLE_BGP_VNC
6746 /* prints an additional line, indented, with VNC info, if
6747 * present */
6748 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
6749 rfapi_vty_out_vncinfo(vty, p, binfo, safi);
6750 #endif
6751 }
6752 }
6753
6754 /* called from terminal list command */
6755 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
6756 safi_t safi, uint8_t use_json, json_object *json_ar)
6757 {
6758 json_object *json_status = NULL;
6759 json_object *json_net = NULL;
6760 char buff[BUFSIZ];
6761 /* Route status display. */
6762 if (use_json) {
6763 json_status = json_object_new_object();
6764 json_net = json_object_new_object();
6765 } else {
6766 vty_out(vty, "*");
6767 vty_out(vty, ">");
6768 vty_out(vty, " ");
6769 }
6770
6771 /* print prefix and mask */
6772 if (use_json)
6773 json_object_string_add(
6774 json_net, "addrPrefix",
6775 inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
6776 else
6777 route_vty_out_route(p, vty, NULL);
6778
6779 /* Print attribute */
6780 if (attr) {
6781 if (use_json) {
6782 if (p->family == AF_INET
6783 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6784 || safi == SAFI_EVPN
6785 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6786 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6787 || safi == SAFI_EVPN)
6788 json_object_string_add(
6789 json_net, "nextHop",
6790 inet_ntoa(
6791 attr->mp_nexthop_global_in));
6792 else
6793 json_object_string_add(
6794 json_net, "nextHop",
6795 inet_ntoa(attr->nexthop));
6796 } else if (p->family == AF_INET6
6797 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6798 char buf[BUFSIZ];
6799
6800 json_object_string_add(
6801 json_net, "netHopGloabal",
6802 inet_ntop(AF_INET6,
6803 &attr->mp_nexthop_global, buf,
6804 BUFSIZ));
6805 }
6806
6807 if (attr->flag
6808 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6809 json_object_int_add(json_net, "metric",
6810 attr->med);
6811
6812 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6813 json_object_int_add(json_net, "localPref",
6814 attr->local_pref);
6815
6816 json_object_int_add(json_net, "weight", attr->weight);
6817
6818 /* Print aspath */
6819 if (attr->aspath)
6820 json_object_string_add(json_net, "asPath",
6821 attr->aspath->str);
6822
6823 /* Print origin */
6824 json_object_string_add(json_net, "bgpOriginCode",
6825 bgp_origin_str[attr->origin]);
6826 } else {
6827 if (p->family == AF_INET
6828 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6829 || safi == SAFI_EVPN
6830 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6831 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6832 || safi == SAFI_EVPN)
6833 vty_out(vty, "%-16s",
6834 inet_ntoa(
6835 attr->mp_nexthop_global_in));
6836 else
6837 vty_out(vty, "%-16s",
6838 inet_ntoa(attr->nexthop));
6839 } else if (p->family == AF_INET6
6840 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6841 int len;
6842 char buf[BUFSIZ];
6843
6844 len = vty_out(
6845 vty, "%s",
6846 inet_ntop(AF_INET6,
6847 &attr->mp_nexthop_global, buf,
6848 BUFSIZ));
6849 len = 16 - len;
6850 if (len < 1)
6851 vty_out(vty, "\n%*s", 36, " ");
6852 else
6853 vty_out(vty, "%*s", len, " ");
6854 }
6855 if (attr->flag
6856 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6857 vty_out(vty, "%10u", attr->med);
6858 else
6859 vty_out(vty, " ");
6860
6861 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6862 vty_out(vty, "%7u", attr->local_pref);
6863 else
6864 vty_out(vty, " ");
6865
6866 vty_out(vty, "%7u ", attr->weight);
6867
6868 /* Print aspath */
6869 if (attr->aspath)
6870 aspath_print_vty(vty, "%s", attr->aspath, " ");
6871
6872 /* Print origin */
6873 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6874 }
6875 }
6876 if (use_json) {
6877 json_object_boolean_true_add(json_status, "*");
6878 json_object_boolean_true_add(json_status, ">");
6879 json_object_object_add(json_net, "appliedStatusSymbols",
6880 json_status);
6881 char buf_cut[BUFSIZ];
6882 json_object_object_add(
6883 json_ar,
6884 inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
6885 json_net);
6886 } else
6887 vty_out(vty, "\n");
6888 }
6889
6890 void route_vty_out_tag(struct vty *vty, struct prefix *p,
6891 struct bgp_info *binfo, int display, safi_t safi,
6892 json_object *json)
6893 {
6894 json_object *json_out = NULL;
6895 struct attr *attr;
6896 mpls_label_t label = MPLS_INVALID_LABEL;
6897
6898 if (!binfo->extra)
6899 return;
6900
6901 if (json)
6902 json_out = json_object_new_object();
6903
6904 /* short status lead text */
6905 route_vty_short_status_out(vty, binfo, json_out);
6906
6907 /* print prefix and mask */
6908 if (json == NULL) {
6909 if (!display)
6910 route_vty_out_route(p, vty, NULL);
6911 else
6912 vty_out(vty, "%*s", 17, " ");
6913 }
6914
6915 /* Print attribute */
6916 attr = binfo->attr;
6917 if (attr) {
6918 if (((p->family == AF_INET)
6919 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6920 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6921 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6922 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6923 || safi == SAFI_EVPN) {
6924 if (json)
6925 json_object_string_add(
6926 json_out, "mpNexthopGlobalIn",
6927 inet_ntoa(
6928 attr->mp_nexthop_global_in));
6929 else
6930 vty_out(vty, "%-16s",
6931 inet_ntoa(
6932 attr->mp_nexthop_global_in));
6933 } else {
6934 if (json)
6935 json_object_string_add(
6936 json_out, "nexthop",
6937 inet_ntoa(attr->nexthop));
6938 else
6939 vty_out(vty, "%-16s",
6940 inet_ntoa(attr->nexthop));
6941 }
6942 } else if (((p->family == AF_INET6)
6943 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6944 || (safi == SAFI_EVPN
6945 && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6946 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6947 char buf_a[BUFSIZ];
6948 char buf_b[BUFSIZ];
6949 char buf_c[BUFSIZ];
6950 if (attr->mp_nexthop_len
6951 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
6952 if (json)
6953 json_object_string_add(
6954 json_out, "mpNexthopGlobalIn",
6955 inet_ntop(
6956 AF_INET6,
6957 &attr->mp_nexthop_global,
6958 buf_a, BUFSIZ));
6959 else
6960 vty_out(vty, "%s",
6961 inet_ntop(
6962 AF_INET6,
6963 &attr->mp_nexthop_global,
6964 buf_a, BUFSIZ));
6965 } else if (attr->mp_nexthop_len
6966 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
6967 if (json) {
6968 inet_ntop(AF_INET6,
6969 &attr->mp_nexthop_global,
6970 buf_a, BUFSIZ);
6971 inet_ntop(AF_INET6,
6972 &attr->mp_nexthop_local,
6973 buf_b, BUFSIZ);
6974 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
6975 json_object_string_add(
6976 json_out,
6977 "mpNexthopGlobalLocal", buf_c);
6978 } else
6979 vty_out(vty, "%s(%s)",
6980 inet_ntop(
6981 AF_INET6,
6982 &attr->mp_nexthop_global,
6983 buf_a, BUFSIZ),
6984 inet_ntop(
6985 AF_INET6,
6986 &attr->mp_nexthop_local,
6987 buf_b, BUFSIZ));
6988 }
6989 }
6990 }
6991
6992 label = decode_label(&binfo->extra->label[0]);
6993
6994 if (bgp_is_valid_label(&label)) {
6995 if (json) {
6996 json_object_int_add(json_out, "notag", label);
6997 json_object_array_add(json, json_out);
6998 } else {
6999 vty_out(vty, "notag/%d", label);
7000 vty_out(vty, "\n");
7001 }
7002 }
7003 }
7004
7005 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7006 struct bgp_info *binfo, int display,
7007 json_object *json_paths)
7008 {
7009 struct attr *attr;
7010 char buf[BUFSIZ];
7011 json_object *json_path = NULL;
7012
7013 if (json_paths)
7014 json_path = json_object_new_object();
7015
7016 if (!binfo->extra)
7017 return;
7018
7019 /* short status lead text */
7020 route_vty_short_status_out(vty, binfo, json_path);
7021
7022 /* print prefix and mask */
7023 if (!display)
7024 route_vty_out_route(p, vty, NULL);
7025 else
7026 vty_out(vty, "%*s", 17, " ");
7027
7028 /* Print attribute */
7029 attr = binfo->attr;
7030 if (attr) {
7031 char buf1[BUFSIZ];
7032 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7033
7034 switch (af) {
7035 case AF_INET:
7036 vty_out(vty, "%-16s",
7037 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7038 BUFSIZ));
7039 break;
7040 case AF_INET6:
7041 vty_out(vty, "%s(%s)",
7042 inet_ntop(af, &attr->mp_nexthop_global, buf,
7043 BUFSIZ),
7044 inet_ntop(af, &attr->mp_nexthop_local, buf1,
7045 BUFSIZ));
7046 break;
7047 default:
7048 vty_out(vty, "?");
7049 }
7050
7051 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7052
7053 vty_out(vty, "%s", str);
7054 XFREE(MTYPE_TMP, str);
7055
7056 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)) {
7057 vty_out(vty, "/%s",
7058 inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
7059 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)p)) {
7060 vty_out(vty, "/%s",
7061 inet_ntop(AF_INET6,
7062 &(attr->evpn_overlay.gw_ip.ipv6), buf,
7063 BUFSIZ));
7064 }
7065 if (attr->ecommunity) {
7066 char *mac = NULL;
7067 struct ecommunity_val *routermac = ecommunity_lookup(
7068 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7069 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7070 if (routermac)
7071 mac = ecom_mac2str((char *)routermac->val);
7072 if (mac) {
7073 vty_out(vty, "/%s", (char *)mac);
7074 XFREE(MTYPE_TMP, mac);
7075 }
7076 }
7077 vty_out(vty, "\n");
7078 }
7079
7080 }
7081
7082 /* dampening route */
7083 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7084 struct bgp_info *binfo, int display, safi_t safi,
7085 uint8_t use_json, json_object *json)
7086 {
7087 struct attr *attr;
7088 int len;
7089 char timebuf[BGP_UPTIME_LEN];
7090
7091 /* short status lead text */
7092 route_vty_short_status_out(vty, binfo, json);
7093
7094 /* print prefix and mask */
7095 if (!use_json) {
7096 if (!display)
7097 route_vty_out_route(p, vty, NULL);
7098 else
7099 vty_out(vty, "%*s", 17, " ");
7100 }
7101
7102 len = vty_out(vty, "%s", binfo->peer->host);
7103 len = 17 - len;
7104 if (len < 1) {
7105 if (!use_json)
7106 vty_out(vty, "\n%*s", 34, " ");
7107 } else {
7108 if (use_json)
7109 json_object_int_add(json, "peerHost", len);
7110 else
7111 vty_out(vty, "%*s", len, " ");
7112 }
7113
7114 if (use_json)
7115 bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
7116 use_json, json);
7117 else
7118 vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7119 BGP_UPTIME_LEN,
7120 use_json, json));
7121
7122 /* Print attribute */
7123 attr = binfo->attr;
7124 if (attr) {
7125 /* Print aspath */
7126 if (attr->aspath) {
7127 if (use_json)
7128 json_object_string_add(json, "asPath",
7129 attr->aspath->str);
7130 else
7131 aspath_print_vty(vty, "%s", attr->aspath, " ");
7132 }
7133
7134 /* Print origin */
7135 if (use_json)
7136 json_object_string_add(json, "origin",
7137 bgp_origin_str[attr->origin]);
7138 else
7139 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7140 }
7141 if (!use_json)
7142 vty_out(vty, "\n");
7143 }
7144
7145 /* flap route */
7146 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7147 struct bgp_info *binfo, int display, safi_t safi,
7148 uint8_t use_json, json_object *json)
7149 {
7150 struct attr *attr;
7151 struct bgp_damp_info *bdi;
7152 char timebuf[BGP_UPTIME_LEN];
7153 int len;
7154
7155 if (!binfo->extra)
7156 return;
7157
7158 bdi = binfo->extra->damp_info;
7159
7160 /* short status lead text */
7161 route_vty_short_status_out(vty, binfo, json);
7162
7163 /* print prefix and mask */
7164 if (!use_json) {
7165 if (!display)
7166 route_vty_out_route(p, vty, NULL);
7167 else
7168 vty_out(vty, "%*s", 17, " ");
7169 }
7170
7171 len = vty_out(vty, "%s", binfo->peer->host);
7172 len = 16 - len;
7173 if (len < 1) {
7174 if (!use_json)
7175 vty_out(vty, "\n%*s", 33, " ");
7176 } else {
7177 if (use_json)
7178 json_object_int_add(json, "peerHost", len);
7179 else
7180 vty_out(vty, "%*s", len, " ");
7181 }
7182
7183 len = vty_out(vty, "%d", bdi->flap);
7184 len = 5 - len;
7185 if (len < 1) {
7186 if (!use_json)
7187 vty_out(vty, " ");
7188 } else {
7189 if (use_json)
7190 json_object_int_add(json, "bdiFlap", len);
7191 else
7192 vty_out(vty, "%*s", len, " ");
7193 }
7194
7195 if (use_json)
7196 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
7197 json);
7198 else
7199 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
7200 BGP_UPTIME_LEN, 0, NULL));
7201
7202 if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
7203 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7204 if (use_json)
7205 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7206 BGP_UPTIME_LEN, use_json, json);
7207 else
7208 vty_out(vty, "%s ",
7209 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7210 BGP_UPTIME_LEN,
7211 use_json, json));
7212 } else {
7213 if (!use_json)
7214 vty_out(vty, "%*s ", 8, " ");
7215 }
7216
7217 /* Print attribute */
7218 attr = binfo->attr;
7219 if (attr) {
7220 /* Print aspath */
7221 if (attr->aspath) {
7222 if (use_json)
7223 json_object_string_add(json, "asPath",
7224 attr->aspath->str);
7225 else
7226 aspath_print_vty(vty, "%s", attr->aspath, " ");
7227 }
7228
7229 /* Print origin */
7230 if (use_json)
7231 json_object_string_add(json, "origin",
7232 bgp_origin_str[attr->origin]);
7233 else
7234 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7235 }
7236 if (!use_json)
7237 vty_out(vty, "\n");
7238 }
7239
7240 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
7241 int *first, const char *header,
7242 json_object *json_adv_to)
7243 {
7244 char buf1[INET6_ADDRSTRLEN];
7245 json_object *json_peer = NULL;
7246
7247 if (json_adv_to) {
7248 /* 'advertised-to' is a dictionary of peers we have advertised
7249 * this
7250 * prefix too. The key is the peer's IP or swpX, the value is
7251 * the
7252 * hostname if we know it and "" if not.
7253 */
7254 json_peer = json_object_new_object();
7255
7256 if (peer->hostname)
7257 json_object_string_add(json_peer, "hostname",
7258 peer->hostname);
7259
7260 if (peer->conf_if)
7261 json_object_object_add(json_adv_to, peer->conf_if,
7262 json_peer);
7263 else
7264 json_object_object_add(
7265 json_adv_to,
7266 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
7267 json_peer);
7268 } else {
7269 if (*first) {
7270 vty_out(vty, "%s", header);
7271 *first = 0;
7272 }
7273
7274 if (peer->hostname
7275 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
7276 if (peer->conf_if)
7277 vty_out(vty, " %s(%s)", peer->hostname,
7278 peer->conf_if);
7279 else
7280 vty_out(vty, " %s(%s)", peer->hostname,
7281 sockunion2str(&peer->su, buf1,
7282 SU_ADDRSTRLEN));
7283 } else {
7284 if (peer->conf_if)
7285 vty_out(vty, " %s", peer->conf_if);
7286 else
7287 vty_out(vty, " %s",
7288 sockunion2str(&peer->su, buf1,
7289 SU_ADDRSTRLEN));
7290 }
7291 }
7292 }
7293
7294 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
7295 struct bgp_info *binfo, afi_t afi, safi_t safi,
7296 json_object *json_paths)
7297 {
7298 char buf[INET6_ADDRSTRLEN];
7299 char buf1[BUFSIZ];
7300 #if defined(HAVE_CUMULUS)
7301 char buf2[EVPN_ROUTE_STRLEN];
7302 #endif
7303 struct attr *attr;
7304 int sockunion_vty_out(struct vty *, union sockunion *);
7305 time_t tbuf;
7306 json_object *json_bestpath = NULL;
7307 json_object *json_cluster_list = NULL;
7308 json_object *json_cluster_list_list = NULL;
7309 json_object *json_ext_community = NULL;
7310 json_object *json_lcommunity = NULL;
7311 json_object *json_last_update = NULL;
7312 json_object *json_pmsi = NULL;
7313 json_object *json_nexthop_global = NULL;
7314 json_object *json_nexthop_ll = NULL;
7315 json_object *json_nexthops = NULL;
7316 json_object *json_path = NULL;
7317 json_object *json_peer = NULL;
7318 json_object *json_string = NULL;
7319 json_object *json_adv_to = NULL;
7320 int first = 0;
7321 struct listnode *node, *nnode;
7322 struct peer *peer;
7323 int addpath_capable;
7324 int has_adj;
7325 unsigned int first_as;
7326
7327 if (json_paths) {
7328 json_path = json_object_new_object();
7329 json_peer = json_object_new_object();
7330 json_nexthop_global = json_object_new_object();
7331 }
7332
7333 #if defined(HAVE_CUMULUS)
7334 if (!json_paths && safi == SAFI_EVPN) {
7335 char tag_buf[30];
7336
7337 bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
7338 vty_out(vty, " Route %s", buf2);
7339 tag_buf[0] = '\0';
7340 if (binfo->extra && binfo->extra->num_labels) {
7341 bgp_evpn_label2str(binfo->extra->label,
7342 binfo->extra->num_labels, tag_buf,
7343 sizeof(tag_buf));
7344 vty_out(vty, " VNI %s", tag_buf);
7345 }
7346 vty_out(vty, "\n");
7347 if (binfo->extra && binfo->extra->parent) {
7348 struct bgp_info *parent_ri;
7349 struct bgp_node *rn, *prn;
7350
7351 parent_ri = (struct bgp_info *)binfo->extra->parent;
7352 rn = parent_ri->net;
7353 if (rn && rn->prn) {
7354 prn = rn->prn;
7355 vty_out(vty, " Imported from %s:%s\n",
7356 prefix_rd2str(
7357 (struct prefix_rd *)&prn->p,
7358 buf1, sizeof(buf1)),
7359 buf2);
7360 }
7361 }
7362 }
7363 #endif
7364
7365 attr = binfo->attr;
7366
7367 if (attr) {
7368 /* Line1 display AS-path, Aggregator */
7369 if (attr->aspath) {
7370 if (json_paths) {
7371 if (!attr->aspath->json)
7372 aspath_str_update(attr->aspath, true);
7373 json_object_lock(attr->aspath->json);
7374 json_object_object_add(json_path, "aspath",
7375 attr->aspath->json);
7376 } else {
7377 if (attr->aspath->segments)
7378 aspath_print_vty(vty, " %s",
7379 attr->aspath, "");
7380 else
7381 vty_out(vty, " Local");
7382 }
7383 }
7384
7385 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED)) {
7386 if (json_paths)
7387 json_object_boolean_true_add(json_path,
7388 "removed");
7389 else
7390 vty_out(vty, ", (removed)");
7391 }
7392
7393 if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE)) {
7394 if (json_paths)
7395 json_object_boolean_true_add(json_path,
7396 "stale");
7397 else
7398 vty_out(vty, ", (stale)");
7399 }
7400
7401 if (CHECK_FLAG(attr->flag,
7402 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
7403 if (json_paths) {
7404 json_object_int_add(json_path, "aggregatorAs",
7405 attr->aggregator_as);
7406 json_object_string_add(
7407 json_path, "aggregatorId",
7408 inet_ntoa(attr->aggregator_addr));
7409 } else {
7410 vty_out(vty, ", (aggregated by %u %s)",
7411 attr->aggregator_as,
7412 inet_ntoa(attr->aggregator_addr));
7413 }
7414 }
7415
7416 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7417 PEER_FLAG_REFLECTOR_CLIENT)) {
7418 if (json_paths)
7419 json_object_boolean_true_add(
7420 json_path, "rxedFromRrClient");
7421 else
7422 vty_out(vty, ", (Received from a RR-client)");
7423 }
7424
7425 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7426 PEER_FLAG_RSERVER_CLIENT)) {
7427 if (json_paths)
7428 json_object_boolean_true_add(
7429 json_path, "rxedFromRsClient");
7430 else
7431 vty_out(vty, ", (Received from a RS-client)");
7432 }
7433
7434 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7435 if (json_paths)
7436 json_object_boolean_true_add(
7437 json_path, "dampeningHistoryEntry");
7438 else
7439 vty_out(vty, ", (history entry)");
7440 } else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
7441 if (json_paths)
7442 json_object_boolean_true_add(
7443 json_path, "dampeningSuppressed");
7444 else
7445 vty_out(vty, ", (suppressed due to dampening)");
7446 }
7447
7448 if (!json_paths)
7449 vty_out(vty, "\n");
7450
7451 /* Line2 display Next-hop, Neighbor, Router-id */
7452 /* Display the nexthop */
7453 if ((p->family == AF_INET || p->family == AF_ETHERNET
7454 || p->family == AF_EVPN)
7455 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7456 || safi == SAFI_EVPN
7457 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7458 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7459 || safi == SAFI_EVPN) {
7460 if (json_paths)
7461 json_object_string_add(
7462 json_nexthop_global, "ip",
7463 inet_ntoa(
7464 attr->mp_nexthop_global_in));
7465 else
7466 vty_out(vty, " %s",
7467 inet_ntoa(
7468 attr->mp_nexthop_global_in));
7469 } else {
7470 if (json_paths)
7471 json_object_string_add(
7472 json_nexthop_global, "ip",
7473 inet_ntoa(attr->nexthop));
7474 else
7475 vty_out(vty, " %s",
7476 inet_ntoa(attr->nexthop));
7477 }
7478
7479 if (json_paths)
7480 json_object_string_add(json_nexthop_global,
7481 "afi", "ipv4");
7482 } else {
7483 if (json_paths) {
7484 json_object_string_add(
7485 json_nexthop_global, "ip",
7486 inet_ntop(AF_INET6,
7487 &attr->mp_nexthop_global, buf,
7488 INET6_ADDRSTRLEN));
7489 json_object_string_add(json_nexthop_global,
7490 "afi", "ipv6");
7491 json_object_string_add(json_nexthop_global,
7492 "scope", "global");
7493 } else {
7494 vty_out(vty, " %s",
7495 inet_ntop(AF_INET6,
7496 &attr->mp_nexthop_global, buf,
7497 INET6_ADDRSTRLEN));
7498 }
7499 }
7500
7501 /* Display the IGP cost or 'inaccessible' */
7502 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7503 if (json_paths)
7504 json_object_boolean_false_add(
7505 json_nexthop_global, "accessible");
7506 else
7507 vty_out(vty, " (inaccessible)");
7508 } else {
7509 if (binfo->extra && binfo->extra->igpmetric) {
7510 if (json_paths)
7511 json_object_int_add(
7512 json_nexthop_global, "metric",
7513 binfo->extra->igpmetric);
7514 else
7515 vty_out(vty, " (metric %u)",
7516 binfo->extra->igpmetric);
7517 }
7518
7519 /* IGP cost is 0, display this only for json */
7520 else {
7521 if (json_paths)
7522 json_object_int_add(json_nexthop_global,
7523 "metric", 0);
7524 }
7525
7526 if (json_paths)
7527 json_object_boolean_true_add(
7528 json_nexthop_global, "accessible");
7529 }
7530
7531 /* Display peer "from" output */
7532 /* This path was originated locally */
7533 if (binfo->peer == bgp->peer_self) {
7534
7535 if (safi == SAFI_EVPN
7536 || (p->family == AF_INET
7537 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7538 if (json_paths)
7539 json_object_string_add(
7540 json_peer, "peerId", "0.0.0.0");
7541 else
7542 vty_out(vty, " from 0.0.0.0 ");
7543 } else {
7544 if (json_paths)
7545 json_object_string_add(json_peer,
7546 "peerId", "::");
7547 else
7548 vty_out(vty, " from :: ");
7549 }
7550
7551 if (json_paths)
7552 json_object_string_add(
7553 json_peer, "routerId",
7554 inet_ntoa(bgp->router_id));
7555 else
7556 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
7557 }
7558
7559 /* We RXed this path from one of our peers */
7560 else {
7561
7562 if (json_paths) {
7563 json_object_string_add(
7564 json_peer, "peerId",
7565 sockunion2str(&binfo->peer->su, buf,
7566 SU_ADDRSTRLEN));
7567 json_object_string_add(
7568 json_peer, "routerId",
7569 inet_ntop(AF_INET,
7570 &binfo->peer->remote_id, buf1,
7571 sizeof(buf1)));
7572
7573 if (binfo->peer->hostname)
7574 json_object_string_add(
7575 json_peer, "hostname",
7576 binfo->peer->hostname);
7577
7578 if (binfo->peer->domainname)
7579 json_object_string_add(
7580 json_peer, "domainname",
7581 binfo->peer->domainname);
7582
7583 if (binfo->peer->conf_if)
7584 json_object_string_add(
7585 json_peer, "interface",
7586 binfo->peer->conf_if);
7587 } else {
7588 if (binfo->peer->conf_if) {
7589 if (binfo->peer->hostname
7590 && bgp_flag_check(
7591 binfo->peer->bgp,
7592 BGP_FLAG_SHOW_HOSTNAME))
7593 vty_out(vty, " from %s(%s)",
7594 binfo->peer->hostname,
7595 binfo->peer->conf_if);
7596 else
7597 vty_out(vty, " from %s",
7598 binfo->peer->conf_if);
7599 } else {
7600 if (binfo->peer->hostname
7601 && bgp_flag_check(
7602 binfo->peer->bgp,
7603 BGP_FLAG_SHOW_HOSTNAME))
7604 vty_out(vty, " from %s(%s)",
7605 binfo->peer->hostname,
7606 binfo->peer->host);
7607 else
7608 vty_out(vty, " from %s",
7609 sockunion2str(
7610 &binfo->peer
7611 ->su,
7612 buf,
7613 SU_ADDRSTRLEN));
7614 }
7615
7616 if (attr->flag
7617 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7618 vty_out(vty, " (%s)",
7619 inet_ntoa(attr->originator_id));
7620 else
7621 vty_out(vty, " (%s)",
7622 inet_ntop(
7623 AF_INET,
7624 &binfo->peer->remote_id,
7625 buf1, sizeof(buf1)));
7626 }
7627 }
7628
7629 if (!json_paths)
7630 vty_out(vty, "\n");
7631
7632 /* display the link-local nexthop */
7633 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7634 if (json_paths) {
7635 json_nexthop_ll = json_object_new_object();
7636 json_object_string_add(
7637 json_nexthop_ll, "ip",
7638 inet_ntop(AF_INET6,
7639 &attr->mp_nexthop_local, buf,
7640 INET6_ADDRSTRLEN));
7641 json_object_string_add(json_nexthop_ll, "afi",
7642 "ipv6");
7643 json_object_string_add(json_nexthop_ll, "scope",
7644 "link-local");
7645
7646 json_object_boolean_true_add(json_nexthop_ll,
7647 "accessible");
7648
7649 if (!attr->mp_nexthop_prefer_global)
7650 json_object_boolean_true_add(
7651 json_nexthop_ll, "used");
7652 else
7653 json_object_boolean_true_add(
7654 json_nexthop_global, "used");
7655 } else {
7656 vty_out(vty, " (%s) %s\n",
7657 inet_ntop(AF_INET6,
7658 &attr->mp_nexthop_local, buf,
7659 INET6_ADDRSTRLEN),
7660 attr->mp_nexthop_prefer_global
7661 ? "(prefer-global)"
7662 : "(used)");
7663 }
7664 }
7665 /* If we do not have a link-local nexthop then we must flag the
7666 global as "used" */
7667 else {
7668 if (json_paths)
7669 json_object_boolean_true_add(
7670 json_nexthop_global, "used");
7671 }
7672
7673 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7674 * Int/Ext/Local, Atomic, best */
7675 if (json_paths)
7676 json_object_string_add(
7677 json_path, "origin",
7678 bgp_origin_long_str[attr->origin]);
7679 else
7680 vty_out(vty, " Origin %s",
7681 bgp_origin_long_str[attr->origin]);
7682
7683 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
7684 if (json_paths)
7685 json_object_int_add(json_path, "med",
7686 attr->med);
7687 else
7688 vty_out(vty, ", metric %u", attr->med);
7689 }
7690
7691 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7692 if (json_paths)
7693 json_object_int_add(json_path, "localpref",
7694 attr->local_pref);
7695 else
7696 vty_out(vty, ", localpref %u",
7697 attr->local_pref);
7698 } else {
7699 if (json_paths)
7700 json_object_int_add(json_path, "localpref",
7701 bgp->default_local_pref);
7702 else
7703 vty_out(vty, ", localpref %u",
7704 bgp->default_local_pref);
7705 }
7706
7707 if (attr->weight != 0) {
7708 if (json_paths)
7709 json_object_int_add(json_path, "weight",
7710 attr->weight);
7711 else
7712 vty_out(vty, ", weight %u", attr->weight);
7713 }
7714
7715 if (attr->tag != 0) {
7716 if (json_paths)
7717 json_object_int_add(json_path, "tag",
7718 attr->tag);
7719 else
7720 vty_out(vty, ", tag %" ROUTE_TAG_PRI,
7721 attr->tag);
7722 }
7723
7724 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7725 if (json_paths)
7726 json_object_boolean_false_add(json_path,
7727 "valid");
7728 else
7729 vty_out(vty, ", invalid");
7730 } else if (!CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7731 if (json_paths)
7732 json_object_boolean_true_add(json_path,
7733 "valid");
7734 else
7735 vty_out(vty, ", valid");
7736 }
7737
7738 if (binfo->peer != bgp->peer_self) {
7739 if (binfo->peer->as == binfo->peer->local_as) {
7740 if (CHECK_FLAG(bgp->config,
7741 BGP_CONFIG_CONFEDERATION)) {
7742 if (json_paths)
7743 json_object_string_add(
7744 json_peer, "type",
7745 "confed-internal");
7746 else
7747 vty_out(vty,
7748 ", confed-internal");
7749 } else {
7750 if (json_paths)
7751 json_object_string_add(
7752 json_peer, "type",
7753 "internal");
7754 else
7755 vty_out(vty, ", internal");
7756 }
7757 } else {
7758 if (bgp_confederation_peers_check(
7759 bgp, binfo->peer->as)) {
7760 if (json_paths)
7761 json_object_string_add(
7762 json_peer, "type",
7763 "confed-external");
7764 else
7765 vty_out(vty,
7766 ", confed-external");
7767 } else {
7768 if (json_paths)
7769 json_object_string_add(
7770 json_peer, "type",
7771 "external");
7772 else
7773 vty_out(vty, ", external");
7774 }
7775 }
7776 } else if (binfo->sub_type == BGP_ROUTE_AGGREGATE) {
7777 if (json_paths) {
7778 json_object_boolean_true_add(json_path,
7779 "aggregated");
7780 json_object_boolean_true_add(json_path,
7781 "local");
7782 } else {
7783 vty_out(vty, ", aggregated, local");
7784 }
7785 } else if (binfo->type != ZEBRA_ROUTE_BGP) {
7786 if (json_paths)
7787 json_object_boolean_true_add(json_path,
7788 "sourced");
7789 else
7790 vty_out(vty, ", sourced");
7791 } else {
7792 if (json_paths) {
7793 json_object_boolean_true_add(json_path,
7794 "sourced");
7795 json_object_boolean_true_add(json_path,
7796 "local");
7797 } else {
7798 vty_out(vty, ", sourced, local");
7799 }
7800 }
7801
7802 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
7803 if (json_paths)
7804 json_object_boolean_true_add(json_path,
7805 "atomicAggregate");
7806 else
7807 vty_out(vty, ", atomic-aggregate");
7808 }
7809
7810 if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH)
7811 || (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)
7812 && bgp_info_mpath_count(binfo))) {
7813 if (json_paths)
7814 json_object_boolean_true_add(json_path,
7815 "multipath");
7816 else
7817 vty_out(vty, ", multipath");
7818 }
7819
7820 // Mark the bestpath(s)
7821 if (CHECK_FLAG(binfo->flags, BGP_INFO_DMED_SELECTED)) {
7822 first_as = aspath_get_first_as(attr->aspath);
7823
7824 if (json_paths) {
7825 if (!json_bestpath)
7826 json_bestpath =
7827 json_object_new_object();
7828 json_object_int_add(json_bestpath,
7829 "bestpathFromAs", first_as);
7830 } else {
7831 if (first_as)
7832 vty_out(vty, ", bestpath-from-AS %u",
7833 first_as);
7834 else
7835 vty_out(vty,
7836 ", bestpath-from-AS Local");
7837 }
7838 }
7839
7840 if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)) {
7841 if (json_paths) {
7842 if (!json_bestpath)
7843 json_bestpath =
7844 json_object_new_object();
7845 json_object_boolean_true_add(json_bestpath,
7846 "overall");
7847 } else
7848 vty_out(vty, ", best");
7849 }
7850
7851 if (json_bestpath)
7852 json_object_object_add(json_path, "bestpath",
7853 json_bestpath);
7854
7855 if (!json_paths)
7856 vty_out(vty, "\n");
7857
7858 /* Line 4 display Community */
7859 if (attr->community) {
7860 if (json_paths) {
7861 if (!attr->community->json)
7862 community_str(attr->community, true);
7863 json_object_lock(attr->community->json);
7864 json_object_object_add(json_path, "community",
7865 attr->community->json);
7866 } else {
7867 vty_out(vty, " Community: %s\n",
7868 attr->community->str);
7869 }
7870 }
7871
7872 /* Line 5 display Extended-community */
7873 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7874 if (json_paths) {
7875 json_ext_community = json_object_new_object();
7876 json_object_string_add(json_ext_community,
7877 "string",
7878 attr->ecommunity->str);
7879 json_object_object_add(json_path,
7880 "extendedCommunity",
7881 json_ext_community);
7882 } else {
7883 vty_out(vty, " Extended Community: %s\n",
7884 attr->ecommunity->str);
7885 }
7886 }
7887
7888 /* Line 6 display Large community */
7889 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
7890 if (json_paths) {
7891 json_lcommunity = json_object_new_object();
7892 json_object_string_add(json_lcommunity,
7893 "string",
7894 attr->lcommunity->str);
7895 json_object_object_add(json_path,
7896 "largeCommunity",
7897 json_lcommunity);
7898 } else {
7899 vty_out(vty, " Large Community: %s\n",
7900 attr->lcommunity->str);
7901 }
7902 }
7903
7904 /* Line 7 display Originator, Cluster-id */
7905 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7906 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
7907 if (attr->flag
7908 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
7909 if (json_paths)
7910 json_object_string_add(
7911 json_path, "originatorId",
7912 inet_ntoa(attr->originator_id));
7913 else
7914 vty_out(vty, " Originator: %s",
7915 inet_ntoa(attr->originator_id));
7916 }
7917
7918 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
7919 int i;
7920
7921 if (json_paths) {
7922 json_cluster_list =
7923 json_object_new_object();
7924 json_cluster_list_list =
7925 json_object_new_array();
7926
7927 for (i = 0;
7928 i < attr->cluster->length / 4;
7929 i++) {
7930 json_string = json_object_new_string(
7931 inet_ntoa(
7932 attr->cluster->list
7933 [i]));
7934 json_object_array_add(
7935 json_cluster_list_list,
7936 json_string);
7937 }
7938
7939 /* struct cluster_list does not have
7940 "str" variable like
7941 * aspath and community do. Add this
7942 someday if someone
7943 * asks for it.
7944 json_object_string_add(json_cluster_list,
7945 "string", attr->cluster->str);
7946 */
7947 json_object_object_add(
7948 json_cluster_list, "list",
7949 json_cluster_list_list);
7950 json_object_object_add(
7951 json_path, "clusterList",
7952 json_cluster_list);
7953 } else {
7954 vty_out(vty, ", Cluster list: ");
7955
7956 for (i = 0;
7957 i < attr->cluster->length / 4;
7958 i++) {
7959 vty_out(vty, "%s ",
7960 inet_ntoa(
7961 attr->cluster->list
7962 [i]));
7963 }
7964 }
7965 }
7966
7967 if (!json_paths)
7968 vty_out(vty, "\n");
7969 }
7970
7971 if (binfo->extra && binfo->extra->damp_info)
7972 bgp_damp_info_vty(vty, binfo, json_path);
7973
7974 /* Remote Label */
7975 #if defined(HAVE_CUMULUS)
7976 if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])
7977 && safi != SAFI_EVPN)
7978 #else
7979 if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0]))
7980 #endif
7981 {
7982 mpls_label_t label =
7983 label_pton(&binfo->extra->label[0]);
7984 if (json_paths)
7985 json_object_int_add(json_path, "remoteLabel",
7986 label);
7987 else
7988 vty_out(vty, " Remote label: %d\n", label);
7989 }
7990
7991 /* Label Index */
7992 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
7993 if (json_paths)
7994 json_object_int_add(json_path, "labelIndex",
7995 attr->label_index);
7996 else
7997 vty_out(vty, " Label Index: %d\n",
7998 attr->label_index);
7999 }
8000
8001 /* Line 8 display Addpath IDs */
8002 if (binfo->addpath_rx_id || binfo->addpath_tx_id) {
8003 if (json_paths) {
8004 json_object_int_add(json_path, "addpathRxId",
8005 binfo->addpath_rx_id);
8006 json_object_int_add(json_path, "addpathTxId",
8007 binfo->addpath_tx_id);
8008 } else {
8009 vty_out(vty, " AddPath ID: RX %u, TX %u\n",
8010 binfo->addpath_rx_id,
8011 binfo->addpath_tx_id);
8012 }
8013 }
8014
8015 /* If we used addpath to TX a non-bestpath we need to display
8016 * "Advertised to" on a path-by-path basis */
8017 if (bgp->addpath_tx_used[afi][safi]) {
8018 first = 1;
8019
8020 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8021 addpath_capable =
8022 bgp_addpath_encode_tx(peer, afi, safi);
8023 has_adj = bgp_adj_out_lookup(
8024 peer, binfo->net, binfo->addpath_tx_id);
8025
8026 if ((addpath_capable && has_adj)
8027 || (!addpath_capable && has_adj
8028 && CHECK_FLAG(binfo->flags,
8029 BGP_INFO_SELECTED))) {
8030 if (json_path && !json_adv_to)
8031 json_adv_to =
8032 json_object_new_object();
8033
8034 route_vty_out_advertised_to(
8035 vty, peer, &first,
8036 " Advertised to:",
8037 json_adv_to);
8038 }
8039 }
8040
8041 if (json_path) {
8042 if (json_adv_to) {
8043 json_object_object_add(json_path,
8044 "advertisedTo",
8045 json_adv_to);
8046 }
8047 } else {
8048 if (!first) {
8049 vty_out(vty, "\n");
8050 }
8051 }
8052 }
8053
8054 /* Line 9 display Uptime */
8055 tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
8056 if (json_paths) {
8057 json_last_update = json_object_new_object();
8058 json_object_int_add(json_last_update, "epoch", tbuf);
8059 json_object_string_add(json_last_update, "string",
8060 ctime(&tbuf));
8061 json_object_object_add(json_path, "lastUpdate",
8062 json_last_update);
8063 } else
8064 vty_out(vty, " Last update: %s", ctime(&tbuf));
8065
8066 /* Line 10 display PMSI tunnel attribute, if present */
8067 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
8068 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
8069 attr->pmsi_tnl_type,
8070 PMSI_TNLTYPE_STR_DEFAULT);
8071
8072 if (json_paths) {
8073 json_pmsi = json_object_new_object();
8074 json_object_string_add(json_pmsi,
8075 "tunnelType", str);
8076 json_object_object_add(json_path, "pmsi",
8077 json_pmsi);
8078 } else
8079 vty_out(vty, " PMSI Tunnel Type: %s\n",
8080 str);
8081 }
8082
8083 }
8084
8085 /* We've constructed the json object for this path, add it to the json
8086 * array of paths
8087 */
8088 if (json_paths) {
8089 if (json_nexthop_global || json_nexthop_ll) {
8090 json_nexthops = json_object_new_array();
8091
8092 if (json_nexthop_global)
8093 json_object_array_add(json_nexthops,
8094 json_nexthop_global);
8095
8096 if (json_nexthop_ll)
8097 json_object_array_add(json_nexthops,
8098 json_nexthop_ll);
8099
8100 json_object_object_add(json_path, "nexthops",
8101 json_nexthops);
8102 }
8103
8104 json_object_object_add(json_path, "peer", json_peer);
8105 json_object_array_add(json_paths, json_path);
8106 } else
8107 vty_out(vty, "\n");
8108 }
8109
8110 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8111 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8112 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8113
8114 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
8115 const char *prefix_list_str, afi_t afi,
8116 safi_t safi, enum bgp_show_type type);
8117 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
8118 const char *filter, afi_t afi, safi_t safi,
8119 enum bgp_show_type type);
8120 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
8121 const char *rmap_str, afi_t afi, safi_t safi,
8122 enum bgp_show_type type);
8123 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
8124 const char *com, int exact, afi_t afi,
8125 safi_t safi);
8126 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
8127 const char *prefix, afi_t afi, safi_t safi,
8128 enum bgp_show_type type);
8129 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
8130 afi_t afi, safi_t safi, enum bgp_show_type type);
8131 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
8132 const char *comstr, int exact, afi_t afi,
8133 safi_t safi);
8134
8135
8136 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
8137 struct bgp_table *table, enum bgp_show_type type,
8138 void *output_arg, uint8_t use_json, char *rd,
8139 int is_last, unsigned long *output_cum,
8140 unsigned long *total_cum,
8141 unsigned long *json_header_depth)
8142 {
8143 struct bgp_info *ri;
8144 struct bgp_node *rn;
8145 int header = 1;
8146 int display;
8147 unsigned long output_count = 0;
8148 unsigned long total_count = 0;
8149 struct prefix *p;
8150 char buf[BUFSIZ];
8151 char buf2[BUFSIZ];
8152 json_object *json_paths = NULL;
8153 int first = 1;
8154
8155 if (output_cum && *output_cum != 0)
8156 header = 0;
8157
8158 if (use_json && !*json_header_depth) {
8159 vty_out(vty,
8160 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8161 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8162 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
8163 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
8164 : bgp->name,
8165 table->version, inet_ntoa(bgp->router_id));
8166 *json_header_depth = 2;
8167 if (rd) {
8168 vty_out(vty, " \"routeDistinguishers\" : {");
8169 ++*json_header_depth;
8170 }
8171 json_paths = json_object_new_object();
8172 }
8173
8174 if (use_json && rd) {
8175 vty_out(vty, " \"%s\" : { ", rd);
8176 }
8177
8178 /* Start processing of routes. */
8179 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
8180 if (rn->info == NULL)
8181 continue;
8182
8183 display = 0;
8184 if (use_json)
8185 json_paths = json_object_new_array();
8186 else
8187 json_paths = NULL;
8188
8189 for (ri = rn->info; ri; ri = ri->next) {
8190 total_count++;
8191 if (type == bgp_show_type_flap_statistics
8192 || type == bgp_show_type_flap_neighbor
8193 || type == bgp_show_type_dampend_paths
8194 || type == bgp_show_type_damp_neighbor) {
8195 if (!(ri->extra && ri->extra->damp_info))
8196 continue;
8197 }
8198 if (type == bgp_show_type_regexp) {
8199 regex_t *regex = output_arg;
8200
8201 if (bgp_regexec(regex, ri->attr->aspath)
8202 == REG_NOMATCH)
8203 continue;
8204 }
8205 if (type == bgp_show_type_prefix_list) {
8206 struct prefix_list *plist = output_arg;
8207
8208 if (prefix_list_apply(plist, &rn->p)
8209 != PREFIX_PERMIT)
8210 continue;
8211 }
8212 if (type == bgp_show_type_filter_list) {
8213 struct as_list *as_list = output_arg;
8214
8215 if (as_list_apply(as_list, ri->attr->aspath)
8216 != AS_FILTER_PERMIT)
8217 continue;
8218 }
8219 if (type == bgp_show_type_route_map) {
8220 struct route_map *rmap = output_arg;
8221 struct bgp_info binfo;
8222 struct attr dummy_attr;
8223 int ret;
8224
8225 bgp_attr_dup(&dummy_attr, ri->attr);
8226
8227 binfo.peer = ri->peer;
8228 binfo.attr = &dummy_attr;
8229
8230 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
8231 &binfo);
8232 if (ret == RMAP_DENYMATCH)
8233 continue;
8234 }
8235 if (type == bgp_show_type_neighbor
8236 || type == bgp_show_type_flap_neighbor
8237 || type == bgp_show_type_damp_neighbor) {
8238 union sockunion *su = output_arg;
8239
8240 if (ri->peer == NULL
8241 || ri->peer->su_remote == NULL
8242 || !sockunion_same(ri->peer->su_remote, su))
8243 continue;
8244 }
8245 if (type == bgp_show_type_cidr_only) {
8246 uint32_t destination;
8247
8248 destination = ntohl(rn->p.u.prefix4.s_addr);
8249 if (IN_CLASSC(destination)
8250 && rn->p.prefixlen == 24)
8251 continue;
8252 if (IN_CLASSB(destination)
8253 && rn->p.prefixlen == 16)
8254 continue;
8255 if (IN_CLASSA(destination)
8256 && rn->p.prefixlen == 8)
8257 continue;
8258 }
8259 if (type == bgp_show_type_prefix_longer) {
8260 struct prefix *p = output_arg;
8261
8262 if (!prefix_match(p, &rn->p))
8263 continue;
8264 }
8265 if (type == bgp_show_type_community_all) {
8266 if (!ri->attr->community)
8267 continue;
8268 }
8269 if (type == bgp_show_type_community) {
8270 struct community *com = output_arg;
8271
8272 if (!ri->attr->community
8273 || !community_match(ri->attr->community,
8274 com))
8275 continue;
8276 }
8277 if (type == bgp_show_type_community_exact) {
8278 struct community *com = output_arg;
8279
8280 if (!ri->attr->community
8281 || !community_cmp(ri->attr->community, com))
8282 continue;
8283 }
8284 if (type == bgp_show_type_community_list) {
8285 struct community_list *list = output_arg;
8286
8287 if (!community_list_match(ri->attr->community,
8288 list))
8289 continue;
8290 }
8291 if (type == bgp_show_type_community_list_exact) {
8292 struct community_list *list = output_arg;
8293
8294 if (!community_list_exact_match(
8295 ri->attr->community, list))
8296 continue;
8297 }
8298 if (type == bgp_show_type_lcommunity) {
8299 struct lcommunity *lcom = output_arg;
8300
8301 if (!ri->attr->lcommunity
8302 || !lcommunity_match(ri->attr->lcommunity,
8303 lcom))
8304 continue;
8305 }
8306 if (type == bgp_show_type_lcommunity_list) {
8307 struct community_list *list = output_arg;
8308
8309 if (!lcommunity_list_match(ri->attr->lcommunity,
8310 list))
8311 continue;
8312 }
8313 if (type == bgp_show_type_lcommunity_all) {
8314 if (!ri->attr->lcommunity)
8315 continue;
8316 }
8317 if (type == bgp_show_type_dampend_paths
8318 || type == bgp_show_type_damp_neighbor) {
8319 if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED)
8320 || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
8321 continue;
8322 }
8323
8324 if (!use_json && header) {
8325 vty_out(vty, "BGP table version is %" PRIu64
8326 ", local router ID is %s\n",
8327 table->version,
8328 inet_ntoa(bgp->router_id));
8329 vty_out(vty, BGP_SHOW_SCODE_HEADER);
8330 vty_out(vty, BGP_SHOW_OCODE_HEADER);
8331 if (type == bgp_show_type_dampend_paths
8332 || type == bgp_show_type_damp_neighbor)
8333 vty_out(vty, BGP_SHOW_DAMP_HEADER);
8334 else if (type == bgp_show_type_flap_statistics
8335 || type == bgp_show_type_flap_neighbor)
8336 vty_out(vty, BGP_SHOW_FLAP_HEADER);
8337 else
8338 vty_out(vty, BGP_SHOW_HEADER);
8339 header = 0;
8340 }
8341 if (rd != NULL && !display && !output_count) {
8342 if (!use_json)
8343 vty_out(vty,
8344 "Route Distinguisher: %s\n",
8345 rd);
8346 }
8347 if (type == bgp_show_type_dampend_paths
8348 || type == bgp_show_type_damp_neighbor)
8349 damp_route_vty_out(vty, &rn->p, ri, display,
8350 safi, use_json, json_paths);
8351 else if (type == bgp_show_type_flap_statistics
8352 || type == bgp_show_type_flap_neighbor)
8353 flap_route_vty_out(vty, &rn->p, ri, display,
8354 safi, use_json, json_paths);
8355 else
8356 route_vty_out(vty, &rn->p, ri, display, safi,
8357 json_paths);
8358 display++;
8359 }
8360
8361 if (display) {
8362 output_count++;
8363 if (!use_json)
8364 continue;
8365
8366 p = &rn->p;
8367 sprintf(buf2, "%s/%d",
8368 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
8369 p->prefixlen);
8370 if (first)
8371 vty_out(vty, "\"%s\": ", buf2);
8372 else
8373 vty_out(vty, ",\"%s\": ", buf2);
8374
8375 vty_out(vty, "%s",
8376 json_object_to_json_string(json_paths));
8377 json_object_free(json_paths);
8378 json_paths = NULL;
8379 first = 0;
8380 }
8381 }
8382
8383 if (output_cum) {
8384 output_count += *output_cum;
8385 *output_cum = output_count;
8386 }
8387 if (total_cum) {
8388 total_count += *total_cum;
8389 *total_cum = total_count;
8390 }
8391 if (use_json) {
8392 if (json_paths)
8393 json_object_free(json_paths);
8394 if (rd) {
8395 vty_out(vty, " }%s ", (is_last ? "" : ","));
8396 }
8397 if (is_last) {
8398 unsigned long i;
8399 for (i = 0; i < *json_header_depth; ++i)
8400 vty_out(vty, " } ");
8401 }
8402 } else {
8403 if (is_last) {
8404 /* No route is displayed */
8405 if (output_count == 0) {
8406 if (type == bgp_show_type_normal)
8407 vty_out(vty,
8408 "No BGP prefixes displayed, %ld exist\n",
8409 total_count);
8410 } else
8411 vty_out(vty,
8412 "\nDisplayed %ld routes and %ld total paths\n",
8413 output_count, total_count);
8414 }
8415 }
8416
8417 return CMD_SUCCESS;
8418 }
8419
8420 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
8421 struct bgp_table *table, struct prefix_rd *prd_match,
8422 enum bgp_show_type type, void *output_arg,
8423 uint8_t use_json)
8424 {
8425 struct bgp_node *rn, *next;
8426 unsigned long output_cum = 0;
8427 unsigned long total_cum = 0;
8428 unsigned long json_header_depth = 0;
8429 bool show_msg;
8430
8431 show_msg = (!use_json && type == bgp_show_type_normal);
8432
8433 for (rn = bgp_table_top(table); rn; rn = next) {
8434 next = bgp_route_next(rn);
8435 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
8436 continue;
8437 if (rn->info != NULL) {
8438 struct prefix_rd prd;
8439 char rd[RD_ADDRSTRLEN];
8440
8441 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
8442 prefix_rd2str(&prd, rd, sizeof(rd));
8443 bgp_show_table(vty, bgp, safi, rn->info, type,
8444 output_arg, use_json, rd, next == NULL,
8445 &output_cum, &total_cum,
8446 &json_header_depth);
8447 if (next == NULL)
8448 show_msg = false;
8449 }
8450 }
8451 if (show_msg) {
8452 if (output_cum == 0)
8453 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
8454 total_cum);
8455 else
8456 vty_out(vty,
8457 "\nDisplayed %ld routes and %ld total paths\n",
8458 output_cum, total_cum);
8459 }
8460 return CMD_SUCCESS;
8461 }
8462 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
8463 enum bgp_show_type type, void *output_arg, uint8_t use_json)
8464 {
8465 struct bgp_table *table;
8466 unsigned long json_header_depth = 0;
8467
8468 if (bgp == NULL) {
8469 bgp = bgp_get_default();
8470 }
8471
8472 if (bgp == NULL) {
8473 if (!use_json)
8474 vty_out(vty, "No BGP process is configured\n");
8475 else
8476 vty_out(vty, "{}\n");
8477 return CMD_WARNING;
8478 }
8479
8480 table = bgp->rib[afi][safi];
8481 /* use MPLS and ENCAP specific shows until they are merged */
8482 if (safi == SAFI_MPLS_VPN) {
8483 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
8484 output_arg, use_json);
8485 }
8486
8487 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
8488 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
8489 output_arg, use_json,
8490 1, NULL, NULL);
8491 }
8492 /* labeled-unicast routes live in the unicast table */
8493 else if (safi == SAFI_LABELED_UNICAST)
8494 safi = SAFI_UNICAST;
8495
8496 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
8497 NULL, 1, NULL, NULL, &json_header_depth);
8498 }
8499
8500 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
8501 safi_t safi, uint8_t use_json)
8502 {
8503 struct listnode *node, *nnode;
8504 struct bgp *bgp;
8505 int is_first = 1;
8506
8507 if (use_json)
8508 vty_out(vty, "{\n");
8509
8510 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8511 if (use_json) {
8512 if (!is_first)
8513 vty_out(vty, ",\n");
8514 else
8515 is_first = 0;
8516
8517 vty_out(vty, "\"%s\":",
8518 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8519 ? "Default"
8520 : bgp->name);
8521 } else {
8522 vty_out(vty, "\nInstance %s:\n",
8523 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8524 ? "Default"
8525 : bgp->name);
8526 }
8527 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
8528 use_json);
8529 }
8530
8531 if (use_json)
8532 vty_out(vty, "}\n");
8533 }
8534
8535 /* Header of detailed BGP route information */
8536 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
8537 struct bgp_node *rn, struct prefix_rd *prd,
8538 afi_t afi, safi_t safi, json_object *json)
8539 {
8540 struct bgp_info *ri;
8541 struct prefix *p;
8542 struct peer *peer;
8543 struct listnode *node, *nnode;
8544 char buf1[RD_ADDRSTRLEN];
8545 char buf2[INET6_ADDRSTRLEN];
8546 #if defined(HAVE_CUMULUS)
8547 char buf3[EVPN_ROUTE_STRLEN];
8548 #endif
8549 char prefix_str[BUFSIZ];
8550 int count = 0;
8551 int best = 0;
8552 int suppress = 0;
8553 int no_export = 0;
8554 int no_advertise = 0;
8555 int local_as = 0;
8556 int first = 1;
8557 int has_valid_label = 0;
8558 mpls_label_t label = 0;
8559 json_object *json_adv_to = NULL;
8560
8561 p = &rn->p;
8562 has_valid_label = bgp_is_valid_label(&rn->local_label);
8563
8564 if (has_valid_label)
8565 label = label_pton(&rn->local_label);
8566
8567 if (json) {
8568 if (has_valid_label)
8569 json_object_int_add(json, "localLabel", label);
8570
8571 json_object_string_add(
8572 json, "prefix",
8573 prefix2str(p, prefix_str, sizeof(prefix_str)));
8574 } else {
8575 #if defined(HAVE_CUMULUS)
8576 if (safi == SAFI_EVPN)
8577 vty_out(vty, "BGP routing table entry for %s%s%s\n",
8578 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
8579 : "",
8580 prd ? ":" : "",
8581 bgp_evpn_route2str((struct prefix_evpn *)p,
8582 buf3, sizeof(buf3)));
8583 else
8584 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8585 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8586 ? prefix_rd2str(prd, buf1,
8587 sizeof(buf1))
8588 : ""),
8589 safi == SAFI_MPLS_VPN ? ":" : "",
8590 inet_ntop(p->family, &p->u.prefix, buf2,
8591 INET6_ADDRSTRLEN),
8592 p->prefixlen);
8593 #else
8594 if (p->family == AF_ETHERNET)
8595 prefix2str(p, buf2, INET6_ADDRSTRLEN);
8596 else
8597 inet_ntop(p->family, &p->u.prefix, buf2,
8598 INET6_ADDRSTRLEN);
8599 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8600 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8601 || safi == SAFI_EVPN)
8602 ? prefix_rd2str(prd, buf1, sizeof(buf1))
8603 : ""),
8604 ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":"
8605 : "",
8606 buf2, p->prefixlen);
8607 #endif
8608
8609 if (has_valid_label)
8610 vty_out(vty, "Local label: %d\n", label);
8611 #if defined(HAVE_CUMULUS)
8612 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
8613 #else
8614 if (bgp_labeled_safi(safi))
8615 #endif
8616 vty_out(vty, "not allocated\n");
8617 }
8618
8619 for (ri = rn->info; ri; ri = ri->next) {
8620 count++;
8621 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
8622 best = count;
8623 if (ri->extra && ri->extra->suppress)
8624 suppress = 1;
8625 if (ri->attr->community != NULL) {
8626 if (community_include(ri->attr->community,
8627 COMMUNITY_NO_ADVERTISE))
8628 no_advertise = 1;
8629 if (community_include(ri->attr->community,
8630 COMMUNITY_NO_EXPORT))
8631 no_export = 1;
8632 if (community_include(ri->attr->community,
8633 COMMUNITY_LOCAL_AS))
8634 local_as = 1;
8635 }
8636 }
8637 }
8638
8639 if (!json) {
8640 vty_out(vty, "Paths: (%d available", count);
8641 if (best) {
8642 vty_out(vty, ", best #%d", best);
8643 if (safi == SAFI_UNICAST)
8644 vty_out(vty, ", table %s",
8645 (bgp->inst_type
8646 == BGP_INSTANCE_TYPE_DEFAULT)
8647 ? "Default-IP-Routing-Table"
8648 : bgp->name);
8649 } else
8650 vty_out(vty, ", no best path");
8651
8652 if (no_advertise)
8653 vty_out(vty, ", not advertised to any peer");
8654 else if (no_export)
8655 vty_out(vty, ", not advertised to EBGP peer");
8656 else if (local_as)
8657 vty_out(vty, ", not advertised outside local AS");
8658
8659 if (suppress)
8660 vty_out(vty,
8661 ", Advertisements suppressed by an aggregate.");
8662 vty_out(vty, ")\n");
8663 }
8664
8665 /* If we are not using addpath then we can display Advertised to and
8666 * that will
8667 * show what peers we advertised the bestpath to. If we are using
8668 * addpath
8669 * though then we must display Advertised to on a path-by-path basis. */
8670 if (!bgp->addpath_tx_used[afi][safi]) {
8671 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8672 if (bgp_adj_out_lookup(peer, rn, 0)) {
8673 if (json && !json_adv_to)
8674 json_adv_to = json_object_new_object();
8675
8676 route_vty_out_advertised_to(
8677 vty, peer, &first,
8678 " Advertised to non peer-group peers:\n ",
8679 json_adv_to);
8680 }
8681 }
8682
8683 if (json) {
8684 if (json_adv_to) {
8685 json_object_object_add(json, "advertisedTo",
8686 json_adv_to);
8687 }
8688 } else {
8689 if (first)
8690 vty_out(vty, " Not advertised to any peer");
8691 vty_out(vty, "\n");
8692 }
8693 }
8694 }
8695
8696 /* Display specified route of BGP table. */
8697 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
8698 struct bgp_table *rib, const char *ip_str,
8699 afi_t afi, safi_t safi,
8700 struct prefix_rd *prd, int prefix_check,
8701 enum bgp_path_type pathtype,
8702 uint8_t use_json)
8703 {
8704 int ret;
8705 int header;
8706 int display = 0;
8707 struct prefix match;
8708 struct bgp_node *rn;
8709 struct bgp_node *rm;
8710 struct bgp_info *ri;
8711 struct bgp_table *table;
8712 json_object *json = NULL;
8713 json_object *json_paths = NULL;
8714
8715 /* Check IP address argument. */
8716 ret = str2prefix(ip_str, &match);
8717 if (!ret) {
8718 vty_out(vty, "address is malformed\n");
8719 return CMD_WARNING;
8720 }
8721
8722 match.family = afi2family(afi);
8723
8724 if (use_json) {
8725 json = json_object_new_object();
8726 json_paths = json_object_new_array();
8727 }
8728
8729 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
8730 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
8731 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
8732 continue;
8733
8734 if ((table = rn->info) == NULL)
8735 continue;
8736
8737 header = 1;
8738
8739 if ((rm = bgp_node_match(table, &match)) == NULL)
8740 continue;
8741
8742 if (prefix_check
8743 && rm->p.prefixlen != match.prefixlen) {
8744 bgp_unlock_node(rm);
8745 continue;
8746 }
8747
8748 for (ri = rm->info; ri; ri = ri->next) {
8749 if (header) {
8750 route_vty_out_detail_header(
8751 vty, bgp, rm,
8752 (struct prefix_rd *)&rn->p,
8753 AFI_IP, safi, json);
8754 header = 0;
8755 }
8756 display++;
8757
8758 if (pathtype == BGP_PATH_ALL
8759 || (pathtype == BGP_PATH_BESTPATH
8760 && CHECK_FLAG(ri->flags,
8761 BGP_INFO_SELECTED))
8762 || (pathtype == BGP_PATH_MULTIPATH
8763 && (CHECK_FLAG(ri->flags,
8764 BGP_INFO_MULTIPATH)
8765 || CHECK_FLAG(ri->flags,
8766 BGP_INFO_SELECTED))))
8767 route_vty_out_detail(vty, bgp, &rm->p,
8768 ri, AFI_IP, safi,
8769 json_paths);
8770 }
8771
8772 bgp_unlock_node(rm);
8773 }
8774 } else if (safi == SAFI_FLOWSPEC) {
8775 rn = bgp_flowspec_get_match_per_ip(afi, rib,
8776 &match, prefix_check);
8777 if (rn != NULL) {
8778 route_vty_out_flowspec(vty, &rn->p,
8779 rn->info, use_json ?
8780 NLRI_STRING_FORMAT_JSON :
8781 NLRI_STRING_FORMAT_LARGE,
8782 json_paths);
8783 display++;
8784 bgp_unlock_node(rn);
8785 }
8786 } else {
8787 header = 1;
8788
8789 if ((rn = bgp_node_match(rib, &match)) != NULL) {
8790 if (!prefix_check
8791 || rn->p.prefixlen == match.prefixlen) {
8792 for (ri = rn->info; ri; ri = ri->next) {
8793 if (header) {
8794 route_vty_out_detail_header(
8795 vty, bgp, rn, NULL, afi,
8796 safi, json);
8797 header = 0;
8798 }
8799 display++;
8800
8801 if (pathtype == BGP_PATH_ALL
8802 || (pathtype == BGP_PATH_BESTPATH
8803 && CHECK_FLAG(
8804 ri->flags,
8805 BGP_INFO_SELECTED))
8806 || (pathtype == BGP_PATH_MULTIPATH
8807 && (CHECK_FLAG(
8808 ri->flags,
8809 BGP_INFO_MULTIPATH)
8810 || CHECK_FLAG(
8811 ri->flags,
8812 BGP_INFO_SELECTED))))
8813 route_vty_out_detail(
8814 vty, bgp, &rn->p, ri,
8815 afi, safi, json_paths);
8816 }
8817 }
8818
8819 bgp_unlock_node(rn);
8820 }
8821 }
8822
8823 if (use_json) {
8824 if (display)
8825 json_object_object_add(json, "paths", json_paths);
8826
8827 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8828 json, JSON_C_TO_STRING_PRETTY));
8829 json_object_free(json);
8830 } else {
8831 if (!display) {
8832 vty_out(vty, "%% Network not in table\n");
8833 return CMD_WARNING;
8834 }
8835 }
8836
8837 return CMD_SUCCESS;
8838 }
8839
8840 /* Display specified route of Main RIB */
8841 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
8842 afi_t afi, safi_t safi, struct prefix_rd *prd,
8843 int prefix_check, enum bgp_path_type pathtype,
8844 uint8_t use_json)
8845 {
8846 if (!bgp) {
8847 bgp = bgp_get_default();
8848 if (!bgp) {
8849 if (!use_json)
8850 vty_out(vty, "No BGP process is configured\n");
8851 else
8852 vty_out(vty, "{}\n");
8853 return CMD_WARNING;
8854 }
8855 }
8856
8857 /* labeled-unicast routes live in the unicast table */
8858 if (safi == SAFI_LABELED_UNICAST)
8859 safi = SAFI_UNICAST;
8860
8861 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
8862 afi, safi, prd, prefix_check, pathtype,
8863 use_json);
8864 }
8865
8866 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
8867 struct cmd_token **argv, afi_t afi, safi_t safi,
8868 uint8_t uj)
8869 {
8870 struct lcommunity *lcom;
8871 struct buffer *b;
8872 int i;
8873 char *str;
8874 int first = 0;
8875
8876 b = buffer_new(1024);
8877 for (i = 0; i < argc; i++) {
8878 if (first)
8879 buffer_putc(b, ' ');
8880 else {
8881 if (strmatch(argv[i]->text, "AA:BB:CC")) {
8882 first = 1;
8883 buffer_putstr(b, argv[i]->arg);
8884 }
8885 }
8886 }
8887 buffer_putc(b, '\0');
8888
8889 str = buffer_getstr(b);
8890 buffer_free(b);
8891
8892 lcom = lcommunity_str2com(str);
8893 XFREE(MTYPE_TMP, str);
8894 if (!lcom) {
8895 vty_out(vty, "%% Large-community malformed\n");
8896 return CMD_WARNING;
8897 }
8898
8899 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
8900 uj);
8901 }
8902
8903 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
8904 const char *lcom, afi_t afi, safi_t safi,
8905 uint8_t uj)
8906 {
8907 struct community_list *list;
8908
8909 list = community_list_lookup(bgp_clist, lcom,
8910 LARGE_COMMUNITY_LIST_MASTER);
8911 if (list == NULL) {
8912 vty_out(vty, "%% %s is not a valid large-community-list name\n",
8913 lcom);
8914 return CMD_WARNING;
8915 }
8916
8917 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
8918 list, uj);
8919 }
8920
8921 DEFUN (show_ip_bgp_large_community_list,
8922 show_ip_bgp_large_community_list_cmd,
8923 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
8924 SHOW_STR
8925 IP_STR
8926 BGP_STR
8927 BGP_INSTANCE_HELP_STR
8928 BGP_AFI_HELP_STR
8929 BGP_SAFI_WITH_LABEL_HELP_STR
8930 "Display routes matching the large-community-list\n"
8931 "large-community-list number\n"
8932 "large-community-list name\n"
8933 JSON_STR)
8934 {
8935 char *vrf = NULL;
8936 afi_t afi = AFI_IP6;
8937 safi_t safi = SAFI_UNICAST;
8938 int idx = 0;
8939
8940 if (argv_find(argv, argc, "ip", &idx))
8941 afi = AFI_IP;
8942 if (argv_find(argv, argc, "view", &idx)
8943 || argv_find(argv, argc, "vrf", &idx))
8944 vrf = argv[++idx]->arg;
8945 if (argv_find(argv, argc, "ipv4", &idx)
8946 || argv_find(argv, argc, "ipv6", &idx)) {
8947 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8948 if (argv_find(argv, argc, "unicast", &idx)
8949 || argv_find(argv, argc, "multicast", &idx))
8950 safi = bgp_vty_safi_from_str(argv[idx]->text);
8951 }
8952
8953 int uj = use_json(argc, argv);
8954
8955 struct bgp *bgp = bgp_lookup_by_name(vrf);
8956 if (bgp == NULL) {
8957 vty_out(vty, "Can't find BGP instance %s\n", vrf);
8958 return CMD_WARNING;
8959 }
8960
8961 argv_find(argv, argc, "large-community-list", &idx);
8962 return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
8963 uj);
8964 }
8965 DEFUN (show_ip_bgp_large_community,
8966 show_ip_bgp_large_community_cmd,
8967 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]",
8968 SHOW_STR
8969 IP_STR
8970 BGP_STR
8971 BGP_INSTANCE_HELP_STR
8972 BGP_AFI_HELP_STR
8973 BGP_SAFI_WITH_LABEL_HELP_STR
8974 "Display routes matching the large-communities\n"
8975 "List of large-community numbers\n"
8976 JSON_STR)
8977 {
8978 char *vrf = NULL;
8979 afi_t afi = AFI_IP6;
8980 safi_t safi = SAFI_UNICAST;
8981 int idx = 0;
8982
8983 if (argv_find(argv, argc, "ip", &idx))
8984 afi = AFI_IP;
8985 if (argv_find(argv, argc, "view", &idx)
8986 || argv_find(argv, argc, "vrf", &idx))
8987 vrf = argv[++idx]->arg;
8988 if (argv_find(argv, argc, "ipv4", &idx)
8989 || argv_find(argv, argc, "ipv6", &idx)) {
8990 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8991 if (argv_find(argv, argc, "unicast", &idx)
8992 || argv_find(argv, argc, "multicast", &idx))
8993 safi = bgp_vty_safi_from_str(argv[idx]->text);
8994 }
8995
8996 int uj = use_json(argc, argv);
8997
8998 struct bgp *bgp = bgp_lookup_by_name(vrf);
8999 if (bgp == NULL) {
9000 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9001 return CMD_WARNING;
9002 }
9003
9004 if (argv_find(argv, argc, "AA:BB:CC", &idx))
9005 return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
9006 else
9007 return bgp_show(vty, bgp, afi, safi,
9008 bgp_show_type_lcommunity_all, NULL, uj);
9009 }
9010
9011 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9012 safi_t safi);
9013
9014
9015 /* BGP route print out function without JSON */
9016 DEFUN (show_ip_bgp,
9017 show_ip_bgp_cmd,
9018 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9019 <dampening <parameters>\
9020 |route-map WORD\
9021 |prefix-list WORD\
9022 |filter-list WORD\
9023 |statistics\
9024 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
9025 |community-list <(1-500)|WORD> [exact-match]\
9026 |A.B.C.D/M longer-prefixes\
9027 |X:X::X:X/M longer-prefixes\
9028 >",
9029 SHOW_STR
9030 IP_STR
9031 BGP_STR
9032 BGP_INSTANCE_HELP_STR
9033 BGP_AFI_HELP_STR
9034 BGP_SAFI_WITH_LABEL_HELP_STR
9035 "Display detailed information about dampening\n"
9036 "Display detail of configured dampening parameters\n"
9037 "Display routes matching the route-map\n"
9038 "A route-map to match on\n"
9039 "Display routes conforming to the prefix-list\n"
9040 "Prefix-list name\n"
9041 "Display routes conforming to the filter-list\n"
9042 "Regular expression access list name\n"
9043 "BGP RIB advertisement statistics\n"
9044 "Display routes matching the communities\n"
9045 COMMUNITY_AANN_STR
9046 "Do not send outside local AS (well-known community)\n"
9047 "Do not advertise to any peer (well-known community)\n"
9048 "Do not export to next AS (well-known community)\n"
9049 "Graceful shutdown (well-known community)\n"
9050 "Exact match of the communities\n"
9051 "Display routes matching the community-list\n"
9052 "community-list number\n"
9053 "community-list name\n"
9054 "Exact match of the communities\n"
9055 "IPv4 prefix\n"
9056 "Display route and more specific routes\n"
9057 "IPv6 prefix\n"
9058 "Display route and more specific routes\n")
9059 {
9060 afi_t afi = AFI_IP6;
9061 safi_t safi = SAFI_UNICAST;
9062 int exact_match = 0;
9063 struct bgp *bgp = NULL;
9064 int idx = 0;
9065 int idx_community_type = 0;
9066
9067 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9068 &bgp);
9069 if (!idx)
9070 return CMD_WARNING;
9071
9072 if (argv_find(argv, argc, "dampening", &idx)) {
9073 if (argv_find(argv, argc, "parameters", &idx))
9074 return bgp_show_dampening_parameters(vty, afi, safi);
9075 }
9076
9077 if (argv_find(argv, argc, "prefix-list", &idx))
9078 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
9079 safi, bgp_show_type_prefix_list);
9080
9081 if (argv_find(argv, argc, "filter-list", &idx))
9082 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
9083 safi, bgp_show_type_filter_list);
9084
9085 if (argv_find(argv, argc, "statistics", &idx))
9086 return bgp_table_stats(vty, bgp, afi, safi);
9087
9088 if (argv_find(argv, argc, "route-map", &idx))
9089 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
9090 safi, bgp_show_type_route_map);
9091
9092 if (argv_find(argv, argc, "community", &idx)) {
9093 /* show a specific community */
9094 if (argv_find(argv, argc, "local-AS", &idx_community_type)
9095 || argv_find(argv, argc, "no-advertise",
9096 &idx_community_type)
9097 || argv_find(argv, argc, "no-export", &idx_community_type)
9098 || argv_find(argv, argc, "graceful-shutdown",
9099 &idx_community_type)
9100 || argv_find(argv, argc, "AA:NN", &idx_community_type)) {
9101
9102 if (argv_find(argv, argc, "exact-match", &idx))
9103 exact_match = 1;
9104 return bgp_show_community(vty, bgp,
9105 argv[idx_community_type]->arg,
9106 exact_match, afi, safi);
9107 }
9108 }
9109
9110 if (argv_find(argv, argc, "community-list", &idx)) {
9111 const char *clist_number_or_name = argv[++idx]->arg;
9112 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
9113 exact_match = 1;
9114 return bgp_show_community_list(vty, bgp, clist_number_or_name,
9115 exact_match, afi, safi);
9116 }
9117 /* prefix-longer */
9118 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9119 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9120 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
9121 safi,
9122 bgp_show_type_prefix_longer);
9123
9124 return CMD_WARNING;
9125 }
9126
9127 /* BGP route print out function with JSON */
9128 DEFUN (show_ip_bgp_json,
9129 show_ip_bgp_json_cmd,
9130 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9131 [<\
9132 cidr-only\
9133 |dampening <flap-statistics|dampened-paths>\
9134 |community \
9135 >] [json]",
9136 SHOW_STR
9137 IP_STR
9138 BGP_STR
9139 BGP_INSTANCE_HELP_STR
9140 BGP_AFI_HELP_STR
9141 BGP_SAFI_WITH_LABEL_HELP_STR
9142 "Display only routes with non-natural netmasks\n"
9143 "Display detailed information about dampening\n"
9144 "Display flap statistics of routes\n"
9145 "Display paths suppressed due to dampening\n"
9146 "Display routes matching the communities\n"
9147 JSON_STR)
9148 {
9149 afi_t afi = AFI_IP6;
9150 safi_t safi = SAFI_UNICAST;
9151 enum bgp_show_type sh_type = bgp_show_type_normal;
9152 struct bgp *bgp = NULL;
9153 int idx = 0;
9154
9155 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9156 &bgp);
9157 if (!idx)
9158 return CMD_WARNING;
9159
9160 int uj = use_json(argc, argv);
9161 if (uj)
9162 argc--;
9163
9164 if (argv_find(argv, argc, "cidr-only", &idx))
9165 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
9166 NULL, uj);
9167
9168 if (argv_find(argv, argc, "dampening", &idx)) {
9169 if (argv_find(argv, argc, "dampened-paths", &idx))
9170 return bgp_show(vty, bgp, afi, safi,
9171 bgp_show_type_dampend_paths, NULL, uj);
9172 else if (argv_find(argv, argc, "flap-statistics", &idx))
9173 return bgp_show(vty, bgp, afi, safi,
9174 bgp_show_type_flap_statistics, NULL,
9175 uj);
9176 }
9177
9178 if (argv_find(argv, argc, "community", &idx)) {
9179 /* show all communities */
9180 return bgp_show(vty, bgp, afi, safi,
9181 bgp_show_type_community_all, NULL, uj);
9182 }
9183 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
9184 }
9185
9186 DEFUN (show_ip_bgp_route,
9187 show_ip_bgp_route_cmd,
9188 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
9189 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9190 SHOW_STR
9191 IP_STR
9192 BGP_STR
9193 BGP_INSTANCE_HELP_STR
9194 BGP_AFI_HELP_STR
9195 BGP_SAFI_WITH_LABEL_HELP_STR
9196 "Network in the BGP routing table to display\n"
9197 "IPv4 prefix\n"
9198 "Network in the BGP routing table to display\n"
9199 "IPv6 prefix\n"
9200 "Display only the bestpath\n"
9201 "Display only multipaths\n"
9202 JSON_STR)
9203 {
9204 int prefix_check = 0;
9205
9206 afi_t afi = AFI_IP6;
9207 safi_t safi = SAFI_UNICAST;
9208 char *prefix = NULL;
9209 struct bgp *bgp = NULL;
9210 enum bgp_path_type path_type;
9211 uint8_t uj = use_json(argc, argv);
9212
9213 int idx = 0;
9214
9215 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9216 &bgp);
9217 if (!idx)
9218 return CMD_WARNING;
9219
9220 if (!bgp) {
9221 vty_out(vty,
9222 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9223 return CMD_WARNING;
9224 }
9225
9226 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9227 if (argv_find(argv, argc, "A.B.C.D", &idx)
9228 || argv_find(argv, argc, "X:X::X:X", &idx))
9229 prefix_check = 0;
9230 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9231 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9232 prefix_check = 1;
9233
9234 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
9235 && afi != AFI_IP6) {
9236 vty_out(vty,
9237 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9238 return CMD_WARNING;
9239 }
9240 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
9241 && afi != AFI_IP) {
9242 vty_out(vty,
9243 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9244 return CMD_WARNING;
9245 }
9246
9247 prefix = argv[idx]->arg;
9248
9249 /* [<bestpath|multipath>] */
9250 if (argv_find(argv, argc, "bestpath", &idx))
9251 path_type = BGP_PATH_BESTPATH;
9252 else if (argv_find(argv, argc, "multipath", &idx))
9253 path_type = BGP_PATH_MULTIPATH;
9254 else
9255 path_type = BGP_PATH_ALL;
9256
9257 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
9258 path_type, uj);
9259 }
9260
9261 DEFUN (show_ip_bgp_regexp,
9262 show_ip_bgp_regexp_cmd,
9263 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
9264 SHOW_STR
9265 IP_STR
9266 BGP_STR
9267 BGP_INSTANCE_HELP_STR
9268 BGP_AFI_HELP_STR
9269 BGP_SAFI_WITH_LABEL_HELP_STR
9270 "Display routes matching the AS path regular expression\n"
9271 "A regular-expression to match the BGP AS paths\n")
9272 {
9273 afi_t afi = AFI_IP6;
9274 safi_t safi = SAFI_UNICAST;
9275 struct bgp *bgp = NULL;
9276
9277 int idx = 0;
9278 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9279 &bgp);
9280 if (!idx)
9281 return CMD_WARNING;
9282
9283 // get index of regex
9284 argv_find(argv, argc, "regexp", &idx);
9285 idx++;
9286
9287 char *regstr = argv_concat(argv, argc, idx);
9288 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
9289 bgp_show_type_regexp);
9290 XFREE(MTYPE_TMP, regstr);
9291 return rc;
9292 }
9293
9294 DEFUN (show_ip_bgp_instance_all,
9295 show_ip_bgp_instance_all_cmd,
9296 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
9297 SHOW_STR
9298 IP_STR
9299 BGP_STR
9300 BGP_INSTANCE_ALL_HELP_STR
9301 BGP_AFI_HELP_STR
9302 BGP_SAFI_WITH_LABEL_HELP_STR
9303 JSON_STR)
9304 {
9305 afi_t afi = AFI_IP;
9306 safi_t safi = SAFI_UNICAST;
9307 struct bgp *bgp = NULL;
9308
9309 int idx = 0;
9310 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9311 &bgp);
9312 if (!idx)
9313 return CMD_WARNING;
9314
9315 int uj = use_json(argc, argv);
9316 if (uj)
9317 argc--;
9318
9319 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
9320 return CMD_SUCCESS;
9321 }
9322
9323 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9324 afi_t afi, safi_t safi, enum bgp_show_type type)
9325 {
9326 regex_t *regex;
9327 int rc;
9328
9329 regex = bgp_regcomp(regstr);
9330 if (!regex) {
9331 vty_out(vty, "Can't compile regexp %s\n", regstr);
9332 return CMD_WARNING;
9333 }
9334
9335 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
9336 bgp_regex_free(regex);
9337 return rc;
9338 }
9339
9340 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9341 const char *prefix_list_str, afi_t afi,
9342 safi_t safi, enum bgp_show_type type)
9343 {
9344 struct prefix_list *plist;
9345
9346 plist = prefix_list_lookup(afi, prefix_list_str);
9347 if (plist == NULL) {
9348 vty_out(vty, "%% %s is not a valid prefix-list name\n",
9349 prefix_list_str);
9350 return CMD_WARNING;
9351 }
9352
9353 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
9354 }
9355
9356 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9357 const char *filter, afi_t afi, safi_t safi,
9358 enum bgp_show_type type)
9359 {
9360 struct as_list *as_list;
9361
9362 as_list = as_list_lookup(filter);
9363 if (as_list == NULL) {
9364 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
9365 filter);
9366 return CMD_WARNING;
9367 }
9368
9369 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
9370 }
9371
9372 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9373 const char *rmap_str, afi_t afi, safi_t safi,
9374 enum bgp_show_type type)
9375 {
9376 struct route_map *rmap;
9377
9378 rmap = route_map_lookup_by_name(rmap_str);
9379 if (!rmap) {
9380 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
9381 return CMD_WARNING;
9382 }
9383
9384 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
9385 }
9386
9387 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9388 const char *comstr, int exact, afi_t afi,
9389 safi_t safi)
9390 {
9391 struct community *com;
9392 int ret = 0;
9393
9394 com = community_str2com(comstr);
9395 if (!com) {
9396 vty_out(vty, "%% Community malformed: %s\n", comstr);
9397 return CMD_WARNING;
9398 }
9399
9400 ret = bgp_show(vty, bgp, afi, safi,
9401 (exact ? bgp_show_type_community_exact
9402 : bgp_show_type_community),
9403 com, 0);
9404 community_free(com);
9405
9406 return ret;
9407 }
9408
9409 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9410 const char *com, int exact, afi_t afi,
9411 safi_t safi)
9412 {
9413 struct community_list *list;
9414
9415 list = community_list_lookup(bgp_clist, com, COMMUNITY_LIST_MASTER);
9416 if (list == NULL) {
9417 vty_out(vty, "%% %s is not a valid community-list name\n", com);
9418 return CMD_WARNING;
9419 }
9420
9421 return bgp_show(vty, bgp, afi, safi,
9422 (exact ? bgp_show_type_community_list_exact
9423 : bgp_show_type_community_list),
9424 list, 0);
9425 }
9426
9427 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9428 const char *prefix, afi_t afi, safi_t safi,
9429 enum bgp_show_type type)
9430 {
9431 int ret;
9432 struct prefix *p;
9433
9434 p = prefix_new();
9435
9436 ret = str2prefix(prefix, p);
9437 if (!ret) {
9438 vty_out(vty, "%% Malformed Prefix\n");
9439 return CMD_WARNING;
9440 }
9441
9442 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
9443 prefix_free(p);
9444 return ret;
9445 }
9446
9447 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
9448 const char *ip_str, uint8_t use_json)
9449 {
9450 int ret;
9451 struct peer *peer;
9452 union sockunion su;
9453
9454 /* Get peer sockunion. */
9455 ret = str2sockunion(ip_str, &su);
9456 if (ret < 0) {
9457 peer = peer_lookup_by_conf_if(bgp, ip_str);
9458 if (!peer) {
9459 peer = peer_lookup_by_hostname(bgp, ip_str);
9460
9461 if (!peer) {
9462 if (use_json) {
9463 json_object *json_no = NULL;
9464 json_no = json_object_new_object();
9465 json_object_string_add(
9466 json_no,
9467 "malformedAddressOrName",
9468 ip_str);
9469 vty_out(vty, "%s\n",
9470 json_object_to_json_string_ext(
9471 json_no,
9472 JSON_C_TO_STRING_PRETTY));
9473 json_object_free(json_no);
9474 } else
9475 vty_out(vty,
9476 "%% Malformed address or name: %s\n",
9477 ip_str);
9478 return NULL;
9479 }
9480 }
9481 return peer;
9482 }
9483
9484 /* Peer structure lookup. */
9485 peer = peer_lookup(bgp, &su);
9486 if (!peer) {
9487 if (use_json) {
9488 json_object *json_no = NULL;
9489 json_no = json_object_new_object();
9490 json_object_string_add(json_no, "warning",
9491 "No such neighbor");
9492 vty_out(vty, "%s\n",
9493 json_object_to_json_string_ext(
9494 json_no, JSON_C_TO_STRING_PRETTY));
9495 json_object_free(json_no);
9496 } else
9497 vty_out(vty, "No such neighbor\n");
9498 return NULL;
9499 }
9500
9501 return peer;
9502 }
9503
9504 enum bgp_stats {
9505 BGP_STATS_MAXBITLEN = 0,
9506 BGP_STATS_RIB,
9507 BGP_STATS_PREFIXES,
9508 BGP_STATS_TOTPLEN,
9509 BGP_STATS_UNAGGREGATEABLE,
9510 BGP_STATS_MAX_AGGREGATEABLE,
9511 BGP_STATS_AGGREGATES,
9512 BGP_STATS_SPACE,
9513 BGP_STATS_ASPATH_COUNT,
9514 BGP_STATS_ASPATH_MAXHOPS,
9515 BGP_STATS_ASPATH_TOTHOPS,
9516 BGP_STATS_ASPATH_MAXSIZE,
9517 BGP_STATS_ASPATH_TOTSIZE,
9518 BGP_STATS_ASN_HIGHEST,
9519 BGP_STATS_MAX,
9520 };
9521
9522 static const char *table_stats_strs[] = {
9523 [BGP_STATS_PREFIXES] = "Total Prefixes",
9524 [BGP_STATS_TOTPLEN] = "Average prefix length",
9525 [BGP_STATS_RIB] = "Total Advertisements",
9526 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
9527 [BGP_STATS_MAX_AGGREGATEABLE] =
9528 "Maximum aggregateable prefixes",
9529 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
9530 [BGP_STATS_SPACE] = "Address space advertised",
9531 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
9532 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
9533 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
9534 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
9535 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
9536 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
9537 [BGP_STATS_MAX] = NULL,
9538 };
9539
9540 struct bgp_table_stats {
9541 struct bgp_table *table;
9542 unsigned long long counts[BGP_STATS_MAX];
9543 double total_space;
9544 };
9545
9546 #if 0
9547 #define TALLY_SIGFIG 100000
9548 static unsigned long
9549 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
9550 {
9551 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
9552 unsigned long res = (newtot * TALLY_SIGFIG) / count;
9553 unsigned long ret = newtot / count;
9554
9555 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
9556 return ret + 1;
9557 else
9558 return ret;
9559 }
9560 #endif
9561
9562 static int bgp_table_stats_walker(struct thread *t)
9563 {
9564 struct bgp_node *rn;
9565 struct bgp_node *top;
9566 struct bgp_table_stats *ts = THREAD_ARG(t);
9567 unsigned int space = 0;
9568
9569 if (!(top = bgp_table_top(ts->table)))
9570 return 0;
9571
9572 switch (top->p.family) {
9573 case AF_INET:
9574 space = IPV4_MAX_BITLEN;
9575 break;
9576 case AF_INET6:
9577 space = IPV6_MAX_BITLEN;
9578 break;
9579 }
9580
9581 ts->counts[BGP_STATS_MAXBITLEN] = space;
9582
9583 for (rn = top; rn; rn = bgp_route_next(rn)) {
9584 struct bgp_info *ri;
9585 struct bgp_node *prn = bgp_node_parent_nolock(rn);
9586 unsigned int rinum = 0;
9587
9588 if (rn == top)
9589 continue;
9590
9591 if (!rn->info)
9592 continue;
9593
9594 ts->counts[BGP_STATS_PREFIXES]++;
9595 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
9596
9597 #if 0
9598 ts->counts[BGP_STATS_AVGPLEN]
9599 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
9600 ts->counts[BGP_STATS_AVGPLEN],
9601 rn->p.prefixlen);
9602 #endif
9603
9604 /* check if the prefix is included by any other announcements */
9605 while (prn && !prn->info)
9606 prn = bgp_node_parent_nolock(prn);
9607
9608 if (prn == NULL || prn == top) {
9609 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
9610 /* announced address space */
9611 if (space)
9612 ts->total_space +=
9613 pow(2.0, space - rn->p.prefixlen);
9614 } else if (prn->info)
9615 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
9616
9617 for (ri = rn->info; ri; ri = ri->next) {
9618 rinum++;
9619 ts->counts[BGP_STATS_RIB]++;
9620
9621 if (ri->attr
9622 && (CHECK_FLAG(ri->attr->flag,
9623 ATTR_FLAG_BIT(
9624 BGP_ATTR_ATOMIC_AGGREGATE))))
9625 ts->counts[BGP_STATS_AGGREGATES]++;
9626
9627 /* as-path stats */
9628 if (ri->attr && ri->attr->aspath) {
9629 unsigned int hops =
9630 aspath_count_hops(ri->attr->aspath);
9631 unsigned int size =
9632 aspath_size(ri->attr->aspath);
9633 as_t highest = aspath_highest(ri->attr->aspath);
9634
9635 ts->counts[BGP_STATS_ASPATH_COUNT]++;
9636
9637 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
9638 ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
9639 hops;
9640
9641 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
9642 ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
9643 size;
9644
9645 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
9646 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
9647 #if 0
9648 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
9649 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9650 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
9651 hops);
9652 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
9653 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9654 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
9655 size);
9656 #endif
9657 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
9658 ts->counts[BGP_STATS_ASN_HIGHEST] =
9659 highest;
9660 }
9661 }
9662 }
9663 return 0;
9664 }
9665
9666 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9667 safi_t safi)
9668 {
9669 struct bgp_table_stats ts;
9670 unsigned int i;
9671
9672 if (!bgp->rib[afi][safi]) {
9673 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9674 afi, safi);
9675 return CMD_WARNING;
9676 }
9677
9678 vty_out(vty, "BGP %s RIB statistics\n", afi_safi_print(afi, safi));
9679
9680 /* labeled-unicast routes live in the unicast table */
9681 if (safi == SAFI_LABELED_UNICAST)
9682 safi = SAFI_UNICAST;
9683
9684 memset(&ts, 0, sizeof(ts));
9685 ts.table = bgp->rib[afi][safi];
9686 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
9687
9688 for (i = 0; i < BGP_STATS_MAX; i++) {
9689 if (!table_stats_strs[i])
9690 continue;
9691
9692 switch (i) {
9693 #if 0
9694 case BGP_STATS_ASPATH_AVGHOPS:
9695 case BGP_STATS_ASPATH_AVGSIZE:
9696 case BGP_STATS_AVGPLEN:
9697 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9698 vty_out (vty, "%12.2f",
9699 (float)ts.counts[i] / (float)TALLY_SIGFIG);
9700 break;
9701 #endif
9702 case BGP_STATS_ASPATH_TOTHOPS:
9703 case BGP_STATS_ASPATH_TOTSIZE:
9704 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9705 vty_out(vty, "%12.2f",
9706 ts.counts[i]
9707 ? (float)ts.counts[i]
9708 / (float)ts.counts
9709 [BGP_STATS_ASPATH_COUNT]
9710 : 0);
9711 break;
9712 case BGP_STATS_TOTPLEN:
9713 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9714 vty_out(vty, "%12.2f",
9715 ts.counts[i]
9716 ? (float)ts.counts[i]
9717 / (float)ts.counts
9718 [BGP_STATS_PREFIXES]
9719 : 0);
9720 break;
9721 case BGP_STATS_SPACE:
9722 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9723 vty_out(vty, "%12g\n", ts.total_space);
9724
9725 if (afi == AFI_IP6) {
9726 vty_out(vty, "%30s: ", "/32 equivalent ");
9727 vty_out(vty, "%12g\n",
9728 ts.total_space * pow(2.0, -128 + 32));
9729 vty_out(vty, "%30s: ", "/48 equivalent ");
9730 vty_out(vty, "%12g\n",
9731 ts.total_space * pow(2.0, -128 + 48));
9732 } else {
9733 vty_out(vty, "%30s: ", "% announced ");
9734 vty_out(vty, "%12.2f\n",
9735 ts.total_space * 100. * pow(2.0, -32));
9736 vty_out(vty, "%30s: ", "/8 equivalent ");
9737 vty_out(vty, "%12.2f\n",
9738 ts.total_space * pow(2.0, -32 + 8));
9739 vty_out(vty, "%30s: ", "/24 equivalent ");
9740 vty_out(vty, "%12.2f\n",
9741 ts.total_space * pow(2.0, -32 + 24));
9742 }
9743 break;
9744 default:
9745 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9746 vty_out(vty, "%12llu", ts.counts[i]);
9747 }
9748
9749 vty_out(vty, "\n");
9750 }
9751 return CMD_SUCCESS;
9752 }
9753
9754 enum bgp_pcounts {
9755 PCOUNT_ADJ_IN = 0,
9756 PCOUNT_DAMPED,
9757 PCOUNT_REMOVED,
9758 PCOUNT_HISTORY,
9759 PCOUNT_STALE,
9760 PCOUNT_VALID,
9761 PCOUNT_ALL,
9762 PCOUNT_COUNTED,
9763 PCOUNT_PFCNT, /* the figure we display to users */
9764 PCOUNT_MAX,
9765 };
9766
9767 static const char *pcount_strs[] = {
9768 [PCOUNT_ADJ_IN] = "Adj-in",
9769 [PCOUNT_DAMPED] = "Damped",
9770 [PCOUNT_REMOVED] = "Removed",
9771 [PCOUNT_HISTORY] = "History",
9772 [PCOUNT_STALE] = "Stale",
9773 [PCOUNT_VALID] = "Valid",
9774 [PCOUNT_ALL] = "All RIB",
9775 [PCOUNT_COUNTED] = "PfxCt counted",
9776 [PCOUNT_PFCNT] = "Useable",
9777 [PCOUNT_MAX] = NULL,
9778 };
9779
9780 struct peer_pcounts {
9781 unsigned int count[PCOUNT_MAX];
9782 const struct peer *peer;
9783 const struct bgp_table *table;
9784 };
9785
9786 static int bgp_peer_count_walker(struct thread *t)
9787 {
9788 struct bgp_node *rn;
9789 struct peer_pcounts *pc = THREAD_ARG(t);
9790 const struct peer *peer = pc->peer;
9791
9792 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
9793 struct bgp_adj_in *ain;
9794 struct bgp_info *ri;
9795
9796 for (ain = rn->adj_in; ain; ain = ain->next)
9797 if (ain->peer == peer)
9798 pc->count[PCOUNT_ADJ_IN]++;
9799
9800 for (ri = rn->info; ri; ri = ri->next) {
9801 char buf[SU_ADDRSTRLEN];
9802
9803 if (ri->peer != peer)
9804 continue;
9805
9806 pc->count[PCOUNT_ALL]++;
9807
9808 if (CHECK_FLAG(ri->flags, BGP_INFO_DAMPED))
9809 pc->count[PCOUNT_DAMPED]++;
9810 if (CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
9811 pc->count[PCOUNT_HISTORY]++;
9812 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
9813 pc->count[PCOUNT_REMOVED]++;
9814 if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
9815 pc->count[PCOUNT_STALE]++;
9816 if (CHECK_FLAG(ri->flags, BGP_INFO_VALID))
9817 pc->count[PCOUNT_VALID]++;
9818 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9819 pc->count[PCOUNT_PFCNT]++;
9820
9821 if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
9822 pc->count[PCOUNT_COUNTED]++;
9823 if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9824 zlog_warn(
9825 "%s [pcount] %s/%d is counted but flags 0x%x",
9826 peer->host,
9827 inet_ntop(rn->p.family,
9828 &rn->p.u.prefix, buf,
9829 SU_ADDRSTRLEN),
9830 rn->p.prefixlen, ri->flags);
9831 } else {
9832 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9833 zlog_warn(
9834 "%s [pcount] %s/%d not counted but flags 0x%x",
9835 peer->host,
9836 inet_ntop(rn->p.family,
9837 &rn->p.u.prefix, buf,
9838 SU_ADDRSTRLEN),
9839 rn->p.prefixlen, ri->flags);
9840 }
9841 }
9842 }
9843 return 0;
9844 }
9845
9846 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
9847 safi_t safi, uint8_t use_json)
9848 {
9849 struct peer_pcounts pcounts = {.peer = peer};
9850 unsigned int i;
9851 json_object *json = NULL;
9852 json_object *json_loop = NULL;
9853
9854 if (use_json) {
9855 json = json_object_new_object();
9856 json_loop = json_object_new_object();
9857 }
9858
9859 if (!peer || !peer->bgp || !peer->afc[afi][safi]
9860 || !peer->bgp->rib[afi][safi]) {
9861 if (use_json) {
9862 json_object_string_add(
9863 json, "warning",
9864 "No such neighbor or address family");
9865 vty_out(vty, "%s\n", json_object_to_json_string(json));
9866 json_object_free(json);
9867 } else
9868 vty_out(vty, "%% No such neighbor or address family\n");
9869
9870 return CMD_WARNING;
9871 }
9872
9873 memset(&pcounts, 0, sizeof(pcounts));
9874 pcounts.peer = peer;
9875 pcounts.table = peer->bgp->rib[afi][safi];
9876
9877 /* in-place call via thread subsystem so as to record execution time
9878 * stats for the thread-walk (i.e. ensure this can't be blamed on
9879 * on just vty_read()).
9880 */
9881 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
9882
9883 if (use_json) {
9884 json_object_string_add(json, "prefixCountsFor", peer->host);
9885 json_object_string_add(json, "multiProtocol",
9886 afi_safi_print(afi, safi));
9887 json_object_int_add(json, "pfxCounter",
9888 peer->pcount[afi][safi]);
9889
9890 for (i = 0; i < PCOUNT_MAX; i++)
9891 json_object_int_add(json_loop, pcount_strs[i],
9892 pcounts.count[i]);
9893
9894 json_object_object_add(json, "ribTableWalkCounters", json_loop);
9895
9896 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9897 json_object_string_add(json, "pfxctDriftFor",
9898 peer->host);
9899 json_object_string_add(
9900 json, "recommended",
9901 "Please report this bug, with the above command output");
9902 }
9903 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9904 json, JSON_C_TO_STRING_PRETTY));
9905 json_object_free(json);
9906 } else {
9907
9908 if (peer->hostname
9909 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
9910 vty_out(vty, "Prefix counts for %s/%s, %s\n",
9911 peer->hostname, peer->host,
9912 afi_safi_print(afi, safi));
9913 } else {
9914 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
9915 afi_safi_print(afi, safi));
9916 }
9917
9918 vty_out(vty, "PfxCt: %ld\n", peer->pcount[afi][safi]);
9919 vty_out(vty, "\nCounts from RIB table walk:\n\n");
9920
9921 for (i = 0; i < PCOUNT_MAX; i++)
9922 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
9923 pcounts.count[i]);
9924
9925 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9926 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
9927 vty_out(vty,
9928 "Please report this bug, with the above command output\n");
9929 }
9930 }
9931
9932 return CMD_SUCCESS;
9933 }
9934
9935 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
9936 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
9937 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9938 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9939 SHOW_STR
9940 IP_STR
9941 BGP_STR
9942 BGP_INSTANCE_HELP_STR
9943 BGP_AFI_HELP_STR
9944 BGP_SAFI_HELP_STR
9945 "Detailed information on TCP and BGP neighbor connections\n"
9946 "Neighbor to display information about\n"
9947 "Neighbor to display information about\n"
9948 "Neighbor on BGP configured interface\n"
9949 "Display detailed prefix count information\n"
9950 JSON_STR)
9951 {
9952 afi_t afi = AFI_IP6;
9953 safi_t safi = SAFI_UNICAST;
9954 struct peer *peer;
9955 int idx = 0;
9956 struct bgp *bgp = NULL;
9957
9958 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9959 &bgp);
9960 if (!idx)
9961 return CMD_WARNING;
9962
9963 int uj = use_json(argc, argv);
9964 if (uj)
9965 argc--;
9966
9967 argv_find(argv, argc, "neighbors", &idx);
9968 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
9969 if (!peer)
9970 return CMD_WARNING;
9971
9972 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
9973 }
9974
9975 #ifdef KEEP_OLD_VPN_COMMANDS
9976 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
9977 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
9978 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9979 SHOW_STR
9980 IP_STR
9981 BGP_STR
9982 BGP_VPNVX_HELP_STR
9983 "Display information about all VPNv4 NLRIs\n"
9984 "Detailed information on TCP and BGP neighbor connections\n"
9985 "Neighbor to display information about\n"
9986 "Neighbor to display information about\n"
9987 "Neighbor on BGP configured interface\n"
9988 "Display detailed prefix count information\n"
9989 JSON_STR)
9990 {
9991 int idx_peer = 6;
9992 struct peer *peer;
9993 uint8_t uj = use_json(argc, argv);
9994
9995 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
9996 if (!peer)
9997 return CMD_WARNING;
9998
9999 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
10000 }
10001
10002 DEFUN (show_ip_bgp_vpn_all_route_prefix,
10003 show_ip_bgp_vpn_all_route_prefix_cmd,
10004 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10005 SHOW_STR
10006 IP_STR
10007 BGP_STR
10008 BGP_VPNVX_HELP_STR
10009 "Display information about all VPNv4 NLRIs\n"
10010 "Network in the BGP routing table to display\n"
10011 "Network in the BGP routing table to display\n"
10012 JSON_STR)
10013 {
10014 int idx = 0;
10015 char *network = NULL;
10016 struct bgp *bgp = bgp_get_default();
10017 if (!bgp) {
10018 vty_out(vty, "Can't find default instance\n");
10019 return CMD_WARNING;
10020 }
10021
10022 if (argv_find(argv, argc, "A.B.C.D", &idx))
10023 network = argv[idx]->arg;
10024 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10025 network = argv[idx]->arg;
10026 else {
10027 vty_out(vty, "Unable to figure out Network\n");
10028 return CMD_WARNING;
10029 }
10030
10031 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
10032 BGP_PATH_ALL, use_json(argc, argv));
10033 }
10034 #endif /* KEEP_OLD_VPN_COMMANDS */
10035
10036 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
10037 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
10038 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10039 SHOW_STR
10040 IP_STR
10041 BGP_STR
10042 L2VPN_HELP_STR
10043 EVPN_HELP_STR
10044 "Display information about all EVPN NLRIs\n"
10045 "Network in the BGP routing table to display\n"
10046 "Network in the BGP routing table to display\n"
10047 JSON_STR)
10048 {
10049 int idx = 0;
10050 char *network = NULL;
10051
10052 if (argv_find(argv, argc, "A.B.C.D", &idx))
10053 network = argv[idx]->arg;
10054 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10055 network = argv[idx]->arg;
10056 else {
10057 vty_out(vty, "Unable to figure out Network\n");
10058 return CMD_WARNING;
10059 }
10060 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
10061 BGP_PATH_ALL, use_json(argc, argv));
10062 }
10063
10064 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
10065 safi_t safi, int in, const char *rmap_name,
10066 uint8_t use_json, json_object *json)
10067 {
10068 struct bgp_table *table;
10069 struct bgp_adj_in *ain;
10070 struct bgp_adj_out *adj;
10071 unsigned long output_count;
10072 unsigned long filtered_count;
10073 struct bgp_node *rn;
10074 int header1 = 1;
10075 struct bgp *bgp;
10076 int header2 = 1;
10077 struct attr attr;
10078 int ret;
10079 struct update_subgroup *subgrp;
10080 json_object *json_scode = NULL;
10081 json_object *json_ocode = NULL;
10082 json_object *json_ar = NULL;
10083 struct peer_af *paf;
10084
10085 if (use_json) {
10086 json_scode = json_object_new_object();
10087 json_ocode = json_object_new_object();
10088 json_ar = json_object_new_object();
10089
10090 json_object_string_add(json_scode, "suppressed", "s");
10091 json_object_string_add(json_scode, "damped", "d");
10092 json_object_string_add(json_scode, "history", "h");
10093 json_object_string_add(json_scode, "valid", "*");
10094 json_object_string_add(json_scode, "best", ">");
10095 json_object_string_add(json_scode, "multipath", "=");
10096 json_object_string_add(json_scode, "internal", "i");
10097 json_object_string_add(json_scode, "ribFailure", "r");
10098 json_object_string_add(json_scode, "stale", "S");
10099 json_object_string_add(json_scode, "removed", "R");
10100
10101 json_object_string_add(json_ocode, "igp", "i");
10102 json_object_string_add(json_ocode, "egp", "e");
10103 json_object_string_add(json_ocode, "incomplete", "?");
10104 }
10105
10106 bgp = peer->bgp;
10107
10108 if (!bgp) {
10109 if (use_json) {
10110 json_object_string_add(json, "alert", "no BGP");
10111 vty_out(vty, "%s\n", json_object_to_json_string(json));
10112 json_object_free(json);
10113 } else
10114 vty_out(vty, "%% No bgp\n");
10115 return;
10116 }
10117
10118 table = bgp->rib[afi][safi];
10119
10120 output_count = filtered_count = 0;
10121 subgrp = peer_subgroup(peer, afi, safi);
10122
10123 if (!in && subgrp
10124 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
10125 if (use_json) {
10126 json_object_int_add(json, "bgpTableVersion",
10127 table->version);
10128 json_object_string_add(json, "bgpLocalRouterId",
10129 inet_ntoa(bgp->router_id));
10130 json_object_object_add(json, "bgpStatusCodes",
10131 json_scode);
10132 json_object_object_add(json, "bgpOriginCodes",
10133 json_ocode);
10134 json_object_string_add(json,
10135 "bgpOriginatingDefaultNetwork",
10136 "0.0.0.0");
10137 } else {
10138 vty_out(vty, "BGP table version is %" PRIu64
10139 ", local router ID is %s\n",
10140 table->version, inet_ntoa(bgp->router_id));
10141 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10142 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10143
10144 vty_out(vty, "Originating default network 0.0.0.0\n\n");
10145 }
10146 header1 = 0;
10147 }
10148
10149 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
10150 if (in) {
10151 for (ain = rn->adj_in; ain; ain = ain->next) {
10152 if (ain->peer != peer)
10153 continue;
10154 if (header1) {
10155 if (use_json) {
10156 json_object_int_add(
10157 json, "bgpTableVersion",
10158 0);
10159 json_object_string_add(
10160 json,
10161 "bgpLocalRouterId",
10162 inet_ntoa(
10163 bgp->router_id));
10164 json_object_object_add(
10165 json, "bgpStatusCodes",
10166 json_scode);
10167 json_object_object_add(
10168 json, "bgpOriginCodes",
10169 json_ocode);
10170 } else {
10171 vty_out(vty,
10172 "BGP table version is 0, local router ID is %s\n",
10173 inet_ntoa(
10174 bgp->router_id));
10175 vty_out(vty,
10176 BGP_SHOW_SCODE_HEADER);
10177 vty_out(vty,
10178 BGP_SHOW_OCODE_HEADER);
10179 }
10180 header1 = 0;
10181 }
10182 if (header2) {
10183 if (!use_json)
10184 vty_out(vty, BGP_SHOW_HEADER);
10185 header2 = 0;
10186 }
10187 if (ain->attr) {
10188 bgp_attr_dup(&attr, ain->attr);
10189 if (bgp_input_modifier(peer, &rn->p,
10190 &attr, afi, safi,
10191 rmap_name)
10192 != RMAP_DENY) {
10193 route_vty_out_tmp(vty, &rn->p,
10194 &attr, safi,
10195 use_json,
10196 json_ar);
10197 output_count++;
10198 } else
10199 filtered_count++;
10200 }
10201 }
10202 } else {
10203 for (adj = rn->adj_out; adj; adj = adj->next)
10204 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
10205 if (paf->peer != peer)
10206 continue;
10207
10208 if (header1) {
10209 if (use_json) {
10210 json_object_int_add(
10211 json,
10212 "bgpTableVersion",
10213 table->version);
10214 json_object_string_add(
10215 json,
10216 "bgpLocalRouterId",
10217 inet_ntoa(
10218 bgp->router_id));
10219 json_object_object_add(
10220 json,
10221 "bgpStatusCodes",
10222 json_scode);
10223 json_object_object_add(
10224 json,
10225 "bgpOriginCodes",
10226 json_ocode);
10227 } else {
10228 vty_out(vty,
10229 "BGP table version is %" PRIu64
10230 ", local router ID is %s\n",
10231 table->version,
10232 inet_ntoa(
10233 bgp->router_id));
10234 vty_out(vty,
10235 BGP_SHOW_SCODE_HEADER);
10236 vty_out(vty,
10237 BGP_SHOW_OCODE_HEADER);
10238 }
10239 header1 = 0;
10240 }
10241
10242 if (header2) {
10243 if (!use_json)
10244 vty_out(vty,
10245 BGP_SHOW_HEADER);
10246 header2 = 0;
10247 }
10248
10249 if (adj->attr) {
10250 bgp_attr_dup(&attr, adj->attr);
10251 ret = bgp_output_modifier(
10252 peer, &rn->p, &attr,
10253 afi, safi, rmap_name);
10254 if (ret != RMAP_DENY) {
10255 route_vty_out_tmp(
10256 vty, &rn->p,
10257 &attr, safi,
10258 use_json,
10259 json_ar);
10260 output_count++;
10261 } else
10262 filtered_count++;
10263
10264 bgp_attr_undup(&attr,
10265 adj->attr);
10266 }
10267 }
10268 }
10269 }
10270 if (use_json)
10271 json_object_object_add(json, "advertisedRoutes", json_ar);
10272
10273 if (output_count != 0) {
10274 if (use_json)
10275 json_object_int_add(json, "totalPrefixCounter",
10276 output_count);
10277 else
10278 vty_out(vty, "\nTotal number of prefixes %ld\n",
10279 output_count);
10280 }
10281 if (use_json) {
10282 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10283 json, JSON_C_TO_STRING_PRETTY));
10284 json_object_free(json);
10285 }
10286 }
10287
10288 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
10289 safi_t safi, int in, const char *rmap_name,
10290 uint8_t use_json)
10291 {
10292 json_object *json = NULL;
10293
10294 if (use_json)
10295 json = json_object_new_object();
10296
10297 /* labeled-unicast routes live in the unicast table */
10298 if (safi == SAFI_LABELED_UNICAST)
10299 safi = SAFI_UNICAST;
10300
10301 if (!peer || !peer->afc[afi][safi]) {
10302 if (use_json) {
10303 json_object_string_add(
10304 json, "warning",
10305 "No such neighbor or address family");
10306 vty_out(vty, "%s\n", json_object_to_json_string(json));
10307 json_object_free(json);
10308 } else
10309 vty_out(vty, "%% No such neighbor or address family\n");
10310
10311 return CMD_WARNING;
10312 }
10313
10314 if (in
10315 && !CHECK_FLAG(peer->af_flags[afi][safi],
10316 PEER_FLAG_SOFT_RECONFIG)) {
10317 if (use_json) {
10318 json_object_string_add(
10319 json, "warning",
10320 "Inbound soft reconfiguration not enabled");
10321 vty_out(vty, "%s\n", json_object_to_json_string(json));
10322 json_object_free(json);
10323 } else
10324 vty_out(vty,
10325 "%% Inbound soft reconfiguration not enabled\n");
10326
10327 return CMD_WARNING;
10328 }
10329
10330 show_adj_route(vty, peer, afi, safi, in, rmap_name, use_json, json);
10331
10332 return CMD_SUCCESS;
10333 }
10334
10335 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
10336 show_ip_bgp_instance_neighbor_advertised_route_cmd,
10337 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10338 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10339 SHOW_STR
10340 IP_STR
10341 BGP_STR
10342 BGP_INSTANCE_HELP_STR
10343 BGP_AFI_HELP_STR
10344 BGP_SAFI_WITH_LABEL_HELP_STR
10345 "Detailed information on TCP and BGP neighbor connections\n"
10346 "Neighbor to display information about\n"
10347 "Neighbor to display information about\n"
10348 "Neighbor on BGP configured interface\n"
10349 "Display the received routes from neighbor\n"
10350 "Display the routes advertised to a BGP neighbor\n"
10351 "Route-map to modify the attributes\n"
10352 "Name of the route map\n"
10353 JSON_STR)
10354 {
10355 afi_t afi = AFI_IP6;
10356 safi_t safi = SAFI_UNICAST;
10357 char *rmap_name = NULL;
10358 char *peerstr = NULL;
10359 int rcvd = 0;
10360 struct bgp *bgp = NULL;
10361 struct peer *peer;
10362
10363 int idx = 0;
10364
10365 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10366 &bgp);
10367 if (!idx)
10368 return CMD_WARNING;
10369
10370 int uj = use_json(argc, argv);
10371 if (uj)
10372 argc--;
10373
10374 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10375 argv_find(argv, argc, "neighbors", &idx);
10376 peerstr = argv[++idx]->arg;
10377
10378 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10379 if (!peer)
10380 return CMD_WARNING;
10381
10382 if (argv_find(argv, argc, "received-routes", &idx))
10383 rcvd = 1;
10384 if (argv_find(argv, argc, "advertised-routes", &idx))
10385 rcvd = 0;
10386 if (argv_find(argv, argc, "route-map", &idx))
10387 rmap_name = argv[++idx]->arg;
10388
10389 return peer_adj_routes(vty, peer, afi, safi, rcvd, rmap_name, uj);
10390 }
10391
10392 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
10393 show_ip_bgp_neighbor_received_prefix_filter_cmd,
10394 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10395 SHOW_STR
10396 IP_STR
10397 BGP_STR
10398 "Address Family\n"
10399 "Address Family\n"
10400 "Address Family modifier\n"
10401 "Detailed information on TCP and BGP neighbor connections\n"
10402 "Neighbor to display information about\n"
10403 "Neighbor to display information about\n"
10404 "Neighbor on BGP configured interface\n"
10405 "Display information received from a BGP neighbor\n"
10406 "Display the prefixlist filter\n"
10407 JSON_STR)
10408 {
10409 afi_t afi = AFI_IP6;
10410 safi_t safi = SAFI_UNICAST;
10411 char *peerstr = NULL;
10412
10413 char name[BUFSIZ];
10414 union sockunion su;
10415 struct peer *peer;
10416 int count, ret;
10417
10418 int idx = 0;
10419
10420 /* show [ip] bgp */
10421 if (argv_find(argv, argc, "ip", &idx))
10422 afi = AFI_IP;
10423 /* [<ipv4|ipv6> [unicast]] */
10424 if (argv_find(argv, argc, "ipv4", &idx))
10425 afi = AFI_IP;
10426 if (argv_find(argv, argc, "ipv6", &idx))
10427 afi = AFI_IP6;
10428 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10429 argv_find(argv, argc, "neighbors", &idx);
10430 peerstr = argv[++idx]->arg;
10431
10432 uint8_t uj = use_json(argc, argv);
10433
10434 ret = str2sockunion(peerstr, &su);
10435 if (ret < 0) {
10436 peer = peer_lookup_by_conf_if(NULL, peerstr);
10437 if (!peer) {
10438 if (uj)
10439 vty_out(vty, "{}\n");
10440 else
10441 vty_out(vty,
10442 "%% Malformed address or name: %s\n",
10443 peerstr);
10444 return CMD_WARNING;
10445 }
10446 } else {
10447 peer = peer_lookup(NULL, &su);
10448 if (!peer) {
10449 if (uj)
10450 vty_out(vty, "{}\n");
10451 else
10452 vty_out(vty, "No peer\n");
10453 return CMD_WARNING;
10454 }
10455 }
10456
10457 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
10458 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
10459 if (count) {
10460 if (!uj)
10461 vty_out(vty, "Address Family: %s\n",
10462 afi_safi_print(afi, safi));
10463 prefix_bgp_show_prefix_list(vty, afi, name, uj);
10464 } else {
10465 if (uj)
10466 vty_out(vty, "{}\n");
10467 else
10468 vty_out(vty, "No functional output\n");
10469 }
10470
10471 return CMD_SUCCESS;
10472 }
10473
10474 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
10475 afi_t afi, safi_t safi,
10476 enum bgp_show_type type, uint8_t use_json)
10477 {
10478 /* labeled-unicast routes live in the unicast table */
10479 if (safi == SAFI_LABELED_UNICAST)
10480 safi = SAFI_UNICAST;
10481
10482 if (!peer || !peer->afc[afi][safi]) {
10483 if (use_json) {
10484 json_object *json_no = NULL;
10485 json_no = json_object_new_object();
10486 json_object_string_add(
10487 json_no, "warning",
10488 "No such neighbor or address family");
10489 vty_out(vty, "%s\n",
10490 json_object_to_json_string(json_no));
10491 json_object_free(json_no);
10492 } else
10493 vty_out(vty, "%% No such neighbor or address family\n");
10494 return CMD_WARNING;
10495 }
10496
10497 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
10498 }
10499
10500 DEFUN (show_ip_bgp_flowspec_routes_detailed,
10501 show_ip_bgp_flowspec_routes_detailed_cmd,
10502 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
10503 SHOW_STR
10504 IP_STR
10505 BGP_STR
10506 BGP_INSTANCE_HELP_STR
10507 BGP_AFI_HELP_STR
10508 "SAFI Flowspec\n"
10509 "Detailed information on flowspec entries\n"
10510 JSON_STR)
10511 {
10512 afi_t afi = AFI_IP;
10513 safi_t safi = SAFI_UNICAST;
10514 struct bgp *bgp = NULL;
10515 int idx = 0;
10516
10517 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10518 &bgp);
10519 if (!idx)
10520 return CMD_WARNING;
10521
10522 return bgp_show(vty, bgp, afi, safi,
10523 bgp_show_type_detail, NULL, use_json(argc, argv));
10524 }
10525
10526 DEFUN (show_ip_bgp_neighbor_routes,
10527 show_ip_bgp_neighbor_routes_cmd,
10528 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10529 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10530 SHOW_STR
10531 IP_STR
10532 BGP_STR
10533 BGP_INSTANCE_HELP_STR
10534 BGP_AFI_HELP_STR
10535 BGP_SAFI_WITH_LABEL_HELP_STR
10536 "Detailed information on TCP and BGP neighbor connections\n"
10537 "Neighbor to display information about\n"
10538 "Neighbor to display information about\n"
10539 "Neighbor on BGP configured interface\n"
10540 "Display flap statistics of the routes learned from neighbor\n"
10541 "Display the dampened routes received from neighbor\n"
10542 "Display routes learned from neighbor\n"
10543 JSON_STR)
10544 {
10545 char *peerstr = NULL;
10546 struct bgp *bgp = NULL;
10547 afi_t afi = AFI_IP6;
10548 safi_t safi = SAFI_UNICAST;
10549 struct peer *peer;
10550 enum bgp_show_type sh_type = bgp_show_type_neighbor;
10551
10552 int idx = 0;
10553
10554 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10555 &bgp);
10556 if (!idx)
10557 return CMD_WARNING;
10558
10559 int uj = use_json(argc, argv);
10560 if (uj)
10561 argc--;
10562
10563 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10564 argv_find(argv, argc, "neighbors", &idx);
10565 peerstr = argv[++idx]->arg;
10566
10567 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10568 if (!peer) {
10569 vty_out(vty, "No such neighbor\n");
10570 return CMD_WARNING;
10571 }
10572
10573 if (argv_find(argv, argc, "flap-statistics", &idx))
10574 sh_type = bgp_show_type_flap_neighbor;
10575 else if (argv_find(argv, argc, "dampened-routes", &idx))
10576 sh_type = bgp_show_type_damp_neighbor;
10577 else if (argv_find(argv, argc, "routes", &idx))
10578 sh_type = bgp_show_type_neighbor;
10579
10580 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
10581 }
10582
10583 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
10584
10585 struct bgp_distance {
10586 /* Distance value for the IP source prefix. */
10587 uint8_t distance;
10588
10589 /* Name of the access-list to be matched. */
10590 char *access_list;
10591 };
10592
10593 DEFUN (show_bgp_afi_vpn_rd_route,
10594 show_bgp_afi_vpn_rd_route_cmd,
10595 "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]",
10596 SHOW_STR
10597 BGP_STR
10598 BGP_AFI_HELP_STR
10599 "Address Family modifier\n"
10600 "Display information for a route distinguisher\n"
10601 "Route Distinguisher\n"
10602 "Network in the BGP routing table to display\n"
10603 "Network in the BGP routing table to display\n"
10604 JSON_STR)
10605 {
10606 int ret;
10607 struct prefix_rd prd;
10608 afi_t afi = AFI_MAX;
10609 int idx = 0;
10610
10611 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
10612 vty_out(vty, "%% Malformed Address Family\n");
10613 return CMD_WARNING;
10614 }
10615
10616 ret = str2prefix_rd(argv[5]->arg, &prd);
10617 if (!ret) {
10618 vty_out(vty, "%% Malformed Route Distinguisher\n");
10619 return CMD_WARNING;
10620 }
10621
10622 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
10623 0, BGP_PATH_ALL, use_json(argc, argv));
10624 }
10625
10626 static struct bgp_distance *bgp_distance_new(void)
10627 {
10628 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
10629 }
10630
10631 static void bgp_distance_free(struct bgp_distance *bdistance)
10632 {
10633 XFREE(MTYPE_BGP_DISTANCE, bdistance);
10634 }
10635
10636 static int bgp_distance_set(struct vty *vty, const char *distance_str,
10637 const char *ip_str, const char *access_list_str)
10638 {
10639 int ret;
10640 afi_t afi;
10641 safi_t safi;
10642 struct prefix p;
10643 uint8_t distance;
10644 struct bgp_node *rn;
10645 struct bgp_distance *bdistance;
10646
10647 afi = bgp_node_afi(vty);
10648 safi = bgp_node_safi(vty);
10649
10650 ret = str2prefix(ip_str, &p);
10651 if (ret == 0) {
10652 vty_out(vty, "Malformed prefix\n");
10653 return CMD_WARNING_CONFIG_FAILED;
10654 }
10655
10656 distance = atoi(distance_str);
10657
10658 /* Get BGP distance node. */
10659 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
10660 if (rn->info) {
10661 bdistance = rn->info;
10662 bgp_unlock_node(rn);
10663 } else {
10664 bdistance = bgp_distance_new();
10665 rn->info = bdistance;
10666 }
10667
10668 /* Set distance value. */
10669 bdistance->distance = distance;
10670
10671 /* Reset access-list configuration. */
10672 if (bdistance->access_list) {
10673 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10674 bdistance->access_list = NULL;
10675 }
10676 if (access_list_str)
10677 bdistance->access_list =
10678 XSTRDUP(MTYPE_AS_LIST, access_list_str);
10679
10680 return CMD_SUCCESS;
10681 }
10682
10683 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
10684 const char *ip_str, const char *access_list_str)
10685 {
10686 int ret;
10687 afi_t afi;
10688 safi_t safi;
10689 struct prefix p;
10690 int distance;
10691 struct bgp_node *rn;
10692 struct bgp_distance *bdistance;
10693
10694 afi = bgp_node_afi(vty);
10695 safi = bgp_node_safi(vty);
10696
10697 ret = str2prefix(ip_str, &p);
10698 if (ret == 0) {
10699 vty_out(vty, "Malformed prefix\n");
10700 return CMD_WARNING_CONFIG_FAILED;
10701 }
10702
10703 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
10704 (struct prefix *)&p);
10705 if (!rn) {
10706 vty_out(vty, "Can't find specified prefix\n");
10707 return CMD_WARNING_CONFIG_FAILED;
10708 }
10709
10710 bdistance = rn->info;
10711 distance = atoi(distance_str);
10712
10713 if (bdistance->distance != distance) {
10714 vty_out(vty, "Distance does not match configured\n");
10715 return CMD_WARNING_CONFIG_FAILED;
10716 }
10717
10718 if (bdistance->access_list)
10719 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10720 bgp_distance_free(bdistance);
10721
10722 rn->info = NULL;
10723 bgp_unlock_node(rn);
10724 bgp_unlock_node(rn);
10725
10726 return CMD_SUCCESS;
10727 }
10728
10729 /* Apply BGP information to distance method. */
10730 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
10731 safi_t safi, struct bgp *bgp)
10732 {
10733 struct bgp_node *rn;
10734 struct prefix q;
10735 struct peer *peer;
10736 struct bgp_distance *bdistance;
10737 struct access_list *alist;
10738 struct bgp_static *bgp_static;
10739
10740 if (!bgp)
10741 return 0;
10742
10743 peer = rinfo->peer;
10744
10745 /* Check source address. */
10746 sockunion2hostprefix(&peer->su, &q);
10747 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
10748 if (rn) {
10749 bdistance = rn->info;
10750 bgp_unlock_node(rn);
10751
10752 if (bdistance->access_list) {
10753 alist = access_list_lookup(afi, bdistance->access_list);
10754 if (alist
10755 && access_list_apply(alist, p) == FILTER_PERMIT)
10756 return bdistance->distance;
10757 } else
10758 return bdistance->distance;
10759 }
10760
10761 /* Backdoor check. */
10762 rn = bgp_node_lookup(bgp->route[afi][safi], p);
10763 if (rn) {
10764 bgp_static = rn->info;
10765 bgp_unlock_node(rn);
10766
10767 if (bgp_static->backdoor) {
10768 if (bgp->distance_local[afi][safi])
10769 return bgp->distance_local[afi][safi];
10770 else
10771 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10772 }
10773 }
10774
10775 if (peer->sort == BGP_PEER_EBGP) {
10776 if (bgp->distance_ebgp[afi][safi])
10777 return bgp->distance_ebgp[afi][safi];
10778 return ZEBRA_EBGP_DISTANCE_DEFAULT;
10779 } else {
10780 if (bgp->distance_ibgp[afi][safi])
10781 return bgp->distance_ibgp[afi][safi];
10782 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10783 }
10784 }
10785
10786 DEFUN (bgp_distance,
10787 bgp_distance_cmd,
10788 "distance bgp (1-255) (1-255) (1-255)",
10789 "Define an administrative distance\n"
10790 "BGP distance\n"
10791 "Distance for routes external to the AS\n"
10792 "Distance for routes internal to the AS\n"
10793 "Distance for local routes\n")
10794 {
10795 VTY_DECLVAR_CONTEXT(bgp, bgp);
10796 int idx_number = 2;
10797 int idx_number_2 = 3;
10798 int idx_number_3 = 4;
10799 afi_t afi;
10800 safi_t safi;
10801
10802 afi = bgp_node_afi(vty);
10803 safi = bgp_node_safi(vty);
10804
10805 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
10806 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
10807 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
10808 return CMD_SUCCESS;
10809 }
10810
10811 DEFUN (no_bgp_distance,
10812 no_bgp_distance_cmd,
10813 "no distance bgp [(1-255) (1-255) (1-255)]",
10814 NO_STR
10815 "Define an administrative distance\n"
10816 "BGP distance\n"
10817 "Distance for routes external to the AS\n"
10818 "Distance for routes internal to the AS\n"
10819 "Distance for local routes\n")
10820 {
10821 VTY_DECLVAR_CONTEXT(bgp, bgp);
10822 afi_t afi;
10823 safi_t safi;
10824
10825 afi = bgp_node_afi(vty);
10826 safi = bgp_node_safi(vty);
10827
10828 bgp->distance_ebgp[afi][safi] = 0;
10829 bgp->distance_ibgp[afi][safi] = 0;
10830 bgp->distance_local[afi][safi] = 0;
10831 return CMD_SUCCESS;
10832 }
10833
10834
10835 DEFUN (bgp_distance_source,
10836 bgp_distance_source_cmd,
10837 "distance (1-255) A.B.C.D/M",
10838 "Define an administrative distance\n"
10839 "Administrative distance\n"
10840 "IP source prefix\n")
10841 {
10842 int idx_number = 1;
10843 int idx_ipv4_prefixlen = 2;
10844 bgp_distance_set(vty, argv[idx_number]->arg,
10845 argv[idx_ipv4_prefixlen]->arg, NULL);
10846 return CMD_SUCCESS;
10847 }
10848
10849 DEFUN (no_bgp_distance_source,
10850 no_bgp_distance_source_cmd,
10851 "no distance (1-255) A.B.C.D/M",
10852 NO_STR
10853 "Define an administrative distance\n"
10854 "Administrative distance\n"
10855 "IP source prefix\n")
10856 {
10857 int idx_number = 2;
10858 int idx_ipv4_prefixlen = 3;
10859 bgp_distance_unset(vty, argv[idx_number]->arg,
10860 argv[idx_ipv4_prefixlen]->arg, NULL);
10861 return CMD_SUCCESS;
10862 }
10863
10864 DEFUN (bgp_distance_source_access_list,
10865 bgp_distance_source_access_list_cmd,
10866 "distance (1-255) A.B.C.D/M WORD",
10867 "Define an administrative distance\n"
10868 "Administrative distance\n"
10869 "IP source prefix\n"
10870 "Access list name\n")
10871 {
10872 int idx_number = 1;
10873 int idx_ipv4_prefixlen = 2;
10874 int idx_word = 3;
10875 bgp_distance_set(vty, argv[idx_number]->arg,
10876 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10877 return CMD_SUCCESS;
10878 }
10879
10880 DEFUN (no_bgp_distance_source_access_list,
10881 no_bgp_distance_source_access_list_cmd,
10882 "no distance (1-255) A.B.C.D/M WORD",
10883 NO_STR
10884 "Define an administrative distance\n"
10885 "Administrative distance\n"
10886 "IP source prefix\n"
10887 "Access list name\n")
10888 {
10889 int idx_number = 2;
10890 int idx_ipv4_prefixlen = 3;
10891 int idx_word = 4;
10892 bgp_distance_unset(vty, argv[idx_number]->arg,
10893 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10894 return CMD_SUCCESS;
10895 }
10896
10897 DEFUN (ipv6_bgp_distance_source,
10898 ipv6_bgp_distance_source_cmd,
10899 "distance (1-255) X:X::X:X/M",
10900 "Define an administrative distance\n"
10901 "Administrative distance\n"
10902 "IP source prefix\n")
10903 {
10904 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
10905 return CMD_SUCCESS;
10906 }
10907
10908 DEFUN (no_ipv6_bgp_distance_source,
10909 no_ipv6_bgp_distance_source_cmd,
10910 "no distance (1-255) X:X::X:X/M",
10911 NO_STR
10912 "Define an administrative distance\n"
10913 "Administrative distance\n"
10914 "IP source prefix\n")
10915 {
10916 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
10917 return CMD_SUCCESS;
10918 }
10919
10920 DEFUN (ipv6_bgp_distance_source_access_list,
10921 ipv6_bgp_distance_source_access_list_cmd,
10922 "distance (1-255) X:X::X:X/M WORD",
10923 "Define an administrative distance\n"
10924 "Administrative distance\n"
10925 "IP source prefix\n"
10926 "Access list name\n")
10927 {
10928 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
10929 return CMD_SUCCESS;
10930 }
10931
10932 DEFUN (no_ipv6_bgp_distance_source_access_list,
10933 no_ipv6_bgp_distance_source_access_list_cmd,
10934 "no distance (1-255) X:X::X:X/M WORD",
10935 NO_STR
10936 "Define an administrative distance\n"
10937 "Administrative distance\n"
10938 "IP source prefix\n"
10939 "Access list name\n")
10940 {
10941 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
10942 return CMD_SUCCESS;
10943 }
10944
10945 DEFUN (bgp_damp_set,
10946 bgp_damp_set_cmd,
10947 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10948 "BGP Specific commands\n"
10949 "Enable route-flap dampening\n"
10950 "Half-life time for the penalty\n"
10951 "Value to start reusing a route\n"
10952 "Value to start suppressing a route\n"
10953 "Maximum duration to suppress a stable route\n")
10954 {
10955 VTY_DECLVAR_CONTEXT(bgp, bgp);
10956 int idx_half_life = 2;
10957 int idx_reuse = 3;
10958 int idx_suppress = 4;
10959 int idx_max_suppress = 5;
10960 int half = DEFAULT_HALF_LIFE * 60;
10961 int reuse = DEFAULT_REUSE;
10962 int suppress = DEFAULT_SUPPRESS;
10963 int max = 4 * half;
10964
10965 if (argc == 6) {
10966 half = atoi(argv[idx_half_life]->arg) * 60;
10967 reuse = atoi(argv[idx_reuse]->arg);
10968 suppress = atoi(argv[idx_suppress]->arg);
10969 max = atoi(argv[idx_max_suppress]->arg) * 60;
10970 } else if (argc == 3) {
10971 half = atoi(argv[idx_half_life]->arg) * 60;
10972 max = 4 * half;
10973 }
10974
10975 if (suppress < reuse) {
10976 vty_out(vty,
10977 "Suppress value cannot be less than reuse value \n");
10978 return 0;
10979 }
10980
10981 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
10982 reuse, suppress, max);
10983 }
10984
10985 DEFUN (bgp_damp_unset,
10986 bgp_damp_unset_cmd,
10987 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10988 NO_STR
10989 "BGP Specific commands\n"
10990 "Enable route-flap dampening\n"
10991 "Half-life time for the penalty\n"
10992 "Value to start reusing a route\n"
10993 "Value to start suppressing a route\n"
10994 "Maximum duration to suppress a stable route\n")
10995 {
10996 VTY_DECLVAR_CONTEXT(bgp, bgp);
10997 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
10998 }
10999
11000 /* Display specified route of BGP table. */
11001 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
11002 const char *ip_str, afi_t afi, safi_t safi,
11003 struct prefix_rd *prd, int prefix_check)
11004 {
11005 int ret;
11006 struct prefix match;
11007 struct bgp_node *rn;
11008 struct bgp_node *rm;
11009 struct bgp_info *ri;
11010 struct bgp_info *ri_temp;
11011 struct bgp *bgp;
11012 struct bgp_table *table;
11013
11014 /* BGP structure lookup. */
11015 if (view_name) {
11016 bgp = bgp_lookup_by_name(view_name);
11017 if (bgp == NULL) {
11018 vty_out(vty, "%% Can't find BGP instance %s\n",
11019 view_name);
11020 return CMD_WARNING;
11021 }
11022 } else {
11023 bgp = bgp_get_default();
11024 if (bgp == NULL) {
11025 vty_out(vty, "%% No BGP process is configured\n");
11026 return CMD_WARNING;
11027 }
11028 }
11029
11030 /* Check IP address argument. */
11031 ret = str2prefix(ip_str, &match);
11032 if (!ret) {
11033 vty_out(vty, "%% address is malformed\n");
11034 return CMD_WARNING;
11035 }
11036
11037 match.family = afi2family(afi);
11038
11039 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
11040 || (safi == SAFI_EVPN)) {
11041 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
11042 rn = bgp_route_next(rn)) {
11043 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
11044 continue;
11045 if ((table = rn->info) == NULL)
11046 continue;
11047 if ((rm = bgp_node_match(table, &match)) == NULL)
11048 continue;
11049
11050 if (!prefix_check
11051 || rm->p.prefixlen == match.prefixlen) {
11052 ri = rm->info;
11053 while (ri) {
11054 if (ri->extra && ri->extra->damp_info) {
11055 ri_temp = ri->next;
11056 bgp_damp_info_free(
11057 ri->extra->damp_info,
11058 1);
11059 ri = ri_temp;
11060 } else
11061 ri = ri->next;
11062 }
11063 }
11064
11065 bgp_unlock_node(rm);
11066 }
11067 } else {
11068 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
11069 != NULL) {
11070 if (!prefix_check
11071 || rn->p.prefixlen == match.prefixlen) {
11072 ri = rn->info;
11073 while (ri) {
11074 if (ri->extra && ri->extra->damp_info) {
11075 ri_temp = ri->next;
11076 bgp_damp_info_free(
11077 ri->extra->damp_info,
11078 1);
11079 ri = ri_temp;
11080 } else
11081 ri = ri->next;
11082 }
11083 }
11084
11085 bgp_unlock_node(rn);
11086 }
11087 }
11088
11089 return CMD_SUCCESS;
11090 }
11091
11092 DEFUN (clear_ip_bgp_dampening,
11093 clear_ip_bgp_dampening_cmd,
11094 "clear ip bgp dampening",
11095 CLEAR_STR
11096 IP_STR
11097 BGP_STR
11098 "Clear route flap dampening information\n")
11099 {
11100 bgp_damp_info_clean();
11101 return CMD_SUCCESS;
11102 }
11103
11104 DEFUN (clear_ip_bgp_dampening_prefix,
11105 clear_ip_bgp_dampening_prefix_cmd,
11106 "clear ip bgp dampening A.B.C.D/M",
11107 CLEAR_STR
11108 IP_STR
11109 BGP_STR
11110 "Clear route flap dampening information\n"
11111 "IPv4 prefix\n")
11112 {
11113 int idx_ipv4_prefixlen = 4;
11114 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
11115 AFI_IP, SAFI_UNICAST, NULL, 1);
11116 }
11117
11118 DEFUN (clear_ip_bgp_dampening_address,
11119 clear_ip_bgp_dampening_address_cmd,
11120 "clear ip bgp dampening A.B.C.D",
11121 CLEAR_STR
11122 IP_STR
11123 BGP_STR
11124 "Clear route flap dampening information\n"
11125 "Network to clear damping information\n")
11126 {
11127 int idx_ipv4 = 4;
11128 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
11129 SAFI_UNICAST, NULL, 0);
11130 }
11131
11132 DEFUN (clear_ip_bgp_dampening_address_mask,
11133 clear_ip_bgp_dampening_address_mask_cmd,
11134 "clear ip bgp dampening A.B.C.D A.B.C.D",
11135 CLEAR_STR
11136 IP_STR
11137 BGP_STR
11138 "Clear route flap dampening information\n"
11139 "Network to clear damping information\n"
11140 "Network mask\n")
11141 {
11142 int idx_ipv4 = 4;
11143 int idx_ipv4_2 = 5;
11144 int ret;
11145 char prefix_str[BUFSIZ];
11146
11147 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
11148 prefix_str);
11149 if (!ret) {
11150 vty_out(vty, "%% Inconsistent address and mask\n");
11151 return CMD_WARNING;
11152 }
11153
11154 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
11155 NULL, 0);
11156 }
11157
11158 /* also used for encap safi */
11159 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
11160 afi_t afi, safi_t safi)
11161 {
11162 struct bgp_node *prn;
11163 struct bgp_node *rn;
11164 struct bgp_table *table;
11165 struct prefix *p;
11166 struct prefix_rd *prd;
11167 struct bgp_static *bgp_static;
11168 mpls_label_t label;
11169 char buf[SU_ADDRSTRLEN];
11170 char rdbuf[RD_ADDRSTRLEN];
11171
11172 /* Network configuration. */
11173 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11174 prn = bgp_route_next(prn)) {
11175 if ((table = prn->info) == NULL)
11176 continue;
11177
11178 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11179 if ((bgp_static = rn->info) == NULL)
11180 continue;
11181
11182 p = &rn->p;
11183 prd = (struct prefix_rd *)&prn->p;
11184
11185 /* "network" configuration display. */
11186 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11187 label = decode_label(&bgp_static->label);
11188
11189 vty_out(vty, " network %s/%d rd %s",
11190 inet_ntop(p->family, &p->u.prefix, buf,
11191 SU_ADDRSTRLEN),
11192 p->prefixlen, rdbuf);
11193 if (safi == SAFI_MPLS_VPN)
11194 vty_out(vty, " label %u", label);
11195
11196 if (bgp_static->rmap.name)
11197 vty_out(vty, " route-map %s",
11198 bgp_static->rmap.name);
11199
11200 if (bgp_static->backdoor)
11201 vty_out(vty, " backdoor");
11202
11203 vty_out(vty, "\n");
11204 }
11205 }
11206 }
11207
11208 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
11209 afi_t afi, safi_t safi)
11210 {
11211 struct bgp_node *prn;
11212 struct bgp_node *rn;
11213 struct bgp_table *table;
11214 struct prefix *p;
11215 struct prefix_rd *prd;
11216 struct bgp_static *bgp_static;
11217 char buf[PREFIX_STRLEN];
11218 char buf2[SU_ADDRSTRLEN];
11219 char rdbuf[RD_ADDRSTRLEN];
11220
11221 /* Network configuration. */
11222 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11223 prn = bgp_route_next(prn)) {
11224 if ((table = prn->info) == NULL)
11225 continue;
11226
11227 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11228 if ((bgp_static = rn->info) == NULL)
11229 continue;
11230
11231 char *macrouter = NULL;
11232 char *esi = NULL;
11233
11234 if (bgp_static->router_mac)
11235 macrouter = prefix_mac2str(
11236 bgp_static->router_mac, NULL, 0);
11237 if (bgp_static->eth_s_id)
11238 esi = esi2str(bgp_static->eth_s_id);
11239 p = &rn->p;
11240 prd = (struct prefix_rd *)&prn->p;
11241
11242 /* "network" configuration display. */
11243 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11244 if (p->u.prefix_evpn.route_type == 5) {
11245 char local_buf[PREFIX_STRLEN];
11246 uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((
11247 struct prefix_evpn *)p)
11248 ? AF_INET
11249 : AF_INET6;
11250 inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr,
11251 local_buf, PREFIX_STRLEN);
11252 sprintf(buf, "%s/%u", local_buf,
11253 p->u.prefix_evpn.ip_prefix_length);
11254 } else {
11255 prefix2str(p, buf, sizeof(buf));
11256 }
11257
11258 if (bgp_static->gatewayIp.family == AF_INET
11259 || bgp_static->gatewayIp.family == AF_INET6)
11260 inet_ntop(bgp_static->gatewayIp.family,
11261 &bgp_static->gatewayIp.u.prefix, buf2,
11262 sizeof(buf2));
11263 vty_out(vty,
11264 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11265 buf, rdbuf, p->u.prefix_evpn.eth_tag,
11266 decode_label(&bgp_static->label), esi, buf2,
11267 macrouter);
11268
11269 if (macrouter)
11270 XFREE(MTYPE_TMP, macrouter);
11271 if (esi)
11272 XFREE(MTYPE_TMP, esi);
11273 }
11274 }
11275 }
11276
11277 /* Configuration of static route announcement and aggregate
11278 information. */
11279 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
11280 safi_t safi)
11281 {
11282 struct bgp_node *rn;
11283 struct prefix *p;
11284 struct bgp_static *bgp_static;
11285 struct bgp_aggregate *bgp_aggregate;
11286 char buf[SU_ADDRSTRLEN];
11287
11288 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
11289 bgp_config_write_network_vpn(vty, bgp, afi, safi);
11290 return;
11291 }
11292
11293 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
11294 bgp_config_write_network_evpn(vty, bgp, afi, safi);
11295 return;
11296 }
11297
11298 /* Network configuration. */
11299 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
11300 rn = bgp_route_next(rn)) {
11301 if ((bgp_static = rn->info) == NULL)
11302 continue;
11303
11304 p = &rn->p;
11305
11306 /* "network" configuration display. */
11307 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11308 uint32_t destination;
11309 struct in_addr netmask;
11310
11311 destination = ntohl(p->u.prefix4.s_addr);
11312 masklen2ip(p->prefixlen, &netmask);
11313 vty_out(vty, " network %s",
11314 inet_ntop(p->family, &p->u.prefix, buf,
11315 SU_ADDRSTRLEN));
11316
11317 if ((IN_CLASSC(destination) && p->prefixlen == 24)
11318 || (IN_CLASSB(destination) && p->prefixlen == 16)
11319 || (IN_CLASSA(destination) && p->prefixlen == 8)
11320 || p->u.prefix4.s_addr == 0) {
11321 /* Natural mask is not display. */
11322 } else
11323 vty_out(vty, " mask %s", inet_ntoa(netmask));
11324 } else {
11325 vty_out(vty, " network %s/%d",
11326 inet_ntop(p->family, &p->u.prefix, buf,
11327 SU_ADDRSTRLEN),
11328 p->prefixlen);
11329 }
11330
11331 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
11332 vty_out(vty, " label-index %u",
11333 bgp_static->label_index);
11334
11335 if (bgp_static->rmap.name)
11336 vty_out(vty, " route-map %s", bgp_static->rmap.name);
11337
11338 if (bgp_static->backdoor)
11339 vty_out(vty, " backdoor");
11340
11341 vty_out(vty, "\n");
11342 }
11343
11344 /* Aggregate-address configuration. */
11345 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
11346 rn = bgp_route_next(rn)) {
11347 if ((bgp_aggregate = rn->info) == NULL)
11348 continue;
11349
11350 p = &rn->p;
11351
11352 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11353 struct in_addr netmask;
11354
11355 masklen2ip(p->prefixlen, &netmask);
11356 vty_out(vty, " aggregate-address %s %s",
11357 inet_ntop(p->family, &p->u.prefix, buf,
11358 SU_ADDRSTRLEN),
11359 inet_ntoa(netmask));
11360 } else {
11361 vty_out(vty, " aggregate-address %s/%d",
11362 inet_ntop(p->family, &p->u.prefix, buf,
11363 SU_ADDRSTRLEN),
11364 p->prefixlen);
11365 }
11366
11367 if (bgp_aggregate->as_set)
11368 vty_out(vty, " as-set");
11369
11370 if (bgp_aggregate->summary_only)
11371 vty_out(vty, " summary-only");
11372
11373 vty_out(vty, "\n");
11374 }
11375 }
11376
11377 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
11378 safi_t safi)
11379 {
11380 struct bgp_node *rn;
11381 struct bgp_distance *bdistance;
11382
11383 /* Distance configuration. */
11384 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
11385 && bgp->distance_local[afi][safi]
11386 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
11387 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
11388 || bgp->distance_local[afi][safi]
11389 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
11390 vty_out(vty, " distance bgp %d %d %d\n",
11391 bgp->distance_ebgp[afi][safi],
11392 bgp->distance_ibgp[afi][safi],
11393 bgp->distance_local[afi][safi]);
11394 }
11395
11396 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
11397 rn = bgp_route_next(rn))
11398 if ((bdistance = rn->info) != NULL) {
11399 char buf[PREFIX_STRLEN];
11400
11401 vty_out(vty, " distance %d %s %s\n",
11402 bdistance->distance,
11403 prefix2str(&rn->p, buf, sizeof(buf)),
11404 bdistance->access_list ? bdistance->access_list
11405 : "");
11406 }
11407 }
11408
11409 /* Allocate routing table structure and install commands. */
11410 void bgp_route_init(void)
11411 {
11412 afi_t afi;
11413 safi_t safi;
11414
11415 /* Init BGP distance table. */
11416 FOREACH_AFI_SAFI (afi, safi)
11417 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
11418
11419 /* IPv4 BGP commands. */
11420 install_element(BGP_NODE, &bgp_table_map_cmd);
11421 install_element(BGP_NODE, &bgp_network_cmd);
11422 install_element(BGP_NODE, &no_bgp_table_map_cmd);
11423
11424 install_element(BGP_NODE, &aggregate_address_cmd);
11425 install_element(BGP_NODE, &aggregate_address_mask_cmd);
11426 install_element(BGP_NODE, &no_aggregate_address_cmd);
11427 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
11428
11429 /* IPv4 unicast configuration. */
11430 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
11431 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
11432 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
11433
11434 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
11435 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
11436 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
11437 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
11438
11439 /* IPv4 multicast configuration. */
11440 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
11441 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
11442 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
11443 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
11444 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
11445 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
11446 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
11447
11448 /* IPv4 labeled-unicast configuration. */
11449 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
11450 install_element(VIEW_NODE, &show_ip_bgp_cmd);
11451 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
11452 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
11453 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
11454
11455 install_element(VIEW_NODE,
11456 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
11457 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
11458 install_element(VIEW_NODE,
11459 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
11460 #ifdef KEEP_OLD_VPN_COMMANDS
11461 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
11462 #endif /* KEEP_OLD_VPN_COMMANDS */
11463 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
11464 install_element(VIEW_NODE,
11465 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
11466
11467 /* BGP dampening clear commands */
11468 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
11469 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
11470
11471 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
11472 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
11473
11474 /* prefix count */
11475 install_element(ENABLE_NODE,
11476 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
11477 #ifdef KEEP_OLD_VPN_COMMANDS
11478 install_element(ENABLE_NODE,
11479 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
11480 #endif /* KEEP_OLD_VPN_COMMANDS */
11481
11482 /* New config IPv6 BGP commands. */
11483 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
11484 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
11485 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
11486
11487 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
11488 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
11489
11490 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
11491
11492 install_element(BGP_NODE, &bgp_distance_cmd);
11493 install_element(BGP_NODE, &no_bgp_distance_cmd);
11494 install_element(BGP_NODE, &bgp_distance_source_cmd);
11495 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
11496 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
11497 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
11498 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
11499 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
11500 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
11501 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
11502 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
11503 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
11504 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
11505 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
11506 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
11507 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
11508 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
11509 install_element(BGP_IPV4M_NODE,
11510 &no_bgp_distance_source_access_list_cmd);
11511 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
11512 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
11513 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
11514 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
11515 install_element(BGP_IPV6_NODE,
11516 &ipv6_bgp_distance_source_access_list_cmd);
11517 install_element(BGP_IPV6_NODE,
11518 &no_ipv6_bgp_distance_source_access_list_cmd);
11519 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
11520 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
11521 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
11522 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
11523 install_element(BGP_IPV6M_NODE,
11524 &ipv6_bgp_distance_source_access_list_cmd);
11525 install_element(BGP_IPV6M_NODE,
11526 &no_ipv6_bgp_distance_source_access_list_cmd);
11527
11528 install_element(BGP_NODE, &bgp_damp_set_cmd);
11529 install_element(BGP_NODE, &bgp_damp_unset_cmd);
11530 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
11531 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
11532
11533 /* IPv4 Multicast Mode */
11534 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
11535 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
11536
11537 /* Large Communities */
11538 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
11539 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
11540
11541 /* show bgp ipv4 flowspec detailed */
11542 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
11543
11544 }
11545
11546 void bgp_route_finish(void)
11547 {
11548 afi_t afi;
11549 safi_t safi;
11550
11551 FOREACH_AFI_SAFI (afi, safi) {
11552 bgp_table_unlock(bgp_distance_table[afi][safi]);
11553 bgp_distance_table[afi][safi] = NULL;
11554 }
11555 }