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