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