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