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