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