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