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