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