1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 * This file is part of GNU Zebra.
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
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.
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
34 #include "sockunion.h"
37 #include "workqueue.h"
41 #include "lib_errors.h"
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgpd/bgp_route.h"
46 #include "bgpd/bgp_attr.h"
47 #include "bgpd/bgp_debug.h"
48 #include "bgpd/bgp_errors.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_regex.h"
51 #include "bgpd/bgp_community.h"
52 #include "bgpd/bgp_ecommunity.h"
53 #include "bgpd/bgp_lcommunity.h"
54 #include "bgpd/bgp_clist.h"
55 #include "bgpd/bgp_packet.h"
56 #include "bgpd/bgp_filter.h"
57 #include "bgpd/bgp_fsm.h"
58 #include "bgpd/bgp_mplsvpn.h"
59 #include "bgpd/bgp_nexthop.h"
60 #include "bgpd/bgp_damp.h"
61 #include "bgpd/bgp_advertise.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_vty.h"
64 #include "bgpd/bgp_mpath.h"
65 #include "bgpd/bgp_nht.h"
66 #include "bgpd/bgp_updgrp.h"
67 #include "bgpd/bgp_label.h"
68 #include "bgpd/bgp_addpath.h"
69 #include "bgpd/bgp_mac.h"
72 #include "bgpd/rfapi/rfapi_backend.h"
73 #include "bgpd/rfapi/vnc_import_bgp.h"
74 #include "bgpd/rfapi/vnc_export_bgp.h"
76 #include "bgpd/bgp_encap_types.h"
77 #include "bgpd/bgp_encap_tlv.h"
78 #include "bgpd/bgp_evpn.h"
79 #include "bgpd/bgp_evpn_vty.h"
80 #include "bgpd/bgp_flowspec.h"
81 #include "bgpd/bgp_flowspec_util.h"
82 #include "bgpd/bgp_pbr.h"
84 #ifndef VTYSH_EXTRACT_PL
85 #include "bgpd/bgp_route_clippy.c"
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str
[];
90 extern const char *bgp_origin_long_str
[];
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str
[] = {
96 {PMSI_TNLTYPE_NO_INFO
, PMSI_TNLTYPE_STR_NO_INFO
},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP
, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP
, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM
, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM
, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR
, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL
, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP
, "mLDP MP2MP"},
107 #define VRFID_NONE_STR "-"
109 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
110 safi_t safi
, struct prefix
*p
,
111 struct prefix_rd
*prd
)
114 struct bgp_node
*prn
= NULL
;
120 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
121 || (safi
== SAFI_EVPN
)) {
122 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
124 if (!bgp_node_has_bgp_path_info_data(prn
))
125 bgp_node_set_bgp_table_info(
126 prn
, bgp_table_init(table
->bgp
, afi
, safi
));
128 bgp_unlock_node(prn
);
129 table
= bgp_node_get_bgp_table_info(prn
);
132 rn
= bgp_node_get(table
, p
);
134 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
135 || (safi
== SAFI_EVPN
))
141 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
142 safi_t safi
, struct prefix
*p
,
143 struct prefix_rd
*prd
)
146 struct bgp_node
*prn
= NULL
;
151 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
152 || (safi
== SAFI_EVPN
)) {
153 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
157 if (!bgp_node_has_bgp_path_info_data(prn
)) {
158 bgp_unlock_node(prn
);
162 table
= bgp_node_get_bgp_table_info(prn
);
165 rn
= bgp_node_lookup(table
, p
);
170 /* Allocate bgp_path_info_extra */
171 static struct bgp_path_info_extra
*bgp_path_info_extra_new(void)
173 struct bgp_path_info_extra
*new;
174 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
,
175 sizeof(struct bgp_path_info_extra
));
176 new->label
[0] = MPLS_INVALID_LABEL
;
181 void bgp_path_info_extra_free(struct bgp_path_info_extra
**extra
)
183 struct bgp_path_info_extra
*e
;
185 if (!extra
|| !*extra
)
190 bgp_damp_info_free(e
->damp_info
, 0);
194 struct bgp_path_info
*bpi
= (struct bgp_path_info
*)e
->parent
;
197 /* FIXME: since multiple e may have the same e->parent
198 * and e->parent->net is holding a refcount for each
199 * of them, we need to do some fudging here.
201 * WARNING: if bpi->net->lock drops to 0, bpi may be
202 * freed as well (because bpi->net was holding the
203 * last reference to bpi) => write after free!
207 bpi
= bgp_path_info_lock(bpi
);
208 refcount
= bpi
->net
->lock
- 1;
209 bgp_unlock_node((struct bgp_node
*)bpi
->net
);
212 bgp_path_info_unlock(bpi
);
214 bgp_path_info_unlock(e
->parent
);
219 bgp_unlock(e
->bgp_orig
);
221 if ((*extra
)->bgp_fs_pbr
)
222 list_delete(&((*extra
)->bgp_fs_pbr
));
223 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
228 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
229 * allocated if required.
231 struct bgp_path_info_extra
*bgp_path_info_extra_get(struct bgp_path_info
*pi
)
234 pi
->extra
= bgp_path_info_extra_new();
238 /* Allocate new bgp info structure. */
239 struct bgp_path_info
*bgp_path_info_new(void)
241 return XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_path_info
));
244 /* Free bgp route information. */
245 static void bgp_path_info_free(struct bgp_path_info
*path
)
248 bgp_attr_unintern(&path
->attr
);
250 bgp_unlink_nexthop(path
);
251 bgp_path_info_extra_free(&path
->extra
);
252 bgp_path_info_mpath_free(&path
->mpath
);
253 bgp_addpath_free_info_data(&path
->tx_addpath
,
254 path
->net
? &path
->net
->tx_addpath
: NULL
);
256 peer_unlock(path
->peer
); /* bgp_path_info peer reference */
258 XFREE(MTYPE_BGP_ROUTE
, path
);
261 struct bgp_path_info
*bgp_path_info_lock(struct bgp_path_info
*path
)
267 struct bgp_path_info
*bgp_path_info_unlock(struct bgp_path_info
*path
)
269 assert(path
&& path
->lock
> 0);
272 if (path
->lock
== 0) {
274 zlog_debug ("%s: unlocked and freeing", __func__
);
275 zlog_backtrace (LOG_DEBUG
);
277 bgp_path_info_free(path
);
284 zlog_debug ("%s: unlocked to 1", __func__
);
285 zlog_backtrace (LOG_DEBUG
);
292 void bgp_path_info_add(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
294 struct bgp_path_info
*top
;
296 top
= bgp_node_get_bgp_path_info(rn
);
302 bgp_node_set_bgp_path_info(rn
, pi
);
304 bgp_path_info_lock(pi
);
306 peer_lock(pi
->peer
); /* bgp_path_info peer reference */
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
)
314 pi
->next
->prev
= pi
->prev
;
316 pi
->prev
->next
= pi
->next
;
318 bgp_node_set_bgp_path_info(rn
, pi
->next
);
320 bgp_path_info_mpath_dequeue(pi
);
321 bgp_path_info_unlock(pi
);
325 void bgp_path_info_delete(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
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
);
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
)
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
);
342 /* Adjust pcount as required */
343 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
345 struct bgp_table
*table
;
347 assert(rn
&& bgp_node_table(rn
));
348 assert(pi
&& pi
->peer
&& pi
->peer
->bgp
);
350 table
= bgp_node_table(rn
);
352 if (pi
->peer
== pi
->peer
->bgp
->peer_self
)
355 if (!BGP_PATH_COUNTABLE(pi
)
356 && CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
358 UNSET_FLAG(pi
->flags
, BGP_PATH_COUNTED
);
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
]--;
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
]++;
373 static int bgp_label_index_differs(struct bgp_path_info
*pi1
,
374 struct bgp_path_info
*pi2
)
376 return (!(pi1
->attr
->label_index
== pi2
->attr
->label_index
));
379 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
380 * This is here primarily to keep prefix-count in check.
382 void bgp_path_info_set_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
385 SET_FLAG(pi
->flags
, flag
);
387 /* early bath if we know it's not a flag that changes countability state
389 if (!CHECK_FLAG(flag
,
390 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
393 bgp_pcount_adjust(rn
, pi
);
396 void bgp_path_info_unset_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
399 UNSET_FLAG(pi
->flags
, flag
);
401 /* early bath if we know it's not a flag that changes countability state
403 if (!CHECK_FLAG(flag
,
404 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
407 bgp_pcount_adjust(rn
, pi
);
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
)
414 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
417 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
424 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info
*pi
, char *buf
)
426 if (pi
->addpath_rx_id
)
427 sprintf(buf
, "path %s (addpath rxid %d)", pi
->peer
->host
,
430 sprintf(buf
, "path %s", pi
->peer
->host
);
433 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
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
)
440 struct attr
*newattr
, *existattr
;
441 bgp_peer_sort_t new_sort
;
442 bgp_peer_sort_t exist_sort
;
448 uint32_t exist_weight
;
449 uint32_t newm
, existm
;
450 struct in_addr new_id
;
451 struct in_addr exist_id
;
454 int internal_as_route
;
457 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
458 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
460 uint32_t exist_mm_seq
;
468 zlog_debug("%s: new is NULL", pfx_buf
);
473 bgp_path_info_path_with_addpath_rx_str(new, new_buf
);
477 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
483 bgp_path_info_path_with_addpath_rx_str(exist
, exist_buf
);
484 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
485 pfx_buf
, new_buf
, new->flags
, exist_buf
,
490 existattr
= exist
->attr
;
492 /* For EVPN routes, we cannot just go by local vs remote, we have to
493 * look at the MAC mobility sequence number, if present.
495 if (safi
== SAFI_EVPN
) {
496 /* This is an error condition described in RFC 7432 Section
498 * states that in this scenario "the PE MUST alert the operator"
500 * does not state what other action to take. In order to provide
502 * consistency in this scenario we are going to prefer the path
506 if (newattr
->sticky
!= existattr
->sticky
) {
508 prefix2str(&new->net
->p
, pfx_buf
,
510 * PREFIX2STR_BUFFER
);
511 bgp_path_info_path_with_addpath_rx_str(new,
513 bgp_path_info_path_with_addpath_rx_str(
517 if (newattr
->sticky
&& !existattr
->sticky
) {
520 "%s: %s wins over %s due to sticky MAC flag",
521 pfx_buf
, new_buf
, exist_buf
);
525 if (!newattr
->sticky
&& existattr
->sticky
) {
528 "%s: %s loses to %s due to sticky MAC flag",
529 pfx_buf
, new_buf
, exist_buf
);
534 new_mm_seq
= mac_mobility_seqnum(newattr
);
535 exist_mm_seq
= mac_mobility_seqnum(existattr
);
537 if (new_mm_seq
> exist_mm_seq
) {
540 "%s: %s wins over %s due to MM seq %u > %u",
541 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
546 if (new_mm_seq
< exist_mm_seq
) {
549 "%s: %s loses to %s due to MM seq %u < %u",
550 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
556 * if sequence numbers are the same path with the lowest IP
559 nh_cmp
= bgp_path_info_nexthop_cmp(new, exist
);
563 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
564 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
565 inet_ntoa(new->attr
->nexthop
));
571 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
572 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
573 inet_ntoa(new->attr
->nexthop
));
578 /* 1. Weight check. */
579 new_weight
= newattr
->weight
;
580 exist_weight
= existattr
->weight
;
582 if (new_weight
> exist_weight
) {
584 zlog_debug("%s: %s wins over %s due to weight %d > %d",
585 pfx_buf
, new_buf
, exist_buf
, new_weight
,
590 if (new_weight
< exist_weight
) {
592 zlog_debug("%s: %s loses to %s due to weight %d < %d",
593 pfx_buf
, new_buf
, exist_buf
, new_weight
,
598 /* 2. Local preference check. */
599 new_pref
= exist_pref
= bgp
->default_local_pref
;
601 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
602 new_pref
= newattr
->local_pref
;
603 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
604 exist_pref
= existattr
->local_pref
;
606 if (new_pref
> exist_pref
) {
609 "%s: %s wins over %s due to localpref %d > %d",
610 pfx_buf
, new_buf
, exist_buf
, new_pref
,
615 if (new_pref
< exist_pref
) {
618 "%s: %s loses to %s due to localpref %d < %d",
619 pfx_buf
, new_buf
, exist_buf
, new_pref
,
624 /* 3. Local route check. We prefer:
626 * - BGP_ROUTE_AGGREGATE
627 * - BGP_ROUTE_REDISTRIBUTE
629 if (!(new->sub_type
== BGP_ROUTE_NORMAL
||
630 new->sub_type
== BGP_ROUTE_IMPORTED
)) {
633 "%s: %s wins over %s due to preferred BGP_ROUTE type",
634 pfx_buf
, new_buf
, exist_buf
);
638 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
||
639 exist
->sub_type
== BGP_ROUTE_IMPORTED
)) {
642 "%s: %s loses to %s due to preferred BGP_ROUTE type",
643 pfx_buf
, new_buf
, exist_buf
);
647 /* 4. AS path length check. */
648 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
649 int exist_hops
= aspath_count_hops(existattr
->aspath
);
650 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
652 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
655 aspath_hops
= aspath_count_hops(newattr
->aspath
);
656 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
658 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
661 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
662 pfx_buf
, new_buf
, exist_buf
,
664 (exist_hops
+ exist_confeds
));
668 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
671 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
672 pfx_buf
, new_buf
, exist_buf
,
674 (exist_hops
+ exist_confeds
));
678 int newhops
= aspath_count_hops(newattr
->aspath
);
680 if (newhops
< exist_hops
) {
683 "%s: %s wins over %s due to aspath hopcount %d < %d",
684 pfx_buf
, new_buf
, exist_buf
,
685 newhops
, exist_hops
);
689 if (newhops
> exist_hops
) {
692 "%s: %s loses to %s due to aspath hopcount %d > %d",
693 pfx_buf
, new_buf
, exist_buf
,
694 newhops
, exist_hops
);
700 /* 5. Origin check. */
701 if (newattr
->origin
< existattr
->origin
) {
703 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
704 pfx_buf
, new_buf
, exist_buf
,
705 bgp_origin_long_str
[newattr
->origin
],
706 bgp_origin_long_str
[existattr
->origin
]);
710 if (newattr
->origin
> existattr
->origin
) {
712 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
713 pfx_buf
, new_buf
, exist_buf
,
714 bgp_origin_long_str
[newattr
->origin
],
715 bgp_origin_long_str
[existattr
->origin
]);
720 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
721 && aspath_count_hops(existattr
->aspath
) == 0);
722 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
723 && aspath_count_confeds(existattr
->aspath
) > 0
724 && aspath_count_hops(newattr
->aspath
) == 0
725 && aspath_count_hops(existattr
->aspath
) == 0);
727 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
728 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
729 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
730 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
731 || internal_as_route
) {
732 new_med
= bgp_med_value(new->attr
, bgp
);
733 exist_med
= bgp_med_value(exist
->attr
, bgp
);
735 if (new_med
< exist_med
) {
738 "%s: %s wins over %s due to MED %d < %d",
739 pfx_buf
, new_buf
, exist_buf
, new_med
,
744 if (new_med
> exist_med
) {
747 "%s: %s loses to %s due to MED %d > %d",
748 pfx_buf
, new_buf
, exist_buf
, new_med
,
754 /* 7. Peer type check. */
755 new_sort
= new->peer
->sort
;
756 exist_sort
= exist
->peer
->sort
;
758 if (new_sort
== BGP_PEER_EBGP
759 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
762 "%s: %s wins over %s due to eBGP peer > iBGP peer",
763 pfx_buf
, new_buf
, exist_buf
);
767 if (exist_sort
== BGP_PEER_EBGP
768 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
771 "%s: %s loses to %s due to iBGP peer < eBGP peer",
772 pfx_buf
, new_buf
, exist_buf
);
776 /* 8. IGP metric check. */
780 newm
= new->extra
->igpmetric
;
782 existm
= exist
->extra
->igpmetric
;
787 "%s: %s wins over %s due to IGP metric %d < %d",
788 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
795 "%s: %s loses to %s due to IGP metric %d > %d",
796 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
800 /* 9. Same IGP metric. Compare the cluster list length as
801 representative of IGP hops metric. Rewrite the metric value
802 pair (newm, existm) with the cluster list length. Prefer the
803 path with smaller cluster list length. */
804 if (newm
== existm
) {
805 if (peer_sort(new->peer
) == BGP_PEER_IBGP
806 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
807 && (mpath_cfg
== NULL
809 mpath_cfg
->ibgp_flags
,
810 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
811 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
812 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
817 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
818 pfx_buf
, new_buf
, exist_buf
,
826 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
827 pfx_buf
, new_buf
, exist_buf
,
834 /* 10. confed-external vs. confed-internal */
835 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
836 if (new_sort
== BGP_PEER_CONFED
837 && exist_sort
== BGP_PEER_IBGP
) {
840 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
841 pfx_buf
, new_buf
, exist_buf
);
845 if (exist_sort
== BGP_PEER_CONFED
846 && new_sort
== BGP_PEER_IBGP
) {
849 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
850 pfx_buf
, new_buf
, exist_buf
);
855 /* 11. Maximum path check. */
856 if (newm
== existm
) {
857 /* If one path has a label but the other does not, do not treat
858 * them as equals for multipath
860 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
[0]))
862 && bgp_is_valid_label(&exist
->extra
->label
[0]))) {
865 "%s: %s and %s cannot be multipath, one has a label while the other does not",
866 pfx_buf
, new_buf
, exist_buf
);
867 } else if (bgp_flag_check(bgp
,
868 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
871 * For the two paths, all comparison steps till IGP
873 * have succeeded - including AS_PATH hop count. Since
875 * bestpath as-path multipath-relax' knob is on, we
877 * an exact match of AS_PATH. Thus, mark the paths are
879 * That will trigger both these paths to get into the
887 "%s: %s and %s are equal via multipath-relax",
888 pfx_buf
, new_buf
, exist_buf
);
889 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
890 if (aspath_cmp(new->attr
->aspath
,
891 exist
->attr
->aspath
)) {
896 "%s: %s and %s are equal via matching aspaths",
897 pfx_buf
, new_buf
, exist_buf
);
899 } else if (new->peer
->as
== exist
->peer
->as
) {
904 "%s: %s and %s are equal via same remote-as",
905 pfx_buf
, new_buf
, exist_buf
);
909 * TODO: If unequal cost ibgp multipath is enabled we can
910 * mark the paths as equal here instead of returning
915 "%s: %s wins over %s after IGP metric comparison",
916 pfx_buf
, new_buf
, exist_buf
);
919 "%s: %s loses to %s after IGP metric comparison",
920 pfx_buf
, new_buf
, exist_buf
);
925 /* 12. If both paths are external, prefer the path that was received
926 first (the oldest one). This step minimizes route-flap, since a
927 newer path won't displace an older one, even if it was the
928 preferred route based on the additional decision criteria below. */
929 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
930 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
931 if (CHECK_FLAG(new->flags
, BGP_PATH_SELECTED
)) {
934 "%s: %s wins over %s due to oldest external",
935 pfx_buf
, new_buf
, exist_buf
);
939 if (CHECK_FLAG(exist
->flags
, BGP_PATH_SELECTED
)) {
942 "%s: %s loses to %s due to oldest external",
943 pfx_buf
, new_buf
, exist_buf
);
948 /* 13. Router-ID comparision. */
949 /* If one of the paths is "stale", the corresponding peer router-id will
950 * be 0 and would always win over the other path. If originator id is
951 * used for the comparision, it will decide which path is better.
953 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
954 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
956 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
957 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
958 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
960 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
962 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
965 "%s: %s wins over %s due to Router-ID comparison",
966 pfx_buf
, new_buf
, exist_buf
);
970 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
973 "%s: %s loses to %s due to Router-ID comparison",
974 pfx_buf
, new_buf
, exist_buf
);
978 /* 14. Cluster length comparision. */
979 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
980 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
982 if (new_cluster
< exist_cluster
) {
985 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
986 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
991 if (new_cluster
> exist_cluster
) {
994 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
995 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
1000 /* 15. Neighbor address comparision. */
1001 /* Do this only if neither path is "stale" as stale paths do not have
1002 * valid peer information (as the connection may or may not be up).
1004 if (CHECK_FLAG(exist
->flags
, BGP_PATH_STALE
)) {
1007 "%s: %s wins over %s due to latter path being STALE",
1008 pfx_buf
, new_buf
, exist_buf
);
1012 if (CHECK_FLAG(new->flags
, BGP_PATH_STALE
)) {
1015 "%s: %s loses to %s due to former path being STALE",
1016 pfx_buf
, new_buf
, exist_buf
);
1020 /* locally configured routes to advertise do not have su_remote */
1021 if (new->peer
->su_remote
== NULL
)
1023 if (exist
->peer
->su_remote
== NULL
)
1026 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
1031 "%s: %s loses to %s due to Neighor IP comparison",
1032 pfx_buf
, new_buf
, exist_buf
);
1039 "%s: %s wins over %s due to Neighor IP comparison",
1040 pfx_buf
, new_buf
, exist_buf
);
1045 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1046 pfx_buf
, new_buf
, exist_buf
);
1051 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1052 * is preferred, or 0 if they are the same (usually will only occur if
1053 * multipath is enabled
1054 * This version is compatible with */
1055 int bgp_path_info_cmp_compatible(struct bgp
*bgp
, struct bgp_path_info
*new,
1056 struct bgp_path_info
*exist
, char *pfx_buf
,
1057 afi_t afi
, safi_t safi
)
1061 ret
= bgp_path_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
,
1075 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
1076 struct attr
*attr
, afi_t afi
,
1079 struct bgp_filter
*filter
;
1081 filter
= &peer
->filter
[afi
][safi
];
1083 #define FILTER_EXIST_WARN(F, f, filter) \
1084 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1085 zlog_debug("%s: Could not find configured input %s-list %s!", \
1086 peer->host, #f, F##_IN_NAME(filter));
1088 if (DISTRIBUTE_IN_NAME(filter
)) {
1089 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1091 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1095 if (PREFIX_LIST_IN_NAME(filter
)) {
1096 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1098 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1102 if (FILTER_LIST_IN_NAME(filter
)) {
1103 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1105 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1110 return FILTER_PERMIT
;
1111 #undef FILTER_EXIST_WARN
1114 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1115 struct attr
*attr
, afi_t afi
,
1118 struct bgp_filter
*filter
;
1120 filter
= &peer
->filter
[afi
][safi
];
1122 #define FILTER_EXIST_WARN(F, f, filter) \
1123 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1124 zlog_debug("%s: Could not find configured output %s-list %s!", \
1125 peer->host, #f, F##_OUT_NAME(filter));
1127 if (DISTRIBUTE_OUT_NAME(filter
)) {
1128 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1130 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1134 if (PREFIX_LIST_OUT_NAME(filter
)) {
1135 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1137 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1142 if (FILTER_LIST_OUT_NAME(filter
)) {
1143 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1145 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1150 return FILTER_PERMIT
;
1151 #undef FILTER_EXIST_WARN
1154 /* If community attribute includes no_export then return 1. */
1155 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1157 if (attr
->community
) {
1158 /* NO_ADVERTISE check. */
1159 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1162 /* NO_EXPORT check. */
1163 if (peer
->sort
== BGP_PEER_EBGP
1164 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1167 /* NO_EXPORT_SUBCONFED check. */
1168 if (peer
->sort
== BGP_PEER_EBGP
1169 || peer
->sort
== BGP_PEER_CONFED
)
1170 if (community_include(attr
->community
,
1171 COMMUNITY_NO_EXPORT_SUBCONFED
))
1177 /* Route reflection loop check. */
1178 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1180 struct in_addr cluster_id
;
1182 if (attr
->cluster
) {
1183 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1184 cluster_id
= peer
->bgp
->cluster_id
;
1186 cluster_id
= peer
->bgp
->router_id
;
1188 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1194 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1195 struct attr
*attr
, afi_t afi
, safi_t safi
,
1196 const char *rmap_name
)
1198 struct bgp_filter
*filter
;
1199 struct bgp_path_info rmap_path
;
1200 route_map_result_t ret
;
1201 struct route_map
*rmap
= NULL
;
1203 filter
= &peer
->filter
[afi
][safi
];
1205 /* Apply default weight value. */
1206 if (peer
->weight
[afi
][safi
])
1207 attr
->weight
= peer
->weight
[afi
][safi
];
1210 rmap
= route_map_lookup_by_name(rmap_name
);
1215 if (ROUTE_MAP_IN_NAME(filter
)) {
1216 rmap
= ROUTE_MAP_IN(filter
);
1223 /* Route map apply. */
1225 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1226 /* Duplicate current value to new strucutre for modification. */
1227 rmap_path
.peer
= peer
;
1228 rmap_path
.attr
= attr
;
1230 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1232 /* Apply BGP route map to the attribute. */
1233 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1235 peer
->rmap_type
= 0;
1237 if (ret
== RMAP_DENYMATCH
)
1243 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1244 struct attr
*attr
, afi_t afi
, safi_t safi
,
1245 const char *rmap_name
)
1247 struct bgp_path_info rmap_path
;
1248 route_map_result_t ret
;
1249 struct route_map
*rmap
= NULL
;
1253 * So if we get to this point and have no rmap_name
1254 * we want to just show the output as it currently
1260 /* Apply default weight value. */
1261 if (peer
->weight
[afi
][safi
])
1262 attr
->weight
= peer
->weight
[afi
][safi
];
1264 rmap
= route_map_lookup_by_name(rmap_name
);
1267 * If we have a route map name and we do not find
1268 * the routemap that means we have an implicit
1274 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1275 /* Route map apply. */
1276 /* Duplicate current value to new strucutre for modification. */
1277 rmap_path
.peer
= peer
;
1278 rmap_path
.attr
= attr
;
1280 rmap_type
= peer
->rmap_type
;
1281 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1283 /* Apply BGP route map to the attribute. */
1284 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1286 peer
->rmap_type
= rmap_type
;
1288 if (ret
== RMAP_DENYMATCH
)
1290 * caller has multiple error paths with bgp_attr_flush()
1297 /* If this is an EBGP peer with remove-private-AS */
1298 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1299 struct peer
*peer
, struct attr
*attr
)
1301 if (peer
->sort
== BGP_PEER_EBGP
1302 && (peer_af_flag_check(peer
, afi
, safi
,
1303 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1304 || peer_af_flag_check(peer
, afi
, safi
,
1305 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1306 || peer_af_flag_check(peer
, afi
, safi
,
1307 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1308 || peer_af_flag_check(peer
, afi
, safi
,
1309 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1310 // Take action on the entire aspath
1311 if (peer_af_flag_check(peer
, afi
, safi
,
1312 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1313 || peer_af_flag_check(peer
, afi
, safi
,
1314 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1315 if (peer_af_flag_check(
1317 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1318 attr
->aspath
= aspath_replace_private_asns(
1319 attr
->aspath
, bgp
->as
);
1321 // The entire aspath consists of private ASNs so create
1323 else if (aspath_private_as_check(attr
->aspath
))
1324 attr
->aspath
= aspath_empty_get();
1326 // There are some public and some private ASNs, remove
1329 attr
->aspath
= aspath_remove_private_asns(
1333 // 'all' was not specified so the entire aspath must be private
1335 // for us to do anything
1336 else if (aspath_private_as_check(attr
->aspath
)) {
1337 if (peer_af_flag_check(
1339 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1340 attr
->aspath
= aspath_replace_private_asns(
1341 attr
->aspath
, bgp
->as
);
1343 attr
->aspath
= aspath_empty_get();
1348 /* If this is an EBGP peer with as-override */
1349 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1350 struct peer
*peer
, struct attr
*attr
)
1352 if (peer
->sort
== BGP_PEER_EBGP
1353 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1354 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1355 attr
->aspath
= aspath_replace_specific_asn(
1356 attr
->aspath
, peer
->as
, bgp
->as
);
1360 void bgp_attr_add_gshut_community(struct attr
*attr
)
1362 struct community
*old
;
1363 struct community
*new;
1364 struct community
*merge
;
1365 struct community
*gshut
;
1367 old
= attr
->community
;
1368 gshut
= community_str2com("graceful-shutdown");
1373 merge
= community_merge(community_dup(old
), gshut
);
1375 if (old
->refcnt
== 0)
1376 community_free(&old
);
1378 new = community_uniq_sort(merge
);
1379 community_free(&merge
);
1381 new = community_dup(gshut
);
1384 community_free(&gshut
);
1385 attr
->community
= new;
1386 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1388 /* When we add the graceful-shutdown community we must also
1389 * lower the local-preference */
1390 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1391 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1395 static void subgroup_announce_reset_nhop(uint8_t family
, struct attr
*attr
)
1397 if (family
== AF_INET
) {
1398 attr
->nexthop
.s_addr
= 0;
1399 attr
->mp_nexthop_global_in
.s_addr
= 0;
1401 if (family
== AF_INET6
)
1402 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1403 if (family
== AF_EVPN
)
1404 memset(&attr
->mp_nexthop_global_in
, 0, BGP_ATTR_NHLEN_IPV4
);
1407 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
1408 struct update_subgroup
*subgrp
, struct prefix
*p
,
1411 struct bgp_filter
*filter
;
1414 struct peer
*onlypeer
;
1416 struct attr
*piattr
;
1417 char buf
[PREFIX_STRLEN
];
1423 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1425 if (DISABLE_BGP_ANNOUNCE
)
1428 afi
= SUBGRP_AFI(subgrp
);
1429 safi
= SUBGRP_SAFI(subgrp
);
1430 peer
= SUBGRP_PEER(subgrp
);
1432 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1433 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1436 filter
= &peer
->filter
[afi
][safi
];
1437 bgp
= SUBGRP_INST(subgrp
);
1438 piattr
= bgp_path_info_mpath_count(pi
) ? bgp_path_info_mpath_attr(pi
)
1442 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1443 && ((pi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1444 || (pi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1447 * direct and direct_ext type routes originate internally even
1448 * though they can have peer pointers that reference other
1451 prefix2str(p
, buf
, PREFIX_STRLEN
);
1452 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1458 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
))
1459 && ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_UNICAST
))
1460 && (pi
->type
== ZEBRA_ROUTE_BGP
)
1461 && (pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
1463 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1468 /* With addpath we may be asked to TX all kinds of paths so make sure
1470 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
1471 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)
1472 || CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
1476 /* If this is not the bestpath then check to see if there is an enabled
1478 * feature that requires us to advertise it */
1479 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
1480 if (!bgp_addpath_tx_path(peer
->addpath_type
[afi
][safi
], pi
)) {
1485 /* Aggregate-address suppress check. */
1486 if (pi
->extra
&& pi
->extra
->suppress
)
1487 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1492 * If we are doing VRF 2 VRF leaking via the import
1493 * statement, we want to prevent the route going
1494 * off box as that the RT and RD created are localy
1495 * significant and globaly useless.
1497 if (safi
== SAFI_MPLS_VPN
&& pi
->extra
&& pi
->extra
->num_labels
1498 && pi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
1501 /* If it's labeled safi, make sure the route has a valid label. */
1502 if (safi
== SAFI_LABELED_UNICAST
) {
1503 mpls_label_t label
= bgp_adv_label(rn
, pi
, peer
, afi
, safi
);
1504 if (!bgp_is_valid_label(&label
)) {
1505 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1506 zlog_debug("u%" PRIu64
":s%" PRIu64
1507 " %s/%d is filtered - no label (%p)",
1508 subgrp
->update_group
->id
, subgrp
->id
,
1509 inet_ntop(p
->family
, &p
->u
.prefix
,
1510 buf
, SU_ADDRSTRLEN
),
1511 p
->prefixlen
, &label
);
1516 /* Do not send back route to sender. */
1517 if (onlypeer
&& from
== onlypeer
) {
1521 /* Do not send the default route in the BGP table if the neighbor is
1522 * configured for default-originate */
1523 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1524 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1525 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1527 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1531 /* Transparency check. */
1532 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1533 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1538 /* If community is not disabled check the no-export and local. */
1539 if (!transparent
&& bgp_community_filter(peer
, piattr
)) {
1540 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1542 "subgrpannouncecheck: community filter check fail");
1546 /* If the attribute has originator-id and it is same as remote
1548 if (onlypeer
&& piattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1549 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &piattr
->originator_id
))) {
1550 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1552 "%s [Update:SEND] %s originator-id is same as "
1555 prefix2str(p
, buf
, sizeof(buf
)));
1559 /* ORF prefix-list filter check */
1560 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1561 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1562 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1563 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1564 if (peer
->orf_plist
[afi
][safi
]) {
1565 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1567 if (bgp_debug_update(NULL
, p
,
1568 subgrp
->update_group
, 0))
1570 "%s [Update:SEND] %s is filtered via ORF",
1578 /* Output filter check. */
1579 if (bgp_output_filter(peer
, p
, piattr
, afi
, safi
) == FILTER_DENY
) {
1580 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1581 zlog_debug("%s [Update:SEND] %s is filtered",
1582 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1586 #ifdef BGP_SEND_ASPATH_CHECK
1587 /* AS path loop check. */
1588 if (onlypeer
&& aspath_loop_check(piattr
->aspath
, onlypeer
->as
)) {
1589 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1591 "%s [Update:SEND] suppress announcement to peer AS %u "
1592 "that is part of AS path.",
1593 onlypeer
->host
, onlypeer
->as
);
1596 #endif /* BGP_SEND_ASPATH_CHECK */
1598 /* If we're a CONFED we need to loop check the CONFED ID too */
1599 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1600 if (aspath_loop_check(piattr
->aspath
, bgp
->confed_id
)) {
1601 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1603 "%s [Update:SEND] suppress announcement to peer AS %u"
1605 peer
->host
, bgp
->confed_id
);
1610 /* Route-Reflect check. */
1611 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1616 /* IBGP reflection check. */
1617 if (reflect
&& !samepeer_safe
) {
1618 /* A route from a Client peer. */
1619 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1620 PEER_FLAG_REFLECTOR_CLIENT
)) {
1621 /* Reflect to all the Non-Client peers and also to the
1622 Client peers other than the originator. Originator
1624 is already done. So there is noting to do. */
1625 /* no bgp client-to-client reflection check. */
1626 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1627 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1628 PEER_FLAG_REFLECTOR_CLIENT
))
1631 /* A route from a Non-client peer. Reflect to all other
1633 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1634 PEER_FLAG_REFLECTOR_CLIENT
))
1639 /* For modify attribute, copy it to temporary structure. */
1640 bgp_attr_dup(attr
, piattr
);
1642 /* If local-preference is not set. */
1643 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1644 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1645 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1646 attr
->local_pref
= bgp
->default_local_pref
;
1649 /* If originator-id is not set and the route is to be reflected,
1650 set the originator id */
1652 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1653 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1654 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1657 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1659 if (peer
->sort
== BGP_PEER_EBGP
1660 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1661 if (from
!= bgp
->peer_self
&& !transparent
1662 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1663 PEER_FLAG_MED_UNCHANGED
))
1665 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1668 /* Since the nexthop attribute can vary per peer, it is not explicitly
1670 * in announce check, only certain flags and length (or number of
1672 * -- for IPv6/MP_REACH) are set here in order to guide the update
1674 * code in setting the nexthop(s) on a per peer basis in
1676 * Typically, the source nexthop in the attribute is preserved but in
1678 * scenarios where we know it will always be overwritten, we reset the
1679 * nexthop to "0" in an attempt to achieve better Update packing. An
1680 * example of this is when a prefix from each of 2 IBGP peers needs to
1682 * announced to an EBGP peer (and they have the same attributes barring
1686 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1688 #define NEXTHOP_IS_V6 \
1689 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1690 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1691 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1692 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1694 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1696 * the peer (group) is configured to receive link-local nexthop
1698 * and it is available in the prefix OR we're not reflecting the route
1700 * the peer (group) to whom we're going to announce is on a shared
1702 * and this is either a self-originated route or the peer is EBGP.
1704 if (NEXTHOP_IS_V6
) {
1705 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1706 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1707 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1708 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1709 || (!reflect
&& peer
->shared_network
1710 && (from
== bgp
->peer_self
1711 || peer
->sort
== BGP_PEER_EBGP
))) {
1712 attr
->mp_nexthop_len
=
1713 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1716 /* Clear off link-local nexthop in source, whenever it is not
1718 * ensure more prefixes share the same attribute for
1721 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1722 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1723 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1726 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1727 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1729 /* Route map & unsuppress-map apply. */
1730 if (ROUTE_MAP_OUT_NAME(filter
) || (pi
->extra
&& pi
->extra
->suppress
)) {
1731 struct bgp_path_info rmap_path
;
1732 struct bgp_path_info_extra dummy_rmap_path_extra
;
1733 struct attr dummy_attr
;
1735 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1736 rmap_path
.peer
= peer
;
1737 rmap_path
.attr
= attr
;
1740 memcpy(&dummy_rmap_path_extra
, pi
->extra
,
1741 sizeof(struct bgp_path_info_extra
));
1742 rmap_path
.extra
= &dummy_rmap_path_extra
;
1745 /* don't confuse inbound and outbound setting */
1746 RESET_FLAG(attr
->rmap_change_flags
);
1749 * The route reflector is not allowed to modify the attributes
1750 * of the reflected IBGP routes unless explicitly allowed.
1752 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1753 && !bgp_flag_check(bgp
,
1754 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1755 bgp_attr_dup(&dummy_attr
, attr
);
1756 rmap_path
.attr
= &dummy_attr
;
1759 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1761 if (pi
->extra
&& pi
->extra
->suppress
)
1762 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1763 RMAP_BGP
, &rmap_path
);
1765 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1766 RMAP_BGP
, &rmap_path
);
1768 peer
->rmap_type
= 0;
1770 if (ret
== RMAP_DENYMATCH
) {
1771 bgp_attr_flush(attr
);
1776 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1777 if (peer
->sort
== BGP_PEER_IBGP
1778 || peer
->sort
== BGP_PEER_CONFED
) {
1779 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1780 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1782 bgp_attr_add_gshut_community(attr
);
1786 /* After route-map has been applied, we check to see if the nexthop to
1787 * be carried in the attribute (that is used for the announcement) can
1788 * be cleared off or not. We do this in all cases where we would be
1789 * setting the nexthop to "ourselves". For IPv6, we only need to
1791 * the global nexthop here; the link-local nexthop would have been
1793 * already, and if not, it is required by the update formation code.
1794 * Also see earlier comments in this function.
1797 * If route-map has performed some operation on the nexthop or the peer
1798 * configuration says to pass it unchanged, we cannot reset the nexthop
1799 * here, so only attempt to do it if these aren't true. Note that the
1800 * route-map handler itself might have cleared the nexthop, if for
1802 * it is configured as 'peer-address'.
1804 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1805 piattr
->rmap_change_flags
)
1807 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1808 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1809 /* We can reset the nexthop, if setting (or forcing) it to
1811 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1812 PEER_FLAG_NEXTHOP_SELF
)
1813 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1814 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1816 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1817 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1818 subgroup_announce_reset_nhop(
1819 (peer_cap_enhe(peer
, afi
, safi
)
1823 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1824 /* Can also reset the nexthop if announcing to EBGP, but
1826 * no peer in the subgroup is on a shared subnet.
1827 * Note: 3rd party nexthop currently implemented for
1830 if (!bgp_subgrp_multiaccess_check_v4(piattr
->nexthop
,
1832 subgroup_announce_reset_nhop(
1833 (peer_cap_enhe(peer
, afi
, safi
)
1837 } else if (CHECK_FLAG(pi
->flags
, BGP_PATH_ANNC_NH_SELF
)) {
1839 * This flag is used for leaked vpn-vrf routes
1841 int family
= p
->family
;
1843 if (peer_cap_enhe(peer
, afi
, safi
))
1846 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1848 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
1849 __func__
, family2str(family
));
1850 subgroup_announce_reset_nhop(family
, attr
);
1853 /* If IPv6/MP and nexthop does not have any override and happens
1855 * be a link-local address, reset it so that we don't pass along
1857 * source's link-local IPv6 address to recipients who may not be
1859 * the same interface.
1861 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1862 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1863 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1870 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1871 struct bgp_maxpaths_cfg
*mpath_cfg
,
1872 struct bgp_path_info_pair
*result
, afi_t afi
,
1875 struct bgp_path_info
*new_select
;
1876 struct bgp_path_info
*old_select
;
1877 struct bgp_path_info
*pi
;
1878 struct bgp_path_info
*pi1
;
1879 struct bgp_path_info
*pi2
;
1880 struct bgp_path_info
*nextpi
= NULL
;
1881 int paths_eq
, do_mpath
, debug
;
1882 struct list mp_list
;
1883 char pfx_buf
[PREFIX2STR_BUFFER
];
1884 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1886 bgp_mp_list_init(&mp_list
);
1888 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1890 debug
= bgp_debug_bestpath(&rn
->p
);
1893 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1895 /* bgp deterministic-med */
1897 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1899 /* Clear BGP_PATH_DMED_SELECTED for all paths */
1900 for (pi1
= bgp_node_get_bgp_path_info(rn
); pi1
;
1902 bgp_path_info_unset_flag(rn
, pi1
,
1903 BGP_PATH_DMED_SELECTED
);
1905 for (pi1
= bgp_node_get_bgp_path_info(rn
); pi1
;
1907 if (CHECK_FLAG(pi1
->flags
, BGP_PATH_DMED_CHECK
))
1909 if (BGP_PATH_HOLDDOWN(pi1
))
1911 if (pi1
->peer
&& pi1
->peer
!= bgp
->peer_self
)
1912 if (pi1
->peer
->status
!= Established
)
1917 for (pi2
= pi1
->next
; pi2
; pi2
= pi2
->next
) {
1918 if (CHECK_FLAG(pi2
->flags
,
1919 BGP_PATH_DMED_CHECK
))
1921 if (BGP_PATH_HOLDDOWN(pi2
))
1924 && pi2
->peer
!= bgp
->peer_self
1927 PEER_STATUS_NSF_WAIT
))
1928 if (pi2
->peer
->status
1932 if (!aspath_cmp_left(pi1
->attr
->aspath
,
1934 && !aspath_cmp_left_confed(
1939 if (bgp_path_info_cmp(
1940 bgp
, pi2
, new_select
,
1941 &paths_eq
, mpath_cfg
, debug
,
1942 pfx_buf
, afi
, safi
)) {
1943 bgp_path_info_unset_flag(
1945 BGP_PATH_DMED_SELECTED
);
1949 bgp_path_info_set_flag(
1950 rn
, pi2
, BGP_PATH_DMED_CHECK
);
1953 bgp_path_info_set_flag(rn
, new_select
,
1954 BGP_PATH_DMED_CHECK
);
1955 bgp_path_info_set_flag(rn
, new_select
,
1956 BGP_PATH_DMED_SELECTED
);
1959 bgp_path_info_path_with_addpath_rx_str(
1960 new_select
, path_buf
);
1961 zlog_debug("%s: %s is the bestpath from AS %u",
1963 aspath_get_first_as(
1964 new_select
->attr
->aspath
));
1969 /* Check old selected route and new selected route. */
1972 for (pi
= bgp_node_get_bgp_path_info(rn
);
1973 (pi
!= NULL
) && (nextpi
= pi
->next
, 1); pi
= nextpi
) {
1974 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
))
1977 if (BGP_PATH_HOLDDOWN(pi
)) {
1978 /* reap REMOVED routes, if needs be
1979 * selected route must stay for a while longer though
1981 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
1982 && (pi
!= old_select
))
1983 bgp_path_info_reap(rn
, pi
);
1986 zlog_debug("%s: pi %p in holddown", __func__
,
1992 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
1993 && !CHECK_FLAG(pi
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1994 if (pi
->peer
->status
!= Established
) {
1998 "%s: pi %p non self peer %s not estab state",
1999 __func__
, pi
, pi
->peer
->host
);
2004 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
2005 && (!CHECK_FLAG(pi
->flags
, BGP_PATH_DMED_SELECTED
))) {
2006 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2008 zlog_debug("%s: pi %p dmed", __func__
, pi
);
2012 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2014 if (bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
, mpath_cfg
,
2015 debug
, pfx_buf
, afi
, safi
)) {
2020 /* Now that we know which path is the bestpath see if any of the other
2022 * qualify as multipaths
2026 bgp_path_info_path_with_addpath_rx_str(new_select
,
2029 sprintf(path_buf
, "NONE");
2031 "%s: After path selection, newbest is %s oldbest was %s",
2033 old_select
? old_select
->peer
->host
: "NONE");
2036 if (do_mpath
&& new_select
) {
2037 for (pi
= bgp_node_get_bgp_path_info(rn
);
2038 (pi
!= NULL
) && (nextpi
= pi
->next
, 1); pi
= nextpi
) {
2041 bgp_path_info_path_with_addpath_rx_str(
2044 if (pi
== new_select
) {
2047 "%s: %s is the bestpath, add to the multipath list",
2049 bgp_mp_list_add(&mp_list
, pi
);
2053 if (BGP_PATH_HOLDDOWN(pi
))
2056 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
2057 && !CHECK_FLAG(pi
->peer
->sflags
,
2058 PEER_STATUS_NSF_WAIT
))
2059 if (pi
->peer
->status
!= Established
)
2062 if (!bgp_path_info_nexthop_cmp(pi
, new_select
)) {
2065 "%s: %s has the same nexthop as the bestpath, skip it",
2070 bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
,
2071 mpath_cfg
, debug
, pfx_buf
, afi
, safi
);
2076 "%s: %s is equivalent to the bestpath, add to the multipath list",
2078 bgp_mp_list_add(&mp_list
, pi
);
2083 bgp_path_info_mpath_update(rn
, new_select
, old_select
, &mp_list
,
2085 bgp_path_info_mpath_aggregate_update(new_select
, old_select
);
2086 bgp_mp_list_clear(&mp_list
);
2088 bgp_addpath_update_ids(bgp
, rn
, afi
, safi
);
2090 result
->old
= old_select
;
2091 result
->new = new_select
;
2097 * A new route/change in bestpath of an existing route. Evaluate the path
2098 * for advertisement to the subgroup.
2100 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
2101 struct bgp_path_info
*selected
,
2102 struct bgp_node
*rn
,
2103 uint32_t addpath_tx_id
)
2106 struct peer
*onlypeer
;
2112 afi
= SUBGRP_AFI(subgrp
);
2113 safi
= SUBGRP_SAFI(subgrp
);
2114 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
2117 if (BGP_DEBUG(update
, UPDATE_OUT
)) {
2118 char buf_prefix
[PREFIX_STRLEN
];
2119 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
2120 zlog_debug("%s: p=%s, selected=%p", __func__
, buf_prefix
,
2124 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2125 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
2126 PEER_STATUS_ORF_WAIT_REFRESH
))
2129 memset(&attr
, 0, sizeof(struct attr
));
2130 /* It's initialized in bgp_announce_check() */
2132 /* Announcement to the subgroup. If the route is filtered withdraw it.
2135 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
2136 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
2138 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
2142 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2144 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
2151 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2152 * This is called at the end of route processing.
2154 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2156 struct bgp_path_info
*pi
;
2158 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
2159 if (BGP_PATH_HOLDDOWN(pi
))
2161 UNSET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2162 UNSET_FLAG(pi
->flags
, BGP_PATH_ATTR_CHANGED
);
2167 * Has the route changed from the RIB's perspective? This is invoked only
2168 * if the route selection returns the same best route as earlier - to
2169 * determine if we need to update zebra or not.
2171 int bgp_zebra_has_route_changed(struct bgp_node
*rn
,
2172 struct bgp_path_info
*selected
)
2174 struct bgp_path_info
*mpinfo
;
2176 /* If this is multipath, check all selected paths for any nexthop
2177 * change or attribute change. Some attribute changes (e.g., community)
2178 * aren't of relevance to the RIB, but we'll update zebra to ensure
2179 * we handle the case of BGP nexthop change. This is the behavior
2180 * when the best path has an attribute change anyway.
2182 if (CHECK_FLAG(selected
->flags
, BGP_PATH_IGP_CHANGED
)
2183 || CHECK_FLAG(selected
->flags
, BGP_PATH_MULTIPATH_CHG
))
2187 * If this is multipath, check all selected paths for any nexthop change
2189 for (mpinfo
= bgp_path_info_mpath_first(selected
); mpinfo
;
2190 mpinfo
= bgp_path_info_mpath_next(mpinfo
)) {
2191 if (CHECK_FLAG(mpinfo
->flags
, BGP_PATH_IGP_CHANGED
)
2192 || CHECK_FLAG(mpinfo
->flags
, BGP_PATH_ATTR_CHANGED
))
2196 /* Nothing has changed from the RIB's perspective. */
2200 struct bgp_process_queue
{
2202 STAILQ_HEAD(, bgp_node
) pqueue
;
2203 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2205 unsigned int queued
;
2209 * old_select = The old best path
2210 * new_select = the new best path
2212 * if (!old_select && new_select)
2213 * We are sending new information on.
2215 * if (old_select && new_select) {
2216 * if (new_select != old_select)
2217 * We have a new best path send a change
2219 * We've received a update with new attributes that needs
2223 * if (old_select && !new_select)
2224 * We have no eligible route that we can announce or the rn
2227 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2228 afi_t afi
, safi_t safi
)
2230 struct bgp_path_info
*new_select
;
2231 struct bgp_path_info
*old_select
;
2232 struct bgp_path_info_pair old_and_new
;
2233 char pfx_buf
[PREFIX2STR_BUFFER
];
2236 /* Is it end of initial update? (after startup) */
2238 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2239 sizeof(bgp
->update_delay_zebra_resume_time
));
2241 bgp
->main_zebra_update_hold
= 0;
2242 FOREACH_AFI_SAFI (afi
, safi
) {
2243 if (bgp_fibupd_safi(safi
))
2244 bgp_zebra_announce_table(bgp
, afi
, safi
);
2246 bgp
->main_peers_update_hold
= 0;
2248 bgp_start_routeadv(bgp
);
2252 struct prefix
*p
= &rn
->p
;
2254 debug
= bgp_debug_bestpath(&rn
->p
);
2256 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2257 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2258 afi2str(afi
), safi2str(safi
));
2261 /* Best path selection. */
2262 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2264 old_select
= old_and_new
.old
;
2265 new_select
= old_and_new
.new;
2267 /* Do we need to allocate or free labels?
2268 * Right now, since we only deal with per-prefix labels, it is not
2269 * necessary to do this upon changes to best path. Exceptions:
2270 * - label index has changed -> recalculate resulting label
2271 * - path_info sub_type changed -> switch to/from implicit-null
2272 * - no valid label (due to removed static label binding) -> get new one
2274 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2277 || bgp_label_index_differs(new_select
, old_select
)
2278 || new_select
->sub_type
!= old_select
->sub_type
2279 || !bgp_is_valid_label(&rn
->local_label
)) {
2280 /* Enforced penultimate hop popping:
2281 * implicit-null for local routes, aggregate
2282 * and redistributed routes
2284 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2285 || new_select
->sub_type
2286 == BGP_ROUTE_AGGREGATE
2287 || new_select
->sub_type
2288 == BGP_ROUTE_REDISTRIBUTE
) {
2291 BGP_NODE_REGISTERED_FOR_LABEL
))
2292 bgp_unregister_for_label(rn
);
2293 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2295 bgp_set_valid_label(&rn
->local_label
);
2297 bgp_register_for_label(rn
, new_select
);
2299 } else if (CHECK_FLAG(rn
->flags
,
2300 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2301 bgp_unregister_for_label(rn
);
2303 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2304 bgp_unregister_for_label(rn
);
2308 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2310 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2311 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2312 old_select
, new_select
);
2315 /* If best route remains the same and this is not due to user-initiated
2316 * clear, see exactly what needs to be done.
2318 if (old_select
&& old_select
== new_select
2319 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2320 && !CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2321 && !bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
2322 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2324 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2325 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2327 if (bgp_fibupd_safi(safi
)
2328 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2330 if (new_select
->type
== ZEBRA_ROUTE_BGP
2331 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2332 || new_select
->sub_type
2333 == BGP_ROUTE_IMPORTED
))
2335 bgp_zebra_announce(rn
, p
, old_select
,
2339 UNSET_FLAG(old_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2340 bgp_zebra_clear_route_change_flags(rn
);
2342 /* If there is a change of interest to peers, reannounce the
2344 if (CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2345 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2346 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2348 /* unicast routes must also be annouced to
2349 * labeled-unicast update-groups */
2350 if (safi
== SAFI_UNICAST
)
2351 group_announce_route(bgp
, afi
,
2352 SAFI_LABELED_UNICAST
, rn
,
2355 UNSET_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
);
2356 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2359 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2363 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2365 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2367 /* bestpath has changed; bump version */
2368 if (old_select
|| new_select
) {
2369 bgp_bump_version(rn
);
2371 if (!bgp
->t_rmap_def_originate_eval
) {
2375 update_group_refresh_default_originate_route_map
,
2376 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2377 &bgp
->t_rmap_def_originate_eval
);
2382 bgp_path_info_unset_flag(rn
, old_select
, BGP_PATH_SELECTED
);
2385 zlog_debug("%s: setting SELECTED flag", __func__
);
2386 bgp_path_info_set_flag(rn
, new_select
, BGP_PATH_SELECTED
);
2387 bgp_path_info_unset_flag(rn
, new_select
, BGP_PATH_ATTR_CHANGED
);
2388 UNSET_FLAG(new_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2392 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2393 if (old_select
!= new_select
) {
2395 vnc_import_bgp_exterior_del_route(bgp
, p
,
2397 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2400 vnc_import_bgp_exterior_add_route(bgp
, p
,
2402 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2408 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2410 /* unicast routes must also be annouced to labeled-unicast update-groups
2412 if (safi
== SAFI_UNICAST
)
2413 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2417 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2418 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2419 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2420 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2421 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2422 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
)) {
2424 /* if this is an evpn imported type-5 prefix,
2425 * we need to withdraw the route first to clear
2426 * the nh neigh and the RMAC entry.
2429 is_route_parent_evpn(old_select
))
2430 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2432 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2434 /* Withdraw the route from the kernel. */
2435 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2436 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2437 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2438 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2440 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2444 /* advertise/withdraw type-5 routes */
2445 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2446 if (advertise_type5_routes(bgp
, afi
) && new_select
&&
2447 (!new_select
->extra
|| !new_select
->extra
->parent
)) {
2449 /* apply the route-map */
2450 if (bgp
->adv_cmd_rmap
[afi
][safi
].map
) {
2453 ret
= route_map_apply(
2454 bgp
->adv_cmd_rmap
[afi
][safi
].map
,
2455 &rn
->p
, RMAP_BGP
, new_select
);
2456 if (ret
== RMAP_MATCH
)
2457 bgp_evpn_advertise_type5_route(
2458 bgp
, &rn
->p
, new_select
->attr
,
2461 bgp_evpn_advertise_type5_route(bgp
,
2467 } else if (advertise_type5_routes(bgp
, afi
) && old_select
&&
2468 (!old_select
->extra
|| !old_select
->extra
->parent
))
2469 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2472 /* Clear any route change flags. */
2473 bgp_zebra_clear_route_change_flags(rn
);
2475 /* Reap old select bgp_path_info, if it has been removed */
2476 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_PATH_REMOVED
))
2477 bgp_path_info_reap(rn
, old_select
);
2479 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2483 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2485 struct bgp_process_queue
*pqnode
= data
;
2486 struct bgp
*bgp
= pqnode
->bgp
;
2487 struct bgp_table
*table
;
2488 struct bgp_node
*rn
;
2491 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2492 bgp_process_main_one(bgp
, NULL
, 0, 0);
2493 /* should always have dedicated wq call */
2494 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2498 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2499 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2500 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2501 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2502 table
= bgp_node_table(rn
);
2503 /* note, new RNs may be added as part of processing */
2504 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2506 bgp_unlock_node(rn
);
2507 bgp_table_unlock(table
);
2513 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2515 struct bgp_process_queue
*pqnode
= data
;
2517 bgp_unlock(pqnode
->bgp
);
2519 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2522 void bgp_process_queue_init(void)
2524 if (!bm
->process_main_queue
)
2525 bm
->process_main_queue
=
2526 work_queue_new(bm
->master
, "process_main_queue");
2528 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2529 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2530 bm
->process_main_queue
->spec
.max_retries
= 0;
2531 bm
->process_main_queue
->spec
.hold
= 50;
2532 /* Use a higher yield value of 50ms for main queue processing */
2533 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2536 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2538 struct bgp_process_queue
*pqnode
;
2540 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2541 sizeof(struct bgp_process_queue
));
2543 /* unlocked in bgp_processq_del */
2544 pqnode
->bgp
= bgp_lock(bgp
);
2545 STAILQ_INIT(&pqnode
->pqueue
);
2550 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2552 #define ARBITRARY_PROCESS_QLEN 10000
2553 struct work_queue
*wq
= bm
->process_main_queue
;
2554 struct bgp_process_queue
*pqnode
;
2555 int pqnode_reuse
= 0;
2557 /* already scheduled for processing? */
2558 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2564 /* Add route nodes to an existing work queue item until reaching the
2565 limit only if is from the same BGP view and it's not an EOIU marker
2567 if (work_queue_item_count(wq
)) {
2568 struct work_queue_item
*item
= work_queue_last_item(wq
);
2569 pqnode
= item
->data
;
2571 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2572 || pqnode
->bgp
!= bgp
2573 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2574 pqnode
= bgp_processq_alloc(bgp
);
2578 pqnode
= bgp_processq_alloc(bgp
);
2579 /* all unlocked in bgp_process_wq */
2580 bgp_table_lock(bgp_node_table(rn
));
2582 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2585 /* can't be enqueued twice */
2586 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2587 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2591 work_queue_add(wq
, pqnode
);
2596 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2598 struct bgp_process_queue
*pqnode
;
2600 if (bm
->process_main_queue
== NULL
)
2603 pqnode
= bgp_processq_alloc(bgp
);
2605 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2606 work_queue_add(bm
->process_main_queue
, pqnode
);
2609 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2613 peer
= THREAD_ARG(thread
);
2614 peer
->t_pmax_restart
= NULL
;
2616 if (bgp_debug_neighbor_events(peer
))
2618 "%s Maximum-prefix restart timer expired, restore peering",
2621 if ((peer_clear(peer
, NULL
) < 0) && bgp_debug_neighbor_events(peer
))
2622 zlog_debug("%s: %s peer_clear failed",
2623 __PRETTY_FUNCTION__
, peer
->host
);
2628 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2632 iana_safi_t pkt_safi
;
2634 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2637 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2638 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2639 PEER_STATUS_PREFIX_LIMIT
)
2644 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2646 afi_safi_print(afi
, safi
), peer
->host
,
2647 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2648 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2650 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2651 PEER_FLAG_MAX_PREFIX_WARNING
))
2654 /* Convert AFI, SAFI to values for packet. */
2655 pkt_afi
= afi_int2iana(afi
);
2656 pkt_safi
= safi_int2iana(safi
);
2660 ndata
[0] = (pkt_afi
>> 8);
2662 ndata
[2] = pkt_safi
;
2663 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2664 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2665 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2666 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2668 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2669 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2670 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2674 /* Dynamic peers will just close their connection. */
2675 if (peer_dynamic_neighbor(peer
))
2678 /* restart timer start */
2679 if (peer
->pmax_restart
[afi
][safi
]) {
2680 peer
->v_pmax_restart
=
2681 peer
->pmax_restart
[afi
][safi
] * 60;
2683 if (bgp_debug_neighbor_events(peer
))
2685 "%s Maximum-prefix restart timer started for %d secs",
2686 peer
->host
, peer
->v_pmax_restart
);
2688 BGP_TIMER_ON(peer
->t_pmax_restart
,
2689 bgp_maximum_prefix_restart_timer
,
2690 peer
->v_pmax_restart
);
2695 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2696 PEER_STATUS_PREFIX_LIMIT
);
2698 if (peer
->pcount
[afi
][safi
]
2699 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2700 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2701 PEER_STATUS_PREFIX_THRESHOLD
)
2706 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2707 afi_safi_print(afi
, safi
), peer
->host
,
2708 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2709 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2710 PEER_STATUS_PREFIX_THRESHOLD
);
2712 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2713 PEER_STATUS_PREFIX_THRESHOLD
);
2717 /* Unconditionally remove the route from the RIB, without taking
2718 * damping into consideration (eg, because the session went down)
2720 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2721 struct peer
*peer
, afi_t afi
, safi_t safi
)
2723 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
, safi
);
2725 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
2726 bgp_path_info_delete(rn
, pi
); /* keep historical info */
2728 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2731 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2732 struct peer
*peer
, afi_t afi
, safi_t safi
,
2733 struct prefix_rd
*prd
)
2735 /* apply dampening, if result is suppressed, we'll be retaining
2736 * the bgp_path_info in the RIB for historical reference.
2738 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2739 && peer
->sort
== BGP_PEER_EBGP
)
2740 if ((bgp_damp_withdraw(pi
, rn
, afi
, safi
, 0))
2741 == BGP_DAMP_SUPPRESSED
) {
2742 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
,
2748 if (safi
== SAFI_MPLS_VPN
) {
2749 struct bgp_node
*prn
= NULL
;
2750 struct bgp_table
*table
= NULL
;
2752 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2753 (struct prefix
*)prd
);
2754 if (bgp_node_has_bgp_path_info_data(prn
)) {
2755 table
= bgp_node_get_bgp_table_info(prn
);
2757 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2758 peer
->bgp
, prd
, table
, &rn
->p
, pi
);
2760 bgp_unlock_node(prn
);
2762 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2763 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
2765 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, pi
);
2766 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2772 /* If this is an EVPN route, process for un-import. */
2773 if (safi
== SAFI_EVPN
)
2774 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, pi
);
2776 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
2779 struct bgp_path_info
*info_make(int type
, int sub_type
, unsigned short instance
,
2780 struct peer
*peer
, struct attr
*attr
,
2781 struct bgp_node
*rn
)
2783 struct bgp_path_info
*new;
2785 /* Make new BGP info. */
2786 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_path_info
));
2788 new->instance
= instance
;
2789 new->sub_type
= sub_type
;
2792 new->uptime
= bgp_clock();
2797 static void overlay_index_update(struct attr
*attr
,
2798 struct eth_segment_id
*eth_s_id
,
2799 union gw_addr
*gw_ip
)
2804 if (eth_s_id
== NULL
) {
2805 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2806 sizeof(struct eth_segment_id
));
2808 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2809 sizeof(struct eth_segment_id
));
2811 if (gw_ip
== NULL
) {
2812 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2814 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2815 sizeof(union gw_addr
));
2819 static bool overlay_index_equal(afi_t afi
, struct bgp_path_info
*path
,
2820 struct eth_segment_id
*eth_s_id
,
2821 union gw_addr
*gw_ip
)
2823 struct eth_segment_id
*path_eth_s_id
, *path_eth_s_id_remote
;
2824 union gw_addr
*path_gw_ip
, *path_gw_ip_remote
;
2826 struct eth_segment_id esi
;
2830 if (afi
!= AFI_L2VPN
)
2833 memset(&temp
, 0, sizeof(temp
));
2834 path_eth_s_id
= &temp
.esi
;
2835 path_gw_ip
= &temp
.ip
;
2837 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2840 path_eth_s_id
= &(path
->attr
->evpn_overlay
.eth_s_id
);
2841 path_gw_ip
= &(path
->attr
->evpn_overlay
.gw_ip
);
2844 if (gw_ip
== NULL
) {
2845 memset(&temp
, 0, sizeof(temp
));
2846 path_gw_ip_remote
= &temp
.ip
;
2848 path_gw_ip_remote
= gw_ip
;
2850 if (eth_s_id
== NULL
) {
2851 memset(&temp
, 0, sizeof(temp
));
2852 path_eth_s_id_remote
= &temp
.esi
;
2854 path_eth_s_id_remote
= eth_s_id
;
2856 if (!memcmp(path_gw_ip
, path_gw_ip_remote
, sizeof(union gw_addr
)))
2859 return !memcmp(path_eth_s_id
, path_eth_s_id_remote
,
2860 sizeof(struct eth_segment_id
));
2863 /* Check if received nexthop is valid or not. */
2864 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2869 /* Only validated for unicast and multicast currently. */
2870 /* Also valid for EVPN where the nexthop is an IP address. */
2871 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2874 /* If NEXT_HOP is present, validate it. */
2875 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2876 if (attr
->nexthop
.s_addr
== 0
2877 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2878 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2882 /* If MP_NEXTHOP is present, validate it. */
2883 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2884 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2885 * it is not an IPv6 link-local address.
2887 if (attr
->mp_nexthop_len
) {
2888 switch (attr
->mp_nexthop_len
) {
2889 case BGP_ATTR_NHLEN_IPV4
:
2890 case BGP_ATTR_NHLEN_VPNV4
:
2891 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2892 || IPV4_CLASS_DE(ntohl(
2893 attr
->mp_nexthop_global_in
.s_addr
))
2894 || bgp_nexthop_self(bgp
,
2895 attr
->mp_nexthop_global_in
));
2898 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2899 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2900 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2901 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2902 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2903 || IN6_IS_ADDR_MULTICAST(
2904 &attr
->mp_nexthop_global
));
2916 int bgp_update(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
2917 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2918 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2919 uint32_t num_labels
, int soft_reconfig
,
2920 struct bgp_route_evpn
*evpn
)
2923 int aspath_loop_count
= 0;
2924 struct bgp_node
*rn
;
2926 struct attr new_attr
;
2927 struct attr
*attr_new
;
2928 struct bgp_path_info
*pi
;
2929 struct bgp_path_info
*new;
2930 struct bgp_path_info_extra
*extra
;
2932 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2934 int do_loop_check
= 1;
2935 int has_valid_label
= 0;
2937 int vnc_implicit_withdraw
= 0;
2941 memset(&new_attr
, 0, sizeof(struct attr
));
2942 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2943 new_attr
.label
= MPLS_INVALID_LABEL
;
2946 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2947 /* TODO: Check to see if we can get rid of "is_valid_label" */
2948 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
2949 has_valid_label
= (num_labels
> 0) ? 1 : 0;
2951 has_valid_label
= bgp_is_valid_label(label
);
2953 /* When peer's soft reconfiguration enabled. Record input packet in
2956 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2957 && peer
!= bgp
->peer_self
)
2958 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2960 /* Check previously received route. */
2961 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
2962 if (pi
->peer
== peer
&& pi
->type
== type
2963 && pi
->sub_type
== sub_type
2964 && pi
->addpath_rx_id
== addpath_id
)
2967 /* AS path local-as loop check. */
2968 if (peer
->change_local_as
) {
2969 if (peer
->allowas_in
[afi
][safi
])
2970 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
2971 else if (!CHECK_FLAG(peer
->flags
,
2972 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2973 aspath_loop_count
= 1;
2975 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2976 > aspath_loop_count
) {
2977 reason
= "as-path contains our own AS;";
2982 /* If the peer is configured for "allowas-in origin" and the last ASN in
2984 * as-path is our ASN then we do not need to call aspath_loop_check
2986 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2987 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2990 /* AS path loop check. */
2991 if (do_loop_check
) {
2992 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2993 > peer
->allowas_in
[afi
][safi
]
2994 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2995 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2996 > peer
->allowas_in
[afi
][safi
])) {
2997 reason
= "as-path contains our own AS;";
3002 /* Route reflector originator ID check. */
3003 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
3004 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
3005 reason
= "originator is us;";
3009 /* Route reflector cluster ID check. */
3010 if (bgp_cluster_filter(peer
, attr
)) {
3011 reason
= "reflected from the same cluster;";
3015 /* Apply incoming filter. */
3016 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
3021 bgp_attr_dup(&new_attr
, attr
);
3023 /* Apply incoming route-map.
3024 * NB: new_attr may now contain newly allocated values from route-map
3026 * commands, so we need bgp_attr_flush in the error paths, until we
3028 * the attr (which takes over the memory references) */
3029 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
3031 reason
= "route-map;";
3032 bgp_attr_flush(&new_attr
);
3036 if (peer
->sort
== BGP_PEER_EBGP
) {
3038 /* If we receive the graceful-shutdown community from an eBGP
3039 * peer we must lower local-preference */
3040 if (new_attr
.community
3041 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
3042 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
3043 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
3045 /* If graceful-shutdown is configured then add the GSHUT
3046 * community to all paths received from eBGP peers */
3047 } else if (bgp_flag_check(peer
->bgp
,
3048 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
3049 bgp_attr_add_gshut_community(&new_attr
);
3053 /* next hop check. */
3054 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
3055 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
3056 reason
= "martian or self next-hop;";
3057 bgp_attr_flush(&new_attr
);
3061 if (bgp_mac_entry_exists(p
)) {
3062 reason
= "self mac;";
3066 attr_new
= bgp_attr_intern(&new_attr
);
3068 /* If the update is implicit withdraw. */
3070 pi
->uptime
= bgp_clock();
3071 same_attr
= attrhash_cmp(pi
->attr
, attr_new
);
3073 /* Same attribute comes in. */
3074 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
3075 && attrhash_cmp(pi
->attr
, attr_new
)
3076 && (!has_valid_label
3077 || memcmp(&(bgp_path_info_extra_get(pi
))->label
, label
,
3078 num_labels
* sizeof(mpls_label_t
))
3080 && (overlay_index_equal(
3081 afi
, pi
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3082 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
3083 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
3084 BGP_CONFIG_DAMPENING
)
3085 && peer
->sort
== BGP_PEER_EBGP
3086 && CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3087 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3088 bgp_debug_rdpfxpath2str(
3089 afi
, safi
, prd
, p
, label
,
3090 num_labels
, addpath_id
? 1 : 0,
3091 addpath_id
, pfx_buf
,
3093 zlog_debug("%s rcvd %s", peer
->host
,
3097 if (bgp_damp_update(pi
, rn
, afi
, safi
)
3098 != BGP_DAMP_SUPPRESSED
) {
3099 bgp_aggregate_increment(bgp
, p
, pi
, afi
,
3101 bgp_process(bgp
, rn
, afi
, safi
);
3103 } else /* Duplicate - odd */
3105 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3106 if (!peer
->rcvd_attr_printed
) {
3108 "%s rcvd UPDATE w/ attr: %s",
3110 peer
->rcvd_attr_str
);
3111 peer
->rcvd_attr_printed
= 1;
3114 bgp_debug_rdpfxpath2str(
3115 afi
, safi
, prd
, p
, label
,
3116 num_labels
, addpath_id
? 1 : 0,
3117 addpath_id
, pfx_buf
,
3120 "%s rcvd %s...duplicate ignored",
3121 peer
->host
, pfx_buf
);
3124 /* graceful restart STALE flag unset. */
3125 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)) {
3126 bgp_path_info_unset_flag(
3127 rn
, pi
, BGP_PATH_STALE
);
3128 bgp_process(bgp
, rn
, afi
, safi
);
3132 bgp_unlock_node(rn
);
3133 bgp_attr_unintern(&attr_new
);
3138 /* Withdraw/Announce before we fully processed the withdraw */
3139 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
3140 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3141 bgp_debug_rdpfxpath2str(
3142 afi
, safi
, prd
, p
, label
, num_labels
,
3143 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3146 "%s rcvd %s, flapped quicker than processing",
3147 peer
->host
, pfx_buf
);
3150 bgp_path_info_restore(rn
, pi
);
3153 /* Received Logging. */
3154 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3155 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3156 num_labels
, addpath_id
? 1 : 0,
3157 addpath_id
, pfx_buf
,
3159 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3162 /* graceful restart STALE flag unset. */
3163 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
3164 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_STALE
);
3166 /* The attribute is changed. */
3167 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
3169 /* implicit withdraw, decrement aggregate and pcount here.
3170 * only if update is accepted, they'll increment below.
3172 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
3174 /* Update bgp route dampening information. */
3175 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3176 && peer
->sort
== BGP_PEER_EBGP
) {
3177 /* This is implicit withdraw so we should update
3180 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
3181 bgp_damp_withdraw(pi
, rn
, afi
, safi
, 1);
3184 if (safi
== SAFI_MPLS_VPN
) {
3185 struct bgp_node
*prn
= NULL
;
3186 struct bgp_table
*table
= NULL
;
3188 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3189 (struct prefix
*)prd
);
3190 if (bgp_node_has_bgp_path_info_data(prn
)) {
3191 table
= bgp_node_get_bgp_table_info(prn
);
3193 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3194 bgp
, prd
, table
, p
, pi
);
3196 bgp_unlock_node(prn
);
3198 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3199 && (safi
== SAFI_UNICAST
)) {
3200 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
3202 * Implicit withdraw case.
3204 ++vnc_implicit_withdraw
;
3205 vnc_import_bgp_del_route(bgp
, p
, pi
);
3206 vnc_import_bgp_exterior_del_route(bgp
, p
, pi
);
3211 /* Special handling for EVPN update of an existing route. If the
3212 * extended community attribute has changed, we need to
3214 * the route using its existing extended community. It will be
3215 * subsequently processed for import with the new extended
3218 if (safi
== SAFI_EVPN
&& !same_attr
) {
3220 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3222 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3225 cmp
= ecommunity_cmp(pi
->attr
->ecommunity
,
3226 attr_new
->ecommunity
);
3228 if (bgp_debug_update(peer
, p
, NULL
, 1))
3230 "Change in EXT-COMM, existing %s new %s",
3232 pi
->attr
->ecommunity
),
3234 attr_new
->ecommunity
));
3235 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3241 /* Update to new attribute. */
3242 bgp_attr_unintern(&pi
->attr
);
3243 pi
->attr
= attr_new
;
3245 /* Update MPLS label */
3246 if (has_valid_label
) {
3247 extra
= bgp_path_info_extra_get(pi
);
3248 memcpy(&extra
->label
, label
,
3249 num_labels
* sizeof(mpls_label_t
));
3250 extra
->num_labels
= num_labels
;
3251 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3252 bgp_set_valid_label(&extra
->label
[0]);
3256 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3257 && (safi
== SAFI_UNICAST
)) {
3258 if (vnc_implicit_withdraw
) {
3260 * Add back the route with its new attributes
3262 * The route is still selected, until the route
3264 * queued by bgp_process actually runs. We have
3266 * update to the VNC side immediately to avoid
3268 * configuration changes (e.g., route-map
3270 * trigger re-importation of the entire RIB.
3272 vnc_import_bgp_add_route(bgp
, p
, pi
);
3273 vnc_import_bgp_exterior_add_route(bgp
, p
, pi
);
3277 /* Update Overlay Index */
3278 if (afi
== AFI_L2VPN
) {
3279 overlay_index_update(
3280 pi
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3281 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3284 /* Update bgp route dampening information. */
3285 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3286 && peer
->sort
== BGP_PEER_EBGP
) {
3287 /* Now we do normal update dampening. */
3288 ret
= bgp_damp_update(pi
, rn
, afi
, safi
);
3289 if (ret
== BGP_DAMP_SUPPRESSED
) {
3290 bgp_unlock_node(rn
);
3295 /* Nexthop reachability check - for unicast and
3296 * labeled-unicast.. */
3297 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3298 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3299 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3300 && !CHECK_FLAG(peer
->flags
,
3301 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3303 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3308 struct bgp
*bgp_nexthop
= bgp
;
3310 if (pi
->extra
&& pi
->extra
->bgp_orig
)
3311 bgp_nexthop
= pi
->extra
->bgp_orig
;
3313 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, pi
,
3315 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3316 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3318 if (BGP_DEBUG(nht
, NHT
)) {
3319 char buf1
[INET6_ADDRSTRLEN
];
3321 (const void *)&attr_new
3323 buf1
, INET6_ADDRSTRLEN
);
3324 zlog_debug("%s(%s): NH unresolved",
3325 __FUNCTION__
, buf1
);
3327 bgp_path_info_unset_flag(rn
, pi
,
3331 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3334 if (safi
== SAFI_MPLS_VPN
) {
3335 struct bgp_node
*prn
= NULL
;
3336 struct bgp_table
*table
= NULL
;
3338 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3339 (struct prefix
*)prd
);
3340 if (bgp_node_has_bgp_path_info_data(prn
)) {
3341 table
= bgp_node_get_bgp_table_info(prn
);
3343 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3344 bgp
, prd
, table
, p
, pi
);
3346 bgp_unlock_node(prn
);
3350 /* If this is an EVPN route and some attribute has changed,
3352 * route for import. If the extended community has changed, we
3354 * have done the un-import earlier and the import would result
3356 * route getting injected into appropriate L2 VNIs. If it is
3358 * some other attribute change, the import will result in
3360 * the attributes for the route in the VNI(s).
3362 if (safi
== SAFI_EVPN
&& !same_attr
)
3363 bgp_evpn_import_route(bgp
, afi
, safi
, p
, pi
);
3365 /* Process change. */
3366 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
3368 bgp_process(bgp
, rn
, afi
, safi
);
3369 bgp_unlock_node(rn
);
3371 if (SAFI_UNICAST
== safi
3372 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3373 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3375 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, pi
);
3377 if ((SAFI_MPLS_VPN
== safi
)
3378 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3380 vpn_leak_to_vrf_update(bgp
, pi
);
3384 if (SAFI_MPLS_VPN
== safi
) {
3385 mpls_label_t label_decoded
= decode_label(label
);
3387 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3388 type
, sub_type
, &label_decoded
);
3390 if (SAFI_ENCAP
== safi
) {
3391 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3392 type
, sub_type
, NULL
);
3397 } // End of implicit withdraw
3399 /* Received Logging. */
3400 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3401 if (!peer
->rcvd_attr_printed
) {
3402 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3403 peer
->rcvd_attr_str
);
3404 peer
->rcvd_attr_printed
= 1;
3407 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3408 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3410 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3413 /* Make new BGP info. */
3414 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3416 /* Update MPLS label */
3417 if (has_valid_label
) {
3418 extra
= bgp_path_info_extra_get(new);
3419 memcpy(&extra
->label
, label
, num_labels
* sizeof(mpls_label_t
));
3420 extra
->num_labels
= num_labels
;
3421 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3422 bgp_set_valid_label(&extra
->label
[0]);
3425 /* Update Overlay Index */
3426 if (afi
== AFI_L2VPN
) {
3427 overlay_index_update(new->attr
,
3428 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3429 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3431 /* Nexthop reachability check. */
3432 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3433 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3434 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3435 && !CHECK_FLAG(peer
->flags
,
3436 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3437 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3442 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, connected
)
3443 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3444 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3446 if (BGP_DEBUG(nht
, NHT
)) {
3447 char buf1
[INET6_ADDRSTRLEN
];
3449 (const void *)&attr_new
->nexthop
,
3450 buf1
, INET6_ADDRSTRLEN
);
3451 zlog_debug("%s(%s): NH unresolved",
3452 __FUNCTION__
, buf1
);
3454 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
3457 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3460 new->addpath_rx_id
= addpath_id
;
3462 /* Increment prefix */
3463 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3465 /* Register new BGP information. */
3466 bgp_path_info_add(rn
, new);
3468 /* route_node_get lock */
3469 bgp_unlock_node(rn
);
3472 if (safi
== SAFI_MPLS_VPN
) {
3473 struct bgp_node
*prn
= NULL
;
3474 struct bgp_table
*table
= NULL
;
3476 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3477 if (bgp_node_has_bgp_path_info_data(prn
)) {
3478 table
= bgp_node_get_bgp_table_info(prn
);
3480 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3481 bgp
, prd
, table
, p
, new);
3483 bgp_unlock_node(prn
);
3487 /* If maximum prefix count is configured and current prefix
3489 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3492 /* If this is an EVPN route, process for import. */
3493 if (safi
== SAFI_EVPN
)
3494 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3496 /* Process change. */
3497 bgp_process(bgp
, rn
, afi
, safi
);
3499 if (SAFI_UNICAST
== safi
3500 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3501 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3502 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3504 if ((SAFI_MPLS_VPN
== safi
)
3505 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3507 vpn_leak_to_vrf_update(bgp
, new);
3510 if (SAFI_MPLS_VPN
== safi
) {
3511 mpls_label_t label_decoded
= decode_label(label
);
3513 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3514 sub_type
, &label_decoded
);
3516 if (SAFI_ENCAP
== safi
) {
3517 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3524 /* This BGP update is filtered. Log the reason then update BGP
3527 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3528 if (!peer
->rcvd_attr_printed
) {
3529 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3530 peer
->rcvd_attr_str
);
3531 peer
->rcvd_attr_printed
= 1;
3534 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3535 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3537 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3538 peer
->host
, pfx_buf
, reason
);
3542 /* If this is an EVPN route, un-import it as it is now filtered.
3544 if (safi
== SAFI_EVPN
)
3545 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, pi
);
3547 if (SAFI_UNICAST
== safi
3548 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3549 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3551 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3553 if ((SAFI_MPLS_VPN
== safi
)
3554 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3556 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3559 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3562 bgp_unlock_node(rn
);
3566 * Filtered update is treated as an implicit withdrawal (see
3568 * a few lines above)
3570 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3571 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3579 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
3580 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3581 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3582 uint32_t num_labels
, struct bgp_route_evpn
*evpn
)
3585 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3586 struct bgp_node
*rn
;
3587 struct bgp_path_info
*pi
;
3590 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3591 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3599 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3601 /* If peer is soft reconfiguration enabled. Record input packet for
3602 * further calculation.
3604 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3605 * routes that are filtered. This tanks out Quagga RS pretty badly due
3607 * the iteration over all RS clients.
3608 * Since we need to remove the entry from adj_in anyway, do that first
3610 * if there was no entry, we don't need to do anything more.
3612 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3613 && peer
!= bgp
->peer_self
)
3614 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3615 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3616 bgp_debug_rdpfxpath2str(
3617 afi
, safi
, prd
, p
, label
, num_labels
,
3618 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3621 "%s withdrawing route %s not in adj-in",
3622 peer
->host
, pfx_buf
);
3624 bgp_unlock_node(rn
);
3628 /* Lookup withdrawn route. */
3629 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
3630 if (pi
->peer
== peer
&& pi
->type
== type
3631 && pi
->sub_type
== sub_type
3632 && pi
->addpath_rx_id
== addpath_id
)
3636 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3637 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3638 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3640 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3644 /* Withdraw specified route from routing table. */
3645 if (pi
&& !CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3646 bgp_rib_withdraw(rn
, pi
, peer
, afi
, safi
, prd
);
3647 if (SAFI_UNICAST
== safi
3648 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3649 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3650 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3652 if ((SAFI_MPLS_VPN
== safi
)
3653 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3655 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3657 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3658 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3659 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3661 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3664 /* Unlock bgp_node_get() lock. */
3665 bgp_unlock_node(rn
);
3670 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3673 struct update_subgroup
*subgrp
;
3674 subgrp
= peer_subgroup(peer
, afi
, safi
);
3675 subgroup_default_originate(subgrp
, withdraw
);
3680 * bgp_stop_announce_route_timer
3682 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3684 if (!paf
->t_announce_route
)
3687 THREAD_TIMER_OFF(paf
->t_announce_route
);
3691 * bgp_announce_route_timer_expired
3693 * Callback that is invoked when the route announcement timer for a
3696 static int bgp_announce_route_timer_expired(struct thread
*t
)
3698 struct peer_af
*paf
;
3701 paf
= THREAD_ARG(t
);
3704 if (peer
->status
!= Established
)
3707 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3710 peer_af_announce_route(paf
, 1);
3715 * bgp_announce_route
3717 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3719 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3721 struct peer_af
*paf
;
3722 struct update_subgroup
*subgrp
;
3724 paf
= peer_af_find(peer
, afi
, safi
);
3727 subgrp
= PAF_SUBGRP(paf
);
3730 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3731 * or a refresh has already been triggered.
3733 if (!subgrp
|| paf
->t_announce_route
)
3737 * Start a timer to stagger/delay the announce. This serves
3738 * two purposes - announcement can potentially be combined for
3739 * multiple peers and the announcement doesn't happen in the
3742 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3743 (subgrp
->peer_count
== 1)
3744 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3745 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3746 &paf
->t_announce_route
);
3750 * Announce routes from all AF tables to a peer.
3752 * This should ONLY be called when there is a need to refresh the
3753 * routes to the peer based on a policy change for this peer alone
3754 * or a route refresh request received from the peer.
3755 * The operation will result in splitting the peer from its existing
3756 * subgroups and putting it in new subgroups.
3758 void bgp_announce_route_all(struct peer
*peer
)
3763 FOREACH_AFI_SAFI (afi
, safi
)
3764 bgp_announce_route(peer
, afi
, safi
);
3767 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3768 struct bgp_table
*table
,
3769 struct prefix_rd
*prd
)
3772 struct bgp_node
*rn
;
3773 struct bgp_adj_in
*ain
;
3776 table
= peer
->bgp
->rib
[afi
][safi
];
3778 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3779 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3780 if (ain
->peer
!= peer
)
3783 struct bgp_path_info
*pi
=
3784 bgp_node_get_bgp_path_info(rn
);
3785 uint32_t num_labels
= 0;
3786 mpls_label_t
*label_pnt
= NULL
;
3787 struct bgp_route_evpn evpn
;
3789 if (pi
&& pi
->extra
)
3790 num_labels
= pi
->extra
->num_labels
;
3792 label_pnt
= &pi
->extra
->label
[0];
3794 memcpy(&evpn
, &pi
->attr
->evpn_overlay
,
3797 memset(&evpn
, 0, sizeof(evpn
));
3799 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3800 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3801 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3802 num_labels
, 1, &evpn
);
3805 bgp_unlock_node(rn
);
3811 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3813 struct bgp_node
*rn
;
3814 struct bgp_table
*table
;
3816 if (peer
->status
!= Established
)
3819 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3820 && (safi
!= SAFI_EVPN
))
3821 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3823 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3824 rn
= bgp_route_next(rn
)) {
3825 table
= bgp_node_get_bgp_table_info(rn
);
3826 if (table
!= NULL
) {
3827 struct prefix_rd prd
;
3829 prd
.family
= AF_UNSPEC
;
3831 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3833 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3840 struct bgp_clear_node_queue
{
3841 struct bgp_node
*rn
;
3844 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3846 struct bgp_clear_node_queue
*cnq
= data
;
3847 struct bgp_node
*rn
= cnq
->rn
;
3848 struct peer
*peer
= wq
->spec
.data
;
3849 struct bgp_path_info
*pi
;
3851 afi_t afi
= bgp_node_table(rn
)->afi
;
3852 safi_t safi
= bgp_node_table(rn
)->safi
;
3857 /* It is possible that we have multiple paths for a prefix from a peer
3858 * if that peer is using AddPath.
3860 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
3861 if (pi
->peer
!= peer
)
3864 /* graceful restart STALE flag set. */
3865 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3866 && peer
->nsf
[afi
][safi
]
3867 && !CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)
3868 && !CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
3869 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_STALE
);
3871 /* If this is an EVPN route, process for
3873 if (safi
== SAFI_EVPN
)
3874 bgp_evpn_unimport_route(bgp
, afi
, safi
, &rn
->p
,
3876 /* Handle withdraw for VRF route-leaking and L3VPN */
3877 if (SAFI_UNICAST
== safi
3878 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
||
3879 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3880 vpn_leak_from_vrf_withdraw(bgp_get_default(),
3883 if (SAFI_MPLS_VPN
== safi
&&
3884 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3885 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3888 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3894 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3896 struct bgp_clear_node_queue
*cnq
= data
;
3897 struct bgp_node
*rn
= cnq
->rn
;
3898 struct bgp_table
*table
= bgp_node_table(rn
);
3900 bgp_unlock_node(rn
);
3901 bgp_table_unlock(table
);
3902 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3905 static void bgp_clear_node_complete(struct work_queue
*wq
)
3907 struct peer
*peer
= wq
->spec
.data
;
3909 /* Tickle FSM to start moving again */
3910 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3912 peer_unlock(peer
); /* bgp_clear_route */
3915 static void bgp_clear_node_queue_init(struct peer
*peer
)
3917 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3919 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3920 #undef CLEAR_QUEUE_NAME_LEN
3922 peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
);
3923 peer
->clear_node_queue
->spec
.hold
= 10;
3924 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3925 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3926 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3927 peer
->clear_node_queue
->spec
.max_retries
= 0;
3929 /* we only 'lock' this peer reference when the queue is actually active
3931 peer
->clear_node_queue
->spec
.data
= peer
;
3934 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3935 struct bgp_table
*table
)
3937 struct bgp_node
*rn
;
3938 int force
= bm
->process_main_queue
? 0 : 1;
3941 table
= peer
->bgp
->rib
[afi
][safi
];
3943 /* If still no table => afi/safi isn't configured at all or smth. */
3947 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3948 struct bgp_path_info
*pi
, *next
;
3949 struct bgp_adj_in
*ain
;
3950 struct bgp_adj_in
*ain_next
;
3952 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3953 * queued for every clearing peer, regardless of whether it is
3954 * relevant to the peer at hand.
3956 * Overview: There are 3 different indices which need to be
3957 * scrubbed, potentially, when a peer is removed:
3959 * 1 peer's routes visible via the RIB (ie accepted routes)
3960 * 2 peer's routes visible by the (optional) peer's adj-in index
3961 * 3 other routes visible by the peer's adj-out index
3963 * 3 there is no hurry in scrubbing, once the struct peer is
3964 * removed from bgp->peer, we could just GC such deleted peer's
3965 * adj-outs at our leisure.
3967 * 1 and 2 must be 'scrubbed' in some way, at least made
3968 * invisible via RIB index before peer session is allowed to be
3969 * brought back up. So one needs to know when such a 'search' is
3974 * - there'd be a single global queue or a single RIB walker
3975 * - rather than tracking which route_nodes still need to be
3976 * examined on a peer basis, we'd track which peers still
3979 * Given that our per-peer prefix-counts now should be reliable,
3980 * this may actually be achievable. It doesn't seem to be a huge
3981 * problem at this time,
3983 * It is possible that we have multiple paths for a prefix from
3985 * if that peer is using AddPath.
3989 ain_next
= ain
->next
;
3991 if (ain
->peer
== peer
) {
3992 bgp_adj_in_remove(rn
, ain
);
3993 bgp_unlock_node(rn
);
3999 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= next
) {
4001 if (pi
->peer
!= peer
)
4005 bgp_path_info_reap(rn
, pi
);
4007 struct bgp_clear_node_queue
*cnq
;
4009 /* both unlocked in bgp_clear_node_queue_del */
4010 bgp_table_lock(bgp_node_table(rn
));
4013 MTYPE_BGP_CLEAR_NODE_QUEUE
,
4014 sizeof(struct bgp_clear_node_queue
));
4016 work_queue_add(peer
->clear_node_queue
, cnq
);
4024 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4026 struct bgp_node
*rn
;
4027 struct bgp_table
*table
;
4029 if (peer
->clear_node_queue
== NULL
)
4030 bgp_clear_node_queue_init(peer
);
4032 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4033 * Idle until it receives a Clearing_Completed event. This protects
4034 * against peers which flap faster than we can we clear, which could
4037 * a) race with routes from the new session being installed before
4038 * clear_route_node visits the node (to delete the route of that
4040 * b) resource exhaustion, clear_route_node likely leads to an entry
4041 * on the process_main queue. Fast-flapping could cause that queue
4045 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4046 * the unlock will happen upon work-queue completion; other wise, the
4047 * unlock happens at the end of this function.
4049 if (!peer
->clear_node_queue
->thread
)
4052 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
4053 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
4055 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4056 rn
= bgp_route_next(rn
)) {
4057 table
= bgp_node_get_bgp_table_info(rn
);
4061 bgp_clear_route_table(peer
, afi
, safi
, table
);
4064 /* unlock if no nodes got added to the clear-node-queue. */
4065 if (!peer
->clear_node_queue
->thread
)
4069 void bgp_clear_route_all(struct peer
*peer
)
4074 FOREACH_AFI_SAFI (afi
, safi
)
4075 bgp_clear_route(peer
, afi
, safi
);
4078 rfapiProcessPeerDown(peer
);
4082 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
4084 struct bgp_table
*table
;
4085 struct bgp_node
*rn
;
4086 struct bgp_adj_in
*ain
;
4087 struct bgp_adj_in
*ain_next
;
4089 table
= peer
->bgp
->rib
[afi
][safi
];
4091 /* It is possible that we have multiple paths for a prefix from a peer
4092 * if that peer is using AddPath.
4094 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4098 ain_next
= ain
->next
;
4100 if (ain
->peer
== peer
) {
4101 bgp_adj_in_remove(rn
, ain
);
4102 bgp_unlock_node(rn
);
4110 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4112 struct bgp_node
*rn
;
4113 struct bgp_path_info
*pi
;
4114 struct bgp_table
*table
;
4116 if (safi
== SAFI_MPLS_VPN
) {
4117 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4118 rn
= bgp_route_next(rn
)) {
4119 struct bgp_node
*rm
;
4121 /* look for neighbor in tables */
4122 table
= bgp_node_get_bgp_table_info(rn
);
4126 for (rm
= bgp_table_top(table
); rm
;
4127 rm
= bgp_route_next(rm
))
4128 for (pi
= bgp_node_get_bgp_path_info(rm
); pi
;
4130 if (pi
->peer
!= peer
)
4132 if (!CHECK_FLAG(pi
->flags
,
4136 bgp_rib_remove(rm
, pi
, peer
, afi
, safi
);
4141 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4142 rn
= bgp_route_next(rn
))
4143 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
;
4145 if (pi
->peer
!= peer
)
4147 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
4149 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
4155 static void bgp_cleanup_table(struct bgp
*bgp
, struct bgp_table
*table
,
4158 struct bgp_node
*rn
;
4159 struct bgp_path_info
*pi
;
4160 struct bgp_path_info
*next
;
4162 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
4163 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= next
) {
4165 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)
4166 && pi
->type
== ZEBRA_ROUTE_BGP
4167 && (pi
->sub_type
== BGP_ROUTE_NORMAL
4168 || pi
->sub_type
== BGP_ROUTE_AGGREGATE
4169 || pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
4171 if (bgp_fibupd_safi(safi
))
4172 bgp_zebra_withdraw(&rn
->p
, pi
, bgp
,
4174 bgp_path_info_reap(rn
, pi
);
4179 /* Delete all kernel routes. */
4180 void bgp_cleanup_routes(struct bgp
*bgp
)
4183 struct bgp_node
*rn
;
4184 struct bgp_table
*table
;
4186 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4187 if (afi
== AFI_L2VPN
)
4189 bgp_cleanup_table(bgp
, bgp
->rib
[afi
][SAFI_UNICAST
],
4192 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4194 if (afi
!= AFI_L2VPN
) {
4196 safi
= SAFI_MPLS_VPN
;
4197 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4198 rn
= bgp_route_next(rn
)) {
4199 table
= bgp_node_get_bgp_table_info(rn
);
4200 if (table
!= NULL
) {
4201 bgp_cleanup_table(bgp
, table
, safi
);
4202 bgp_table_finish(&table
);
4203 bgp_node_set_bgp_table_info(rn
, NULL
);
4204 bgp_unlock_node(rn
);
4208 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4209 rn
= bgp_route_next(rn
)) {
4210 table
= bgp_node_get_bgp_table_info(rn
);
4211 if (table
!= NULL
) {
4212 bgp_cleanup_table(bgp
, table
, safi
);
4213 bgp_table_finish(&table
);
4214 bgp_node_set_bgp_table_info(rn
, NULL
);
4215 bgp_unlock_node(rn
);
4220 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4221 rn
= bgp_route_next(rn
)) {
4222 table
= bgp_node_get_bgp_table_info(rn
);
4223 if (table
!= NULL
) {
4224 bgp_cleanup_table(bgp
, table
, SAFI_EVPN
);
4225 bgp_table_finish(&table
);
4226 bgp_node_set_bgp_table_info(rn
, NULL
);
4227 bgp_unlock_node(rn
);
4232 void bgp_reset(void)
4235 bgp_zclient_reset();
4236 access_list_reset();
4237 prefix_list_reset();
4240 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4242 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4243 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4244 PEER_CAP_ADDPATH_AF_TX_RCV
));
4247 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4249 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4250 struct bgp_nlri
*packet
)
4259 int addpath_encoded
;
4260 uint32_t addpath_id
;
4263 lim
= pnt
+ packet
->length
;
4265 safi
= packet
->safi
;
4267 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4269 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4270 syntactic validity. If the field is syntactically incorrect,
4271 then the Error Subcode is set to Invalid Network Field. */
4272 for (; pnt
< lim
; pnt
+= psize
) {
4273 /* Clear prefix structure. */
4274 memset(&p
, 0, sizeof(struct prefix
));
4276 if (addpath_encoded
) {
4278 /* When packet overflow occurs return immediately. */
4279 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4282 addpath_id
= ntohl(*((uint32_t *)pnt
));
4283 pnt
+= BGP_ADDPATH_ID_LEN
;
4286 /* Fetch prefix length. */
4287 p
.prefixlen
= *pnt
++;
4288 /* afi/safi validity already verified by caller,
4289 * bgp_update_receive */
4290 p
.family
= afi2family(afi
);
4292 /* Prefix length check. */
4293 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4296 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4297 peer
->host
, p
.prefixlen
, packet
->afi
);
4301 /* Packet size overflow check. */
4302 psize
= PSIZE(p
.prefixlen
);
4304 /* When packet overflow occur return immediately. */
4305 if (pnt
+ psize
> lim
) {
4308 "%s [Error] Update packet error (prefix length %d overflows packet)",
4309 peer
->host
, p
.prefixlen
);
4313 /* Defensive coding, double-check the psize fits in a struct
4315 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4318 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4319 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4323 /* Fetch prefix from NLRI packet. */
4324 memcpy(p
.u
.val
, pnt
, psize
);
4326 /* Check address. */
4327 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4328 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4329 /* From RFC4271 Section 6.3:
4331 * If a prefix in the NLRI field is semantically
4333 * (e.g., an unexpected multicast IP address),
4335 * be logged locally, and the prefix SHOULD be
4340 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4341 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4346 /* Check address. */
4347 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4348 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4353 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4355 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4360 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4365 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4367 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4374 /* Normal process. */
4376 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4377 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4378 NULL
, NULL
, 0, 0, NULL
);
4380 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4381 safi
, ZEBRA_ROUTE_BGP
,
4382 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4385 /* Address family configuration mismatch or maximum-prefix count
4391 /* Packet length consistency check. */
4395 "%s [Error] Update packet error (prefix length mismatch with total length)",
4403 static struct bgp_static
*bgp_static_new(void)
4405 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4408 static void bgp_static_free(struct bgp_static
*bgp_static
)
4410 if (bgp_static
->rmap
.name
)
4411 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4412 if (bgp_static
->eth_s_id
)
4413 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4414 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4417 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4418 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4420 struct bgp_node
*rn
;
4421 struct bgp_path_info
*pi
;
4422 struct bgp_path_info
*new;
4423 struct bgp_path_info rmap_path
;
4425 struct attr
*attr_new
;
4428 int vnc_implicit_withdraw
= 0;
4435 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4437 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4439 attr
.nexthop
= bgp_static
->igpnexthop
;
4440 attr
.med
= bgp_static
->igpmetric
;
4441 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4443 if (bgp_static
->atomic
)
4444 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4446 /* Store label index, if required. */
4447 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4448 attr
.label_index
= bgp_static
->label_index
;
4449 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4452 /* Apply route-map. */
4453 if (bgp_static
->rmap
.name
) {
4454 struct attr attr_tmp
= attr
;
4456 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
4457 rmap_path
.peer
= bgp
->peer_self
;
4458 rmap_path
.attr
= &attr_tmp
;
4460 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4462 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4465 bgp
->peer_self
->rmap_type
= 0;
4467 if (ret
== RMAP_DENYMATCH
) {
4468 /* Free uninterned attribute. */
4469 bgp_attr_flush(&attr_tmp
);
4471 /* Unintern original. */
4472 aspath_unintern(&attr
.aspath
);
4473 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4477 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4478 bgp_attr_add_gshut_community(&attr_tmp
);
4480 attr_new
= bgp_attr_intern(&attr_tmp
);
4483 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4484 bgp_attr_add_gshut_community(&attr
);
4486 attr_new
= bgp_attr_intern(&attr
);
4489 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4490 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4491 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4495 if (attrhash_cmp(pi
->attr
, attr_new
)
4496 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
4497 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4498 bgp_unlock_node(rn
);
4499 bgp_attr_unintern(&attr_new
);
4500 aspath_unintern(&attr
.aspath
);
4503 /* The attribute is changed. */
4504 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4506 /* Rewrite BGP route information. */
4507 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4508 bgp_path_info_restore(rn
, pi
);
4510 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4512 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4513 && (safi
== SAFI_UNICAST
)) {
4514 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
4516 * Implicit withdraw case.
4517 * We have to do this before pi is
4520 ++vnc_implicit_withdraw
;
4521 vnc_import_bgp_del_route(bgp
, p
, pi
);
4522 vnc_import_bgp_exterior_del_route(
4527 bgp_attr_unintern(&pi
->attr
);
4528 pi
->attr
= attr_new
;
4529 pi
->uptime
= bgp_clock();
4531 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4532 && (safi
== SAFI_UNICAST
)) {
4533 if (vnc_implicit_withdraw
) {
4534 vnc_import_bgp_add_route(bgp
, p
, pi
);
4535 vnc_import_bgp_exterior_add_route(
4541 /* Nexthop reachability check. */
4542 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4543 && (safi
== SAFI_UNICAST
4544 || safi
== SAFI_LABELED_UNICAST
)) {
4546 struct bgp
*bgp_nexthop
= bgp
;
4548 if (pi
->extra
&& pi
->extra
->bgp_orig
)
4549 bgp_nexthop
= pi
->extra
->bgp_orig
;
4551 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
4553 bgp_path_info_set_flag(rn
, pi
,
4556 if (BGP_DEBUG(nht
, NHT
)) {
4557 char buf1
[INET6_ADDRSTRLEN
];
4558 inet_ntop(p
->family
,
4562 "%s(%s): Route not in table, not advertising",
4563 __FUNCTION__
, buf1
);
4565 bgp_path_info_unset_flag(
4566 rn
, pi
, BGP_PATH_VALID
);
4569 /* Delete the NHT structure if any, if we're
4571 * enabling/disabling import check. We
4572 * deregister the route
4573 * from NHT to avoid overloading NHT and the
4574 * process interaction
4576 bgp_unlink_nexthop(pi
);
4577 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
4579 /* Process change. */
4580 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4581 bgp_process(bgp
, rn
, afi
, safi
);
4583 if (SAFI_UNICAST
== safi
4584 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4586 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4587 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4591 bgp_unlock_node(rn
);
4592 aspath_unintern(&attr
.aspath
);
4597 /* Make new BGP info. */
4598 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4600 /* Nexthop reachability check. */
4601 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4602 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4603 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, 0))
4604 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4606 if (BGP_DEBUG(nht
, NHT
)) {
4607 char buf1
[INET6_ADDRSTRLEN
];
4608 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4611 "%s(%s): Route not in table, not advertising",
4612 __FUNCTION__
, buf1
);
4614 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
4617 /* Delete the NHT structure if any, if we're toggling between
4618 * enabling/disabling import check. We deregister the route
4619 * from NHT to avoid overloading NHT and the process interaction
4621 bgp_unlink_nexthop(new);
4623 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4626 /* Aggregate address increment. */
4627 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4629 /* Register new BGP information. */
4630 bgp_path_info_add(rn
, new);
4632 /* route_node_get lock */
4633 bgp_unlock_node(rn
);
4635 /* Process change. */
4636 bgp_process(bgp
, rn
, afi
, safi
);
4638 if (SAFI_UNICAST
== safi
4639 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4640 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4641 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4644 /* Unintern original. */
4645 aspath_unintern(&attr
.aspath
);
4648 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4651 struct bgp_node
*rn
;
4652 struct bgp_path_info
*pi
;
4654 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4656 /* Check selected route and self inserted route. */
4657 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4658 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4659 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4662 /* Withdraw static BGP route from routing table. */
4664 if (SAFI_UNICAST
== safi
4665 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4666 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4667 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
4669 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4670 bgp_unlink_nexthop(pi
);
4671 bgp_path_info_delete(rn
, pi
);
4672 bgp_process(bgp
, rn
, afi
, safi
);
4675 /* Unlock bgp_node_lookup. */
4676 bgp_unlock_node(rn
);
4680 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4682 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4683 afi_t afi
, safi_t safi
,
4684 struct prefix_rd
*prd
)
4686 struct bgp_node
*rn
;
4687 struct bgp_path_info
*pi
;
4689 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4691 /* Check selected route and self inserted route. */
4692 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4693 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4694 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4697 /* Withdraw static BGP route from routing table. */
4700 rfapiProcessWithdraw(
4701 pi
->peer
, NULL
, p
, prd
, pi
->attr
, afi
, safi
, pi
->type
,
4702 1); /* Kill, since it is an administrative change */
4704 if (SAFI_MPLS_VPN
== safi
4705 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4706 vpn_leak_to_vrf_withdraw(bgp
, pi
);
4708 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4709 bgp_path_info_delete(rn
, pi
);
4710 bgp_process(bgp
, rn
, afi
, safi
);
4713 /* Unlock bgp_node_lookup. */
4714 bgp_unlock_node(rn
);
4717 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4718 struct bgp_static
*bgp_static
, afi_t afi
,
4721 struct bgp_node
*rn
;
4722 struct bgp_path_info
*new;
4723 struct attr
*attr_new
;
4724 struct attr attr
= {0};
4725 struct bgp_path_info
*pi
;
4727 mpls_label_t label
= 0;
4729 uint32_t num_labels
= 0;
4734 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4736 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4739 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4741 attr
.nexthop
= bgp_static
->igpnexthop
;
4742 attr
.med
= bgp_static
->igpmetric
;
4743 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4745 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4746 || (safi
== SAFI_ENCAP
)) {
4747 if (afi
== AFI_IP
) {
4748 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4749 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4752 if (afi
== AFI_L2VPN
) {
4753 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4755 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4756 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4757 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4758 sizeof(struct in6_addr
));
4759 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4760 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4761 struct bgp_encap_type_vxlan bet
;
4762 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4763 bet
.vnid
= p
->u
.prefix_evpn
.prefix_addr
.eth_tag
;
4764 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4766 if (bgp_static
->router_mac
) {
4767 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4770 /* Apply route-map. */
4771 if (bgp_static
->rmap
.name
) {
4772 struct attr attr_tmp
= attr
;
4773 struct bgp_path_info rmap_path
;
4776 rmap_path
.peer
= bgp
->peer_self
;
4777 rmap_path
.attr
= &attr_tmp
;
4779 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4781 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4784 bgp
->peer_self
->rmap_type
= 0;
4786 if (ret
== RMAP_DENYMATCH
) {
4787 /* Free uninterned attribute. */
4788 bgp_attr_flush(&attr_tmp
);
4790 /* Unintern original. */
4791 aspath_unintern(&attr
.aspath
);
4792 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4797 attr_new
= bgp_attr_intern(&attr_tmp
);
4799 attr_new
= bgp_attr_intern(&attr
);
4802 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4803 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4804 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4808 memset(&add
, 0, sizeof(union gw_addr
));
4809 if (attrhash_cmp(pi
->attr
, attr_new
)
4810 && overlay_index_equal(afi
, pi
, bgp_static
->eth_s_id
, &add
)
4811 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
4812 bgp_unlock_node(rn
);
4813 bgp_attr_unintern(&attr_new
);
4814 aspath_unintern(&attr
.aspath
);
4817 /* The attribute is changed. */
4818 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4820 /* Rewrite BGP route information. */
4821 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4822 bgp_path_info_restore(rn
, pi
);
4824 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4825 bgp_attr_unintern(&pi
->attr
);
4826 pi
->attr
= attr_new
;
4827 pi
->uptime
= bgp_clock();
4830 label
= decode_label(&pi
->extra
->label
[0]);
4833 /* Process change. */
4834 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4835 bgp_process(bgp
, rn
, afi
, safi
);
4837 if (SAFI_MPLS_VPN
== safi
4838 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4839 vpn_leak_to_vrf_update(bgp
, pi
);
4842 rfapiProcessUpdate(pi
->peer
, NULL
, p
, &bgp_static
->prd
,
4843 pi
->attr
, afi
, safi
, pi
->type
,
4844 pi
->sub_type
, &label
);
4846 bgp_unlock_node(rn
);
4847 aspath_unintern(&attr
.aspath
);
4853 /* Make new BGP info. */
4854 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4856 SET_FLAG(new->flags
, BGP_PATH_VALID
);
4857 new->extra
= bgp_path_info_extra_new();
4859 new->extra
->label
[0] = bgp_static
->label
;
4860 new->extra
->num_labels
= num_labels
;
4863 label
= decode_label(&bgp_static
->label
);
4866 /* Aggregate address increment. */
4867 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4869 /* Register new BGP information. */
4870 bgp_path_info_add(rn
, new);
4871 /* route_node_get lock */
4872 bgp_unlock_node(rn
);
4874 /* Process change. */
4875 bgp_process(bgp
, rn
, afi
, safi
);
4877 if (SAFI_MPLS_VPN
== safi
4878 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4879 vpn_leak_to_vrf_update(bgp
, new);
4882 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4883 safi
, new->type
, new->sub_type
, &label
);
4886 /* Unintern original. */
4887 aspath_unintern(&attr
.aspath
);
4890 /* Configure static BGP network. When user don't run zebra, static
4891 route should be installed as valid. */
4892 static int bgp_static_set(struct vty
*vty
, const char *negate
,
4893 const char *ip_str
, afi_t afi
, safi_t safi
,
4894 const char *rmap
, int backdoor
, uint32_t label_index
)
4896 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4899 struct bgp_static
*bgp_static
;
4900 struct bgp_node
*rn
;
4901 uint8_t need_update
= 0;
4903 /* Convert IP prefix string to struct prefix. */
4904 ret
= str2prefix(ip_str
, &p
);
4906 vty_out(vty
, "%% Malformed prefix\n");
4907 return CMD_WARNING_CONFIG_FAILED
;
4909 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4910 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4911 return CMD_WARNING_CONFIG_FAILED
;
4918 /* Set BGP static route configuration. */
4919 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4922 vty_out(vty
, "%% Can't find static route specified\n");
4923 return CMD_WARNING_CONFIG_FAILED
;
4926 bgp_static
= bgp_node_get_bgp_static_info(rn
);
4928 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
4929 && (label_index
!= bgp_static
->label_index
)) {
4931 "%% label-index doesn't match static route\n");
4932 return CMD_WARNING_CONFIG_FAILED
;
4935 if ((rmap
&& bgp_static
->rmap
.name
)
4936 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
4938 "%% route-map name doesn't match static route\n");
4939 return CMD_WARNING_CONFIG_FAILED
;
4942 /* Update BGP RIB. */
4943 if (!bgp_static
->backdoor
)
4944 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4946 /* Clear configuration. */
4947 bgp_static_free(bgp_static
);
4948 bgp_node_set_bgp_static_info(rn
, NULL
);
4949 bgp_unlock_node(rn
);
4950 bgp_unlock_node(rn
);
4953 /* Set BGP static route configuration. */
4954 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4956 bgp_static
= bgp_node_get_bgp_static_info(rn
);
4958 /* Configuration change. */
4959 /* Label index cannot be changed. */
4960 if (bgp_static
->label_index
!= label_index
) {
4961 vty_out(vty
, "%% cannot change label-index\n");
4962 return CMD_WARNING_CONFIG_FAILED
;
4965 /* Check previous routes are installed into BGP. */
4966 if (bgp_static
->valid
4967 && bgp_static
->backdoor
!= backdoor
)
4970 bgp_static
->backdoor
= backdoor
;
4973 if (bgp_static
->rmap
.name
)
4974 XFREE(MTYPE_ROUTE_MAP_NAME
,
4975 bgp_static
->rmap
.name
);
4976 bgp_static
->rmap
.name
=
4977 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4978 bgp_static
->rmap
.map
=
4979 route_map_lookup_by_name(rmap
);
4981 if (bgp_static
->rmap
.name
)
4982 XFREE(MTYPE_ROUTE_MAP_NAME
,
4983 bgp_static
->rmap
.name
);
4984 bgp_static
->rmap
.name
= NULL
;
4985 bgp_static
->rmap
.map
= NULL
;
4986 bgp_static
->valid
= 0;
4988 bgp_unlock_node(rn
);
4990 /* New configuration. */
4991 bgp_static
= bgp_static_new();
4992 bgp_static
->backdoor
= backdoor
;
4993 bgp_static
->valid
= 0;
4994 bgp_static
->igpmetric
= 0;
4995 bgp_static
->igpnexthop
.s_addr
= 0;
4996 bgp_static
->label_index
= label_index
;
4999 if (bgp_static
->rmap
.name
)
5000 XFREE(MTYPE_ROUTE_MAP_NAME
,
5001 bgp_static
->rmap
.name
);
5002 bgp_static
->rmap
.name
=
5003 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
5004 bgp_static
->rmap
.map
=
5005 route_map_lookup_by_name(rmap
);
5007 bgp_node_set_bgp_static_info(rn
, bgp_static
);
5010 bgp_static
->valid
= 1;
5012 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
5014 if (!bgp_static
->backdoor
)
5015 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
5021 void bgp_static_add(struct bgp
*bgp
)
5025 struct bgp_node
*rn
;
5026 struct bgp_node
*rm
;
5027 struct bgp_table
*table
;
5028 struct bgp_static
*bgp_static
;
5030 FOREACH_AFI_SAFI (afi
, safi
)
5031 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5032 rn
= bgp_route_next(rn
)) {
5033 if (!bgp_node_has_bgp_path_info_data(rn
))
5036 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5037 || (safi
== SAFI_EVPN
)) {
5038 table
= bgp_node_get_bgp_table_info(rn
);
5040 for (rm
= bgp_table_top(table
); rm
;
5041 rm
= bgp_route_next(rm
)) {
5043 bgp_node_get_bgp_static_info(
5045 bgp_static_update_safi(bgp
, &rm
->p
,
5052 bgp_node_get_bgp_static_info(rn
), afi
,
5058 /* Called from bgp_delete(). Delete all static routes from the BGP
5060 void bgp_static_delete(struct bgp
*bgp
)
5064 struct bgp_node
*rn
;
5065 struct bgp_node
*rm
;
5066 struct bgp_table
*table
;
5067 struct bgp_static
*bgp_static
;
5069 FOREACH_AFI_SAFI (afi
, safi
)
5070 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5071 rn
= bgp_route_next(rn
)) {
5072 if (!bgp_node_has_bgp_path_info_data(rn
))
5075 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5076 || (safi
== SAFI_EVPN
)) {
5077 table
= bgp_node_get_bgp_table_info(rn
);
5079 for (rm
= bgp_table_top(table
); rm
;
5080 rm
= bgp_route_next(rm
)) {
5082 bgp_node_get_bgp_static_info(
5087 bgp_static_withdraw_safi(
5088 bgp
, &rm
->p
, AFI_IP
, safi
,
5089 (struct prefix_rd
*)&rn
->p
);
5090 bgp_static_free(bgp_static
);
5091 bgp_node_set_bgp_static_info(rn
, NULL
);
5092 bgp_unlock_node(rn
);
5095 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5096 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
5097 bgp_static_free(bgp_static
);
5098 bgp_node_set_bgp_static_info(rn
, NULL
);
5099 bgp_unlock_node(rn
);
5104 void bgp_static_redo_import_check(struct bgp
*bgp
)
5108 struct bgp_node
*rn
;
5109 struct bgp_node
*rm
;
5110 struct bgp_table
*table
;
5111 struct bgp_static
*bgp_static
;
5113 /* Use this flag to force reprocessing of the route */
5114 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5115 FOREACH_AFI_SAFI (afi
, safi
) {
5116 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5117 rn
= bgp_route_next(rn
)) {
5118 if (!bgp_node_has_bgp_path_info_data(rn
))
5121 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5122 || (safi
== SAFI_EVPN
)) {
5123 table
= bgp_node_get_bgp_table_info(rn
);
5125 for (rm
= bgp_table_top(table
); rm
;
5126 rm
= bgp_route_next(rm
)) {
5128 bgp_node_get_bgp_static_info(
5130 bgp_static_update_safi(bgp
, &rm
->p
,
5135 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5136 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
5141 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5144 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
5147 struct bgp_table
*table
;
5148 struct bgp_node
*rn
;
5149 struct bgp_path_info
*pi
;
5151 table
= bgp
->rib
[afi
][safi
];
5152 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
5153 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5154 if (pi
->peer
== bgp
->peer_self
5155 && ((pi
->type
== ZEBRA_ROUTE_BGP
5156 && pi
->sub_type
== BGP_ROUTE_STATIC
)
5157 || (pi
->type
!= ZEBRA_ROUTE_BGP
5159 == BGP_ROUTE_REDISTRIBUTE
))) {
5160 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
5162 bgp_unlink_nexthop(pi
);
5163 bgp_path_info_delete(rn
, pi
);
5164 bgp_process(bgp
, rn
, afi
, safi
);
5171 * Purge all networks and redistributed routes from routing table.
5172 * Invoked upon the instance going down.
5174 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
5179 FOREACH_AFI_SAFI (afi
, safi
)
5180 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
5185 * Currently this is used to set static routes for VPN and ENCAP.
5186 * I think it can probably be factored with bgp_static_set.
5188 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5189 const char *ip_str
, const char *rd_str
,
5190 const char *label_str
, const char *rmap_str
,
5191 int evpn_type
, const char *esi
, const char *gwip
,
5192 const char *ethtag
, const char *routermac
)
5194 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5197 struct prefix_rd prd
;
5198 struct bgp_node
*prn
;
5199 struct bgp_node
*rn
;
5200 struct bgp_table
*table
;
5201 struct bgp_static
*bgp_static
;
5202 mpls_label_t label
= MPLS_INVALID_LABEL
;
5203 struct prefix gw_ip
;
5205 /* validate ip prefix */
5206 ret
= str2prefix(ip_str
, &p
);
5208 vty_out(vty
, "%% Malformed prefix\n");
5209 return CMD_WARNING_CONFIG_FAILED
;
5212 if ((afi
== AFI_L2VPN
)
5213 && (bgp_build_evpn_prefix(evpn_type
,
5214 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5215 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5216 return CMD_WARNING_CONFIG_FAILED
;
5219 ret
= str2prefix_rd(rd_str
, &prd
);
5221 vty_out(vty
, "%% Malformed rd\n");
5222 return CMD_WARNING_CONFIG_FAILED
;
5226 unsigned long label_val
;
5227 label_val
= strtoul(label_str
, NULL
, 10);
5228 encode_label(label_val
, &label
);
5231 if (safi
== SAFI_EVPN
) {
5232 if (esi
&& str2esi(esi
, NULL
) == 0) {
5233 vty_out(vty
, "%% Malformed ESI\n");
5234 return CMD_WARNING_CONFIG_FAILED
;
5236 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5237 vty_out(vty
, "%% Malformed Router MAC\n");
5238 return CMD_WARNING_CONFIG_FAILED
;
5241 memset(&gw_ip
, 0, sizeof(struct prefix
));
5242 ret
= str2prefix(gwip
, &gw_ip
);
5244 vty_out(vty
, "%% Malformed GatewayIp\n");
5245 return CMD_WARNING_CONFIG_FAILED
;
5247 if ((gw_ip
.family
== AF_INET
5248 && is_evpn_prefix_ipaddr_v6(
5249 (struct prefix_evpn
*)&p
))
5250 || (gw_ip
.family
== AF_INET6
5251 && is_evpn_prefix_ipaddr_v4(
5252 (struct prefix_evpn
*)&p
))) {
5254 "%% GatewayIp family differs with IP prefix\n");
5255 return CMD_WARNING_CONFIG_FAILED
;
5259 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5260 if (!bgp_node_has_bgp_path_info_data(prn
))
5261 bgp_node_set_bgp_table_info(prn
,
5262 bgp_table_init(bgp
, afi
, safi
));
5263 table
= bgp_node_get_bgp_table_info(prn
);
5265 rn
= bgp_node_get(table
, &p
);
5267 if (bgp_node_has_bgp_path_info_data(rn
)) {
5268 vty_out(vty
, "%% Same network configuration exists\n");
5269 bgp_unlock_node(rn
);
5271 /* New configuration. */
5272 bgp_static
= bgp_static_new();
5273 bgp_static
->backdoor
= 0;
5274 bgp_static
->valid
= 0;
5275 bgp_static
->igpmetric
= 0;
5276 bgp_static
->igpnexthop
.s_addr
= 0;
5277 bgp_static
->label
= label
;
5278 bgp_static
->prd
= prd
;
5281 if (bgp_static
->rmap
.name
)
5282 XFREE(MTYPE_ROUTE_MAP_NAME
,
5283 bgp_static
->rmap
.name
);
5284 bgp_static
->rmap
.name
=
5285 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5286 bgp_static
->rmap
.map
=
5287 route_map_lookup_by_name(rmap_str
);
5290 if (safi
== SAFI_EVPN
) {
5292 bgp_static
->eth_s_id
=
5294 sizeof(struct eth_segment_id
));
5295 str2esi(esi
, bgp_static
->eth_s_id
);
5298 bgp_static
->router_mac
=
5299 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5300 (void)prefix_str2mac(routermac
,
5301 bgp_static
->router_mac
);
5304 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5306 bgp_node_set_bgp_static_info(rn
, bgp_static
);
5308 bgp_static
->valid
= 1;
5309 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5315 /* Configure static BGP network. */
5316 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5317 const char *ip_str
, const char *rd_str
,
5318 const char *label_str
, int evpn_type
, const char *esi
,
5319 const char *gwip
, const char *ethtag
)
5321 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5324 struct prefix_rd prd
;
5325 struct bgp_node
*prn
;
5326 struct bgp_node
*rn
;
5327 struct bgp_table
*table
;
5328 struct bgp_static
*bgp_static
;
5329 mpls_label_t label
= MPLS_INVALID_LABEL
;
5331 /* Convert IP prefix string to struct prefix. */
5332 ret
= str2prefix(ip_str
, &p
);
5334 vty_out(vty
, "%% Malformed prefix\n");
5335 return CMD_WARNING_CONFIG_FAILED
;
5338 if ((afi
== AFI_L2VPN
)
5339 && (bgp_build_evpn_prefix(evpn_type
,
5340 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5341 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5342 return CMD_WARNING_CONFIG_FAILED
;
5344 ret
= str2prefix_rd(rd_str
, &prd
);
5346 vty_out(vty
, "%% Malformed rd\n");
5347 return CMD_WARNING_CONFIG_FAILED
;
5351 unsigned long label_val
;
5352 label_val
= strtoul(label_str
, NULL
, 10);
5353 encode_label(label_val
, &label
);
5356 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5357 if (!bgp_node_has_bgp_path_info_data(prn
))
5358 bgp_node_set_bgp_table_info(prn
,
5359 bgp_table_init(bgp
, afi
, safi
));
5361 bgp_unlock_node(prn
);
5362 table
= bgp_node_get_bgp_table_info(prn
);
5364 rn
= bgp_node_lookup(table
, &p
);
5367 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5369 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5370 bgp_static_free(bgp_static
);
5371 bgp_node_set_bgp_static_info(rn
, NULL
);
5372 bgp_unlock_node(rn
);
5373 bgp_unlock_node(rn
);
5375 vty_out(vty
, "%% Can't find the route\n");
5380 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5381 const char *rmap_name
)
5383 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5384 struct bgp_rmap
*rmap
;
5386 rmap
= &bgp
->table_map
[afi
][safi
];
5389 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5390 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5391 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5394 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5399 if (bgp_fibupd_safi(safi
))
5400 bgp_zebra_announce_table(bgp
, afi
, safi
);
5405 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5406 const char *rmap_name
)
5408 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5409 struct bgp_rmap
*rmap
;
5411 rmap
= &bgp
->table_map
[afi
][safi
];
5413 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5417 if (bgp_fibupd_safi(safi
))
5418 bgp_zebra_announce_table(bgp
, afi
, safi
);
5423 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5426 if (bgp
->table_map
[afi
][safi
].name
) {
5427 vty_out(vty
, " table-map %s\n",
5428 bgp
->table_map
[afi
][safi
].name
);
5432 DEFUN (bgp_table_map
,
5435 "BGP table to RIB route download filter\n"
5436 "Name of the route map\n")
5439 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5440 argv
[idx_word
]->arg
);
5442 DEFUN (no_bgp_table_map
,
5443 no_bgp_table_map_cmd
,
5444 "no table-map WORD",
5446 "BGP table to RIB route download filter\n"
5447 "Name of the route map\n")
5450 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5451 argv
[idx_word
]->arg
);
5457 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5458 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5459 backdoor$backdoor}]",
5461 "Specify a network to announce via BGP\n"
5466 "Route-map to modify the attributes\n"
5467 "Name of the route map\n"
5468 "Label index to associate with the prefix\n"
5469 "Label index value\n"
5470 "Specify a BGP backdoor route\n")
5472 char addr_prefix_str
[BUFSIZ
];
5477 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5480 vty_out(vty
, "%% Inconsistent address and mask\n");
5481 return CMD_WARNING_CONFIG_FAILED
;
5485 return bgp_static_set(
5486 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5487 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5488 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5491 DEFPY(ipv6_bgp_network
,
5492 ipv6_bgp_network_cmd
,
5493 "[no] network X:X::X:X/M$prefix \
5494 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5496 "Specify a network to announce via BGP\n"
5498 "Route-map to modify the attributes\n"
5499 "Name of the route map\n"
5500 "Label index to associate with the prefix\n"
5501 "Label index value\n")
5503 return bgp_static_set(
5504 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5505 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5508 /* Aggreagete address:
5510 advertise-map Set condition to advertise attribute
5511 as-set Generate AS set path information
5512 attribute-map Set attributes of aggregate
5513 route-map Set parameters of aggregate
5514 summary-only Filter more specific routes from updates
5515 suppress-map Conditionally filter more specific routes from updates
5518 struct bgp_aggregate
{
5519 /* Summary-only flag. */
5520 uint8_t summary_only
;
5522 /* AS set generation. */
5525 /* Route-map for aggregated route. */
5526 struct route_map
*map
;
5528 /* Suppress-count. */
5529 unsigned long count
;
5531 /* SAFI configuration. */
5535 static struct bgp_aggregate
*bgp_aggregate_new(void)
5537 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5540 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5542 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5545 static int bgp_aggregate_info_same(struct bgp_path_info
*pi
, uint8_t origin
,
5546 struct aspath
*aspath
,
5547 struct community
*comm
,
5548 struct ecommunity
*ecomm
,
5549 struct lcommunity
*lcomm
)
5551 static struct aspath
*ae
= NULL
;
5554 ae
= aspath_empty();
5559 if (origin
!= pi
->attr
->origin
)
5562 if (!aspath_cmp(pi
->attr
->aspath
, (aspath
) ? aspath
: ae
))
5565 if (!community_cmp(pi
->attr
->community
, comm
))
5568 if (!ecommunity_cmp(pi
->attr
->ecommunity
, ecomm
))
5571 if (!lcommunity_cmp(pi
->attr
->lcommunity
, lcomm
))
5574 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
5580 static void bgp_aggregate_install(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
5581 struct prefix
*p
, uint8_t origin
,
5582 struct aspath
*aspath
,
5583 struct community
*community
,
5584 struct ecommunity
*ecommunity
,
5585 struct lcommunity
*lcommunity
,
5586 uint8_t atomic_aggregate
,
5587 struct bgp_aggregate
*aggregate
)
5589 struct bgp_node
*rn
;
5590 struct bgp_table
*table
;
5591 struct bgp_path_info
*pi
, *orig
, *new;
5593 table
= bgp
->rib
[afi
][safi
];
5595 rn
= bgp_node_get(table
, p
);
5597 for (orig
= pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
5598 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
5599 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5602 if (aggregate
->count
> 0) {
5604 * If the aggregate information has not changed
5605 * no need to re-install it again.
5607 if (bgp_aggregate_info_same(orig
, origin
, aspath
, community
,
5608 ecommunity
, lcommunity
)) {
5609 bgp_unlock_node(rn
);
5612 aspath_free(aspath
);
5614 community_free(&community
);
5616 ecommunity_free(&ecommunity
);
5618 lcommunity_free(&lcommunity
);
5624 * Mark the old as unusable
5627 bgp_path_info_delete(rn
, pi
);
5629 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0,
5631 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5632 community
, ecommunity
,
5637 SET_FLAG(new->flags
, BGP_PATH_VALID
);
5639 bgp_path_info_add(rn
, new);
5640 bgp_process(bgp
, rn
, afi
, safi
);
5642 for (pi
= orig
; pi
; pi
= pi
->next
)
5643 if (pi
->peer
== bgp
->peer_self
5644 && pi
->type
== ZEBRA_ROUTE_BGP
5645 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5648 /* Withdraw static BGP route from routing table. */
5650 bgp_path_info_delete(rn
, pi
);
5651 bgp_process(bgp
, rn
, afi
, safi
);
5655 bgp_unlock_node(rn
);
5658 /* Update an aggregate as routes are added/removed from the BGP table */
5659 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5660 struct bgp_path_info
*pinew
, afi_t afi
,
5661 safi_t safi
, struct bgp_path_info
*del
,
5662 struct bgp_aggregate
*aggregate
)
5664 struct bgp_table
*table
;
5665 struct bgp_node
*top
;
5666 struct bgp_node
*rn
;
5668 struct aspath
*aspath
= NULL
;
5669 struct aspath
*asmerge
= NULL
;
5670 struct community
*community
= NULL
;
5671 struct community
*commerge
= NULL
;
5672 struct ecommunity
*ecommunity
= NULL
;
5673 struct ecommunity
*ecommerge
= NULL
;
5674 struct lcommunity
*lcommunity
= NULL
;
5675 struct lcommunity
*lcommerge
= NULL
;
5676 struct bgp_path_info
*pi
;
5677 unsigned long match
= 0;
5678 uint8_t atomic_aggregate
= 0;
5680 /* ORIGIN attribute: If at least one route among routes that are
5681 aggregated has ORIGIN with the value INCOMPLETE, then the
5682 aggregated route must have the ORIGIN attribute with the value
5683 INCOMPLETE. Otherwise, if at least one route among routes that
5684 are aggregated has ORIGIN with the value EGP, then the aggregated
5685 route must have the origin attribute with the value EGP. In all
5686 other case the value of the ORIGIN attribute of the aggregated
5687 route is INTERNAL. */
5688 origin
= BGP_ORIGIN_IGP
;
5690 table
= bgp
->rib
[afi
][safi
];
5692 top
= bgp_node_get(table
, p
);
5693 for (rn
= bgp_node_get(table
, p
); rn
;
5694 rn
= bgp_route_next_until(rn
, top
)) {
5695 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5700 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5701 if (BGP_PATH_HOLDDOWN(pi
))
5704 if (del
&& pi
== del
)
5708 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5709 atomic_aggregate
= 1;
5711 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5715 * summary-only aggregate route suppress
5716 * aggregated route announcements.
5718 if (aggregate
->summary_only
) {
5719 (bgp_path_info_extra_get(pi
))->suppress
++;
5720 bgp_path_info_set_flag(rn
, pi
,
5721 BGP_PATH_ATTR_CHANGED
);
5728 * If at least one route among routes that are
5729 * aggregated has ORIGIN with the value INCOMPLETE,
5730 * then the aggregated route MUST have the ORIGIN
5731 * attribute with the value INCOMPLETE. Otherwise, if
5732 * at least one route among routes that are aggregated
5733 * has ORIGIN with the value EGP, then the aggregated
5734 * route MUST have the ORIGIN attribute with the value
5737 if (origin
< pi
->attr
->origin
)
5738 origin
= pi
->attr
->origin
;
5740 if (!aggregate
->as_set
)
5744 * as-set aggregate route generate origin, as path,
5745 * and community aggregation.
5748 asmerge
= aspath_aggregate(aspath
,
5750 aspath_free(aspath
);
5753 aspath
= aspath_dup(pi
->attr
->aspath
);
5755 if (pi
->attr
->community
) {
5757 commerge
= community_merge(
5758 community
, pi
->attr
->community
);
5760 community_uniq_sort(commerge
);
5761 community_free(&commerge
);
5763 community
= community_dup(
5764 pi
->attr
->community
);
5767 if (pi
->attr
->ecommunity
) {
5769 ecommerge
= ecommunity_merge(
5771 pi
->attr
->ecommunity
);
5773 ecommunity_uniq_sort(ecommerge
);
5774 ecommunity_free(&ecommerge
);
5776 ecommunity
= ecommunity_dup(
5777 pi
->attr
->ecommunity
);
5780 if (pi
->attr
->lcommunity
) {
5782 lcommerge
= lcommunity_merge(
5784 pi
->attr
->lcommunity
);
5786 lcommunity_uniq_sort(lcommerge
);
5787 lcommunity_free(&lcommerge
);
5789 lcommunity
= lcommunity_dup(
5790 pi
->attr
->lcommunity
);
5794 bgp_process(bgp
, rn
, afi
, safi
);
5796 bgp_unlock_node(top
);
5801 if (aggregate
->summary_only
)
5802 (bgp_path_info_extra_get(pinew
))->suppress
++;
5804 if (origin
< pinew
->attr
->origin
)
5805 origin
= pinew
->attr
->origin
;
5807 if (aggregate
->as_set
) {
5809 asmerge
= aspath_aggregate(aspath
,
5810 pinew
->attr
->aspath
);
5811 aspath_free(aspath
);
5814 aspath
= aspath_dup(pinew
->attr
->aspath
);
5816 if (pinew
->attr
->community
) {
5818 commerge
= community_merge(
5820 pinew
->attr
->community
);
5822 community_uniq_sort(commerge
);
5823 community_free(&commerge
);
5825 community
= community_dup(
5826 pinew
->attr
->community
);
5829 if (pinew
->attr
->ecommunity
) {
5831 ecommerge
= ecommunity_merge(
5833 pinew
->attr
->ecommunity
);
5835 ecommunity_uniq_sort(ecommerge
);
5836 ecommunity_free(&ecommerge
);
5838 ecommunity
= ecommunity_dup(
5839 pinew
->attr
->ecommunity
);
5842 if (pinew
->attr
->lcommunity
) {
5844 lcommerge
= lcommunity_merge(
5846 pinew
->attr
->lcommunity
);
5848 lcommunity_uniq_sort(lcommerge
);
5849 lcommunity_free(&lcommerge
);
5851 lcommunity
= lcommunity_dup(
5852 pinew
->attr
->lcommunity
);
5857 bgp_aggregate_install(bgp
, afi
, safi
, p
, origin
, aspath
, community
,
5858 ecommunity
, lcommunity
, atomic_aggregate
,
5861 if (aggregate
->count
== 0) {
5863 aspath_free(aspath
);
5865 community_free(&community
);
5867 ecommunity_free(&ecommunity
);
5869 lcommunity_free(&lcommunity
);
5873 static void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5874 safi_t safi
, struct bgp_aggregate
*aggregate
)
5876 struct bgp_table
*table
;
5877 struct bgp_node
*top
;
5878 struct bgp_node
*rn
;
5879 struct bgp_path_info
*pi
;
5880 unsigned long match
;
5882 table
= bgp
->rib
[afi
][safi
];
5884 /* If routes exists below this node, generate aggregate routes. */
5885 top
= bgp_node_get(table
, p
);
5886 for (rn
= bgp_node_get(table
, p
); rn
;
5887 rn
= bgp_route_next_until(rn
, top
)) {
5888 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5892 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5893 if (BGP_PATH_HOLDDOWN(pi
))
5896 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5899 if (aggregate
->summary_only
&& pi
->extra
) {
5900 pi
->extra
->suppress
--;
5902 if (pi
->extra
->suppress
== 0) {
5903 bgp_path_info_set_flag(
5904 rn
, pi
, BGP_PATH_ATTR_CHANGED
);
5911 /* If this node was suppressed, process the change. */
5913 bgp_process(bgp
, rn
, afi
, safi
);
5915 bgp_unlock_node(top
);
5918 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5919 struct bgp_path_info
*pi
, afi_t afi
, safi_t safi
)
5921 struct bgp_node
*child
;
5922 struct bgp_node
*rn
;
5923 struct bgp_aggregate
*aggregate
;
5924 struct bgp_table
*table
;
5926 table
= bgp
->aggregate
[afi
][safi
];
5928 /* No aggregates configured. */
5929 if (bgp_table_top_nolock(table
) == NULL
)
5932 if (p
->prefixlen
== 0)
5935 if (BGP_PATH_HOLDDOWN(pi
))
5938 child
= bgp_node_get(table
, p
);
5940 /* Aggregate address configuration check. */
5941 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
5942 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
5943 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
5944 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5945 bgp_aggregate_route(bgp
, &rn
->p
, pi
, afi
, safi
, NULL
,
5949 bgp_unlock_node(child
);
5952 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5953 struct bgp_path_info
*del
, afi_t afi
, safi_t safi
)
5955 struct bgp_node
*child
;
5956 struct bgp_node
*rn
;
5957 struct bgp_aggregate
*aggregate
;
5958 struct bgp_table
*table
;
5960 table
= bgp
->aggregate
[afi
][safi
];
5962 /* No aggregates configured. */
5963 if (bgp_table_top_nolock(table
) == NULL
)
5966 if (p
->prefixlen
== 0)
5969 child
= bgp_node_get(table
, p
);
5971 /* Aggregate address configuration check. */
5972 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
5973 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
5974 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
5975 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5976 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5980 bgp_unlock_node(child
);
5983 /* Aggregate route attribute. */
5984 #define AGGREGATE_SUMMARY_ONLY 1
5985 #define AGGREGATE_AS_SET 1
5987 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5988 afi_t afi
, safi_t safi
)
5990 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5993 struct bgp_node
*rn
;
5994 struct bgp_aggregate
*aggregate
;
5996 /* Convert string to prefix structure. */
5997 ret
= str2prefix(prefix_str
, &p
);
5999 vty_out(vty
, "Malformed prefix\n");
6000 return CMD_WARNING_CONFIG_FAILED
;
6004 /* Old configuration check. */
6005 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
6008 "%% There is no aggregate-address configuration.\n");
6009 return CMD_WARNING_CONFIG_FAILED
;
6012 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
6013 bgp_aggregate_delete(bgp
, &p
, afi
, safi
, aggregate
);
6014 bgp_aggregate_install(bgp
, afi
, safi
, &p
, 0, NULL
, NULL
,
6015 NULL
, NULL
, 0, aggregate
);
6017 /* Unlock aggregate address configuration. */
6018 bgp_node_set_bgp_aggregate_info(rn
, NULL
);
6019 bgp_aggregate_free(aggregate
);
6020 bgp_unlock_node(rn
);
6021 bgp_unlock_node(rn
);
6026 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
6027 safi_t safi
, uint8_t summary_only
, uint8_t as_set
)
6029 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
6032 struct bgp_node
*rn
;
6033 struct bgp_aggregate
*aggregate
;
6035 /* Convert string to prefix structure. */
6036 ret
= str2prefix(prefix_str
, &p
);
6038 vty_out(vty
, "Malformed prefix\n");
6039 return CMD_WARNING_CONFIG_FAILED
;
6043 if ((afi
== AFI_IP
&& p
.prefixlen
== IPV4_MAX_BITLEN
) ||
6044 (afi
== AFI_IP6
&& p
.prefixlen
== IPV6_MAX_BITLEN
)) {
6045 vty_out(vty
, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6047 return CMD_WARNING_CONFIG_FAILED
;
6050 /* Old configuration check. */
6051 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
6053 if (bgp_node_has_bgp_path_info_data(rn
)) {
6054 vty_out(vty
, "There is already same aggregate network.\n");
6055 /* try to remove the old entry */
6056 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
6058 vty_out(vty
, "Error deleting aggregate.\n");
6059 bgp_unlock_node(rn
);
6060 return CMD_WARNING_CONFIG_FAILED
;
6064 /* Make aggregate address structure. */
6065 aggregate
= bgp_aggregate_new();
6066 aggregate
->summary_only
= summary_only
;
6067 aggregate
->as_set
= as_set
;
6068 aggregate
->safi
= safi
;
6069 bgp_node_set_bgp_aggregate_info(rn
, aggregate
);
6071 /* Aggregate address insert into BGP routing table. */
6072 bgp_aggregate_route(bgp
, &p
, NULL
, afi
, safi
, NULL
, aggregate
);
6077 DEFUN (aggregate_address
,
6078 aggregate_address_cmd
,
6079 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6080 "Configure BGP aggregate entries\n"
6081 "Aggregate prefix\n"
6082 "Generate AS set path information\n"
6083 "Filter more specific routes from updates\n"
6084 "Filter more specific routes from updates\n"
6085 "Generate AS set path information\n")
6088 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6089 char *prefix
= argv
[idx
]->arg
;
6091 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6093 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6094 ? AGGREGATE_SUMMARY_ONLY
6097 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
6098 summary_only
, as_set
);
6101 DEFUN (aggregate_address_mask
,
6102 aggregate_address_mask_cmd
,
6103 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6104 "Configure BGP aggregate entries\n"
6105 "Aggregate address\n"
6107 "Generate AS set path information\n"
6108 "Filter more specific routes from updates\n"
6109 "Filter more specific routes from updates\n"
6110 "Generate AS set path information\n")
6113 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6114 char *prefix
= argv
[idx
]->arg
;
6115 char *mask
= argv
[idx
+ 1]->arg
;
6117 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6119 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6120 ? AGGREGATE_SUMMARY_ONLY
6123 char prefix_str
[BUFSIZ
];
6124 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6127 vty_out(vty
, "%% Inconsistent address and mask\n");
6128 return CMD_WARNING_CONFIG_FAILED
;
6131 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
6132 summary_only
, as_set
);
6135 DEFUN (no_aggregate_address
,
6136 no_aggregate_address_cmd
,
6137 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6139 "Configure BGP aggregate entries\n"
6140 "Aggregate prefix\n"
6141 "Generate AS set path information\n"
6142 "Filter more specific routes from updates\n"
6143 "Filter more specific routes from updates\n"
6144 "Generate AS set path information\n")
6147 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6148 char *prefix
= argv
[idx
]->arg
;
6149 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
6152 DEFUN (no_aggregate_address_mask
,
6153 no_aggregate_address_mask_cmd
,
6154 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6156 "Configure BGP aggregate entries\n"
6157 "Aggregate address\n"
6159 "Generate AS set path information\n"
6160 "Filter more specific routes from updates\n"
6161 "Filter more specific routes from updates\n"
6162 "Generate AS set path information\n")
6165 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6166 char *prefix
= argv
[idx
]->arg
;
6167 char *mask
= argv
[idx
+ 1]->arg
;
6169 char prefix_str
[BUFSIZ
];
6170 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6173 vty_out(vty
, "%% Inconsistent address and mask\n");
6174 return CMD_WARNING_CONFIG_FAILED
;
6177 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6180 DEFUN (ipv6_aggregate_address
,
6181 ipv6_aggregate_address_cmd
,
6182 "aggregate-address X:X::X:X/M [summary-only]",
6183 "Configure BGP aggregate entries\n"
6184 "Aggregate prefix\n"
6185 "Filter more specific routes from updates\n")
6188 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6189 char *prefix
= argv
[idx
]->arg
;
6190 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6191 ? AGGREGATE_SUMMARY_ONLY
6193 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6197 DEFUN (no_ipv6_aggregate_address
,
6198 no_ipv6_aggregate_address_cmd
,
6199 "no aggregate-address X:X::X:X/M [summary-only]",
6201 "Configure BGP aggregate entries\n"
6202 "Aggregate prefix\n"
6203 "Filter more specific routes from updates\n")
6206 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6207 char *prefix
= argv
[idx
]->arg
;
6208 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6211 /* Redistribute route treatment. */
6212 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6213 const union g_addr
*nexthop
, ifindex_t ifindex
,
6214 enum nexthop_types_t nhtype
, uint32_t metric
,
6215 uint8_t type
, unsigned short instance
,
6218 struct bgp_path_info
*new;
6219 struct bgp_path_info
*bpi
;
6220 struct bgp_path_info rmap_path
;
6221 struct bgp_node
*bn
;
6223 struct attr
*new_attr
;
6226 struct bgp_redist
*red
;
6228 /* Make default attribute. */
6229 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6232 case NEXTHOP_TYPE_IFINDEX
:
6234 case NEXTHOP_TYPE_IPV4
:
6235 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6236 attr
.nexthop
= nexthop
->ipv4
;
6238 case NEXTHOP_TYPE_IPV6
:
6239 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6240 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6241 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6243 case NEXTHOP_TYPE_BLACKHOLE
:
6244 switch (p
->family
) {
6246 attr
.nexthop
.s_addr
= INADDR_ANY
;
6249 memset(&attr
.mp_nexthop_global
, 0,
6250 sizeof(attr
.mp_nexthop_global
));
6251 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6256 attr
.nh_ifindex
= ifindex
;
6259 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6262 afi
= family2afi(p
->family
);
6264 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6266 struct attr attr_new
;
6268 /* Copy attribute for modification. */
6269 bgp_attr_dup(&attr_new
, &attr
);
6271 if (red
->redist_metric_flag
)
6272 attr_new
.med
= red
->redist_metric
;
6274 /* Apply route-map. */
6275 if (red
->rmap
.name
) {
6276 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
6277 rmap_path
.peer
= bgp
->peer_self
;
6278 rmap_path
.attr
= &attr_new
;
6280 SET_FLAG(bgp
->peer_self
->rmap_type
,
6281 PEER_RMAP_TYPE_REDISTRIBUTE
);
6283 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6286 bgp
->peer_self
->rmap_type
= 0;
6288 if (ret
== RMAP_DENYMATCH
) {
6289 /* Free uninterned attribute. */
6290 bgp_attr_flush(&attr_new
);
6292 /* Unintern original. */
6293 aspath_unintern(&attr
.aspath
);
6294 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6299 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6300 bgp_attr_add_gshut_community(&attr_new
);
6302 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6303 SAFI_UNICAST
, p
, NULL
);
6305 new_attr
= bgp_attr_intern(&attr_new
);
6307 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
6309 if (bpi
->peer
== bgp
->peer_self
6310 && bpi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6314 /* Ensure the (source route) type is updated. */
6316 if (attrhash_cmp(bpi
->attr
, new_attr
)
6317 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
6318 bgp_attr_unintern(&new_attr
);
6319 aspath_unintern(&attr
.aspath
);
6320 bgp_unlock_node(bn
);
6323 /* The attribute is changed. */
6324 bgp_path_info_set_flag(bn
, bpi
,
6325 BGP_PATH_ATTR_CHANGED
);
6327 /* Rewrite BGP route information. */
6328 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
6329 bgp_path_info_restore(bn
, bpi
);
6331 bgp_aggregate_decrement(
6332 bgp
, p
, bpi
, afi
, SAFI_UNICAST
);
6333 bgp_attr_unintern(&bpi
->attr
);
6334 bpi
->attr
= new_attr
;
6335 bpi
->uptime
= bgp_clock();
6337 /* Process change. */
6338 bgp_aggregate_increment(bgp
, p
, bpi
, afi
,
6340 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6341 bgp_unlock_node(bn
);
6342 aspath_unintern(&attr
.aspath
);
6344 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6346 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6348 vpn_leak_from_vrf_update(
6349 bgp_get_default(), bgp
, bpi
);
6355 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6356 bgp
->peer_self
, new_attr
, bn
);
6357 SET_FLAG(new->flags
, BGP_PATH_VALID
);
6359 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6360 bgp_path_info_add(bn
, new);
6361 bgp_unlock_node(bn
);
6362 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6364 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6365 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6367 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6371 /* Unintern original. */
6372 aspath_unintern(&attr
.aspath
);
6375 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, uint8_t type
,
6376 unsigned short instance
)
6379 struct bgp_node
*rn
;
6380 struct bgp_path_info
*pi
;
6381 struct bgp_redist
*red
;
6383 afi
= family2afi(p
->family
);
6385 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6387 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6388 SAFI_UNICAST
, p
, NULL
);
6390 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
6391 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
)
6395 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6396 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6398 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6401 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, SAFI_UNICAST
);
6402 bgp_path_info_delete(rn
, pi
);
6403 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6405 bgp_unlock_node(rn
);
6409 /* Withdraw specified route type's route. */
6410 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6411 unsigned short instance
)
6413 struct bgp_node
*rn
;
6414 struct bgp_path_info
*pi
;
6415 struct bgp_table
*table
;
6417 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6419 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6420 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
6421 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
6422 && pi
->instance
== instance
)
6426 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6427 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6429 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6432 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
6434 bgp_path_info_delete(rn
, pi
);
6435 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6440 /* Static function to display route. */
6441 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6448 if (p
->family
== AF_INET
) {
6452 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6455 json_object_string_add(json
, "prefix",
6456 inet_ntop(p
->family
,
6459 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6460 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6461 json_object_string_add(json
, "network", buf2
);
6463 } else if (p
->family
== AF_ETHERNET
) {
6464 prefix2str(p
, buf
, PREFIX_STRLEN
);
6465 len
= vty_out(vty
, "%s", buf
);
6466 } else if (p
->family
== AF_EVPN
) {
6470 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6473 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6474 } else if (p
->family
== AF_FLOWSPEC
) {
6475 route_vty_out_flowspec(vty
, p
, NULL
,
6477 NLRI_STRING_FORMAT_JSON_SIMPLE
:
6478 NLRI_STRING_FORMAT_MIN
, json
);
6483 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6486 json_object_string_add(json
, "prefix",
6487 inet_ntop(p
->family
,
6490 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6491 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6492 json_object_string_add(json
, "network", buf2
);
6499 vty_out(vty
, "\n%*s", 20, " ");
6501 vty_out(vty
, "%*s", len
, " ");
6505 enum bgp_display_type
{
6509 /* Print the short form route status for a bgp_path_info */
6510 static void route_vty_short_status_out(struct vty
*vty
,
6511 struct bgp_path_info
*path
,
6512 json_object
*json_path
)
6516 /* Route status display. */
6517 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6518 json_object_boolean_true_add(json_path
, "removed");
6520 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6521 json_object_boolean_true_add(json_path
, "stale");
6523 if (path
->extra
&& path
->extra
->suppress
)
6524 json_object_boolean_true_add(json_path
, "suppressed");
6526 if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6527 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6528 json_object_boolean_true_add(json_path
, "valid");
6531 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6532 json_object_boolean_true_add(json_path
, "history");
6534 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6535 json_object_boolean_true_add(json_path
, "damped");
6537 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6538 json_object_boolean_true_add(json_path
, "bestpath");
6540 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6541 json_object_boolean_true_add(json_path
, "multipath");
6543 /* Internal route. */
6544 if ((path
->peer
->as
)
6545 && (path
->peer
->as
== path
->peer
->local_as
))
6546 json_object_string_add(json_path
, "pathFrom",
6549 json_object_string_add(json_path
, "pathFrom",
6555 /* Route status display. */
6556 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6558 else if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6560 else if (path
->extra
&& path
->extra
->suppress
)
6562 else if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6563 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6569 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6571 else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6573 else if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6575 else if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6580 /* Internal route. */
6581 if (path
->peer
&& (path
->peer
->as
)
6582 && (path
->peer
->as
== path
->peer
->local_as
))
6588 /* called from terminal list command */
6589 void route_vty_out(struct vty
*vty
, struct prefix
*p
,
6590 struct bgp_path_info
*path
, int display
, safi_t safi
,
6591 json_object
*json_paths
)
6594 json_object
*json_path
= NULL
;
6595 json_object
*json_nexthops
= NULL
;
6596 json_object
*json_nexthop_global
= NULL
;
6597 json_object
*json_nexthop_ll
= NULL
;
6598 char vrf_id_str
[VRF_NAMSIZ
] = {0};
6600 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
6601 bool nexthop_othervrf
= false;
6602 vrf_id_t nexthop_vrfid
= VRF_DEFAULT
;
6603 const char *nexthop_vrfname
= VRF_DEFAULT_NAME
;
6606 json_path
= json_object_new_object();
6608 /* short status lead text */
6609 route_vty_short_status_out(vty
, path
, json_path
);
6612 /* print prefix and mask */
6614 route_vty_out_route(p
, vty
, json_path
);
6616 vty_out(vty
, "%*s", 17, " ");
6618 route_vty_out_route(p
, vty
, json_path
);
6621 /* Print attribute */
6625 json_object_array_add(json_paths
, json_path
);
6633 * If vrf id of nexthop is different from that of prefix,
6634 * set up printable string to append
6636 if (path
->extra
&& path
->extra
->bgp_orig
) {
6637 const char *self
= "";
6642 nexthop_othervrf
= true;
6643 nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
6645 if (path
->extra
->bgp_orig
->vrf_id
== VRF_UNKNOWN
)
6646 snprintf(vrf_id_str
, sizeof(vrf_id_str
),
6647 "@%s%s", VRFID_NONE_STR
, self
);
6649 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "@%u%s",
6650 path
->extra
->bgp_orig
->vrf_id
, self
);
6652 if (path
->extra
->bgp_orig
->inst_type
6653 != BGP_INSTANCE_TYPE_DEFAULT
)
6655 nexthop_vrfname
= path
->extra
->bgp_orig
->name
;
6657 const char *self
= "";
6662 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "%s", self
);
6666 * For ENCAP and EVPN routes, nexthop address family is not
6667 * neccessarily the same as the prefix address family.
6668 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6669 * EVPN routes are also exchanged with a MP nexthop. Currently,
6671 * is only IPv4, the value will be present in either
6673 * attr->mp_nexthop_global_in
6675 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6678 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6682 sprintf(nexthop
, "%s",
6683 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6687 sprintf(nexthop
, "%s",
6688 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6692 sprintf(nexthop
, "?");
6697 json_nexthop_global
= json_object_new_object();
6699 json_object_string_add(json_nexthop_global
, "afi",
6700 (af
== AF_INET
) ? "ip" : "ipv6");
6701 json_object_string_add(json_nexthop_global
,
6702 (af
== AF_INET
) ? "ip" : "ipv6",
6704 json_object_boolean_true_add(json_nexthop_global
,
6707 vty_out(vty
, "%s%s", nexthop
, vrf_id_str
);
6708 } else if (safi
== SAFI_EVPN
) {
6710 json_nexthop_global
= json_object_new_object();
6712 json_object_string_add(json_nexthop_global
, "ip",
6713 inet_ntoa(attr
->nexthop
));
6714 json_object_string_add(json_nexthop_global
, "afi",
6716 json_object_boolean_true_add(json_nexthop_global
,
6719 vty_out(vty
, "%-16s%s", inet_ntoa(attr
->nexthop
),
6721 } else if (safi
== SAFI_FLOWSPEC
) {
6722 if (attr
->nexthop
.s_addr
!= 0) {
6724 json_nexthop_global
= json_object_new_object();
6725 json_object_string_add(
6726 json_nexthop_global
, "ip",
6727 inet_ntoa(attr
->nexthop
));
6728 json_object_string_add(json_nexthop_global
,
6730 json_object_boolean_true_add(
6731 json_nexthop_global
,
6734 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6737 } else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6739 json_nexthop_global
= json_object_new_object();
6741 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6742 json_object_string_add(
6743 json_nexthop_global
, "ip",
6744 inet_ntoa(attr
->mp_nexthop_global_in
));
6746 json_object_string_add(
6747 json_nexthop_global
, "ip",
6748 inet_ntoa(attr
->nexthop
));
6750 json_object_string_add(json_nexthop_global
, "afi",
6752 json_object_boolean_true_add(json_nexthop_global
,
6757 snprintf(buf
, sizeof(buf
), "%s%s",
6758 inet_ntoa(attr
->nexthop
), vrf_id_str
);
6759 vty_out(vty
, "%-16s", buf
);
6764 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6769 json_nexthop_global
= json_object_new_object();
6770 json_object_string_add(
6771 json_nexthop_global
, "ip",
6772 inet_ntop(AF_INET6
, &attr
->mp_nexthop_global
,
6774 json_object_string_add(json_nexthop_global
, "afi",
6776 json_object_string_add(json_nexthop_global
, "scope",
6779 /* We display both LL & GL if both have been
6781 if ((attr
->mp_nexthop_len
== 32)
6782 || (path
->peer
->conf_if
)) {
6783 json_nexthop_ll
= json_object_new_object();
6784 json_object_string_add(
6785 json_nexthop_ll
, "ip",
6787 &attr
->mp_nexthop_local
, buf
,
6789 json_object_string_add(json_nexthop_ll
, "afi",
6791 json_object_string_add(json_nexthop_ll
, "scope",
6794 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
6795 &attr
->mp_nexthop_local
)
6797 && !attr
->mp_nexthop_prefer_global
)
6798 json_object_boolean_true_add(
6799 json_nexthop_ll
, "used");
6801 json_object_boolean_true_add(
6802 json_nexthop_global
, "used");
6804 json_object_boolean_true_add(
6805 json_nexthop_global
, "used");
6807 /* Display LL if LL/Global both in table unless
6808 * prefer-global is set */
6809 if (((attr
->mp_nexthop_len
== 32)
6810 && !attr
->mp_nexthop_prefer_global
)
6811 || (path
->peer
->conf_if
)) {
6812 if (path
->peer
->conf_if
) {
6813 len
= vty_out(vty
, "%s",
6814 path
->peer
->conf_if
);
6815 len
= 16 - len
; /* len of IPv6
6821 vty_out(vty
, "\n%*s", 36, " ");
6823 vty_out(vty
, "%*s", len
, " ");
6829 &attr
->mp_nexthop_local
,
6835 vty_out(vty
, "\n%*s", 36, " ");
6837 vty_out(vty
, "%*s", len
, " ");
6843 &attr
->mp_nexthop_global
, buf
,
6849 vty_out(vty
, "\n%*s", 36, " ");
6851 vty_out(vty
, "%*s", len
, " ");
6857 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6861 * Adding "metric" field to match with corresponding
6862 * CLI. "med" will be deprecated in future.
6864 json_object_int_add(json_path
, "med", attr
->med
);
6865 json_object_int_add(json_path
, "metric", attr
->med
);
6867 vty_out(vty
, "%10u", attr
->med
);
6868 else if (!json_paths
)
6872 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6876 * Adding "locPrf" field to match with corresponding
6877 * CLI. "localPref" will be deprecated in future.
6879 json_object_int_add(json_path
, "localpref",
6881 json_object_int_add(json_path
, "locPrf",
6884 vty_out(vty
, "%7u", attr
->local_pref
);
6885 else if (!json_paths
)
6889 json_object_int_add(json_path
, "weight", attr
->weight
);
6891 vty_out(vty
, "%7u ", attr
->weight
);
6895 json_object_string_add(
6896 json_path
, "peerId",
6897 sockunion2str(&path
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6905 * Adding "path" field to match with corresponding
6906 * CLI. "aspath" will be deprecated in future.
6908 json_object_string_add(json_path
, "aspath",
6910 json_object_string_add(json_path
, "path",
6913 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6918 json_object_string_add(json_path
, "origin",
6919 bgp_origin_long_str
[attr
->origin
]);
6921 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6925 json_object_boolean_true_add(json_path
,
6926 "announceNexthopSelf");
6927 if (nexthop_othervrf
) {
6928 json_object_string_add(json_path
, "nhVrfName",
6931 json_object_int_add(json_path
, "nhVrfId",
6932 ((nexthop_vrfid
== VRF_UNKNOWN
)
6934 : (int)nexthop_vrfid
));
6939 if (json_nexthop_global
|| json_nexthop_ll
) {
6940 json_nexthops
= json_object_new_array();
6942 if (json_nexthop_global
)
6943 json_object_array_add(json_nexthops
,
6944 json_nexthop_global
);
6946 if (json_nexthop_ll
)
6947 json_object_array_add(json_nexthops
,
6950 json_object_object_add(json_path
, "nexthops",
6954 json_object_array_add(json_paths
, json_path
);
6958 /* prints an additional line, indented, with VNC info, if
6960 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6961 rfapi_vty_out_vncinfo(vty
, p
, path
, safi
);
6966 /* called from terminal list command */
6967 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6968 safi_t safi
, bool use_json
, json_object
*json_ar
)
6970 json_object
*json_status
= NULL
;
6971 json_object
*json_net
= NULL
;
6974 /* Route status display. */
6976 json_status
= json_object_new_object();
6977 json_net
= json_object_new_object();
6984 /* print prefix and mask */
6986 json_object_string_add(
6987 json_net
, "addrPrefix",
6988 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6989 json_object_int_add(json_net
, "prefixLen", p
->prefixlen
);
6990 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6991 json_object_string_add(json_net
, "network", buf2
);
6993 route_vty_out_route(p
, vty
, NULL
);
6995 /* Print attribute */
6998 if (p
->family
== AF_INET
6999 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7000 || safi
== SAFI_EVPN
7001 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7002 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7003 || safi
== SAFI_EVPN
)
7004 json_object_string_add(
7005 json_net
, "nextHop",
7007 attr
->mp_nexthop_global_in
));
7009 json_object_string_add(
7010 json_net
, "nextHop",
7011 inet_ntoa(attr
->nexthop
));
7012 } else if (p
->family
== AF_INET6
7013 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7016 json_object_string_add(
7017 json_net
, "nextHopGlobal",
7019 &attr
->mp_nexthop_global
, buf
,
7024 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7025 json_object_int_add(json_net
, "metric",
7028 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7031 * Adding "locPrf" field to match with
7032 * corresponding CLI. "localPref" will be
7033 * deprecated in future.
7035 json_object_int_add(json_net
, "localPref",
7037 json_object_int_add(json_net
, "locPrf",
7041 json_object_int_add(json_net
, "weight", attr
->weight
);
7047 * Adding "path" field to match with
7048 * corresponding CLI. "localPref" will be
7049 * deprecated in future.
7051 json_object_string_add(json_net
, "asPath",
7053 json_object_string_add(json_net
, "path",
7058 json_object_string_add(json_net
, "bgpOriginCode",
7059 bgp_origin_str
[attr
->origin
]);
7061 if (p
->family
== AF_INET
7062 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7063 || safi
== SAFI_EVPN
7064 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7065 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7066 || safi
== SAFI_EVPN
)
7067 vty_out(vty
, "%-16s",
7069 attr
->mp_nexthop_global_in
));
7071 vty_out(vty
, "%-16s",
7072 inet_ntoa(attr
->nexthop
));
7073 } else if (p
->family
== AF_INET6
7074 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7081 &attr
->mp_nexthop_global
, buf
,
7085 vty_out(vty
, "\n%*s", 36, " ");
7087 vty_out(vty
, "%*s", len
, " ");
7090 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7091 vty_out(vty
, "%10u", attr
->med
);
7095 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7096 vty_out(vty
, "%7u", attr
->local_pref
);
7100 vty_out(vty
, "%7u ", attr
->weight
);
7104 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7107 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7111 json_object_boolean_true_add(json_status
, "*");
7112 json_object_boolean_true_add(json_status
, ">");
7113 json_object_object_add(json_net
, "appliedStatusSymbols",
7115 char buf_cut
[BUFSIZ
];
7116 json_object_object_add(
7118 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
7124 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
7125 struct bgp_path_info
*path
, int display
, safi_t safi
,
7128 json_object
*json_out
= NULL
;
7130 mpls_label_t label
= MPLS_INVALID_LABEL
;
7136 json_out
= json_object_new_object();
7138 /* short status lead text */
7139 route_vty_short_status_out(vty
, path
, json_out
);
7141 /* print prefix and mask */
7144 route_vty_out_route(p
, vty
, NULL
);
7146 vty_out(vty
, "%*s", 17, " ");
7149 /* Print attribute */
7152 if (((p
->family
== AF_INET
)
7153 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7154 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7155 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7156 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7157 || safi
== SAFI_EVPN
) {
7159 json_object_string_add(
7160 json_out
, "mpNexthopGlobalIn",
7162 attr
->mp_nexthop_global_in
));
7164 vty_out(vty
, "%-16s",
7166 attr
->mp_nexthop_global_in
));
7169 json_object_string_add(
7170 json_out
, "nexthop",
7171 inet_ntoa(attr
->nexthop
));
7173 vty_out(vty
, "%-16s",
7174 inet_ntoa(attr
->nexthop
));
7176 } else if (((p
->family
== AF_INET6
)
7177 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7178 || (safi
== SAFI_EVPN
7179 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7180 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7184 if (attr
->mp_nexthop_len
7185 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
7187 json_object_string_add(
7188 json_out
, "mpNexthopGlobalIn",
7191 &attr
->mp_nexthop_global
,
7192 buf_a
, sizeof(buf_a
)));
7197 &attr
->mp_nexthop_global
,
7198 buf_a
, sizeof(buf_a
)));
7199 } else if (attr
->mp_nexthop_len
7200 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7203 &attr
->mp_nexthop_global
,
7204 buf_a
, sizeof(buf_a
));
7206 &attr
->mp_nexthop_local
,
7207 buf_b
, sizeof(buf_b
));
7208 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
7209 json_object_string_add(
7211 "mpNexthopGlobalLocal", buf_c
);
7213 vty_out(vty
, "%s(%s)",
7216 &attr
->mp_nexthop_global
,
7217 buf_a
, sizeof(buf_a
)),
7220 &attr
->mp_nexthop_local
,
7221 buf_b
, sizeof(buf_b
)));
7226 label
= decode_label(&path
->extra
->label
[0]);
7228 if (bgp_is_valid_label(&label
)) {
7230 json_object_int_add(json_out
, "notag", label
);
7231 json_object_array_add(json
, json_out
);
7233 vty_out(vty
, "notag/%d", label
);
7239 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
7240 struct bgp_path_info
*path
, int display
,
7241 json_object
*json_paths
)
7245 json_object
*json_path
= NULL
;
7248 json_path
= json_object_new_object();
7253 /* short status lead text */
7254 route_vty_short_status_out(vty
, path
, json_path
);
7256 /* print prefix and mask */
7258 route_vty_out_route(p
, vty
, NULL
);
7260 vty_out(vty
, "%*s", 17, " ");
7262 /* Print attribute */
7266 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
7270 vty_out(vty
, "%-16s",
7271 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
7275 vty_out(vty
, "%s(%s)",
7276 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
7278 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
7285 char *str
= esi2str(&(attr
->evpn_overlay
.eth_s_id
));
7287 vty_out(vty
, "%s", str
);
7288 XFREE(MTYPE_TMP
, str
);
7290 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn
*)p
)) {
7292 inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
7293 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn
*)p
)) {
7296 &(attr
->evpn_overlay
.gw_ip
.ipv6
), buf
,
7299 if (attr
->ecommunity
) {
7301 struct ecommunity_val
*routermac
= ecommunity_lookup(
7302 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
7303 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
7305 mac
= ecom_mac2str((char *)routermac
->val
);
7307 vty_out(vty
, "/%s", (char *)mac
);
7308 XFREE(MTYPE_TMP
, mac
);
7316 /* dampening route */
7317 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7318 struct bgp_path_info
*path
, int display
,
7319 safi_t safi
, bool use_json
, json_object
*json
)
7323 char timebuf
[BGP_UPTIME_LEN
];
7325 /* short status lead text */
7326 route_vty_short_status_out(vty
, path
, json
);
7328 /* print prefix and mask */
7331 route_vty_out_route(p
, vty
, NULL
);
7333 vty_out(vty
, "%*s", 17, " ");
7336 len
= vty_out(vty
, "%s", path
->peer
->host
);
7340 vty_out(vty
, "\n%*s", 34, " ");
7343 json_object_int_add(json
, "peerHost", len
);
7345 vty_out(vty
, "%*s", len
, " ");
7349 bgp_damp_reuse_time_vty(vty
, path
, timebuf
, BGP_UPTIME_LEN
,
7353 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7354 BGP_UPTIME_LEN
, use_json
,
7357 /* Print attribute */
7363 json_object_string_add(json
, "asPath",
7366 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7371 json_object_string_add(json
, "origin",
7372 bgp_origin_str
[attr
->origin
]);
7374 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7381 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7382 struct bgp_path_info
*path
, int display
,
7383 safi_t safi
, bool use_json
, json_object
*json
)
7386 struct bgp_damp_info
*bdi
;
7387 char timebuf
[BGP_UPTIME_LEN
];
7393 bdi
= path
->extra
->damp_info
;
7395 /* short status lead text */
7396 route_vty_short_status_out(vty
, path
, json
);
7398 /* print prefix and mask */
7401 route_vty_out_route(p
, vty
, NULL
);
7403 vty_out(vty
, "%*s", 17, " ");
7406 len
= vty_out(vty
, "%s", path
->peer
->host
);
7410 vty_out(vty
, "\n%*s", 33, " ");
7413 json_object_int_add(json
, "peerHost", len
);
7415 vty_out(vty
, "%*s", len
, " ");
7418 len
= vty_out(vty
, "%d", bdi
->flap
);
7425 json_object_int_add(json
, "bdiFlap", len
);
7427 vty_out(vty
, "%*s", len
, " ");
7431 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7434 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7435 BGP_UPTIME_LEN
, 0, NULL
));
7437 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)
7438 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7440 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7441 BGP_UPTIME_LEN
, use_json
, json
);
7444 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7449 vty_out(vty
, "%*s ", 8, " ");
7452 /* Print attribute */
7458 json_object_string_add(json
, "asPath",
7461 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7466 json_object_string_add(json
, "origin",
7467 bgp_origin_str
[attr
->origin
]);
7469 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7475 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7476 int *first
, const char *header
,
7477 json_object
*json_adv_to
)
7479 char buf1
[INET6_ADDRSTRLEN
];
7480 json_object
*json_peer
= NULL
;
7483 /* 'advertised-to' is a dictionary of peers we have advertised
7485 * prefix too. The key is the peer's IP or swpX, the value is
7487 * hostname if we know it and "" if not.
7489 json_peer
= json_object_new_object();
7492 json_object_string_add(json_peer
, "hostname",
7496 json_object_object_add(json_adv_to
, peer
->conf_if
,
7499 json_object_object_add(
7501 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7505 vty_out(vty
, "%s", header
);
7510 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7512 vty_out(vty
, " %s(%s)", peer
->hostname
,
7515 vty_out(vty
, " %s(%s)", peer
->hostname
,
7516 sockunion2str(&peer
->su
, buf1
,
7520 vty_out(vty
, " %s", peer
->conf_if
);
7523 sockunion2str(&peer
->su
, buf1
,
7529 static void route_vty_out_tx_ids(struct vty
*vty
,
7530 struct bgp_addpath_info_data
*d
)
7534 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
7535 vty_out(vty
, "TX-%s %u%s", bgp_addpath_names(i
)->human_name
,
7536 d
->addpath_tx_id
[i
],
7537 i
< BGP_ADDPATH_MAX
- 1 ? " " : "\n");
7541 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7542 struct bgp_path_info
*path
, afi_t afi
, safi_t safi
,
7543 json_object
*json_paths
)
7545 char buf
[INET6_ADDRSTRLEN
];
7547 char buf2
[EVPN_ROUTE_STRLEN
];
7549 int sockunion_vty_out(struct vty
*, union sockunion
*);
7551 json_object
*json_bestpath
= NULL
;
7552 json_object
*json_cluster_list
= NULL
;
7553 json_object
*json_cluster_list_list
= NULL
;
7554 json_object
*json_ext_community
= NULL
;
7555 json_object
*json_last_update
= NULL
;
7556 json_object
*json_pmsi
= NULL
;
7557 json_object
*json_nexthop_global
= NULL
;
7558 json_object
*json_nexthop_ll
= NULL
;
7559 json_object
*json_nexthops
= NULL
;
7560 json_object
*json_path
= NULL
;
7561 json_object
*json_peer
= NULL
;
7562 json_object
*json_string
= NULL
;
7563 json_object
*json_adv_to
= NULL
;
7565 struct listnode
*node
, *nnode
;
7567 int addpath_capable
;
7569 unsigned int first_as
;
7571 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
7575 json_path
= json_object_new_object();
7576 json_peer
= json_object_new_object();
7577 json_nexthop_global
= json_object_new_object();
7580 if (!json_paths
&& safi
== SAFI_EVPN
) {
7583 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7584 vty_out(vty
, " Route %s", buf2
);
7586 if (path
->extra
&& path
->extra
->num_labels
) {
7587 bgp_evpn_label2str(path
->extra
->label
,
7588 path
->extra
->num_labels
, tag_buf
,
7590 vty_out(vty
, " VNI %s", tag_buf
);
7593 if (path
->extra
&& path
->extra
->parent
) {
7594 struct bgp_path_info
*parent_ri
;
7595 struct bgp_node
*rn
, *prn
;
7597 parent_ri
= (struct bgp_path_info
*)path
->extra
->parent
;
7598 rn
= parent_ri
->net
;
7599 if (rn
&& rn
->prn
) {
7601 vty_out(vty
, " Imported from %s:%s\n",
7603 (struct prefix_rd
*)&prn
->p
,
7604 buf1
, sizeof(buf1
)),
7613 /* Line1 display AS-path, Aggregator */
7616 if (!attr
->aspath
->json
)
7617 aspath_str_update(attr
->aspath
, true);
7618 json_object_lock(attr
->aspath
->json
);
7619 json_object_object_add(json_path
, "aspath",
7620 attr
->aspath
->json
);
7622 if (attr
->aspath
->segments
)
7623 aspath_print_vty(vty
, " %s",
7626 vty_out(vty
, " Local");
7630 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
)) {
7632 json_object_boolean_true_add(json_path
,
7635 vty_out(vty
, ", (removed)");
7638 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
)) {
7640 json_object_boolean_true_add(json_path
,
7643 vty_out(vty
, ", (stale)");
7646 if (CHECK_FLAG(attr
->flag
,
7647 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7649 json_object_int_add(json_path
, "aggregatorAs",
7650 attr
->aggregator_as
);
7651 json_object_string_add(
7652 json_path
, "aggregatorId",
7653 inet_ntoa(attr
->aggregator_addr
));
7655 vty_out(vty
, ", (aggregated by %u %s)",
7656 attr
->aggregator_as
,
7657 inet_ntoa(attr
->aggregator_addr
));
7661 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
7662 PEER_FLAG_REFLECTOR_CLIENT
)) {
7664 json_object_boolean_true_add(
7665 json_path
, "rxedFromRrClient");
7667 vty_out(vty
, ", (Received from a RR-client)");
7670 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
7671 PEER_FLAG_RSERVER_CLIENT
)) {
7673 json_object_boolean_true_add(
7674 json_path
, "rxedFromRsClient");
7676 vty_out(vty
, ", (Received from a RS-client)");
7679 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7681 json_object_boolean_true_add(
7682 json_path
, "dampeningHistoryEntry");
7684 vty_out(vty
, ", (history entry)");
7685 } else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)) {
7687 json_object_boolean_true_add(
7688 json_path
, "dampeningSuppressed");
7690 vty_out(vty
, ", (suppressed due to dampening)");
7696 /* Line2 display Next-hop, Neighbor, Router-id */
7697 /* Display the nexthop */
7698 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
7699 || p
->family
== AF_EVPN
)
7700 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7701 || safi
== SAFI_EVPN
7702 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7703 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7704 || safi
== SAFI_EVPN
) {
7706 json_object_string_add(
7707 json_nexthop_global
, "ip",
7709 attr
->mp_nexthop_global_in
));
7713 attr
->mp_nexthop_global_in
));
7716 json_object_string_add(
7717 json_nexthop_global
, "ip",
7718 inet_ntoa(attr
->nexthop
));
7721 inet_ntoa(attr
->nexthop
));
7725 json_object_string_add(json_nexthop_global
,
7729 json_object_string_add(
7730 json_nexthop_global
, "ip",
7732 &attr
->mp_nexthop_global
, buf
,
7734 json_object_string_add(json_nexthop_global
,
7736 json_object_string_add(json_nexthop_global
,
7741 &attr
->mp_nexthop_global
, buf
,
7746 /* Display the IGP cost or 'inaccessible' */
7747 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
7749 json_object_boolean_false_add(
7750 json_nexthop_global
, "accessible");
7752 vty_out(vty
, " (inaccessible)");
7754 if (path
->extra
&& path
->extra
->igpmetric
) {
7756 json_object_int_add(
7757 json_nexthop_global
, "metric",
7758 path
->extra
->igpmetric
);
7760 vty_out(vty
, " (metric %u)",
7761 path
->extra
->igpmetric
);
7764 /* IGP cost is 0, display this only for json */
7767 json_object_int_add(json_nexthop_global
,
7772 json_object_boolean_true_add(
7773 json_nexthop_global
, "accessible");
7776 /* Display peer "from" output */
7777 /* This path was originated locally */
7778 if (path
->peer
== bgp
->peer_self
) {
7780 if (safi
== SAFI_EVPN
7781 || (p
->family
== AF_INET
7782 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7784 json_object_string_add(
7785 json_peer
, "peerId", "0.0.0.0");
7787 vty_out(vty
, " from 0.0.0.0 ");
7790 json_object_string_add(json_peer
,
7793 vty_out(vty
, " from :: ");
7797 json_object_string_add(
7798 json_peer
, "routerId",
7799 inet_ntoa(bgp
->router_id
));
7801 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7804 /* We RXed this path from one of our peers */
7808 json_object_string_add(
7809 json_peer
, "peerId",
7810 sockunion2str(&path
->peer
->su
, buf
,
7812 json_object_string_add(
7813 json_peer
, "routerId",
7815 &path
->peer
->remote_id
, buf1
,
7818 if (path
->peer
->hostname
)
7819 json_object_string_add(
7820 json_peer
, "hostname",
7821 path
->peer
->hostname
);
7823 if (path
->peer
->domainname
)
7824 json_object_string_add(
7825 json_peer
, "domainname",
7826 path
->peer
->domainname
);
7828 if (path
->peer
->conf_if
)
7829 json_object_string_add(
7830 json_peer
, "interface",
7831 path
->peer
->conf_if
);
7833 if (path
->peer
->conf_if
) {
7834 if (path
->peer
->hostname
7837 BGP_FLAG_SHOW_HOSTNAME
))
7838 vty_out(vty
, " from %s(%s)",
7839 path
->peer
->hostname
,
7840 path
->peer
->conf_if
);
7842 vty_out(vty
, " from %s",
7843 path
->peer
->conf_if
);
7845 if (path
->peer
->hostname
7848 BGP_FLAG_SHOW_HOSTNAME
))
7849 vty_out(vty
, " from %s(%s)",
7850 path
->peer
->hostname
,
7853 vty_out(vty
, " from %s",
7861 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7862 vty_out(vty
, " (%s)",
7863 inet_ntoa(attr
->originator_id
));
7865 vty_out(vty
, " (%s)",
7868 &path
->peer
->remote_id
,
7869 buf1
, sizeof(buf1
)));
7874 * Note when vrfid of nexthop is different from that of prefix
7876 if (path
->extra
&& path
->extra
->bgp_orig
) {
7877 vrf_id_t nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
7882 if (path
->extra
->bgp_orig
->inst_type
7883 == BGP_INSTANCE_TYPE_DEFAULT
)
7885 vn
= VRF_DEFAULT_NAME
;
7887 vn
= path
->extra
->bgp_orig
->name
;
7889 json_object_string_add(json_path
, "nhVrfName",
7892 if (nexthop_vrfid
== VRF_UNKNOWN
) {
7893 json_object_int_add(json_path
,
7896 json_object_int_add(json_path
,
7897 "nhVrfId", (int)nexthop_vrfid
);
7900 if (nexthop_vrfid
== VRF_UNKNOWN
)
7901 vty_out(vty
, " vrf ?");
7903 vty_out(vty
, " vrf %u", nexthop_vrfid
);
7909 json_object_boolean_true_add(json_path
,
7910 "announceNexthopSelf");
7912 vty_out(vty
, " announce-nh-self");
7919 /* display the link-local nexthop */
7920 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7922 json_nexthop_ll
= json_object_new_object();
7923 json_object_string_add(
7924 json_nexthop_ll
, "ip",
7926 &attr
->mp_nexthop_local
, buf
,
7928 json_object_string_add(json_nexthop_ll
, "afi",
7930 json_object_string_add(json_nexthop_ll
, "scope",
7933 json_object_boolean_true_add(json_nexthop_ll
,
7936 if (!attr
->mp_nexthop_prefer_global
)
7937 json_object_boolean_true_add(
7938 json_nexthop_ll
, "used");
7940 json_object_boolean_true_add(
7941 json_nexthop_global
, "used");
7943 vty_out(vty
, " (%s) %s\n",
7945 &attr
->mp_nexthop_local
, buf
,
7947 attr
->mp_nexthop_prefer_global
7952 /* If we do not have a link-local nexthop then we must flag the
7956 json_object_boolean_true_add(
7957 json_nexthop_global
, "used");
7960 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7961 * Int/Ext/Local, Atomic, best */
7963 json_object_string_add(
7964 json_path
, "origin",
7965 bgp_origin_long_str
[attr
->origin
]);
7967 vty_out(vty
, " Origin %s",
7968 bgp_origin_long_str
[attr
->origin
]);
7970 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7974 * Adding "metric" field to match with
7975 * corresponding CLI. "med" will be
7976 * deprecated in future.
7978 json_object_int_add(json_path
, "med",
7980 json_object_int_add(json_path
, "metric",
7983 vty_out(vty
, ", metric %u", attr
->med
);
7986 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7988 json_object_int_add(json_path
, "localpref",
7991 vty_out(vty
, ", localpref %u",
7995 if (attr
->weight
!= 0) {
7997 json_object_int_add(json_path
, "weight",
8000 vty_out(vty
, ", weight %u", attr
->weight
);
8003 if (attr
->tag
!= 0) {
8005 json_object_int_add(json_path
, "tag",
8008 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
8012 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
8014 json_object_boolean_false_add(json_path
,
8017 vty_out(vty
, ", invalid");
8018 } else if (!CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
8020 json_object_boolean_true_add(json_path
,
8023 vty_out(vty
, ", valid");
8026 if (path
->peer
!= bgp
->peer_self
) {
8027 if (path
->peer
->as
== path
->peer
->local_as
) {
8028 if (CHECK_FLAG(bgp
->config
,
8029 BGP_CONFIG_CONFEDERATION
)) {
8031 json_object_string_add(
8036 ", confed-internal");
8039 json_object_string_add(
8043 vty_out(vty
, ", internal");
8046 if (bgp_confederation_peers_check(
8047 bgp
, path
->peer
->as
)) {
8049 json_object_string_add(
8054 ", confed-external");
8057 json_object_string_add(
8061 vty_out(vty
, ", external");
8064 } else if (path
->sub_type
== BGP_ROUTE_AGGREGATE
) {
8066 json_object_boolean_true_add(json_path
,
8068 json_object_boolean_true_add(json_path
,
8071 vty_out(vty
, ", aggregated, local");
8073 } else if (path
->type
!= ZEBRA_ROUTE_BGP
) {
8075 json_object_boolean_true_add(json_path
,
8078 vty_out(vty
, ", sourced");
8081 json_object_boolean_true_add(json_path
,
8083 json_object_boolean_true_add(json_path
,
8086 vty_out(vty
, ", sourced, local");
8090 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
8092 json_object_boolean_true_add(json_path
,
8095 vty_out(vty
, ", atomic-aggregate");
8098 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
)
8099 || (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)
8100 && bgp_path_info_mpath_count(path
))) {
8102 json_object_boolean_true_add(json_path
,
8105 vty_out(vty
, ", multipath");
8108 // Mark the bestpath(s)
8109 if (CHECK_FLAG(path
->flags
, BGP_PATH_DMED_SELECTED
)) {
8110 first_as
= aspath_get_first_as(attr
->aspath
);
8115 json_object_new_object();
8116 json_object_int_add(json_bestpath
,
8117 "bestpathFromAs", first_as
);
8120 vty_out(vty
, ", bestpath-from-AS %u",
8124 ", bestpath-from-AS Local");
8128 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)) {
8132 json_object_new_object();
8133 json_object_boolean_true_add(json_bestpath
,
8136 vty_out(vty
, ", best");
8140 json_object_object_add(json_path
, "bestpath",
8146 /* Line 4 display Community */
8147 if (attr
->community
) {
8149 if (!attr
->community
->json
)
8150 community_str(attr
->community
, true);
8151 json_object_lock(attr
->community
->json
);
8152 json_object_object_add(json_path
, "community",
8153 attr
->community
->json
);
8155 vty_out(vty
, " Community: %s\n",
8156 attr
->community
->str
);
8160 /* Line 5 display Extended-community */
8161 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
8163 json_ext_community
= json_object_new_object();
8164 json_object_string_add(json_ext_community
,
8166 attr
->ecommunity
->str
);
8167 json_object_object_add(json_path
,
8168 "extendedCommunity",
8169 json_ext_community
);
8171 vty_out(vty
, " Extended Community: %s\n",
8172 attr
->ecommunity
->str
);
8176 /* Line 6 display Large community */
8177 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
8179 if (!attr
->lcommunity
->json
)
8180 lcommunity_str(attr
->lcommunity
, true);
8181 json_object_lock(attr
->lcommunity
->json
);
8182 json_object_object_add(json_path
,
8184 attr
->lcommunity
->json
);
8186 vty_out(vty
, " Large Community: %s\n",
8187 attr
->lcommunity
->str
);
8191 /* Line 7 display Originator, Cluster-id */
8192 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
8193 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
8195 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
8197 json_object_string_add(
8198 json_path
, "originatorId",
8199 inet_ntoa(attr
->originator_id
));
8201 vty_out(vty
, " Originator: %s",
8202 inet_ntoa(attr
->originator_id
));
8205 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
8210 json_object_new_object();
8211 json_cluster_list_list
=
8212 json_object_new_array();
8215 i
< attr
->cluster
->length
/ 4;
8217 json_string
= json_object_new_string(
8221 json_object_array_add(
8222 json_cluster_list_list
,
8226 /* struct cluster_list does not have
8228 * aspath and community do. Add this
8231 json_object_string_add(json_cluster_list,
8232 "string", attr->cluster->str);
8234 json_object_object_add(
8235 json_cluster_list
, "list",
8236 json_cluster_list_list
);
8237 json_object_object_add(
8238 json_path
, "clusterList",
8241 vty_out(vty
, ", Cluster list: ");
8244 i
< attr
->cluster
->length
/ 4;
8258 if (path
->extra
&& path
->extra
->damp_info
)
8259 bgp_damp_info_vty(vty
, path
, json_path
);
8262 if (path
->extra
&& bgp_is_valid_label(&path
->extra
->label
[0])
8263 && safi
!= SAFI_EVPN
) {
8264 mpls_label_t label
= label_pton(&path
->extra
->label
[0]);
8267 json_object_int_add(json_path
, "remoteLabel",
8270 vty_out(vty
, " Remote label: %d\n", label
);
8274 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
8276 json_object_int_add(json_path
, "labelIndex",
8279 vty_out(vty
, " Label Index: %d\n",
8283 /* Line 8 display Addpath IDs */
8284 if (path
->addpath_rx_id
8285 || bgp_addpath_info_has_ids(&path
->tx_addpath
)) {
8287 json_object_int_add(json_path
, "addpathRxId",
8288 path
->addpath_rx_id
);
8290 /* Keep backwards compatibility with the old API
8291 * by putting TX All's ID in the old field
8293 json_object_int_add(
8294 json_path
, "addpathTxId",
8295 path
->tx_addpath
.addpath_tx_id
8298 /* ... but create a specific field for each
8301 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
8302 json_object_int_add(
8304 bgp_addpath_names(i
)
8310 vty_out(vty
, " AddPath ID: RX %u, ",
8311 path
->addpath_rx_id
);
8313 route_vty_out_tx_ids(vty
, &path
->tx_addpath
);
8317 /* If we used addpath to TX a non-bestpath we need to display
8318 * "Advertised to" on a path-by-path basis
8320 if (bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
8323 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8325 bgp_addpath_encode_tx(peer
, afi
, safi
);
8326 has_adj
= bgp_adj_out_lookup(
8328 bgp_addpath_id_for_peer(
8330 &path
->tx_addpath
));
8332 if ((addpath_capable
&& has_adj
)
8333 || (!addpath_capable
&& has_adj
8334 && CHECK_FLAG(path
->flags
,
8335 BGP_PATH_SELECTED
))) {
8336 if (json_path
&& !json_adv_to
)
8338 json_object_new_object();
8340 route_vty_out_advertised_to(
8349 json_object_object_add(json_path
,
8360 /* Line 9 display Uptime */
8361 tbuf
= time(NULL
) - (bgp_clock() - path
->uptime
);
8363 json_last_update
= json_object_new_object();
8364 json_object_int_add(json_last_update
, "epoch", tbuf
);
8365 json_object_string_add(json_last_update
, "string",
8367 json_object_object_add(json_path
, "lastUpdate",
8370 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
8372 /* Line 10 display PMSI tunnel attribute, if present */
8373 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
8374 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
8375 attr
->pmsi_tnl_type
,
8376 PMSI_TNLTYPE_STR_DEFAULT
);
8379 json_pmsi
= json_object_new_object();
8380 json_object_string_add(json_pmsi
,
8382 json_object_object_add(json_path
, "pmsi",
8385 vty_out(vty
, " PMSI Tunnel Type: %s\n",
8391 /* We've constructed the json object for this path, add it to the json
8395 if (json_nexthop_global
|| json_nexthop_ll
) {
8396 json_nexthops
= json_object_new_array();
8398 if (json_nexthop_global
)
8399 json_object_array_add(json_nexthops
,
8400 json_nexthop_global
);
8402 if (json_nexthop_ll
)
8403 json_object_array_add(json_nexthops
,
8406 json_object_object_add(json_path
, "nexthops",
8410 json_object_object_add(json_path
, "peer", json_peer
);
8411 json_object_array_add(json_paths
, json_path
);
8416 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8417 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8418 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8420 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8421 const char *prefix_list_str
, afi_t afi
,
8422 safi_t safi
, enum bgp_show_type type
);
8423 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8424 const char *filter
, afi_t afi
, safi_t safi
,
8425 enum bgp_show_type type
);
8426 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8427 const char *rmap_str
, afi_t afi
, safi_t safi
,
8428 enum bgp_show_type type
);
8429 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8430 const char *com
, int exact
, afi_t afi
,
8432 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8433 const char *prefix
, afi_t afi
, safi_t safi
,
8434 enum bgp_show_type type
);
8435 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8436 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8437 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8438 const char *comstr
, int exact
, afi_t afi
,
8439 safi_t safi
, bool use_json
);
8442 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8443 struct bgp_table
*table
, enum bgp_show_type type
,
8444 void *output_arg
, bool use_json
, char *rd
,
8445 int is_last
, unsigned long *output_cum
,
8446 unsigned long *total_cum
,
8447 unsigned long *json_header_depth
)
8449 struct bgp_path_info
*pi
;
8450 struct bgp_node
*rn
;
8453 unsigned long output_count
= 0;
8454 unsigned long total_count
= 0;
8457 json_object
*json_paths
= NULL
;
8460 if (output_cum
&& *output_cum
!= 0)
8463 if (use_json
&& !*json_header_depth
) {
8465 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8466 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
8467 " \"localAS\": %u,\n \"routes\": { ",
8468 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
8469 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
8472 table
->version
, inet_ntoa(bgp
->router_id
),
8473 bgp
->default_local_pref
, bgp
->as
);
8474 *json_header_depth
= 2;
8476 vty_out(vty
, " \"routeDistinguishers\" : {");
8477 ++*json_header_depth
;
8481 if (use_json
&& rd
) {
8482 vty_out(vty
, " \"%s\" : { ", rd
);
8485 /* Start processing of routes. */
8486 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
8487 pi
= bgp_node_get_bgp_path_info(rn
);
8493 json_paths
= json_object_new_array();
8497 for (; pi
; pi
= pi
->next
) {
8499 if (type
== bgp_show_type_flap_statistics
8500 || type
== bgp_show_type_flap_neighbor
8501 || type
== bgp_show_type_dampend_paths
8502 || type
== bgp_show_type_damp_neighbor
) {
8503 if (!(pi
->extra
&& pi
->extra
->damp_info
))
8506 if (type
== bgp_show_type_regexp
) {
8507 regex_t
*regex
= output_arg
;
8509 if (bgp_regexec(regex
, pi
->attr
->aspath
)
8513 if (type
== bgp_show_type_prefix_list
) {
8514 struct prefix_list
*plist
= output_arg
;
8516 if (prefix_list_apply(plist
, &rn
->p
)
8520 if (type
== bgp_show_type_filter_list
) {
8521 struct as_list
*as_list
= output_arg
;
8523 if (as_list_apply(as_list
, pi
->attr
->aspath
)
8524 != AS_FILTER_PERMIT
)
8527 if (type
== bgp_show_type_route_map
) {
8528 struct route_map
*rmap
= output_arg
;
8529 struct bgp_path_info path
;
8530 struct attr dummy_attr
;
8533 bgp_attr_dup(&dummy_attr
, pi
->attr
);
8535 path
.peer
= pi
->peer
;
8536 path
.attr
= &dummy_attr
;
8538 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
8540 if (ret
== RMAP_DENYMATCH
)
8543 if (type
== bgp_show_type_neighbor
8544 || type
== bgp_show_type_flap_neighbor
8545 || type
== bgp_show_type_damp_neighbor
) {
8546 union sockunion
*su
= output_arg
;
8548 if (pi
->peer
== NULL
8549 || pi
->peer
->su_remote
== NULL
8550 || !sockunion_same(pi
->peer
->su_remote
, su
))
8553 if (type
== bgp_show_type_cidr_only
) {
8554 uint32_t destination
;
8556 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
8557 if (IN_CLASSC(destination
)
8558 && rn
->p
.prefixlen
== 24)
8560 if (IN_CLASSB(destination
)
8561 && rn
->p
.prefixlen
== 16)
8563 if (IN_CLASSA(destination
)
8564 && rn
->p
.prefixlen
== 8)
8567 if (type
== bgp_show_type_prefix_longer
) {
8569 if (!prefix_match(p
, &rn
->p
))
8572 if (type
== bgp_show_type_community_all
) {
8573 if (!pi
->attr
->community
)
8576 if (type
== bgp_show_type_community
) {
8577 struct community
*com
= output_arg
;
8579 if (!pi
->attr
->community
8580 || !community_match(pi
->attr
->community
,
8584 if (type
== bgp_show_type_community_exact
) {
8585 struct community
*com
= output_arg
;
8587 if (!pi
->attr
->community
8588 || !community_cmp(pi
->attr
->community
, com
))
8591 if (type
== bgp_show_type_community_list
) {
8592 struct community_list
*list
= output_arg
;
8594 if (!community_list_match(pi
->attr
->community
,
8598 if (type
== bgp_show_type_community_list_exact
) {
8599 struct community_list
*list
= output_arg
;
8601 if (!community_list_exact_match(
8602 pi
->attr
->community
, list
))
8605 if (type
== bgp_show_type_lcommunity
) {
8606 struct lcommunity
*lcom
= output_arg
;
8608 if (!pi
->attr
->lcommunity
8609 || !lcommunity_match(pi
->attr
->lcommunity
,
8613 if (type
== bgp_show_type_lcommunity_list
) {
8614 struct community_list
*list
= output_arg
;
8616 if (!lcommunity_list_match(pi
->attr
->lcommunity
,
8620 if (type
== bgp_show_type_lcommunity_all
) {
8621 if (!pi
->attr
->lcommunity
)
8624 if (type
== bgp_show_type_dampend_paths
8625 || type
== bgp_show_type_damp_neighbor
) {
8626 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
)
8627 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
8631 if (!use_json
&& header
) {
8632 vty_out(vty
, "BGP table version is %" PRIu64
8633 ", local router ID is %s, vrf id ",
8635 inet_ntoa(bgp
->router_id
));
8636 if (bgp
->vrf_id
== VRF_UNKNOWN
)
8637 vty_out(vty
, "%s", VRFID_NONE_STR
);
8639 vty_out(vty
, "%u", bgp
->vrf_id
);
8641 vty_out(vty
, "Default local pref %u, ",
8642 bgp
->default_local_pref
);
8643 vty_out(vty
, "local AS %u\n", bgp
->as
);
8644 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8645 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
8646 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8647 if (type
== bgp_show_type_dampend_paths
8648 || type
== bgp_show_type_damp_neighbor
)
8649 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
8650 else if (type
== bgp_show_type_flap_statistics
8651 || type
== bgp_show_type_flap_neighbor
)
8652 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
8654 vty_out(vty
, BGP_SHOW_HEADER
);
8657 if (rd
!= NULL
&& !display
&& !output_count
) {
8660 "Route Distinguisher: %s\n",
8663 if (type
== bgp_show_type_dampend_paths
8664 || type
== bgp_show_type_damp_neighbor
)
8665 damp_route_vty_out(vty
, &rn
->p
, pi
, display
,
8666 safi
, use_json
, json_paths
);
8667 else if (type
== bgp_show_type_flap_statistics
8668 || type
== bgp_show_type_flap_neighbor
)
8669 flap_route_vty_out(vty
, &rn
->p
, pi
, display
,
8670 safi
, use_json
, json_paths
);
8672 route_vty_out(vty
, &rn
->p
, pi
, display
, safi
,
8684 if (p
->family
== AF_FLOWSPEC
) {
8685 char retstr
[BGP_FLOWSPEC_STRING_DISPLAY_MAX
];
8687 bgp_fs_nlri_get_string((unsigned char *)
8688 p
->u
.prefix_flowspec
.ptr
,
8689 p
->u
.prefix_flowspec
8692 NLRI_STRING_FORMAT_MIN
,
8695 vty_out(vty
, "\"%s/%d\": ",
8697 p
->u
.prefix_flowspec
.prefixlen
);
8699 vty_out(vty
, ",\"%s/%d\": ",
8701 p
->u
.prefix_flowspec
.prefixlen
);
8703 prefix2str(p
, buf2
, sizeof(buf2
));
8705 vty_out(vty
, "\"%s\": ", buf2
);
8707 vty_out(vty
, ",\"%s\": ", buf2
);
8710 json_object_to_json_string(json_paths
));
8711 json_object_free(json_paths
);
8718 output_count
+= *output_cum
;
8719 *output_cum
= output_count
;
8722 total_count
+= *total_cum
;
8723 *total_cum
= total_count
;
8727 vty_out(vty
, " }%s ", (is_last
? "" : ","));
8731 for (i
= 0; i
< *json_header_depth
; ++i
)
8732 vty_out(vty
, " } ");
8736 /* No route is displayed */
8737 if (output_count
== 0) {
8738 if (type
== bgp_show_type_normal
)
8740 "No BGP prefixes displayed, %ld exist\n",
8744 "\nDisplayed %ld routes and %ld total paths\n",
8745 output_count
, total_count
);
8752 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8753 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
8754 enum bgp_show_type type
, void *output_arg
, bool use_json
)
8756 struct bgp_node
*rn
, *next
;
8757 unsigned long output_cum
= 0;
8758 unsigned long total_cum
= 0;
8759 unsigned long json_header_depth
= 0;
8760 struct bgp_table
*itable
;
8763 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
8765 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
8766 next
= bgp_route_next(rn
);
8767 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
8770 itable
= bgp_node_get_bgp_table_info(rn
);
8771 if (itable
!= NULL
) {
8772 struct prefix_rd prd
;
8773 char rd
[RD_ADDRSTRLEN
];
8775 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
8776 prefix_rd2str(&prd
, rd
, sizeof(rd
));
8777 bgp_show_table(vty
, bgp
, safi
, itable
, type
, output_arg
,
8778 use_json
, rd
, next
== NULL
, &output_cum
,
8779 &total_cum
, &json_header_depth
);
8785 if (output_cum
== 0)
8786 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
8790 "\nDisplayed %ld routes and %ld total paths\n",
8791 output_cum
, total_cum
);
8795 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8796 enum bgp_show_type type
, void *output_arg
, bool use_json
)
8798 struct bgp_table
*table
;
8799 unsigned long json_header_depth
= 0;
8802 bgp
= bgp_get_default();
8807 vty_out(vty
, "No BGP process is configured\n");
8809 vty_out(vty
, "{}\n");
8813 table
= bgp
->rib
[afi
][safi
];
8814 /* use MPLS and ENCAP specific shows until they are merged */
8815 if (safi
== SAFI_MPLS_VPN
) {
8816 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
8817 output_arg
, use_json
);
8820 if (safi
== SAFI_FLOWSPEC
&& type
== bgp_show_type_detail
) {
8821 return bgp_show_table_flowspec(vty
, bgp
, afi
, table
, type
,
8822 output_arg
, use_json
,
8825 /* labeled-unicast routes live in the unicast table */
8826 else if (safi
== SAFI_LABELED_UNICAST
)
8827 safi
= SAFI_UNICAST
;
8829 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
8830 NULL
, 1, NULL
, NULL
, &json_header_depth
);
8833 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8834 safi_t safi
, bool use_json
)
8836 struct listnode
*node
, *nnode
;
8839 bool route_output
= false;
8842 vty_out(vty
, "{\n");
8844 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8845 route_output
= true;
8848 vty_out(vty
, ",\n");
8852 vty_out(vty
, "\"%s\":",
8853 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8857 vty_out(vty
, "\nInstance %s:\n",
8858 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8862 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8867 vty_out(vty
, "}\n");
8868 else if (!route_output
)
8869 vty_out(vty
, "%% BGP instance not found\n");
8872 /* Header of detailed BGP route information */
8873 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8874 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8875 afi_t afi
, safi_t safi
, json_object
*json
)
8877 struct bgp_path_info
*pi
;
8880 struct listnode
*node
, *nnode
;
8881 char buf1
[RD_ADDRSTRLEN
];
8882 char buf2
[INET6_ADDRSTRLEN
];
8883 char buf3
[EVPN_ROUTE_STRLEN
];
8884 char prefix_str
[BUFSIZ
];
8889 int route_filter_translated_v4
= 0;
8890 int route_filter_v4
= 0;
8891 int route_filter_translated_v6
= 0;
8892 int route_filter_v6
= 0;
8895 int accept_own_nexthop
= 0;
8898 int no_advertise
= 0;
8902 int has_valid_label
= 0;
8903 mpls_label_t label
= 0;
8904 json_object
*json_adv_to
= NULL
;
8907 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8909 if (has_valid_label
)
8910 label
= label_pton(&rn
->local_label
);
8913 if (has_valid_label
)
8914 json_object_int_add(json
, "localLabel", label
);
8916 json_object_string_add(
8918 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
8920 if (safi
== SAFI_EVPN
)
8921 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8922 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8925 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8926 buf3
, sizeof(buf3
)));
8928 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8929 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8930 ? prefix_rd2str(prd
, buf1
,
8933 safi
== SAFI_MPLS_VPN
? ":" : "",
8934 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8938 if (has_valid_label
)
8939 vty_out(vty
, "Local label: %d\n", label
);
8940 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8941 vty_out(vty
, "not allocated\n");
8944 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
8946 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
8948 if (pi
->extra
&& pi
->extra
->suppress
)
8951 if (pi
->attr
->community
== NULL
)
8954 no_advertise
+= community_include(
8955 pi
->attr
->community
, COMMUNITY_NO_ADVERTISE
);
8956 no_export
+= community_include(pi
->attr
->community
,
8957 COMMUNITY_NO_EXPORT
);
8958 local_as
+= community_include(pi
->attr
->community
,
8959 COMMUNITY_LOCAL_AS
);
8960 accept_own
+= community_include(pi
->attr
->community
,
8961 COMMUNITY_ACCEPT_OWN
);
8962 route_filter_translated_v4
+= community_include(
8963 pi
->attr
->community
,
8964 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4
);
8965 route_filter_translated_v6
+= community_include(
8966 pi
->attr
->community
,
8967 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6
);
8968 route_filter_v4
+= community_include(
8969 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v4
);
8970 route_filter_v6
+= community_include(
8971 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v6
);
8972 llgr_stale
+= community_include(pi
->attr
->community
,
8973 COMMUNITY_LLGR_STALE
);
8974 no_llgr
+= community_include(pi
->attr
->community
,
8976 accept_own_nexthop
+=
8977 community_include(pi
->attr
->community
,
8978 COMMUNITY_ACCEPT_OWN_NEXTHOP
);
8979 blackhole
+= community_include(pi
->attr
->community
,
8980 COMMUNITY_BLACKHOLE
);
8981 no_peer
+= community_include(pi
->attr
->community
,
8987 vty_out(vty
, "Paths: (%d available", count
);
8989 vty_out(vty
, ", best #%d", best
);
8990 if (safi
== SAFI_UNICAST
)
8991 vty_out(vty
, ", table %s",
8993 == BGP_INSTANCE_TYPE_DEFAULT
)
8997 vty_out(vty
, ", no best path");
9001 ", accept own local route exported and imported in different VRF");
9002 else if (route_filter_translated_v4
)
9004 ", mark translated RTs for VPNv4 route filtering");
9005 else if (route_filter_v4
)
9007 ", attach RT as-is for VPNv4 route filtering");
9008 else if (route_filter_translated_v6
)
9010 ", mark translated RTs for VPNv6 route filtering");
9011 else if (route_filter_v6
)
9013 ", attach RT as-is for VPNv6 route filtering");
9014 else if (llgr_stale
)
9016 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9019 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9020 else if (accept_own_nexthop
)
9022 ", accept local nexthop");
9024 vty_out(vty
, ", inform peer to blackhole prefix");
9026 vty_out(vty
, ", not advertised to EBGP peer");
9027 else if (no_advertise
)
9028 vty_out(vty
, ", not advertised to any peer");
9030 vty_out(vty
, ", not advertised outside local AS");
9033 ", inform EBGP peer not to advertise to their EBGP peers");
9037 ", Advertisements suppressed by an aggregate.");
9038 vty_out(vty
, ")\n");
9041 /* If we are not using addpath then we can display Advertised to and
9043 * show what peers we advertised the bestpath to. If we are using
9045 * though then we must display Advertised to on a path-by-path basis. */
9046 if (!bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
9047 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
9048 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
9049 if (json
&& !json_adv_to
)
9050 json_adv_to
= json_object_new_object();
9052 route_vty_out_advertised_to(
9054 " Advertised to non peer-group peers:\n ",
9061 json_object_object_add(json
, "advertisedTo",
9066 vty_out(vty
, " Not advertised to any peer");
9072 /* Display specified route of BGP table. */
9073 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
9074 struct bgp_table
*rib
, const char *ip_str
,
9075 afi_t afi
, safi_t safi
,
9076 struct prefix_rd
*prd
, int prefix_check
,
9077 enum bgp_path_type pathtype
, bool use_json
)
9082 struct prefix match
;
9083 struct bgp_node
*rn
;
9084 struct bgp_node
*rm
;
9085 struct bgp_path_info
*pi
;
9086 struct bgp_table
*table
;
9087 json_object
*json
= NULL
;
9088 json_object
*json_paths
= NULL
;
9090 /* Check IP address argument. */
9091 ret
= str2prefix(ip_str
, &match
);
9093 vty_out(vty
, "address is malformed\n");
9097 match
.family
= afi2family(afi
);
9100 json
= json_object_new_object();
9101 json_paths
= json_object_new_array();
9104 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
9105 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
9106 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
9108 table
= bgp_node_get_bgp_table_info(rn
);
9114 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
9118 && rm
->p
.prefixlen
!= match
.prefixlen
) {
9119 bgp_unlock_node(rm
);
9123 for (pi
= bgp_node_get_bgp_path_info(rm
); pi
;
9126 route_vty_out_detail_header(
9128 (struct prefix_rd
*)&rn
->p
,
9129 AFI_IP
, safi
, json
);
9134 if (pathtype
== BGP_PATH_SHOW_ALL
9135 || (pathtype
== BGP_PATH_SHOW_BESTPATH
9136 && CHECK_FLAG(pi
->flags
,
9138 || (pathtype
== BGP_PATH_SHOW_MULTIPATH
9139 && (CHECK_FLAG(pi
->flags
,
9141 || CHECK_FLAG(pi
->flags
,
9142 BGP_PATH_SELECTED
))))
9143 route_vty_out_detail(vty
, bgp
, &rm
->p
,
9148 bgp_unlock_node(rm
);
9150 } else if (safi
== SAFI_FLOWSPEC
) {
9151 display
= bgp_flowspec_display_match_per_ip(afi
, rib
,
9152 &match
, prefix_check
,
9159 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
9161 || rn
->p
.prefixlen
== match
.prefixlen
) {
9162 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
;
9165 route_vty_out_detail_header(
9166 vty
, bgp
, rn
, NULL
, afi
,
9172 if (pathtype
== BGP_PATH_SHOW_ALL
9174 == BGP_PATH_SHOW_BESTPATH
9179 == BGP_PATH_SHOW_MULTIPATH
9185 BGP_PATH_SELECTED
))))
9186 route_vty_out_detail(
9187 vty
, bgp
, &rn
->p
, pi
,
9188 afi
, safi
, json_paths
);
9192 bgp_unlock_node(rn
);
9198 json_object_object_add(json
, "paths", json_paths
);
9200 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9201 json
, JSON_C_TO_STRING_PRETTY
));
9202 json_object_free(json
);
9205 vty_out(vty
, "%% Network not in table\n");
9213 /* Display specified route of Main RIB */
9214 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
9215 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
9216 int prefix_check
, enum bgp_path_type pathtype
,
9220 bgp
= bgp_get_default();
9223 vty_out(vty
, "No BGP process is configured\n");
9225 vty_out(vty
, "{}\n");
9230 /* labeled-unicast routes live in the unicast table */
9231 if (safi
== SAFI_LABELED_UNICAST
)
9232 safi
= SAFI_UNICAST
;
9234 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
9235 afi
, safi
, prd
, prefix_check
, pathtype
,
9239 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
9240 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
9243 struct lcommunity
*lcom
;
9249 b
= buffer_new(1024);
9250 for (i
= 0; i
< argc
; i
++) {
9252 buffer_putc(b
, ' ');
9254 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
9256 buffer_putstr(b
, argv
[i
]->arg
);
9260 buffer_putc(b
, '\0');
9262 str
= buffer_getstr(b
);
9265 lcom
= lcommunity_str2com(str
);
9266 XFREE(MTYPE_TMP
, str
);
9268 vty_out(vty
, "%% Large-community malformed\n");
9272 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
9276 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
9277 const char *lcom
, afi_t afi
, safi_t safi
,
9280 struct community_list
*list
;
9282 list
= community_list_lookup(bgp_clist
, lcom
, 0,
9283 LARGE_COMMUNITY_LIST_MASTER
);
9285 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
9290 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
9294 DEFUN (show_ip_bgp_large_community_list
,
9295 show_ip_bgp_large_community_list_cmd
,
9296 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
9300 BGP_INSTANCE_HELP_STR
9302 BGP_SAFI_WITH_LABEL_HELP_STR
9303 "Display routes matching the large-community-list\n"
9304 "large-community-list number\n"
9305 "large-community-list name\n"
9309 afi_t afi
= AFI_IP6
;
9310 safi_t safi
= SAFI_UNICAST
;
9313 if (argv_find(argv
, argc
, "ip", &idx
))
9315 if (argv_find(argv
, argc
, "view", &idx
)
9316 || argv_find(argv
, argc
, "vrf", &idx
))
9317 vrf
= argv
[++idx
]->arg
;
9318 if (argv_find(argv
, argc
, "ipv4", &idx
)
9319 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9320 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9321 if (argv_find(argv
, argc
, "unicast", &idx
)
9322 || argv_find(argv
, argc
, "multicast", &idx
))
9323 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9326 bool uj
= use_json(argc
, argv
);
9328 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9330 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9334 argv_find(argv
, argc
, "large-community-list", &idx
);
9335 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
9338 DEFUN (show_ip_bgp_large_community
,
9339 show_ip_bgp_large_community_cmd
,
9340 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
9344 BGP_INSTANCE_HELP_STR
9346 BGP_SAFI_WITH_LABEL_HELP_STR
9347 "Display routes matching the large-communities\n"
9348 "List of large-community numbers\n"
9352 afi_t afi
= AFI_IP6
;
9353 safi_t safi
= SAFI_UNICAST
;
9356 if (argv_find(argv
, argc
, "ip", &idx
))
9358 if (argv_find(argv
, argc
, "view", &idx
)
9359 || argv_find(argv
, argc
, "vrf", &idx
))
9360 vrf
= argv
[++idx
]->arg
;
9361 if (argv_find(argv
, argc
, "ipv4", &idx
)
9362 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9363 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9364 if (argv_find(argv
, argc
, "unicast", &idx
)
9365 || argv_find(argv
, argc
, "multicast", &idx
))
9366 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9369 bool uj
= use_json(argc
, argv
);
9371 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9373 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9377 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
9378 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
9380 return bgp_show(vty
, bgp
, afi
, safi
,
9381 bgp_show_type_lcommunity_all
, NULL
, uj
);
9384 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9388 /* BGP route print out function without JSON */
9391 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9392 <dampening <parameters>\
9397 |community-list <(1-500)|WORD> [exact-match]\
9398 |A.B.C.D/M longer-prefixes\
9399 |X:X::X:X/M longer-prefixes\
9404 BGP_INSTANCE_HELP_STR
9406 BGP_SAFI_WITH_LABEL_HELP_STR
9407 "Display detailed information about dampening\n"
9408 "Display detail of configured dampening parameters\n"
9409 "Display routes matching the route-map\n"
9410 "A route-map to match on\n"
9411 "Display routes conforming to the prefix-list\n"
9412 "Prefix-list name\n"
9413 "Display routes conforming to the filter-list\n"
9414 "Regular expression access list name\n"
9415 "BGP RIB advertisement statistics\n"
9416 "Display routes matching the community-list\n"
9417 "community-list number\n"
9418 "community-list name\n"
9419 "Exact match of the communities\n"
9421 "Display route and more specific routes\n"
9423 "Display route and more specific routes\n")
9425 afi_t afi
= AFI_IP6
;
9426 safi_t safi
= SAFI_UNICAST
;
9427 int exact_match
= 0;
9428 struct bgp
*bgp
= NULL
;
9431 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9436 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9437 if (argv_find(argv
, argc
, "parameters", &idx
))
9438 return bgp_show_dampening_parameters(vty
, afi
, safi
);
9441 if (argv_find(argv
, argc
, "prefix-list", &idx
))
9442 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9443 safi
, bgp_show_type_prefix_list
);
9445 if (argv_find(argv
, argc
, "filter-list", &idx
))
9446 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9447 safi
, bgp_show_type_filter_list
);
9449 if (argv_find(argv
, argc
, "statistics", &idx
))
9450 return bgp_table_stats(vty
, bgp
, afi
, safi
);
9452 if (argv_find(argv
, argc
, "route-map", &idx
))
9453 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9454 safi
, bgp_show_type_route_map
);
9456 if (argv_find(argv
, argc
, "community-list", &idx
)) {
9457 const char *clist_number_or_name
= argv
[++idx
]->arg
;
9458 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
9460 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9461 exact_match
, afi
, safi
);
9464 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9465 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9466 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9468 bgp_show_type_prefix_longer
);
9473 /* BGP route print out function with JSON */
9474 DEFUN (show_ip_bgp_json
,
9475 show_ip_bgp_json_cmd
,
9476 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9478 |dampening <flap-statistics|dampened-paths>\
9479 |community [AA:NN|local-AS|no-advertise|no-export\
9480 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
9481 |accept-own|accept-own-nexthop|route-filter-v6\
9482 |route-filter-v4|route-filter-translated-v6\
9483 |route-filter-translated-v4] [exact-match]\
9488 BGP_INSTANCE_HELP_STR
9490 BGP_SAFI_WITH_LABEL_HELP_STR
9491 "Display only routes with non-natural netmasks\n"
9492 "Display detailed information about dampening\n"
9493 "Display flap statistics of routes\n"
9494 "Display paths suppressed due to dampening\n"
9495 "Display routes matching the communities\n"
9497 "Do not send outside local AS (well-known community)\n"
9498 "Do not advertise to any peer (well-known community)\n"
9499 "Do not export to next AS (well-known community)\n"
9500 "Graceful shutdown (well-known community)\n"
9501 "Do not export to any peer (well-known community)\n"
9502 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
9503 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
9504 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
9505 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
9506 "Should accept VPN route with local nexthop (well-known community)\n"
9507 "RT VPNv6 route filtering (well-known community)\n"
9508 "RT VPNv4 route filtering (well-known community)\n"
9509 "RT translated VPNv6 route filtering (well-known community)\n"
9510 "RT translated VPNv4 route filtering (well-known community)\n"
9511 "Exact match of the communities\n"
9514 afi_t afi
= AFI_IP6
;
9515 safi_t safi
= SAFI_UNICAST
;
9516 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9517 struct bgp
*bgp
= NULL
;
9519 int exact_match
= 0;
9520 bool uj
= use_json(argc
, argv
);
9525 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9530 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9531 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9534 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9535 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9536 return bgp_show(vty
, bgp
, afi
, safi
,
9537 bgp_show_type_dampend_paths
, NULL
, uj
);
9538 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9539 return bgp_show(vty
, bgp
, afi
, safi
,
9540 bgp_show_type_flap_statistics
, NULL
,
9544 if (argv_find(argv
, argc
, "community", &idx
)) {
9545 char *maybecomm
= NULL
;
9546 char *community
= NULL
;
9548 if (idx
+ 1 < argc
) {
9549 if (argv
[idx
+ 1]->type
== VARIABLE_TKN
)
9550 maybecomm
= argv
[idx
+ 1]->arg
;
9552 maybecomm
= argv
[idx
+ 1]->text
;
9555 if (maybecomm
&& !strmatch(maybecomm
, "json")
9556 && !strmatch(maybecomm
, "exact-match"))
9557 community
= maybecomm
;
9559 if (argv_find(argv
, argc
, "exact-match", &idx
))
9563 return bgp_show_community(vty
, bgp
, community
,
9564 exact_match
, afi
, safi
, uj
);
9566 return (bgp_show(vty
, bgp
, afi
, safi
,
9567 bgp_show_type_community_all
, NULL
,
9571 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9574 DEFUN (show_ip_bgp_route
,
9575 show_ip_bgp_route_cmd
,
9576 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9577 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9581 BGP_INSTANCE_HELP_STR
9583 BGP_SAFI_WITH_LABEL_HELP_STR
9584 "Network in the BGP routing table to display\n"
9586 "Network in the BGP routing table to display\n"
9588 "Display only the bestpath\n"
9589 "Display only multipaths\n"
9592 int prefix_check
= 0;
9594 afi_t afi
= AFI_IP6
;
9595 safi_t safi
= SAFI_UNICAST
;
9596 char *prefix
= NULL
;
9597 struct bgp
*bgp
= NULL
;
9598 enum bgp_path_type path_type
;
9599 bool uj
= use_json(argc
, argv
);
9603 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9610 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9614 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9615 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9616 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9618 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9619 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9622 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9623 && afi
!= AFI_IP6
) {
9625 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9628 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9631 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9635 prefix
= argv
[idx
]->arg
;
9637 /* [<bestpath|multipath>] */
9638 if (argv_find(argv
, argc
, "bestpath", &idx
))
9639 path_type
= BGP_PATH_SHOW_BESTPATH
;
9640 else if (argv_find(argv
, argc
, "multipath", &idx
))
9641 path_type
= BGP_PATH_SHOW_MULTIPATH
;
9643 path_type
= BGP_PATH_SHOW_ALL
;
9645 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9649 DEFUN (show_ip_bgp_regexp
,
9650 show_ip_bgp_regexp_cmd
,
9651 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9655 BGP_INSTANCE_HELP_STR
9657 BGP_SAFI_WITH_LABEL_HELP_STR
9658 "Display routes matching the AS path regular expression\n"
9659 "A regular-expression to match the BGP AS paths\n")
9661 afi_t afi
= AFI_IP6
;
9662 safi_t safi
= SAFI_UNICAST
;
9663 struct bgp
*bgp
= NULL
;
9666 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9671 // get index of regex
9672 argv_find(argv
, argc
, "regexp", &idx
);
9675 char *regstr
= argv_concat(argv
, argc
, idx
);
9676 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9677 bgp_show_type_regexp
);
9678 XFREE(MTYPE_TMP
, regstr
);
9682 DEFUN (show_ip_bgp_instance_all
,
9683 show_ip_bgp_instance_all_cmd
,
9684 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9688 BGP_INSTANCE_ALL_HELP_STR
9690 BGP_SAFI_WITH_LABEL_HELP_STR
9694 safi_t safi
= SAFI_UNICAST
;
9695 struct bgp
*bgp
= NULL
;
9697 bool uj
= use_json(argc
, argv
);
9702 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9707 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9711 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
9712 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
9717 regex
= bgp_regcomp(regstr
);
9719 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9723 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9724 bgp_regex_free(regex
);
9728 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9729 const char *prefix_list_str
, afi_t afi
,
9730 safi_t safi
, enum bgp_show_type type
)
9732 struct prefix_list
*plist
;
9734 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9735 if (plist
== NULL
) {
9736 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9741 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9744 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9745 const char *filter
, afi_t afi
, safi_t safi
,
9746 enum bgp_show_type type
)
9748 struct as_list
*as_list
;
9750 as_list
= as_list_lookup(filter
);
9751 if (as_list
== NULL
) {
9752 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9757 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9760 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9761 const char *rmap_str
, afi_t afi
, safi_t safi
,
9762 enum bgp_show_type type
)
9764 struct route_map
*rmap
;
9766 rmap
= route_map_lookup_by_name(rmap_str
);
9768 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9772 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9775 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9776 const char *comstr
, int exact
, afi_t afi
,
9777 safi_t safi
, bool use_json
)
9779 struct community
*com
;
9782 com
= community_str2com(comstr
);
9784 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9788 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9789 (exact
? bgp_show_type_community_exact
9790 : bgp_show_type_community
),
9792 community_free(&com
);
9797 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9798 const char *com
, int exact
, afi_t afi
,
9801 struct community_list
*list
;
9803 list
= community_list_lookup(bgp_clist
, com
, 0, COMMUNITY_LIST_MASTER
);
9805 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9809 return bgp_show(vty
, bgp
, afi
, safi
,
9810 (exact
? bgp_show_type_community_list_exact
9811 : bgp_show_type_community_list
),
9815 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9816 const char *prefix
, afi_t afi
, safi_t safi
,
9817 enum bgp_show_type type
)
9824 ret
= str2prefix(prefix
, p
);
9826 vty_out(vty
, "%% Malformed Prefix\n");
9830 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9835 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9836 const char *ip_str
, bool use_json
)
9842 /* Get peer sockunion. */
9843 ret
= str2sockunion(ip_str
, &su
);
9845 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9847 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9851 json_object
*json_no
= NULL
;
9852 json_no
= json_object_new_object();
9853 json_object_string_add(
9855 "malformedAddressOrName",
9857 vty_out(vty
, "%s\n",
9858 json_object_to_json_string_ext(
9860 JSON_C_TO_STRING_PRETTY
));
9861 json_object_free(json_no
);
9864 "%% Malformed address or name: %s\n",
9872 /* Peer structure lookup. */
9873 peer
= peer_lookup(bgp
, &su
);
9876 json_object
*json_no
= NULL
;
9877 json_no
= json_object_new_object();
9878 json_object_string_add(json_no
, "warning",
9879 "No such neighbor in this view/vrf");
9880 vty_out(vty
, "%s\n",
9881 json_object_to_json_string_ext(
9882 json_no
, JSON_C_TO_STRING_PRETTY
));
9883 json_object_free(json_no
);
9885 vty_out(vty
, "No such neighbor in this view/vrf\n");
9893 BGP_STATS_MAXBITLEN
= 0,
9897 BGP_STATS_UNAGGREGATEABLE
,
9898 BGP_STATS_MAX_AGGREGATEABLE
,
9899 BGP_STATS_AGGREGATES
,
9901 BGP_STATS_ASPATH_COUNT
,
9902 BGP_STATS_ASPATH_MAXHOPS
,
9903 BGP_STATS_ASPATH_TOTHOPS
,
9904 BGP_STATS_ASPATH_MAXSIZE
,
9905 BGP_STATS_ASPATH_TOTSIZE
,
9906 BGP_STATS_ASN_HIGHEST
,
9910 static const char *table_stats_strs
[] = {
9911 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9912 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9913 [BGP_STATS_RIB
] = "Total Advertisements",
9914 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9915 [BGP_STATS_MAX_AGGREGATEABLE
] =
9916 "Maximum aggregateable prefixes",
9917 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9918 [BGP_STATS_SPACE
] = "Address space advertised",
9919 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9920 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9921 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9922 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9923 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9924 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9925 [BGP_STATS_MAX
] = NULL
,
9928 struct bgp_table_stats
{
9929 struct bgp_table
*table
;
9930 unsigned long long counts
[BGP_STATS_MAX
];
9935 #define TALLY_SIGFIG 100000
9936 static unsigned long
9937 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9939 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9940 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9941 unsigned long ret
= newtot
/ count
;
9943 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9950 static int bgp_table_stats_walker(struct thread
*t
)
9952 struct bgp_node
*rn
;
9953 struct bgp_node
*top
;
9954 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9955 unsigned int space
= 0;
9957 if (!(top
= bgp_table_top(ts
->table
)))
9960 switch (top
->p
.family
) {
9962 space
= IPV4_MAX_BITLEN
;
9965 space
= IPV6_MAX_BITLEN
;
9969 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9971 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9972 struct bgp_path_info
*pi
;
9973 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9974 unsigned int pinum
= 0;
9979 if (!bgp_node_has_bgp_path_info_data(rn
))
9982 ts
->counts
[BGP_STATS_PREFIXES
]++;
9983 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9986 ts
->counts
[BGP_STATS_AVGPLEN
]
9987 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9988 ts
->counts
[BGP_STATS_AVGPLEN
],
9992 /* check if the prefix is included by any other announcements */
9993 while (prn
&& !bgp_node_has_bgp_path_info_data(prn
))
9994 prn
= bgp_node_parent_nolock(prn
);
9996 if (prn
== NULL
|| prn
== top
) {
9997 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9998 /* announced address space */
10001 pow(2.0, space
- rn
->p
.prefixlen
);
10002 } else if (bgp_node_has_bgp_path_info_data(prn
))
10003 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
10005 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
10007 ts
->counts
[BGP_STATS_RIB
]++;
10010 && (CHECK_FLAG(pi
->attr
->flag
,
10012 BGP_ATTR_ATOMIC_AGGREGATE
))))
10013 ts
->counts
[BGP_STATS_AGGREGATES
]++;
10015 /* as-path stats */
10016 if (pi
->attr
&& pi
->attr
->aspath
) {
10017 unsigned int hops
=
10018 aspath_count_hops(pi
->attr
->aspath
);
10019 unsigned int size
=
10020 aspath_size(pi
->attr
->aspath
);
10021 as_t highest
= aspath_highest(pi
->attr
->aspath
);
10023 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
10025 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
10026 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
10029 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
10030 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
10033 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
10034 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
10036 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
10037 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
10038 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
10040 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
10041 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
10042 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
10045 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
10046 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
10054 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10057 struct bgp_table_stats ts
;
10060 if (!bgp
->rib
[afi
][safi
]) {
10061 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10063 return CMD_WARNING
;
10066 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
10068 /* labeled-unicast routes live in the unicast table */
10069 if (safi
== SAFI_LABELED_UNICAST
)
10070 safi
= SAFI_UNICAST
;
10072 memset(&ts
, 0, sizeof(ts
));
10073 ts
.table
= bgp
->rib
[afi
][safi
];
10074 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
10076 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
10077 if (!table_stats_strs
[i
])
10082 case BGP_STATS_ASPATH_AVGHOPS
:
10083 case BGP_STATS_ASPATH_AVGSIZE
:
10084 case BGP_STATS_AVGPLEN
:
10085 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
10086 vty_out (vty
, "%12.2f",
10087 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
10090 case BGP_STATS_ASPATH_TOTHOPS
:
10091 case BGP_STATS_ASPATH_TOTSIZE
:
10092 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10093 vty_out(vty
, "%12.2f",
10095 ? (float)ts
.counts
[i
]
10097 [BGP_STATS_ASPATH_COUNT
]
10100 case BGP_STATS_TOTPLEN
:
10101 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10102 vty_out(vty
, "%12.2f",
10104 ? (float)ts
.counts
[i
]
10106 [BGP_STATS_PREFIXES
]
10109 case BGP_STATS_SPACE
:
10110 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10111 vty_out(vty
, "%12g\n", ts
.total_space
);
10113 if (afi
== AFI_IP6
) {
10114 vty_out(vty
, "%30s: ", "/32 equivalent ");
10115 vty_out(vty
, "%12g\n",
10116 ts
.total_space
* pow(2.0, -128 + 32));
10117 vty_out(vty
, "%30s: ", "/48 equivalent ");
10118 vty_out(vty
, "%12g\n",
10119 ts
.total_space
* pow(2.0, -128 + 48));
10121 vty_out(vty
, "%30s: ", "% announced ");
10122 vty_out(vty
, "%12.2f\n",
10123 ts
.total_space
* 100. * pow(2.0, -32));
10124 vty_out(vty
, "%30s: ", "/8 equivalent ");
10125 vty_out(vty
, "%12.2f\n",
10126 ts
.total_space
* pow(2.0, -32 + 8));
10127 vty_out(vty
, "%30s: ", "/24 equivalent ");
10128 vty_out(vty
, "%12.2f\n",
10129 ts
.total_space
* pow(2.0, -32 + 24));
10133 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10134 vty_out(vty
, "%12llu", ts
.counts
[i
]);
10137 vty_out(vty
, "\n");
10139 return CMD_SUCCESS
;
10151 PCOUNT_PFCNT
, /* the figure we display to users */
10155 static const char *pcount_strs
[] = {
10156 [PCOUNT_ADJ_IN
] = "Adj-in",
10157 [PCOUNT_DAMPED
] = "Damped",
10158 [PCOUNT_REMOVED
] = "Removed",
10159 [PCOUNT_HISTORY
] = "History",
10160 [PCOUNT_STALE
] = "Stale",
10161 [PCOUNT_VALID
] = "Valid",
10162 [PCOUNT_ALL
] = "All RIB",
10163 [PCOUNT_COUNTED
] = "PfxCt counted",
10164 [PCOUNT_PFCNT
] = "Useable",
10165 [PCOUNT_MAX
] = NULL
,
10168 struct peer_pcounts
{
10169 unsigned int count
[PCOUNT_MAX
];
10170 const struct peer
*peer
;
10171 const struct bgp_table
*table
;
10174 static int bgp_peer_count_walker(struct thread
*t
)
10176 struct bgp_node
*rn
;
10177 struct peer_pcounts
*pc
= THREAD_ARG(t
);
10178 const struct peer
*peer
= pc
->peer
;
10180 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
10181 struct bgp_adj_in
*ain
;
10182 struct bgp_path_info
*pi
;
10184 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
10185 if (ain
->peer
== peer
)
10186 pc
->count
[PCOUNT_ADJ_IN
]++;
10188 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
10190 if (pi
->peer
!= peer
)
10193 pc
->count
[PCOUNT_ALL
]++;
10195 if (CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
))
10196 pc
->count
[PCOUNT_DAMPED
]++;
10197 if (CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
10198 pc
->count
[PCOUNT_HISTORY
]++;
10199 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
10200 pc
->count
[PCOUNT_REMOVED
]++;
10201 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
10202 pc
->count
[PCOUNT_STALE
]++;
10203 if (CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
10204 pc
->count
[PCOUNT_VALID
]++;
10205 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10206 pc
->count
[PCOUNT_PFCNT
]++;
10208 if (CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
10209 pc
->count
[PCOUNT_COUNTED
]++;
10210 if (CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10212 EC_LIB_DEVELOPMENT
,
10213 "Attempting to count but flags say it is unusable");
10215 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10217 EC_LIB_DEVELOPMENT
,
10218 "Not counted but flags say we should");
10225 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10226 safi_t safi
, bool use_json
)
10228 struct peer_pcounts pcounts
= {.peer
= peer
};
10230 json_object
*json
= NULL
;
10231 json_object
*json_loop
= NULL
;
10234 json
= json_object_new_object();
10235 json_loop
= json_object_new_object();
10238 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
10239 || !peer
->bgp
->rib
[afi
][safi
]) {
10241 json_object_string_add(
10243 "No such neighbor or address family");
10244 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10245 json_object_free(json
);
10247 vty_out(vty
, "%% No such neighbor or address family\n");
10249 return CMD_WARNING
;
10252 memset(&pcounts
, 0, sizeof(pcounts
));
10253 pcounts
.peer
= peer
;
10254 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
10256 /* in-place call via thread subsystem so as to record execution time
10257 * stats for the thread-walk (i.e. ensure this can't be blamed on
10258 * on just vty_read()).
10260 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
10263 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
10264 json_object_string_add(json
, "multiProtocol",
10265 afi_safi_print(afi
, safi
));
10266 json_object_int_add(json
, "pfxCounter",
10267 peer
->pcount
[afi
][safi
]);
10269 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10270 json_object_int_add(json_loop
, pcount_strs
[i
],
10273 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
10275 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10276 json_object_string_add(json
, "pfxctDriftFor",
10278 json_object_string_add(
10279 json
, "recommended",
10280 "Please report this bug, with the above command output");
10282 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10283 json
, JSON_C_TO_STRING_PRETTY
));
10284 json_object_free(json
);
10288 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
10289 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
10290 peer
->hostname
, peer
->host
,
10291 afi_safi_print(afi
, safi
));
10293 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
10294 afi_safi_print(afi
, safi
));
10297 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
10298 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
10300 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10301 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
10304 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10305 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
10307 "Please report this bug, with the above command output\n");
10311 return CMD_SUCCESS
;
10314 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
10315 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
10316 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
10317 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10321 BGP_INSTANCE_HELP_STR
10324 "Detailed information on TCP and BGP neighbor connections\n"
10325 "Neighbor to display information about\n"
10326 "Neighbor to display information about\n"
10327 "Neighbor on BGP configured interface\n"
10328 "Display detailed prefix count information\n"
10331 afi_t afi
= AFI_IP6
;
10332 safi_t safi
= SAFI_UNICAST
;
10335 struct bgp
*bgp
= NULL
;
10336 bool uj
= use_json(argc
, argv
);
10341 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10344 return CMD_WARNING
;
10346 argv_find(argv
, argc
, "neighbors", &idx
);
10347 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
10349 return CMD_WARNING
;
10351 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
10354 #ifdef KEEP_OLD_VPN_COMMANDS
10355 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
10356 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
10357 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10362 "Display information about all VPNv4 NLRIs\n"
10363 "Detailed information on TCP and BGP neighbor connections\n"
10364 "Neighbor to display information about\n"
10365 "Neighbor to display information about\n"
10366 "Neighbor on BGP configured interface\n"
10367 "Display detailed prefix count information\n"
10372 bool uj
= use_json(argc
, argv
);
10374 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
10376 return CMD_WARNING
;
10378 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
10381 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
10382 show_ip_bgp_vpn_all_route_prefix_cmd
,
10383 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10388 "Display information about all VPNv4 NLRIs\n"
10389 "Network in the BGP routing table to display\n"
10390 "Network in the BGP routing table to display\n"
10394 char *network
= NULL
;
10395 struct bgp
*bgp
= bgp_get_default();
10397 vty_out(vty
, "Can't find default instance\n");
10398 return CMD_WARNING
;
10401 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10402 network
= argv
[idx
]->arg
;
10403 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
10404 network
= argv
[idx
]->arg
;
10406 vty_out(vty
, "Unable to figure out Network\n");
10407 return CMD_WARNING
;
10410 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
10411 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
10413 #endif /* KEEP_OLD_VPN_COMMANDS */
10415 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
10416 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
10417 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10423 "Display information about all EVPN NLRIs\n"
10424 "Network in the BGP routing table to display\n"
10425 "Network in the BGP routing table to display\n"
10429 char *network
= NULL
;
10431 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10432 network
= argv
[idx
]->arg
;
10433 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
10434 network
= argv
[idx
]->arg
;
10436 vty_out(vty
, "Unable to figure out Network\n");
10437 return CMD_WARNING
;
10439 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
10440 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
10443 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10444 safi_t safi
, enum bgp_show_adj_route_type type
,
10445 const char *rmap_name
, bool use_json
,
10448 struct bgp_table
*table
;
10449 struct bgp_adj_in
*ain
;
10450 struct bgp_adj_out
*adj
;
10451 unsigned long output_count
;
10452 unsigned long filtered_count
;
10453 struct bgp_node
*rn
;
10459 struct update_subgroup
*subgrp
;
10460 json_object
*json_scode
= NULL
;
10461 json_object
*json_ocode
= NULL
;
10462 json_object
*json_ar
= NULL
;
10463 struct peer_af
*paf
;
10464 bool route_filtered
;
10467 json_scode
= json_object_new_object();
10468 json_ocode
= json_object_new_object();
10469 json_ar
= json_object_new_object();
10471 json_object_string_add(json_scode
, "suppressed", "s");
10472 json_object_string_add(json_scode
, "damped", "d");
10473 json_object_string_add(json_scode
, "history", "h");
10474 json_object_string_add(json_scode
, "valid", "*");
10475 json_object_string_add(json_scode
, "best", ">");
10476 json_object_string_add(json_scode
, "multipath", "=");
10477 json_object_string_add(json_scode
, "internal", "i");
10478 json_object_string_add(json_scode
, "ribFailure", "r");
10479 json_object_string_add(json_scode
, "stale", "S");
10480 json_object_string_add(json_scode
, "removed", "R");
10482 json_object_string_add(json_ocode
, "igp", "i");
10483 json_object_string_add(json_ocode
, "egp", "e");
10484 json_object_string_add(json_ocode
, "incomplete", "?");
10491 json_object_string_add(json
, "alert", "no BGP");
10492 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10493 json_object_free(json
);
10495 vty_out(vty
, "%% No bgp\n");
10499 table
= bgp
->rib
[afi
][safi
];
10501 output_count
= filtered_count
= 0;
10502 subgrp
= peer_subgroup(peer
, afi
, safi
);
10504 if (type
== bgp_show_adj_route_advertised
&& subgrp
10505 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10507 json_object_int_add(json
, "bgpTableVersion",
10509 json_object_string_add(json
, "bgpLocalRouterId",
10510 inet_ntoa(bgp
->router_id
));
10511 json_object_int_add(json
, "defaultLocPrf",
10512 bgp
->default_local_pref
);
10513 json_object_int_add(json
, "localAS", bgp
->as
);
10514 json_object_object_add(json
, "bgpStatusCodes",
10516 json_object_object_add(json
, "bgpOriginCodes",
10518 json_object_string_add(
10519 json
, "bgpOriginatingDefaultNetwork",
10520 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
10522 vty_out(vty
, "BGP table version is %" PRIu64
10523 ", local router ID is %s, vrf id ",
10524 table
->version
, inet_ntoa(bgp
->router_id
));
10525 if (bgp
->vrf_id
== VRF_UNKNOWN
)
10526 vty_out(vty
, "%s", VRFID_NONE_STR
);
10528 vty_out(vty
, "%u", bgp
->vrf_id
);
10529 vty_out(vty
, "\n");
10530 vty_out(vty
, "Default local pref %u, ",
10531 bgp
->default_local_pref
);
10532 vty_out(vty
, "local AS %u\n", bgp
->as
);
10533 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10534 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
10535 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10537 vty_out(vty
, "Originating default network %s\n\n",
10538 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
10543 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10544 if (type
== bgp_show_adj_route_received
10545 || type
== bgp_show_adj_route_filtered
) {
10546 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10547 if (ain
->peer
!= peer
|| !ain
->attr
)
10552 json_object_int_add(
10553 json
, "bgpTableVersion",
10555 json_object_string_add(
10557 "bgpLocalRouterId",
10560 json_object_int_add(json
,
10562 bgp
->default_local_pref
);
10563 json_object_int_add(json
,
10564 "localAS", bgp
->as
);
10565 json_object_object_add(
10566 json
, "bgpStatusCodes",
10568 json_object_object_add(
10569 json
, "bgpOriginCodes",
10573 "BGP table version is 0, local router ID is %s, vrf id ",
10576 if (bgp
->vrf_id
== VRF_UNKNOWN
)
10582 vty_out(vty
, "\n");
10584 "Default local pref %u, ",
10585 bgp
->default_local_pref
);
10586 vty_out(vty
, "local AS %u\n",
10589 BGP_SHOW_SCODE_HEADER
);
10591 BGP_SHOW_NCODE_HEADER
);
10593 BGP_SHOW_OCODE_HEADER
);
10599 vty_out(vty
, BGP_SHOW_HEADER
);
10603 bgp_attr_dup(&attr
, ain
->attr
);
10604 route_filtered
= false;
10606 /* Filter prefix using distribute list,
10607 * filter list or prefix list
10609 if ((bgp_input_filter(peer
, &rn
->p
, &attr
, afi
,
10610 safi
)) == FILTER_DENY
)
10611 route_filtered
= true;
10613 /* Filter prefix using route-map */
10614 ret
= bgp_input_modifier(peer
, &rn
->p
, &attr
,
10615 afi
, safi
, rmap_name
);
10617 if (type
== bgp_show_adj_route_filtered
&&
10618 !route_filtered
&& ret
!= RMAP_DENY
) {
10619 bgp_attr_undup(&attr
, ain
->attr
);
10623 if (type
== bgp_show_adj_route_received
&&
10624 (route_filtered
|| ret
== RMAP_DENY
))
10627 route_vty_out_tmp(vty
, &rn
->p
, &attr
, safi
,
10628 use_json
, json_ar
);
10629 bgp_attr_undup(&attr
, ain
->attr
);
10632 } else if (type
== bgp_show_adj_route_advertised
) {
10633 RB_FOREACH (adj
, bgp_adj_out_rb
, &rn
->adj_out
)
10634 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
10635 if (paf
->peer
!= peer
|| !adj
->attr
)
10640 json_object_int_add(
10644 json_object_string_add(
10646 "bgpLocalRouterId",
10649 json_object_int_add(
10650 json
, "defaultLocPrf",
10651 bgp
->default_local_pref
10653 json_object_int_add(
10656 json_object_object_add(
10660 json_object_object_add(
10666 "BGP table version is %" PRIu64
10667 ", local router ID is %s, vrf id ",
10680 vty_out(vty
, "\n");
10682 "Default local pref %u, ",
10683 bgp
->default_local_pref
10689 BGP_SHOW_SCODE_HEADER
);
10691 BGP_SHOW_NCODE_HEADER
);
10693 BGP_SHOW_OCODE_HEADER
);
10704 bgp_attr_dup(&attr
, adj
->attr
);
10705 ret
= bgp_output_modifier(
10706 peer
, &rn
->p
, &attr
, afi
, safi
,
10709 if (ret
!= RMAP_DENY
) {
10710 route_vty_out_tmp(vty
, &rn
->p
,
10719 bgp_attr_undup(&attr
, adj
->attr
);
10725 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10726 json_object_int_add(json
, "totalPrefixCounter", output_count
);
10727 json_object_int_add(json
, "filteredPrefixCounter",
10730 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10731 json
, JSON_C_TO_STRING_PRETTY
));
10732 json_object_free(json
);
10733 } else if (output_count
> 0) {
10734 if (filtered_count
> 0)
10736 "\nTotal number of prefixes %ld (%ld filtered)\n",
10737 output_count
, filtered_count
);
10739 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10744 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10745 safi_t safi
, enum bgp_show_adj_route_type type
,
10746 const char *rmap_name
, bool use_json
)
10748 json_object
*json
= NULL
;
10751 json
= json_object_new_object();
10753 /* labeled-unicast routes live in the unicast table */
10754 if (safi
== SAFI_LABELED_UNICAST
)
10755 safi
= SAFI_UNICAST
;
10757 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10759 json_object_string_add(
10761 "No such neighbor or address family");
10762 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10763 json_object_free(json
);
10765 vty_out(vty
, "%% No such neighbor or address family\n");
10767 return CMD_WARNING
;
10770 if ((type
== bgp_show_adj_route_received
10771 || type
== bgp_show_adj_route_filtered
)
10772 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10773 PEER_FLAG_SOFT_RECONFIG
)) {
10775 json_object_string_add(
10777 "Inbound soft reconfiguration not enabled");
10778 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10779 json_object_free(json
);
10782 "%% Inbound soft reconfiguration not enabled\n");
10784 return CMD_WARNING
;
10787 show_adj_route(vty
, peer
, afi
, safi
, type
, rmap_name
, use_json
, json
);
10789 return CMD_SUCCESS
;
10792 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10793 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10794 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10795 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
10799 BGP_INSTANCE_HELP_STR
10801 BGP_SAFI_WITH_LABEL_HELP_STR
10802 "Detailed information on TCP and BGP neighbor connections\n"
10803 "Neighbor to display information about\n"
10804 "Neighbor to display information about\n"
10805 "Neighbor on BGP configured interface\n"
10806 "Display the routes advertised to a BGP neighbor\n"
10807 "Display the received routes from neighbor\n"
10808 "Display the filtered routes received from neighbor\n"
10809 "Route-map to modify the attributes\n"
10810 "Name of the route map\n"
10813 afi_t afi
= AFI_IP6
;
10814 safi_t safi
= SAFI_UNICAST
;
10815 char *rmap_name
= NULL
;
10816 char *peerstr
= NULL
;
10817 struct bgp
*bgp
= NULL
;
10819 enum bgp_show_adj_route_type type
= bgp_show_adj_route_advertised
;
10821 bool uj
= use_json(argc
, argv
);
10826 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10829 return CMD_WARNING
;
10831 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10832 argv_find(argv
, argc
, "neighbors", &idx
);
10833 peerstr
= argv
[++idx
]->arg
;
10835 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10837 return CMD_WARNING
;
10839 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10840 type
= bgp_show_adj_route_advertised
;
10841 else if (argv_find(argv
, argc
, "received-routes", &idx
))
10842 type
= bgp_show_adj_route_received
;
10843 else if (argv_find(argv
, argc
, "filtered-routes", &idx
))
10844 type
= bgp_show_adj_route_filtered
;
10846 if (argv_find(argv
, argc
, "route-map", &idx
))
10847 rmap_name
= argv
[++idx
]->arg
;
10849 return peer_adj_routes(vty
, peer
, afi
, safi
, type
, rmap_name
, uj
);
10852 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10853 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10854 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10860 "Address Family modifier\n"
10861 "Detailed information on TCP and BGP neighbor connections\n"
10862 "Neighbor to display information about\n"
10863 "Neighbor to display information about\n"
10864 "Neighbor on BGP configured interface\n"
10865 "Display information received from a BGP neighbor\n"
10866 "Display the prefixlist filter\n"
10869 afi_t afi
= AFI_IP6
;
10870 safi_t safi
= SAFI_UNICAST
;
10871 char *peerstr
= NULL
;
10874 union sockunion su
;
10880 /* show [ip] bgp */
10881 if (argv_find(argv
, argc
, "ip", &idx
))
10883 /* [<ipv4|ipv6> [unicast]] */
10884 if (argv_find(argv
, argc
, "ipv4", &idx
))
10886 if (argv_find(argv
, argc
, "ipv6", &idx
))
10888 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10889 argv_find(argv
, argc
, "neighbors", &idx
);
10890 peerstr
= argv
[++idx
]->arg
;
10892 bool uj
= use_json(argc
, argv
);
10894 ret
= str2sockunion(peerstr
, &su
);
10896 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10899 vty_out(vty
, "{}\n");
10902 "%% Malformed address or name: %s\n",
10904 return CMD_WARNING
;
10907 peer
= peer_lookup(NULL
, &su
);
10910 vty_out(vty
, "{}\n");
10912 vty_out(vty
, "No peer\n");
10913 return CMD_WARNING
;
10917 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10918 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10921 vty_out(vty
, "Address Family: %s\n",
10922 afi_safi_print(afi
, safi
));
10923 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10926 vty_out(vty
, "{}\n");
10928 vty_out(vty
, "No functional output\n");
10931 return CMD_SUCCESS
;
10934 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10935 afi_t afi
, safi_t safi
,
10936 enum bgp_show_type type
, bool use_json
)
10938 /* labeled-unicast routes live in the unicast table */
10939 if (safi
== SAFI_LABELED_UNICAST
)
10940 safi
= SAFI_UNICAST
;
10942 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10944 json_object
*json_no
= NULL
;
10945 json_no
= json_object_new_object();
10946 json_object_string_add(
10947 json_no
, "warning",
10948 "No such neighbor or address family");
10949 vty_out(vty
, "%s\n",
10950 json_object_to_json_string(json_no
));
10951 json_object_free(json_no
);
10953 vty_out(vty
, "%% No such neighbor or address family\n");
10954 return CMD_WARNING
;
10957 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10960 DEFUN (show_ip_bgp_flowspec_routes_detailed
,
10961 show_ip_bgp_flowspec_routes_detailed_cmd
,
10962 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" flowspec] detail [json]",
10966 BGP_INSTANCE_HELP_STR
10969 "Detailed information on flowspec entries\n"
10972 afi_t afi
= AFI_IP
;
10973 safi_t safi
= SAFI_UNICAST
;
10974 struct bgp
*bgp
= NULL
;
10976 bool uj
= use_json(argc
, argv
);
10981 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10984 return CMD_WARNING
;
10986 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_detail
, NULL
, uj
);
10989 DEFUN (show_ip_bgp_neighbor_routes
,
10990 show_ip_bgp_neighbor_routes_cmd
,
10991 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10992 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10996 BGP_INSTANCE_HELP_STR
10998 BGP_SAFI_WITH_LABEL_HELP_STR
10999 "Detailed information on TCP and BGP neighbor connections\n"
11000 "Neighbor to display information about\n"
11001 "Neighbor to display information about\n"
11002 "Neighbor on BGP configured interface\n"
11003 "Display flap statistics of the routes learned from neighbor\n"
11004 "Display the dampened routes received from neighbor\n"
11005 "Display routes learned from neighbor\n"
11008 char *peerstr
= NULL
;
11009 struct bgp
*bgp
= NULL
;
11010 afi_t afi
= AFI_IP6
;
11011 safi_t safi
= SAFI_UNICAST
;
11013 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
11015 bool uj
= use_json(argc
, argv
);
11020 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
11023 return CMD_WARNING
;
11025 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11026 argv_find(argv
, argc
, "neighbors", &idx
);
11027 peerstr
= argv
[++idx
]->arg
;
11029 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
11031 return CMD_WARNING
;
11033 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
11034 sh_type
= bgp_show_type_flap_neighbor
;
11035 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
11036 sh_type
= bgp_show_type_damp_neighbor
;
11037 else if (argv_find(argv
, argc
, "routes", &idx
))
11038 sh_type
= bgp_show_type_neighbor
;
11040 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
11043 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
11045 struct bgp_distance
{
11046 /* Distance value for the IP source prefix. */
11049 /* Name of the access-list to be matched. */
11053 DEFUN (show_bgp_afi_vpn_rd_route
,
11054 show_bgp_afi_vpn_rd_route_cmd
,
11055 "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]",
11059 "Address Family modifier\n"
11060 "Display information for a route distinguisher\n"
11061 "Route Distinguisher\n"
11062 "Network in the BGP routing table to display\n"
11063 "Network in the BGP routing table to display\n"
11067 struct prefix_rd prd
;
11068 afi_t afi
= AFI_MAX
;
11071 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
11072 vty_out(vty
, "%% Malformed Address Family\n");
11073 return CMD_WARNING
;
11076 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
11078 vty_out(vty
, "%% Malformed Route Distinguisher\n");
11079 return CMD_WARNING
;
11082 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
11083 0, BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
11086 static struct bgp_distance
*bgp_distance_new(void)
11088 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
11091 static void bgp_distance_free(struct bgp_distance
*bdistance
)
11093 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
11096 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
11097 const char *ip_str
, const char *access_list_str
)
11104 struct bgp_node
*rn
;
11105 struct bgp_distance
*bdistance
;
11107 afi
= bgp_node_afi(vty
);
11108 safi
= bgp_node_safi(vty
);
11110 ret
= str2prefix(ip_str
, &p
);
11112 vty_out(vty
, "Malformed prefix\n");
11113 return CMD_WARNING_CONFIG_FAILED
;
11116 distance
= atoi(distance_str
);
11118 /* Get BGP distance node. */
11119 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
11120 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11122 bgp_unlock_node(rn
);
11124 bdistance
= bgp_distance_new();
11125 bgp_node_set_bgp_distance_info(rn
, bdistance
);
11128 /* Set distance value. */
11129 bdistance
->distance
= distance
;
11131 /* Reset access-list configuration. */
11132 if (bdistance
->access_list
) {
11133 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11134 bdistance
->access_list
= NULL
;
11136 if (access_list_str
)
11137 bdistance
->access_list
=
11138 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
11140 return CMD_SUCCESS
;
11143 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
11144 const char *ip_str
, const char *access_list_str
)
11151 struct bgp_node
*rn
;
11152 struct bgp_distance
*bdistance
;
11154 afi
= bgp_node_afi(vty
);
11155 safi
= bgp_node_safi(vty
);
11157 ret
= str2prefix(ip_str
, &p
);
11159 vty_out(vty
, "Malformed prefix\n");
11160 return CMD_WARNING_CONFIG_FAILED
;
11163 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
11164 (struct prefix
*)&p
);
11166 vty_out(vty
, "Can't find specified prefix\n");
11167 return CMD_WARNING_CONFIG_FAILED
;
11170 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11171 distance
= atoi(distance_str
);
11173 if (bdistance
->distance
!= distance
) {
11174 vty_out(vty
, "Distance does not match configured\n");
11175 return CMD_WARNING_CONFIG_FAILED
;
11178 if (bdistance
->access_list
)
11179 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11180 bgp_distance_free(bdistance
);
11182 bgp_node_set_bgp_path_info(rn
, NULL
);
11183 bgp_unlock_node(rn
);
11184 bgp_unlock_node(rn
);
11186 return CMD_SUCCESS
;
11189 /* Apply BGP information to distance method. */
11190 uint8_t bgp_distance_apply(struct prefix
*p
, struct bgp_path_info
*pinfo
,
11191 afi_t afi
, safi_t safi
, struct bgp
*bgp
)
11193 struct bgp_node
*rn
;
11196 struct bgp_distance
*bdistance
;
11197 struct access_list
*alist
;
11198 struct bgp_static
*bgp_static
;
11203 peer
= pinfo
->peer
;
11205 /* Check source address. */
11206 sockunion2hostprefix(&peer
->su
, &q
);
11207 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
11209 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11210 bgp_unlock_node(rn
);
11212 if (bdistance
->access_list
) {
11213 alist
= access_list_lookup(afi
, bdistance
->access_list
);
11215 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
11216 return bdistance
->distance
;
11218 return bdistance
->distance
;
11221 /* Backdoor check. */
11222 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
11224 bgp_static
= bgp_node_get_bgp_static_info(rn
);
11225 bgp_unlock_node(rn
);
11227 if (bgp_static
->backdoor
) {
11228 if (bgp
->distance_local
[afi
][safi
])
11229 return bgp
->distance_local
[afi
][safi
];
11231 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11235 if (peer
->sort
== BGP_PEER_EBGP
) {
11236 if (bgp
->distance_ebgp
[afi
][safi
])
11237 return bgp
->distance_ebgp
[afi
][safi
];
11238 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
11240 if (bgp
->distance_ibgp
[afi
][safi
])
11241 return bgp
->distance_ibgp
[afi
][safi
];
11242 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11246 DEFUN (bgp_distance
,
11248 "distance bgp (1-255) (1-255) (1-255)",
11249 "Define an administrative distance\n"
11251 "Distance for routes external to the AS\n"
11252 "Distance for routes internal to the AS\n"
11253 "Distance for local routes\n")
11255 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11256 int idx_number
= 2;
11257 int idx_number_2
= 3;
11258 int idx_number_3
= 4;
11262 afi
= bgp_node_afi(vty
);
11263 safi
= bgp_node_safi(vty
);
11265 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
11266 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
11267 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
11268 return CMD_SUCCESS
;
11271 DEFUN (no_bgp_distance
,
11272 no_bgp_distance_cmd
,
11273 "no distance bgp [(1-255) (1-255) (1-255)]",
11275 "Define an administrative distance\n"
11277 "Distance for routes external to the AS\n"
11278 "Distance for routes internal to the AS\n"
11279 "Distance for local routes\n")
11281 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11285 afi
= bgp_node_afi(vty
);
11286 safi
= bgp_node_safi(vty
);
11288 bgp
->distance_ebgp
[afi
][safi
] = 0;
11289 bgp
->distance_ibgp
[afi
][safi
] = 0;
11290 bgp
->distance_local
[afi
][safi
] = 0;
11291 return CMD_SUCCESS
;
11295 DEFUN (bgp_distance_source
,
11296 bgp_distance_source_cmd
,
11297 "distance (1-255) A.B.C.D/M",
11298 "Define an administrative distance\n"
11299 "Administrative distance\n"
11300 "IP source prefix\n")
11302 int idx_number
= 1;
11303 int idx_ipv4_prefixlen
= 2;
11304 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11305 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11306 return CMD_SUCCESS
;
11309 DEFUN (no_bgp_distance_source
,
11310 no_bgp_distance_source_cmd
,
11311 "no distance (1-255) A.B.C.D/M",
11313 "Define an administrative distance\n"
11314 "Administrative distance\n"
11315 "IP source prefix\n")
11317 int idx_number
= 2;
11318 int idx_ipv4_prefixlen
= 3;
11319 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11320 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11321 return CMD_SUCCESS
;
11324 DEFUN (bgp_distance_source_access_list
,
11325 bgp_distance_source_access_list_cmd
,
11326 "distance (1-255) A.B.C.D/M WORD",
11327 "Define an administrative distance\n"
11328 "Administrative distance\n"
11329 "IP source prefix\n"
11330 "Access list name\n")
11332 int idx_number
= 1;
11333 int idx_ipv4_prefixlen
= 2;
11335 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11336 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11337 return CMD_SUCCESS
;
11340 DEFUN (no_bgp_distance_source_access_list
,
11341 no_bgp_distance_source_access_list_cmd
,
11342 "no distance (1-255) A.B.C.D/M WORD",
11344 "Define an administrative distance\n"
11345 "Administrative distance\n"
11346 "IP source prefix\n"
11347 "Access list name\n")
11349 int idx_number
= 2;
11350 int idx_ipv4_prefixlen
= 3;
11352 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11353 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11354 return CMD_SUCCESS
;
11357 DEFUN (ipv6_bgp_distance_source
,
11358 ipv6_bgp_distance_source_cmd
,
11359 "distance (1-255) X:X::X:X/M",
11360 "Define an administrative distance\n"
11361 "Administrative distance\n"
11362 "IP source prefix\n")
11364 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
11365 return CMD_SUCCESS
;
11368 DEFUN (no_ipv6_bgp_distance_source
,
11369 no_ipv6_bgp_distance_source_cmd
,
11370 "no distance (1-255) X:X::X:X/M",
11372 "Define an administrative distance\n"
11373 "Administrative distance\n"
11374 "IP source prefix\n")
11376 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
11377 return CMD_SUCCESS
;
11380 DEFUN (ipv6_bgp_distance_source_access_list
,
11381 ipv6_bgp_distance_source_access_list_cmd
,
11382 "distance (1-255) X:X::X:X/M WORD",
11383 "Define an administrative distance\n"
11384 "Administrative distance\n"
11385 "IP source prefix\n"
11386 "Access list name\n")
11388 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
11389 return CMD_SUCCESS
;
11392 DEFUN (no_ipv6_bgp_distance_source_access_list
,
11393 no_ipv6_bgp_distance_source_access_list_cmd
,
11394 "no distance (1-255) X:X::X:X/M WORD",
11396 "Define an administrative distance\n"
11397 "Administrative distance\n"
11398 "IP source prefix\n"
11399 "Access list name\n")
11401 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
11402 return CMD_SUCCESS
;
11405 DEFUN (bgp_damp_set
,
11407 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11408 "BGP Specific commands\n"
11409 "Enable route-flap dampening\n"
11410 "Half-life time for the penalty\n"
11411 "Value to start reusing a route\n"
11412 "Value to start suppressing a route\n"
11413 "Maximum duration to suppress a stable route\n")
11415 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11416 int idx_half_life
= 2;
11418 int idx_suppress
= 4;
11419 int idx_max_suppress
= 5;
11420 int half
= DEFAULT_HALF_LIFE
* 60;
11421 int reuse
= DEFAULT_REUSE
;
11422 int suppress
= DEFAULT_SUPPRESS
;
11423 int max
= 4 * half
;
11426 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
11427 reuse
= atoi(argv
[idx_reuse
]->arg
);
11428 suppress
= atoi(argv
[idx_suppress
]->arg
);
11429 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
11430 } else if (argc
== 3) {
11431 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
11435 if (suppress
< reuse
) {
11437 "Suppress value cannot be less than reuse value \n");
11441 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
11442 reuse
, suppress
, max
);
11445 DEFUN (bgp_damp_unset
,
11446 bgp_damp_unset_cmd
,
11447 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11449 "BGP Specific commands\n"
11450 "Enable route-flap dampening\n"
11451 "Half-life time for the penalty\n"
11452 "Value to start reusing a route\n"
11453 "Value to start suppressing a route\n"
11454 "Maximum duration to suppress a stable route\n")
11456 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11457 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
11460 /* Display specified route of BGP table. */
11461 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
11462 const char *ip_str
, afi_t afi
, safi_t safi
,
11463 struct prefix_rd
*prd
, int prefix_check
)
11466 struct prefix match
;
11467 struct bgp_node
*rn
;
11468 struct bgp_node
*rm
;
11469 struct bgp_path_info
*pi
;
11470 struct bgp_path_info
*pi_temp
;
11472 struct bgp_table
*table
;
11474 /* BGP structure lookup. */
11476 bgp
= bgp_lookup_by_name(view_name
);
11478 vty_out(vty
, "%% Can't find BGP instance %s\n",
11480 return CMD_WARNING
;
11483 bgp
= bgp_get_default();
11485 vty_out(vty
, "%% No BGP process is configured\n");
11486 return CMD_WARNING
;
11490 /* Check IP address argument. */
11491 ret
= str2prefix(ip_str
, &match
);
11493 vty_out(vty
, "%% address is malformed\n");
11494 return CMD_WARNING
;
11497 match
.family
= afi2family(afi
);
11499 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
11500 || (safi
== SAFI_EVPN
)) {
11501 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
11502 rn
= bgp_route_next(rn
)) {
11503 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
11505 table
= bgp_node_get_bgp_table_info(rn
);
11508 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
11512 || rm
->p
.prefixlen
== match
.prefixlen
) {
11513 pi
= bgp_node_get_bgp_path_info(rm
);
11515 if (pi
->extra
&& pi
->extra
->damp_info
) {
11516 pi_temp
= pi
->next
;
11517 bgp_damp_info_free(
11518 pi
->extra
->damp_info
,
11526 bgp_unlock_node(rm
);
11529 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
11532 || rn
->p
.prefixlen
== match
.prefixlen
) {
11533 pi
= bgp_node_get_bgp_path_info(rn
);
11535 if (pi
->extra
&& pi
->extra
->damp_info
) {
11536 pi_temp
= pi
->next
;
11537 bgp_damp_info_free(
11538 pi
->extra
->damp_info
,
11546 bgp_unlock_node(rn
);
11550 return CMD_SUCCESS
;
11553 DEFUN (clear_ip_bgp_dampening
,
11554 clear_ip_bgp_dampening_cmd
,
11555 "clear ip bgp dampening",
11559 "Clear route flap dampening information\n")
11561 bgp_damp_info_clean();
11562 return CMD_SUCCESS
;
11565 DEFUN (clear_ip_bgp_dampening_prefix
,
11566 clear_ip_bgp_dampening_prefix_cmd
,
11567 "clear ip bgp dampening A.B.C.D/M",
11571 "Clear route flap dampening information\n"
11574 int idx_ipv4_prefixlen
= 4;
11575 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
11576 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
11579 DEFUN (clear_ip_bgp_dampening_address
,
11580 clear_ip_bgp_dampening_address_cmd
,
11581 "clear ip bgp dampening A.B.C.D",
11585 "Clear route flap dampening information\n"
11586 "Network to clear damping information\n")
11589 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
11590 SAFI_UNICAST
, NULL
, 0);
11593 DEFUN (clear_ip_bgp_dampening_address_mask
,
11594 clear_ip_bgp_dampening_address_mask_cmd
,
11595 "clear ip bgp dampening A.B.C.D A.B.C.D",
11599 "Clear route flap dampening information\n"
11600 "Network to clear damping information\n"
11604 int idx_ipv4_2
= 5;
11606 char prefix_str
[BUFSIZ
];
11608 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11611 vty_out(vty
, "%% Inconsistent address and mask\n");
11612 return CMD_WARNING
;
11615 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11619 static void show_bgp_peerhash_entry(struct hash_backet
*backet
, void *arg
)
11621 struct vty
*vty
= arg
;
11622 struct peer
*peer
= backet
->data
;
11623 char buf
[SU_ADDRSTRLEN
];
11625 vty_out(vty
, "\tPeer: %s %s\n", peer
->host
,
11626 sockunion2str(&peer
->su
, buf
, sizeof(buf
)));
11629 DEFUN (show_bgp_peerhash
,
11630 show_bgp_peerhash_cmd
,
11631 "show bgp peerhash",
11634 "Display information about the BGP peerhash\n")
11636 struct list
*instances
= bm
->bgp
;
11637 struct listnode
*node
;
11640 for (ALL_LIST_ELEMENTS_RO(instances
, node
, bgp
)) {
11641 vty_out(vty
, "BGP: %s\n", bgp
->name
);
11642 hash_iterate(bgp
->peerhash
, show_bgp_peerhash_entry
,
11646 return CMD_SUCCESS
;
11649 /* also used for encap safi */
11650 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11651 afi_t afi
, safi_t safi
)
11653 struct bgp_node
*prn
;
11654 struct bgp_node
*rn
;
11655 struct bgp_table
*table
;
11657 struct prefix_rd
*prd
;
11658 struct bgp_static
*bgp_static
;
11659 mpls_label_t label
;
11660 char buf
[SU_ADDRSTRLEN
];
11661 char rdbuf
[RD_ADDRSTRLEN
];
11663 /* Network configuration. */
11664 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11665 prn
= bgp_route_next(prn
)) {
11666 table
= bgp_node_get_bgp_table_info(prn
);
11670 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11671 bgp_static
= bgp_node_get_bgp_static_info(rn
);
11672 if (bgp_static
== NULL
)
11676 prd
= (struct prefix_rd
*)&prn
->p
;
11678 /* "network" configuration display. */
11679 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11680 label
= decode_label(&bgp_static
->label
);
11682 vty_out(vty
, " network %s/%d rd %s",
11683 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11685 p
->prefixlen
, rdbuf
);
11686 if (safi
== SAFI_MPLS_VPN
)
11687 vty_out(vty
, " label %u", label
);
11689 if (bgp_static
->rmap
.name
)
11690 vty_out(vty
, " route-map %s",
11691 bgp_static
->rmap
.name
);
11693 if (bgp_static
->backdoor
)
11694 vty_out(vty
, " backdoor");
11696 vty_out(vty
, "\n");
11701 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11702 afi_t afi
, safi_t safi
)
11704 struct bgp_node
*prn
;
11705 struct bgp_node
*rn
;
11706 struct bgp_table
*table
;
11708 struct prefix_rd
*prd
;
11709 struct bgp_static
*bgp_static
;
11710 char buf
[PREFIX_STRLEN
* 2];
11711 char buf2
[SU_ADDRSTRLEN
];
11712 char rdbuf
[RD_ADDRSTRLEN
];
11714 /* Network configuration. */
11715 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11716 prn
= bgp_route_next(prn
)) {
11717 table
= bgp_node_get_bgp_table_info(prn
);
11721 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11722 bgp_static
= bgp_node_get_bgp_static_info(rn
);
11723 if (bgp_static
== NULL
)
11726 char *macrouter
= NULL
;
11729 if (bgp_static
->router_mac
)
11730 macrouter
= prefix_mac2str(
11731 bgp_static
->router_mac
, NULL
, 0);
11732 if (bgp_static
->eth_s_id
)
11733 esi
= esi2str(bgp_static
->eth_s_id
);
11735 prd
= (struct prefix_rd
*)&prn
->p
;
11737 /* "network" configuration display. */
11738 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11739 if (p
->u
.prefix_evpn
.route_type
== 5) {
11740 char local_buf
[PREFIX_STRLEN
];
11741 uint8_t family
= is_evpn_prefix_ipaddr_v4((
11742 struct prefix_evpn
*)p
)
11746 &p
->u
.prefix_evpn
.prefix_addr
.ip
.ip
.addr
,
11747 local_buf
, PREFIX_STRLEN
);
11748 sprintf(buf
, "%s/%u", local_buf
,
11749 p
->u
.prefix_evpn
.prefix_addr
.ip_prefix_length
);
11751 prefix2str(p
, buf
, sizeof(buf
));
11754 if (bgp_static
->gatewayIp
.family
== AF_INET
11755 || bgp_static
->gatewayIp
.family
== AF_INET6
)
11756 inet_ntop(bgp_static
->gatewayIp
.family
,
11757 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
11760 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11762 p
->u
.prefix_evpn
.prefix_addr
.eth_tag
,
11763 decode_label(&bgp_static
->label
), esi
, buf2
,
11767 XFREE(MTYPE_TMP
, macrouter
);
11769 XFREE(MTYPE_TMP
, esi
);
11774 /* Configuration of static route announcement and aggregate
11776 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11779 struct bgp_node
*rn
;
11781 struct bgp_static
*bgp_static
;
11782 struct bgp_aggregate
*bgp_aggregate
;
11783 char buf
[SU_ADDRSTRLEN
];
11785 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
11786 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
11790 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
11791 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
11795 /* Network configuration. */
11796 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11797 rn
= bgp_route_next(rn
)) {
11798 bgp_static
= bgp_node_get_bgp_static_info(rn
);
11799 if (bgp_static
== NULL
)
11804 /* "network" configuration display. */
11805 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11806 uint32_t destination
;
11807 struct in_addr netmask
;
11809 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11810 masklen2ip(p
->prefixlen
, &netmask
);
11811 vty_out(vty
, " network %s",
11812 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11815 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
11816 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
11817 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
11818 || p
->u
.prefix4
.s_addr
== 0) {
11819 /* Natural mask is not display. */
11821 vty_out(vty
, " mask %s", inet_ntoa(netmask
));
11823 vty_out(vty
, " network %s/%d",
11824 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11829 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11830 vty_out(vty
, " label-index %u",
11831 bgp_static
->label_index
);
11833 if (bgp_static
->rmap
.name
)
11834 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
11836 if (bgp_static
->backdoor
)
11837 vty_out(vty
, " backdoor");
11839 vty_out(vty
, "\n");
11842 /* Aggregate-address configuration. */
11843 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11844 rn
= bgp_route_next(rn
)) {
11845 bgp_aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
11846 if (bgp_aggregate
== NULL
)
11851 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11852 struct in_addr netmask
;
11854 masklen2ip(p
->prefixlen
, &netmask
);
11855 vty_out(vty
, " aggregate-address %s %s",
11856 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11858 inet_ntoa(netmask
));
11860 vty_out(vty
, " aggregate-address %s/%d",
11861 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11866 if (bgp_aggregate
->as_set
)
11867 vty_out(vty
, " as-set");
11869 if (bgp_aggregate
->summary_only
)
11870 vty_out(vty
, " summary-only");
11872 vty_out(vty
, "\n");
11876 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11879 struct bgp_node
*rn
;
11880 struct bgp_distance
*bdistance
;
11882 /* Distance configuration. */
11883 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11884 && bgp
->distance_local
[afi
][safi
]
11885 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11886 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11887 || bgp
->distance_local
[afi
][safi
]
11888 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11889 vty_out(vty
, " distance bgp %d %d %d\n",
11890 bgp
->distance_ebgp
[afi
][safi
],
11891 bgp
->distance_ibgp
[afi
][safi
],
11892 bgp
->distance_local
[afi
][safi
]);
11895 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11896 rn
= bgp_route_next(rn
)) {
11897 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11898 if (bdistance
!= NULL
) {
11899 char buf
[PREFIX_STRLEN
];
11901 vty_out(vty
, " distance %d %s %s\n",
11902 bdistance
->distance
,
11903 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11904 bdistance
->access_list
? bdistance
->access_list
11910 /* Allocate routing table structure and install commands. */
11911 void bgp_route_init(void)
11916 /* Init BGP distance table. */
11917 FOREACH_AFI_SAFI (afi
, safi
)
11918 bgp_distance_table
[afi
][safi
] = bgp_table_init(NULL
, afi
, safi
);
11920 /* IPv4 BGP commands. */
11921 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11922 install_element(BGP_NODE
, &bgp_network_cmd
);
11923 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11925 install_element(BGP_NODE
, &aggregate_address_cmd
);
11926 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11927 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11928 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11930 /* IPv4 unicast configuration. */
11931 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11932 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11933 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11935 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11936 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11937 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11938 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11940 /* IPv4 multicast configuration. */
11941 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11942 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11943 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11944 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11945 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11946 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11947 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11949 /* IPv4 labeled-unicast configuration. */
11950 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11951 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11952 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11953 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11954 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11956 install_element(VIEW_NODE
,
11957 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11958 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11959 install_element(VIEW_NODE
,
11960 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11961 #ifdef KEEP_OLD_VPN_COMMANDS
11962 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11963 #endif /* KEEP_OLD_VPN_COMMANDS */
11964 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11965 install_element(VIEW_NODE
,
11966 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11968 /* BGP dampening clear commands */
11969 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11970 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11972 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11973 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11976 install_element(ENABLE_NODE
,
11977 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11978 #ifdef KEEP_OLD_VPN_COMMANDS
11979 install_element(ENABLE_NODE
,
11980 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11981 #endif /* KEEP_OLD_VPN_COMMANDS */
11983 /* New config IPv6 BGP commands. */
11984 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11985 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11986 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11988 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11989 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11991 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11993 install_element(BGP_NODE
, &bgp_distance_cmd
);
11994 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11995 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11996 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11997 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11998 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11999 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
12000 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
12001 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
12002 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
12003 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
12004 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
12005 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
12006 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
12007 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
12008 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
12009 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
12010 install_element(BGP_IPV4M_NODE
,
12011 &no_bgp_distance_source_access_list_cmd
);
12012 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
12013 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
12014 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
12015 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
12016 install_element(BGP_IPV6_NODE
,
12017 &ipv6_bgp_distance_source_access_list_cmd
);
12018 install_element(BGP_IPV6_NODE
,
12019 &no_ipv6_bgp_distance_source_access_list_cmd
);
12020 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
12021 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
12022 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
12023 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
12024 install_element(BGP_IPV6M_NODE
,
12025 &ipv6_bgp_distance_source_access_list_cmd
);
12026 install_element(BGP_IPV6M_NODE
,
12027 &no_ipv6_bgp_distance_source_access_list_cmd
);
12029 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
12030 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
12031 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
12032 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
12034 /* IPv4 Multicast Mode */
12035 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
12036 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
12038 /* Large Communities */
12039 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
12040 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
12042 /* show bgp ipv4 flowspec detailed */
12043 install_element(VIEW_NODE
, &show_ip_bgp_flowspec_routes_detailed_cmd
);
12045 install_element(VIEW_NODE
, &show_bgp_peerhash_cmd
);
12048 void bgp_route_finish(void)
12053 FOREACH_AFI_SAFI (afi
, safi
) {
12054 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
12055 bgp_distance_table
[afi
][safi
] = NULL
;