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