]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #3040 from pacovn/static_analysis__drop_const_1
[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(EC_LIB_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
4044 /* look for neighbor in tables */
4045 if ((table = rn->info) == NULL)
4046 continue;
4047
4048 for (rm = bgp_table_top(table); rm;
4049 rm = bgp_route_next(rm))
4050 for (ri = rm->info; ri; ri = ri->next) {
4051 if (ri->peer != peer)
4052 continue;
4053 if (!CHECK_FLAG(ri->flags,
4054 BGP_INFO_STALE))
4055 break;
4056
4057 bgp_rib_remove(rm, ri, peer, afi, safi);
4058 break;
4059 }
4060 }
4061 } else {
4062 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4063 rn = bgp_route_next(rn))
4064 for (ri = rn->info; ri; ri = ri->next) {
4065 if (ri->peer != peer)
4066 continue;
4067 if (!CHECK_FLAG(ri->flags, BGP_INFO_STALE))
4068 break;
4069 bgp_rib_remove(rn, ri, peer, afi, safi);
4070 break;
4071 }
4072 }
4073 }
4074
4075 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4076 safi_t safi)
4077 {
4078 struct bgp_node *rn;
4079 struct bgp_info *ri;
4080 struct bgp_info *next;
4081
4082 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4083 for (ri = rn->info; ri; ri = next) {
4084 next = ri->next;
4085 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
4086 && ri->type == ZEBRA_ROUTE_BGP
4087 && (ri->sub_type == BGP_ROUTE_NORMAL
4088 || ri->sub_type == BGP_ROUTE_AGGREGATE
4089 || ri->sub_type == BGP_ROUTE_IMPORTED)) {
4090
4091 if (bgp_fibupd_safi(safi))
4092 bgp_zebra_withdraw(&rn->p, ri,
4093 bgp, safi);
4094 bgp_info_reap(rn, ri);
4095 }
4096 }
4097 }
4098
4099 /* Delete all kernel routes. */
4100 void bgp_cleanup_routes(struct bgp *bgp)
4101 {
4102 afi_t afi;
4103 struct bgp_node *rn;
4104
4105 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4106 if (afi == AFI_L2VPN)
4107 continue;
4108 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4109 SAFI_UNICAST);
4110 /*
4111 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4112 */
4113 if (afi != AFI_L2VPN) {
4114 safi_t safi;
4115 safi = SAFI_MPLS_VPN;
4116 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4117 rn = bgp_route_next(rn)) {
4118 if (rn->info) {
4119 bgp_cleanup_table(bgp,
4120 (struct bgp_table *)(rn->info),
4121 safi);
4122 bgp_table_finish((struct bgp_table **)&(
4123 rn->info));
4124 rn->info = NULL;
4125 bgp_unlock_node(rn);
4126 }
4127 }
4128 safi = SAFI_ENCAP;
4129 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4130 rn = bgp_route_next(rn)) {
4131 if (rn->info) {
4132 bgp_cleanup_table(bgp,
4133 (struct bgp_table *)(rn->info),
4134 safi);
4135 bgp_table_finish((struct bgp_table **)&(
4136 rn->info));
4137 rn->info = NULL;
4138 bgp_unlock_node(rn);
4139 }
4140 }
4141 }
4142 }
4143 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
4144 rn = bgp_route_next(rn)) {
4145 if (rn->info) {
4146 bgp_cleanup_table(bgp,
4147 (struct bgp_table *)(rn->info),
4148 SAFI_EVPN);
4149 bgp_table_finish((struct bgp_table **)&(rn->info));
4150 rn->info = NULL;
4151 bgp_unlock_node(rn);
4152 }
4153 }
4154 }
4155
4156 void bgp_reset(void)
4157 {
4158 vty_reset();
4159 bgp_zclient_reset();
4160 access_list_reset();
4161 prefix_list_reset();
4162 }
4163
4164 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4165 {
4166 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4167 && CHECK_FLAG(peer->af_cap[afi][safi],
4168 PEER_CAP_ADDPATH_AF_TX_RCV));
4169 }
4170
4171 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4172 value. */
4173 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4174 struct bgp_nlri *packet)
4175 {
4176 uint8_t *pnt;
4177 uint8_t *lim;
4178 struct prefix p;
4179 int psize;
4180 int ret;
4181 afi_t afi;
4182 safi_t safi;
4183 int addpath_encoded;
4184 uint32_t addpath_id;
4185
4186 pnt = packet->nlri;
4187 lim = pnt + packet->length;
4188 afi = packet->afi;
4189 safi = packet->safi;
4190 addpath_id = 0;
4191 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4192
4193 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4194 syntactic validity. If the field is syntactically incorrect,
4195 then the Error Subcode is set to Invalid Network Field. */
4196 for (; pnt < lim; pnt += psize) {
4197 /* Clear prefix structure. */
4198 memset(&p, 0, sizeof(struct prefix));
4199
4200 if (addpath_encoded) {
4201
4202 /* When packet overflow occurs return immediately. */
4203 if (pnt + BGP_ADDPATH_ID_LEN > lim)
4204 return -1;
4205
4206 addpath_id = ntohl(*((uint32_t *)pnt));
4207 pnt += BGP_ADDPATH_ID_LEN;
4208 }
4209
4210 /* Fetch prefix length. */
4211 p.prefixlen = *pnt++;
4212 /* afi/safi validity already verified by caller,
4213 * bgp_update_receive */
4214 p.family = afi2family(afi);
4215
4216 /* Prefix length check. */
4217 if (p.prefixlen > prefix_blen(&p) * 8) {
4218 flog_err(
4219 EC_BGP_UPDATE_RCV,
4220 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4221 peer->host, p.prefixlen, packet->afi);
4222 return -1;
4223 }
4224
4225 /* Packet size overflow check. */
4226 psize = PSIZE(p.prefixlen);
4227
4228 /* When packet overflow occur return immediately. */
4229 if (pnt + psize > lim) {
4230 flog_err(
4231 EC_BGP_UPDATE_RCV,
4232 "%s [Error] Update packet error (prefix length %d overflows packet)",
4233 peer->host, p.prefixlen);
4234 return -1;
4235 }
4236
4237 /* Defensive coding, double-check the psize fits in a struct
4238 * prefix */
4239 if (psize > (ssize_t)sizeof(p.u)) {
4240 flog_err(
4241 EC_BGP_UPDATE_RCV,
4242 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4243 peer->host, p.prefixlen, sizeof(p.u));
4244 return -1;
4245 }
4246
4247 /* Fetch prefix from NLRI packet. */
4248 memcpy(p.u.val, pnt, psize);
4249
4250 /* Check address. */
4251 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4252 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4253 /* From RFC4271 Section 6.3:
4254 *
4255 * If a prefix in the NLRI field is semantically
4256 * incorrect
4257 * (e.g., an unexpected multicast IP address),
4258 * an error SHOULD
4259 * be logged locally, and the prefix SHOULD be
4260 * ignored.
4261 */
4262 flog_err(
4263 EC_BGP_UPDATE_RCV,
4264 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4265 peer->host, inet_ntoa(p.u.prefix4));
4266 continue;
4267 }
4268 }
4269
4270 /* Check address. */
4271 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4272 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4273 char buf[BUFSIZ];
4274
4275 flog_err(
4276 EC_BGP_UPDATE_RCV,
4277 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4278 peer->host,
4279 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4280 BUFSIZ));
4281
4282 continue;
4283 }
4284 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
4285 char buf[BUFSIZ];
4286
4287 flog_err(
4288 EC_BGP_UPDATE_RCV,
4289 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4290 peer->host,
4291 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4292 BUFSIZ));
4293
4294 continue;
4295 }
4296 }
4297
4298 /* Normal process. */
4299 if (attr)
4300 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
4301 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
4302 NULL, NULL, 0, 0, NULL);
4303 else
4304 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
4305 safi, ZEBRA_ROUTE_BGP,
4306 BGP_ROUTE_NORMAL, NULL, NULL, 0,
4307 NULL);
4308
4309 /* Address family configuration mismatch or maximum-prefix count
4310 overflow. */
4311 if (ret < 0)
4312 return -1;
4313 }
4314
4315 /* Packet length consistency check. */
4316 if (pnt != lim) {
4317 flog_err(
4318 EC_BGP_UPDATE_RCV,
4319 "%s [Error] Update packet error (prefix length mismatch with total length)",
4320 peer->host);
4321 return -1;
4322 }
4323
4324 return 0;
4325 }
4326
4327 static struct bgp_static *bgp_static_new(void)
4328 {
4329 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
4330 }
4331
4332 static void bgp_static_free(struct bgp_static *bgp_static)
4333 {
4334 if (bgp_static->rmap.name)
4335 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4336 if (bgp_static->eth_s_id)
4337 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4338 XFREE(MTYPE_BGP_STATIC, bgp_static);
4339 }
4340
4341 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4342 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4343 {
4344 struct bgp_node *rn;
4345 struct bgp_info *ri;
4346 struct bgp_info *new;
4347 struct bgp_info info;
4348 struct attr attr;
4349 struct attr *attr_new;
4350 int ret;
4351 #if ENABLE_BGP_VNC
4352 int vnc_implicit_withdraw = 0;
4353 #endif
4354
4355 assert(bgp_static);
4356 if (!bgp_static)
4357 return;
4358
4359 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4360
4361 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4362
4363 attr.nexthop = bgp_static->igpnexthop;
4364 attr.med = bgp_static->igpmetric;
4365 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4366
4367 if (bgp_static->atomic)
4368 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4369
4370 /* Store label index, if required. */
4371 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4372 attr.label_index = bgp_static->label_index;
4373 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4374 }
4375
4376 /* Apply route-map. */
4377 if (bgp_static->rmap.name) {
4378 struct attr attr_tmp = attr;
4379
4380 memset(&info, 0, sizeof(struct bgp_info));
4381 info.peer = bgp->peer_self;
4382 info.attr = &attr_tmp;
4383
4384 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4385
4386 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
4387
4388 bgp->peer_self->rmap_type = 0;
4389
4390 if (ret == RMAP_DENYMATCH) {
4391 /* Free uninterned attribute. */
4392 bgp_attr_flush(&attr_tmp);
4393
4394 /* Unintern original. */
4395 aspath_unintern(&attr.aspath);
4396 bgp_static_withdraw(bgp, p, afi, safi);
4397 return;
4398 }
4399
4400 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4401 bgp_attr_add_gshut_community(&attr_tmp);
4402
4403 attr_new = bgp_attr_intern(&attr_tmp);
4404 } else {
4405
4406 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4407 bgp_attr_add_gshut_community(&attr);
4408
4409 attr_new = bgp_attr_intern(&attr);
4410 }
4411
4412 for (ri = rn->info; ri; ri = ri->next)
4413 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4414 && ri->sub_type == BGP_ROUTE_STATIC)
4415 break;
4416
4417 if (ri) {
4418 if (attrhash_cmp(ri->attr, attr_new)
4419 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
4420 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4421 bgp_unlock_node(rn);
4422 bgp_attr_unintern(&attr_new);
4423 aspath_unintern(&attr.aspath);
4424 return;
4425 } else {
4426 /* The attribute is changed. */
4427 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
4428
4429 /* Rewrite BGP route information. */
4430 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4431 bgp_info_restore(rn, ri);
4432 else
4433 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4434 #if ENABLE_BGP_VNC
4435 if ((afi == AFI_IP || afi == AFI_IP6)
4436 && (safi == SAFI_UNICAST)) {
4437 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
4438 /*
4439 * Implicit withdraw case.
4440 * We have to do this before ri is
4441 * changed
4442 */
4443 ++vnc_implicit_withdraw;
4444 vnc_import_bgp_del_route(bgp, p, ri);
4445 vnc_import_bgp_exterior_del_route(
4446 bgp, p, ri);
4447 }
4448 }
4449 #endif
4450 bgp_attr_unintern(&ri->attr);
4451 ri->attr = attr_new;
4452 ri->uptime = bgp_clock();
4453 #if ENABLE_BGP_VNC
4454 if ((afi == AFI_IP || afi == AFI_IP6)
4455 && (safi == SAFI_UNICAST)) {
4456 if (vnc_implicit_withdraw) {
4457 vnc_import_bgp_add_route(bgp, p, ri);
4458 vnc_import_bgp_exterior_add_route(
4459 bgp, p, ri);
4460 }
4461 }
4462 #endif
4463
4464 /* Nexthop reachability check. */
4465 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4466 && (safi == SAFI_UNICAST
4467 || safi == SAFI_LABELED_UNICAST)) {
4468
4469 struct bgp *bgp_nexthop = bgp;
4470
4471 if (ri->extra && ri->extra->bgp_orig)
4472 bgp_nexthop = ri->extra->bgp_orig;
4473
4474 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
4475 afi, ri, NULL, 0))
4476 bgp_info_set_flag(rn, ri,
4477 BGP_INFO_VALID);
4478 else {
4479 if (BGP_DEBUG(nht, NHT)) {
4480 char buf1[INET6_ADDRSTRLEN];
4481 inet_ntop(p->family,
4482 &p->u.prefix, buf1,
4483 INET6_ADDRSTRLEN);
4484 zlog_debug(
4485 "%s(%s): Route not in table, not advertising",
4486 __FUNCTION__, buf1);
4487 }
4488 bgp_info_unset_flag(rn, ri,
4489 BGP_INFO_VALID);
4490 }
4491 } else {
4492 /* Delete the NHT structure if any, if we're
4493 * toggling between
4494 * enabling/disabling import check. We
4495 * deregister the route
4496 * from NHT to avoid overloading NHT and the
4497 * process interaction
4498 */
4499 bgp_unlink_nexthop(ri);
4500 bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
4501 }
4502 /* Process change. */
4503 bgp_aggregate_increment(bgp, p, ri, afi, safi);
4504 bgp_process(bgp, rn, afi, safi);
4505
4506 if (SAFI_UNICAST == safi
4507 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4508 || bgp->inst_type
4509 == BGP_INSTANCE_TYPE_DEFAULT)) {
4510 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
4511 ri);
4512 }
4513
4514 bgp_unlock_node(rn);
4515 aspath_unintern(&attr.aspath);
4516 return;
4517 }
4518 }
4519
4520 /* Make new BGP info. */
4521 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4522 attr_new, rn);
4523 /* Nexthop reachability check. */
4524 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4525 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4526 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
4527 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
4528 else {
4529 if (BGP_DEBUG(nht, NHT)) {
4530 char buf1[INET6_ADDRSTRLEN];
4531 inet_ntop(p->family, &p->u.prefix, buf1,
4532 INET6_ADDRSTRLEN);
4533 zlog_debug(
4534 "%s(%s): Route not in table, not advertising",
4535 __FUNCTION__, buf1);
4536 }
4537 bgp_info_unset_flag(rn, new, BGP_INFO_VALID);
4538 }
4539 } else {
4540 /* Delete the NHT structure if any, if we're toggling between
4541 * enabling/disabling import check. We deregister the route
4542 * from NHT to avoid overloading NHT and the process interaction
4543 */
4544 bgp_unlink_nexthop(new);
4545
4546 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
4547 }
4548
4549 /* Aggregate address increment. */
4550 bgp_aggregate_increment(bgp, p, new, afi, safi);
4551
4552 /* Register new BGP information. */
4553 bgp_info_add(rn, new);
4554
4555 /* route_node_get lock */
4556 bgp_unlock_node(rn);
4557
4558 /* Process change. */
4559 bgp_process(bgp, rn, afi, safi);
4560
4561 if (SAFI_UNICAST == safi
4562 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4563 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4564 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4565 }
4566
4567 /* Unintern original. */
4568 aspath_unintern(&attr.aspath);
4569 }
4570
4571 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4572 safi_t safi)
4573 {
4574 struct bgp_node *rn;
4575 struct bgp_info *ri;
4576
4577 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4578
4579 /* Check selected route and self inserted route. */
4580 for (ri = rn->info; ri; ri = ri->next)
4581 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4582 && ri->sub_type == BGP_ROUTE_STATIC)
4583 break;
4584
4585 /* Withdraw static BGP route from routing table. */
4586 if (ri) {
4587 if (SAFI_UNICAST == safi
4588 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4589 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4590 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, ri);
4591 }
4592 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4593 bgp_unlink_nexthop(ri);
4594 bgp_info_delete(rn, ri);
4595 bgp_process(bgp, rn, afi, safi);
4596 }
4597
4598 /* Unlock bgp_node_lookup. */
4599 bgp_unlock_node(rn);
4600 }
4601
4602 /*
4603 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4604 */
4605 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4606 afi_t afi, safi_t safi,
4607 struct prefix_rd *prd)
4608 {
4609 struct bgp_node *rn;
4610 struct bgp_info *ri;
4611
4612 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4613
4614 /* Check selected route and self inserted route. */
4615 for (ri = rn->info; ri; ri = ri->next)
4616 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4617 && ri->sub_type == BGP_ROUTE_STATIC)
4618 break;
4619
4620 /* Withdraw static BGP route from routing table. */
4621 if (ri) {
4622 #if ENABLE_BGP_VNC
4623 rfapiProcessWithdraw(
4624 ri->peer, NULL, p, prd, ri->attr, afi, safi, ri->type,
4625 1); /* Kill, since it is an administrative change */
4626 #endif
4627 if (SAFI_MPLS_VPN == safi
4628 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4629 vpn_leak_to_vrf_withdraw(bgp, ri);
4630 }
4631 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4632 bgp_info_delete(rn, ri);
4633 bgp_process(bgp, rn, afi, safi);
4634 }
4635
4636 /* Unlock bgp_node_lookup. */
4637 bgp_unlock_node(rn);
4638 }
4639
4640 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4641 struct bgp_static *bgp_static, afi_t afi,
4642 safi_t safi)
4643 {
4644 struct bgp_node *rn;
4645 struct bgp_info *new;
4646 struct attr *attr_new;
4647 struct attr attr = {0};
4648 struct bgp_info *ri;
4649 #if ENABLE_BGP_VNC
4650 mpls_label_t label = 0;
4651 #endif
4652 uint32_t num_labels = 0;
4653 union gw_addr add;
4654
4655 assert(bgp_static);
4656
4657 if (bgp_static->label != MPLS_INVALID_LABEL)
4658 num_labels = 1;
4659 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4660 &bgp_static->prd);
4661
4662 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4663
4664 attr.nexthop = bgp_static->igpnexthop;
4665 attr.med = bgp_static->igpmetric;
4666 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4667
4668 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4669 || (safi == SAFI_ENCAP)) {
4670 if (afi == AFI_IP) {
4671 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4672 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4673 }
4674 }
4675 if (afi == AFI_L2VPN) {
4676 if (bgp_static->gatewayIp.family == AF_INET)
4677 add.ipv4.s_addr =
4678 bgp_static->gatewayIp.u.prefix4.s_addr;
4679 else if (bgp_static->gatewayIp.family == AF_INET6)
4680 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4681 sizeof(struct in6_addr));
4682 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4683 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
4684 struct bgp_encap_type_vxlan bet;
4685 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4686 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
4687 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4688 }
4689 if (bgp_static->router_mac) {
4690 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
4691 }
4692 }
4693 /* Apply route-map. */
4694 if (bgp_static->rmap.name) {
4695 struct attr attr_tmp = attr;
4696 struct bgp_info info;
4697 int ret;
4698
4699 info.peer = bgp->peer_self;
4700 info.attr = &attr_tmp;
4701
4702 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4703
4704 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
4705
4706 bgp->peer_self->rmap_type = 0;
4707
4708 if (ret == RMAP_DENYMATCH) {
4709 /* Free uninterned attribute. */
4710 bgp_attr_flush(&attr_tmp);
4711
4712 /* Unintern original. */
4713 aspath_unintern(&attr.aspath);
4714 bgp_static_withdraw_safi(bgp, p, afi, safi,
4715 &bgp_static->prd);
4716 return;
4717 }
4718
4719 attr_new = bgp_attr_intern(&attr_tmp);
4720 } else {
4721 attr_new = bgp_attr_intern(&attr);
4722 }
4723
4724 for (ri = rn->info; ri; ri = ri->next)
4725 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4726 && ri->sub_type == BGP_ROUTE_STATIC)
4727 break;
4728
4729 if (ri) {
4730 memset(&add, 0, sizeof(union gw_addr));
4731 if (attrhash_cmp(ri->attr, attr_new)
4732 && overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
4733 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
4734 bgp_unlock_node(rn);
4735 bgp_attr_unintern(&attr_new);
4736 aspath_unintern(&attr.aspath);
4737 return;
4738 } else {
4739 /* The attribute is changed. */
4740 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
4741
4742 /* Rewrite BGP route information. */
4743 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4744 bgp_info_restore(rn, ri);
4745 else
4746 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4747 bgp_attr_unintern(&ri->attr);
4748 ri->attr = attr_new;
4749 ri->uptime = bgp_clock();
4750 #if ENABLE_BGP_VNC
4751 if (ri->extra)
4752 label = decode_label(&ri->extra->label[0]);
4753 #endif
4754
4755 /* Process change. */
4756 bgp_aggregate_increment(bgp, p, ri, afi, safi);
4757 bgp_process(bgp, rn, afi, safi);
4758
4759 if (SAFI_MPLS_VPN == safi
4760 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4761 vpn_leak_to_vrf_update(bgp, ri);
4762 }
4763 #if ENABLE_BGP_VNC
4764 rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
4765 ri->attr, afi, safi, ri->type,
4766 ri->sub_type, &label);
4767 #endif
4768 bgp_unlock_node(rn);
4769 aspath_unintern(&attr.aspath);
4770 return;
4771 }
4772 }
4773
4774
4775 /* Make new BGP info. */
4776 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4777 attr_new, rn);
4778 SET_FLAG(new->flags, BGP_INFO_VALID);
4779 new->extra = bgp_info_extra_new();
4780 if (num_labels) {
4781 new->extra->label[0] = bgp_static->label;
4782 new->extra->num_labels = num_labels;
4783 }
4784 #if ENABLE_BGP_VNC
4785 label = decode_label(&bgp_static->label);
4786 #endif
4787
4788 /* Aggregate address increment. */
4789 bgp_aggregate_increment(bgp, p, new, afi, safi);
4790
4791 /* Register new BGP information. */
4792 bgp_info_add(rn, new);
4793 /* route_node_get lock */
4794 bgp_unlock_node(rn);
4795
4796 /* Process change. */
4797 bgp_process(bgp, rn, afi, safi);
4798
4799 if (SAFI_MPLS_VPN == safi
4800 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4801 vpn_leak_to_vrf_update(bgp, new);
4802 }
4803 #if ENABLE_BGP_VNC
4804 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
4805 safi, new->type, new->sub_type, &label);
4806 #endif
4807
4808 /* Unintern original. */
4809 aspath_unintern(&attr.aspath);
4810 }
4811
4812 /* Configure static BGP network. When user don't run zebra, static
4813 route should be installed as valid. */
4814 static int bgp_static_set(struct vty *vty, const char *negate,
4815 const char *ip_str, afi_t afi, safi_t safi,
4816 const char *rmap, int backdoor, uint32_t label_index)
4817 {
4818 VTY_DECLVAR_CONTEXT(bgp, bgp);
4819 int ret;
4820 struct prefix p;
4821 struct bgp_static *bgp_static;
4822 struct bgp_node *rn;
4823 uint8_t need_update = 0;
4824
4825 /* Convert IP prefix string to struct prefix. */
4826 ret = str2prefix(ip_str, &p);
4827 if (!ret) {
4828 vty_out(vty, "%% Malformed prefix\n");
4829 return CMD_WARNING_CONFIG_FAILED;
4830 }
4831 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4832 vty_out(vty, "%% Malformed prefix (link-local address)\n");
4833 return CMD_WARNING_CONFIG_FAILED;
4834 }
4835
4836 apply_mask(&p);
4837
4838 if (negate) {
4839
4840 /* Set BGP static route configuration. */
4841 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
4842
4843 if (!rn) {
4844 vty_out(vty, "%% Can't find static route specified\n");
4845 return CMD_WARNING_CONFIG_FAILED;
4846 }
4847
4848 bgp_static = rn->info;
4849
4850 if ((label_index != BGP_INVALID_LABEL_INDEX)
4851 && (label_index != bgp_static->label_index)) {
4852 vty_out(vty,
4853 "%% label-index doesn't match static route\n");
4854 return CMD_WARNING_CONFIG_FAILED;
4855 }
4856
4857 if ((rmap && bgp_static->rmap.name)
4858 && strcmp(rmap, bgp_static->rmap.name)) {
4859 vty_out(vty,
4860 "%% route-map name doesn't match static route\n");
4861 return CMD_WARNING_CONFIG_FAILED;
4862 }
4863
4864 /* Update BGP RIB. */
4865 if (!bgp_static->backdoor)
4866 bgp_static_withdraw(bgp, &p, afi, safi);
4867
4868 /* Clear configuration. */
4869 bgp_static_free(bgp_static);
4870 rn->info = NULL;
4871 bgp_unlock_node(rn);
4872 bgp_unlock_node(rn);
4873 } else {
4874
4875 /* Set BGP static route configuration. */
4876 rn = bgp_node_get(bgp->route[afi][safi], &p);
4877
4878 if (rn->info) {
4879 /* Configuration change. */
4880 bgp_static = rn->info;
4881
4882 /* Label index cannot be changed. */
4883 if (bgp_static->label_index != label_index) {
4884 vty_out(vty, "%% cannot change label-index\n");
4885 return CMD_WARNING_CONFIG_FAILED;
4886 }
4887
4888 /* Check previous routes are installed into BGP. */
4889 if (bgp_static->valid
4890 && bgp_static->backdoor != backdoor)
4891 need_update = 1;
4892
4893 bgp_static->backdoor = backdoor;
4894
4895 if (rmap) {
4896 if (bgp_static->rmap.name)
4897 XFREE(MTYPE_ROUTE_MAP_NAME,
4898 bgp_static->rmap.name);
4899 bgp_static->rmap.name =
4900 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4901 bgp_static->rmap.map =
4902 route_map_lookup_by_name(rmap);
4903 } else {
4904 if (bgp_static->rmap.name)
4905 XFREE(MTYPE_ROUTE_MAP_NAME,
4906 bgp_static->rmap.name);
4907 bgp_static->rmap.name = NULL;
4908 bgp_static->rmap.map = NULL;
4909 bgp_static->valid = 0;
4910 }
4911 bgp_unlock_node(rn);
4912 } else {
4913 /* New configuration. */
4914 bgp_static = bgp_static_new();
4915 bgp_static->backdoor = backdoor;
4916 bgp_static->valid = 0;
4917 bgp_static->igpmetric = 0;
4918 bgp_static->igpnexthop.s_addr = 0;
4919 bgp_static->label_index = label_index;
4920
4921 if (rmap) {
4922 if (bgp_static->rmap.name)
4923 XFREE(MTYPE_ROUTE_MAP_NAME,
4924 bgp_static->rmap.name);
4925 bgp_static->rmap.name =
4926 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4927 bgp_static->rmap.map =
4928 route_map_lookup_by_name(rmap);
4929 }
4930 rn->info = bgp_static;
4931 }
4932
4933 bgp_static->valid = 1;
4934 if (need_update)
4935 bgp_static_withdraw(bgp, &p, afi, safi);
4936
4937 if (!bgp_static->backdoor)
4938 bgp_static_update(bgp, &p, bgp_static, afi, safi);
4939 }
4940
4941 return CMD_SUCCESS;
4942 }
4943
4944 void bgp_static_add(struct bgp *bgp)
4945 {
4946 afi_t afi;
4947 safi_t safi;
4948 struct bgp_node *rn;
4949 struct bgp_node *rm;
4950 struct bgp_table *table;
4951 struct bgp_static *bgp_static;
4952
4953 FOREACH_AFI_SAFI (afi, safi)
4954 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
4955 rn = bgp_route_next(rn)) {
4956 if (rn->info == NULL)
4957 continue;
4958
4959 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
4960 || (safi == SAFI_EVPN)) {
4961 table = rn->info;
4962
4963 for (rm = bgp_table_top(table); rm;
4964 rm = bgp_route_next(rm)) {
4965 bgp_static = rm->info;
4966 bgp_static_update_safi(bgp, &rm->p,
4967 bgp_static, afi,
4968 safi);
4969 }
4970 } else {
4971 bgp_static_update(bgp, &rn->p, rn->info, afi,
4972 safi);
4973 }
4974 }
4975 }
4976
4977 /* Called from bgp_delete(). Delete all static routes from the BGP
4978 instance. */
4979 void bgp_static_delete(struct bgp *bgp)
4980 {
4981 afi_t afi;
4982 safi_t safi;
4983 struct bgp_node *rn;
4984 struct bgp_node *rm;
4985 struct bgp_table *table;
4986 struct bgp_static *bgp_static;
4987
4988 FOREACH_AFI_SAFI (afi, safi)
4989 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
4990 rn = bgp_route_next(rn)) {
4991 if (rn->info == NULL)
4992 continue;
4993
4994 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
4995 || (safi == SAFI_EVPN)) {
4996 table = rn->info;
4997
4998 for (rm = bgp_table_top(table); rm;
4999 rm = bgp_route_next(rm)) {
5000 bgp_static = rm->info;
5001 bgp_static_withdraw_safi(
5002 bgp, &rm->p, AFI_IP, safi,
5003 (struct prefix_rd *)&rn->p);
5004 bgp_static_free(bgp_static);
5005 rn->info = NULL;
5006 bgp_unlock_node(rn);
5007 }
5008 } else {
5009 bgp_static = rn->info;
5010 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5011 bgp_static_free(bgp_static);
5012 rn->info = NULL;
5013 bgp_unlock_node(rn);
5014 }
5015 }
5016 }
5017
5018 void bgp_static_redo_import_check(struct bgp *bgp)
5019 {
5020 afi_t afi;
5021 safi_t safi;
5022 struct bgp_node *rn;
5023 struct bgp_node *rm;
5024 struct bgp_table *table;
5025 struct bgp_static *bgp_static;
5026
5027 /* Use this flag to force reprocessing of the route */
5028 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5029 FOREACH_AFI_SAFI (afi, safi) {
5030 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5031 rn = bgp_route_next(rn)) {
5032 if (rn->info == NULL)
5033 continue;
5034
5035 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5036 || (safi == SAFI_EVPN)) {
5037 table = rn->info;
5038
5039 for (rm = bgp_table_top(table); rm;
5040 rm = bgp_route_next(rm)) {
5041 bgp_static = rm->info;
5042 bgp_static_update_safi(bgp, &rm->p,
5043 bgp_static, afi,
5044 safi);
5045 }
5046 } else {
5047 bgp_static = rn->info;
5048 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5049 safi);
5050 }
5051 }
5052 }
5053 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5054 }
5055
5056 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5057 safi_t safi)
5058 {
5059 struct bgp_table *table;
5060 struct bgp_node *rn;
5061 struct bgp_info *ri;
5062
5063 table = bgp->rib[afi][safi];
5064 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5065 for (ri = rn->info; ri; ri = ri->next) {
5066 if (ri->peer == bgp->peer_self
5067 && ((ri->type == ZEBRA_ROUTE_BGP
5068 && ri->sub_type == BGP_ROUTE_STATIC)
5069 || (ri->type != ZEBRA_ROUTE_BGP
5070 && ri->sub_type
5071 == BGP_ROUTE_REDISTRIBUTE))) {
5072 bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
5073 safi);
5074 bgp_unlink_nexthop(ri);
5075 bgp_info_delete(rn, ri);
5076 bgp_process(bgp, rn, afi, safi);
5077 }
5078 }
5079 }
5080 }
5081
5082 /*
5083 * Purge all networks and redistributed routes from routing table.
5084 * Invoked upon the instance going down.
5085 */
5086 void bgp_purge_static_redist_routes(struct bgp *bgp)
5087 {
5088 afi_t afi;
5089 safi_t safi;
5090
5091 FOREACH_AFI_SAFI (afi, safi)
5092 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5093 }
5094
5095 /*
5096 * gpz 110624
5097 * Currently this is used to set static routes for VPN and ENCAP.
5098 * I think it can probably be factored with bgp_static_set.
5099 */
5100 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5101 const char *ip_str, const char *rd_str,
5102 const char *label_str, const char *rmap_str,
5103 int evpn_type, const char *esi, const char *gwip,
5104 const char *ethtag, const char *routermac)
5105 {
5106 VTY_DECLVAR_CONTEXT(bgp, bgp);
5107 int ret;
5108 struct prefix p;
5109 struct prefix_rd prd;
5110 struct bgp_node *prn;
5111 struct bgp_node *rn;
5112 struct bgp_table *table;
5113 struct bgp_static *bgp_static;
5114 mpls_label_t label = MPLS_INVALID_LABEL;
5115 struct prefix gw_ip;
5116
5117 /* validate ip prefix */
5118 ret = str2prefix(ip_str, &p);
5119 if (!ret) {
5120 vty_out(vty, "%% Malformed prefix\n");
5121 return CMD_WARNING_CONFIG_FAILED;
5122 }
5123 apply_mask(&p);
5124 if ((afi == AFI_L2VPN)
5125 && (bgp_build_evpn_prefix(evpn_type,
5126 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5127 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5128 return CMD_WARNING_CONFIG_FAILED;
5129 }
5130
5131 ret = str2prefix_rd(rd_str, &prd);
5132 if (!ret) {
5133 vty_out(vty, "%% Malformed rd\n");
5134 return CMD_WARNING_CONFIG_FAILED;
5135 }
5136
5137 if (label_str) {
5138 unsigned long label_val;
5139 label_val = strtoul(label_str, NULL, 10);
5140 encode_label(label_val, &label);
5141 }
5142
5143 if (safi == SAFI_EVPN) {
5144 if (esi && str2esi(esi, NULL) == 0) {
5145 vty_out(vty, "%% Malformed ESI\n");
5146 return CMD_WARNING_CONFIG_FAILED;
5147 }
5148 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5149 vty_out(vty, "%% Malformed Router MAC\n");
5150 return CMD_WARNING_CONFIG_FAILED;
5151 }
5152 if (gwip) {
5153 memset(&gw_ip, 0, sizeof(struct prefix));
5154 ret = str2prefix(gwip, &gw_ip);
5155 if (!ret) {
5156 vty_out(vty, "%% Malformed GatewayIp\n");
5157 return CMD_WARNING_CONFIG_FAILED;
5158 }
5159 if ((gw_ip.family == AF_INET
5160 && is_evpn_prefix_ipaddr_v6(
5161 (struct prefix_evpn *)&p))
5162 || (gw_ip.family == AF_INET6
5163 && is_evpn_prefix_ipaddr_v4(
5164 (struct prefix_evpn *)&p))) {
5165 vty_out(vty,
5166 "%% GatewayIp family differs with IP prefix\n");
5167 return CMD_WARNING_CONFIG_FAILED;
5168 }
5169 }
5170 }
5171 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5172 if (prn->info == NULL)
5173 prn->info = bgp_table_init(bgp, afi, safi);
5174 else
5175 bgp_unlock_node(prn);
5176 table = prn->info;
5177
5178 rn = bgp_node_get(table, &p);
5179
5180 if (rn->info) {
5181 vty_out(vty, "%% Same network configuration exists\n");
5182 bgp_unlock_node(rn);
5183 } else {
5184 /* New configuration. */
5185 bgp_static = bgp_static_new();
5186 bgp_static->backdoor = 0;
5187 bgp_static->valid = 0;
5188 bgp_static->igpmetric = 0;
5189 bgp_static->igpnexthop.s_addr = 0;
5190 bgp_static->label = label;
5191 bgp_static->prd = prd;
5192
5193 if (rmap_str) {
5194 if (bgp_static->rmap.name)
5195 XFREE(MTYPE_ROUTE_MAP_NAME,
5196 bgp_static->rmap.name);
5197 bgp_static->rmap.name =
5198 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5199 bgp_static->rmap.map =
5200 route_map_lookup_by_name(rmap_str);
5201 }
5202
5203 if (safi == SAFI_EVPN) {
5204 if (esi) {
5205 bgp_static->eth_s_id =
5206 XCALLOC(MTYPE_ATTR,
5207 sizeof(struct eth_segment_id));
5208 str2esi(esi, bgp_static->eth_s_id);
5209 }
5210 if (routermac) {
5211 bgp_static->router_mac =
5212 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5213 (void)prefix_str2mac(routermac,
5214 bgp_static->router_mac);
5215 }
5216 if (gwip)
5217 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5218 }
5219 rn->info = bgp_static;
5220
5221 bgp_static->valid = 1;
5222 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5223 }
5224
5225 return CMD_SUCCESS;
5226 }
5227
5228 /* Configure static BGP network. */
5229 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5230 const char *ip_str, const char *rd_str,
5231 const char *label_str, int evpn_type, const char *esi,
5232 const char *gwip, const char *ethtag)
5233 {
5234 VTY_DECLVAR_CONTEXT(bgp, bgp);
5235 int ret;
5236 struct prefix p;
5237 struct prefix_rd prd;
5238 struct bgp_node *prn;
5239 struct bgp_node *rn;
5240 struct bgp_table *table;
5241 struct bgp_static *bgp_static;
5242 mpls_label_t label = MPLS_INVALID_LABEL;
5243
5244 /* Convert IP prefix string to struct prefix. */
5245 ret = str2prefix(ip_str, &p);
5246 if (!ret) {
5247 vty_out(vty, "%% Malformed prefix\n");
5248 return CMD_WARNING_CONFIG_FAILED;
5249 }
5250 apply_mask(&p);
5251 if ((afi == AFI_L2VPN)
5252 && (bgp_build_evpn_prefix(evpn_type,
5253 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5254 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5255 return CMD_WARNING_CONFIG_FAILED;
5256 }
5257 ret = str2prefix_rd(rd_str, &prd);
5258 if (!ret) {
5259 vty_out(vty, "%% Malformed rd\n");
5260 return CMD_WARNING_CONFIG_FAILED;
5261 }
5262
5263 if (label_str) {
5264 unsigned long label_val;
5265 label_val = strtoul(label_str, NULL, 10);
5266 encode_label(label_val, &label);
5267 }
5268
5269 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5270 if (prn->info == NULL)
5271 prn->info = bgp_table_init(bgp, afi, safi);
5272 else
5273 bgp_unlock_node(prn);
5274 table = prn->info;
5275
5276 rn = bgp_node_lookup(table, &p);
5277
5278 if (rn) {
5279 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5280
5281 bgp_static = rn->info;
5282 bgp_static_free(bgp_static);
5283 rn->info = NULL;
5284 bgp_unlock_node(rn);
5285 bgp_unlock_node(rn);
5286 } else
5287 vty_out(vty, "%% Can't find the route\n");
5288
5289 return CMD_SUCCESS;
5290 }
5291
5292 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5293 const char *rmap_name)
5294 {
5295 VTY_DECLVAR_CONTEXT(bgp, bgp);
5296 struct bgp_rmap *rmap;
5297
5298 rmap = &bgp->table_map[afi][safi];
5299 if (rmap_name) {
5300 if (rmap->name)
5301 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5302 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5303 rmap->map = route_map_lookup_by_name(rmap_name);
5304 } else {
5305 if (rmap->name)
5306 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5307 rmap->name = NULL;
5308 rmap->map = NULL;
5309 }
5310
5311 if (bgp_fibupd_safi(safi))
5312 bgp_zebra_announce_table(bgp, afi, safi);
5313
5314 return CMD_SUCCESS;
5315 }
5316
5317 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5318 const char *rmap_name)
5319 {
5320 VTY_DECLVAR_CONTEXT(bgp, bgp);
5321 struct bgp_rmap *rmap;
5322
5323 rmap = &bgp->table_map[afi][safi];
5324 if (rmap->name)
5325 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5326 rmap->name = NULL;
5327 rmap->map = NULL;
5328
5329 if (bgp_fibupd_safi(safi))
5330 bgp_zebra_announce_table(bgp, afi, safi);
5331
5332 return CMD_SUCCESS;
5333 }
5334
5335 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5336 safi_t safi)
5337 {
5338 if (bgp->table_map[afi][safi].name) {
5339 vty_out(vty, " table-map %s\n",
5340 bgp->table_map[afi][safi].name);
5341 }
5342 }
5343
5344 DEFUN (bgp_table_map,
5345 bgp_table_map_cmd,
5346 "table-map WORD",
5347 "BGP table to RIB route download filter\n"
5348 "Name of the route map\n")
5349 {
5350 int idx_word = 1;
5351 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5352 argv[idx_word]->arg);
5353 }
5354 DEFUN (no_bgp_table_map,
5355 no_bgp_table_map_cmd,
5356 "no table-map WORD",
5357 NO_STR
5358 "BGP table to RIB route download filter\n"
5359 "Name of the route map\n")
5360 {
5361 int idx_word = 2;
5362 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5363 argv[idx_word]->arg);
5364 }
5365
5366 DEFPY(bgp_network,
5367 bgp_network_cmd,
5368 "[no] network \
5369 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5370 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5371 backdoor$backdoor}]",
5372 NO_STR
5373 "Specify a network to announce via BGP\n"
5374 "IPv4 prefix\n"
5375 "Network number\n"
5376 "Network mask\n"
5377 "Network mask\n"
5378 "Route-map to modify the attributes\n"
5379 "Name of the route map\n"
5380 "Label index to associate with the prefix\n"
5381 "Label index value\n"
5382 "Specify a BGP backdoor route\n")
5383 {
5384 char addr_prefix_str[BUFSIZ];
5385
5386 if (address_str) {
5387 int ret;
5388
5389 ret = netmask_str2prefix_str(address_str, netmask_str,
5390 addr_prefix_str);
5391 if (!ret) {
5392 vty_out(vty, "%% Inconsistent address and mask\n");
5393 return CMD_WARNING_CONFIG_FAILED;
5394 }
5395 }
5396
5397 return bgp_static_set(
5398 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5399 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5400 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5401 }
5402
5403 DEFPY(ipv6_bgp_network,
5404 ipv6_bgp_network_cmd,
5405 "[no] network X:X::X:X/M$prefix \
5406 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5407 NO_STR
5408 "Specify a network to announce via BGP\n"
5409 "IPv6 prefix\n"
5410 "Route-map to modify the attributes\n"
5411 "Name of the route map\n"
5412 "Label index to associate with the prefix\n"
5413 "Label index value\n")
5414 {
5415 return bgp_static_set(
5416 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5417 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5418 }
5419
5420 /* Aggreagete address:
5421
5422 advertise-map Set condition to advertise attribute
5423 as-set Generate AS set path information
5424 attribute-map Set attributes of aggregate
5425 route-map Set parameters of aggregate
5426 summary-only Filter more specific routes from updates
5427 suppress-map Conditionally filter more specific routes from updates
5428 <cr>
5429 */
5430 struct bgp_aggregate {
5431 /* Summary-only flag. */
5432 uint8_t summary_only;
5433
5434 /* AS set generation. */
5435 uint8_t as_set;
5436
5437 /* Route-map for aggregated route. */
5438 struct route_map *map;
5439
5440 /* Suppress-count. */
5441 unsigned long count;
5442
5443 /* SAFI configuration. */
5444 safi_t safi;
5445 };
5446
5447 static struct bgp_aggregate *bgp_aggregate_new(void)
5448 {
5449 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5450 }
5451
5452 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5453 {
5454 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5455 }
5456
5457 static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin,
5458 struct aspath *aspath,
5459 struct community *comm)
5460 {
5461 static struct aspath *ae = NULL;
5462
5463 if (!ae)
5464 ae = aspath_empty();
5465
5466 if (!ri)
5467 return 0;
5468
5469 if (origin != ri->attr->origin)
5470 return 0;
5471
5472 if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae))
5473 return 0;
5474
5475 if (!community_cmp(ri->attr->community, comm))
5476 return 0;
5477
5478 return 1;
5479 }
5480
5481 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
5482 struct prefix *p, uint8_t origin,
5483 struct aspath *aspath,
5484 struct community *community,
5485 uint8_t atomic_aggregate,
5486 struct bgp_aggregate *aggregate)
5487 {
5488 struct bgp_node *rn;
5489 struct bgp_table *table;
5490 struct bgp_info *ri, *new;
5491
5492 table = bgp->rib[afi][safi];
5493
5494 rn = bgp_node_get(table, p);
5495
5496 for (ri = rn->info; ri; ri = ri->next)
5497 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
5498 && ri->sub_type == BGP_ROUTE_AGGREGATE)
5499 break;
5500
5501 if (aggregate->count > 0) {
5502 /*
5503 * If the aggregate information has not changed
5504 * no need to re-install it again.
5505 */
5506 if (bgp_aggregate_info_same(rn->info, origin, aspath,
5507 community)) {
5508 bgp_unlock_node(rn);
5509
5510 if (aspath)
5511 aspath_free(aspath);
5512 if (community)
5513 community_free(community);
5514
5515 return;
5516 }
5517
5518 /*
5519 * Mark the old as unusable
5520 */
5521 if (ri)
5522 bgp_info_delete(rn, ri);
5523
5524 new = info_make(
5525 ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5526 bgp_attr_aggregate_intern(bgp, origin, aspath,
5527 community, aggregate->as_set,
5528 atomic_aggregate),
5529 rn);
5530 SET_FLAG(new->flags, BGP_INFO_VALID);
5531
5532 bgp_info_add(rn, new);
5533 bgp_process(bgp, rn, afi, safi);
5534 } else {
5535 for (ri = rn->info; ri; ri = ri->next)
5536 if (ri->peer == bgp->peer_self
5537 && ri->type == ZEBRA_ROUTE_BGP
5538 && ri->sub_type == BGP_ROUTE_AGGREGATE)
5539 break;
5540
5541 /* Withdraw static BGP route from routing table. */
5542 if (ri) {
5543 bgp_info_delete(rn, ri);
5544 bgp_process(bgp, rn, afi, safi);
5545 }
5546 }
5547
5548 bgp_unlock_node(rn);
5549 }
5550
5551 /* Update an aggregate as routes are added/removed from the BGP table */
5552 static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5553 struct bgp_info *rinew, afi_t afi, safi_t safi,
5554 struct bgp_info *del,
5555 struct bgp_aggregate *aggregate)
5556 {
5557 struct bgp_table *table;
5558 struct bgp_node *top;
5559 struct bgp_node *rn;
5560 uint8_t origin;
5561 struct aspath *aspath = NULL;
5562 struct aspath *asmerge = NULL;
5563 struct community *community = NULL;
5564 struct community *commerge = NULL;
5565 struct bgp_info *ri;
5566 unsigned long match = 0;
5567 uint8_t atomic_aggregate = 0;
5568
5569 /* ORIGIN attribute: If at least one route among routes that are
5570 aggregated has ORIGIN with the value INCOMPLETE, then the
5571 aggregated route must have the ORIGIN attribute with the value
5572 INCOMPLETE. Otherwise, if at least one route among routes that
5573 are aggregated has ORIGIN with the value EGP, then the aggregated
5574 route must have the origin attribute with the value EGP. In all
5575 other case the value of the ORIGIN attribute of the aggregated
5576 route is INTERNAL. */
5577 origin = BGP_ORIGIN_IGP;
5578
5579 table = bgp->rib[afi][safi];
5580
5581 top = bgp_node_get(table, p);
5582 for (rn = bgp_node_get(table, p); rn;
5583 rn = bgp_route_next_until(rn, top)) {
5584 if (rn->p.prefixlen <= p->prefixlen)
5585 continue;
5586
5587 match = 0;
5588
5589 for (ri = rn->info; ri; ri = ri->next) {
5590 if (BGP_INFO_HOLDDOWN(ri))
5591 continue;
5592
5593 if (del && ri == del)
5594 continue;
5595
5596 if (ri->attr->flag
5597 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5598 atomic_aggregate = 1;
5599
5600 if (ri->sub_type == BGP_ROUTE_AGGREGATE)
5601 continue;
5602
5603 /*
5604 * summary-only aggregate route suppress
5605 * aggregated route announcements.
5606 */
5607 if (aggregate->summary_only) {
5608 (bgp_info_extra_get(ri))->suppress++;
5609 bgp_info_set_flag(rn, ri,
5610 BGP_INFO_ATTR_CHANGED);
5611 match++;
5612 }
5613
5614 aggregate->count++;
5615
5616 /*
5617 * If at least one route among routes that are
5618 * aggregated has ORIGIN with the value INCOMPLETE,
5619 * then the aggregated route MUST have the ORIGIN
5620 * attribute with the value INCOMPLETE. Otherwise, if
5621 * at least one route among routes that are aggregated
5622 * has ORIGIN with the value EGP, then the aggregated
5623 * route MUST have the ORIGIN attribute with the value
5624 * EGP.
5625 */
5626 if (origin < ri->attr->origin)
5627 origin = ri->attr->origin;
5628
5629 if (!aggregate->as_set)
5630 continue;
5631
5632 /*
5633 * as-set aggregate route generate origin, as path,
5634 * and community aggregation.
5635 */
5636 if (aspath) {
5637 asmerge = aspath_aggregate(aspath,
5638 ri->attr->aspath);
5639 aspath_free(aspath);
5640 aspath = asmerge;
5641 } else
5642 aspath = aspath_dup(ri->attr->aspath);
5643
5644 if (!ri->attr->community)
5645 continue;
5646
5647 if (community) {
5648 commerge = community_merge(community,
5649 ri->attr->community);
5650 community = community_uniq_sort(commerge);
5651 community_free(commerge);
5652 } else
5653 community = community_dup(ri->attr->community);
5654 }
5655 if (match)
5656 bgp_process(bgp, rn, afi, safi);
5657 }
5658 bgp_unlock_node(top);
5659
5660 if (rinew) {
5661 aggregate->count++;
5662
5663 if (aggregate->summary_only)
5664 (bgp_info_extra_get(rinew))->suppress++;
5665
5666 if (origin < rinew->attr->origin)
5667 origin = rinew->attr->origin;
5668
5669 if (aggregate->as_set) {
5670 if (aspath) {
5671 asmerge = aspath_aggregate(aspath,
5672 rinew->attr->aspath);
5673 aspath_free(aspath);
5674 aspath = asmerge;
5675 } else
5676 aspath = aspath_dup(rinew->attr->aspath);
5677
5678 if (rinew->attr->community) {
5679 if (community) {
5680 commerge = community_merge(
5681 community,
5682 rinew->attr->community);
5683 community =
5684 community_uniq_sort(commerge);
5685 community_free(commerge);
5686 } else
5687 community = community_dup(
5688 rinew->attr->community);
5689 }
5690 }
5691 }
5692
5693 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
5694 atomic_aggregate, aggregate);
5695
5696 if (aggregate->count == 0) {
5697 if (aspath)
5698 aspath_free(aspath);
5699 if (community)
5700 community_free(community);
5701 }
5702 }
5703
5704 static void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
5705 safi_t safi, struct bgp_aggregate *aggregate)
5706 {
5707 struct bgp_table *table;
5708 struct bgp_node *top;
5709 struct bgp_node *rn;
5710 struct bgp_info *ri;
5711 unsigned long match;
5712
5713 table = bgp->rib[afi][safi];
5714
5715 /* If routes exists below this node, generate aggregate routes. */
5716 top = bgp_node_get(table, p);
5717 for (rn = bgp_node_get(table, p); rn;
5718 rn = bgp_route_next_until(rn, top)) {
5719 if (rn->p.prefixlen <= p->prefixlen)
5720 continue;
5721 match = 0;
5722
5723 for (ri = rn->info; ri; ri = ri->next) {
5724 if (BGP_INFO_HOLDDOWN(ri))
5725 continue;
5726
5727 if (ri->sub_type == BGP_ROUTE_AGGREGATE)
5728 continue;
5729
5730 if (aggregate->summary_only && ri->extra) {
5731 ri->extra->suppress--;
5732
5733 if (ri->extra->suppress == 0) {
5734 bgp_info_set_flag(
5735 rn, ri, BGP_INFO_ATTR_CHANGED);
5736 match++;
5737 }
5738 }
5739 aggregate->count--;
5740 }
5741
5742 /* If this node was suppressed, process the change. */
5743 if (match)
5744 bgp_process(bgp, rn, afi, safi);
5745 }
5746 bgp_unlock_node(top);
5747 }
5748
5749 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
5750 struct bgp_info *ri, afi_t afi, safi_t safi)
5751 {
5752 struct bgp_node *child;
5753 struct bgp_node *rn;
5754 struct bgp_aggregate *aggregate;
5755 struct bgp_table *table;
5756
5757 table = bgp->aggregate[afi][safi];
5758
5759 /* No aggregates configured. */
5760 if (bgp_table_top_nolock(table) == NULL)
5761 return;
5762
5763 if (p->prefixlen == 0)
5764 return;
5765
5766 if (BGP_INFO_HOLDDOWN(ri))
5767 return;
5768
5769 child = bgp_node_get(table, p);
5770
5771 /* Aggregate address configuration check. */
5772 for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
5773 if ((aggregate = rn->info) != NULL
5774 && rn->p.prefixlen < p->prefixlen) {
5775 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
5776 bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
5777 aggregate);
5778 }
5779 bgp_unlock_node(child);
5780 }
5781
5782 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
5783 struct bgp_info *del, afi_t afi, safi_t safi)
5784 {
5785 struct bgp_node *child;
5786 struct bgp_node *rn;
5787 struct bgp_aggregate *aggregate;
5788 struct bgp_table *table;
5789
5790 table = bgp->aggregate[afi][safi];
5791
5792 /* No aggregates configured. */
5793 if (bgp_table_top_nolock(table) == NULL)
5794 return;
5795
5796 if (p->prefixlen == 0)
5797 return;
5798
5799 child = bgp_node_get(table, p);
5800
5801 /* Aggregate address configuration check. */
5802 for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
5803 if ((aggregate = rn->info) != NULL
5804 && rn->p.prefixlen < p->prefixlen) {
5805 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
5806 bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
5807 aggregate);
5808 }
5809 bgp_unlock_node(child);
5810 }
5811
5812 /* Aggregate route attribute. */
5813 #define AGGREGATE_SUMMARY_ONLY 1
5814 #define AGGREGATE_AS_SET 1
5815
5816 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
5817 afi_t afi, safi_t safi)
5818 {
5819 VTY_DECLVAR_CONTEXT(bgp, bgp);
5820 int ret;
5821 struct prefix p;
5822 struct bgp_node *rn;
5823 struct bgp_aggregate *aggregate;
5824
5825 /* Convert string to prefix structure. */
5826 ret = str2prefix(prefix_str, &p);
5827 if (!ret) {
5828 vty_out(vty, "Malformed prefix\n");
5829 return CMD_WARNING_CONFIG_FAILED;
5830 }
5831 apply_mask(&p);
5832
5833 /* Old configuration check. */
5834 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
5835 if (!rn) {
5836 vty_out(vty,
5837 "%% There is no aggregate-address configuration.\n");
5838 return CMD_WARNING_CONFIG_FAILED;
5839 }
5840
5841 aggregate = rn->info;
5842 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
5843 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
5844
5845 /* Unlock aggregate address configuration. */
5846 rn->info = NULL;
5847 bgp_aggregate_free(aggregate);
5848 bgp_unlock_node(rn);
5849 bgp_unlock_node(rn);
5850
5851 return CMD_SUCCESS;
5852 }
5853
5854 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
5855 safi_t safi, uint8_t summary_only, uint8_t as_set)
5856 {
5857 VTY_DECLVAR_CONTEXT(bgp, bgp);
5858 int ret;
5859 struct prefix p;
5860 struct bgp_node *rn;
5861 struct bgp_aggregate *aggregate;
5862
5863 /* Convert string to prefix structure. */
5864 ret = str2prefix(prefix_str, &p);
5865 if (!ret) {
5866 vty_out(vty, "Malformed prefix\n");
5867 return CMD_WARNING_CONFIG_FAILED;
5868 }
5869 apply_mask(&p);
5870
5871 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
5872 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
5873 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
5874 prefix_str);
5875 return CMD_WARNING_CONFIG_FAILED;
5876 }
5877
5878 /* Old configuration check. */
5879 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
5880
5881 if (rn->info) {
5882 vty_out(vty, "There is already same aggregate network.\n");
5883 /* try to remove the old entry */
5884 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
5885 if (ret) {
5886 vty_out(vty, "Error deleting aggregate.\n");
5887 bgp_unlock_node(rn);
5888 return CMD_WARNING_CONFIG_FAILED;
5889 }
5890 }
5891
5892 /* Make aggregate address structure. */
5893 aggregate = bgp_aggregate_new();
5894 aggregate->summary_only = summary_only;
5895 aggregate->as_set = as_set;
5896 aggregate->safi = safi;
5897 rn->info = aggregate;
5898
5899 /* Aggregate address insert into BGP routing table. */
5900 bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
5901
5902 return CMD_SUCCESS;
5903 }
5904
5905 DEFUN (aggregate_address,
5906 aggregate_address_cmd,
5907 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5908 "Configure BGP aggregate entries\n"
5909 "Aggregate prefix\n"
5910 "Generate AS set path information\n"
5911 "Filter more specific routes from updates\n"
5912 "Filter more specific routes from updates\n"
5913 "Generate AS set path information\n")
5914 {
5915 int idx = 0;
5916 argv_find(argv, argc, "A.B.C.D/M", &idx);
5917 char *prefix = argv[idx]->arg;
5918 int as_set =
5919 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5920 idx = 0;
5921 int summary_only = argv_find(argv, argc, "summary-only", &idx)
5922 ? AGGREGATE_SUMMARY_ONLY
5923 : 0;
5924
5925 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
5926 summary_only, as_set);
5927 }
5928
5929 DEFUN (aggregate_address_mask,
5930 aggregate_address_mask_cmd,
5931 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5932 "Configure BGP aggregate entries\n"
5933 "Aggregate address\n"
5934 "Aggregate mask\n"
5935 "Generate AS set path information\n"
5936 "Filter more specific routes from updates\n"
5937 "Filter more specific routes from updates\n"
5938 "Generate AS set path information\n")
5939 {
5940 int idx = 0;
5941 argv_find(argv, argc, "A.B.C.D", &idx);
5942 char *prefix = argv[idx]->arg;
5943 char *mask = argv[idx + 1]->arg;
5944 int as_set =
5945 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5946 idx = 0;
5947 int summary_only = argv_find(argv, argc, "summary-only", &idx)
5948 ? AGGREGATE_SUMMARY_ONLY
5949 : 0;
5950
5951 char prefix_str[BUFSIZ];
5952 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
5953
5954 if (!ret) {
5955 vty_out(vty, "%% Inconsistent address and mask\n");
5956 return CMD_WARNING_CONFIG_FAILED;
5957 }
5958
5959 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
5960 summary_only, as_set);
5961 }
5962
5963 DEFUN (no_aggregate_address,
5964 no_aggregate_address_cmd,
5965 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5966 NO_STR
5967 "Configure BGP aggregate entries\n"
5968 "Aggregate prefix\n"
5969 "Generate AS set path information\n"
5970 "Filter more specific routes from updates\n"
5971 "Filter more specific routes from updates\n"
5972 "Generate AS set path information\n")
5973 {
5974 int idx = 0;
5975 argv_find(argv, argc, "A.B.C.D/M", &idx);
5976 char *prefix = argv[idx]->arg;
5977 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
5978 }
5979
5980 DEFUN (no_aggregate_address_mask,
5981 no_aggregate_address_mask_cmd,
5982 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5983 NO_STR
5984 "Configure BGP aggregate entries\n"
5985 "Aggregate address\n"
5986 "Aggregate mask\n"
5987 "Generate AS set path information\n"
5988 "Filter more specific routes from updates\n"
5989 "Filter more specific routes from updates\n"
5990 "Generate AS set path information\n")
5991 {
5992 int idx = 0;
5993 argv_find(argv, argc, "A.B.C.D", &idx);
5994 char *prefix = argv[idx]->arg;
5995 char *mask = argv[idx + 1]->arg;
5996
5997 char prefix_str[BUFSIZ];
5998 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
5999
6000 if (!ret) {
6001 vty_out(vty, "%% Inconsistent address and mask\n");
6002 return CMD_WARNING_CONFIG_FAILED;
6003 }
6004
6005 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6006 }
6007
6008 DEFUN (ipv6_aggregate_address,
6009 ipv6_aggregate_address_cmd,
6010 "aggregate-address X:X::X:X/M [summary-only]",
6011 "Configure BGP aggregate entries\n"
6012 "Aggregate prefix\n"
6013 "Filter more specific routes from updates\n")
6014 {
6015 int idx = 0;
6016 argv_find(argv, argc, "X:X::X:X/M", &idx);
6017 char *prefix = argv[idx]->arg;
6018 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6019 ? AGGREGATE_SUMMARY_ONLY
6020 : 0;
6021 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only,
6022 0);
6023 }
6024
6025 DEFUN (no_ipv6_aggregate_address,
6026 no_ipv6_aggregate_address_cmd,
6027 "no aggregate-address X:X::X:X/M [summary-only]",
6028 NO_STR
6029 "Configure BGP aggregate entries\n"
6030 "Aggregate prefix\n"
6031 "Filter more specific routes from updates\n")
6032 {
6033 int idx = 0;
6034 argv_find(argv, argc, "X:X::X:X/M", &idx);
6035 char *prefix = argv[idx]->arg;
6036 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6037 }
6038
6039 /* Redistribute route treatment. */
6040 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6041 const union g_addr *nexthop, ifindex_t ifindex,
6042 enum nexthop_types_t nhtype, uint32_t metric,
6043 uint8_t type, unsigned short instance,
6044 route_tag_t tag)
6045 {
6046 struct bgp_info *new;
6047 struct bgp_info *bi;
6048 struct bgp_info info;
6049 struct bgp_node *bn;
6050 struct attr attr;
6051 struct attr *new_attr;
6052 afi_t afi;
6053 int ret;
6054 struct bgp_redist *red;
6055
6056 /* Make default attribute. */
6057 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6058
6059 switch (nhtype) {
6060 case NEXTHOP_TYPE_IFINDEX:
6061 break;
6062 case NEXTHOP_TYPE_IPV4:
6063 case NEXTHOP_TYPE_IPV4_IFINDEX:
6064 attr.nexthop = nexthop->ipv4;
6065 break;
6066 case NEXTHOP_TYPE_IPV6:
6067 case NEXTHOP_TYPE_IPV6_IFINDEX:
6068 attr.mp_nexthop_global = nexthop->ipv6;
6069 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6070 break;
6071 case NEXTHOP_TYPE_BLACKHOLE:
6072 switch (p->family) {
6073 case AF_INET:
6074 attr.nexthop.s_addr = INADDR_ANY;
6075 break;
6076 case AF_INET6:
6077 memset(&attr.mp_nexthop_global, 0,
6078 sizeof(attr.mp_nexthop_global));
6079 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6080 break;
6081 }
6082 break;
6083 }
6084 attr.nh_ifindex = ifindex;
6085
6086 attr.med = metric;
6087 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6088 attr.tag = tag;
6089
6090 afi = family2afi(p->family);
6091
6092 red = bgp_redist_lookup(bgp, afi, type, instance);
6093 if (red) {
6094 struct attr attr_new;
6095
6096 /* Copy attribute for modification. */
6097 bgp_attr_dup(&attr_new, &attr);
6098
6099 if (red->redist_metric_flag)
6100 attr_new.med = red->redist_metric;
6101
6102 /* Apply route-map. */
6103 if (red->rmap.name) {
6104 memset(&info, 0, sizeof(struct bgp_info));
6105 info.peer = bgp->peer_self;
6106 info.attr = &attr_new;
6107
6108 SET_FLAG(bgp->peer_self->rmap_type,
6109 PEER_RMAP_TYPE_REDISTRIBUTE);
6110
6111 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6112 &info);
6113
6114 bgp->peer_self->rmap_type = 0;
6115
6116 if (ret == RMAP_DENYMATCH) {
6117 /* Free uninterned attribute. */
6118 bgp_attr_flush(&attr_new);
6119
6120 /* Unintern original. */
6121 aspath_unintern(&attr.aspath);
6122 bgp_redistribute_delete(bgp, p, type, instance);
6123 return;
6124 }
6125 }
6126
6127 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
6128 bgp_attr_add_gshut_community(&attr_new);
6129
6130 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6131 SAFI_UNICAST, p, NULL);
6132
6133 new_attr = bgp_attr_intern(&attr_new);
6134
6135 for (bi = bn->info; bi; bi = bi->next)
6136 if (bi->peer == bgp->peer_self
6137 && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6138 break;
6139
6140 if (bi) {
6141 /* Ensure the (source route) type is updated. */
6142 bi->type = type;
6143 if (attrhash_cmp(bi->attr, new_attr)
6144 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
6145 bgp_attr_unintern(&new_attr);
6146 aspath_unintern(&attr.aspath);
6147 bgp_unlock_node(bn);
6148 return;
6149 } else {
6150 /* The attribute is changed. */
6151 bgp_info_set_flag(bn, bi,
6152 BGP_INFO_ATTR_CHANGED);
6153
6154 /* Rewrite BGP route information. */
6155 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
6156 bgp_info_restore(bn, bi);
6157 else
6158 bgp_aggregate_decrement(bgp, p, bi, afi,
6159 SAFI_UNICAST);
6160 bgp_attr_unintern(&bi->attr);
6161 bi->attr = new_attr;
6162 bi->uptime = bgp_clock();
6163
6164 /* Process change. */
6165 bgp_aggregate_increment(bgp, p, bi, afi,
6166 SAFI_UNICAST);
6167 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6168 bgp_unlock_node(bn);
6169 aspath_unintern(&attr.aspath);
6170
6171 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6172 || (bgp->inst_type
6173 == BGP_INSTANCE_TYPE_DEFAULT)) {
6174
6175 vpn_leak_from_vrf_update(
6176 bgp_get_default(), bgp, bi);
6177 }
6178 return;
6179 }
6180 }
6181
6182 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6183 bgp->peer_self, new_attr, bn);
6184 SET_FLAG(new->flags, BGP_INFO_VALID);
6185
6186 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6187 bgp_info_add(bn, new);
6188 bgp_unlock_node(bn);
6189 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6190
6191 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6192 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6193
6194 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6195 }
6196 }
6197
6198 /* Unintern original. */
6199 aspath_unintern(&attr.aspath);
6200 }
6201
6202 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
6203 unsigned short instance)
6204 {
6205 afi_t afi;
6206 struct bgp_node *rn;
6207 struct bgp_info *ri;
6208 struct bgp_redist *red;
6209
6210 afi = family2afi(p->family);
6211
6212 red = bgp_redist_lookup(bgp, afi, type, instance);
6213 if (red) {
6214 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6215 SAFI_UNICAST, p, NULL);
6216
6217 for (ri = rn->info; ri; ri = ri->next)
6218 if (ri->peer == bgp->peer_self && ri->type == type)
6219 break;
6220
6221 if (ri) {
6222 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6223 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6224
6225 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6226 bgp, ri);
6227 }
6228 bgp_aggregate_decrement(bgp, p, ri, afi, SAFI_UNICAST);
6229 bgp_info_delete(rn, ri);
6230 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6231 }
6232 bgp_unlock_node(rn);
6233 }
6234 }
6235
6236 /* Withdraw specified route type's route. */
6237 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6238 unsigned short instance)
6239 {
6240 struct bgp_node *rn;
6241 struct bgp_info *ri;
6242 struct bgp_table *table;
6243
6244 table = bgp->rib[afi][SAFI_UNICAST];
6245
6246 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6247 for (ri = rn->info; ri; ri = ri->next)
6248 if (ri->peer == bgp->peer_self && ri->type == type
6249 && ri->instance == instance)
6250 break;
6251
6252 if (ri) {
6253 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6254 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6255
6256 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6257 bgp, ri);
6258 }
6259 bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
6260 SAFI_UNICAST);
6261 bgp_info_delete(rn, ri);
6262 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6263 }
6264 }
6265 }
6266
6267 /* Static function to display route. */
6268 static void route_vty_out_route(struct prefix *p, struct vty *vty,
6269 json_object *json)
6270 {
6271 int len = 0;
6272 char buf[BUFSIZ];
6273
6274 if (p->family == AF_INET) {
6275 if (!json) {
6276 len = vty_out(
6277 vty, "%s/%d",
6278 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6279 p->prefixlen);
6280 } else {
6281 json_object_string_add(json, "prefix",
6282 inet_ntop(p->family,
6283 &p->u.prefix, buf,
6284 BUFSIZ));
6285 json_object_int_add(json, "prefixLen", p->prefixlen);
6286 }
6287 } else if (p->family == AF_ETHERNET) {
6288 prefix2str(p, buf, PREFIX_STRLEN);
6289 len = vty_out(vty, "%s", buf);
6290 } else if (p->family == AF_EVPN) {
6291 if (!json)
6292 len = vty_out(
6293 vty, "%s",
6294 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
6295 BUFSIZ));
6296 else
6297 bgp_evpn_route2json((struct prefix_evpn *)p, json);
6298 } else if (p->family == AF_FLOWSPEC) {
6299 route_vty_out_flowspec(vty, p, NULL,
6300 json ?
6301 NLRI_STRING_FORMAT_JSON_SIMPLE :
6302 NLRI_STRING_FORMAT_MIN, json);
6303 } else {
6304 if (!json)
6305 len = vty_out(
6306 vty, "%s/%d",
6307 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6308 p->prefixlen);
6309 }
6310
6311 if (!json) {
6312 len = 17 - len;
6313 if (len < 1)
6314 vty_out(vty, "\n%*s", 20, " ");
6315 else
6316 vty_out(vty, "%*s", len, " ");
6317 }
6318 }
6319
6320 enum bgp_display_type {
6321 normal_list,
6322 };
6323
6324 /* Print the short form route status for a bgp_info */
6325 static void route_vty_short_status_out(struct vty *vty, struct bgp_info *binfo,
6326 json_object *json_path)
6327 {
6328 if (json_path) {
6329
6330 /* Route status display. */
6331 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
6332 json_object_boolean_true_add(json_path, "removed");
6333
6334 if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
6335 json_object_boolean_true_add(json_path, "stale");
6336
6337 if (binfo->extra && binfo->extra->suppress)
6338 json_object_boolean_true_add(json_path, "suppressed");
6339
6340 if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
6341 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6342 json_object_boolean_true_add(json_path, "valid");
6343
6344 /* Selected */
6345 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6346 json_object_boolean_true_add(json_path, "history");
6347
6348 if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
6349 json_object_boolean_true_add(json_path, "damped");
6350
6351 if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
6352 json_object_boolean_true_add(json_path, "bestpath");
6353
6354 if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
6355 json_object_boolean_true_add(json_path, "multipath");
6356
6357 /* Internal route. */
6358 if ((binfo->peer->as)
6359 && (binfo->peer->as == binfo->peer->local_as))
6360 json_object_string_add(json_path, "pathFrom",
6361 "internal");
6362 else
6363 json_object_string_add(json_path, "pathFrom",
6364 "external");
6365
6366 return;
6367 }
6368
6369 /* Route status display. */
6370 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
6371 vty_out(vty, "R");
6372 else if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
6373 vty_out(vty, "S");
6374 else if (binfo->extra && binfo->extra->suppress)
6375 vty_out(vty, "s");
6376 else if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
6377 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6378 vty_out(vty, "*");
6379 else
6380 vty_out(vty, " ");
6381
6382 /* Selected */
6383 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6384 vty_out(vty, "h");
6385 else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
6386 vty_out(vty, "d");
6387 else if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
6388 vty_out(vty, ">");
6389 else if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
6390 vty_out(vty, "=");
6391 else
6392 vty_out(vty, " ");
6393
6394 /* Internal route. */
6395 if (binfo->peer && (binfo->peer->as)
6396 && (binfo->peer->as == binfo->peer->local_as))
6397 vty_out(vty, "i");
6398 else
6399 vty_out(vty, " ");
6400 }
6401
6402 /* called from terminal list command */
6403 void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6404 int display, safi_t safi, json_object *json_paths)
6405 {
6406 struct attr *attr;
6407 json_object *json_path = NULL;
6408 json_object *json_nexthops = NULL;
6409 json_object *json_nexthop_global = NULL;
6410 json_object *json_nexthop_ll = NULL;
6411 char vrf_id_str[VRF_NAMSIZ] = {0};
6412 bool nexthop_self = CHECK_FLAG(binfo->flags, BGP_INFO_ANNC_NH_SELF)
6413 ? true
6414 : false;
6415 bool nexthop_othervrf = false;
6416 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
6417 const char *nexthop_vrfname = "Default";
6418
6419 if (json_paths)
6420 json_path = json_object_new_object();
6421
6422 /* short status lead text */
6423 route_vty_short_status_out(vty, binfo, json_path);
6424
6425 if (!json_paths) {
6426 /* print prefix and mask */
6427 if (!display)
6428 route_vty_out_route(p, vty, json_path);
6429 else
6430 vty_out(vty, "%*s", 17, " ");
6431 } else {
6432 route_vty_out_route(p, vty, json_path);
6433 }
6434
6435 /* Print attribute */
6436 attr = binfo->attr;
6437 if (!attr) {
6438 if (json_paths)
6439 json_object_array_add(json_paths, json_path);
6440 else
6441 vty_out(vty, "\n");
6442
6443 return;
6444 }
6445
6446 /*
6447 * If vrf id of nexthop is different from that of prefix,
6448 * set up printable string to append
6449 */
6450 if (binfo->extra && binfo->extra->bgp_orig) {
6451 const char *self = "";
6452
6453 if (nexthop_self)
6454 self = "<";
6455
6456 nexthop_othervrf = true;
6457 nexthop_vrfid = binfo->extra->bgp_orig->vrf_id;
6458
6459 if (binfo->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
6460 snprintf(vrf_id_str, sizeof(vrf_id_str),
6461 "@%s%s", VRFID_NONE_STR, self);
6462 else
6463 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
6464 binfo->extra->bgp_orig->vrf_id, self);
6465
6466 if (binfo->extra->bgp_orig->inst_type !=
6467 BGP_INSTANCE_TYPE_DEFAULT)
6468
6469 nexthop_vrfname = binfo->extra->bgp_orig->name;
6470 } else {
6471 const char *self = "";
6472
6473 if (nexthop_self)
6474 self = "<";
6475
6476 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
6477 }
6478
6479 /*
6480 * For ENCAP and EVPN routes, nexthop address family is not
6481 * neccessarily the same as the prefix address family.
6482 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6483 * EVPN routes are also exchanged with a MP nexthop. Currently,
6484 * this
6485 * is only IPv4, the value will be present in either
6486 * attr->nexthop or
6487 * attr->mp_nexthop_global_in
6488 */
6489 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
6490 char buf[BUFSIZ];
6491 char nexthop[128];
6492 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
6493
6494 switch (af) {
6495 case AF_INET:
6496 sprintf(nexthop, "%s",
6497 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
6498 BUFSIZ));
6499 break;
6500 case AF_INET6:
6501 sprintf(nexthop, "%s",
6502 inet_ntop(af, &attr->mp_nexthop_global, buf,
6503 BUFSIZ));
6504 break;
6505 default:
6506 sprintf(nexthop, "?");
6507 break;
6508 }
6509
6510 if (json_paths) {
6511 json_nexthop_global = json_object_new_object();
6512
6513 json_object_string_add(json_nexthop_global, "afi",
6514 (af == AF_INET) ? "ip" : "ipv6");
6515 json_object_string_add(json_nexthop_global,
6516 (af == AF_INET) ? "ip" : "ipv6",
6517 nexthop);
6518 json_object_boolean_true_add(json_nexthop_global,
6519 "used");
6520 } else
6521 vty_out(vty, "%s%s", nexthop, vrf_id_str);
6522 } else if (safi == SAFI_EVPN) {
6523 if (json_paths) {
6524 json_nexthop_global = json_object_new_object();
6525
6526 json_object_string_add(json_nexthop_global, "ip",
6527 inet_ntoa(attr->nexthop));
6528 json_object_string_add(json_nexthop_global, "afi",
6529 "ipv4");
6530 json_object_boolean_true_add(json_nexthop_global,
6531 "used");
6532 } else
6533 vty_out(vty, "%-16s%s", inet_ntoa(attr->nexthop),
6534 vrf_id_str);
6535 } else if (safi == SAFI_FLOWSPEC) {
6536 if (attr->nexthop.s_addr != 0) {
6537 if (json_paths) {
6538 json_nexthop_global = json_object_new_object();
6539 json_object_string_add(
6540 json_nexthop_global, "ip",
6541 inet_ntoa(attr->nexthop));
6542 json_object_string_add(json_nexthop_global,
6543 "afi", "ipv4");
6544 json_object_boolean_true_add(json_nexthop_global,
6545 "used");
6546 } else {
6547 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6548 }
6549 }
6550 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6551 if (json_paths) {
6552 json_nexthop_global = json_object_new_object();
6553
6554 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6555 json_object_string_add(
6556 json_nexthop_global, "ip",
6557 inet_ntoa(attr->mp_nexthop_global_in));
6558 else
6559 json_object_string_add(
6560 json_nexthop_global, "ip",
6561 inet_ntoa(attr->nexthop));
6562
6563 json_object_string_add(json_nexthop_global, "afi",
6564 "ipv4");
6565 json_object_boolean_true_add(json_nexthop_global,
6566 "used");
6567 } else {
6568 char buf[BUFSIZ];
6569
6570 snprintf(buf, sizeof(buf), "%s%s",
6571 inet_ntoa(attr->nexthop), vrf_id_str);
6572 vty_out(vty, "%-16s", buf);
6573 }
6574 }
6575
6576 /* IPv6 Next Hop */
6577 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6578 int len;
6579 char buf[BUFSIZ];
6580
6581 if (json_paths) {
6582 json_nexthop_global = json_object_new_object();
6583 json_object_string_add(
6584 json_nexthop_global, "ip",
6585 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
6586 buf, BUFSIZ));
6587 json_object_string_add(json_nexthop_global, "afi",
6588 "ipv6");
6589 json_object_string_add(json_nexthop_global, "scope",
6590 "global");
6591
6592 /* We display both LL & GL if both have been
6593 * received */
6594 if ((attr->mp_nexthop_len == 32)
6595 || (binfo->peer->conf_if)) {
6596 json_nexthop_ll = json_object_new_object();
6597 json_object_string_add(
6598 json_nexthop_ll, "ip",
6599 inet_ntop(AF_INET6,
6600 &attr->mp_nexthop_local, buf,
6601 BUFSIZ));
6602 json_object_string_add(json_nexthop_ll, "afi",
6603 "ipv6");
6604 json_object_string_add(json_nexthop_ll, "scope",
6605 "link-local");
6606
6607 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
6608 &attr->mp_nexthop_local)
6609 != 0)
6610 && !attr->mp_nexthop_prefer_global)
6611 json_object_boolean_true_add(
6612 json_nexthop_ll, "used");
6613 else
6614 json_object_boolean_true_add(
6615 json_nexthop_global, "used");
6616 } else
6617 json_object_boolean_true_add(
6618 json_nexthop_global, "used");
6619 } else {
6620 /* Display LL if LL/Global both in table unless
6621 * prefer-global is set */
6622 if (((attr->mp_nexthop_len == 32)
6623 && !attr->mp_nexthop_prefer_global)
6624 || (binfo->peer->conf_if)) {
6625 if (binfo->peer->conf_if) {
6626 len = vty_out(vty, "%s",
6627 binfo->peer->conf_if);
6628 len = 16 - len; /* len of IPv6
6629 addr + max
6630 len of def
6631 ifname */
6632
6633 if (len < 1)
6634 vty_out(vty, "\n%*s", 36, " ");
6635 else
6636 vty_out(vty, "%*s", len, " ");
6637 } else {
6638 len = vty_out(
6639 vty, "%s%s",
6640 inet_ntop(
6641 AF_INET6,
6642 &attr->mp_nexthop_local,
6643 buf, BUFSIZ),
6644 vrf_id_str);
6645 len = 16 - len;
6646
6647 if (len < 1)
6648 vty_out(vty, "\n%*s", 36, " ");
6649 else
6650 vty_out(vty, "%*s", len, " ");
6651 }
6652 } else {
6653 len = vty_out(
6654 vty, "%s%s",
6655 inet_ntop(AF_INET6,
6656 &attr->mp_nexthop_global, buf,
6657 BUFSIZ),
6658 vrf_id_str);
6659 len = 16 - len;
6660
6661 if (len < 1)
6662 vty_out(vty, "\n%*s", 36, " ");
6663 else
6664 vty_out(vty, "%*s", len, " ");
6665 }
6666 }
6667 }
6668
6669 /* MED/Metric */
6670 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6671 if (json_paths)
6672 json_object_int_add(json_path, "med", attr->med);
6673 else
6674 vty_out(vty, "%10u", attr->med);
6675 else if (!json_paths)
6676 vty_out(vty, " ");
6677
6678 /* Local Pref */
6679 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6680 if (json_paths)
6681 json_object_int_add(json_path, "localpref",
6682 attr->local_pref);
6683 else
6684 vty_out(vty, "%7u", attr->local_pref);
6685 else if (!json_paths)
6686 vty_out(vty, " ");
6687
6688 if (json_paths)
6689 json_object_int_add(json_path, "weight", attr->weight);
6690 else
6691 vty_out(vty, "%7u ", attr->weight);
6692
6693 if (json_paths) {
6694 char buf[BUFSIZ];
6695 json_object_string_add(
6696 json_path, "peerId",
6697 sockunion2str(&binfo->peer->su, buf, SU_ADDRSTRLEN));
6698 }
6699
6700 /* Print aspath */
6701 if (attr->aspath) {
6702 if (json_paths)
6703 json_object_string_add(json_path, "aspath",
6704 attr->aspath->str);
6705 else
6706 aspath_print_vty(vty, "%s", attr->aspath, " ");
6707 }
6708
6709 /* Print origin */
6710 if (json_paths)
6711 json_object_string_add(json_path, "origin",
6712 bgp_origin_long_str[attr->origin]);
6713 else
6714 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6715
6716 if (json_paths) {
6717 if (nexthop_self)
6718 json_object_boolean_true_add(json_path,
6719 "announceNexthopSelf");
6720 if (nexthop_othervrf) {
6721 json_object_string_add(json_path, "nhVrfName",
6722 nexthop_vrfname);
6723
6724 json_object_int_add(json_path, "nhVrfId",
6725 ((nexthop_vrfid == VRF_UNKNOWN)
6726 ? -1
6727 : (int)nexthop_vrfid));
6728 }
6729 }
6730
6731 if (json_paths) {
6732 if (json_nexthop_global || json_nexthop_ll) {
6733 json_nexthops = json_object_new_array();
6734
6735 if (json_nexthop_global)
6736 json_object_array_add(json_nexthops,
6737 json_nexthop_global);
6738
6739 if (json_nexthop_ll)
6740 json_object_array_add(json_nexthops,
6741 json_nexthop_ll);
6742
6743 json_object_object_add(json_path, "nexthops",
6744 json_nexthops);
6745 }
6746
6747 json_object_array_add(json_paths, json_path);
6748 } else {
6749 vty_out(vty, "\n");
6750 #if ENABLE_BGP_VNC
6751 /* prints an additional line, indented, with VNC info, if
6752 * present */
6753 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
6754 rfapi_vty_out_vncinfo(vty, p, binfo, safi);
6755 #endif
6756 }
6757 }
6758
6759 /* called from terminal list command */
6760 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
6761 safi_t safi, bool use_json, json_object *json_ar)
6762 {
6763 json_object *json_status = NULL;
6764 json_object *json_net = NULL;
6765 char buff[BUFSIZ];
6766 /* Route status display. */
6767 if (use_json) {
6768 json_status = json_object_new_object();
6769 json_net = json_object_new_object();
6770 } else {
6771 vty_out(vty, "*");
6772 vty_out(vty, ">");
6773 vty_out(vty, " ");
6774 }
6775
6776 /* print prefix and mask */
6777 if (use_json)
6778 json_object_string_add(
6779 json_net, "addrPrefix",
6780 inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
6781 else
6782 route_vty_out_route(p, vty, NULL);
6783
6784 /* Print attribute */
6785 if (attr) {
6786 if (use_json) {
6787 if (p->family == AF_INET
6788 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6789 || safi == SAFI_EVPN
6790 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6791 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6792 || safi == SAFI_EVPN)
6793 json_object_string_add(
6794 json_net, "nextHop",
6795 inet_ntoa(
6796 attr->mp_nexthop_global_in));
6797 else
6798 json_object_string_add(
6799 json_net, "nextHop",
6800 inet_ntoa(attr->nexthop));
6801 } else if (p->family == AF_INET6
6802 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6803 char buf[BUFSIZ];
6804
6805 json_object_string_add(
6806 json_net, "netHopGloabal",
6807 inet_ntop(AF_INET6,
6808 &attr->mp_nexthop_global, buf,
6809 BUFSIZ));
6810 }
6811
6812 if (attr->flag
6813 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6814 json_object_int_add(json_net, "metric",
6815 attr->med);
6816
6817 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6818 json_object_int_add(json_net, "localPref",
6819 attr->local_pref);
6820
6821 json_object_int_add(json_net, "weight", attr->weight);
6822
6823 /* Print aspath */
6824 if (attr->aspath)
6825 json_object_string_add(json_net, "asPath",
6826 attr->aspath->str);
6827
6828 /* Print origin */
6829 json_object_string_add(json_net, "bgpOriginCode",
6830 bgp_origin_str[attr->origin]);
6831 } else {
6832 if (p->family == AF_INET
6833 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6834 || safi == SAFI_EVPN
6835 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6836 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6837 || safi == SAFI_EVPN)
6838 vty_out(vty, "%-16s",
6839 inet_ntoa(
6840 attr->mp_nexthop_global_in));
6841 else
6842 vty_out(vty, "%-16s",
6843 inet_ntoa(attr->nexthop));
6844 } else if (p->family == AF_INET6
6845 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6846 int len;
6847 char buf[BUFSIZ];
6848
6849 len = vty_out(
6850 vty, "%s",
6851 inet_ntop(AF_INET6,
6852 &attr->mp_nexthop_global, buf,
6853 BUFSIZ));
6854 len = 16 - len;
6855 if (len < 1)
6856 vty_out(vty, "\n%*s", 36, " ");
6857 else
6858 vty_out(vty, "%*s", len, " ");
6859 }
6860 if (attr->flag
6861 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6862 vty_out(vty, "%10u", attr->med);
6863 else
6864 vty_out(vty, " ");
6865
6866 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6867 vty_out(vty, "%7u", attr->local_pref);
6868 else
6869 vty_out(vty, " ");
6870
6871 vty_out(vty, "%7u ", attr->weight);
6872
6873 /* Print aspath */
6874 if (attr->aspath)
6875 aspath_print_vty(vty, "%s", attr->aspath, " ");
6876
6877 /* Print origin */
6878 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6879 }
6880 }
6881 if (use_json) {
6882 json_object_boolean_true_add(json_status, "*");
6883 json_object_boolean_true_add(json_status, ">");
6884 json_object_object_add(json_net, "appliedStatusSymbols",
6885 json_status);
6886 char buf_cut[BUFSIZ];
6887 json_object_object_add(
6888 json_ar,
6889 inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
6890 json_net);
6891 } else
6892 vty_out(vty, "\n");
6893 }
6894
6895 void route_vty_out_tag(struct vty *vty, struct prefix *p,
6896 struct bgp_info *binfo, int display, safi_t safi,
6897 json_object *json)
6898 {
6899 json_object *json_out = NULL;
6900 struct attr *attr;
6901 mpls_label_t label = MPLS_INVALID_LABEL;
6902
6903 if (!binfo->extra)
6904 return;
6905
6906 if (json)
6907 json_out = json_object_new_object();
6908
6909 /* short status lead text */
6910 route_vty_short_status_out(vty, binfo, json_out);
6911
6912 /* print prefix and mask */
6913 if (json == NULL) {
6914 if (!display)
6915 route_vty_out_route(p, vty, NULL);
6916 else
6917 vty_out(vty, "%*s", 17, " ");
6918 }
6919
6920 /* Print attribute */
6921 attr = binfo->attr;
6922 if (attr) {
6923 if (((p->family == AF_INET)
6924 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6925 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6926 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6927 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6928 || safi == SAFI_EVPN) {
6929 if (json)
6930 json_object_string_add(
6931 json_out, "mpNexthopGlobalIn",
6932 inet_ntoa(
6933 attr->mp_nexthop_global_in));
6934 else
6935 vty_out(vty, "%-16s",
6936 inet_ntoa(
6937 attr->mp_nexthop_global_in));
6938 } else {
6939 if (json)
6940 json_object_string_add(
6941 json_out, "nexthop",
6942 inet_ntoa(attr->nexthop));
6943 else
6944 vty_out(vty, "%-16s",
6945 inet_ntoa(attr->nexthop));
6946 }
6947 } else if (((p->family == AF_INET6)
6948 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6949 || (safi == SAFI_EVPN
6950 && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6951 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6952 char buf_a[512];
6953 char buf_b[512];
6954 char buf_c[BUFSIZ];
6955 if (attr->mp_nexthop_len
6956 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
6957 if (json)
6958 json_object_string_add(
6959 json_out, "mpNexthopGlobalIn",
6960 inet_ntop(
6961 AF_INET6,
6962 &attr->mp_nexthop_global,
6963 buf_a, sizeof(buf_a)));
6964 else
6965 vty_out(vty, "%s",
6966 inet_ntop(
6967 AF_INET6,
6968 &attr->mp_nexthop_global,
6969 buf_a, sizeof(buf_a)));
6970 } else if (attr->mp_nexthop_len
6971 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
6972 if (json) {
6973 inet_ntop(AF_INET6,
6974 &attr->mp_nexthop_global,
6975 buf_a, sizeof(buf_a));
6976 inet_ntop(AF_INET6,
6977 &attr->mp_nexthop_local,
6978 buf_b, sizeof(buf_b));
6979 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
6980 json_object_string_add(
6981 json_out,
6982 "mpNexthopGlobalLocal", buf_c);
6983 } else
6984 vty_out(vty, "%s(%s)",
6985 inet_ntop(
6986 AF_INET6,
6987 &attr->mp_nexthop_global,
6988 buf_a, sizeof(buf_a)),
6989 inet_ntop(
6990 AF_INET6,
6991 &attr->mp_nexthop_local,
6992 buf_b, sizeof(buf_b)));
6993 }
6994 }
6995 }
6996
6997 label = decode_label(&binfo->extra->label[0]);
6998
6999 if (bgp_is_valid_label(&label)) {
7000 if (json) {
7001 json_object_int_add(json_out, "notag", label);
7002 json_object_array_add(json, json_out);
7003 } else {
7004 vty_out(vty, "notag/%d", label);
7005 vty_out(vty, "\n");
7006 }
7007 }
7008 }
7009
7010 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7011 struct bgp_info *binfo, int display,
7012 json_object *json_paths)
7013 {
7014 struct attr *attr;
7015 char buf[BUFSIZ];
7016 json_object *json_path = NULL;
7017
7018 if (json_paths)
7019 json_path = json_object_new_object();
7020
7021 if (!binfo->extra)
7022 return;
7023
7024 /* short status lead text */
7025 route_vty_short_status_out(vty, binfo, json_path);
7026
7027 /* print prefix and mask */
7028 if (!display)
7029 route_vty_out_route(p, vty, NULL);
7030 else
7031 vty_out(vty, "%*s", 17, " ");
7032
7033 /* Print attribute */
7034 attr = binfo->attr;
7035 if (attr) {
7036 char buf1[BUFSIZ];
7037 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7038
7039 switch (af) {
7040 case AF_INET:
7041 vty_out(vty, "%-16s",
7042 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7043 BUFSIZ));
7044 break;
7045 case AF_INET6:
7046 vty_out(vty, "%s(%s)",
7047 inet_ntop(af, &attr->mp_nexthop_global, buf,
7048 BUFSIZ),
7049 inet_ntop(af, &attr->mp_nexthop_local, buf1,
7050 BUFSIZ));
7051 break;
7052 default:
7053 vty_out(vty, "?");
7054 }
7055
7056 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7057
7058 vty_out(vty, "%s", str);
7059 XFREE(MTYPE_TMP, str);
7060
7061 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7062 vty_out(vty, "/%s",
7063 inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
7064 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7065 vty_out(vty, "/%s",
7066 inet_ntop(AF_INET6,
7067 &(attr->evpn_overlay.gw_ip.ipv6), buf,
7068 BUFSIZ));
7069 }
7070 if (attr->ecommunity) {
7071 char *mac = NULL;
7072 struct ecommunity_val *routermac = ecommunity_lookup(
7073 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7074 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7075 if (routermac)
7076 mac = ecom_mac2str((char *)routermac->val);
7077 if (mac) {
7078 vty_out(vty, "/%s", (char *)mac);
7079 XFREE(MTYPE_TMP, mac);
7080 }
7081 }
7082 vty_out(vty, "\n");
7083 }
7084
7085 }
7086
7087 /* dampening route */
7088 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7089 struct bgp_info *binfo, int display, safi_t safi,
7090 bool use_json, json_object *json)
7091 {
7092 struct attr *attr;
7093 int len;
7094 char timebuf[BGP_UPTIME_LEN];
7095
7096 /* short status lead text */
7097 route_vty_short_status_out(vty, binfo, json);
7098
7099 /* print prefix and mask */
7100 if (!use_json) {
7101 if (!display)
7102 route_vty_out_route(p, vty, NULL);
7103 else
7104 vty_out(vty, "%*s", 17, " ");
7105 }
7106
7107 len = vty_out(vty, "%s", binfo->peer->host);
7108 len = 17 - len;
7109 if (len < 1) {
7110 if (!use_json)
7111 vty_out(vty, "\n%*s", 34, " ");
7112 } else {
7113 if (use_json)
7114 json_object_int_add(json, "peerHost", len);
7115 else
7116 vty_out(vty, "%*s", len, " ");
7117 }
7118
7119 if (use_json)
7120 bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
7121 use_json, json);
7122 else
7123 vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7124 BGP_UPTIME_LEN,
7125 use_json, json));
7126
7127 /* Print attribute */
7128 attr = binfo->attr;
7129 if (attr) {
7130 /* Print aspath */
7131 if (attr->aspath) {
7132 if (use_json)
7133 json_object_string_add(json, "asPath",
7134 attr->aspath->str);
7135 else
7136 aspath_print_vty(vty, "%s", attr->aspath, " ");
7137 }
7138
7139 /* Print origin */
7140 if (use_json)
7141 json_object_string_add(json, "origin",
7142 bgp_origin_str[attr->origin]);
7143 else
7144 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7145 }
7146 if (!use_json)
7147 vty_out(vty, "\n");
7148 }
7149
7150 /* flap route */
7151 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7152 struct bgp_info *binfo, int display, safi_t safi,
7153 bool use_json, json_object *json)
7154 {
7155 struct attr *attr;
7156 struct bgp_damp_info *bdi;
7157 char timebuf[BGP_UPTIME_LEN];
7158 int len;
7159
7160 if (!binfo->extra)
7161 return;
7162
7163 bdi = binfo->extra->damp_info;
7164
7165 /* short status lead text */
7166 route_vty_short_status_out(vty, binfo, json);
7167
7168 /* print prefix and mask */
7169 if (!use_json) {
7170 if (!display)
7171 route_vty_out_route(p, vty, NULL);
7172 else
7173 vty_out(vty, "%*s", 17, " ");
7174 }
7175
7176 len = vty_out(vty, "%s", binfo->peer->host);
7177 len = 16 - len;
7178 if (len < 1) {
7179 if (!use_json)
7180 vty_out(vty, "\n%*s", 33, " ");
7181 } else {
7182 if (use_json)
7183 json_object_int_add(json, "peerHost", len);
7184 else
7185 vty_out(vty, "%*s", len, " ");
7186 }
7187
7188 len = vty_out(vty, "%d", bdi->flap);
7189 len = 5 - len;
7190 if (len < 1) {
7191 if (!use_json)
7192 vty_out(vty, " ");
7193 } else {
7194 if (use_json)
7195 json_object_int_add(json, "bdiFlap", len);
7196 else
7197 vty_out(vty, "%*s", len, " ");
7198 }
7199
7200 if (use_json)
7201 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
7202 json);
7203 else
7204 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
7205 BGP_UPTIME_LEN, 0, NULL));
7206
7207 if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
7208 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7209 if (use_json)
7210 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7211 BGP_UPTIME_LEN, use_json, json);
7212 else
7213 vty_out(vty, "%s ",
7214 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7215 BGP_UPTIME_LEN,
7216 use_json, json));
7217 } else {
7218 if (!use_json)
7219 vty_out(vty, "%*s ", 8, " ");
7220 }
7221
7222 /* Print attribute */
7223 attr = binfo->attr;
7224 if (attr) {
7225 /* Print aspath */
7226 if (attr->aspath) {
7227 if (use_json)
7228 json_object_string_add(json, "asPath",
7229 attr->aspath->str);
7230 else
7231 aspath_print_vty(vty, "%s", attr->aspath, " ");
7232 }
7233
7234 /* Print origin */
7235 if (use_json)
7236 json_object_string_add(json, "origin",
7237 bgp_origin_str[attr->origin]);
7238 else
7239 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7240 }
7241 if (!use_json)
7242 vty_out(vty, "\n");
7243 }
7244
7245 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
7246 int *first, const char *header,
7247 json_object *json_adv_to)
7248 {
7249 char buf1[INET6_ADDRSTRLEN];
7250 json_object *json_peer = NULL;
7251
7252 if (json_adv_to) {
7253 /* 'advertised-to' is a dictionary of peers we have advertised
7254 * this
7255 * prefix too. The key is the peer's IP or swpX, the value is
7256 * the
7257 * hostname if we know it and "" if not.
7258 */
7259 json_peer = json_object_new_object();
7260
7261 if (peer->hostname)
7262 json_object_string_add(json_peer, "hostname",
7263 peer->hostname);
7264
7265 if (peer->conf_if)
7266 json_object_object_add(json_adv_to, peer->conf_if,
7267 json_peer);
7268 else
7269 json_object_object_add(
7270 json_adv_to,
7271 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
7272 json_peer);
7273 } else {
7274 if (*first) {
7275 vty_out(vty, "%s", header);
7276 *first = 0;
7277 }
7278
7279 if (peer->hostname
7280 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
7281 if (peer->conf_if)
7282 vty_out(vty, " %s(%s)", peer->hostname,
7283 peer->conf_if);
7284 else
7285 vty_out(vty, " %s(%s)", peer->hostname,
7286 sockunion2str(&peer->su, buf1,
7287 SU_ADDRSTRLEN));
7288 } else {
7289 if (peer->conf_if)
7290 vty_out(vty, " %s", peer->conf_if);
7291 else
7292 vty_out(vty, " %s",
7293 sockunion2str(&peer->su, buf1,
7294 SU_ADDRSTRLEN));
7295 }
7296 }
7297 }
7298
7299 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
7300 struct bgp_info *binfo, afi_t afi, safi_t safi,
7301 json_object *json_paths)
7302 {
7303 char buf[INET6_ADDRSTRLEN];
7304 char buf1[BUFSIZ];
7305 char buf2[EVPN_ROUTE_STRLEN];
7306 struct attr *attr;
7307 int sockunion_vty_out(struct vty *, union sockunion *);
7308 time_t tbuf;
7309 json_object *json_bestpath = NULL;
7310 json_object *json_cluster_list = NULL;
7311 json_object *json_cluster_list_list = NULL;
7312 json_object *json_ext_community = NULL;
7313 json_object *json_last_update = NULL;
7314 json_object *json_pmsi = NULL;
7315 json_object *json_nexthop_global = NULL;
7316 json_object *json_nexthop_ll = NULL;
7317 json_object *json_nexthops = NULL;
7318 json_object *json_path = NULL;
7319 json_object *json_peer = NULL;
7320 json_object *json_string = NULL;
7321 json_object *json_adv_to = NULL;
7322 int first = 0;
7323 struct listnode *node, *nnode;
7324 struct peer *peer;
7325 int addpath_capable;
7326 int has_adj;
7327 unsigned int first_as;
7328 bool nexthop_self = CHECK_FLAG(binfo->flags, BGP_INFO_ANNC_NH_SELF)
7329 ? true
7330 : false;
7331
7332 if (json_paths) {
7333 json_path = json_object_new_object();
7334 json_peer = json_object_new_object();
7335 json_nexthop_global = json_object_new_object();
7336 }
7337
7338 if (!json_paths && safi == SAFI_EVPN) {
7339 char tag_buf[30];
7340
7341 bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
7342 vty_out(vty, " Route %s", buf2);
7343 tag_buf[0] = '\0';
7344 if (binfo->extra && binfo->extra->num_labels) {
7345 bgp_evpn_label2str(binfo->extra->label,
7346 binfo->extra->num_labels, tag_buf,
7347 sizeof(tag_buf));
7348 vty_out(vty, " VNI %s", tag_buf);
7349 }
7350 vty_out(vty, "\n");
7351 if (binfo->extra && binfo->extra->parent) {
7352 struct bgp_info *parent_ri;
7353 struct bgp_node *rn, *prn;
7354
7355 parent_ri = (struct bgp_info *)binfo->extra->parent;
7356 rn = parent_ri->net;
7357 if (rn && rn->prn) {
7358 prn = rn->prn;
7359 vty_out(vty, " Imported from %s:%s\n",
7360 prefix_rd2str(
7361 (struct prefix_rd *)&prn->p,
7362 buf1, sizeof(buf1)),
7363 buf2);
7364 }
7365 }
7366 }
7367
7368 attr = binfo->attr;
7369
7370 if (attr) {
7371 /* Line1 display AS-path, Aggregator */
7372 if (attr->aspath) {
7373 if (json_paths) {
7374 if (!attr->aspath->json)
7375 aspath_str_update(attr->aspath, true);
7376 json_object_lock(attr->aspath->json);
7377 json_object_object_add(json_path, "aspath",
7378 attr->aspath->json);
7379 } else {
7380 if (attr->aspath->segments)
7381 aspath_print_vty(vty, " %s",
7382 attr->aspath, "");
7383 else
7384 vty_out(vty, " Local");
7385 }
7386 }
7387
7388 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED)) {
7389 if (json_paths)
7390 json_object_boolean_true_add(json_path,
7391 "removed");
7392 else
7393 vty_out(vty, ", (removed)");
7394 }
7395
7396 if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE)) {
7397 if (json_paths)
7398 json_object_boolean_true_add(json_path,
7399 "stale");
7400 else
7401 vty_out(vty, ", (stale)");
7402 }
7403
7404 if (CHECK_FLAG(attr->flag,
7405 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
7406 if (json_paths) {
7407 json_object_int_add(json_path, "aggregatorAs",
7408 attr->aggregator_as);
7409 json_object_string_add(
7410 json_path, "aggregatorId",
7411 inet_ntoa(attr->aggregator_addr));
7412 } else {
7413 vty_out(vty, ", (aggregated by %u %s)",
7414 attr->aggregator_as,
7415 inet_ntoa(attr->aggregator_addr));
7416 }
7417 }
7418
7419 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7420 PEER_FLAG_REFLECTOR_CLIENT)) {
7421 if (json_paths)
7422 json_object_boolean_true_add(
7423 json_path, "rxedFromRrClient");
7424 else
7425 vty_out(vty, ", (Received from a RR-client)");
7426 }
7427
7428 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7429 PEER_FLAG_RSERVER_CLIENT)) {
7430 if (json_paths)
7431 json_object_boolean_true_add(
7432 json_path, "rxedFromRsClient");
7433 else
7434 vty_out(vty, ", (Received from a RS-client)");
7435 }
7436
7437 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7438 if (json_paths)
7439 json_object_boolean_true_add(
7440 json_path, "dampeningHistoryEntry");
7441 else
7442 vty_out(vty, ", (history entry)");
7443 } else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
7444 if (json_paths)
7445 json_object_boolean_true_add(
7446 json_path, "dampeningSuppressed");
7447 else
7448 vty_out(vty, ", (suppressed due to dampening)");
7449 }
7450
7451 if (!json_paths)
7452 vty_out(vty, "\n");
7453
7454 /* Line2 display Next-hop, Neighbor, Router-id */
7455 /* Display the nexthop */
7456 if ((p->family == AF_INET || p->family == AF_ETHERNET
7457 || p->family == AF_EVPN)
7458 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7459 || safi == SAFI_EVPN
7460 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7461 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7462 || safi == SAFI_EVPN) {
7463 if (json_paths)
7464 json_object_string_add(
7465 json_nexthop_global, "ip",
7466 inet_ntoa(
7467 attr->mp_nexthop_global_in));
7468 else
7469 vty_out(vty, " %s",
7470 inet_ntoa(
7471 attr->mp_nexthop_global_in));
7472 } else {
7473 if (json_paths)
7474 json_object_string_add(
7475 json_nexthop_global, "ip",
7476 inet_ntoa(attr->nexthop));
7477 else
7478 vty_out(vty, " %s",
7479 inet_ntoa(attr->nexthop));
7480 }
7481
7482 if (json_paths)
7483 json_object_string_add(json_nexthop_global,
7484 "afi", "ipv4");
7485 } else {
7486 if (json_paths) {
7487 json_object_string_add(
7488 json_nexthop_global, "ip",
7489 inet_ntop(AF_INET6,
7490 &attr->mp_nexthop_global, buf,
7491 INET6_ADDRSTRLEN));
7492 json_object_string_add(json_nexthop_global,
7493 "afi", "ipv6");
7494 json_object_string_add(json_nexthop_global,
7495 "scope", "global");
7496 } else {
7497 vty_out(vty, " %s",
7498 inet_ntop(AF_INET6,
7499 &attr->mp_nexthop_global, buf,
7500 INET6_ADDRSTRLEN));
7501 }
7502 }
7503
7504 /* Display the IGP cost or 'inaccessible' */
7505 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7506 if (json_paths)
7507 json_object_boolean_false_add(
7508 json_nexthop_global, "accessible");
7509 else
7510 vty_out(vty, " (inaccessible)");
7511 } else {
7512 if (binfo->extra && binfo->extra->igpmetric) {
7513 if (json_paths)
7514 json_object_int_add(
7515 json_nexthop_global, "metric",
7516 binfo->extra->igpmetric);
7517 else
7518 vty_out(vty, " (metric %u)",
7519 binfo->extra->igpmetric);
7520 }
7521
7522 /* IGP cost is 0, display this only for json */
7523 else {
7524 if (json_paths)
7525 json_object_int_add(json_nexthop_global,
7526 "metric", 0);
7527 }
7528
7529 if (json_paths)
7530 json_object_boolean_true_add(
7531 json_nexthop_global, "accessible");
7532 }
7533
7534 /* Display peer "from" output */
7535 /* This path was originated locally */
7536 if (binfo->peer == bgp->peer_self) {
7537
7538 if (safi == SAFI_EVPN
7539 || (p->family == AF_INET
7540 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7541 if (json_paths)
7542 json_object_string_add(
7543 json_peer, "peerId", "0.0.0.0");
7544 else
7545 vty_out(vty, " from 0.0.0.0 ");
7546 } else {
7547 if (json_paths)
7548 json_object_string_add(json_peer,
7549 "peerId", "::");
7550 else
7551 vty_out(vty, " from :: ");
7552 }
7553
7554 if (json_paths)
7555 json_object_string_add(
7556 json_peer, "routerId",
7557 inet_ntoa(bgp->router_id));
7558 else
7559 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
7560 }
7561
7562 /* We RXed this path from one of our peers */
7563 else {
7564
7565 if (json_paths) {
7566 json_object_string_add(
7567 json_peer, "peerId",
7568 sockunion2str(&binfo->peer->su, buf,
7569 SU_ADDRSTRLEN));
7570 json_object_string_add(
7571 json_peer, "routerId",
7572 inet_ntop(AF_INET,
7573 &binfo->peer->remote_id, buf1,
7574 sizeof(buf1)));
7575
7576 if (binfo->peer->hostname)
7577 json_object_string_add(
7578 json_peer, "hostname",
7579 binfo->peer->hostname);
7580
7581 if (binfo->peer->domainname)
7582 json_object_string_add(
7583 json_peer, "domainname",
7584 binfo->peer->domainname);
7585
7586 if (binfo->peer->conf_if)
7587 json_object_string_add(
7588 json_peer, "interface",
7589 binfo->peer->conf_if);
7590 } else {
7591 if (binfo->peer->conf_if) {
7592 if (binfo->peer->hostname
7593 && bgp_flag_check(
7594 binfo->peer->bgp,
7595 BGP_FLAG_SHOW_HOSTNAME))
7596 vty_out(vty, " from %s(%s)",
7597 binfo->peer->hostname,
7598 binfo->peer->conf_if);
7599 else
7600 vty_out(vty, " from %s",
7601 binfo->peer->conf_if);
7602 } else {
7603 if (binfo->peer->hostname
7604 && bgp_flag_check(
7605 binfo->peer->bgp,
7606 BGP_FLAG_SHOW_HOSTNAME))
7607 vty_out(vty, " from %s(%s)",
7608 binfo->peer->hostname,
7609 binfo->peer->host);
7610 else
7611 vty_out(vty, " from %s",
7612 sockunion2str(
7613 &binfo->peer
7614 ->su,
7615 buf,
7616 SU_ADDRSTRLEN));
7617 }
7618
7619 if (attr->flag
7620 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7621 vty_out(vty, " (%s)",
7622 inet_ntoa(attr->originator_id));
7623 else
7624 vty_out(vty, " (%s)",
7625 inet_ntop(
7626 AF_INET,
7627 &binfo->peer->remote_id,
7628 buf1, sizeof(buf1)));
7629 }
7630 }
7631
7632 /*
7633 * Note when vrfid of nexthop is different from that of prefix
7634 */
7635 if (binfo->extra && binfo->extra->bgp_orig) {
7636 vrf_id_t nexthop_vrfid = binfo->extra->bgp_orig->vrf_id;
7637
7638 if (json_paths) {
7639 const char *vn;
7640
7641 if (binfo->extra->bgp_orig->inst_type ==
7642 BGP_INSTANCE_TYPE_DEFAULT)
7643
7644 vn = "Default";
7645 else
7646 vn = binfo->extra->bgp_orig->name;
7647
7648 json_object_string_add(json_path, "nhVrfName",
7649 vn);
7650
7651 if (nexthop_vrfid == VRF_UNKNOWN) {
7652 json_object_int_add(json_path,
7653 "nhVrfId", -1);
7654 } else {
7655 json_object_int_add(json_path,
7656 "nhVrfId", (int)nexthop_vrfid);
7657 }
7658 } else {
7659 if (nexthop_vrfid == VRF_UNKNOWN)
7660 vty_out(vty, " vrf ?");
7661 else
7662 vty_out(vty, " vrf %u", nexthop_vrfid);
7663 }
7664 }
7665
7666 if (nexthop_self) {
7667 if (json_paths) {
7668 json_object_boolean_true_add(json_path,
7669 "announceNexthopSelf");
7670 } else {
7671 vty_out(vty, " announce-nh-self");
7672 }
7673 }
7674
7675 if (!json_paths)
7676 vty_out(vty, "\n");
7677
7678 /* display the link-local nexthop */
7679 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7680 if (json_paths) {
7681 json_nexthop_ll = json_object_new_object();
7682 json_object_string_add(
7683 json_nexthop_ll, "ip",
7684 inet_ntop(AF_INET6,
7685 &attr->mp_nexthop_local, buf,
7686 INET6_ADDRSTRLEN));
7687 json_object_string_add(json_nexthop_ll, "afi",
7688 "ipv6");
7689 json_object_string_add(json_nexthop_ll, "scope",
7690 "link-local");
7691
7692 json_object_boolean_true_add(json_nexthop_ll,
7693 "accessible");
7694
7695 if (!attr->mp_nexthop_prefer_global)
7696 json_object_boolean_true_add(
7697 json_nexthop_ll, "used");
7698 else
7699 json_object_boolean_true_add(
7700 json_nexthop_global, "used");
7701 } else {
7702 vty_out(vty, " (%s) %s\n",
7703 inet_ntop(AF_INET6,
7704 &attr->mp_nexthop_local, buf,
7705 INET6_ADDRSTRLEN),
7706 attr->mp_nexthop_prefer_global
7707 ? "(prefer-global)"
7708 : "(used)");
7709 }
7710 }
7711 /* If we do not have a link-local nexthop then we must flag the
7712 global as "used" */
7713 else {
7714 if (json_paths)
7715 json_object_boolean_true_add(
7716 json_nexthop_global, "used");
7717 }
7718
7719 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7720 * Int/Ext/Local, Atomic, best */
7721 if (json_paths)
7722 json_object_string_add(
7723 json_path, "origin",
7724 bgp_origin_long_str[attr->origin]);
7725 else
7726 vty_out(vty, " Origin %s",
7727 bgp_origin_long_str[attr->origin]);
7728
7729 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
7730 if (json_paths)
7731 json_object_int_add(json_path, "med",
7732 attr->med);
7733 else
7734 vty_out(vty, ", metric %u", attr->med);
7735 }
7736
7737 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7738 if (json_paths)
7739 json_object_int_add(json_path, "localpref",
7740 attr->local_pref);
7741 else
7742 vty_out(vty, ", localpref %u",
7743 attr->local_pref);
7744 }
7745
7746 if (attr->weight != 0) {
7747 if (json_paths)
7748 json_object_int_add(json_path, "weight",
7749 attr->weight);
7750 else
7751 vty_out(vty, ", weight %u", attr->weight);
7752 }
7753
7754 if (attr->tag != 0) {
7755 if (json_paths)
7756 json_object_int_add(json_path, "tag",
7757 attr->tag);
7758 else
7759 vty_out(vty, ", tag %" ROUTE_TAG_PRI,
7760 attr->tag);
7761 }
7762
7763 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7764 if (json_paths)
7765 json_object_boolean_false_add(json_path,
7766 "valid");
7767 else
7768 vty_out(vty, ", invalid");
7769 } else if (!CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7770 if (json_paths)
7771 json_object_boolean_true_add(json_path,
7772 "valid");
7773 else
7774 vty_out(vty, ", valid");
7775 }
7776
7777 if (binfo->peer != bgp->peer_self) {
7778 if (binfo->peer->as == binfo->peer->local_as) {
7779 if (CHECK_FLAG(bgp->config,
7780 BGP_CONFIG_CONFEDERATION)) {
7781 if (json_paths)
7782 json_object_string_add(
7783 json_peer, "type",
7784 "confed-internal");
7785 else
7786 vty_out(vty,
7787 ", confed-internal");
7788 } else {
7789 if (json_paths)
7790 json_object_string_add(
7791 json_peer, "type",
7792 "internal");
7793 else
7794 vty_out(vty, ", internal");
7795 }
7796 } else {
7797 if (bgp_confederation_peers_check(
7798 bgp, binfo->peer->as)) {
7799 if (json_paths)
7800 json_object_string_add(
7801 json_peer, "type",
7802 "confed-external");
7803 else
7804 vty_out(vty,
7805 ", confed-external");
7806 } else {
7807 if (json_paths)
7808 json_object_string_add(
7809 json_peer, "type",
7810 "external");
7811 else
7812 vty_out(vty, ", external");
7813 }
7814 }
7815 } else if (binfo->sub_type == BGP_ROUTE_AGGREGATE) {
7816 if (json_paths) {
7817 json_object_boolean_true_add(json_path,
7818 "aggregated");
7819 json_object_boolean_true_add(json_path,
7820 "local");
7821 } else {
7822 vty_out(vty, ", aggregated, local");
7823 }
7824 } else if (binfo->type != ZEBRA_ROUTE_BGP) {
7825 if (json_paths)
7826 json_object_boolean_true_add(json_path,
7827 "sourced");
7828 else
7829 vty_out(vty, ", sourced");
7830 } else {
7831 if (json_paths) {
7832 json_object_boolean_true_add(json_path,
7833 "sourced");
7834 json_object_boolean_true_add(json_path,
7835 "local");
7836 } else {
7837 vty_out(vty, ", sourced, local");
7838 }
7839 }
7840
7841 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
7842 if (json_paths)
7843 json_object_boolean_true_add(json_path,
7844 "atomicAggregate");
7845 else
7846 vty_out(vty, ", atomic-aggregate");
7847 }
7848
7849 if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH)
7850 || (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)
7851 && bgp_info_mpath_count(binfo))) {
7852 if (json_paths)
7853 json_object_boolean_true_add(json_path,
7854 "multipath");
7855 else
7856 vty_out(vty, ", multipath");
7857 }
7858
7859 // Mark the bestpath(s)
7860 if (CHECK_FLAG(binfo->flags, BGP_INFO_DMED_SELECTED)) {
7861 first_as = aspath_get_first_as(attr->aspath);
7862
7863 if (json_paths) {
7864 if (!json_bestpath)
7865 json_bestpath =
7866 json_object_new_object();
7867 json_object_int_add(json_bestpath,
7868 "bestpathFromAs", first_as);
7869 } else {
7870 if (first_as)
7871 vty_out(vty, ", bestpath-from-AS %u",
7872 first_as);
7873 else
7874 vty_out(vty,
7875 ", bestpath-from-AS Local");
7876 }
7877 }
7878
7879 if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)) {
7880 if (json_paths) {
7881 if (!json_bestpath)
7882 json_bestpath =
7883 json_object_new_object();
7884 json_object_boolean_true_add(json_bestpath,
7885 "overall");
7886 } else
7887 vty_out(vty, ", best");
7888 }
7889
7890 if (json_bestpath)
7891 json_object_object_add(json_path, "bestpath",
7892 json_bestpath);
7893
7894 if (!json_paths)
7895 vty_out(vty, "\n");
7896
7897 /* Line 4 display Community */
7898 if (attr->community) {
7899 if (json_paths) {
7900 if (!attr->community->json)
7901 community_str(attr->community, true);
7902 json_object_lock(attr->community->json);
7903 json_object_object_add(json_path, "community",
7904 attr->community->json);
7905 } else {
7906 vty_out(vty, " Community: %s\n",
7907 attr->community->str);
7908 }
7909 }
7910
7911 /* Line 5 display Extended-community */
7912 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7913 if (json_paths) {
7914 json_ext_community = json_object_new_object();
7915 json_object_string_add(json_ext_community,
7916 "string",
7917 attr->ecommunity->str);
7918 json_object_object_add(json_path,
7919 "extendedCommunity",
7920 json_ext_community);
7921 } else {
7922 vty_out(vty, " Extended Community: %s\n",
7923 attr->ecommunity->str);
7924 }
7925 }
7926
7927 /* Line 6 display Large community */
7928 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
7929 if (json_paths) {
7930 if (!attr->lcommunity->json)
7931 lcommunity_str(attr->lcommunity, true);
7932 json_object_lock(attr->lcommunity->json);
7933 json_object_object_add(json_path,
7934 "largeCommunity",
7935 attr->lcommunity->json);
7936 } else {
7937 vty_out(vty, " Large Community: %s\n",
7938 attr->lcommunity->str);
7939 }
7940 }
7941
7942 /* Line 7 display Originator, Cluster-id */
7943 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7944 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
7945 if (attr->flag
7946 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
7947 if (json_paths)
7948 json_object_string_add(
7949 json_path, "originatorId",
7950 inet_ntoa(attr->originator_id));
7951 else
7952 vty_out(vty, " Originator: %s",
7953 inet_ntoa(attr->originator_id));
7954 }
7955
7956 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
7957 int i;
7958
7959 if (json_paths) {
7960 json_cluster_list =
7961 json_object_new_object();
7962 json_cluster_list_list =
7963 json_object_new_array();
7964
7965 for (i = 0;
7966 i < attr->cluster->length / 4;
7967 i++) {
7968 json_string = json_object_new_string(
7969 inet_ntoa(
7970 attr->cluster->list
7971 [i]));
7972 json_object_array_add(
7973 json_cluster_list_list,
7974 json_string);
7975 }
7976
7977 /* struct cluster_list does not have
7978 "str" variable like
7979 * aspath and community do. Add this
7980 someday if someone
7981 * asks for it.
7982 json_object_string_add(json_cluster_list,
7983 "string", attr->cluster->str);
7984 */
7985 json_object_object_add(
7986 json_cluster_list, "list",
7987 json_cluster_list_list);
7988 json_object_object_add(
7989 json_path, "clusterList",
7990 json_cluster_list);
7991 } else {
7992 vty_out(vty, ", Cluster list: ");
7993
7994 for (i = 0;
7995 i < attr->cluster->length / 4;
7996 i++) {
7997 vty_out(vty, "%s ",
7998 inet_ntoa(
7999 attr->cluster->list
8000 [i]));
8001 }
8002 }
8003 }
8004
8005 if (!json_paths)
8006 vty_out(vty, "\n");
8007 }
8008
8009 if (binfo->extra && binfo->extra->damp_info)
8010 bgp_damp_info_vty(vty, binfo, json_path);
8011
8012 /* Remote Label */
8013 if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])
8014 && safi != SAFI_EVPN) {
8015 mpls_label_t label =
8016 label_pton(&binfo->extra->label[0]);
8017 if (json_paths)
8018 json_object_int_add(json_path, "remoteLabel",
8019 label);
8020 else
8021 vty_out(vty, " Remote label: %d\n", label);
8022 }
8023
8024 /* Label Index */
8025 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8026 if (json_paths)
8027 json_object_int_add(json_path, "labelIndex",
8028 attr->label_index);
8029 else
8030 vty_out(vty, " Label Index: %d\n",
8031 attr->label_index);
8032 }
8033
8034 /* Line 8 display Addpath IDs */
8035 if (binfo->addpath_rx_id || binfo->addpath_tx_id) {
8036 if (json_paths) {
8037 json_object_int_add(json_path, "addpathRxId",
8038 binfo->addpath_rx_id);
8039 json_object_int_add(json_path, "addpathTxId",
8040 binfo->addpath_tx_id);
8041 } else {
8042 vty_out(vty, " AddPath ID: RX %u, TX %u\n",
8043 binfo->addpath_rx_id,
8044 binfo->addpath_tx_id);
8045 }
8046 }
8047
8048 /* If we used addpath to TX a non-bestpath we need to display
8049 * "Advertised to" on a path-by-path basis */
8050 if (bgp->addpath_tx_used[afi][safi]) {
8051 first = 1;
8052
8053 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8054 addpath_capable =
8055 bgp_addpath_encode_tx(peer, afi, safi);
8056 has_adj = bgp_adj_out_lookup(
8057 peer, binfo->net, binfo->addpath_tx_id);
8058
8059 if ((addpath_capable && has_adj)
8060 || (!addpath_capable && has_adj
8061 && CHECK_FLAG(binfo->flags,
8062 BGP_INFO_SELECTED))) {
8063 if (json_path && !json_adv_to)
8064 json_adv_to =
8065 json_object_new_object();
8066
8067 route_vty_out_advertised_to(
8068 vty, peer, &first,
8069 " Advertised to:",
8070 json_adv_to);
8071 }
8072 }
8073
8074 if (json_path) {
8075 if (json_adv_to) {
8076 json_object_object_add(json_path,
8077 "advertisedTo",
8078 json_adv_to);
8079 }
8080 } else {
8081 if (!first) {
8082 vty_out(vty, "\n");
8083 }
8084 }
8085 }
8086
8087 /* Line 9 display Uptime */
8088 tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
8089 if (json_paths) {
8090 json_last_update = json_object_new_object();
8091 json_object_int_add(json_last_update, "epoch", tbuf);
8092 json_object_string_add(json_last_update, "string",
8093 ctime(&tbuf));
8094 json_object_object_add(json_path, "lastUpdate",
8095 json_last_update);
8096 } else
8097 vty_out(vty, " Last update: %s", ctime(&tbuf));
8098
8099 /* Line 10 display PMSI tunnel attribute, if present */
8100 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
8101 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
8102 attr->pmsi_tnl_type,
8103 PMSI_TNLTYPE_STR_DEFAULT);
8104
8105 if (json_paths) {
8106 json_pmsi = json_object_new_object();
8107 json_object_string_add(json_pmsi,
8108 "tunnelType", str);
8109 json_object_object_add(json_path, "pmsi",
8110 json_pmsi);
8111 } else
8112 vty_out(vty, " PMSI Tunnel Type: %s\n",
8113 str);
8114 }
8115
8116 }
8117
8118 /* We've constructed the json object for this path, add it to the json
8119 * array of paths
8120 */
8121 if (json_paths) {
8122 if (json_nexthop_global || json_nexthop_ll) {
8123 json_nexthops = json_object_new_array();
8124
8125 if (json_nexthop_global)
8126 json_object_array_add(json_nexthops,
8127 json_nexthop_global);
8128
8129 if (json_nexthop_ll)
8130 json_object_array_add(json_nexthops,
8131 json_nexthop_ll);
8132
8133 json_object_object_add(json_path, "nexthops",
8134 json_nexthops);
8135 }
8136
8137 json_object_object_add(json_path, "peer", json_peer);
8138 json_object_array_add(json_paths, json_path);
8139 } else
8140 vty_out(vty, "\n");
8141 }
8142
8143 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8144 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8145 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8146
8147 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
8148 const char *prefix_list_str, afi_t afi,
8149 safi_t safi, enum bgp_show_type type);
8150 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
8151 const char *filter, afi_t afi, safi_t safi,
8152 enum bgp_show_type type);
8153 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
8154 const char *rmap_str, afi_t afi, safi_t safi,
8155 enum bgp_show_type type);
8156 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
8157 const char *com, int exact, afi_t afi,
8158 safi_t safi);
8159 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
8160 const char *prefix, afi_t afi, safi_t safi,
8161 enum bgp_show_type type);
8162 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
8163 afi_t afi, safi_t safi, enum bgp_show_type type);
8164 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
8165 const char *comstr, int exact, afi_t afi,
8166 safi_t safi, bool use_json);
8167
8168
8169 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
8170 struct bgp_table *table, enum bgp_show_type type,
8171 void *output_arg, bool use_json, char *rd,
8172 int is_last, unsigned long *output_cum,
8173 unsigned long *total_cum,
8174 unsigned long *json_header_depth)
8175 {
8176 struct bgp_info *ri;
8177 struct bgp_node *rn;
8178 int header = 1;
8179 int display;
8180 unsigned long output_count = 0;
8181 unsigned long total_count = 0;
8182 struct prefix *p;
8183 char buf[BUFSIZ];
8184 char buf2[BUFSIZ];
8185 json_object *json_paths = NULL;
8186 int first = 1;
8187
8188 if (output_cum && *output_cum != 0)
8189 header = 0;
8190
8191 if (use_json && !*json_header_depth) {
8192 vty_out(vty,
8193 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8194 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8195 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
8196 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
8197 : bgp->name,
8198 table->version, inet_ntoa(bgp->router_id));
8199 *json_header_depth = 2;
8200 if (rd) {
8201 vty_out(vty, " \"routeDistinguishers\" : {");
8202 ++*json_header_depth;
8203 }
8204 }
8205
8206 if (use_json && rd) {
8207 vty_out(vty, " \"%s\" : { ", rd);
8208 }
8209
8210 /* Start processing of routes. */
8211 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
8212 if (rn->info == NULL)
8213 continue;
8214
8215 display = 0;
8216 if (use_json)
8217 json_paths = json_object_new_array();
8218 else
8219 json_paths = NULL;
8220
8221 for (ri = rn->info; ri; ri = ri->next) {
8222 total_count++;
8223 if (type == bgp_show_type_flap_statistics
8224 || type == bgp_show_type_flap_neighbor
8225 || type == bgp_show_type_dampend_paths
8226 || type == bgp_show_type_damp_neighbor) {
8227 if (!(ri->extra && ri->extra->damp_info))
8228 continue;
8229 }
8230 if (type == bgp_show_type_regexp) {
8231 regex_t *regex = output_arg;
8232
8233 if (bgp_regexec(regex, ri->attr->aspath)
8234 == REG_NOMATCH)
8235 continue;
8236 }
8237 if (type == bgp_show_type_prefix_list) {
8238 struct prefix_list *plist = output_arg;
8239
8240 if (prefix_list_apply(plist, &rn->p)
8241 != PREFIX_PERMIT)
8242 continue;
8243 }
8244 if (type == bgp_show_type_filter_list) {
8245 struct as_list *as_list = output_arg;
8246
8247 if (as_list_apply(as_list, ri->attr->aspath)
8248 != AS_FILTER_PERMIT)
8249 continue;
8250 }
8251 if (type == bgp_show_type_route_map) {
8252 struct route_map *rmap = output_arg;
8253 struct bgp_info binfo;
8254 struct attr dummy_attr;
8255 int ret;
8256
8257 bgp_attr_dup(&dummy_attr, ri->attr);
8258
8259 binfo.peer = ri->peer;
8260 binfo.attr = &dummy_attr;
8261
8262 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
8263 &binfo);
8264 if (ret == RMAP_DENYMATCH)
8265 continue;
8266 }
8267 if (type == bgp_show_type_neighbor
8268 || type == bgp_show_type_flap_neighbor
8269 || type == bgp_show_type_damp_neighbor) {
8270 union sockunion *su = output_arg;
8271
8272 if (ri->peer == NULL
8273 || ri->peer->su_remote == NULL
8274 || !sockunion_same(ri->peer->su_remote, su))
8275 continue;
8276 }
8277 if (type == bgp_show_type_cidr_only) {
8278 uint32_t destination;
8279
8280 destination = ntohl(rn->p.u.prefix4.s_addr);
8281 if (IN_CLASSC(destination)
8282 && rn->p.prefixlen == 24)
8283 continue;
8284 if (IN_CLASSB(destination)
8285 && rn->p.prefixlen == 16)
8286 continue;
8287 if (IN_CLASSA(destination)
8288 && rn->p.prefixlen == 8)
8289 continue;
8290 }
8291 if (type == bgp_show_type_prefix_longer) {
8292 p = output_arg;
8293 if (!prefix_match(p, &rn->p))
8294 continue;
8295 }
8296 if (type == bgp_show_type_community_all) {
8297 if (!ri->attr->community)
8298 continue;
8299 }
8300 if (type == bgp_show_type_community) {
8301 struct community *com = output_arg;
8302
8303 if (!ri->attr->community
8304 || !community_match(ri->attr->community,
8305 com))
8306 continue;
8307 }
8308 if (type == bgp_show_type_community_exact) {
8309 struct community *com = output_arg;
8310
8311 if (!ri->attr->community
8312 || !community_cmp(ri->attr->community, com))
8313 continue;
8314 }
8315 if (type == bgp_show_type_community_list) {
8316 struct community_list *list = output_arg;
8317
8318 if (!community_list_match(ri->attr->community,
8319 list))
8320 continue;
8321 }
8322 if (type == bgp_show_type_community_list_exact) {
8323 struct community_list *list = output_arg;
8324
8325 if (!community_list_exact_match(
8326 ri->attr->community, list))
8327 continue;
8328 }
8329 if (type == bgp_show_type_lcommunity) {
8330 struct lcommunity *lcom = output_arg;
8331
8332 if (!ri->attr->lcommunity
8333 || !lcommunity_match(ri->attr->lcommunity,
8334 lcom))
8335 continue;
8336 }
8337 if (type == bgp_show_type_lcommunity_list) {
8338 struct community_list *list = output_arg;
8339
8340 if (!lcommunity_list_match(ri->attr->lcommunity,
8341 list))
8342 continue;
8343 }
8344 if (type == bgp_show_type_lcommunity_all) {
8345 if (!ri->attr->lcommunity)
8346 continue;
8347 }
8348 if (type == bgp_show_type_dampend_paths
8349 || type == bgp_show_type_damp_neighbor) {
8350 if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED)
8351 || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
8352 continue;
8353 }
8354
8355 if (!use_json && header) {
8356 vty_out(vty, "BGP table version is %" PRIu64
8357 ", local router ID is %s, vrf id ",
8358 table->version,
8359 inet_ntoa(bgp->router_id));
8360 if (bgp->vrf_id == VRF_UNKNOWN)
8361 vty_out(vty, "%s", VRFID_NONE_STR);
8362 else
8363 vty_out(vty, "%u", bgp->vrf_id);
8364 vty_out(vty, "\n");
8365 vty_out(vty, BGP_SHOW_SCODE_HEADER);
8366 vty_out(vty, BGP_SHOW_NCODE_HEADER);
8367 vty_out(vty, BGP_SHOW_OCODE_HEADER);
8368 if (type == bgp_show_type_dampend_paths
8369 || type == bgp_show_type_damp_neighbor)
8370 vty_out(vty, BGP_SHOW_DAMP_HEADER);
8371 else if (type == bgp_show_type_flap_statistics
8372 || type == bgp_show_type_flap_neighbor)
8373 vty_out(vty, BGP_SHOW_FLAP_HEADER);
8374 else
8375 vty_out(vty, BGP_SHOW_HEADER);
8376 header = 0;
8377 }
8378 if (rd != NULL && !display && !output_count) {
8379 if (!use_json)
8380 vty_out(vty,
8381 "Route Distinguisher: %s\n",
8382 rd);
8383 }
8384 if (type == bgp_show_type_dampend_paths
8385 || type == bgp_show_type_damp_neighbor)
8386 damp_route_vty_out(vty, &rn->p, ri, display,
8387 safi, use_json, json_paths);
8388 else if (type == bgp_show_type_flap_statistics
8389 || type == bgp_show_type_flap_neighbor)
8390 flap_route_vty_out(vty, &rn->p, ri, display,
8391 safi, use_json, json_paths);
8392 else
8393 route_vty_out(vty, &rn->p, ri, display, safi,
8394 json_paths);
8395 display++;
8396 }
8397
8398 if (display) {
8399 output_count++;
8400 if (!use_json)
8401 continue;
8402
8403 p = &rn->p;
8404 sprintf(buf2, "%s/%d",
8405 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
8406 p->prefixlen);
8407 if (first)
8408 vty_out(vty, "\"%s\": ", buf2);
8409 else
8410 vty_out(vty, ",\"%s\": ", buf2);
8411
8412 vty_out(vty, "%s",
8413 json_object_to_json_string(json_paths));
8414 json_object_free(json_paths);
8415 json_paths = NULL;
8416 first = 0;
8417 }
8418 }
8419
8420 if (output_cum) {
8421 output_count += *output_cum;
8422 *output_cum = output_count;
8423 }
8424 if (total_cum) {
8425 total_count += *total_cum;
8426 *total_cum = total_count;
8427 }
8428 if (use_json) {
8429 if (rd) {
8430 vty_out(vty, " }%s ", (is_last ? "" : ","));
8431 }
8432 if (is_last) {
8433 unsigned long i;
8434 for (i = 0; i < *json_header_depth; ++i)
8435 vty_out(vty, " } ");
8436 }
8437 } else {
8438 if (is_last) {
8439 /* No route is displayed */
8440 if (output_count == 0) {
8441 if (type == bgp_show_type_normal)
8442 vty_out(vty,
8443 "No BGP prefixes displayed, %ld exist\n",
8444 total_count);
8445 } else
8446 vty_out(vty,
8447 "\nDisplayed %ld routes and %ld total paths\n",
8448 output_count, total_count);
8449 }
8450 }
8451
8452 return CMD_SUCCESS;
8453 }
8454
8455 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
8456 struct bgp_table *table, struct prefix_rd *prd_match,
8457 enum bgp_show_type type, void *output_arg, bool use_json)
8458 {
8459 struct bgp_node *rn, *next;
8460 unsigned long output_cum = 0;
8461 unsigned long total_cum = 0;
8462 unsigned long json_header_depth = 0;
8463 bool show_msg;
8464
8465 show_msg = (!use_json && type == bgp_show_type_normal);
8466
8467 for (rn = bgp_table_top(table); rn; rn = next) {
8468 next = bgp_route_next(rn);
8469 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
8470 continue;
8471 if (rn->info != NULL) {
8472 struct prefix_rd prd;
8473 char rd[RD_ADDRSTRLEN];
8474
8475 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
8476 prefix_rd2str(&prd, rd, sizeof(rd));
8477 bgp_show_table(vty, bgp, safi, rn->info, type,
8478 output_arg, use_json, rd, next == NULL,
8479 &output_cum, &total_cum,
8480 &json_header_depth);
8481 if (next == NULL)
8482 show_msg = false;
8483 }
8484 }
8485 if (show_msg) {
8486 if (output_cum == 0)
8487 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
8488 total_cum);
8489 else
8490 vty_out(vty,
8491 "\nDisplayed %ld routes and %ld total paths\n",
8492 output_cum, total_cum);
8493 }
8494 return CMD_SUCCESS;
8495 }
8496 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
8497 enum bgp_show_type type, void *output_arg, bool use_json)
8498 {
8499 struct bgp_table *table;
8500 unsigned long json_header_depth = 0;
8501
8502 if (bgp == NULL) {
8503 bgp = bgp_get_default();
8504 }
8505
8506 if (bgp == NULL) {
8507 if (!use_json)
8508 vty_out(vty, "No BGP process is configured\n");
8509 else
8510 vty_out(vty, "{}\n");
8511 return CMD_WARNING;
8512 }
8513
8514 table = bgp->rib[afi][safi];
8515 /* use MPLS and ENCAP specific shows until they are merged */
8516 if (safi == SAFI_MPLS_VPN) {
8517 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
8518 output_arg, use_json);
8519 }
8520
8521 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
8522 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
8523 output_arg, use_json,
8524 1, NULL, NULL);
8525 }
8526 /* labeled-unicast routes live in the unicast table */
8527 else if (safi == SAFI_LABELED_UNICAST)
8528 safi = SAFI_UNICAST;
8529
8530 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
8531 NULL, 1, NULL, NULL, &json_header_depth);
8532 }
8533
8534 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
8535 safi_t safi, bool use_json)
8536 {
8537 struct listnode *node, *nnode;
8538 struct bgp *bgp;
8539 int is_first = 1;
8540 bool route_output = false;
8541
8542 if (use_json)
8543 vty_out(vty, "{\n");
8544
8545 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8546 route_output = true;
8547 if (use_json) {
8548 if (!is_first)
8549 vty_out(vty, ",\n");
8550 else
8551 is_first = 0;
8552
8553 vty_out(vty, "\"%s\":",
8554 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8555 ? "Default"
8556 : bgp->name);
8557 } else {
8558 vty_out(vty, "\nInstance %s:\n",
8559 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8560 ? "Default"
8561 : bgp->name);
8562 }
8563 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
8564 use_json);
8565 }
8566
8567 if (use_json)
8568 vty_out(vty, "}\n");
8569 else if (!route_output)
8570 vty_out(vty, "%% BGP instance not found\n");
8571 }
8572
8573 /* Header of detailed BGP route information */
8574 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
8575 struct bgp_node *rn, struct prefix_rd *prd,
8576 afi_t afi, safi_t safi, json_object *json)
8577 {
8578 struct bgp_info *ri;
8579 struct prefix *p;
8580 struct peer *peer;
8581 struct listnode *node, *nnode;
8582 char buf1[RD_ADDRSTRLEN];
8583 char buf2[INET6_ADDRSTRLEN];
8584 char buf3[EVPN_ROUTE_STRLEN];
8585 char prefix_str[BUFSIZ];
8586 int count = 0;
8587 int best = 0;
8588 int suppress = 0;
8589 int accept_own = 0;
8590 int route_filter_translated_v4 = 0;
8591 int route_filter_v4 = 0;
8592 int route_filter_translated_v6 = 0;
8593 int route_filter_v6 = 0;
8594 int llgr_stale = 0;
8595 int no_llgr = 0;
8596 int accept_own_nexthop = 0;
8597 int blackhole = 0;
8598 int no_export = 0;
8599 int no_advertise = 0;
8600 int local_as = 0;
8601 int no_peer = 0;
8602 int first = 1;
8603 int has_valid_label = 0;
8604 mpls_label_t label = 0;
8605 json_object *json_adv_to = NULL;
8606
8607 p = &rn->p;
8608 has_valid_label = bgp_is_valid_label(&rn->local_label);
8609
8610 if (has_valid_label)
8611 label = label_pton(&rn->local_label);
8612
8613 if (json) {
8614 if (has_valid_label)
8615 json_object_int_add(json, "localLabel", label);
8616
8617 json_object_string_add(
8618 json, "prefix",
8619 prefix2str(p, prefix_str, sizeof(prefix_str)));
8620 } else {
8621 if (safi == SAFI_EVPN)
8622 vty_out(vty, "BGP routing table entry for %s%s%s\n",
8623 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
8624 : "",
8625 prd ? ":" : "",
8626 bgp_evpn_route2str((struct prefix_evpn *)p,
8627 buf3, sizeof(buf3)));
8628 else
8629 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8630 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8631 ? prefix_rd2str(prd, buf1,
8632 sizeof(buf1))
8633 : ""),
8634 safi == SAFI_MPLS_VPN ? ":" : "",
8635 inet_ntop(p->family, &p->u.prefix, buf2,
8636 INET6_ADDRSTRLEN),
8637 p->prefixlen);
8638
8639 if (has_valid_label)
8640 vty_out(vty, "Local label: %d\n", label);
8641 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
8642 vty_out(vty, "not allocated\n");
8643 }
8644
8645 for (ri = rn->info; ri; ri = ri->next) {
8646 count++;
8647 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
8648 best = count;
8649 if (ri->extra && ri->extra->suppress)
8650 suppress = 1;
8651 if (ri->attr->community != NULL) {
8652 if (community_include(ri->attr->community,
8653 COMMUNITY_NO_ADVERTISE))
8654 no_advertise = 1;
8655 if (community_include(ri->attr->community,
8656 COMMUNITY_NO_EXPORT))
8657 no_export = 1;
8658 if (community_include(ri->attr->community,
8659 COMMUNITY_LOCAL_AS))
8660 local_as = 1;
8661 }
8662 }
8663 }
8664
8665 if (!json) {
8666 vty_out(vty, "Paths: (%d available", count);
8667 if (best) {
8668 vty_out(vty, ", best #%d", best);
8669 if (safi == SAFI_UNICAST)
8670 vty_out(vty, ", table %s",
8671 (bgp->inst_type
8672 == BGP_INSTANCE_TYPE_DEFAULT)
8673 ? "Default-IP-Routing-Table"
8674 : bgp->name);
8675 } else
8676 vty_out(vty, ", no best path");
8677
8678 if (accept_own)
8679 vty_out(vty,
8680 ", accept own local route exported and imported in different VRF");
8681 else if (route_filter_translated_v4)
8682 vty_out(vty,
8683 ", mark translated RTs for VPNv4 route filtering");
8684 else if (route_filter_v4)
8685 vty_out(vty,
8686 ", attach RT as-is for VPNv4 route filtering");
8687 else if (route_filter_translated_v6)
8688 vty_out(vty,
8689 ", mark translated RTs for VPNv6 route filtering");
8690 else if (route_filter_v6)
8691 vty_out(vty,
8692 ", attach RT as-is for VPNv6 route filtering");
8693 else if (llgr_stale)
8694 vty_out(vty,
8695 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
8696 else if (no_llgr)
8697 vty_out(vty,
8698 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
8699 else if (accept_own_nexthop)
8700 vty_out(vty,
8701 ", accept local nexthop");
8702 else if (blackhole)
8703 vty_out(vty, ", inform peer to blackhole prefix");
8704 else if (no_export)
8705 vty_out(vty, ", not advertised to EBGP peer");
8706 else if (no_advertise)
8707 vty_out(vty, ", not advertised to any peer");
8708 else if (local_as)
8709 vty_out(vty, ", not advertised outside local AS");
8710 else if (no_peer)
8711 vty_out(vty,
8712 ", inform EBGP peer not to advertise to their EBGP peers");
8713
8714 if (suppress)
8715 vty_out(vty,
8716 ", Advertisements suppressed by an aggregate.");
8717 vty_out(vty, ")\n");
8718 }
8719
8720 /* If we are not using addpath then we can display Advertised to and
8721 * that will
8722 * show what peers we advertised the bestpath to. If we are using
8723 * addpath
8724 * though then we must display Advertised to on a path-by-path basis. */
8725 if (!bgp->addpath_tx_used[afi][safi]) {
8726 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8727 if (bgp_adj_out_lookup(peer, rn, 0)) {
8728 if (json && !json_adv_to)
8729 json_adv_to = json_object_new_object();
8730
8731 route_vty_out_advertised_to(
8732 vty, peer, &first,
8733 " Advertised to non peer-group peers:\n ",
8734 json_adv_to);
8735 }
8736 }
8737
8738 if (json) {
8739 if (json_adv_to) {
8740 json_object_object_add(json, "advertisedTo",
8741 json_adv_to);
8742 }
8743 } else {
8744 if (first)
8745 vty_out(vty, " Not advertised to any peer");
8746 vty_out(vty, "\n");
8747 }
8748 }
8749 }
8750
8751 /* Display specified route of BGP table. */
8752 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
8753 struct bgp_table *rib, const char *ip_str,
8754 afi_t afi, safi_t safi,
8755 struct prefix_rd *prd, int prefix_check,
8756 enum bgp_path_type pathtype, bool use_json)
8757 {
8758 int ret;
8759 int header;
8760 int display = 0;
8761 struct prefix match;
8762 struct bgp_node *rn;
8763 struct bgp_node *rm;
8764 struct bgp_info *ri;
8765 struct bgp_table *table;
8766 json_object *json = NULL;
8767 json_object *json_paths = NULL;
8768
8769 /* Check IP address argument. */
8770 ret = str2prefix(ip_str, &match);
8771 if (!ret) {
8772 vty_out(vty, "address is malformed\n");
8773 return CMD_WARNING;
8774 }
8775
8776 match.family = afi2family(afi);
8777
8778 if (use_json) {
8779 json = json_object_new_object();
8780 json_paths = json_object_new_array();
8781 }
8782
8783 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
8784 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
8785 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
8786 continue;
8787
8788 if ((table = rn->info) == NULL)
8789 continue;
8790
8791 header = 1;
8792
8793 if ((rm = bgp_node_match(table, &match)) == NULL)
8794 continue;
8795
8796 if (prefix_check
8797 && rm->p.prefixlen != match.prefixlen) {
8798 bgp_unlock_node(rm);
8799 continue;
8800 }
8801
8802 for (ri = rm->info; ri; ri = ri->next) {
8803 if (header) {
8804 route_vty_out_detail_header(
8805 vty, bgp, rm,
8806 (struct prefix_rd *)&rn->p,
8807 AFI_IP, safi, json);
8808 header = 0;
8809 }
8810 display++;
8811
8812 if (pathtype == BGP_PATH_ALL
8813 || (pathtype == BGP_PATH_BESTPATH
8814 && CHECK_FLAG(ri->flags,
8815 BGP_INFO_SELECTED))
8816 || (pathtype == BGP_PATH_MULTIPATH
8817 && (CHECK_FLAG(ri->flags,
8818 BGP_INFO_MULTIPATH)
8819 || CHECK_FLAG(ri->flags,
8820 BGP_INFO_SELECTED))))
8821 route_vty_out_detail(vty, bgp, &rm->p,
8822 ri, AFI_IP, safi,
8823 json_paths);
8824 }
8825
8826 bgp_unlock_node(rm);
8827 }
8828 } else if (safi == SAFI_FLOWSPEC) {
8829 display = bgp_flowspec_display_match_per_ip(afi, rib,
8830 &match, prefix_check,
8831 vty,
8832 use_json,
8833 json_paths);
8834 } else {
8835 header = 1;
8836
8837 if ((rn = bgp_node_match(rib, &match)) != NULL) {
8838 if (!prefix_check
8839 || rn->p.prefixlen == match.prefixlen) {
8840 for (ri = rn->info; ri; ri = ri->next) {
8841 if (header) {
8842 route_vty_out_detail_header(
8843 vty, bgp, rn, NULL, afi,
8844 safi, json);
8845 header = 0;
8846 }
8847 display++;
8848
8849 if (pathtype == BGP_PATH_ALL
8850 || (pathtype == BGP_PATH_BESTPATH
8851 && CHECK_FLAG(
8852 ri->flags,
8853 BGP_INFO_SELECTED))
8854 || (pathtype == BGP_PATH_MULTIPATH
8855 && (CHECK_FLAG(
8856 ri->flags,
8857 BGP_INFO_MULTIPATH)
8858 || CHECK_FLAG(
8859 ri->flags,
8860 BGP_INFO_SELECTED))))
8861 route_vty_out_detail(
8862 vty, bgp, &rn->p, ri,
8863 afi, safi, json_paths);
8864 }
8865 }
8866
8867 bgp_unlock_node(rn);
8868 }
8869 }
8870
8871 if (use_json) {
8872 if (display)
8873 json_object_object_add(json, "paths", json_paths);
8874
8875 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8876 json, JSON_C_TO_STRING_PRETTY));
8877 json_object_free(json);
8878 } else {
8879 if (!display) {
8880 vty_out(vty, "%% Network not in table\n");
8881 return CMD_WARNING;
8882 }
8883 }
8884
8885 return CMD_SUCCESS;
8886 }
8887
8888 /* Display specified route of Main RIB */
8889 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
8890 afi_t afi, safi_t safi, struct prefix_rd *prd,
8891 int prefix_check, enum bgp_path_type pathtype,
8892 bool use_json)
8893 {
8894 if (!bgp) {
8895 bgp = bgp_get_default();
8896 if (!bgp) {
8897 if (!use_json)
8898 vty_out(vty, "No BGP process is configured\n");
8899 else
8900 vty_out(vty, "{}\n");
8901 return CMD_WARNING;
8902 }
8903 }
8904
8905 /* labeled-unicast routes live in the unicast table */
8906 if (safi == SAFI_LABELED_UNICAST)
8907 safi = SAFI_UNICAST;
8908
8909 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
8910 afi, safi, prd, prefix_check, pathtype,
8911 use_json);
8912 }
8913
8914 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
8915 struct cmd_token **argv, afi_t afi, safi_t safi,
8916 bool uj)
8917 {
8918 struct lcommunity *lcom;
8919 struct buffer *b;
8920 int i;
8921 char *str;
8922 int first = 0;
8923
8924 b = buffer_new(1024);
8925 for (i = 0; i < argc; i++) {
8926 if (first)
8927 buffer_putc(b, ' ');
8928 else {
8929 if (strmatch(argv[i]->text, "AA:BB:CC")) {
8930 first = 1;
8931 buffer_putstr(b, argv[i]->arg);
8932 }
8933 }
8934 }
8935 buffer_putc(b, '\0');
8936
8937 str = buffer_getstr(b);
8938 buffer_free(b);
8939
8940 lcom = lcommunity_str2com(str);
8941 XFREE(MTYPE_TMP, str);
8942 if (!lcom) {
8943 vty_out(vty, "%% Large-community malformed\n");
8944 return CMD_WARNING;
8945 }
8946
8947 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
8948 uj);
8949 }
8950
8951 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
8952 const char *lcom, afi_t afi, safi_t safi,
8953 bool uj)
8954 {
8955 struct community_list *list;
8956
8957 list = community_list_lookup(bgp_clist, lcom,
8958 LARGE_COMMUNITY_LIST_MASTER);
8959 if (list == NULL) {
8960 vty_out(vty, "%% %s is not a valid large-community-list name\n",
8961 lcom);
8962 return CMD_WARNING;
8963 }
8964
8965 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
8966 list, uj);
8967 }
8968
8969 DEFUN (show_ip_bgp_large_community_list,
8970 show_ip_bgp_large_community_list_cmd,
8971 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
8972 SHOW_STR
8973 IP_STR
8974 BGP_STR
8975 BGP_INSTANCE_HELP_STR
8976 BGP_AFI_HELP_STR
8977 BGP_SAFI_WITH_LABEL_HELP_STR
8978 "Display routes matching the large-community-list\n"
8979 "large-community-list number\n"
8980 "large-community-list name\n"
8981 JSON_STR)
8982 {
8983 char *vrf = NULL;
8984 afi_t afi = AFI_IP6;
8985 safi_t safi = SAFI_UNICAST;
8986 int idx = 0;
8987
8988 if (argv_find(argv, argc, "ip", &idx))
8989 afi = AFI_IP;
8990 if (argv_find(argv, argc, "view", &idx)
8991 || argv_find(argv, argc, "vrf", &idx))
8992 vrf = argv[++idx]->arg;
8993 if (argv_find(argv, argc, "ipv4", &idx)
8994 || argv_find(argv, argc, "ipv6", &idx)) {
8995 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8996 if (argv_find(argv, argc, "unicast", &idx)
8997 || argv_find(argv, argc, "multicast", &idx))
8998 safi = bgp_vty_safi_from_str(argv[idx]->text);
8999 }
9000
9001 bool uj = use_json(argc, argv);
9002
9003 struct bgp *bgp = bgp_lookup_by_name(vrf);
9004 if (bgp == NULL) {
9005 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9006 return CMD_WARNING;
9007 }
9008
9009 argv_find(argv, argc, "large-community-list", &idx);
9010 return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
9011 uj);
9012 }
9013 DEFUN (show_ip_bgp_large_community,
9014 show_ip_bgp_large_community_cmd,
9015 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]",
9016 SHOW_STR
9017 IP_STR
9018 BGP_STR
9019 BGP_INSTANCE_HELP_STR
9020 BGP_AFI_HELP_STR
9021 BGP_SAFI_WITH_LABEL_HELP_STR
9022 "Display routes matching the large-communities\n"
9023 "List of large-community numbers\n"
9024 JSON_STR)
9025 {
9026 char *vrf = NULL;
9027 afi_t afi = AFI_IP6;
9028 safi_t safi = SAFI_UNICAST;
9029 int idx = 0;
9030
9031 if (argv_find(argv, argc, "ip", &idx))
9032 afi = AFI_IP;
9033 if (argv_find(argv, argc, "view", &idx)
9034 || argv_find(argv, argc, "vrf", &idx))
9035 vrf = argv[++idx]->arg;
9036 if (argv_find(argv, argc, "ipv4", &idx)
9037 || argv_find(argv, argc, "ipv6", &idx)) {
9038 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
9039 if (argv_find(argv, argc, "unicast", &idx)
9040 || argv_find(argv, argc, "multicast", &idx))
9041 safi = bgp_vty_safi_from_str(argv[idx]->text);
9042 }
9043
9044 bool uj = use_json(argc, argv);
9045
9046 struct bgp *bgp = bgp_lookup_by_name(vrf);
9047 if (bgp == NULL) {
9048 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9049 return CMD_WARNING;
9050 }
9051
9052 if (argv_find(argv, argc, "AA:BB:CC", &idx))
9053 return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
9054 else
9055 return bgp_show(vty, bgp, afi, safi,
9056 bgp_show_type_lcommunity_all, NULL, uj);
9057 }
9058
9059 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9060 safi_t safi);
9061
9062
9063 /* BGP route print out function without JSON */
9064 DEFUN (show_ip_bgp,
9065 show_ip_bgp_cmd,
9066 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9067 <dampening <parameters>\
9068 |route-map WORD\
9069 |prefix-list WORD\
9070 |filter-list WORD\
9071 |statistics\
9072 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown\
9073 no-peer|blackhole|llgr-stale|no-llgr|accept-own|accept-own-nexthop\
9074 route-filter-v6|route-filter-v4|route-filter-translated-v6|\
9075 route-filter-translated-v4> [exact-match]\
9076 |community-list <(1-500)|WORD> [exact-match]\
9077 |A.B.C.D/M longer-prefixes\
9078 |X:X::X:X/M longer-prefixes\
9079 >",
9080 SHOW_STR
9081 IP_STR
9082 BGP_STR
9083 BGP_INSTANCE_HELP_STR
9084 BGP_AFI_HELP_STR
9085 BGP_SAFI_WITH_LABEL_HELP_STR
9086 "Display detailed information about dampening\n"
9087 "Display detail of configured dampening parameters\n"
9088 "Display routes matching the route-map\n"
9089 "A route-map to match on\n"
9090 "Display routes conforming to the prefix-list\n"
9091 "Prefix-list name\n"
9092 "Display routes conforming to the filter-list\n"
9093 "Regular expression access list name\n"
9094 "BGP RIB advertisement statistics\n"
9095 "Display routes matching the communities\n"
9096 COMMUNITY_AANN_STR
9097 "Do not send outside local AS (well-known community)\n"
9098 "Do not advertise to any peer (well-known community)\n"
9099 "Do not export to next AS (well-known community)\n"
9100 "Graceful shutdown (well-known community)\n"
9101 "Do not export to any peer (well-known community)\n"
9102 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
9103 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
9104 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
9105 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
9106 "Should accept VPN route with local nexthop (well-known community)\n"
9107 "RT VPNv6 route filtering (well-known community)\n"
9108 "RT VPNv4 route filtering (well-known community)\n"
9109 "RT translated VPNv6 route filtering (well-known community)\n"
9110 "RT translated VPNv4 route filtering (well-known community)\n"
9111 "Exact match of the communities\n"
9112 "Display routes matching the community-list\n"
9113 "community-list number\n"
9114 "community-list name\n"
9115 "Exact match of the communities\n"
9116 "IPv4 prefix\n"
9117 "Display route and more specific routes\n"
9118 "IPv6 prefix\n"
9119 "Display route and more specific routes\n")
9120 {
9121 afi_t afi = AFI_IP6;
9122 safi_t safi = SAFI_UNICAST;
9123 int exact_match = 0;
9124 struct bgp *bgp = NULL;
9125 int idx = 0;
9126
9127 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9128 &bgp, false);
9129 if (!idx)
9130 return CMD_WARNING;
9131
9132 if (argv_find(argv, argc, "dampening", &idx)) {
9133 if (argv_find(argv, argc, "parameters", &idx))
9134 return bgp_show_dampening_parameters(vty, afi, safi);
9135 }
9136
9137 if (argv_find(argv, argc, "prefix-list", &idx))
9138 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
9139 safi, bgp_show_type_prefix_list);
9140
9141 if (argv_find(argv, argc, "filter-list", &idx))
9142 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
9143 safi, bgp_show_type_filter_list);
9144
9145 if (argv_find(argv, argc, "statistics", &idx))
9146 return bgp_table_stats(vty, bgp, afi, safi);
9147
9148 if (argv_find(argv, argc, "route-map", &idx))
9149 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
9150 safi, bgp_show_type_route_map);
9151
9152 if (argv_find(argv, argc, "community-list", &idx)) {
9153 const char *clist_number_or_name = argv[++idx]->arg;
9154 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
9155 exact_match = 1;
9156 return bgp_show_community_list(vty, bgp, clist_number_or_name,
9157 exact_match, afi, safi);
9158 }
9159 /* prefix-longer */
9160 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9161 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9162 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
9163 safi,
9164 bgp_show_type_prefix_longer);
9165
9166 return CMD_WARNING;
9167 }
9168
9169 /* BGP route print out function with JSON */
9170 DEFUN (show_ip_bgp_json,
9171 show_ip_bgp_json_cmd,
9172 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9173 [<\
9174 cidr-only\
9175 |dampening <flap-statistics|dampened-paths>\
9176 |community [<AA:NN|local-AS|no-advertise|no-export|graceful-shutdown>] [exact-match]\
9177 >] [json]",
9178 SHOW_STR
9179 IP_STR
9180 BGP_STR
9181 BGP_INSTANCE_HELP_STR
9182 BGP_AFI_HELP_STR
9183 BGP_SAFI_WITH_LABEL_HELP_STR
9184 "Display only routes with non-natural netmasks\n"
9185 "Display detailed information about dampening\n"
9186 "Display flap statistics of routes\n"
9187 "Display paths suppressed due to dampening\n"
9188 "Display routes matching the communities\n"
9189 COMMUNITY_AANN_STR
9190 "Do not send outside local AS (well-known community)\n"
9191 "Do not advertise to any peer (well-known community)\n"
9192 "Do not export to next AS (well-known community)\n"
9193 "Graceful shutdown (well-known community)\n"
9194 "Exact match of the communities\n"
9195 JSON_STR)
9196 {
9197 afi_t afi = AFI_IP6;
9198 safi_t safi = SAFI_UNICAST;
9199 enum bgp_show_type sh_type = bgp_show_type_normal;
9200 struct bgp *bgp = NULL;
9201 int idx = 0;
9202 int idx_community_type = 0;
9203 int exact_match = 0;
9204 bool uj = use_json(argc, argv);
9205
9206 if (uj)
9207 argc--;
9208
9209 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9210 &bgp, uj);
9211 if (!idx)
9212 return CMD_WARNING;
9213
9214 if (argv_find(argv, argc, "cidr-only", &idx))
9215 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
9216 NULL, uj);
9217
9218 if (argv_find(argv, argc, "dampening", &idx)) {
9219 if (argv_find(argv, argc, "dampened-paths", &idx))
9220 return bgp_show(vty, bgp, afi, safi,
9221 bgp_show_type_dampend_paths, NULL, uj);
9222 else if (argv_find(argv, argc, "flap-statistics", &idx))
9223 return bgp_show(vty, bgp, afi, safi,
9224 bgp_show_type_flap_statistics, NULL,
9225 uj);
9226 }
9227
9228 if (argv_find(argv, argc, "community", &idx)) {
9229
9230 /* show a specific community */
9231 if (argv_find(argv, argc, "local-AS", &idx_community_type) ||
9232 argv_find(argv, argc, "no-advertise",
9233 &idx_community_type) ||
9234 argv_find(argv, argc, "no-export",
9235 &idx_community_type) ||
9236 argv_find(argv, argc, "graceful-shutdown",
9237 &idx_community_type) ||
9238 argv_find(argv, argc, "AA:NN", &idx_community_type)) {
9239 if (argv_find(argv, argc, "exact-match", &idx))
9240 exact_match = 1;
9241
9242 return (bgp_show_community(vty, bgp,
9243 argv[idx_community_type]->arg,
9244 exact_match, afi, safi, uj));
9245 } else {
9246
9247 /* show all communities */
9248 return (bgp_show(vty, bgp, afi, safi,
9249 bgp_show_type_community_all, NULL,
9250 uj));
9251 }
9252 }
9253
9254 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
9255 }
9256
9257 DEFUN (show_ip_bgp_route,
9258 show_ip_bgp_route_cmd,
9259 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
9260 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9261 SHOW_STR
9262 IP_STR
9263 BGP_STR
9264 BGP_INSTANCE_HELP_STR
9265 BGP_AFI_HELP_STR
9266 BGP_SAFI_WITH_LABEL_HELP_STR
9267 "Network in the BGP routing table to display\n"
9268 "IPv4 prefix\n"
9269 "Network in the BGP routing table to display\n"
9270 "IPv6 prefix\n"
9271 "Display only the bestpath\n"
9272 "Display only multipaths\n"
9273 JSON_STR)
9274 {
9275 int prefix_check = 0;
9276
9277 afi_t afi = AFI_IP6;
9278 safi_t safi = SAFI_UNICAST;
9279 char *prefix = NULL;
9280 struct bgp *bgp = NULL;
9281 enum bgp_path_type path_type;
9282 bool uj = use_json(argc, argv);
9283
9284 int idx = 0;
9285
9286 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9287 &bgp, uj);
9288 if (!idx)
9289 return CMD_WARNING;
9290
9291 if (!bgp) {
9292 vty_out(vty,
9293 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9294 return CMD_WARNING;
9295 }
9296
9297 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9298 if (argv_find(argv, argc, "A.B.C.D", &idx)
9299 || argv_find(argv, argc, "X:X::X:X", &idx))
9300 prefix_check = 0;
9301 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9302 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9303 prefix_check = 1;
9304
9305 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
9306 && afi != AFI_IP6) {
9307 vty_out(vty,
9308 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9309 return CMD_WARNING;
9310 }
9311 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
9312 && afi != AFI_IP) {
9313 vty_out(vty,
9314 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9315 return CMD_WARNING;
9316 }
9317
9318 prefix = argv[idx]->arg;
9319
9320 /* [<bestpath|multipath>] */
9321 if (argv_find(argv, argc, "bestpath", &idx))
9322 path_type = BGP_PATH_BESTPATH;
9323 else if (argv_find(argv, argc, "multipath", &idx))
9324 path_type = BGP_PATH_MULTIPATH;
9325 else
9326 path_type = BGP_PATH_ALL;
9327
9328 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
9329 path_type, uj);
9330 }
9331
9332 DEFUN (show_ip_bgp_regexp,
9333 show_ip_bgp_regexp_cmd,
9334 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
9335 SHOW_STR
9336 IP_STR
9337 BGP_STR
9338 BGP_INSTANCE_HELP_STR
9339 BGP_AFI_HELP_STR
9340 BGP_SAFI_WITH_LABEL_HELP_STR
9341 "Display routes matching the AS path regular expression\n"
9342 "A regular-expression to match the BGP AS paths\n")
9343 {
9344 afi_t afi = AFI_IP6;
9345 safi_t safi = SAFI_UNICAST;
9346 struct bgp *bgp = NULL;
9347
9348 int idx = 0;
9349 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9350 &bgp, false);
9351 if (!idx)
9352 return CMD_WARNING;
9353
9354 // get index of regex
9355 argv_find(argv, argc, "regexp", &idx);
9356 idx++;
9357
9358 char *regstr = argv_concat(argv, argc, idx);
9359 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
9360 bgp_show_type_regexp);
9361 XFREE(MTYPE_TMP, regstr);
9362 return rc;
9363 }
9364
9365 DEFUN (show_ip_bgp_instance_all,
9366 show_ip_bgp_instance_all_cmd,
9367 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
9368 SHOW_STR
9369 IP_STR
9370 BGP_STR
9371 BGP_INSTANCE_ALL_HELP_STR
9372 BGP_AFI_HELP_STR
9373 BGP_SAFI_WITH_LABEL_HELP_STR
9374 JSON_STR)
9375 {
9376 afi_t afi = AFI_IP;
9377 safi_t safi = SAFI_UNICAST;
9378 struct bgp *bgp = NULL;
9379 int idx = 0;
9380 bool uj = use_json(argc, argv);
9381
9382 if (uj)
9383 argc--;
9384
9385 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9386 &bgp, uj);
9387 if (!idx)
9388 return CMD_WARNING;
9389
9390 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
9391 return CMD_SUCCESS;
9392 }
9393
9394 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9395 afi_t afi, safi_t safi, enum bgp_show_type type)
9396 {
9397 regex_t *regex;
9398 int rc;
9399
9400 regex = bgp_regcomp(regstr);
9401 if (!regex) {
9402 vty_out(vty, "Can't compile regexp %s\n", regstr);
9403 return CMD_WARNING;
9404 }
9405
9406 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
9407 bgp_regex_free(regex);
9408 return rc;
9409 }
9410
9411 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9412 const char *prefix_list_str, afi_t afi,
9413 safi_t safi, enum bgp_show_type type)
9414 {
9415 struct prefix_list *plist;
9416
9417 plist = prefix_list_lookup(afi, prefix_list_str);
9418 if (plist == NULL) {
9419 vty_out(vty, "%% %s is not a valid prefix-list name\n",
9420 prefix_list_str);
9421 return CMD_WARNING;
9422 }
9423
9424 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
9425 }
9426
9427 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9428 const char *filter, afi_t afi, safi_t safi,
9429 enum bgp_show_type type)
9430 {
9431 struct as_list *as_list;
9432
9433 as_list = as_list_lookup(filter);
9434 if (as_list == NULL) {
9435 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
9436 filter);
9437 return CMD_WARNING;
9438 }
9439
9440 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
9441 }
9442
9443 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9444 const char *rmap_str, afi_t afi, safi_t safi,
9445 enum bgp_show_type type)
9446 {
9447 struct route_map *rmap;
9448
9449 rmap = route_map_lookup_by_name(rmap_str);
9450 if (!rmap) {
9451 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
9452 return CMD_WARNING;
9453 }
9454
9455 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
9456 }
9457
9458 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9459 const char *comstr, int exact, afi_t afi,
9460 safi_t safi, bool use_json)
9461 {
9462 struct community *com;
9463 int ret = 0;
9464
9465 com = community_str2com(comstr);
9466 if (!com) {
9467 vty_out(vty, "%% Community malformed: %s\n", comstr);
9468 return CMD_WARNING;
9469 }
9470
9471 ret = bgp_show(vty, bgp, afi, safi,
9472 (exact ? bgp_show_type_community_exact
9473 : bgp_show_type_community),
9474 com, use_json);
9475 community_free(com);
9476
9477 return ret;
9478 }
9479
9480 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9481 const char *com, int exact, afi_t afi,
9482 safi_t safi)
9483 {
9484 struct community_list *list;
9485
9486 list = community_list_lookup(bgp_clist, com, COMMUNITY_LIST_MASTER);
9487 if (list == NULL) {
9488 vty_out(vty, "%% %s is not a valid community-list name\n", com);
9489 return CMD_WARNING;
9490 }
9491
9492 return bgp_show(vty, bgp, afi, safi,
9493 (exact ? bgp_show_type_community_list_exact
9494 : bgp_show_type_community_list),
9495 list, 0);
9496 }
9497
9498 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9499 const char *prefix, afi_t afi, safi_t safi,
9500 enum bgp_show_type type)
9501 {
9502 int ret;
9503 struct prefix *p;
9504
9505 p = prefix_new();
9506
9507 ret = str2prefix(prefix, p);
9508 if (!ret) {
9509 vty_out(vty, "%% Malformed Prefix\n");
9510 return CMD_WARNING;
9511 }
9512
9513 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
9514 prefix_free(p);
9515 return ret;
9516 }
9517
9518 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
9519 const char *ip_str, bool use_json)
9520 {
9521 int ret;
9522 struct peer *peer;
9523 union sockunion su;
9524
9525 /* Get peer sockunion. */
9526 ret = str2sockunion(ip_str, &su);
9527 if (ret < 0) {
9528 peer = peer_lookup_by_conf_if(bgp, ip_str);
9529 if (!peer) {
9530 peer = peer_lookup_by_hostname(bgp, ip_str);
9531
9532 if (!peer) {
9533 if (use_json) {
9534 json_object *json_no = NULL;
9535 json_no = json_object_new_object();
9536 json_object_string_add(
9537 json_no,
9538 "malformedAddressOrName",
9539 ip_str);
9540 vty_out(vty, "%s\n",
9541 json_object_to_json_string_ext(
9542 json_no,
9543 JSON_C_TO_STRING_PRETTY));
9544 json_object_free(json_no);
9545 } else
9546 vty_out(vty,
9547 "%% Malformed address or name: %s\n",
9548 ip_str);
9549 return NULL;
9550 }
9551 }
9552 return peer;
9553 }
9554
9555 /* Peer structure lookup. */
9556 peer = peer_lookup(bgp, &su);
9557 if (!peer) {
9558 if (use_json) {
9559 json_object *json_no = NULL;
9560 json_no = json_object_new_object();
9561 json_object_string_add(json_no, "warning",
9562 "No such neighbor in this view/vrf");
9563 vty_out(vty, "%s\n",
9564 json_object_to_json_string_ext(
9565 json_no, JSON_C_TO_STRING_PRETTY));
9566 json_object_free(json_no);
9567 } else
9568 vty_out(vty, "No such neighbor in this view/vrf\n");
9569 return NULL;
9570 }
9571
9572 return peer;
9573 }
9574
9575 enum bgp_stats {
9576 BGP_STATS_MAXBITLEN = 0,
9577 BGP_STATS_RIB,
9578 BGP_STATS_PREFIXES,
9579 BGP_STATS_TOTPLEN,
9580 BGP_STATS_UNAGGREGATEABLE,
9581 BGP_STATS_MAX_AGGREGATEABLE,
9582 BGP_STATS_AGGREGATES,
9583 BGP_STATS_SPACE,
9584 BGP_STATS_ASPATH_COUNT,
9585 BGP_STATS_ASPATH_MAXHOPS,
9586 BGP_STATS_ASPATH_TOTHOPS,
9587 BGP_STATS_ASPATH_MAXSIZE,
9588 BGP_STATS_ASPATH_TOTSIZE,
9589 BGP_STATS_ASN_HIGHEST,
9590 BGP_STATS_MAX,
9591 };
9592
9593 static const char *table_stats_strs[] = {
9594 [BGP_STATS_PREFIXES] = "Total Prefixes",
9595 [BGP_STATS_TOTPLEN] = "Average prefix length",
9596 [BGP_STATS_RIB] = "Total Advertisements",
9597 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
9598 [BGP_STATS_MAX_AGGREGATEABLE] =
9599 "Maximum aggregateable prefixes",
9600 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
9601 [BGP_STATS_SPACE] = "Address space advertised",
9602 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
9603 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
9604 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
9605 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
9606 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
9607 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
9608 [BGP_STATS_MAX] = NULL,
9609 };
9610
9611 struct bgp_table_stats {
9612 struct bgp_table *table;
9613 unsigned long long counts[BGP_STATS_MAX];
9614 double total_space;
9615 };
9616
9617 #if 0
9618 #define TALLY_SIGFIG 100000
9619 static unsigned long
9620 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
9621 {
9622 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
9623 unsigned long res = (newtot * TALLY_SIGFIG) / count;
9624 unsigned long ret = newtot / count;
9625
9626 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
9627 return ret + 1;
9628 else
9629 return ret;
9630 }
9631 #endif
9632
9633 static int bgp_table_stats_walker(struct thread *t)
9634 {
9635 struct bgp_node *rn;
9636 struct bgp_node *top;
9637 struct bgp_table_stats *ts = THREAD_ARG(t);
9638 unsigned int space = 0;
9639
9640 if (!(top = bgp_table_top(ts->table)))
9641 return 0;
9642
9643 switch (top->p.family) {
9644 case AF_INET:
9645 space = IPV4_MAX_BITLEN;
9646 break;
9647 case AF_INET6:
9648 space = IPV6_MAX_BITLEN;
9649 break;
9650 }
9651
9652 ts->counts[BGP_STATS_MAXBITLEN] = space;
9653
9654 for (rn = top; rn; rn = bgp_route_next(rn)) {
9655 struct bgp_info *ri;
9656 struct bgp_node *prn = bgp_node_parent_nolock(rn);
9657 unsigned int rinum = 0;
9658
9659 if (rn == top)
9660 continue;
9661
9662 if (!rn->info)
9663 continue;
9664
9665 ts->counts[BGP_STATS_PREFIXES]++;
9666 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
9667
9668 #if 0
9669 ts->counts[BGP_STATS_AVGPLEN]
9670 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
9671 ts->counts[BGP_STATS_AVGPLEN],
9672 rn->p.prefixlen);
9673 #endif
9674
9675 /* check if the prefix is included by any other announcements */
9676 while (prn && !prn->info)
9677 prn = bgp_node_parent_nolock(prn);
9678
9679 if (prn == NULL || prn == top) {
9680 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
9681 /* announced address space */
9682 if (space)
9683 ts->total_space +=
9684 pow(2.0, space - rn->p.prefixlen);
9685 } else if (prn->info)
9686 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
9687
9688 for (ri = rn->info; ri; ri = ri->next) {
9689 rinum++;
9690 ts->counts[BGP_STATS_RIB]++;
9691
9692 if (ri->attr
9693 && (CHECK_FLAG(ri->attr->flag,
9694 ATTR_FLAG_BIT(
9695 BGP_ATTR_ATOMIC_AGGREGATE))))
9696 ts->counts[BGP_STATS_AGGREGATES]++;
9697
9698 /* as-path stats */
9699 if (ri->attr && ri->attr->aspath) {
9700 unsigned int hops =
9701 aspath_count_hops(ri->attr->aspath);
9702 unsigned int size =
9703 aspath_size(ri->attr->aspath);
9704 as_t highest = aspath_highest(ri->attr->aspath);
9705
9706 ts->counts[BGP_STATS_ASPATH_COUNT]++;
9707
9708 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
9709 ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
9710 hops;
9711
9712 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
9713 ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
9714 size;
9715
9716 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
9717 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
9718 #if 0
9719 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
9720 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9721 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
9722 hops);
9723 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
9724 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9725 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
9726 size);
9727 #endif
9728 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
9729 ts->counts[BGP_STATS_ASN_HIGHEST] =
9730 highest;
9731 }
9732 }
9733 }
9734 return 0;
9735 }
9736
9737 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9738 safi_t safi)
9739 {
9740 struct bgp_table_stats ts;
9741 unsigned int i;
9742
9743 if (!bgp->rib[afi][safi]) {
9744 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9745 afi, safi);
9746 return CMD_WARNING;
9747 }
9748
9749 vty_out(vty, "BGP %s RIB statistics\n", afi_safi_print(afi, safi));
9750
9751 /* labeled-unicast routes live in the unicast table */
9752 if (safi == SAFI_LABELED_UNICAST)
9753 safi = SAFI_UNICAST;
9754
9755 memset(&ts, 0, sizeof(ts));
9756 ts.table = bgp->rib[afi][safi];
9757 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
9758
9759 for (i = 0; i < BGP_STATS_MAX; i++) {
9760 if (!table_stats_strs[i])
9761 continue;
9762
9763 switch (i) {
9764 #if 0
9765 case BGP_STATS_ASPATH_AVGHOPS:
9766 case BGP_STATS_ASPATH_AVGSIZE:
9767 case BGP_STATS_AVGPLEN:
9768 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9769 vty_out (vty, "%12.2f",
9770 (float)ts.counts[i] / (float)TALLY_SIGFIG);
9771 break;
9772 #endif
9773 case BGP_STATS_ASPATH_TOTHOPS:
9774 case BGP_STATS_ASPATH_TOTSIZE:
9775 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9776 vty_out(vty, "%12.2f",
9777 ts.counts[i]
9778 ? (float)ts.counts[i]
9779 / (float)ts.counts
9780 [BGP_STATS_ASPATH_COUNT]
9781 : 0);
9782 break;
9783 case BGP_STATS_TOTPLEN:
9784 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9785 vty_out(vty, "%12.2f",
9786 ts.counts[i]
9787 ? (float)ts.counts[i]
9788 / (float)ts.counts
9789 [BGP_STATS_PREFIXES]
9790 : 0);
9791 break;
9792 case BGP_STATS_SPACE:
9793 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9794 vty_out(vty, "%12g\n", ts.total_space);
9795
9796 if (afi == AFI_IP6) {
9797 vty_out(vty, "%30s: ", "/32 equivalent ");
9798 vty_out(vty, "%12g\n",
9799 ts.total_space * pow(2.0, -128 + 32));
9800 vty_out(vty, "%30s: ", "/48 equivalent ");
9801 vty_out(vty, "%12g\n",
9802 ts.total_space * pow(2.0, -128 + 48));
9803 } else {
9804 vty_out(vty, "%30s: ", "% announced ");
9805 vty_out(vty, "%12.2f\n",
9806 ts.total_space * 100. * pow(2.0, -32));
9807 vty_out(vty, "%30s: ", "/8 equivalent ");
9808 vty_out(vty, "%12.2f\n",
9809 ts.total_space * pow(2.0, -32 + 8));
9810 vty_out(vty, "%30s: ", "/24 equivalent ");
9811 vty_out(vty, "%12.2f\n",
9812 ts.total_space * pow(2.0, -32 + 24));
9813 }
9814 break;
9815 default:
9816 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9817 vty_out(vty, "%12llu", ts.counts[i]);
9818 }
9819
9820 vty_out(vty, "\n");
9821 }
9822 return CMD_SUCCESS;
9823 }
9824
9825 enum bgp_pcounts {
9826 PCOUNT_ADJ_IN = 0,
9827 PCOUNT_DAMPED,
9828 PCOUNT_REMOVED,
9829 PCOUNT_HISTORY,
9830 PCOUNT_STALE,
9831 PCOUNT_VALID,
9832 PCOUNT_ALL,
9833 PCOUNT_COUNTED,
9834 PCOUNT_PFCNT, /* the figure we display to users */
9835 PCOUNT_MAX,
9836 };
9837
9838 static const char *pcount_strs[] = {
9839 [PCOUNT_ADJ_IN] = "Adj-in",
9840 [PCOUNT_DAMPED] = "Damped",
9841 [PCOUNT_REMOVED] = "Removed",
9842 [PCOUNT_HISTORY] = "History",
9843 [PCOUNT_STALE] = "Stale",
9844 [PCOUNT_VALID] = "Valid",
9845 [PCOUNT_ALL] = "All RIB",
9846 [PCOUNT_COUNTED] = "PfxCt counted",
9847 [PCOUNT_PFCNT] = "Useable",
9848 [PCOUNT_MAX] = NULL,
9849 };
9850
9851 struct peer_pcounts {
9852 unsigned int count[PCOUNT_MAX];
9853 const struct peer *peer;
9854 const struct bgp_table *table;
9855 };
9856
9857 static int bgp_peer_count_walker(struct thread *t)
9858 {
9859 struct bgp_node *rn;
9860 struct peer_pcounts *pc = THREAD_ARG(t);
9861 const struct peer *peer = pc->peer;
9862
9863 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
9864 struct bgp_adj_in *ain;
9865 struct bgp_info *ri;
9866
9867 for (ain = rn->adj_in; ain; ain = ain->next)
9868 if (ain->peer == peer)
9869 pc->count[PCOUNT_ADJ_IN]++;
9870
9871 for (ri = rn->info; ri; ri = ri->next) {
9872 if (ri->peer != peer)
9873 continue;
9874
9875 pc->count[PCOUNT_ALL]++;
9876
9877 if (CHECK_FLAG(ri->flags, BGP_INFO_DAMPED))
9878 pc->count[PCOUNT_DAMPED]++;
9879 if (CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
9880 pc->count[PCOUNT_HISTORY]++;
9881 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
9882 pc->count[PCOUNT_REMOVED]++;
9883 if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
9884 pc->count[PCOUNT_STALE]++;
9885 if (CHECK_FLAG(ri->flags, BGP_INFO_VALID))
9886 pc->count[PCOUNT_VALID]++;
9887 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9888 pc->count[PCOUNT_PFCNT]++;
9889
9890 if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
9891 pc->count[PCOUNT_COUNTED]++;
9892 if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9893 flog_err(
9894 EC_LIB_DEVELOPMENT,
9895 "Attempting to count but flags say it is unusable");
9896 } else {
9897 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9898 flog_err(
9899 EC_LIB_DEVELOPMENT,
9900 "Not counted but flags say we should");
9901 }
9902 }
9903 }
9904 return 0;
9905 }
9906
9907 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
9908 safi_t safi, bool use_json)
9909 {
9910 struct peer_pcounts pcounts = {.peer = peer};
9911 unsigned int i;
9912 json_object *json = NULL;
9913 json_object *json_loop = NULL;
9914
9915 if (use_json) {
9916 json = json_object_new_object();
9917 json_loop = json_object_new_object();
9918 }
9919
9920 if (!peer || !peer->bgp || !peer->afc[afi][safi]
9921 || !peer->bgp->rib[afi][safi]) {
9922 if (use_json) {
9923 json_object_string_add(
9924 json, "warning",
9925 "No such neighbor or address family");
9926 vty_out(vty, "%s\n", json_object_to_json_string(json));
9927 json_object_free(json);
9928 } else
9929 vty_out(vty, "%% No such neighbor or address family\n");
9930
9931 return CMD_WARNING;
9932 }
9933
9934 memset(&pcounts, 0, sizeof(pcounts));
9935 pcounts.peer = peer;
9936 pcounts.table = peer->bgp->rib[afi][safi];
9937
9938 /* in-place call via thread subsystem so as to record execution time
9939 * stats for the thread-walk (i.e. ensure this can't be blamed on
9940 * on just vty_read()).
9941 */
9942 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
9943
9944 if (use_json) {
9945 json_object_string_add(json, "prefixCountsFor", peer->host);
9946 json_object_string_add(json, "multiProtocol",
9947 afi_safi_print(afi, safi));
9948 json_object_int_add(json, "pfxCounter",
9949 peer->pcount[afi][safi]);
9950
9951 for (i = 0; i < PCOUNT_MAX; i++)
9952 json_object_int_add(json_loop, pcount_strs[i],
9953 pcounts.count[i]);
9954
9955 json_object_object_add(json, "ribTableWalkCounters", json_loop);
9956
9957 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9958 json_object_string_add(json, "pfxctDriftFor",
9959 peer->host);
9960 json_object_string_add(
9961 json, "recommended",
9962 "Please report this bug, with the above command output");
9963 }
9964 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9965 json, JSON_C_TO_STRING_PRETTY));
9966 json_object_free(json);
9967 } else {
9968
9969 if (peer->hostname
9970 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
9971 vty_out(vty, "Prefix counts for %s/%s, %s\n",
9972 peer->hostname, peer->host,
9973 afi_safi_print(afi, safi));
9974 } else {
9975 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
9976 afi_safi_print(afi, safi));
9977 }
9978
9979 vty_out(vty, "PfxCt: %ld\n", peer->pcount[afi][safi]);
9980 vty_out(vty, "\nCounts from RIB table walk:\n\n");
9981
9982 for (i = 0; i < PCOUNT_MAX; i++)
9983 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
9984 pcounts.count[i]);
9985
9986 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9987 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
9988 vty_out(vty,
9989 "Please report this bug, with the above command output\n");
9990 }
9991 }
9992
9993 return CMD_SUCCESS;
9994 }
9995
9996 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
9997 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
9998 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9999 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10000 SHOW_STR
10001 IP_STR
10002 BGP_STR
10003 BGP_INSTANCE_HELP_STR
10004 BGP_AFI_HELP_STR
10005 BGP_SAFI_HELP_STR
10006 "Detailed information on TCP and BGP neighbor connections\n"
10007 "Neighbor to display information about\n"
10008 "Neighbor to display information about\n"
10009 "Neighbor on BGP configured interface\n"
10010 "Display detailed prefix count information\n"
10011 JSON_STR)
10012 {
10013 afi_t afi = AFI_IP6;
10014 safi_t safi = SAFI_UNICAST;
10015 struct peer *peer;
10016 int idx = 0;
10017 struct bgp *bgp = NULL;
10018 bool uj = use_json(argc, argv);
10019
10020 if (uj)
10021 argc--;
10022
10023 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10024 &bgp, uj);
10025 if (!idx)
10026 return CMD_WARNING;
10027
10028 argv_find(argv, argc, "neighbors", &idx);
10029 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
10030 if (!peer)
10031 return CMD_WARNING;
10032
10033 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
10034 }
10035
10036 #ifdef KEEP_OLD_VPN_COMMANDS
10037 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
10038 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
10039 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10040 SHOW_STR
10041 IP_STR
10042 BGP_STR
10043 BGP_VPNVX_HELP_STR
10044 "Display information about all VPNv4 NLRIs\n"
10045 "Detailed information on TCP and BGP neighbor connections\n"
10046 "Neighbor to display information about\n"
10047 "Neighbor to display information about\n"
10048 "Neighbor on BGP configured interface\n"
10049 "Display detailed prefix count information\n"
10050 JSON_STR)
10051 {
10052 int idx_peer = 6;
10053 struct peer *peer;
10054 bool uj = use_json(argc, argv);
10055
10056 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
10057 if (!peer)
10058 return CMD_WARNING;
10059
10060 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
10061 }
10062
10063 DEFUN (show_ip_bgp_vpn_all_route_prefix,
10064 show_ip_bgp_vpn_all_route_prefix_cmd,
10065 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10066 SHOW_STR
10067 IP_STR
10068 BGP_STR
10069 BGP_VPNVX_HELP_STR
10070 "Display information about all VPNv4 NLRIs\n"
10071 "Network in the BGP routing table to display\n"
10072 "Network in the BGP routing table to display\n"
10073 JSON_STR)
10074 {
10075 int idx = 0;
10076 char *network = NULL;
10077 struct bgp *bgp = bgp_get_default();
10078 if (!bgp) {
10079 vty_out(vty, "Can't find default instance\n");
10080 return CMD_WARNING;
10081 }
10082
10083 if (argv_find(argv, argc, "A.B.C.D", &idx))
10084 network = argv[idx]->arg;
10085 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10086 network = argv[idx]->arg;
10087 else {
10088 vty_out(vty, "Unable to figure out Network\n");
10089 return CMD_WARNING;
10090 }
10091
10092 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
10093 BGP_PATH_ALL, use_json(argc, argv));
10094 }
10095 #endif /* KEEP_OLD_VPN_COMMANDS */
10096
10097 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
10098 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
10099 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10100 SHOW_STR
10101 IP_STR
10102 BGP_STR
10103 L2VPN_HELP_STR
10104 EVPN_HELP_STR
10105 "Display information about all EVPN NLRIs\n"
10106 "Network in the BGP routing table to display\n"
10107 "Network in the BGP routing table to display\n"
10108 JSON_STR)
10109 {
10110 int idx = 0;
10111 char *network = NULL;
10112
10113 if (argv_find(argv, argc, "A.B.C.D", &idx))
10114 network = argv[idx]->arg;
10115 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10116 network = argv[idx]->arg;
10117 else {
10118 vty_out(vty, "Unable to figure out Network\n");
10119 return CMD_WARNING;
10120 }
10121 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
10122 BGP_PATH_ALL, use_json(argc, argv));
10123 }
10124
10125 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
10126 safi_t safi, enum bgp_show_adj_route_type type,
10127 const char *rmap_name, bool use_json,
10128 json_object *json)
10129 {
10130 struct bgp_table *table;
10131 struct bgp_adj_in *ain;
10132 struct bgp_adj_out *adj;
10133 unsigned long output_count;
10134 unsigned long filtered_count;
10135 struct bgp_node *rn;
10136 int header1 = 1;
10137 struct bgp *bgp;
10138 int header2 = 1;
10139 struct attr attr;
10140 int ret;
10141 struct update_subgroup *subgrp;
10142 json_object *json_scode = NULL;
10143 json_object *json_ocode = NULL;
10144 json_object *json_ar = NULL;
10145 struct peer_af *paf;
10146 bool route_filtered;
10147
10148 if (use_json) {
10149 json_scode = json_object_new_object();
10150 json_ocode = json_object_new_object();
10151 json_ar = json_object_new_object();
10152
10153 json_object_string_add(json_scode, "suppressed", "s");
10154 json_object_string_add(json_scode, "damped", "d");
10155 json_object_string_add(json_scode, "history", "h");
10156 json_object_string_add(json_scode, "valid", "*");
10157 json_object_string_add(json_scode, "best", ">");
10158 json_object_string_add(json_scode, "multipath", "=");
10159 json_object_string_add(json_scode, "internal", "i");
10160 json_object_string_add(json_scode, "ribFailure", "r");
10161 json_object_string_add(json_scode, "stale", "S");
10162 json_object_string_add(json_scode, "removed", "R");
10163
10164 json_object_string_add(json_ocode, "igp", "i");
10165 json_object_string_add(json_ocode, "egp", "e");
10166 json_object_string_add(json_ocode, "incomplete", "?");
10167 }
10168
10169 bgp = peer->bgp;
10170
10171 if (!bgp) {
10172 if (use_json) {
10173 json_object_string_add(json, "alert", "no BGP");
10174 vty_out(vty, "%s\n", json_object_to_json_string(json));
10175 json_object_free(json);
10176 } else
10177 vty_out(vty, "%% No bgp\n");
10178 return;
10179 }
10180
10181 table = bgp->rib[afi][safi];
10182
10183 output_count = filtered_count = 0;
10184 subgrp = peer_subgroup(peer, afi, safi);
10185
10186 if (type == bgp_show_adj_route_advertised && subgrp
10187 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
10188 if (use_json) {
10189 json_object_int_add(json, "bgpTableVersion",
10190 table->version);
10191 json_object_string_add(json, "bgpLocalRouterId",
10192 inet_ntoa(bgp->router_id));
10193 json_object_object_add(json, "bgpStatusCodes",
10194 json_scode);
10195 json_object_object_add(json, "bgpOriginCodes",
10196 json_ocode);
10197 json_object_string_add(
10198 json, "bgpOriginatingDefaultNetwork",
10199 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10200 } else {
10201 vty_out(vty, "BGP table version is %" PRIu64
10202 ", local router ID is %s, vrf id ",
10203 table->version, inet_ntoa(bgp->router_id));
10204 if (bgp->vrf_id == VRF_UNKNOWN)
10205 vty_out(vty, "%s", VRFID_NONE_STR);
10206 else
10207 vty_out(vty, "%u", bgp->vrf_id);
10208 vty_out(vty, "\n");
10209 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10210 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10211 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10212
10213 vty_out(vty, "Originating default network %s\n\n",
10214 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10215 }
10216 header1 = 0;
10217 }
10218
10219 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
10220 if (type == bgp_show_adj_route_received
10221 || type == bgp_show_adj_route_filtered) {
10222 for (ain = rn->adj_in; ain; ain = ain->next) {
10223 if (ain->peer != peer || !ain->attr)
10224 continue;
10225
10226 if (header1) {
10227 if (use_json) {
10228 json_object_int_add(
10229 json, "bgpTableVersion",
10230 0);
10231 json_object_string_add(
10232 json,
10233 "bgpLocalRouterId",
10234 inet_ntoa(
10235 bgp->router_id));
10236 json_object_object_add(
10237 json, "bgpStatusCodes",
10238 json_scode);
10239 json_object_object_add(
10240 json, "bgpOriginCodes",
10241 json_ocode);
10242 } else {
10243 vty_out(vty,
10244 "BGP table version is 0, local router ID is %s, vrf id ",
10245 inet_ntoa(
10246 bgp->router_id));
10247 if (bgp->vrf_id == VRF_UNKNOWN)
10248 vty_out(vty, "%s",
10249 VRFID_NONE_STR);
10250 else
10251 vty_out(vty, "%u",
10252 bgp->vrf_id);
10253 vty_out(vty, "\n");
10254 vty_out(vty,
10255 BGP_SHOW_SCODE_HEADER);
10256 vty_out(vty,
10257 BGP_SHOW_NCODE_HEADER);
10258 vty_out(vty,
10259 BGP_SHOW_OCODE_HEADER);
10260 }
10261 header1 = 0;
10262 }
10263 if (header2) {
10264 if (!use_json)
10265 vty_out(vty, BGP_SHOW_HEADER);
10266 header2 = 0;
10267 }
10268
10269 bgp_attr_dup(&attr, ain->attr);
10270 route_filtered = false;
10271
10272 /* Filter prefix using distribute list,
10273 * filter list or prefix list
10274 */
10275 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
10276 safi)) == FILTER_DENY)
10277 route_filtered = true;
10278
10279 /* Filter prefix using route-map */
10280 ret = bgp_input_modifier(peer, &rn->p, &attr,
10281 afi, safi, rmap_name);
10282
10283 if (type == bgp_show_adj_route_filtered &&
10284 !route_filtered && ret != RMAP_DENY) {
10285 bgp_attr_undup(&attr, ain->attr);
10286 continue;
10287 }
10288
10289 if (type == bgp_show_adj_route_received &&
10290 (route_filtered || ret == RMAP_DENY))
10291 filtered_count++;
10292
10293 route_vty_out_tmp(vty, &rn->p, &attr, safi,
10294 use_json, json_ar);
10295 bgp_attr_undup(&attr, ain->attr);
10296 output_count++;
10297 }
10298 } else if (type == bgp_show_adj_route_advertised) {
10299 for (adj = rn->adj_out; adj; adj = adj->next)
10300 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
10301 if (paf->peer != peer || !adj->attr)
10302 continue;
10303
10304 if (header1) {
10305 if (use_json) {
10306 json_object_int_add(
10307 json,
10308 "bgpTableVersion",
10309 table->version);
10310 json_object_string_add(
10311 json,
10312 "bgpLocalRouterId",
10313 inet_ntoa(
10314 bgp->router_id));
10315 json_object_object_add(
10316 json,
10317 "bgpStatusCodes",
10318 json_scode);
10319 json_object_object_add(
10320 json,
10321 "bgpOriginCodes",
10322 json_ocode);
10323 } else {
10324 vty_out(vty,
10325 "BGP table version is %" PRIu64
10326 ", local router ID is %s, vrf id ",
10327 table->version,
10328 inet_ntoa(
10329 bgp->router_id));
10330 if (bgp->vrf_id ==
10331 VRF_UNKNOWN)
10332 vty_out(vty,
10333 "%s",
10334 VRFID_NONE_STR);
10335 else
10336 vty_out(vty,
10337 "%u",
10338 bgp->vrf_id);
10339 vty_out(vty, "\n");
10340 vty_out(vty,
10341 BGP_SHOW_SCODE_HEADER);
10342 vty_out(vty,
10343 BGP_SHOW_NCODE_HEADER);
10344 vty_out(vty,
10345 BGP_SHOW_OCODE_HEADER);
10346 }
10347 header1 = 0;
10348 }
10349 if (header2) {
10350 if (!use_json)
10351 vty_out(vty,
10352 BGP_SHOW_HEADER);
10353 header2 = 0;
10354 }
10355
10356 bgp_attr_dup(&attr, adj->attr);
10357 ret = bgp_output_modifier(
10358 peer, &rn->p, &attr, afi, safi,
10359 rmap_name);
10360
10361 if (ret != RMAP_DENY) {
10362 route_vty_out_tmp(vty, &rn->p,
10363 &attr, safi,
10364 use_json,
10365 json_ar);
10366 output_count++;
10367 } else {
10368 filtered_count++;
10369 }
10370
10371 bgp_attr_undup(&attr, adj->attr);
10372 }
10373 }
10374 }
10375
10376 if (use_json) {
10377 json_object_object_add(json, "advertisedRoutes", json_ar);
10378 json_object_int_add(json, "totalPrefixCounter", output_count);
10379 json_object_int_add(json, "filteredPrefixCounter",
10380 filtered_count);
10381
10382 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10383 json, JSON_C_TO_STRING_PRETTY));
10384 json_object_free(json);
10385 } else if (output_count > 0) {
10386 if (filtered_count > 0)
10387 vty_out(vty,
10388 "\nTotal number of prefixes %ld (%ld filtered)\n",
10389 output_count, filtered_count);
10390 else
10391 vty_out(vty, "\nTotal number of prefixes %ld\n",
10392 output_count);
10393 }
10394 }
10395
10396 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
10397 safi_t safi, enum bgp_show_adj_route_type type,
10398 const char *rmap_name, bool use_json)
10399 {
10400 json_object *json = NULL;
10401
10402 if (use_json)
10403 json = json_object_new_object();
10404
10405 /* labeled-unicast routes live in the unicast table */
10406 if (safi == SAFI_LABELED_UNICAST)
10407 safi = SAFI_UNICAST;
10408
10409 if (!peer || !peer->afc[afi][safi]) {
10410 if (use_json) {
10411 json_object_string_add(
10412 json, "warning",
10413 "No such neighbor or address family");
10414 vty_out(vty, "%s\n", json_object_to_json_string(json));
10415 json_object_free(json);
10416 } else
10417 vty_out(vty, "%% No such neighbor or address family\n");
10418
10419 return CMD_WARNING;
10420 }
10421
10422 if ((type == bgp_show_adj_route_received
10423 || type == bgp_show_adj_route_filtered)
10424 && !CHECK_FLAG(peer->af_flags[afi][safi],
10425 PEER_FLAG_SOFT_RECONFIG)) {
10426 if (use_json) {
10427 json_object_string_add(
10428 json, "warning",
10429 "Inbound soft reconfiguration not enabled");
10430 vty_out(vty, "%s\n", json_object_to_json_string(json));
10431 json_object_free(json);
10432 } else
10433 vty_out(vty,
10434 "%% Inbound soft reconfiguration not enabled\n");
10435
10436 return CMD_WARNING;
10437 }
10438
10439 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
10440
10441 return CMD_SUCCESS;
10442 }
10443
10444 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
10445 show_ip_bgp_instance_neighbor_advertised_route_cmd,
10446 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10447 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
10448 SHOW_STR
10449 IP_STR
10450 BGP_STR
10451 BGP_INSTANCE_HELP_STR
10452 BGP_AFI_HELP_STR
10453 BGP_SAFI_WITH_LABEL_HELP_STR
10454 "Detailed information on TCP and BGP neighbor connections\n"
10455 "Neighbor to display information about\n"
10456 "Neighbor to display information about\n"
10457 "Neighbor on BGP configured interface\n"
10458 "Display the routes advertised to a BGP neighbor\n"
10459 "Display the received routes from neighbor\n"
10460 "Display the filtered routes received from neighbor\n"
10461 "Route-map to modify the attributes\n"
10462 "Name of the route map\n"
10463 JSON_STR)
10464 {
10465 afi_t afi = AFI_IP6;
10466 safi_t safi = SAFI_UNICAST;
10467 char *rmap_name = NULL;
10468 char *peerstr = NULL;
10469 struct bgp *bgp = NULL;
10470 struct peer *peer;
10471 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
10472 int idx = 0;
10473 bool uj = use_json(argc, argv);
10474
10475 if (uj)
10476 argc--;
10477
10478 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10479 &bgp, uj);
10480 if (!idx)
10481 return CMD_WARNING;
10482
10483 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10484 argv_find(argv, argc, "neighbors", &idx);
10485 peerstr = argv[++idx]->arg;
10486
10487 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10488 if (!peer)
10489 return CMD_WARNING;
10490
10491 if (argv_find(argv, argc, "advertised-routes", &idx))
10492 type = bgp_show_adj_route_advertised;
10493 else if (argv_find(argv, argc, "received-routes", &idx))
10494 type = bgp_show_adj_route_received;
10495 else if (argv_find(argv, argc, "filtered-routes", &idx))
10496 type = bgp_show_adj_route_filtered;
10497
10498 if (argv_find(argv, argc, "route-map", &idx))
10499 rmap_name = argv[++idx]->arg;
10500
10501 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
10502 }
10503
10504 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
10505 show_ip_bgp_neighbor_received_prefix_filter_cmd,
10506 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10507 SHOW_STR
10508 IP_STR
10509 BGP_STR
10510 "Address Family\n"
10511 "Address Family\n"
10512 "Address Family modifier\n"
10513 "Detailed information on TCP and BGP neighbor connections\n"
10514 "Neighbor to display information about\n"
10515 "Neighbor to display information about\n"
10516 "Neighbor on BGP configured interface\n"
10517 "Display information received from a BGP neighbor\n"
10518 "Display the prefixlist filter\n"
10519 JSON_STR)
10520 {
10521 afi_t afi = AFI_IP6;
10522 safi_t safi = SAFI_UNICAST;
10523 char *peerstr = NULL;
10524
10525 char name[BUFSIZ];
10526 union sockunion su;
10527 struct peer *peer;
10528 int count, ret;
10529
10530 int idx = 0;
10531
10532 /* show [ip] bgp */
10533 if (argv_find(argv, argc, "ip", &idx))
10534 afi = AFI_IP;
10535 /* [<ipv4|ipv6> [unicast]] */
10536 if (argv_find(argv, argc, "ipv4", &idx))
10537 afi = AFI_IP;
10538 if (argv_find(argv, argc, "ipv6", &idx))
10539 afi = AFI_IP6;
10540 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10541 argv_find(argv, argc, "neighbors", &idx);
10542 peerstr = argv[++idx]->arg;
10543
10544 bool uj = use_json(argc, argv);
10545
10546 ret = str2sockunion(peerstr, &su);
10547 if (ret < 0) {
10548 peer = peer_lookup_by_conf_if(NULL, peerstr);
10549 if (!peer) {
10550 if (uj)
10551 vty_out(vty, "{}\n");
10552 else
10553 vty_out(vty,
10554 "%% Malformed address or name: %s\n",
10555 peerstr);
10556 return CMD_WARNING;
10557 }
10558 } else {
10559 peer = peer_lookup(NULL, &su);
10560 if (!peer) {
10561 if (uj)
10562 vty_out(vty, "{}\n");
10563 else
10564 vty_out(vty, "No peer\n");
10565 return CMD_WARNING;
10566 }
10567 }
10568
10569 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
10570 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
10571 if (count) {
10572 if (!uj)
10573 vty_out(vty, "Address Family: %s\n",
10574 afi_safi_print(afi, safi));
10575 prefix_bgp_show_prefix_list(vty, afi, name, uj);
10576 } else {
10577 if (uj)
10578 vty_out(vty, "{}\n");
10579 else
10580 vty_out(vty, "No functional output\n");
10581 }
10582
10583 return CMD_SUCCESS;
10584 }
10585
10586 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
10587 afi_t afi, safi_t safi,
10588 enum bgp_show_type type, bool use_json)
10589 {
10590 /* labeled-unicast routes live in the unicast table */
10591 if (safi == SAFI_LABELED_UNICAST)
10592 safi = SAFI_UNICAST;
10593
10594 if (!peer || !peer->afc[afi][safi]) {
10595 if (use_json) {
10596 json_object *json_no = NULL;
10597 json_no = json_object_new_object();
10598 json_object_string_add(
10599 json_no, "warning",
10600 "No such neighbor or address family");
10601 vty_out(vty, "%s\n",
10602 json_object_to_json_string(json_no));
10603 json_object_free(json_no);
10604 } else
10605 vty_out(vty, "%% No such neighbor or address family\n");
10606 return CMD_WARNING;
10607 }
10608
10609 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
10610 }
10611
10612 DEFUN (show_ip_bgp_flowspec_routes_detailed,
10613 show_ip_bgp_flowspec_routes_detailed_cmd,
10614 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
10615 SHOW_STR
10616 IP_STR
10617 BGP_STR
10618 BGP_INSTANCE_HELP_STR
10619 BGP_AFI_HELP_STR
10620 "SAFI Flowspec\n"
10621 "Detailed information on flowspec entries\n"
10622 JSON_STR)
10623 {
10624 afi_t afi = AFI_IP;
10625 safi_t safi = SAFI_UNICAST;
10626 struct bgp *bgp = NULL;
10627 int idx = 0;
10628 bool uj = use_json(argc, argv);
10629
10630 if (uj)
10631 argc--;
10632
10633 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10634 &bgp, uj);
10635 if (!idx)
10636 return CMD_WARNING;
10637
10638 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
10639 }
10640
10641 DEFUN (show_ip_bgp_neighbor_routes,
10642 show_ip_bgp_neighbor_routes_cmd,
10643 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10644 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10645 SHOW_STR
10646 IP_STR
10647 BGP_STR
10648 BGP_INSTANCE_HELP_STR
10649 BGP_AFI_HELP_STR
10650 BGP_SAFI_WITH_LABEL_HELP_STR
10651 "Detailed information on TCP and BGP neighbor connections\n"
10652 "Neighbor to display information about\n"
10653 "Neighbor to display information about\n"
10654 "Neighbor on BGP configured interface\n"
10655 "Display flap statistics of the routes learned from neighbor\n"
10656 "Display the dampened routes received from neighbor\n"
10657 "Display routes learned from neighbor\n"
10658 JSON_STR)
10659 {
10660 char *peerstr = NULL;
10661 struct bgp *bgp = NULL;
10662 afi_t afi = AFI_IP6;
10663 safi_t safi = SAFI_UNICAST;
10664 struct peer *peer;
10665 enum bgp_show_type sh_type = bgp_show_type_neighbor;
10666 int idx = 0;
10667 bool uj = use_json(argc, argv);
10668
10669 if (uj)
10670 argc--;
10671
10672 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10673 &bgp, uj);
10674 if (!idx)
10675 return CMD_WARNING;
10676
10677 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10678 argv_find(argv, argc, "neighbors", &idx);
10679 peerstr = argv[++idx]->arg;
10680
10681 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10682 if (!peer)
10683 return CMD_WARNING;
10684
10685 if (argv_find(argv, argc, "flap-statistics", &idx))
10686 sh_type = bgp_show_type_flap_neighbor;
10687 else if (argv_find(argv, argc, "dampened-routes", &idx))
10688 sh_type = bgp_show_type_damp_neighbor;
10689 else if (argv_find(argv, argc, "routes", &idx))
10690 sh_type = bgp_show_type_neighbor;
10691
10692 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
10693 }
10694
10695 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
10696
10697 struct bgp_distance {
10698 /* Distance value for the IP source prefix. */
10699 uint8_t distance;
10700
10701 /* Name of the access-list to be matched. */
10702 char *access_list;
10703 };
10704
10705 DEFUN (show_bgp_afi_vpn_rd_route,
10706 show_bgp_afi_vpn_rd_route_cmd,
10707 "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]",
10708 SHOW_STR
10709 BGP_STR
10710 BGP_AFI_HELP_STR
10711 "Address Family modifier\n"
10712 "Display information for a route distinguisher\n"
10713 "Route Distinguisher\n"
10714 "Network in the BGP routing table to display\n"
10715 "Network in the BGP routing table to display\n"
10716 JSON_STR)
10717 {
10718 int ret;
10719 struct prefix_rd prd;
10720 afi_t afi = AFI_MAX;
10721 int idx = 0;
10722
10723 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
10724 vty_out(vty, "%% Malformed Address Family\n");
10725 return CMD_WARNING;
10726 }
10727
10728 ret = str2prefix_rd(argv[5]->arg, &prd);
10729 if (!ret) {
10730 vty_out(vty, "%% Malformed Route Distinguisher\n");
10731 return CMD_WARNING;
10732 }
10733
10734 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
10735 0, BGP_PATH_ALL, use_json(argc, argv));
10736 }
10737
10738 static struct bgp_distance *bgp_distance_new(void)
10739 {
10740 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
10741 }
10742
10743 static void bgp_distance_free(struct bgp_distance *bdistance)
10744 {
10745 XFREE(MTYPE_BGP_DISTANCE, bdistance);
10746 }
10747
10748 static int bgp_distance_set(struct vty *vty, const char *distance_str,
10749 const char *ip_str, const char *access_list_str)
10750 {
10751 int ret;
10752 afi_t afi;
10753 safi_t safi;
10754 struct prefix p;
10755 uint8_t distance;
10756 struct bgp_node *rn;
10757 struct bgp_distance *bdistance;
10758
10759 afi = bgp_node_afi(vty);
10760 safi = bgp_node_safi(vty);
10761
10762 ret = str2prefix(ip_str, &p);
10763 if (ret == 0) {
10764 vty_out(vty, "Malformed prefix\n");
10765 return CMD_WARNING_CONFIG_FAILED;
10766 }
10767
10768 distance = atoi(distance_str);
10769
10770 /* Get BGP distance node. */
10771 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
10772 if (rn->info) {
10773 bdistance = rn->info;
10774 bgp_unlock_node(rn);
10775 } else {
10776 bdistance = bgp_distance_new();
10777 rn->info = bdistance;
10778 }
10779
10780 /* Set distance value. */
10781 bdistance->distance = distance;
10782
10783 /* Reset access-list configuration. */
10784 if (bdistance->access_list) {
10785 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10786 bdistance->access_list = NULL;
10787 }
10788 if (access_list_str)
10789 bdistance->access_list =
10790 XSTRDUP(MTYPE_AS_LIST, access_list_str);
10791
10792 return CMD_SUCCESS;
10793 }
10794
10795 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
10796 const char *ip_str, const char *access_list_str)
10797 {
10798 int ret;
10799 afi_t afi;
10800 safi_t safi;
10801 struct prefix p;
10802 int distance;
10803 struct bgp_node *rn;
10804 struct bgp_distance *bdistance;
10805
10806 afi = bgp_node_afi(vty);
10807 safi = bgp_node_safi(vty);
10808
10809 ret = str2prefix(ip_str, &p);
10810 if (ret == 0) {
10811 vty_out(vty, "Malformed prefix\n");
10812 return CMD_WARNING_CONFIG_FAILED;
10813 }
10814
10815 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
10816 (struct prefix *)&p);
10817 if (!rn) {
10818 vty_out(vty, "Can't find specified prefix\n");
10819 return CMD_WARNING_CONFIG_FAILED;
10820 }
10821
10822 bdistance = rn->info;
10823 distance = atoi(distance_str);
10824
10825 if (bdistance->distance != distance) {
10826 vty_out(vty, "Distance does not match configured\n");
10827 return CMD_WARNING_CONFIG_FAILED;
10828 }
10829
10830 if (bdistance->access_list)
10831 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10832 bgp_distance_free(bdistance);
10833
10834 rn->info = NULL;
10835 bgp_unlock_node(rn);
10836 bgp_unlock_node(rn);
10837
10838 return CMD_SUCCESS;
10839 }
10840
10841 /* Apply BGP information to distance method. */
10842 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
10843 safi_t safi, struct bgp *bgp)
10844 {
10845 struct bgp_node *rn;
10846 struct prefix q;
10847 struct peer *peer;
10848 struct bgp_distance *bdistance;
10849 struct access_list *alist;
10850 struct bgp_static *bgp_static;
10851
10852 if (!bgp)
10853 return 0;
10854
10855 peer = rinfo->peer;
10856
10857 /* Check source address. */
10858 sockunion2hostprefix(&peer->su, &q);
10859 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
10860 if (rn) {
10861 bdistance = rn->info;
10862 bgp_unlock_node(rn);
10863
10864 if (bdistance->access_list) {
10865 alist = access_list_lookup(afi, bdistance->access_list);
10866 if (alist
10867 && access_list_apply(alist, p) == FILTER_PERMIT)
10868 return bdistance->distance;
10869 } else
10870 return bdistance->distance;
10871 }
10872
10873 /* Backdoor check. */
10874 rn = bgp_node_lookup(bgp->route[afi][safi], p);
10875 if (rn) {
10876 bgp_static = rn->info;
10877 bgp_unlock_node(rn);
10878
10879 if (bgp_static->backdoor) {
10880 if (bgp->distance_local[afi][safi])
10881 return bgp->distance_local[afi][safi];
10882 else
10883 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10884 }
10885 }
10886
10887 if (peer->sort == BGP_PEER_EBGP) {
10888 if (bgp->distance_ebgp[afi][safi])
10889 return bgp->distance_ebgp[afi][safi];
10890 return ZEBRA_EBGP_DISTANCE_DEFAULT;
10891 } else {
10892 if (bgp->distance_ibgp[afi][safi])
10893 return bgp->distance_ibgp[afi][safi];
10894 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10895 }
10896 }
10897
10898 DEFUN (bgp_distance,
10899 bgp_distance_cmd,
10900 "distance bgp (1-255) (1-255) (1-255)",
10901 "Define an administrative distance\n"
10902 "BGP distance\n"
10903 "Distance for routes external to the AS\n"
10904 "Distance for routes internal to the AS\n"
10905 "Distance for local routes\n")
10906 {
10907 VTY_DECLVAR_CONTEXT(bgp, bgp);
10908 int idx_number = 2;
10909 int idx_number_2 = 3;
10910 int idx_number_3 = 4;
10911 afi_t afi;
10912 safi_t safi;
10913
10914 afi = bgp_node_afi(vty);
10915 safi = bgp_node_safi(vty);
10916
10917 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
10918 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
10919 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
10920 return CMD_SUCCESS;
10921 }
10922
10923 DEFUN (no_bgp_distance,
10924 no_bgp_distance_cmd,
10925 "no distance bgp [(1-255) (1-255) (1-255)]",
10926 NO_STR
10927 "Define an administrative distance\n"
10928 "BGP distance\n"
10929 "Distance for routes external to the AS\n"
10930 "Distance for routes internal to the AS\n"
10931 "Distance for local routes\n")
10932 {
10933 VTY_DECLVAR_CONTEXT(bgp, bgp);
10934 afi_t afi;
10935 safi_t safi;
10936
10937 afi = bgp_node_afi(vty);
10938 safi = bgp_node_safi(vty);
10939
10940 bgp->distance_ebgp[afi][safi] = 0;
10941 bgp->distance_ibgp[afi][safi] = 0;
10942 bgp->distance_local[afi][safi] = 0;
10943 return CMD_SUCCESS;
10944 }
10945
10946
10947 DEFUN (bgp_distance_source,
10948 bgp_distance_source_cmd,
10949 "distance (1-255) A.B.C.D/M",
10950 "Define an administrative distance\n"
10951 "Administrative distance\n"
10952 "IP source prefix\n")
10953 {
10954 int idx_number = 1;
10955 int idx_ipv4_prefixlen = 2;
10956 bgp_distance_set(vty, argv[idx_number]->arg,
10957 argv[idx_ipv4_prefixlen]->arg, NULL);
10958 return CMD_SUCCESS;
10959 }
10960
10961 DEFUN (no_bgp_distance_source,
10962 no_bgp_distance_source_cmd,
10963 "no distance (1-255) A.B.C.D/M",
10964 NO_STR
10965 "Define an administrative distance\n"
10966 "Administrative distance\n"
10967 "IP source prefix\n")
10968 {
10969 int idx_number = 2;
10970 int idx_ipv4_prefixlen = 3;
10971 bgp_distance_unset(vty, argv[idx_number]->arg,
10972 argv[idx_ipv4_prefixlen]->arg, NULL);
10973 return CMD_SUCCESS;
10974 }
10975
10976 DEFUN (bgp_distance_source_access_list,
10977 bgp_distance_source_access_list_cmd,
10978 "distance (1-255) A.B.C.D/M WORD",
10979 "Define an administrative distance\n"
10980 "Administrative distance\n"
10981 "IP source prefix\n"
10982 "Access list name\n")
10983 {
10984 int idx_number = 1;
10985 int idx_ipv4_prefixlen = 2;
10986 int idx_word = 3;
10987 bgp_distance_set(vty, argv[idx_number]->arg,
10988 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10989 return CMD_SUCCESS;
10990 }
10991
10992 DEFUN (no_bgp_distance_source_access_list,
10993 no_bgp_distance_source_access_list_cmd,
10994 "no distance (1-255) A.B.C.D/M WORD",
10995 NO_STR
10996 "Define an administrative distance\n"
10997 "Administrative distance\n"
10998 "IP source prefix\n"
10999 "Access list name\n")
11000 {
11001 int idx_number = 2;
11002 int idx_ipv4_prefixlen = 3;
11003 int idx_word = 4;
11004 bgp_distance_unset(vty, argv[idx_number]->arg,
11005 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
11006 return CMD_SUCCESS;
11007 }
11008
11009 DEFUN (ipv6_bgp_distance_source,
11010 ipv6_bgp_distance_source_cmd,
11011 "distance (1-255) X:X::X:X/M",
11012 "Define an administrative distance\n"
11013 "Administrative distance\n"
11014 "IP source prefix\n")
11015 {
11016 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
11017 return CMD_SUCCESS;
11018 }
11019
11020 DEFUN (no_ipv6_bgp_distance_source,
11021 no_ipv6_bgp_distance_source_cmd,
11022 "no distance (1-255) X:X::X:X/M",
11023 NO_STR
11024 "Define an administrative distance\n"
11025 "Administrative distance\n"
11026 "IP source prefix\n")
11027 {
11028 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
11029 return CMD_SUCCESS;
11030 }
11031
11032 DEFUN (ipv6_bgp_distance_source_access_list,
11033 ipv6_bgp_distance_source_access_list_cmd,
11034 "distance (1-255) X:X::X:X/M WORD",
11035 "Define an administrative distance\n"
11036 "Administrative distance\n"
11037 "IP source prefix\n"
11038 "Access list name\n")
11039 {
11040 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
11041 return CMD_SUCCESS;
11042 }
11043
11044 DEFUN (no_ipv6_bgp_distance_source_access_list,
11045 no_ipv6_bgp_distance_source_access_list_cmd,
11046 "no distance (1-255) X:X::X:X/M WORD",
11047 NO_STR
11048 "Define an administrative distance\n"
11049 "Administrative distance\n"
11050 "IP source prefix\n"
11051 "Access list name\n")
11052 {
11053 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
11054 return CMD_SUCCESS;
11055 }
11056
11057 DEFUN (bgp_damp_set,
11058 bgp_damp_set_cmd,
11059 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11060 "BGP Specific commands\n"
11061 "Enable route-flap dampening\n"
11062 "Half-life time for the penalty\n"
11063 "Value to start reusing a route\n"
11064 "Value to start suppressing a route\n"
11065 "Maximum duration to suppress a stable route\n")
11066 {
11067 VTY_DECLVAR_CONTEXT(bgp, bgp);
11068 int idx_half_life = 2;
11069 int idx_reuse = 3;
11070 int idx_suppress = 4;
11071 int idx_max_suppress = 5;
11072 int half = DEFAULT_HALF_LIFE * 60;
11073 int reuse = DEFAULT_REUSE;
11074 int suppress = DEFAULT_SUPPRESS;
11075 int max = 4 * half;
11076
11077 if (argc == 6) {
11078 half = atoi(argv[idx_half_life]->arg) * 60;
11079 reuse = atoi(argv[idx_reuse]->arg);
11080 suppress = atoi(argv[idx_suppress]->arg);
11081 max = atoi(argv[idx_max_suppress]->arg) * 60;
11082 } else if (argc == 3) {
11083 half = atoi(argv[idx_half_life]->arg) * 60;
11084 max = 4 * half;
11085 }
11086
11087 if (suppress < reuse) {
11088 vty_out(vty,
11089 "Suppress value cannot be less than reuse value \n");
11090 return 0;
11091 }
11092
11093 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
11094 reuse, suppress, max);
11095 }
11096
11097 DEFUN (bgp_damp_unset,
11098 bgp_damp_unset_cmd,
11099 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11100 NO_STR
11101 "BGP Specific commands\n"
11102 "Enable route-flap dampening\n"
11103 "Half-life time for the penalty\n"
11104 "Value to start reusing a route\n"
11105 "Value to start suppressing a route\n"
11106 "Maximum duration to suppress a stable route\n")
11107 {
11108 VTY_DECLVAR_CONTEXT(bgp, bgp);
11109 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
11110 }
11111
11112 /* Display specified route of BGP table. */
11113 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
11114 const char *ip_str, afi_t afi, safi_t safi,
11115 struct prefix_rd *prd, int prefix_check)
11116 {
11117 int ret;
11118 struct prefix match;
11119 struct bgp_node *rn;
11120 struct bgp_node *rm;
11121 struct bgp_info *ri;
11122 struct bgp_info *ri_temp;
11123 struct bgp *bgp;
11124 struct bgp_table *table;
11125
11126 /* BGP structure lookup. */
11127 if (view_name) {
11128 bgp = bgp_lookup_by_name(view_name);
11129 if (bgp == NULL) {
11130 vty_out(vty, "%% Can't find BGP instance %s\n",
11131 view_name);
11132 return CMD_WARNING;
11133 }
11134 } else {
11135 bgp = bgp_get_default();
11136 if (bgp == NULL) {
11137 vty_out(vty, "%% No BGP process is configured\n");
11138 return CMD_WARNING;
11139 }
11140 }
11141
11142 /* Check IP address argument. */
11143 ret = str2prefix(ip_str, &match);
11144 if (!ret) {
11145 vty_out(vty, "%% address is malformed\n");
11146 return CMD_WARNING;
11147 }
11148
11149 match.family = afi2family(afi);
11150
11151 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
11152 || (safi == SAFI_EVPN)) {
11153 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
11154 rn = bgp_route_next(rn)) {
11155 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
11156 continue;
11157 if ((table = rn->info) == NULL)
11158 continue;
11159 if ((rm = bgp_node_match(table, &match)) == NULL)
11160 continue;
11161
11162 if (!prefix_check
11163 || rm->p.prefixlen == match.prefixlen) {
11164 ri = rm->info;
11165 while (ri) {
11166 if (ri->extra && ri->extra->damp_info) {
11167 ri_temp = ri->next;
11168 bgp_damp_info_free(
11169 ri->extra->damp_info,
11170 1);
11171 ri = ri_temp;
11172 } else
11173 ri = ri->next;
11174 }
11175 }
11176
11177 bgp_unlock_node(rm);
11178 }
11179 } else {
11180 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
11181 != NULL) {
11182 if (!prefix_check
11183 || rn->p.prefixlen == match.prefixlen) {
11184 ri = rn->info;
11185 while (ri) {
11186 if (ri->extra && ri->extra->damp_info) {
11187 ri_temp = ri->next;
11188 bgp_damp_info_free(
11189 ri->extra->damp_info,
11190 1);
11191 ri = ri_temp;
11192 } else
11193 ri = ri->next;
11194 }
11195 }
11196
11197 bgp_unlock_node(rn);
11198 }
11199 }
11200
11201 return CMD_SUCCESS;
11202 }
11203
11204 DEFUN (clear_ip_bgp_dampening,
11205 clear_ip_bgp_dampening_cmd,
11206 "clear ip bgp dampening",
11207 CLEAR_STR
11208 IP_STR
11209 BGP_STR
11210 "Clear route flap dampening information\n")
11211 {
11212 bgp_damp_info_clean();
11213 return CMD_SUCCESS;
11214 }
11215
11216 DEFUN (clear_ip_bgp_dampening_prefix,
11217 clear_ip_bgp_dampening_prefix_cmd,
11218 "clear ip bgp dampening A.B.C.D/M",
11219 CLEAR_STR
11220 IP_STR
11221 BGP_STR
11222 "Clear route flap dampening information\n"
11223 "IPv4 prefix\n")
11224 {
11225 int idx_ipv4_prefixlen = 4;
11226 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
11227 AFI_IP, SAFI_UNICAST, NULL, 1);
11228 }
11229
11230 DEFUN (clear_ip_bgp_dampening_address,
11231 clear_ip_bgp_dampening_address_cmd,
11232 "clear ip bgp dampening A.B.C.D",
11233 CLEAR_STR
11234 IP_STR
11235 BGP_STR
11236 "Clear route flap dampening information\n"
11237 "Network to clear damping information\n")
11238 {
11239 int idx_ipv4 = 4;
11240 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
11241 SAFI_UNICAST, NULL, 0);
11242 }
11243
11244 DEFUN (clear_ip_bgp_dampening_address_mask,
11245 clear_ip_bgp_dampening_address_mask_cmd,
11246 "clear ip bgp dampening A.B.C.D A.B.C.D",
11247 CLEAR_STR
11248 IP_STR
11249 BGP_STR
11250 "Clear route flap dampening information\n"
11251 "Network to clear damping information\n"
11252 "Network mask\n")
11253 {
11254 int idx_ipv4 = 4;
11255 int idx_ipv4_2 = 5;
11256 int ret;
11257 char prefix_str[BUFSIZ];
11258
11259 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
11260 prefix_str);
11261 if (!ret) {
11262 vty_out(vty, "%% Inconsistent address and mask\n");
11263 return CMD_WARNING;
11264 }
11265
11266 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
11267 NULL, 0);
11268 }
11269
11270 /* also used for encap safi */
11271 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
11272 afi_t afi, safi_t safi)
11273 {
11274 struct bgp_node *prn;
11275 struct bgp_node *rn;
11276 struct bgp_table *table;
11277 struct prefix *p;
11278 struct prefix_rd *prd;
11279 struct bgp_static *bgp_static;
11280 mpls_label_t label;
11281 char buf[SU_ADDRSTRLEN];
11282 char rdbuf[RD_ADDRSTRLEN];
11283
11284 /* Network configuration. */
11285 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11286 prn = bgp_route_next(prn)) {
11287 if ((table = prn->info) == NULL)
11288 continue;
11289
11290 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11291 if ((bgp_static = rn->info) == NULL)
11292 continue;
11293
11294 p = &rn->p;
11295 prd = (struct prefix_rd *)&prn->p;
11296
11297 /* "network" configuration display. */
11298 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11299 label = decode_label(&bgp_static->label);
11300
11301 vty_out(vty, " network %s/%d rd %s",
11302 inet_ntop(p->family, &p->u.prefix, buf,
11303 SU_ADDRSTRLEN),
11304 p->prefixlen, rdbuf);
11305 if (safi == SAFI_MPLS_VPN)
11306 vty_out(vty, " label %u", label);
11307
11308 if (bgp_static->rmap.name)
11309 vty_out(vty, " route-map %s",
11310 bgp_static->rmap.name);
11311
11312 if (bgp_static->backdoor)
11313 vty_out(vty, " backdoor");
11314
11315 vty_out(vty, "\n");
11316 }
11317 }
11318 }
11319
11320 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
11321 afi_t afi, safi_t safi)
11322 {
11323 struct bgp_node *prn;
11324 struct bgp_node *rn;
11325 struct bgp_table *table;
11326 struct prefix *p;
11327 struct prefix_rd *prd;
11328 struct bgp_static *bgp_static;
11329 char buf[PREFIX_STRLEN * 2];
11330 char buf2[SU_ADDRSTRLEN];
11331 char rdbuf[RD_ADDRSTRLEN];
11332
11333 /* Network configuration. */
11334 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11335 prn = bgp_route_next(prn)) {
11336 if ((table = prn->info) == NULL)
11337 continue;
11338
11339 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11340 if ((bgp_static = rn->info) == NULL)
11341 continue;
11342
11343 char *macrouter = NULL;
11344 char *esi = NULL;
11345
11346 if (bgp_static->router_mac)
11347 macrouter = prefix_mac2str(
11348 bgp_static->router_mac, NULL, 0);
11349 if (bgp_static->eth_s_id)
11350 esi = esi2str(bgp_static->eth_s_id);
11351 p = &rn->p;
11352 prd = (struct prefix_rd *)&prn->p;
11353
11354 /* "network" configuration display. */
11355 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11356 if (p->u.prefix_evpn.route_type == 5) {
11357 char local_buf[PREFIX_STRLEN];
11358 uint8_t family = is_evpn_prefix_ipaddr_v4((
11359 struct prefix_evpn *)p)
11360 ? AF_INET
11361 : AF_INET6;
11362 inet_ntop(family,
11363 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
11364 local_buf, PREFIX_STRLEN);
11365 sprintf(buf, "%s/%u", local_buf,
11366 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
11367 } else {
11368 prefix2str(p, buf, sizeof(buf));
11369 }
11370
11371 if (bgp_static->gatewayIp.family == AF_INET
11372 || bgp_static->gatewayIp.family == AF_INET6)
11373 inet_ntop(bgp_static->gatewayIp.family,
11374 &bgp_static->gatewayIp.u.prefix, buf2,
11375 sizeof(buf2));
11376 vty_out(vty,
11377 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11378 buf, rdbuf,
11379 p->u.prefix_evpn.prefix_addr.eth_tag,
11380 decode_label(&bgp_static->label), esi, buf2,
11381 macrouter);
11382
11383 if (macrouter)
11384 XFREE(MTYPE_TMP, macrouter);
11385 if (esi)
11386 XFREE(MTYPE_TMP, esi);
11387 }
11388 }
11389 }
11390
11391 /* Configuration of static route announcement and aggregate
11392 information. */
11393 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
11394 safi_t safi)
11395 {
11396 struct bgp_node *rn;
11397 struct prefix *p;
11398 struct bgp_static *bgp_static;
11399 struct bgp_aggregate *bgp_aggregate;
11400 char buf[SU_ADDRSTRLEN];
11401
11402 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
11403 bgp_config_write_network_vpn(vty, bgp, afi, safi);
11404 return;
11405 }
11406
11407 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
11408 bgp_config_write_network_evpn(vty, bgp, afi, safi);
11409 return;
11410 }
11411
11412 /* Network configuration. */
11413 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
11414 rn = bgp_route_next(rn)) {
11415 if ((bgp_static = rn->info) == NULL)
11416 continue;
11417
11418 p = &rn->p;
11419
11420 /* "network" configuration display. */
11421 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11422 uint32_t destination;
11423 struct in_addr netmask;
11424
11425 destination = ntohl(p->u.prefix4.s_addr);
11426 masklen2ip(p->prefixlen, &netmask);
11427 vty_out(vty, " network %s",
11428 inet_ntop(p->family, &p->u.prefix, buf,
11429 SU_ADDRSTRLEN));
11430
11431 if ((IN_CLASSC(destination) && p->prefixlen == 24)
11432 || (IN_CLASSB(destination) && p->prefixlen == 16)
11433 || (IN_CLASSA(destination) && p->prefixlen == 8)
11434 || p->u.prefix4.s_addr == 0) {
11435 /* Natural mask is not display. */
11436 } else
11437 vty_out(vty, " mask %s", inet_ntoa(netmask));
11438 } else {
11439 vty_out(vty, " network %s/%d",
11440 inet_ntop(p->family, &p->u.prefix, buf,
11441 SU_ADDRSTRLEN),
11442 p->prefixlen);
11443 }
11444
11445 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
11446 vty_out(vty, " label-index %u",
11447 bgp_static->label_index);
11448
11449 if (bgp_static->rmap.name)
11450 vty_out(vty, " route-map %s", bgp_static->rmap.name);
11451
11452 if (bgp_static->backdoor)
11453 vty_out(vty, " backdoor");
11454
11455 vty_out(vty, "\n");
11456 }
11457
11458 /* Aggregate-address configuration. */
11459 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
11460 rn = bgp_route_next(rn)) {
11461 if ((bgp_aggregate = rn->info) == NULL)
11462 continue;
11463
11464 p = &rn->p;
11465
11466 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11467 struct in_addr netmask;
11468
11469 masklen2ip(p->prefixlen, &netmask);
11470 vty_out(vty, " aggregate-address %s %s",
11471 inet_ntop(p->family, &p->u.prefix, buf,
11472 SU_ADDRSTRLEN),
11473 inet_ntoa(netmask));
11474 } else {
11475 vty_out(vty, " aggregate-address %s/%d",
11476 inet_ntop(p->family, &p->u.prefix, buf,
11477 SU_ADDRSTRLEN),
11478 p->prefixlen);
11479 }
11480
11481 if (bgp_aggregate->as_set)
11482 vty_out(vty, " as-set");
11483
11484 if (bgp_aggregate->summary_only)
11485 vty_out(vty, " summary-only");
11486
11487 vty_out(vty, "\n");
11488 }
11489 }
11490
11491 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
11492 safi_t safi)
11493 {
11494 struct bgp_node *rn;
11495 struct bgp_distance *bdistance;
11496
11497 /* Distance configuration. */
11498 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
11499 && bgp->distance_local[afi][safi]
11500 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
11501 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
11502 || bgp->distance_local[afi][safi]
11503 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
11504 vty_out(vty, " distance bgp %d %d %d\n",
11505 bgp->distance_ebgp[afi][safi],
11506 bgp->distance_ibgp[afi][safi],
11507 bgp->distance_local[afi][safi]);
11508 }
11509
11510 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
11511 rn = bgp_route_next(rn))
11512 if ((bdistance = rn->info) != NULL) {
11513 char buf[PREFIX_STRLEN];
11514
11515 vty_out(vty, " distance %d %s %s\n",
11516 bdistance->distance,
11517 prefix2str(&rn->p, buf, sizeof(buf)),
11518 bdistance->access_list ? bdistance->access_list
11519 : "");
11520 }
11521 }
11522
11523 /* Allocate routing table structure and install commands. */
11524 void bgp_route_init(void)
11525 {
11526 afi_t afi;
11527 safi_t safi;
11528
11529 /* Init BGP distance table. */
11530 FOREACH_AFI_SAFI (afi, safi)
11531 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
11532
11533 /* IPv4 BGP commands. */
11534 install_element(BGP_NODE, &bgp_table_map_cmd);
11535 install_element(BGP_NODE, &bgp_network_cmd);
11536 install_element(BGP_NODE, &no_bgp_table_map_cmd);
11537
11538 install_element(BGP_NODE, &aggregate_address_cmd);
11539 install_element(BGP_NODE, &aggregate_address_mask_cmd);
11540 install_element(BGP_NODE, &no_aggregate_address_cmd);
11541 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
11542
11543 /* IPv4 unicast configuration. */
11544 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
11545 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
11546 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
11547
11548 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
11549 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
11550 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
11551 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
11552
11553 /* IPv4 multicast configuration. */
11554 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
11555 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
11556 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
11557 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
11558 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
11559 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
11560 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
11561
11562 /* IPv4 labeled-unicast configuration. */
11563 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
11564 install_element(VIEW_NODE, &show_ip_bgp_cmd);
11565 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
11566 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
11567 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
11568
11569 install_element(VIEW_NODE,
11570 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
11571 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
11572 install_element(VIEW_NODE,
11573 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
11574 #ifdef KEEP_OLD_VPN_COMMANDS
11575 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
11576 #endif /* KEEP_OLD_VPN_COMMANDS */
11577 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
11578 install_element(VIEW_NODE,
11579 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
11580
11581 /* BGP dampening clear commands */
11582 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
11583 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
11584
11585 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
11586 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
11587
11588 /* prefix count */
11589 install_element(ENABLE_NODE,
11590 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
11591 #ifdef KEEP_OLD_VPN_COMMANDS
11592 install_element(ENABLE_NODE,
11593 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
11594 #endif /* KEEP_OLD_VPN_COMMANDS */
11595
11596 /* New config IPv6 BGP commands. */
11597 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
11598 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
11599 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
11600
11601 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
11602 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
11603
11604 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
11605
11606 install_element(BGP_NODE, &bgp_distance_cmd);
11607 install_element(BGP_NODE, &no_bgp_distance_cmd);
11608 install_element(BGP_NODE, &bgp_distance_source_cmd);
11609 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
11610 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
11611 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
11612 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
11613 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
11614 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
11615 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
11616 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
11617 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
11618 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
11619 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
11620 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
11621 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
11622 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
11623 install_element(BGP_IPV4M_NODE,
11624 &no_bgp_distance_source_access_list_cmd);
11625 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
11626 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
11627 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
11628 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
11629 install_element(BGP_IPV6_NODE,
11630 &ipv6_bgp_distance_source_access_list_cmd);
11631 install_element(BGP_IPV6_NODE,
11632 &no_ipv6_bgp_distance_source_access_list_cmd);
11633 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
11634 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
11635 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
11636 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
11637 install_element(BGP_IPV6M_NODE,
11638 &ipv6_bgp_distance_source_access_list_cmd);
11639 install_element(BGP_IPV6M_NODE,
11640 &no_ipv6_bgp_distance_source_access_list_cmd);
11641
11642 install_element(BGP_NODE, &bgp_damp_set_cmd);
11643 install_element(BGP_NODE, &bgp_damp_unset_cmd);
11644 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
11645 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
11646
11647 /* IPv4 Multicast Mode */
11648 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
11649 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
11650
11651 /* Large Communities */
11652 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
11653 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
11654
11655 /* show bgp ipv4 flowspec detailed */
11656 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
11657
11658 }
11659
11660 void bgp_route_finish(void)
11661 {
11662 afi_t afi;
11663 safi_t safi;
11664
11665 FOREACH_AFI_SAFI (afi, safi) {
11666 bgp_table_unlock(bgp_distance_table[afi][safi]);
11667 bgp_distance_table[afi][safi] = NULL;
11668 }
11669 }