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