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