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
33 #include "sockunion.h"
36 #include "workqueue.h"
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_route.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_debug.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_regex.h"
48 #include "bgpd/bgp_community.h"
49 #include "bgpd/bgp_ecommunity.h"
50 #include "bgpd/bgp_lcommunity.h"
51 #include "bgpd/bgp_clist.h"
52 #include "bgpd/bgp_packet.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_fsm.h"
55 #include "bgpd/bgp_mplsvpn.h"
56 #include "bgpd/bgp_nexthop.h"
57 #include "bgpd/bgp_damp.h"
58 #include "bgpd/bgp_advertise.h"
59 #include "bgpd/bgp_zebra.h"
60 #include "bgpd/bgp_vty.h"
61 #include "bgpd/bgp_mpath.h"
62 #include "bgpd/bgp_nht.h"
63 #include "bgpd/bgp_updgrp.h"
64 #include "bgpd/bgp_label.h"
67 #include "bgpd/rfapi/rfapi_backend.h"
68 #include "bgpd/rfapi/vnc_import_bgp.h"
69 #include "bgpd/rfapi/vnc_export_bgp.h"
71 #include "bgpd/bgp_encap_types.h"
72 #include "bgpd/bgp_encap_tlv.h"
73 #include "bgpd/bgp_evpn.h"
74 #include "bgpd/bgp_evpn_vty.h"
77 /* Extern from bgp_dump.c */
78 extern const char *bgp_origin_str
[];
79 extern const char *bgp_origin_long_str
[];
81 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
82 safi_t safi
, struct prefix
*p
,
83 struct prefix_rd
*prd
)
86 struct bgp_node
*prn
= NULL
;
92 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
93 || (safi
== SAFI_EVPN
)) {
94 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
96 if (prn
->info
== NULL
)
97 prn
->info
= bgp_table_init(afi
, safi
);
103 rn
= bgp_node_get(table
, p
);
105 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
106 || (safi
== SAFI_EVPN
))
112 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
113 safi_t safi
, struct prefix
*p
,
114 struct prefix_rd
*prd
)
117 struct bgp_node
*prn
= NULL
;
122 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
123 || (safi
== SAFI_EVPN
)) {
124 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
128 if (prn
->info
== NULL
) {
129 bgp_unlock_node(prn
);
136 rn
= bgp_node_lookup(table
, p
);
141 /* Allocate bgp_info_extra */
142 static struct bgp_info_extra
*bgp_info_extra_new(void)
144 struct bgp_info_extra
*new;
145 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
, sizeof(struct bgp_info_extra
));
146 new->label
= MPLS_INVALID_LABEL
;
150 static void bgp_info_extra_free(struct bgp_info_extra
**extra
)
152 if (extra
&& *extra
) {
153 if ((*extra
)->damp_info
)
154 bgp_damp_info_free((*extra
)->damp_info
, 0);
156 (*extra
)->damp_info
= NULL
;
158 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
164 /* Get bgp_info extra information for the given bgp_info, lazy allocated
167 struct bgp_info_extra
*bgp_info_extra_get(struct bgp_info
*ri
)
170 ri
->extra
= bgp_info_extra_new();
174 /* Allocate new bgp info structure. */
175 struct bgp_info
*bgp_info_new(void)
177 return XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
180 /* Free bgp route information. */
181 static void bgp_info_free(struct bgp_info
*binfo
)
184 bgp_attr_unintern(&binfo
->attr
);
186 bgp_unlink_nexthop(binfo
);
187 bgp_info_extra_free(&binfo
->extra
);
188 bgp_info_mpath_free(&binfo
->mpath
);
190 peer_unlock(binfo
->peer
); /* bgp_info peer reference */
192 XFREE(MTYPE_BGP_ROUTE
, binfo
);
195 struct bgp_info
*bgp_info_lock(struct bgp_info
*binfo
)
201 struct bgp_info
*bgp_info_unlock(struct bgp_info
*binfo
)
203 assert(binfo
&& binfo
->lock
> 0);
206 if (binfo
->lock
== 0) {
208 zlog_debug ("%s: unlocked and freeing", __func__
);
209 zlog_backtrace (LOG_DEBUG
);
211 bgp_info_free(binfo
);
216 if (binfo
->lock
== 1)
218 zlog_debug ("%s: unlocked to 1", __func__
);
219 zlog_backtrace (LOG_DEBUG
);
226 void bgp_info_add(struct bgp_node
*rn
, struct bgp_info
*ri
)
228 struct bgp_info
*top
;
240 peer_lock(ri
->peer
); /* bgp_info peer reference */
243 /* Do the actual removal of info from RIB, for use by bgp_process
244 completion callback *only* */
245 void bgp_info_reap(struct bgp_node
*rn
, struct bgp_info
*ri
)
248 ri
->next
->prev
= ri
->prev
;
250 ri
->prev
->next
= ri
->next
;
254 bgp_info_mpath_dequeue(ri
);
259 void bgp_info_delete(struct bgp_node
*rn
, struct bgp_info
*ri
)
261 bgp_info_set_flag(rn
, ri
, BGP_INFO_REMOVED
);
262 /* set of previous already took care of pcount */
263 UNSET_FLAG(ri
->flags
, BGP_INFO_VALID
);
266 /* undo the effects of a previous call to bgp_info_delete; typically
267 called when a route is deleted and then quickly re-added before the
268 deletion has been processed */
269 void bgp_info_restore(struct bgp_node
*rn
, struct bgp_info
*ri
)
271 bgp_info_unset_flag(rn
, ri
, BGP_INFO_REMOVED
);
272 /* unset of previous already took care of pcount */
273 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
276 /* Adjust pcount as required */
277 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_info
*ri
)
279 struct bgp_table
*table
;
281 assert(rn
&& bgp_node_table(rn
));
282 assert(ri
&& ri
->peer
&& ri
->peer
->bgp
);
284 table
= bgp_node_table(rn
);
286 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
289 if (!BGP_INFO_COUNTABLE(ri
)
290 && CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
292 UNSET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
294 /* slight hack, but more robust against errors. */
295 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
296 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
299 "%s: Asked to decrement 0 prefix count for peer %s",
300 __func__
, ri
->peer
->host
);
301 zlog_backtrace(LOG_WARNING
);
302 zlog_warn("%s: Please report to Quagga bugzilla",
305 } else if (BGP_INFO_COUNTABLE(ri
)
306 && !CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
307 SET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
308 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
312 static int bgp_label_index_differs(struct bgp_info
*ri1
, struct bgp_info
*ri2
)
314 return (!(ri1
->attr
->label_index
== ri2
->attr
->label_index
));
317 /* Set/unset bgp_info flags, adjusting any other state as needed.
318 * This is here primarily to keep prefix-count in check.
320 void bgp_info_set_flag(struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
322 SET_FLAG(ri
->flags
, flag
);
324 /* early bath if we know it's not a flag that changes countability state
326 if (!CHECK_FLAG(flag
,
327 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
330 bgp_pcount_adjust(rn
, ri
);
333 void bgp_info_unset_flag(struct bgp_node
*rn
, struct bgp_info
*ri
,
336 UNSET_FLAG(ri
->flags
, flag
);
338 /* early bath if we know it's not a flag that changes countability state
340 if (!CHECK_FLAG(flag
,
341 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
344 bgp_pcount_adjust(rn
, ri
);
347 /* Get MED value. If MED value is missing and "bgp bestpath
348 missing-as-worst" is specified, treat it as the worst value. */
349 static u_int32_t
bgp_med_value(struct attr
*attr
, struct bgp
*bgp
)
351 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
354 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
361 void bgp_info_path_with_addpath_rx_str(struct bgp_info
*ri
, char *buf
)
363 if (ri
->addpath_rx_id
)
364 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
,
367 sprintf(buf
, "path %s", ri
->peer
->host
);
370 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
372 static int bgp_info_cmp(struct bgp
*bgp
, struct bgp_info
*new,
373 struct bgp_info
*exist
, int *paths_eq
,
374 struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
375 char *pfx_buf
, afi_t afi
, safi_t safi
)
377 struct attr
*newattr
, *existattr
;
378 bgp_peer_sort_t new_sort
;
379 bgp_peer_sort_t exist_sort
;
381 u_int32_t exist_pref
;
384 u_int32_t new_weight
;
385 u_int32_t exist_weight
;
386 uint32_t newm
, existm
;
387 struct in_addr new_id
;
388 struct in_addr exist_id
;
391 int internal_as_route
;
394 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
395 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
396 u_int32_t new_mm_seq
;
397 u_int32_t exist_mm_seq
;
404 zlog_debug("%s: new is NULL", pfx_buf
);
409 bgp_info_path_with_addpath_rx_str(new, new_buf
);
413 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
419 bgp_info_path_with_addpath_rx_str(exist
, exist_buf
);
420 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
421 pfx_buf
, new_buf
, new->flags
, exist_buf
,
426 existattr
= exist
->attr
;
428 /* For EVPN routes, we cannot just go by local vs remote, we have to
429 * look at the MAC mobility sequence number, if present.
431 if (safi
== SAFI_EVPN
) {
432 /* This is an error condition described in RFC 7432 Section
434 * states that in this scenario "the PE MUST alert the operator"
436 * does not state what other action to take. In order to provide
438 * consistency in this scenario we are going to prefer the path
442 if (newattr
->sticky
!= existattr
->sticky
) {
444 prefix2str(&new->net
->p
, pfx_buf
,
446 * PREFIX2STR_BUFFER
);
447 bgp_info_path_with_addpath_rx_str(new, new_buf
);
448 bgp_info_path_with_addpath_rx_str(exist
,
452 if (newattr
->sticky
&& !existattr
->sticky
) {
454 "%s: %s wins over %s due to sticky MAC flag",
455 pfx_buf
, new_buf
, exist_buf
);
459 if (!newattr
->sticky
&& existattr
->sticky
) {
461 "%s: %s loses to %s due to sticky MAC flag",
462 pfx_buf
, new_buf
, exist_buf
);
467 new_mm_seq
= mac_mobility_seqnum(newattr
);
468 exist_mm_seq
= mac_mobility_seqnum(existattr
);
470 if (new_mm_seq
> exist_mm_seq
) {
473 "%s: %s wins over %s due to MM seq %u > %u",
474 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
479 if (new_mm_seq
< exist_mm_seq
) {
482 "%s: %s loses to %s due to MM seq %u < %u",
483 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
489 /* 1. Weight check. */
490 new_weight
= exist_weight
= 0;
492 new_weight
= newattr
->weight
;
493 exist_weight
= existattr
->weight
;
495 if (new_weight
> exist_weight
) {
497 zlog_debug("%s: %s wins over %s due to weight %d > %d",
498 pfx_buf
, new_buf
, exist_buf
, new_weight
,
503 if (new_weight
< exist_weight
) {
505 zlog_debug("%s: %s loses to %s due to weight %d < %d",
506 pfx_buf
, new_buf
, exist_buf
, new_weight
,
511 /* 2. Local preference check. */
512 new_pref
= exist_pref
= bgp
->default_local_pref
;
514 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
515 new_pref
= newattr
->local_pref
;
516 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
517 exist_pref
= existattr
->local_pref
;
519 if (new_pref
> exist_pref
) {
522 "%s: %s wins over %s due to localpref %d > %d",
523 pfx_buf
, new_buf
, exist_buf
, new_pref
,
528 if (new_pref
< exist_pref
) {
531 "%s: %s loses to %s due to localpref %d < %d",
532 pfx_buf
, new_buf
, exist_buf
, new_pref
,
537 /* 3. Local route check. We prefer:
539 * - BGP_ROUTE_AGGREGATE
540 * - BGP_ROUTE_REDISTRIBUTE
542 if (!(new->sub_type
== BGP_ROUTE_NORMAL
)) {
545 "%s: %s wins over %s due to preferred BGP_ROUTE type",
546 pfx_buf
, new_buf
, exist_buf
);
550 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
)) {
553 "%s: %s loses to %s due to preferred BGP_ROUTE type",
554 pfx_buf
, new_buf
, exist_buf
);
558 /* 4. AS path length check. */
559 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
560 int exist_hops
= aspath_count_hops(existattr
->aspath
);
561 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
563 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
566 aspath_hops
= aspath_count_hops(newattr
->aspath
);
567 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
569 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
572 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
573 pfx_buf
, new_buf
, exist_buf
,
575 (exist_hops
+ exist_confeds
));
579 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
582 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
583 pfx_buf
, new_buf
, exist_buf
,
585 (exist_hops
+ exist_confeds
));
589 int newhops
= aspath_count_hops(newattr
->aspath
);
591 if (newhops
< exist_hops
) {
594 "%s: %s wins over %s due to aspath hopcount %d < %d",
595 pfx_buf
, new_buf
, exist_buf
,
596 newhops
, exist_hops
);
600 if (newhops
> exist_hops
) {
603 "%s: %s loses to %s due to aspath hopcount %d > %d",
604 pfx_buf
, new_buf
, exist_buf
,
605 newhops
, exist_hops
);
611 /* 5. Origin check. */
612 if (newattr
->origin
< existattr
->origin
) {
614 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
615 pfx_buf
, new_buf
, exist_buf
,
616 bgp_origin_long_str
[newattr
->origin
],
617 bgp_origin_long_str
[existattr
->origin
]);
621 if (newattr
->origin
> existattr
->origin
) {
623 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
624 pfx_buf
, new_buf
, exist_buf
,
625 bgp_origin_long_str
[newattr
->origin
],
626 bgp_origin_long_str
[existattr
->origin
]);
631 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
632 && aspath_count_hops(existattr
->aspath
) == 0);
633 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
634 && aspath_count_confeds(existattr
->aspath
) > 0
635 && aspath_count_hops(newattr
->aspath
) == 0
636 && aspath_count_hops(existattr
->aspath
) == 0);
638 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
639 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
640 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
641 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
642 || internal_as_route
) {
643 new_med
= bgp_med_value(new->attr
, bgp
);
644 exist_med
= bgp_med_value(exist
->attr
, bgp
);
646 if (new_med
< exist_med
) {
649 "%s: %s wins over %s due to MED %d < %d",
650 pfx_buf
, new_buf
, exist_buf
, new_med
,
655 if (new_med
> exist_med
) {
658 "%s: %s loses to %s due to MED %d > %d",
659 pfx_buf
, new_buf
, exist_buf
, new_med
,
665 /* 7. Peer type check. */
666 new_sort
= new->peer
->sort
;
667 exist_sort
= exist
->peer
->sort
;
669 if (new_sort
== BGP_PEER_EBGP
670 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
673 "%s: %s wins over %s due to eBGP peer > iBGP peer",
674 pfx_buf
, new_buf
, exist_buf
);
678 if (exist_sort
== BGP_PEER_EBGP
679 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
682 "%s: %s loses to %s due to iBGP peer < eBGP peer",
683 pfx_buf
, new_buf
, exist_buf
);
687 /* 8. IGP metric check. */
691 newm
= new->extra
->igpmetric
;
693 existm
= exist
->extra
->igpmetric
;
698 "%s: %s wins over %s due to IGP metric %d < %d",
699 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
706 "%s: %s loses to %s due to IGP metric %d > %d",
707 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
711 /* 9. Same IGP metric. Compare the cluster list length as
712 representative of IGP hops metric. Rewrite the metric value
713 pair (newm, existm) with the cluster list length. Prefer the
714 path with smaller cluster list length. */
715 if (newm
== existm
) {
716 if (peer_sort(new->peer
) == BGP_PEER_IBGP
717 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
718 && (mpath_cfg
== NULL
720 mpath_cfg
->ibgp_flags
,
721 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
722 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
723 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
728 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
729 pfx_buf
, new_buf
, exist_buf
,
737 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
738 pfx_buf
, new_buf
, exist_buf
,
745 /* 10. confed-external vs. confed-internal */
746 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
747 if (new_sort
== BGP_PEER_CONFED
748 && exist_sort
== BGP_PEER_IBGP
) {
751 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
752 pfx_buf
, new_buf
, exist_buf
);
756 if (exist_sort
== BGP_PEER_CONFED
757 && new_sort
== BGP_PEER_IBGP
) {
760 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
761 pfx_buf
, new_buf
, exist_buf
);
766 /* 11. Maximum path check. */
767 if (newm
== existm
) {
768 /* If one path has a label but the other does not, do not treat
769 * them as equals for multipath
771 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
))
773 && bgp_is_valid_label(&exist
->extra
->label
))) {
776 "%s: %s and %s cannot be multipath, one has a label while the other does not",
777 pfx_buf
, new_buf
, exist_buf
);
778 } else if (bgp_flag_check(bgp
,
779 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
782 * For the two paths, all comparison steps till IGP
784 * have succeeded - including AS_PATH hop count. Since
786 * bestpath as-path multipath-relax' knob is on, we
788 * an exact match of AS_PATH. Thus, mark the paths are
790 * That will trigger both these paths to get into the
798 "%s: %s and %s are equal via multipath-relax",
799 pfx_buf
, new_buf
, exist_buf
);
800 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
801 if (aspath_cmp(new->attr
->aspath
,
802 exist
->attr
->aspath
)) {
807 "%s: %s and %s are equal via matching aspaths",
808 pfx_buf
, new_buf
, exist_buf
);
810 } else if (new->peer
->as
== exist
->peer
->as
) {
815 "%s: %s and %s are equal via same remote-as",
816 pfx_buf
, new_buf
, exist_buf
);
820 * TODO: If unequal cost ibgp multipath is enabled we can
821 * mark the paths as equal here instead of returning
826 "%s: %s wins over %s after IGP metric comparison",
827 pfx_buf
, new_buf
, exist_buf
);
830 "%s: %s loses to %s after IGP metric comparison",
831 pfx_buf
, new_buf
, exist_buf
);
836 /* 12. If both paths are external, prefer the path that was received
837 first (the oldest one). This step minimizes route-flap, since a
838 newer path won't displace an older one, even if it was the
839 preferred route based on the additional decision criteria below. */
840 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
841 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
842 if (CHECK_FLAG(new->flags
, BGP_INFO_SELECTED
)) {
845 "%s: %s wins over %s due to oldest external",
846 pfx_buf
, new_buf
, exist_buf
);
850 if (CHECK_FLAG(exist
->flags
, BGP_INFO_SELECTED
)) {
853 "%s: %s loses to %s due to oldest external",
854 pfx_buf
, new_buf
, exist_buf
);
859 /* 13. Router-ID comparision. */
860 /* If one of the paths is "stale", the corresponding peer router-id will
861 * be 0 and would always win over the other path. If originator id is
862 * used for the comparision, it will decide which path is better.
864 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
865 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
867 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
868 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
869 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
871 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
873 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
876 "%s: %s wins over %s due to Router-ID comparison",
877 pfx_buf
, new_buf
, exist_buf
);
881 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
884 "%s: %s loses to %s due to Router-ID comparison",
885 pfx_buf
, new_buf
, exist_buf
);
889 /* 14. Cluster length comparision. */
890 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
891 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
893 if (new_cluster
< exist_cluster
) {
896 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
897 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
902 if (new_cluster
> exist_cluster
) {
905 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
906 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
911 /* 15. Neighbor address comparision. */
912 /* Do this only if neither path is "stale" as stale paths do not have
913 * valid peer information (as the connection may or may not be up).
915 if (CHECK_FLAG(exist
->flags
, BGP_INFO_STALE
)) {
918 "%s: %s wins over %s due to latter path being STALE",
919 pfx_buf
, new_buf
, exist_buf
);
923 if (CHECK_FLAG(new->flags
, BGP_INFO_STALE
)) {
926 "%s: %s loses to %s due to former path being STALE",
927 pfx_buf
, new_buf
, exist_buf
);
931 /* locally configured routes to advertise do not have su_remote */
932 if (new->peer
->su_remote
== NULL
)
934 if (exist
->peer
->su_remote
== NULL
)
937 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
942 "%s: %s loses to %s due to Neighor IP comparison",
943 pfx_buf
, new_buf
, exist_buf
);
950 "%s: %s wins over %s due to Neighor IP comparison",
951 pfx_buf
, new_buf
, exist_buf
);
956 zlog_debug("%s: %s wins over %s due to nothing left to compare",
957 pfx_buf
, new_buf
, exist_buf
);
962 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
963 * is preferred, or 0 if they are the same (usually will only occur if
964 * multipath is enabled
965 * This version is compatible with */
966 int bgp_info_cmp_compatible(struct bgp
*bgp
, struct bgp_info
*new,
967 struct bgp_info
*exist
, char *pfx_buf
, afi_t afi
,
972 ret
= bgp_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
, afi
,
986 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
987 struct attr
*attr
, afi_t afi
,
990 struct bgp_filter
*filter
;
992 filter
= &peer
->filter
[afi
][safi
];
994 #define FILTER_EXIST_WARN(F, f, filter) \
995 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
996 zlog_warn("%s: Could not find configured input %s-list %s!", \
997 peer->host, #f, F##_IN_NAME(filter));
999 if (DISTRIBUTE_IN_NAME(filter
)) {
1000 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1002 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1006 if (PREFIX_LIST_IN_NAME(filter
)) {
1007 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1009 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1013 if (FILTER_LIST_IN_NAME(filter
)) {
1014 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1016 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1021 return FILTER_PERMIT
;
1022 #undef FILTER_EXIST_WARN
1025 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1026 struct attr
*attr
, afi_t afi
,
1029 struct bgp_filter
*filter
;
1031 filter
= &peer
->filter
[afi
][safi
];
1033 #define FILTER_EXIST_WARN(F, f, filter) \
1034 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1035 zlog_warn("%s: Could not find configured output %s-list %s!", \
1036 peer->host, #f, F##_OUT_NAME(filter));
1038 if (DISTRIBUTE_OUT_NAME(filter
)) {
1039 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1041 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1045 if (PREFIX_LIST_OUT_NAME(filter
)) {
1046 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1048 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1053 if (FILTER_LIST_OUT_NAME(filter
)) {
1054 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1056 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1061 return FILTER_PERMIT
;
1062 #undef FILTER_EXIST_WARN
1065 /* If community attribute includes no_export then return 1. */
1066 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1068 if (attr
->community
) {
1069 /* NO_ADVERTISE check. */
1070 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1073 /* NO_EXPORT check. */
1074 if (peer
->sort
== BGP_PEER_EBGP
1075 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1078 /* NO_EXPORT_SUBCONFED check. */
1079 if (peer
->sort
== BGP_PEER_EBGP
1080 || peer
->sort
== BGP_PEER_CONFED
)
1081 if (community_include(attr
->community
,
1082 COMMUNITY_NO_EXPORT_SUBCONFED
))
1088 /* Route reflection loop check. */
1089 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1091 struct in_addr cluster_id
;
1093 if (attr
->cluster
) {
1094 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1095 cluster_id
= peer
->bgp
->cluster_id
;
1097 cluster_id
= peer
->bgp
->router_id
;
1099 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1105 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1106 struct attr
*attr
, afi_t afi
, safi_t safi
,
1107 const char *rmap_name
)
1109 struct bgp_filter
*filter
;
1110 struct bgp_info info
;
1111 route_map_result_t ret
;
1112 struct route_map
*rmap
= NULL
;
1114 filter
= &peer
->filter
[afi
][safi
];
1116 /* Apply default weight value. */
1117 if (peer
->weight
[afi
][safi
])
1118 attr
->weight
= peer
->weight
[afi
][safi
];
1121 rmap
= route_map_lookup_by_name(rmap_name
);
1126 if (ROUTE_MAP_IN_NAME(filter
)) {
1127 rmap
= ROUTE_MAP_IN(filter
);
1134 /* Route map apply. */
1136 /* Duplicate current value to new strucutre for modification. */
1140 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1142 /* Apply BGP route map to the attribute. */
1143 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1145 peer
->rmap_type
= 0;
1147 if (ret
== RMAP_DENYMATCH
) {
1148 /* Free newly generated AS path and community by
1150 bgp_attr_flush(attr
);
1157 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1158 struct attr
*attr
, afi_t afi
, safi_t safi
,
1159 const char *rmap_name
)
1161 struct bgp_filter
*filter
;
1162 struct bgp_info info
;
1163 route_map_result_t ret
;
1164 struct route_map
*rmap
= NULL
;
1166 filter
= &peer
->filter
[afi
][safi
];
1168 /* Apply default weight value. */
1169 if (peer
->weight
[afi
][safi
])
1170 attr
->weight
= peer
->weight
[afi
][safi
];
1173 rmap
= route_map_lookup_by_name(rmap_name
);
1178 if (ROUTE_MAP_OUT_NAME(filter
)) {
1179 rmap
= ROUTE_MAP_OUT(filter
);
1186 /* Route map apply. */
1188 /* Duplicate current value to new strucutre for modification. */
1192 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1194 /* Apply BGP route map to the attribute. */
1195 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1197 peer
->rmap_type
= 0;
1199 if (ret
== RMAP_DENYMATCH
)
1200 /* caller has multiple error paths with bgp_attr_flush()
1207 /* If this is an EBGP peer with remove-private-AS */
1208 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1209 struct peer
*peer
, struct attr
*attr
)
1211 if (peer
->sort
== BGP_PEER_EBGP
1212 && (peer_af_flag_check(peer
, afi
, safi
,
1213 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1214 || peer_af_flag_check(peer
, afi
, safi
,
1215 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1216 || peer_af_flag_check(peer
, afi
, safi
,
1217 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1218 || peer_af_flag_check(peer
, afi
, safi
,
1219 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1220 // Take action on the entire aspath
1221 if (peer_af_flag_check(peer
, afi
, safi
,
1222 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1223 || peer_af_flag_check(peer
, afi
, safi
,
1224 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1225 if (peer_af_flag_check(
1227 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1228 attr
->aspath
= aspath_replace_private_asns(
1229 attr
->aspath
, bgp
->as
);
1231 // The entire aspath consists of private ASNs so create
1233 else if (aspath_private_as_check(attr
->aspath
))
1234 attr
->aspath
= aspath_empty_get();
1236 // There are some public and some private ASNs, remove
1239 attr
->aspath
= aspath_remove_private_asns(
1243 // 'all' was not specified so the entire aspath must be private
1245 // for us to do anything
1246 else if (aspath_private_as_check(attr
->aspath
)) {
1247 if (peer_af_flag_check(
1249 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1250 attr
->aspath
= aspath_replace_private_asns(
1251 attr
->aspath
, bgp
->as
);
1253 attr
->aspath
= aspath_empty_get();
1258 /* If this is an EBGP peer with as-override */
1259 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1260 struct peer
*peer
, struct attr
*attr
)
1262 if (peer
->sort
== BGP_PEER_EBGP
1263 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1264 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1265 attr
->aspath
= aspath_replace_specific_asn(
1266 attr
->aspath
, peer
->as
, bgp
->as
);
1270 static void subgroup_announce_reset_nhop(u_char family
, struct attr
*attr
)
1272 if (family
== AF_INET
)
1273 attr
->nexthop
.s_addr
= 0;
1274 if (family
== AF_INET6
)
1275 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1278 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_info
*ri
,
1279 struct update_subgroup
*subgrp
, struct prefix
*p
,
1282 struct bgp_filter
*filter
;
1285 struct peer
*onlypeer
;
1287 struct attr
*riattr
;
1288 struct peer_af
*paf
;
1289 char buf
[PREFIX_STRLEN
];
1295 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1297 if (DISABLE_BGP_ANNOUNCE
)
1300 afi
= SUBGRP_AFI(subgrp
);
1301 safi
= SUBGRP_SAFI(subgrp
);
1302 peer
= SUBGRP_PEER(subgrp
);
1304 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1305 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1308 filter
= &peer
->filter
[afi
][safi
];
1309 bgp
= SUBGRP_INST(subgrp
);
1310 riattr
= bgp_info_mpath_count(ri
) ? bgp_info_mpath_attr(ri
) : ri
->attr
;
1313 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1314 && ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1315 || (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1318 * direct and direct_ext type routes originate internally even
1319 * though they can have peer pointers that reference other
1322 prefix2str(p
, buf
, PREFIX_STRLEN
);
1323 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1329 /* With addpath we may be asked to TX all kinds of paths so make sure
1331 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1332 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)
1333 || CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1337 /* If this is not the bestpath then check to see if there is an enabled
1339 * feature that requires us to advertise it */
1340 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
1341 if (!bgp_addpath_tx_path(peer
, afi
, safi
, ri
)) {
1346 /* Aggregate-address suppress check. */
1347 if (ri
->extra
&& ri
->extra
->suppress
)
1348 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1352 /* If it's labeled safi, make sure the route has a valid label. */
1353 if (safi
== SAFI_LABELED_UNICAST
) {
1354 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1355 if (!bgp_is_valid_label(&label
)) {
1356 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1357 zlog_debug("u%" PRIu64
":s%" PRIu64
1358 " %s/%d is filtered - no label (%p)",
1359 subgrp
->update_group
->id
, subgrp
->id
,
1360 inet_ntop(p
->family
, &p
->u
.prefix
,
1361 buf
, SU_ADDRSTRLEN
),
1362 p
->prefixlen
, &label
);
1367 /* Do not send back route to sender. */
1368 if (onlypeer
&& from
== onlypeer
) {
1372 /* Do not send the default route in the BGP table if the neighbor is
1373 * configured for default-originate */
1374 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1375 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1376 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1378 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1382 /* Transparency check. */
1383 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1384 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1389 /* If community is not disabled check the no-export and local. */
1390 if (!transparent
&& bgp_community_filter(peer
, riattr
)) {
1391 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1393 "subgrpannouncecheck: community filter check fail");
1397 /* If the attribute has originator-id and it is same as remote
1399 if (onlypeer
&& riattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1400 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &riattr
->originator_id
))) {
1401 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1403 "%s [Update:SEND] %s originator-id is same as "
1406 prefix2str(p
, buf
, sizeof(buf
)));
1410 /* ORF prefix-list filter check */
1411 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1412 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1413 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1414 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1415 if (peer
->orf_plist
[afi
][safi
]) {
1416 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1418 if (bgp_debug_update(NULL
, p
,
1419 subgrp
->update_group
, 0))
1421 "%s [Update:SEND] %s is filtered via ORF",
1429 /* Output filter check. */
1430 if (bgp_output_filter(peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
) {
1431 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1432 zlog_debug("%s [Update:SEND] %s is filtered",
1433 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1437 #ifdef BGP_SEND_ASPATH_CHECK
1438 /* AS path loop check. */
1439 if (onlypeer
&& aspath_loop_check(riattr
->aspath
, onlypeer
->as
)) {
1440 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1442 "%s [Update:SEND] suppress announcement to peer AS %u "
1443 "that is part of AS path.",
1444 onlypeer
->host
, onlypeer
->as
);
1447 #endif /* BGP_SEND_ASPATH_CHECK */
1449 /* If we're a CONFED we need to loop check the CONFED ID too */
1450 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1451 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
)) {
1452 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1454 "%s [Update:SEND] suppress announcement to peer AS %u"
1456 peer
->host
, bgp
->confed_id
);
1461 /* Route-Reflect check. */
1462 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1467 /* IBGP reflection check. */
1468 if (reflect
&& !samepeer_safe
) {
1469 /* A route from a Client peer. */
1470 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1471 PEER_FLAG_REFLECTOR_CLIENT
)) {
1472 /* Reflect to all the Non-Client peers and also to the
1473 Client peers other than the originator. Originator
1475 is already done. So there is noting to do. */
1476 /* no bgp client-to-client reflection check. */
1477 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1478 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1479 PEER_FLAG_REFLECTOR_CLIENT
))
1482 /* A route from a Non-client peer. Reflect to all other
1484 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1485 PEER_FLAG_REFLECTOR_CLIENT
))
1490 /* For modify attribute, copy it to temporary structure. */
1491 bgp_attr_dup(attr
, riattr
);
1493 /* If local-preference is not set. */
1494 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1495 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1496 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1497 attr
->local_pref
= bgp
->default_local_pref
;
1500 /* If originator-id is not set and the route is to be reflected,
1501 set the originator id */
1503 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1504 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1505 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1508 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1510 if (peer
->sort
== BGP_PEER_EBGP
1511 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1512 if (from
!= bgp
->peer_self
&& !transparent
1513 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1514 PEER_FLAG_MED_UNCHANGED
))
1516 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1519 /* Since the nexthop attribute can vary per peer, it is not explicitly
1521 * in announce check, only certain flags and length (or number of
1523 * -- for IPv6/MP_REACH) are set here in order to guide the update
1525 * code in setting the nexthop(s) on a per peer basis in
1527 * Typically, the source nexthop in the attribute is preserved but in
1529 * scenarios where we know it will always be overwritten, we reset the
1530 * nexthop to "0" in an attempt to achieve better Update packing. An
1531 * example of this is when a prefix from each of 2 IBGP peers needs to
1533 * announced to an EBGP peer (and they have the same attributes barring
1537 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1539 #define NEXTHOP_IS_V6 \
1540 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1541 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1542 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1543 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1545 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1547 * the peer (group) is configured to receive link-local nexthop
1549 * and it is available in the prefix OR we're not reflecting the route
1551 * the peer (group) to whom we're going to announce is on a shared
1553 * and this is either a self-originated route or the peer is EBGP.
1555 if (NEXTHOP_IS_V6
) {
1556 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1557 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1558 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1559 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1560 || (!reflect
&& peer
->shared_network
1561 && (from
== bgp
->peer_self
1562 || peer
->sort
== BGP_PEER_EBGP
))) {
1563 attr
->mp_nexthop_len
=
1564 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1567 /* Clear off link-local nexthop in source, whenever it is not
1569 * ensure more prefixes share the same attribute for
1572 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1573 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1574 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1577 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1578 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1580 /* Route map & unsuppress-map apply. */
1581 if (ROUTE_MAP_OUT_NAME(filter
) || (ri
->extra
&& ri
->extra
->suppress
)) {
1582 struct bgp_info info
;
1583 struct attr dummy_attr
;
1587 /* don't confuse inbound and outbound setting */
1588 RESET_FLAG(attr
->rmap_change_flags
);
1591 * The route reflector is not allowed to modify the attributes
1592 * of the reflected IBGP routes unless explicitly allowed.
1594 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1595 && !bgp_flag_check(bgp
,
1596 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1597 bgp_attr_dup(&dummy_attr
, attr
);
1598 info
.attr
= &dummy_attr
;
1601 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1603 if (ri
->extra
&& ri
->extra
->suppress
)
1604 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1607 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1610 peer
->rmap_type
= 0;
1612 if (ret
== RMAP_DENYMATCH
) {
1613 bgp_attr_flush(attr
);
1618 /* After route-map has been applied, we check to see if the nexthop to
1619 * be carried in the attribute (that is used for the announcement) can
1620 * be cleared off or not. We do this in all cases where we would be
1621 * setting the nexthop to "ourselves". For IPv6, we only need to
1623 * the global nexthop here; the link-local nexthop would have been
1625 * already, and if not, it is required by the update formation code.
1626 * Also see earlier comments in this function.
1629 * If route-map has performed some operation on the nexthop or the peer
1630 * configuration says to pass it unchanged, we cannot reset the nexthop
1631 * here, so only attempt to do it if these aren't true. Note that the
1632 * route-map handler itself might have cleared the nexthop, if for
1634 * it is configured as 'peer-address'.
1636 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1637 riattr
->rmap_change_flags
)
1639 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1640 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1641 /* We can reset the nexthop, if setting (or forcing) it to
1643 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1644 PEER_FLAG_NEXTHOP_SELF
)
1645 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1646 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1648 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1649 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1650 subgroup_announce_reset_nhop(
1651 (peer_cap_enhe(peer
, afi
, safi
)
1655 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1656 /* Can also reset the nexthop if announcing to EBGP, but
1658 * no peer in the subgroup is on a shared subnet.
1659 * Note: 3rd party nexthop currently implemented for
1662 SUBGRP_FOREACH_PEER(subgrp
, paf
)
1664 if (bgp_multiaccess_check_v4(riattr
->nexthop
,
1669 subgroup_announce_reset_nhop(
1670 (peer_cap_enhe(peer
, afi
, safi
)
1675 /* If IPv6/MP and nexthop does not have any override and happens
1677 * be a link-local address, reset it so that we don't pass along
1679 * source's link-local IPv6 address to recipients who may not be
1681 * the same interface.
1683 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1684 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1685 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1692 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1693 struct bgp_maxpaths_cfg
*mpath_cfg
,
1694 struct bgp_info_pair
*result
, afi_t afi
, safi_t safi
)
1696 struct bgp_info
*new_select
;
1697 struct bgp_info
*old_select
;
1698 struct bgp_info
*ri
;
1699 struct bgp_info
*ri1
;
1700 struct bgp_info
*ri2
;
1701 struct bgp_info
*nextri
= NULL
;
1702 int paths_eq
, do_mpath
, debug
;
1703 struct list mp_list
;
1704 char pfx_buf
[PREFIX2STR_BUFFER
];
1705 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1707 bgp_mp_list_init(&mp_list
);
1709 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1711 debug
= bgp_debug_bestpath(&rn
->p
);
1714 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1716 /* bgp deterministic-med */
1718 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1720 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1721 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1722 bgp_info_unset_flag(rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1724 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
) {
1725 if (CHECK_FLAG(ri1
->flags
, BGP_INFO_DMED_CHECK
))
1727 if (BGP_INFO_HOLDDOWN(ri1
))
1729 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1730 if (ri1
->peer
->status
!= Established
)
1735 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
) {
1736 if (CHECK_FLAG(ri2
->flags
,
1737 BGP_INFO_DMED_CHECK
))
1739 if (BGP_INFO_HOLDDOWN(ri2
))
1742 && ri2
->peer
!= bgp
->peer_self
1745 PEER_STATUS_NSF_WAIT
))
1746 if (ri2
->peer
->status
1750 if (aspath_cmp_left(ri1
->attr
->aspath
,
1752 || aspath_cmp_left_confed(
1754 ri2
->attr
->aspath
)) {
1755 if (bgp_info_cmp(bgp
, ri2
,
1761 bgp_info_unset_flag(
1763 BGP_INFO_DMED_SELECTED
);
1769 BGP_INFO_DMED_CHECK
);
1773 bgp_info_set_flag(rn
, new_select
, BGP_INFO_DMED_CHECK
);
1774 bgp_info_set_flag(rn
, new_select
,
1775 BGP_INFO_DMED_SELECTED
);
1778 bgp_info_path_with_addpath_rx_str(new_select
,
1780 zlog_debug("%s: %s is the bestpath from AS %d",
1782 aspath_get_first_as(
1783 new_select
->attr
->aspath
));
1788 /* Check old selected route and new selected route. */
1791 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1793 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
))
1796 if (BGP_INFO_HOLDDOWN(ri
)) {
1797 /* reap REMOVED routes, if needs be
1798 * selected route must stay for a while longer though
1800 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
1801 && (ri
!= old_select
))
1802 bgp_info_reap(rn
, ri
);
1807 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1808 && !CHECK_FLAG(ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1809 if (ri
->peer
->status
!= Established
)
1812 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1813 && (!CHECK_FLAG(ri
->flags
, BGP_INFO_DMED_SELECTED
))) {
1814 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1818 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1820 if (bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1821 debug
, pfx_buf
, afi
, safi
)) {
1826 /* Now that we know which path is the bestpath see if any of the other
1828 * qualify as multipaths
1832 bgp_info_path_with_addpath_rx_str(new_select
, path_buf
);
1834 sprintf(path_buf
, "NONE");
1836 "%s: After path selection, newbest is %s oldbest was %s",
1838 old_select
? old_select
->peer
->host
: "NONE");
1841 if (do_mpath
&& new_select
) {
1842 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1846 bgp_info_path_with_addpath_rx_str(ri
, path_buf
);
1848 if (ri
== new_select
) {
1851 "%s: %s is the bestpath, add to the multipath list",
1853 bgp_mp_list_add(&mp_list
, ri
);
1857 if (BGP_INFO_HOLDDOWN(ri
))
1860 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1861 && !CHECK_FLAG(ri
->peer
->sflags
,
1862 PEER_STATUS_NSF_WAIT
))
1863 if (ri
->peer
->status
!= Established
)
1866 if (!bgp_info_nexthop_cmp(ri
, new_select
)) {
1869 "%s: %s has the same nexthop as the bestpath, skip it",
1874 bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1875 debug
, pfx_buf
, afi
, safi
);
1880 "%s: %s is equivalent to the bestpath, add to the multipath list",
1882 bgp_mp_list_add(&mp_list
, ri
);
1887 bgp_info_mpath_update(rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1888 bgp_info_mpath_aggregate_update(new_select
, old_select
);
1889 bgp_mp_list_clear(&mp_list
);
1891 result
->old
= old_select
;
1892 result
->new = new_select
;
1898 * A new route/change in bestpath of an existing route. Evaluate the path
1899 * for advertisement to the subgroup.
1901 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
1902 struct bgp_info
*selected
,
1903 struct bgp_node
*rn
,
1904 u_int32_t addpath_tx_id
)
1907 struct peer
*onlypeer
;
1913 afi
= SUBGRP_AFI(subgrp
);
1914 safi
= SUBGRP_SAFI(subgrp
);
1915 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
1918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1919 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
1920 PEER_STATUS_ORF_WAIT_REFRESH
))
1923 memset(&attr
, 0, sizeof(struct attr
));
1924 /* It's initialized in bgp_announce_check() */
1926 /* Announcement to the subgroup. If the route is filtered withdraw it.
1929 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1930 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1932 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
1933 selected
->addpath_tx_id
);
1936 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1938 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1945 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1946 * This is called at the end of route processing.
1948 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
1950 struct bgp_info
*ri
;
1952 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1953 if (BGP_INFO_HOLDDOWN(ri
))
1955 UNSET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
1956 UNSET_FLAG(ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1961 * Has the route changed from the RIB's perspective? This is invoked only
1962 * if the route selection returns the same best route as earlier - to
1963 * determine if we need to update zebra or not.
1965 int bgp_zebra_has_route_changed(struct bgp_node
*rn
, struct bgp_info
*selected
)
1967 struct bgp_info
*mpinfo
;
1969 /* If this is multipath, check all selected paths for any nexthop change
1971 * attribute change. Some attribute changes (e.g., community) aren't of
1972 * relevance to the RIB, but we'll update zebra to ensure we handle the
1973 * case of BGP nexthop change. This is the behavior when the best path
1975 * an attribute change anyway.
1977 if (CHECK_FLAG(selected
->flags
, BGP_INFO_IGP_CHANGED
)
1978 || CHECK_FLAG(selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1981 /* If this is multipath, check all selected paths for any nexthop change
1983 for (mpinfo
= bgp_info_mpath_first(selected
); mpinfo
;
1984 mpinfo
= bgp_info_mpath_next(mpinfo
)) {
1985 if (CHECK_FLAG(mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1986 || CHECK_FLAG(mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1990 /* Nothing has changed from the RIB's perspective. */
1994 struct bgp_process_queue
{
1996 struct bgp_node
*rn
;
2001 static wq_item_status
bgp_process_main(struct work_queue
*wq
, void *data
)
2003 struct bgp_process_queue
*pq
= data
;
2004 struct bgp
*bgp
= pq
->bgp
;
2005 struct bgp_node
*rn
= pq
->rn
;
2006 afi_t afi
= pq
->afi
;
2007 safi_t safi
= pq
->safi
;
2008 struct prefix
*p
= &rn
->p
;
2009 struct bgp_info
*new_select
;
2010 struct bgp_info
*old_select
;
2011 struct bgp_info_pair old_and_new
;
2013 /* Is it end of initial update? (after startup) */
2015 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2016 sizeof(bgp
->update_delay_zebra_resume_time
));
2018 bgp
->main_zebra_update_hold
= 0;
2019 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2020 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
2021 if (bgp_fibupd_safi(safi
))
2022 bgp_zebra_announce_table(bgp
, afi
,
2025 bgp
->main_peers_update_hold
= 0;
2027 bgp_start_routeadv(bgp
);
2031 /* Best path selection. */
2032 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2034 old_select
= old_and_new
.old
;
2035 new_select
= old_and_new
.new;
2037 /* Do we need to allocate or free labels?
2038 * Right now, since we only deal with per-prefix labels, it is not
2040 * to do this upon changes to best path except of the label index
2043 if (safi
== SAFI_UNICAST
) {
2046 || bgp_label_index_differs(new_select
, old_select
)
2047 || new_select
->sub_type
!= old_select
->sub_type
) {
2048 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2049 && new_select
->attr
->flag
2051 BGP_ATTR_PREFIX_SID
)
2052 && new_select
->attr
->label_index
2053 != BGP_INVALID_LABEL_INDEX
) {
2056 BGP_NODE_REGISTERED_FOR_LABEL
))
2057 bgp_unregister_for_label(rn
);
2058 label_ntop(MPLS_IMP_NULL_LABEL
, 1,
2060 bgp_set_valid_label(&rn
->local_label
);
2062 bgp_register_for_label(rn
, new_select
);
2064 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
2065 bgp_unregister_for_label(rn
);
2068 /* If best route remains the same and this is not due to user-initiated
2069 * clear, see exactly what needs to be done.
2072 if (old_select
&& old_select
== new_select
2073 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2074 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2075 && !bgp
->addpath_tx_used
[afi
][safi
]) {
2076 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2078 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2079 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2081 if (bgp_fibupd_safi(safi
) && !bgp
->name
2082 && !bgp_option_check(BGP_OPT_NO_FIB
)
2083 && new_select
->type
== ZEBRA_ROUTE_BGP
2084 && new_select
->sub_type
== BGP_ROUTE_NORMAL
)
2085 bgp_zebra_announce(rn
, p
, old_select
, bgp
, afi
,
2088 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2089 bgp_zebra_clear_route_change_flags(rn
);
2091 /* If there is a change of interest to peers, reannounce the
2093 if (CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2094 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2095 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2097 /* unicast routes must also be annouced to
2098 * labeled-unicast update-groups */
2099 if (safi
== SAFI_UNICAST
)
2100 group_announce_route(bgp
, afi
,
2101 SAFI_LABELED_UNICAST
, rn
,
2104 UNSET_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2105 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2108 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2112 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2114 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2116 /* bestpath has changed; bump version */
2117 if (old_select
|| new_select
) {
2118 bgp_bump_version(rn
);
2120 if (!bgp
->t_rmap_def_originate_eval
) {
2124 update_group_refresh_default_originate_route_map
,
2125 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2126 &bgp
->t_rmap_def_originate_eval
);
2131 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
2133 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
2134 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2135 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2139 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2140 if (old_select
!= new_select
) {
2142 vnc_import_bgp_exterior_del_route(bgp
, p
,
2144 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2147 vnc_import_bgp_exterior_add_route(bgp
, p
,
2149 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2155 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2157 /* unicast routes must also be annouced to labeled-unicast update-groups
2159 if (safi
== SAFI_UNICAST
)
2160 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2164 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2165 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2166 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2167 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2168 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2169 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2171 /* Withdraw the route from the kernel. */
2172 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2173 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2174 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2175 bgp_zebra_withdraw(p
, old_select
, safi
);
2179 /* Clear any route change flags. */
2180 bgp_zebra_clear_route_change_flags(rn
);
2182 /* Reap old select bgp_info, if it has been removed */
2183 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
2184 bgp_info_reap(rn
, old_select
);
2186 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2190 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2192 struct bgp_process_queue
*pq
= data
;
2193 struct bgp_table
*table
;
2195 bgp_unlock(pq
->bgp
);
2197 table
= bgp_node_table(pq
->rn
);
2198 bgp_unlock_node(pq
->rn
);
2199 bgp_table_unlock(table
);
2201 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pq
);
2204 void bgp_process_queue_init(void)
2206 if (!bm
->process_main_queue
) {
2207 bm
->process_main_queue
=
2208 work_queue_new(bm
->master
, "process_main_queue");
2210 if (!bm
->process_main_queue
) {
2211 zlog_err("%s: Failed to allocate work queue", __func__
);
2216 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2217 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2218 bm
->process_main_queue
->spec
.max_retries
= 0;
2219 bm
->process_main_queue
->spec
.hold
= 50;
2220 /* Use a higher yield value of 50ms for main queue processing */
2221 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2224 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2226 struct bgp_process_queue
*pqnode
;
2228 /* already scheduled for processing? */
2229 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2232 if (bm
->process_main_queue
== NULL
)
2235 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2236 sizeof(struct bgp_process_queue
));
2240 /* all unlocked in bgp_processq_del */
2241 bgp_table_lock(bgp_node_table(rn
));
2242 pqnode
->rn
= bgp_lock_node(rn
);
2246 pqnode
->safi
= safi
;
2247 work_queue_add(bm
->process_main_queue
, pqnode
);
2248 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2252 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2254 struct bgp_process_queue
*pqnode
;
2256 if (bm
->process_main_queue
== NULL
)
2259 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2260 sizeof(struct bgp_process_queue
));
2267 work_queue_add(bm
->process_main_queue
, pqnode
);
2270 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2274 peer
= THREAD_ARG(thread
);
2275 peer
->t_pmax_restart
= NULL
;
2277 if (bgp_debug_neighbor_events(peer
))
2279 "%s Maximum-prefix restart timer expired, restore peering",
2282 peer_clear(peer
, NULL
);
2287 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2293 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2296 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2297 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2298 PEER_STATUS_PREFIX_LIMIT
)
2303 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2305 afi_safi_print(afi
, safi
), peer
->host
,
2306 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2307 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2309 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2310 PEER_FLAG_MAX_PREFIX_WARNING
))
2313 /* Convert AFI, SAFI to values for packet. */
2314 pkt_afi
= afi_int2iana(afi
);
2315 pkt_safi
= safi_int2iana(safi
);
2319 ndata
[0] = (pkt_afi
>> 8);
2321 ndata
[2] = pkt_safi
;
2322 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2323 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2324 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2325 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2327 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2328 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2329 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2333 /* Dynamic peers will just close their connection. */
2334 if (peer_dynamic_neighbor(peer
))
2337 /* restart timer start */
2338 if (peer
->pmax_restart
[afi
][safi
]) {
2339 peer
->v_pmax_restart
=
2340 peer
->pmax_restart
[afi
][safi
] * 60;
2342 if (bgp_debug_neighbor_events(peer
))
2344 "%s Maximum-prefix restart timer started for %d secs",
2345 peer
->host
, peer
->v_pmax_restart
);
2347 BGP_TIMER_ON(peer
->t_pmax_restart
,
2348 bgp_maximum_prefix_restart_timer
,
2349 peer
->v_pmax_restart
);
2354 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2355 PEER_STATUS_PREFIX_LIMIT
);
2357 if (peer
->pcount
[afi
][safi
]
2358 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2359 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2360 PEER_STATUS_PREFIX_THRESHOLD
)
2365 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2366 afi_safi_print(afi
, safi
), peer
->host
,
2367 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2368 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2369 PEER_STATUS_PREFIX_THRESHOLD
);
2371 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2372 PEER_STATUS_PREFIX_THRESHOLD
);
2376 /* Unconditionally remove the route from the RIB, without taking
2377 * damping into consideration (eg, because the session went down)
2379 static void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_info
*ri
,
2380 struct peer
*peer
, afi_t afi
, safi_t safi
)
2382 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2384 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2385 bgp_info_delete(rn
, ri
); /* keep historical info */
2387 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2390 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_info
*ri
,
2391 struct peer
*peer
, afi_t afi
, safi_t safi
,
2392 struct prefix_rd
*prd
)
2394 int status
= BGP_DAMP_NONE
;
2396 /* apply dampening, if result is suppressed, we'll be retaining
2397 * the bgp_info in the RIB for historical reference.
2399 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2400 && peer
->sort
== BGP_PEER_EBGP
)
2401 if ((status
= bgp_damp_withdraw(ri
, rn
, afi
, safi
, 0))
2402 == BGP_DAMP_SUPPRESSED
) {
2403 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
,
2409 if (safi
== SAFI_MPLS_VPN
) {
2410 struct bgp_node
*prn
= NULL
;
2411 struct bgp_table
*table
= NULL
;
2413 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2414 (struct prefix
*)prd
);
2416 table
= (struct bgp_table
*)(prn
->info
);
2418 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2419 peer
->bgp
, prd
, table
, &rn
->p
, ri
);
2421 bgp_unlock_node(prn
);
2423 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2424 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2426 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2427 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2433 /* If this is an EVPN route, process for un-import. */
2434 if (safi
== SAFI_EVPN
)
2435 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2437 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
2440 struct bgp_info
*info_make(int type
, int sub_type
, u_short instance
,
2441 struct peer
*peer
, struct attr
*attr
,
2442 struct bgp_node
*rn
)
2444 struct bgp_info
*new;
2446 /* Make new BGP info. */
2447 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
2449 new->instance
= instance
;
2450 new->sub_type
= sub_type
;
2453 new->uptime
= bgp_clock();
2455 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2459 static void overlay_index_update(struct attr
*attr
,
2460 struct eth_segment_id
*eth_s_id
,
2461 union gw_addr
*gw_ip
)
2466 if (eth_s_id
== NULL
) {
2467 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2468 sizeof(struct eth_segment_id
));
2470 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2471 sizeof(struct eth_segment_id
));
2473 if (gw_ip
== NULL
) {
2474 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2476 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2477 sizeof(union gw_addr
));
2481 static bool overlay_index_equal(afi_t afi
, struct bgp_info
*info
,
2482 struct eth_segment_id
*eth_s_id
,
2483 union gw_addr
*gw_ip
)
2485 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2486 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2489 if (afi
!= AFI_L2VPN
)
2492 memset(&temp
, 0, 16);
2493 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2494 info_gw_ip
= (union gw_addr
*)&temp
;
2495 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2498 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2499 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2502 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2504 info_gw_ip_remote
= gw_ip
;
2505 if (eth_s_id
== NULL
)
2506 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2508 info_eth_s_id_remote
= eth_s_id
;
2509 if (!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2511 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
,
2512 sizeof(struct eth_segment_id
));
2515 /* Check if received nexthop is valid or not. */
2516 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2521 /* Only validated for unicast and multicast currently. */
2522 /* Also valid for EVPN where the nexthop is an IP address. */
2523 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2526 /* If NEXT_HOP is present, validate it. */
2527 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2528 if (attr
->nexthop
.s_addr
== 0
2529 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2530 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2534 /* If MP_NEXTHOP is present, validate it. */
2535 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2536 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2537 * it is not an IPv6 link-local address.
2539 if (attr
->mp_nexthop_len
) {
2540 switch (attr
->mp_nexthop_len
) {
2541 case BGP_ATTR_NHLEN_IPV4
:
2542 case BGP_ATTR_NHLEN_VPNV4
:
2543 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2544 || IPV4_CLASS_DE(ntohl(
2545 attr
->mp_nexthop_global_in
.s_addr
))
2546 || bgp_nexthop_self(bgp
,
2547 attr
->mp_nexthop_global_in
));
2550 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2551 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2552 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2553 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2554 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2555 || IN6_IS_ADDR_MULTICAST(
2556 &attr
->mp_nexthop_global
));
2568 int bgp_update(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2569 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2570 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2571 int soft_reconfig
, struct bgp_route_evpn
*evpn
)
2574 int aspath_loop_count
= 0;
2575 struct bgp_node
*rn
;
2577 struct attr new_attr
;
2578 struct attr
*attr_new
;
2579 struct bgp_info
*ri
;
2580 struct bgp_info
*new;
2582 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2585 int do_loop_check
= 1;
2586 int has_valid_label
= 0;
2588 int vnc_implicit_withdraw
= 0;
2592 memset(&new_attr
, 0, sizeof(struct attr
));
2593 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2594 new_attr
.label
= MPLS_INVALID_LABEL
;
2597 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2598 has_valid_label
= bgp_is_valid_label(label
);
2600 if (has_valid_label
)
2601 sprintf(label_buf
, "label %u", label_pton(label
));
2603 /* When peer's soft reconfiguration enabled. Record input packet in
2606 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2607 && peer
!= bgp
->peer_self
)
2608 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2610 /* Check previously received route. */
2611 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2612 if (ri
->peer
== peer
&& ri
->type
== type
2613 && ri
->sub_type
== sub_type
2614 && ri
->addpath_rx_id
== addpath_id
)
2617 /* AS path local-as loop check. */
2618 if (peer
->change_local_as
) {
2619 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2620 aspath_loop_count
= 1;
2622 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2623 > aspath_loop_count
) {
2624 reason
= "as-path contains our own AS;";
2629 /* If the peer is configured for "allowas-in origin" and the last ASN in
2631 * as-path is our ASN then we do not need to call aspath_loop_check
2633 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2634 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2637 /* AS path loop check. */
2638 if (do_loop_check
) {
2639 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2640 > peer
->allowas_in
[afi
][safi
]
2641 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2642 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2643 > peer
->allowas_in
[afi
][safi
])) {
2644 reason
= "as-path contains our own AS;";
2649 /* Route reflector originator ID check. */
2650 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2651 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2652 reason
= "originator is us;";
2656 /* Route reflector cluster ID check. */
2657 if (bgp_cluster_filter(peer
, attr
)) {
2658 reason
= "reflected from the same cluster;";
2662 /* Apply incoming filter. */
2663 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
2668 bgp_attr_dup(&new_attr
, attr
);
2670 /* Apply incoming route-map.
2671 * NB: new_attr may now contain newly allocated values from route-map
2673 * commands, so we need bgp_attr_flush in the error paths, until we
2675 * the attr (which takes over the memory references) */
2676 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
2678 reason
= "route-map;";
2679 bgp_attr_flush(&new_attr
);
2683 /* next hop check. */
2684 if (bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
2685 reason
= "martian or self next-hop;";
2686 bgp_attr_flush(&new_attr
);
2690 attr_new
= bgp_attr_intern(&new_attr
);
2692 /* If the update is implicit withdraw. */
2694 ri
->uptime
= bgp_clock();
2695 same_attr
= attrhash_cmp(ri
->attr
, attr_new
);
2697 /* Same attribute comes in. */
2698 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
2699 && attrhash_cmp(ri
->attr
, attr_new
)
2700 && (!has_valid_label
2701 || memcmp(&(bgp_info_extra_get(ri
))->label
, label
,
2704 && (overlay_index_equal(
2705 afi
, ri
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2706 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
2707 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
2708 BGP_CONFIG_DAMPENING
)
2709 && peer
->sort
== BGP_PEER_EBGP
2710 && CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
2711 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2712 bgp_debug_rdpfxpath2str(
2713 afi
, safi
, prd
, p
, label
,
2714 addpath_id
? 1 : 0, addpath_id
,
2715 pfx_buf
, sizeof(pfx_buf
));
2716 zlog_debug("%s rcvd %s", peer
->host
,
2720 if (bgp_damp_update(ri
, rn
, afi
, safi
)
2721 != BGP_DAMP_SUPPRESSED
) {
2722 bgp_aggregate_increment(bgp
, p
, ri
, afi
,
2724 bgp_process(bgp
, rn
, afi
, safi
);
2726 } else /* Duplicate - odd */
2728 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2729 if (!peer
->rcvd_attr_printed
) {
2731 "%s rcvd UPDATE w/ attr: %s",
2733 peer
->rcvd_attr_str
);
2734 peer
->rcvd_attr_printed
= 1;
2737 bgp_debug_rdpfxpath2str(
2738 afi
, safi
, prd
, p
, label
,
2739 addpath_id
? 1 : 0, addpath_id
,
2740 pfx_buf
, sizeof(pfx_buf
));
2742 "%s rcvd %s...duplicate ignored",
2743 peer
->host
, pfx_buf
);
2746 /* graceful restart STALE flag unset. */
2747 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)) {
2748 bgp_info_unset_flag(rn
, ri
,
2750 bgp_process(bgp
, rn
, afi
, safi
);
2754 bgp_unlock_node(rn
);
2755 bgp_attr_unintern(&attr_new
);
2760 /* Withdraw/Announce before we fully processed the withdraw */
2761 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
2762 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2763 bgp_debug_rdpfxpath2str(
2764 afi
, safi
, prd
, p
, label
,
2765 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
2768 "%s rcvd %s, flapped quicker than processing",
2769 peer
->host
, pfx_buf
);
2772 bgp_info_restore(rn
, ri
);
2775 /* Received Logging. */
2776 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2777 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
2778 addpath_id
? 1 : 0, addpath_id
,
2779 pfx_buf
, sizeof(pfx_buf
));
2780 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
2783 /* graceful restart STALE flag unset. */
2784 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
2785 bgp_info_unset_flag(rn
, ri
, BGP_INFO_STALE
);
2787 /* The attribute is changed. */
2788 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2790 /* implicit withdraw, decrement aggregate and pcount here.
2791 * only if update is accepted, they'll increment below.
2793 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
2795 /* Update bgp route dampening information. */
2796 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2797 && peer
->sort
== BGP_PEER_EBGP
) {
2798 /* This is implicit withdraw so we should update
2801 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2802 bgp_damp_withdraw(ri
, rn
, afi
, safi
, 1);
2805 if (safi
== SAFI_MPLS_VPN
) {
2806 struct bgp_node
*prn
= NULL
;
2807 struct bgp_table
*table
= NULL
;
2809 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
2810 (struct prefix
*)prd
);
2812 table
= (struct bgp_table
*)(prn
->info
);
2814 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2815 bgp
, prd
, table
, p
, ri
);
2817 bgp_unlock_node(prn
);
2819 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
2820 && (safi
== SAFI_UNICAST
)) {
2821 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2823 * Implicit withdraw case.
2825 ++vnc_implicit_withdraw
;
2826 vnc_import_bgp_del_route(bgp
, p
, ri
);
2827 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2832 /* Special handling for EVPN update of an existing route. If the
2833 * extended community attribute has changed, we need to
2835 * the route using its existing extended community. It will be
2836 * subsequently processed for import with the new extended
2839 if (safi
== SAFI_EVPN
&& !same_attr
) {
2841 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
2843 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
2846 cmp
= ecommunity_cmp(ri
->attr
->ecommunity
,
2847 attr_new
->ecommunity
);
2849 if (bgp_debug_update(peer
, p
, NULL
, 1))
2851 "Change in EXT-COMM, existing %s new %s",
2853 ri
->attr
->ecommunity
),
2855 attr_new
->ecommunity
));
2856 bgp_evpn_unimport_route(bgp
, afi
, safi
,
2862 /* Update to new attribute. */
2863 bgp_attr_unintern(&ri
->attr
);
2864 ri
->attr
= attr_new
;
2866 /* Update MPLS label */
2867 if (has_valid_label
) {
2868 memcpy(&(bgp_info_extra_get(ri
))->label
, label
,
2870 bgp_set_valid_label(&(bgp_info_extra_get(ri
))->label
);
2874 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
2875 && (safi
== SAFI_UNICAST
)) {
2876 if (vnc_implicit_withdraw
) {
2878 * Add back the route with its new attributes
2880 * The route is still selected, until the route
2882 * queued by bgp_process actually runs. We have
2884 * update to the VNC side immediately to avoid
2886 * configuration changes (e.g., route-map
2888 * trigger re-importation of the entire RIB.
2890 vnc_import_bgp_add_route(bgp
, p
, ri
);
2891 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2895 /* Update Overlay Index */
2896 if (afi
== AFI_L2VPN
) {
2897 overlay_index_update(
2898 ri
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2899 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
2902 /* Update bgp route dampening information. */
2903 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2904 && peer
->sort
== BGP_PEER_EBGP
) {
2905 /* Now we do normal update dampening. */
2906 ret
= bgp_damp_update(ri
, rn
, afi
, safi
);
2907 if (ret
== BGP_DAMP_SUPPRESSED
) {
2908 bgp_unlock_node(rn
);
2913 /* Nexthop reachability check - for unicast and
2914 * labeled-unicast.. */
2915 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
2916 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
2917 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
2918 && !CHECK_FLAG(peer
->flags
,
2919 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2921 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2926 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
2928 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
2930 if (BGP_DEBUG(nht
, NHT
)) {
2931 char buf1
[INET6_ADDRSTRLEN
];
2933 (const void *)&attr_new
2935 buf1
, INET6_ADDRSTRLEN
);
2936 zlog_debug("%s(%s): NH unresolved",
2937 __FUNCTION__
, buf1
);
2939 bgp_info_unset_flag(rn
, ri
, BGP_INFO_VALID
);
2942 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
2945 if (safi
== SAFI_MPLS_VPN
) {
2946 struct bgp_node
*prn
= NULL
;
2947 struct bgp_table
*table
= NULL
;
2949 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
2950 (struct prefix
*)prd
);
2952 table
= (struct bgp_table
*)(prn
->info
);
2954 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2955 bgp
, prd
, table
, p
, ri
);
2957 bgp_unlock_node(prn
);
2961 /* If this is an EVPN route and some attribute has changed,
2963 * route for import. If the extended community has changed, we
2965 * have done the un-import earlier and the import would result
2967 * route getting injected into appropriate L2 VNIs. If it is
2969 * some other attribute change, the import will result in
2971 * the attributes for the route in the VNI(s).
2973 if (safi
== SAFI_EVPN
&& !same_attr
)
2974 bgp_evpn_import_route(bgp
, afi
, safi
, p
, ri
);
2976 /* Process change. */
2977 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
2979 bgp_process(bgp
, rn
, afi
, safi
);
2980 bgp_unlock_node(rn
);
2983 if (SAFI_MPLS_VPN
== safi
) {
2984 mpls_label_t label_decoded
= decode_label(label
);
2986 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
2987 type
, sub_type
, &label_decoded
);
2989 if (SAFI_ENCAP
== safi
) {
2990 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
2991 type
, sub_type
, NULL
);
2996 } // End of implicit withdraw
2998 /* Received Logging. */
2999 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3000 if (!peer
->rcvd_attr_printed
) {
3001 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3002 peer
->rcvd_attr_str
);
3003 peer
->rcvd_attr_printed
= 1;
3006 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3007 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3009 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3012 /* Make new BGP info. */
3013 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3015 /* Update MPLS label */
3016 if (has_valid_label
) {
3017 memcpy(&(bgp_info_extra_get(new))->label
, label
,
3019 bgp_set_valid_label(&(bgp_info_extra_get(new))->label
);
3022 /* Update Overlay Index */
3023 if (afi
== AFI_L2VPN
) {
3024 overlay_index_update(new->attr
,
3025 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3026 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3028 /* Nexthop reachability check. */
3029 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3030 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3031 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3032 && !CHECK_FLAG(peer
->flags
,
3033 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3034 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3039 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, connected
))
3040 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3042 if (BGP_DEBUG(nht
, NHT
)) {
3043 char buf1
[INET6_ADDRSTRLEN
];
3045 (const void *)&attr_new
->nexthop
,
3046 buf1
, INET6_ADDRSTRLEN
);
3047 zlog_debug("%s(%s): NH unresolved",
3048 __FUNCTION__
, buf1
);
3050 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
3053 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3056 new->addpath_rx_id
= addpath_id
;
3058 /* Increment prefix */
3059 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3061 /* Register new BGP information. */
3062 bgp_info_add(rn
, new);
3064 /* route_node_get lock */
3065 bgp_unlock_node(rn
);
3068 if (safi
== SAFI_MPLS_VPN
) {
3069 struct bgp_node
*prn
= NULL
;
3070 struct bgp_table
*table
= NULL
;
3072 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3074 table
= (struct bgp_table
*)(prn
->info
);
3076 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3077 bgp
, prd
, table
, p
, new);
3079 bgp_unlock_node(prn
);
3083 /* If maximum prefix count is configured and current prefix
3085 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3088 /* If this is an EVPN route, process for import. */
3089 if (safi
== SAFI_EVPN
)
3090 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3092 /* Process change. */
3093 bgp_process(bgp
, rn
, afi
, safi
);
3096 if (SAFI_MPLS_VPN
== safi
) {
3097 mpls_label_t label_decoded
= decode_label(label
);
3099 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3100 sub_type
, &label_decoded
);
3102 if (SAFI_ENCAP
== safi
) {
3103 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3110 /* This BGP update is filtered. Log the reason then update BGP
3113 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3114 if (!peer
->rcvd_attr_printed
) {
3115 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3116 peer
->rcvd_attr_str
);
3117 peer
->rcvd_attr_printed
= 1;
3120 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3121 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3123 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3124 peer
->host
, pfx_buf
, reason
);
3128 /* If this is an EVPN route, un-import it as it is now filtered.
3130 if (safi
== SAFI_EVPN
)
3131 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, ri
);
3133 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3136 bgp_unlock_node(rn
);
3140 * Filtered update is treated as an implicit withdrawal (see
3142 * a few lines above)
3144 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3145 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3153 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3154 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3155 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3156 struct bgp_route_evpn
*evpn
)
3159 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3160 struct bgp_node
*rn
;
3161 struct bgp_info
*ri
;
3164 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3165 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3173 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3175 /* If peer is soft reconfiguration enabled. Record input packet for
3176 * further calculation.
3178 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3179 * routes that are filtered. This tanks out Quagga RS pretty badly due
3181 * the iteration over all RS clients.
3182 * Since we need to remove the entry from adj_in anyway, do that first
3184 * if there was no entry, we don't need to do anything more.
3186 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3187 && peer
!= bgp
->peer_self
)
3188 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3189 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3190 bgp_debug_rdpfxpath2str(
3191 afi
, safi
, prd
, p
, label
,
3192 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3195 "%s withdrawing route %s not in adj-in",
3196 peer
->host
, pfx_buf
);
3198 bgp_unlock_node(rn
);
3202 /* Lookup withdrawn route. */
3203 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3204 if (ri
->peer
== peer
&& ri
->type
== type
3205 && ri
->sub_type
== sub_type
3206 && ri
->addpath_rx_id
== addpath_id
)
3210 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3211 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3212 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3214 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3218 /* Withdraw specified route from routing table. */
3219 if (ri
&& !CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
3220 bgp_rib_withdraw(rn
, ri
, peer
, afi
, safi
, prd
);
3221 else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3222 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3223 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3225 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3228 /* Unlock bgp_node_get() lock. */
3229 bgp_unlock_node(rn
);
3234 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3237 struct update_subgroup
*subgrp
;
3238 subgrp
= peer_subgroup(peer
, afi
, safi
);
3239 subgroup_default_originate(subgrp
, withdraw
);
3244 * bgp_stop_announce_route_timer
3246 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3248 if (!paf
->t_announce_route
)
3251 THREAD_TIMER_OFF(paf
->t_announce_route
);
3255 * bgp_announce_route_timer_expired
3257 * Callback that is invoked when the route announcement timer for a
3260 static int bgp_announce_route_timer_expired(struct thread
*t
)
3262 struct peer_af
*paf
;
3265 paf
= THREAD_ARG(t
);
3268 if (peer
->status
!= Established
)
3271 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3274 peer_af_announce_route(paf
, 1);
3279 * bgp_announce_route
3281 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3283 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3285 struct peer_af
*paf
;
3286 struct update_subgroup
*subgrp
;
3288 paf
= peer_af_find(peer
, afi
, safi
);
3291 subgrp
= PAF_SUBGRP(paf
);
3294 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3295 * or a refresh has already been triggered.
3297 if (!subgrp
|| paf
->t_announce_route
)
3301 * Start a timer to stagger/delay the announce. This serves
3302 * two purposes - announcement can potentially be combined for
3303 * multiple peers and the announcement doesn't happen in the
3306 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3307 (subgrp
->peer_count
== 1)
3308 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3309 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3310 &paf
->t_announce_route
);
3314 * Announce routes from all AF tables to a peer.
3316 * This should ONLY be called when there is a need to refresh the
3317 * routes to the peer based on a policy change for this peer alone
3318 * or a route refresh request received from the peer.
3319 * The operation will result in splitting the peer from its existing
3320 * subgroups and putting it in new subgroups.
3322 void bgp_announce_route_all(struct peer
*peer
)
3327 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3328 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3329 bgp_announce_route(peer
, afi
, safi
);
3332 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3333 struct bgp_table
*table
,
3334 struct prefix_rd
*prd
)
3337 struct bgp_node
*rn
;
3338 struct bgp_adj_in
*ain
;
3341 table
= peer
->bgp
->rib
[afi
][safi
];
3343 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3344 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3345 if (ain
->peer
== peer
) {
3346 struct bgp_info
*ri
= rn
->info
;
3347 mpls_label_t label
=
3348 (ri
&& ri
->extra
) ? ri
->extra
->label
3349 : MPLS_INVALID_LABEL
;
3352 peer
, &rn
->p
, ain
->addpath_rx_id
,
3353 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3354 BGP_ROUTE_NORMAL
, prd
, &label
, 1, NULL
);
3357 bgp_unlock_node(rn
);
3364 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3366 struct bgp_node
*rn
;
3367 struct bgp_table
*table
;
3369 if (peer
->status
!= Established
)
3372 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3373 && (safi
!= SAFI_EVPN
))
3374 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3376 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3377 rn
= bgp_route_next(rn
))
3378 if ((table
= rn
->info
) != NULL
) {
3379 struct prefix_rd prd
;
3380 prd
.family
= AF_UNSPEC
;
3382 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3384 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3390 struct bgp_clear_node_queue
{
3391 struct bgp_node
*rn
;
3394 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3396 struct bgp_clear_node_queue
*cnq
= data
;
3397 struct bgp_node
*rn
= cnq
->rn
;
3398 struct peer
*peer
= wq
->spec
.data
;
3399 struct bgp_info
*ri
;
3400 afi_t afi
= bgp_node_table(rn
)->afi
;
3401 safi_t safi
= bgp_node_table(rn
)->safi
;
3405 /* It is possible that we have multiple paths for a prefix from a peer
3406 * if that peer is using AddPath.
3408 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3409 if (ri
->peer
== peer
) {
3410 /* graceful restart STALE flag set. */
3411 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3412 && peer
->nsf
[afi
][safi
]
3413 && !CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)
3414 && !CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
3415 bgp_info_set_flag(rn
, ri
, BGP_INFO_STALE
);
3417 /* If this is an EVPN route, process for
3419 if (safi
== SAFI_EVPN
)
3420 bgp_evpn_unimport_route(peer
->bgp
, afi
,
3423 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3429 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3431 struct bgp_clear_node_queue
*cnq
= data
;
3432 struct bgp_node
*rn
= cnq
->rn
;
3433 struct bgp_table
*table
= bgp_node_table(rn
);
3435 bgp_unlock_node(rn
);
3436 bgp_table_unlock(table
);
3437 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3440 static void bgp_clear_node_complete(struct work_queue
*wq
)
3442 struct peer
*peer
= wq
->spec
.data
;
3444 /* Tickle FSM to start moving again */
3445 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3447 peer_unlock(peer
); /* bgp_clear_route */
3450 static void bgp_clear_node_queue_init(struct peer
*peer
)
3452 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3454 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3455 #undef CLEAR_QUEUE_NAME_LEN
3457 if ((peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
))
3459 zlog_err("%s: Failed to allocate work queue", __func__
);
3462 peer
->clear_node_queue
->spec
.hold
= 10;
3463 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3464 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3465 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3466 peer
->clear_node_queue
->spec
.max_retries
= 0;
3468 /* we only 'lock' this peer reference when the queue is actually active
3470 peer
->clear_node_queue
->spec
.data
= peer
;
3473 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3474 struct bgp_table
*table
)
3476 struct bgp_node
*rn
;
3477 int force
= bm
->process_main_queue
? 0 : 1;
3480 table
= peer
->bgp
->rib
[afi
][safi
];
3482 /* If still no table => afi/safi isn't configured at all or smth. */
3486 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3487 struct bgp_info
*ri
, *next
;
3488 struct bgp_adj_in
*ain
;
3489 struct bgp_adj_in
*ain_next
;
3491 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3492 * queued for every clearing peer, regardless of whether it is
3493 * relevant to the peer at hand.
3495 * Overview: There are 3 different indices which need to be
3496 * scrubbed, potentially, when a peer is removed:
3498 * 1 peer's routes visible via the RIB (ie accepted routes)
3499 * 2 peer's routes visible by the (optional) peer's adj-in index
3500 * 3 other routes visible by the peer's adj-out index
3502 * 3 there is no hurry in scrubbing, once the struct peer is
3503 * removed from bgp->peer, we could just GC such deleted peer's
3504 * adj-outs at our leisure.
3506 * 1 and 2 must be 'scrubbed' in some way, at least made
3507 * invisible via RIB index before peer session is allowed to be
3508 * brought back up. So one needs to know when such a 'search' is
3513 * - there'd be a single global queue or a single RIB walker
3514 * - rather than tracking which route_nodes still need to be
3515 * examined on a peer basis, we'd track which peers still
3518 * Given that our per-peer prefix-counts now should be reliable,
3519 * this may actually be achievable. It doesn't seem to be a huge
3520 * problem at this time,
3522 * It is possible that we have multiple paths for a prefix from
3524 * if that peer is using AddPath.
3528 ain_next
= ain
->next
;
3530 if (ain
->peer
== peer
) {
3531 bgp_adj_in_remove(rn
, ain
);
3532 bgp_unlock_node(rn
);
3538 for (ri
= rn
->info
; ri
; ri
= next
) {
3540 if (ri
->peer
!= peer
)
3544 bgp_info_reap(rn
, ri
);
3546 struct bgp_clear_node_queue
*cnq
;
3548 /* both unlocked in bgp_clear_node_queue_del */
3549 bgp_table_lock(bgp_node_table(rn
));
3552 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3553 sizeof(struct bgp_clear_node_queue
));
3555 work_queue_add(peer
->clear_node_queue
, cnq
);
3563 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3565 struct bgp_node
*rn
;
3566 struct bgp_table
*table
;
3568 if (peer
->clear_node_queue
== NULL
)
3569 bgp_clear_node_queue_init(peer
);
3571 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3572 * Idle until it receives a Clearing_Completed event. This protects
3573 * against peers which flap faster than we can we clear, which could
3576 * a) race with routes from the new session being installed before
3577 * clear_route_node visits the node (to delete the route of that
3579 * b) resource exhaustion, clear_route_node likely leads to an entry
3580 * on the process_main queue. Fast-flapping could cause that queue
3584 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3585 * the unlock will happen upon work-queue completion; other wise, the
3586 * unlock happens at the end of this function.
3588 if (!peer
->clear_node_queue
->thread
)
3591 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3592 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
3594 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3595 rn
= bgp_route_next(rn
))
3596 if ((table
= rn
->info
) != NULL
)
3597 bgp_clear_route_table(peer
, afi
, safi
, table
);
3599 /* unlock if no nodes got added to the clear-node-queue. */
3600 if (!peer
->clear_node_queue
->thread
)
3604 void bgp_clear_route_all(struct peer
*peer
)
3609 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3610 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3611 bgp_clear_route(peer
, afi
, safi
);
3614 rfapiProcessPeerDown(peer
);
3618 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3620 struct bgp_table
*table
;
3621 struct bgp_node
*rn
;
3622 struct bgp_adj_in
*ain
;
3623 struct bgp_adj_in
*ain_next
;
3625 table
= peer
->bgp
->rib
[afi
][safi
];
3627 /* It is possible that we have multiple paths for a prefix from a peer
3628 * if that peer is using AddPath.
3630 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3634 ain_next
= ain
->next
;
3636 if (ain
->peer
== peer
) {
3637 bgp_adj_in_remove(rn
, ain
);
3638 bgp_unlock_node(rn
);
3646 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3648 struct bgp_node
*rn
;
3649 struct bgp_info
*ri
;
3650 struct bgp_table
*table
;
3652 if (safi
== SAFI_MPLS_VPN
) {
3653 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3654 rn
= bgp_route_next(rn
)) {
3655 struct bgp_node
*rm
;
3656 struct bgp_info
*ri
;
3658 /* look for neighbor in tables */
3659 if ((table
= rn
->info
) != NULL
) {
3660 for (rm
= bgp_table_top(table
); rm
;
3661 rm
= bgp_route_next(rm
))
3662 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3663 if (ri
->peer
== peer
) {
3677 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3678 rn
= bgp_route_next(rn
))
3679 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3680 if (ri
->peer
== peer
) {
3681 if (CHECK_FLAG(ri
->flags
,
3683 bgp_rib_remove(rn
, ri
, peer
,
3690 static void bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3692 struct bgp_node
*rn
;
3693 struct bgp_info
*ri
;
3694 struct bgp_info
*next
;
3696 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3697 for (ri
= rn
->info
; ri
; ri
= next
) {
3699 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3700 && ri
->type
== ZEBRA_ROUTE_BGP
3701 && (ri
->sub_type
== BGP_ROUTE_NORMAL
3702 || ri
->sub_type
== BGP_ROUTE_AGGREGATE
)) {
3703 if (bgp_fibupd_safi(safi
))
3704 bgp_zebra_withdraw(&rn
->p
, ri
, safi
);
3705 bgp_info_reap(rn
, ri
);
3710 /* Delete all kernel routes. */
3711 void bgp_cleanup_routes(struct bgp
*bgp
)
3714 struct bgp_node
*rn
;
3716 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
3717 if (afi
== AFI_L2VPN
)
3719 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3721 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3723 if (afi
!= AFI_L2VPN
) {
3725 safi
= SAFI_MPLS_VPN
;
3726 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3727 rn
= bgp_route_next(rn
)) {
3730 (struct bgp_table
*)(rn
->info
),
3732 bgp_table_finish((struct bgp_table
**)&(
3735 bgp_unlock_node(rn
);
3739 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3740 rn
= bgp_route_next(rn
)) {
3743 (struct bgp_table
*)(rn
->info
),
3745 bgp_table_finish((struct bgp_table
**)&(
3748 bgp_unlock_node(rn
);
3753 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3754 rn
= bgp_route_next(rn
)) {
3756 bgp_cleanup_table((struct bgp_table
*)(rn
->info
),
3758 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
3760 bgp_unlock_node(rn
);
3765 void bgp_reset(void)
3768 bgp_zclient_reset();
3769 access_list_reset();
3770 prefix_list_reset();
3773 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
3775 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
3776 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
3777 PEER_CAP_ADDPATH_AF_TX_RCV
));
3780 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3782 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
3783 struct bgp_nlri
*packet
)
3792 int addpath_encoded
;
3793 u_int32_t addpath_id
;
3795 /* Check peer status. */
3796 if (peer
->status
!= Established
)
3800 lim
= pnt
+ packet
->length
;
3802 safi
= packet
->safi
;
3804 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
3806 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3807 syntactic validity. If the field is syntactically incorrect,
3808 then the Error Subcode is set to Invalid Network Field. */
3809 for (; pnt
< lim
; pnt
+= psize
) {
3810 /* Clear prefix structure. */
3811 memset(&p
, 0, sizeof(struct prefix
));
3813 if (addpath_encoded
) {
3815 /* When packet overflow occurs return immediately. */
3816 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3819 addpath_id
= ntohl(*((uint32_t *)pnt
));
3820 pnt
+= BGP_ADDPATH_ID_LEN
;
3823 /* Fetch prefix length. */
3824 p
.prefixlen
= *pnt
++;
3825 /* afi/safi validity already verified by caller,
3826 * bgp_update_receive */
3827 p
.family
= afi2family(afi
);
3829 /* Prefix length check. */
3830 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
3832 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3833 peer
->host
, p
.prefixlen
, packet
->afi
);
3837 /* Packet size overflow check. */
3838 psize
= PSIZE(p
.prefixlen
);
3840 /* When packet overflow occur return immediately. */
3841 if (pnt
+ psize
> lim
) {
3843 "%s [Error] Update packet error (prefix length %d overflows packet)",
3844 peer
->host
, p
.prefixlen
);
3848 /* Defensive coding, double-check the psize fits in a struct
3850 if (psize
> (ssize_t
)sizeof(p
.u
)) {
3852 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3853 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3857 /* Fetch prefix from NLRI packet. */
3858 memcpy(&p
.u
.prefix
, pnt
, psize
);
3860 /* Check address. */
3861 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
3862 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
3863 /* From RFC4271 Section 6.3:
3865 * If a prefix in the NLRI field is semantically
3867 * (e.g., an unexpected multicast IP address),
3869 * be logged locally, and the prefix SHOULD be
3873 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3874 peer
->host
, inet_ntoa(p
.u
.prefix4
));
3879 /* Check address. */
3880 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
3881 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
3885 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3887 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
3892 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
3896 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3898 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
3905 /* Normal process. */
3907 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
3908 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3909 NULL
, NULL
, 0, NULL
);
3911 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
3912 safi
, ZEBRA_ROUTE_BGP
,
3913 BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3915 /* Address family configuration mismatch or maximum-prefix count
3921 /* Packet length consistency check. */
3924 "%s [Error] Update packet error (prefix length mismatch with total length)",
3932 static struct bgp_static
*bgp_static_new(void)
3934 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
3937 static void bgp_static_free(struct bgp_static
*bgp_static
)
3939 if (bgp_static
->rmap
.name
)
3940 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3941 if (bgp_static
->eth_s_id
)
3942 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3943 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
3946 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
3947 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3949 struct bgp_node
*rn
;
3950 struct bgp_info
*ri
;
3951 struct bgp_info
*new;
3952 struct bgp_info info
;
3954 struct attr
*attr_new
;
3957 int vnc_implicit_withdraw
= 0;
3964 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3966 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
3968 attr
.nexthop
= bgp_static
->igpnexthop
;
3969 attr
.med
= bgp_static
->igpmetric
;
3970 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
3972 if (bgp_static
->atomic
)
3973 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
3975 /* Store label index, if required. */
3976 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
3977 attr
.label_index
= bgp_static
->label_index
;
3978 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
3981 /* Apply route-map. */
3982 if (bgp_static
->rmap
.name
) {
3983 struct attr attr_tmp
= attr
;
3984 info
.peer
= bgp
->peer_self
;
3985 info
.attr
= &attr_tmp
;
3987 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3989 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3991 bgp
->peer_self
->rmap_type
= 0;
3993 if (ret
== RMAP_DENYMATCH
) {
3994 /* Free uninterned attribute. */
3995 bgp_attr_flush(&attr_tmp
);
3997 /* Unintern original. */
3998 aspath_unintern(&attr
.aspath
);
3999 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4002 attr_new
= bgp_attr_intern(&attr_tmp
);
4004 attr_new
= bgp_attr_intern(&attr
);
4006 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4007 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4008 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4012 if (attrhash_cmp(ri
->attr
, attr_new
)
4013 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
4014 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4015 bgp_unlock_node(rn
);
4016 bgp_attr_unintern(&attr_new
);
4017 aspath_unintern(&attr
.aspath
);
4020 /* The attribute is changed. */
4021 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4023 /* Rewrite BGP route information. */
4024 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4025 bgp_info_restore(rn
, ri
);
4027 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4029 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4030 && (safi
== SAFI_UNICAST
)) {
4031 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
4033 * Implicit withdraw case.
4034 * We have to do this before ri is
4037 ++vnc_implicit_withdraw
;
4038 vnc_import_bgp_del_route(bgp
, p
, ri
);
4039 vnc_import_bgp_exterior_del_route(
4044 bgp_attr_unintern(&ri
->attr
);
4045 ri
->attr
= attr_new
;
4046 ri
->uptime
= bgp_clock();
4048 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4049 && (safi
== SAFI_UNICAST
)) {
4050 if (vnc_implicit_withdraw
) {
4051 vnc_import_bgp_add_route(bgp
, p
, ri
);
4052 vnc_import_bgp_exterior_add_route(
4058 /* Nexthop reachability check. */
4059 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4060 && (safi
== SAFI_UNICAST
4061 || safi
== SAFI_LABELED_UNICAST
)) {
4062 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
4064 bgp_info_set_flag(rn
, ri
,
4067 if (BGP_DEBUG(nht
, NHT
)) {
4068 char buf1
[INET6_ADDRSTRLEN
];
4069 inet_ntop(p
->family
,
4073 "%s(%s): Route not in table, not advertising",
4074 __FUNCTION__
, buf1
);
4076 bgp_info_unset_flag(rn
, ri
,
4080 /* Delete the NHT structure if any, if we're
4082 * enabling/disabling import check. We
4083 * deregister the route
4084 * from NHT to avoid overloading NHT and the
4085 * process interaction
4087 bgp_unlink_nexthop(ri
);
4088 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
4090 /* Process change. */
4091 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4092 bgp_process(bgp
, rn
, afi
, safi
);
4093 bgp_unlock_node(rn
);
4094 aspath_unintern(&attr
.aspath
);
4099 /* Make new BGP info. */
4100 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4102 /* Nexthop reachability check. */
4103 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4104 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4105 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, 0))
4106 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4108 if (BGP_DEBUG(nht
, NHT
)) {
4109 char buf1
[INET6_ADDRSTRLEN
];
4110 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4113 "%s(%s): Route not in table, not advertising",
4114 __FUNCTION__
, buf1
);
4116 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
4119 /* Delete the NHT structure if any, if we're toggling between
4120 * enabling/disabling import check. We deregister the route
4121 * from NHT to avoid overloading NHT and the process interaction
4123 bgp_unlink_nexthop(new);
4125 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4128 /* Aggregate address increment. */
4129 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4131 /* Register new BGP information. */
4132 bgp_info_add(rn
, new);
4134 /* route_node_get lock */
4135 bgp_unlock_node(rn
);
4137 /* Process change. */
4138 bgp_process(bgp
, rn
, afi
, safi
);
4140 /* Unintern original. */
4141 aspath_unintern(&attr
.aspath
);
4144 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4147 struct bgp_node
*rn
;
4148 struct bgp_info
*ri
;
4150 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4152 /* Check selected route and self inserted route. */
4153 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4154 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4155 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4158 /* Withdraw static BGP route from routing table. */
4160 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4161 bgp_unlink_nexthop(ri
);
4162 bgp_info_delete(rn
, ri
);
4163 bgp_process(bgp
, rn
, afi
, safi
);
4166 /* Unlock bgp_node_lookup. */
4167 bgp_unlock_node(rn
);
4171 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4173 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4174 afi_t afi
, safi_t safi
,
4175 struct prefix_rd
*prd
)
4177 struct bgp_node
*rn
;
4178 struct bgp_info
*ri
;
4180 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4182 /* Check selected route and self inserted route. */
4183 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4184 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4185 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4188 /* Withdraw static BGP route from routing table. */
4191 rfapiProcessWithdraw(
4192 ri
->peer
, NULL
, p
, prd
, ri
->attr
, afi
, safi
, ri
->type
,
4193 1); /* Kill, since it is an administrative change */
4195 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4196 bgp_info_delete(rn
, ri
);
4197 bgp_process(bgp
, rn
, afi
, safi
);
4200 /* Unlock bgp_node_lookup. */
4201 bgp_unlock_node(rn
);
4204 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4205 struct bgp_static
*bgp_static
, afi_t afi
,
4208 struct bgp_node
*rn
;
4209 struct bgp_info
*new;
4210 struct attr
*attr_new
;
4211 struct attr attr
= {0};
4212 struct bgp_info
*ri
;
4214 mpls_label_t label
= 0;
4220 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4223 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4225 attr
.nexthop
= bgp_static
->igpnexthop
;
4226 attr
.med
= bgp_static
->igpmetric
;
4227 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4229 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4230 || (safi
== SAFI_ENCAP
)) {
4231 if (afi
== AFI_IP
) {
4232 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4233 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4236 if (afi
== AFI_L2VPN
) {
4237 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4239 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4240 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4241 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4242 sizeof(struct in6_addr
));
4243 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4244 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4245 struct bgp_encap_type_vxlan bet
;
4246 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4247 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4248 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4250 if (bgp_static
->router_mac
) {
4251 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4254 /* Apply route-map. */
4255 if (bgp_static
->rmap
.name
) {
4256 struct attr attr_tmp
= attr
;
4257 struct bgp_info info
;
4260 info
.peer
= bgp
->peer_self
;
4261 info
.attr
= &attr_tmp
;
4263 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4265 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4267 bgp
->peer_self
->rmap_type
= 0;
4269 if (ret
== RMAP_DENYMATCH
) {
4270 /* Free uninterned attribute. */
4271 bgp_attr_flush(&attr_tmp
);
4273 /* Unintern original. */
4274 aspath_unintern(&attr
.aspath
);
4275 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4280 attr_new
= bgp_attr_intern(&attr_tmp
);
4282 attr_new
= bgp_attr_intern(&attr
);
4285 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4286 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4287 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4292 memset(&add
, 0, sizeof(union gw_addr
));
4293 if (attrhash_cmp(ri
->attr
, attr_new
)
4294 && overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
)
4295 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
4296 bgp_unlock_node(rn
);
4297 bgp_attr_unintern(&attr_new
);
4298 aspath_unintern(&attr
.aspath
);
4301 /* The attribute is changed. */
4302 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4304 /* Rewrite BGP route information. */
4305 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4306 bgp_info_restore(rn
, ri
);
4308 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4309 bgp_attr_unintern(&ri
->attr
);
4310 ri
->attr
= attr_new
;
4311 ri
->uptime
= bgp_clock();
4314 label
= decode_label(&ri
->extra
->label
);
4317 /* Process change. */
4318 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4319 bgp_process(bgp
, rn
, afi
, safi
);
4321 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4322 ri
->attr
, afi
, safi
, ri
->type
,
4323 ri
->sub_type
, &label
);
4325 bgp_unlock_node(rn
);
4326 aspath_unintern(&attr
.aspath
);
4332 /* Make new BGP info. */
4333 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4335 SET_FLAG(new->flags
, BGP_INFO_VALID
);
4336 new->extra
= bgp_info_extra_new();
4337 new->extra
->label
= bgp_static
->label
;
4339 label
= decode_label(&bgp_static
->label
);
4342 /* Aggregate address increment. */
4343 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4345 /* Register new BGP information. */
4346 bgp_info_add(rn
, new);
4347 /* route_node_get lock */
4348 bgp_unlock_node(rn
);
4350 /* Process change. */
4351 bgp_process(bgp
, rn
, afi
, safi
);
4354 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4355 safi
, new->type
, new->sub_type
, &label
);
4358 /* Unintern original. */
4359 aspath_unintern(&attr
.aspath
);
4362 /* Configure static BGP network. When user don't run zebra, static
4363 route should be installed as valid. */
4364 static int bgp_static_set(struct vty
*vty
, const char *ip_str
, afi_t afi
,
4365 safi_t safi
, const char *rmap
, int backdoor
,
4366 u_int32_t label_index
)
4368 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4371 struct bgp_static
*bgp_static
;
4372 struct bgp_node
*rn
;
4373 u_char need_update
= 0;
4375 /* Convert IP prefix string to struct prefix. */
4376 ret
= str2prefix(ip_str
, &p
);
4378 vty_out(vty
, "%% Malformed prefix\n");
4379 return CMD_WARNING_CONFIG_FAILED
;
4381 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4382 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4383 return CMD_WARNING_CONFIG_FAILED
;
4388 /* Set BGP static route configuration. */
4389 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4392 /* Configuration change. */
4393 bgp_static
= rn
->info
;
4395 /* Label index cannot be changed. */
4396 if (bgp_static
->label_index
!= label_index
) {
4397 vty_out(vty
, "%% Label index cannot be changed\n");
4398 return CMD_WARNING_CONFIG_FAILED
;
4401 /* Check previous routes are installed into BGP. */
4402 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4405 bgp_static
->backdoor
= backdoor
;
4408 if (bgp_static
->rmap
.name
)
4409 XFREE(MTYPE_ROUTE_MAP_NAME
,
4410 bgp_static
->rmap
.name
);
4411 bgp_static
->rmap
.name
=
4412 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4413 bgp_static
->rmap
.map
= route_map_lookup_by_name(rmap
);
4415 if (bgp_static
->rmap
.name
)
4416 XFREE(MTYPE_ROUTE_MAP_NAME
,
4417 bgp_static
->rmap
.name
);
4418 bgp_static
->rmap
.name
= NULL
;
4419 bgp_static
->rmap
.map
= NULL
;
4420 bgp_static
->valid
= 0;
4422 bgp_unlock_node(rn
);
4424 /* New configuration. */
4425 bgp_static
= bgp_static_new();
4426 bgp_static
->backdoor
= backdoor
;
4427 bgp_static
->valid
= 0;
4428 bgp_static
->igpmetric
= 0;
4429 bgp_static
->igpnexthop
.s_addr
= 0;
4430 bgp_static
->label_index
= label_index
;
4433 if (bgp_static
->rmap
.name
)
4434 XFREE(MTYPE_ROUTE_MAP_NAME
,
4435 bgp_static
->rmap
.name
);
4436 bgp_static
->rmap
.name
=
4437 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4438 bgp_static
->rmap
.map
= route_map_lookup_by_name(rmap
);
4440 rn
->info
= bgp_static
;
4443 bgp_static
->valid
= 1;
4445 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4447 if (!bgp_static
->backdoor
)
4448 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4453 /* Configure static BGP network. */
4454 static int bgp_static_unset(struct vty
*vty
, const char *ip_str
, afi_t afi
,
4457 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4460 struct bgp_static
*bgp_static
;
4461 struct bgp_node
*rn
;
4463 /* Convert IP prefix string to struct prefix. */
4464 ret
= str2prefix(ip_str
, &p
);
4466 vty_out(vty
, "%% Malformed prefix\n");
4467 return CMD_WARNING_CONFIG_FAILED
;
4469 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4470 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4471 return CMD_WARNING_CONFIG_FAILED
;
4476 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4479 "%% Can't find specified static route configuration.\n");
4480 return CMD_WARNING_CONFIG_FAILED
;
4483 bgp_static
= rn
->info
;
4485 /* Update BGP RIB. */
4486 if (!bgp_static
->backdoor
)
4487 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4489 /* Clear configuration. */
4490 bgp_static_free(bgp_static
);
4492 bgp_unlock_node(rn
);
4493 bgp_unlock_node(rn
);
4498 void bgp_static_add(struct bgp
*bgp
)
4502 struct bgp_node
*rn
;
4503 struct bgp_node
*rm
;
4504 struct bgp_table
*table
;
4505 struct bgp_static
*bgp_static
;
4507 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4508 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4509 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4510 rn
= bgp_route_next(rn
))
4511 if (rn
->info
!= NULL
) {
4512 if ((safi
== SAFI_MPLS_VPN
)
4513 || (safi
== SAFI_ENCAP
)
4514 || (safi
== SAFI_EVPN
)) {
4517 for (rm
= bgp_table_top(table
);
4519 rm
= bgp_route_next(rm
)) {
4520 bgp_static
= rm
->info
;
4521 bgp_static_update_safi(
4527 bgp_static_update(bgp
, &rn
->p
,
4534 /* Called from bgp_delete(). Delete all static routes from the BGP
4536 void bgp_static_delete(struct bgp
*bgp
)
4540 struct bgp_node
*rn
;
4541 struct bgp_node
*rm
;
4542 struct bgp_table
*table
;
4543 struct bgp_static
*bgp_static
;
4545 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4546 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4547 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4548 rn
= bgp_route_next(rn
))
4549 if (rn
->info
!= NULL
) {
4550 if ((safi
== SAFI_MPLS_VPN
)
4551 || (safi
== SAFI_ENCAP
)
4552 || (safi
== SAFI_EVPN
)) {
4555 for (rm
= bgp_table_top(table
);
4557 rm
= bgp_route_next(rm
)) {
4558 bgp_static
= rm
->info
;
4559 bgp_static_withdraw_safi(
4568 bgp_unlock_node(rn
);
4571 bgp_static
= rn
->info
;
4572 bgp_static_withdraw(bgp
, &rn
->p
,
4574 bgp_static_free(bgp_static
);
4576 bgp_unlock_node(rn
);
4581 void bgp_static_redo_import_check(struct bgp
*bgp
)
4585 struct bgp_node
*rn
;
4586 struct bgp_node
*rm
;
4587 struct bgp_table
*table
;
4588 struct bgp_static
*bgp_static
;
4590 /* Use this flag to force reprocessing of the route */
4591 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4592 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4593 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4594 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4595 rn
= bgp_route_next(rn
))
4596 if (rn
->info
!= NULL
) {
4597 if ((safi
== SAFI_MPLS_VPN
)
4598 || (safi
== SAFI_ENCAP
)
4599 || (safi
== SAFI_EVPN
)) {
4602 for (rm
= bgp_table_top(table
);
4604 rm
= bgp_route_next(rm
)) {
4605 bgp_static
= rm
->info
;
4606 bgp_static_update_safi(
4612 bgp_static
= rn
->info
;
4613 bgp_static_update(bgp
, &rn
->p
,
4618 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4621 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
4624 struct bgp_table
*table
;
4625 struct bgp_node
*rn
;
4626 struct bgp_info
*ri
;
4628 table
= bgp
->rib
[afi
][safi
];
4629 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4630 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4631 if (ri
->peer
== bgp
->peer_self
4632 && ((ri
->type
== ZEBRA_ROUTE_BGP
4633 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4634 || (ri
->type
!= ZEBRA_ROUTE_BGP
4636 == BGP_ROUTE_REDISTRIBUTE
))) {
4637 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
4639 bgp_unlink_nexthop(ri
);
4640 bgp_info_delete(rn
, ri
);
4641 bgp_process(bgp
, rn
, afi
, safi
);
4648 * Purge all networks and redistributed routes from routing table.
4649 * Invoked upon the instance going down.
4651 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
4656 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4657 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4658 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
4663 * Currently this is used to set static routes for VPN and ENCAP.
4664 * I think it can probably be factored with bgp_static_set.
4666 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4667 const char *ip_str
, const char *rd_str
,
4668 const char *label_str
, const char *rmap_str
,
4669 int evpn_type
, const char *esi
, const char *gwip
,
4670 const char *ethtag
, const char *routermac
)
4672 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4675 struct prefix_rd prd
;
4676 struct bgp_node
*prn
;
4677 struct bgp_node
*rn
;
4678 struct bgp_table
*table
;
4679 struct bgp_static
*bgp_static
;
4680 mpls_label_t label
= MPLS_INVALID_LABEL
;
4681 struct prefix gw_ip
;
4683 /* validate ip prefix */
4684 ret
= str2prefix(ip_str
, &p
);
4686 vty_out(vty
, "%% Malformed prefix\n");
4687 return CMD_WARNING_CONFIG_FAILED
;
4690 if ((afi
== AFI_L2VPN
)
4691 && (bgp_build_evpn_prefix(evpn_type
,
4692 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4693 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4694 return CMD_WARNING_CONFIG_FAILED
;
4697 ret
= str2prefix_rd(rd_str
, &prd
);
4699 vty_out(vty
, "%% Malformed rd\n");
4700 return CMD_WARNING_CONFIG_FAILED
;
4704 unsigned long label_val
;
4705 label_val
= strtoul(label_str
, NULL
, 10);
4706 encode_label(label_val
, &label
);
4709 if (safi
== SAFI_EVPN
) {
4710 if (esi
&& str2esi(esi
, NULL
) == 0) {
4711 vty_out(vty
, "%% Malformed ESI\n");
4712 return CMD_WARNING_CONFIG_FAILED
;
4714 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
4715 vty_out(vty
, "%% Malformed Router MAC\n");
4716 return CMD_WARNING_CONFIG_FAILED
;
4719 memset(&gw_ip
, 0, sizeof(struct prefix
));
4720 ret
= str2prefix(gwip
, &gw_ip
);
4722 vty_out(vty
, "%% Malformed GatewayIp\n");
4723 return CMD_WARNING_CONFIG_FAILED
;
4725 if ((gw_ip
.family
== AF_INET
4726 && IS_EVPN_PREFIX_IPADDR_V6(
4727 (struct prefix_evpn
*)&p
))
4728 || (gw_ip
.family
== AF_INET6
4729 && IS_EVPN_PREFIX_IPADDR_V4(
4730 (struct prefix_evpn
*)&p
))) {
4732 "%% GatewayIp family differs with IP prefix\n");
4733 return CMD_WARNING_CONFIG_FAILED
;
4737 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
4738 if (prn
->info
== NULL
)
4739 prn
->info
= bgp_table_init(afi
, safi
);
4741 bgp_unlock_node(prn
);
4744 rn
= bgp_node_get(table
, &p
);
4747 vty_out(vty
, "%% Same network configuration exists\n");
4748 bgp_unlock_node(rn
);
4750 /* New configuration. */
4751 bgp_static
= bgp_static_new();
4752 bgp_static
->backdoor
= 0;
4753 bgp_static
->valid
= 0;
4754 bgp_static
->igpmetric
= 0;
4755 bgp_static
->igpnexthop
.s_addr
= 0;
4756 bgp_static
->label
= label
;
4757 bgp_static
->prd
= prd
;
4760 if (bgp_static
->rmap
.name
)
4761 XFREE(MTYPE_ROUTE_MAP_NAME
,
4762 bgp_static
->rmap
.name
);
4763 bgp_static
->rmap
.name
=
4764 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4765 bgp_static
->rmap
.map
=
4766 route_map_lookup_by_name(rmap_str
);
4769 if (safi
== SAFI_EVPN
) {
4771 bgp_static
->eth_s_id
=
4773 sizeof(struct eth_segment_id
));
4774 str2esi(esi
, bgp_static
->eth_s_id
);
4777 bgp_static
->router_mac
=
4778 XCALLOC(MTYPE_ATTR
, ETHER_ADDR_LEN
+ 1);
4779 prefix_str2mac(routermac
,
4780 bgp_static
->router_mac
);
4783 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
4785 rn
->info
= bgp_static
;
4787 bgp_static
->valid
= 1;
4788 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
4794 /* Configure static BGP network. */
4795 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4796 const char *ip_str
, const char *rd_str
,
4797 const char *label_str
, int evpn_type
, const char *esi
,
4798 const char *gwip
, const char *ethtag
)
4800 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4803 struct prefix_rd prd
;
4804 struct bgp_node
*prn
;
4805 struct bgp_node
*rn
;
4806 struct bgp_table
*table
;
4807 struct bgp_static
*bgp_static
;
4808 mpls_label_t label
= MPLS_INVALID_LABEL
;
4810 /* Convert IP prefix string to struct prefix. */
4811 ret
= str2prefix(ip_str
, &p
);
4813 vty_out(vty
, "%% Malformed prefix\n");
4814 return CMD_WARNING_CONFIG_FAILED
;
4817 if ((afi
== AFI_L2VPN
)
4818 && (bgp_build_evpn_prefix(evpn_type
,
4819 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4820 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4821 return CMD_WARNING_CONFIG_FAILED
;
4823 ret
= str2prefix_rd(rd_str
, &prd
);
4825 vty_out(vty
, "%% Malformed rd\n");
4826 return CMD_WARNING_CONFIG_FAILED
;
4830 unsigned long label_val
;
4831 label_val
= strtoul(label_str
, NULL
, 10);
4832 encode_label(label_val
, &label
);
4835 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
4836 if (prn
->info
== NULL
)
4837 prn
->info
= bgp_table_init(afi
, safi
);
4839 bgp_unlock_node(prn
);
4842 rn
= bgp_node_lookup(table
, &p
);
4845 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
4847 bgp_static
= rn
->info
;
4848 bgp_static_free(bgp_static
);
4850 bgp_unlock_node(rn
);
4851 bgp_unlock_node(rn
);
4853 vty_out(vty
, "%% Can't find the route\n");
4858 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
4859 const char *rmap_name
)
4861 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4862 struct bgp_rmap
*rmap
;
4864 rmap
= &bgp
->table_map
[afi
][safi
];
4867 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4868 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4869 rmap
->map
= route_map_lookup_by_name(rmap_name
);
4872 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4877 if (bgp_fibupd_safi(safi
))
4878 bgp_zebra_announce_table(bgp
, afi
, safi
);
4883 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
4884 const char *rmap_name
)
4886 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4887 struct bgp_rmap
*rmap
;
4889 rmap
= &bgp
->table_map
[afi
][safi
];
4891 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4895 if (bgp_fibupd_safi(safi
))
4896 bgp_zebra_announce_table(bgp
, afi
, safi
);
4901 int bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4902 safi_t safi
, int *write
)
4904 if (bgp
->table_map
[afi
][safi
].name
) {
4905 bgp_config_write_family_header(vty
, afi
, safi
, write
);
4906 vty_out(vty
, " table-map %s\n",
4907 bgp
->table_map
[afi
][safi
].name
);
4913 DEFUN (bgp_table_map
,
4916 "BGP table to RIB route download filter\n"
4917 "Name of the route map\n")
4920 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
4921 argv
[idx_word
]->arg
);
4923 DEFUN (no_bgp_table_map
,
4924 no_bgp_table_map_cmd
,
4925 "no table-map WORD",
4927 "BGP table to RIB route download filter\n"
4928 "Name of the route map\n")
4931 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
4932 argv
[idx_word
]->arg
);
4937 "network A.B.C.D/M",
4938 "Specify a network to announce via BGP\n"
4941 int idx_ipv4_prefixlen
= 1;
4942 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4943 bgp_node_safi(vty
), NULL
, 0,
4944 BGP_INVALID_LABEL_INDEX
);
4947 DEFUN (bgp_network_route_map
,
4948 bgp_network_route_map_cmd
,
4949 "network A.B.C.D/M route-map WORD",
4950 "Specify a network to announce via BGP\n"
4952 "Route-map to modify the attributes\n"
4953 "Name of the route map\n")
4955 int idx_ipv4_prefixlen
= 1;
4957 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4958 bgp_node_safi(vty
), argv
[idx_word
]->arg
, 0,
4959 BGP_INVALID_LABEL_INDEX
);
4962 DEFUN (bgp_network_backdoor
,
4963 bgp_network_backdoor_cmd
,
4964 "network A.B.C.D/M backdoor",
4965 "Specify a network to announce via BGP\n"
4967 "Specify a BGP backdoor route\n")
4969 int idx_ipv4_prefixlen
= 1;
4970 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4971 SAFI_UNICAST
, NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4974 DEFUN (bgp_network_mask
,
4975 bgp_network_mask_cmd
,
4976 "network A.B.C.D mask A.B.C.D",
4977 "Specify a network to announce via BGP\n"
4985 char prefix_str
[BUFSIZ
];
4987 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
4990 vty_out(vty
, "%% Inconsistent address and mask\n");
4991 return CMD_WARNING_CONFIG_FAILED
;
4994 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
), NULL
,
4995 0, BGP_INVALID_LABEL_INDEX
);
4998 DEFUN (bgp_network_mask_route_map
,
4999 bgp_network_mask_route_map_cmd
,
5000 "network A.B.C.D mask A.B.C.D route-map WORD",
5001 "Specify a network to announce via BGP\n"
5005 "Route-map to modify the attributes\n"
5006 "Name of the route map\n")
5012 char prefix_str
[BUFSIZ
];
5014 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5017 vty_out(vty
, "%% Inconsistent address and mask\n");
5018 return CMD_WARNING_CONFIG_FAILED
;
5021 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5022 argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
5025 DEFUN (bgp_network_mask_backdoor
,
5026 bgp_network_mask_backdoor_cmd
,
5027 "network A.B.C.D mask A.B.C.D backdoor",
5028 "Specify a network to announce via BGP\n"
5032 "Specify a BGP backdoor route\n")
5037 char prefix_str
[BUFSIZ
];
5039 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5042 vty_out(vty
, "%% Inconsistent address and mask\n");
5043 return CMD_WARNING_CONFIG_FAILED
;
5046 return bgp_static_set(vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
, NULL
, 1,
5047 BGP_INVALID_LABEL_INDEX
);
5050 DEFUN (bgp_network_mask_natural
,
5051 bgp_network_mask_natural_cmd
,
5053 "Specify a network to announce via BGP\n"
5058 char prefix_str
[BUFSIZ
];
5060 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5062 vty_out(vty
, "%% Inconsistent address and mask\n");
5063 return CMD_WARNING_CONFIG_FAILED
;
5066 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
), NULL
,
5067 0, BGP_INVALID_LABEL_INDEX
);
5070 DEFUN (bgp_network_mask_natural_route_map
,
5071 bgp_network_mask_natural_route_map_cmd
,
5072 "network A.B.C.D route-map WORD",
5073 "Specify a network to announce via BGP\n"
5075 "Route-map to modify the attributes\n"
5076 "Name of the route map\n")
5081 char prefix_str
[BUFSIZ
];
5083 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5085 vty_out(vty
, "%% Inconsistent address and mask\n");
5086 return CMD_WARNING_CONFIG_FAILED
;
5089 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5090 argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
5093 DEFUN (bgp_network_mask_natural_backdoor
,
5094 bgp_network_mask_natural_backdoor_cmd
,
5095 "network A.B.C.D backdoor",
5096 "Specify a network to announce via BGP\n"
5098 "Specify a BGP backdoor route\n")
5102 char prefix_str
[BUFSIZ
];
5104 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5106 vty_out(vty
, "%% Inconsistent address and mask\n");
5107 return CMD_WARNING_CONFIG_FAILED
;
5110 return bgp_static_set(vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
, NULL
, 1,
5111 BGP_INVALID_LABEL_INDEX
);
5114 DEFUN (bgp_network_label_index
,
5115 bgp_network_label_index_cmd
,
5116 "network A.B.C.D/M label-index (0-1048560)",
5117 "Specify a network to announce via BGP\n"
5118 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5119 "Label index to associate with the prefix\n"
5120 "Label index value\n")
5122 u_int32_t label_index
;
5124 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5125 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP
, bgp_node_safi(vty
),
5126 NULL
, 0, label_index
);
5129 DEFUN (bgp_network_label_index_route_map
,
5130 bgp_network_label_index_route_map_cmd
,
5131 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5132 "Specify a network to announce via BGP\n"
5134 "Label index to associate with the prefix\n"
5135 "Label index value\n"
5136 "Route-map to modify the attributes\n"
5137 "Name of the route map\n")
5139 u_int32_t label_index
;
5141 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5142 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP
, bgp_node_safi(vty
),
5143 argv
[5]->arg
, 0, label_index
);
5146 DEFUN (no_bgp_network
,
5148 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5150 "Specify a network to announce via BGP\n"
5152 "Specify a BGP backdoor route\n"
5153 "Route-map to modify the attributes\n"
5154 "Name of the route map\n")
5156 int idx_ipv4_prefixlen
= 2;
5157 return bgp_static_unset(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5158 bgp_node_safi(vty
));
5161 DEFUN (no_bgp_network_mask
,
5162 no_bgp_network_mask_cmd
,
5163 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5165 "Specify a network to announce via BGP\n"
5169 "Specify a BGP backdoor route\n"
5170 "Route-map to modify the attributes\n"
5171 "Name of the route map\n")
5176 char prefix_str
[BUFSIZ
];
5178 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5181 vty_out(vty
, "%% Inconsistent address and mask\n");
5182 return CMD_WARNING_CONFIG_FAILED
;
5185 return bgp_static_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5188 DEFUN (no_bgp_network_mask_natural
,
5189 no_bgp_network_mask_natural_cmd
,
5190 "no network A.B.C.D [<backdoor|route-map WORD>]",
5192 "Specify a network to announce via BGP\n"
5194 "Specify a BGP backdoor route\n"
5195 "Route-map to modify the attributes\n"
5196 "Name of the route map\n")
5200 char prefix_str
[BUFSIZ
];
5202 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5204 vty_out(vty
, "%% Inconsistent address and mask\n");
5205 return CMD_WARNING_CONFIG_FAILED
;
5208 return bgp_static_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5211 ALIAS(no_bgp_network
, no_bgp_network_label_index_cmd
,
5212 "no network A.B.C.D/M label-index (0-1048560)", NO_STR
5213 "Specify a network to announce via BGP\n"
5214 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5215 "Label index to associate with the prefix\n"
5216 "Label index value\n")
5218 ALIAS(no_bgp_network
, no_bgp_network_label_index_route_map_cmd
,
5219 "no network A.B.C.D/M label-index (0-1048560) route-map WORD", NO_STR
5220 "Specify a network to announce via BGP\n"
5222 "Label index to associate with the prefix\n"
5223 "Label index value\n"
5224 "Route-map to modify the attributes\n"
5225 "Name of the route map\n")
5227 DEFUN (ipv6_bgp_network
,
5228 ipv6_bgp_network_cmd
,
5229 "network X:X::X:X/M",
5230 "Specify a network to announce via BGP\n"
5233 int idx_ipv6_prefixlen
= 1;
5234 return bgp_static_set(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5235 bgp_node_safi(vty
), NULL
, 0,
5236 BGP_INVALID_LABEL_INDEX
);
5239 DEFUN (ipv6_bgp_network_route_map
,
5240 ipv6_bgp_network_route_map_cmd
,
5241 "network X:X::X:X/M route-map WORD",
5242 "Specify a network to announce via BGP\n"
5244 "Route-map to modify the attributes\n"
5245 "Name of the route map\n")
5247 int idx_ipv6_prefixlen
= 1;
5249 return bgp_static_set(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5250 bgp_node_safi(vty
), argv
[idx_word
]->arg
, 0,
5251 BGP_INVALID_LABEL_INDEX
);
5254 DEFUN (ipv6_bgp_network_label_index
,
5255 ipv6_bgp_network_label_index_cmd
,
5256 "network X:X::X:X/M label-index (0-1048560)",
5257 "Specify a network to announce via BGP\n"
5258 "IPv6 prefix <network>/<length>\n"
5259 "Label index to associate with the prefix\n"
5260 "Label index value\n")
5262 u_int32_t label_index
;
5264 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5265 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5266 NULL
, 0, label_index
);
5269 DEFUN (ipv6_bgp_network_label_index_route_map
,
5270 ipv6_bgp_network_label_index_route_map_cmd
,
5271 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5272 "Specify a network to announce via BGP\n"
5274 "Label index to associate with the prefix\n"
5275 "Label index value\n"
5276 "Route-map to modify the attributes\n"
5277 "Name of the route map\n")
5279 u_int32_t label_index
;
5281 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5282 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5283 argv
[5]->arg
, 0, label_index
);
5286 DEFUN (no_ipv6_bgp_network
,
5287 no_ipv6_bgp_network_cmd
,
5288 "no network X:X::X:X/M [route-map WORD]",
5290 "Specify a network to announce via BGP\n"
5292 "Route-map to modify the attributes\n"
5293 "Name of the route map\n")
5295 int idx_ipv6_prefixlen
= 2;
5296 return bgp_static_unset(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5297 bgp_node_safi(vty
));
5300 ALIAS(no_ipv6_bgp_network
, no_ipv6_bgp_network_label_index_cmd
,
5301 "no network X:X::X:X/M label-index (0-1048560)", NO_STR
5302 "Specify a network to announce via BGP\n"
5303 "IPv6 prefix <network>/<length>\n"
5304 "Label index to associate with the prefix\n"
5305 "Label index value\n")
5307 ALIAS(no_ipv6_bgp_network
, no_ipv6_bgp_network_label_index_route_map_cmd
,
5308 "no network X:X::X:X/M label-index (0-1048560) route-map WORD", NO_STR
5309 "Specify a network to announce via BGP\n"
5311 "Label index to associate with the prefix\n"
5312 "Label index value\n"
5313 "Route-map to modify the attributes\n"
5314 "Name of the route map\n")
5316 /* Aggreagete address:
5318 advertise-map Set condition to advertise attribute
5319 as-set Generate AS set path information
5320 attribute-map Set attributes of aggregate
5321 route-map Set parameters of aggregate
5322 summary-only Filter more specific routes from updates
5323 suppress-map Conditionally filter more specific routes from updates
5326 struct bgp_aggregate
{
5327 /* Summary-only flag. */
5328 u_char summary_only
;
5330 /* AS set generation. */
5333 /* Route-map for aggregated route. */
5334 struct route_map
*map
;
5336 /* Suppress-count. */
5337 unsigned long count
;
5339 /* SAFI configuration. */
5343 static struct bgp_aggregate
*bgp_aggregate_new(void)
5345 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5348 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5350 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5353 /* Update an aggregate as routes are added/removed from the BGP table */
5354 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5355 struct bgp_info
*rinew
, afi_t afi
, safi_t safi
,
5356 struct bgp_info
*del
,
5357 struct bgp_aggregate
*aggregate
)
5359 struct bgp_table
*table
;
5360 struct bgp_node
*top
;
5361 struct bgp_node
*rn
;
5363 struct aspath
*aspath
= NULL
;
5364 struct aspath
*asmerge
= NULL
;
5365 struct community
*community
= NULL
;
5366 struct community
*commerge
= NULL
;
5367 #if defined(AGGREGATE_NEXTHOP_CHECK)
5368 struct in_addr nexthop
;
5371 struct bgp_info
*ri
;
5372 struct bgp_info
*new;
5374 unsigned long match
= 0;
5375 u_char atomic_aggregate
= 0;
5377 /* Record adding route's nexthop and med. */
5379 #if defined(AGGREGATE_NEXTHOP_CHECK)
5380 nexthop
= rinew
->attr
->nexthop
;
5381 med
= rinew
->attr
->med
;
5385 /* ORIGIN attribute: If at least one route among routes that are
5386 aggregated has ORIGIN with the value INCOMPLETE, then the
5387 aggregated route must have the ORIGIN attribute with the value
5388 INCOMPLETE. Otherwise, if at least one route among routes that
5389 are aggregated has ORIGIN with the value EGP, then the aggregated
5390 route must have the origin attribute with the value EGP. In all
5391 other case the value of the ORIGIN attribute of the aggregated
5392 route is INTERNAL. */
5393 origin
= BGP_ORIGIN_IGP
;
5395 table
= bgp
->rib
[afi
][safi
];
5397 top
= bgp_node_get(table
, p
);
5398 for (rn
= bgp_node_get(table
, p
); rn
;
5399 rn
= bgp_route_next_until(rn
, top
))
5400 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5403 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5404 if (BGP_INFO_HOLDDOWN(ri
))
5407 if (del
&& ri
== del
)
5410 if (!rinew
&& first
) {
5411 #if defined(AGGREGATE_NEXTHOP_CHECK)
5412 nexthop
= ri
->attr
->nexthop
;
5413 med
= ri
->attr
->med
;
5418 #ifdef AGGREGATE_NEXTHOP_CHECK
5419 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
,
5421 || ri
->attr
->med
!= med
) {
5423 aspath_free(aspath
);
5425 community_free(community
);
5426 bgp_unlock_node(rn
);
5427 bgp_unlock_node(top
);
5430 #endif /* AGGREGATE_NEXTHOP_CHECK */
5433 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5434 atomic_aggregate
= 1;
5436 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5437 if (aggregate
->summary_only
) {
5438 (bgp_info_extra_get(ri
))
5442 BGP_INFO_ATTR_CHANGED
);
5448 if (origin
< ri
->attr
->origin
)
5449 origin
= ri
->attr
->origin
;
5451 if (aggregate
->as_set
) {
5453 asmerge
= aspath_aggregate(
5456 aspath_free(aspath
);
5459 aspath
= aspath_dup(
5462 if (ri
->attr
->community
) {
5464 commerge
= community_merge(
5466 ri
->attr
->community
);
5467 community
= community_uniq_sort(
5472 community
= community_dup(
5473 ri
->attr
->community
);
5479 bgp_process(bgp
, rn
, afi
, safi
);
5481 bgp_unlock_node(top
);
5486 if (aggregate
->summary_only
)
5487 (bgp_info_extra_get(rinew
))->suppress
++;
5489 if (origin
< rinew
->attr
->origin
)
5490 origin
= rinew
->attr
->origin
;
5492 if (aggregate
->as_set
) {
5494 asmerge
= aspath_aggregate(aspath
,
5495 rinew
->attr
->aspath
);
5496 aspath_free(aspath
);
5499 aspath
= aspath_dup(rinew
->attr
->aspath
);
5501 if (rinew
->attr
->community
) {
5503 commerge
= community_merge(
5505 rinew
->attr
->community
);
5507 community_uniq_sort(commerge
);
5508 community_free(commerge
);
5510 community
= community_dup(
5511 rinew
->attr
->community
);
5516 if (aggregate
->count
> 0) {
5517 rn
= bgp_node_get(table
, p
);
5519 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5520 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5521 community
, aggregate
->as_set
,
5524 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5526 bgp_info_add(rn
, new);
5527 bgp_unlock_node(rn
);
5528 bgp_process(bgp
, rn
, afi
, safi
);
5531 aspath_free(aspath
);
5533 community_free(community
);
5537 void bgp_aggregate_delete(struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5538 struct bgp_aggregate
*);
5540 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5541 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5543 struct bgp_node
*child
;
5544 struct bgp_node
*rn
;
5545 struct bgp_aggregate
*aggregate
;
5546 struct bgp_table
*table
;
5548 /* MPLS-VPN aggregation is not yet supported. */
5549 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5550 || (safi
== SAFI_EVPN
))
5553 table
= bgp
->aggregate
[afi
][safi
];
5555 /* No aggregates configured. */
5556 if (bgp_table_top_nolock(table
) == NULL
)
5559 if (p
->prefixlen
== 0)
5562 if (BGP_INFO_HOLDDOWN(ri
))
5565 child
= bgp_node_get(table
, p
);
5567 /* Aggregate address configuration check. */
5568 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5569 if ((aggregate
= rn
->info
) != NULL
5570 && rn
->p
.prefixlen
< p
->prefixlen
) {
5571 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5572 bgp_aggregate_route(bgp
, &rn
->p
, ri
, afi
, safi
, NULL
,
5575 bgp_unlock_node(child
);
5578 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5579 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5581 struct bgp_node
*child
;
5582 struct bgp_node
*rn
;
5583 struct bgp_aggregate
*aggregate
;
5584 struct bgp_table
*table
;
5586 /* MPLS-VPN aggregation is not yet supported. */
5587 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5588 || (safi
== SAFI_EVPN
))
5591 table
= bgp
->aggregate
[afi
][safi
];
5593 /* No aggregates configured. */
5594 if (bgp_table_top_nolock(table
) == NULL
)
5597 if (p
->prefixlen
== 0)
5600 child
= bgp_node_get(table
, p
);
5602 /* Aggregate address configuration check. */
5603 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5604 if ((aggregate
= rn
->info
) != NULL
5605 && rn
->p
.prefixlen
< p
->prefixlen
) {
5606 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5607 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5610 bgp_unlock_node(child
);
5613 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5614 static void bgp_aggregate_add(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5615 safi_t safi
, struct bgp_aggregate
*aggregate
)
5617 struct bgp_table
*table
;
5618 struct bgp_node
*top
;
5619 struct bgp_node
*rn
;
5620 struct bgp_info
*new;
5621 struct bgp_info
*ri
;
5622 unsigned long match
;
5623 u_char origin
= BGP_ORIGIN_IGP
;
5624 struct aspath
*aspath
= NULL
;
5625 struct aspath
*asmerge
= NULL
;
5626 struct community
*community
= NULL
;
5627 struct community
*commerge
= NULL
;
5628 u_char atomic_aggregate
= 0;
5630 table
= bgp
->rib
[afi
][safi
];
5633 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5635 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5638 /* If routes exists below this node, generate aggregate routes. */
5639 top
= bgp_node_get(table
, p
);
5640 for (rn
= bgp_node_get(table
, p
); rn
;
5641 rn
= bgp_route_next_until(rn
, top
))
5642 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5645 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5646 if (BGP_INFO_HOLDDOWN(ri
))
5650 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5651 atomic_aggregate
= 1;
5653 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5654 /* summary-only aggregate route suppress
5656 route announcement. */
5657 if (aggregate
->summary_only
) {
5658 (bgp_info_extra_get(ri
))
5662 BGP_INFO_ATTR_CHANGED
);
5666 /* If at least one route among routes
5667 * that are aggregated has
5668 * ORIGIN with the value INCOMPLETE,
5669 * then the aggregated route
5670 * MUST have the ORIGIN attribute with
5671 * the value INCOMPLETE.
5672 * Otherwise, if at least one route
5673 * among routes that are
5674 * aggregated has ORIGIN with the value
5675 * EGP, then the aggregated
5676 * route MUST have the ORIGIN attribute
5677 * with the value EGP.
5679 if (origin
< ri
->attr
->origin
)
5680 origin
= ri
->attr
->origin
;
5682 /* as-set aggregate route generate
5684 community aggregation. */
5685 if (aggregate
->as_set
) {
5687 asmerge
= aspath_aggregate(
5690 aspath_free(aspath
);
5693 aspath
= aspath_dup(
5696 if (ri
->attr
->community
) {
5698 commerge
= community_merge(
5700 ri
->attr
->community
);
5701 community
= community_uniq_sort(
5706 community
= community_dup(
5707 ri
->attr
->community
);
5714 /* If this node is suppressed, process the change. */
5716 bgp_process(bgp
, rn
, afi
, safi
);
5718 bgp_unlock_node(top
);
5720 /* Add aggregate route to BGP table. */
5721 if (aggregate
->count
) {
5722 rn
= bgp_node_get(table
, p
);
5724 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5725 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5726 community
, aggregate
->as_set
,
5729 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5731 bgp_info_add(rn
, new);
5732 bgp_unlock_node(rn
);
5734 /* Process change. */
5735 bgp_process(bgp
, rn
, afi
, safi
);
5738 aspath_free(aspath
);
5740 community_free(community
);
5744 void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5745 safi_t safi
, struct bgp_aggregate
*aggregate
)
5747 struct bgp_table
*table
;
5748 struct bgp_node
*top
;
5749 struct bgp_node
*rn
;
5750 struct bgp_info
*ri
;
5751 unsigned long match
;
5753 table
= bgp
->rib
[afi
][safi
];
5755 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5757 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5760 /* If routes exists below this node, generate aggregate routes. */
5761 top
= bgp_node_get(table
, p
);
5762 for (rn
= bgp_node_get(table
, p
); rn
;
5763 rn
= bgp_route_next_until(rn
, top
))
5764 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5767 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5768 if (BGP_INFO_HOLDDOWN(ri
))
5771 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5772 if (aggregate
->summary_only
5774 ri
->extra
->suppress
--;
5776 if (ri
->extra
->suppress
== 0) {
5779 BGP_INFO_ATTR_CHANGED
);
5787 /* If this node was suppressed, process the change. */
5789 bgp_process(bgp
, rn
, afi
, safi
);
5791 bgp_unlock_node(top
);
5793 /* Delete aggregate route from BGP table. */
5794 rn
= bgp_node_get(table
, p
);
5796 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5797 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
5798 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5801 /* Withdraw static BGP route from routing table. */
5803 bgp_info_delete(rn
, ri
);
5804 bgp_process(bgp
, rn
, afi
, safi
);
5807 /* Unlock bgp_node_lookup. */
5808 bgp_unlock_node(rn
);
5811 /* Aggregate route attribute. */
5812 #define AGGREGATE_SUMMARY_ONLY 1
5813 #define AGGREGATE_AS_SET 1
5815 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5816 afi_t afi
, safi_t safi
)
5818 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5821 struct bgp_node
*rn
;
5822 struct bgp_aggregate
*aggregate
;
5824 /* Convert string to prefix structure. */
5825 ret
= str2prefix(prefix_str
, &p
);
5827 vty_out(vty
, "Malformed prefix\n");
5828 return CMD_WARNING_CONFIG_FAILED
;
5832 /* Old configuration check. */
5833 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5836 "%% There is no aggregate-address configuration.\n");
5837 return CMD_WARNING_CONFIG_FAILED
;
5840 aggregate
= rn
->info
;
5841 if (aggregate
->safi
== SAFI_UNICAST
)
5842 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5843 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5844 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5846 if (aggregate
->safi
== SAFI_MULTICAST
)
5847 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5849 /* Unlock aggregate address configuration. */
5851 bgp_aggregate_free(aggregate
);
5852 bgp_unlock_node(rn
);
5853 bgp_unlock_node(rn
);
5858 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5859 safi_t safi
, u_char summary_only
, u_char as_set
)
5861 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5864 struct bgp_node
*rn
;
5865 struct bgp_aggregate
*aggregate
;
5867 /* Convert string to prefix structure. */
5868 ret
= str2prefix(prefix_str
, &p
);
5870 vty_out(vty
, "Malformed prefix\n");
5871 return CMD_WARNING_CONFIG_FAILED
;
5875 /* Old configuration check. */
5876 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
5879 vty_out(vty
, "There is already same aggregate network.\n");
5880 /* try to remove the old entry */
5881 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
5883 vty_out(vty
, "Error deleting aggregate.\n");
5884 bgp_unlock_node(rn
);
5885 return CMD_WARNING_CONFIG_FAILED
;
5889 /* Make aggregate address structure. */
5890 aggregate
= bgp_aggregate_new();
5891 aggregate
->summary_only
= summary_only
;
5892 aggregate
->as_set
= as_set
;
5893 aggregate
->safi
= safi
;
5894 rn
->info
= aggregate
;
5896 /* Aggregate address insert into BGP routing table. */
5897 if (safi
== SAFI_UNICAST
)
5898 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5899 if (safi
== SAFI_LABELED_UNICAST
)
5900 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5902 if (safi
== SAFI_MULTICAST
)
5903 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5908 DEFUN (aggregate_address
,
5909 aggregate_address_cmd
,
5910 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5911 "Configure BGP aggregate entries\n"
5912 "Aggregate prefix\n"
5913 "Generate AS set path information\n"
5914 "Filter more specific routes from updates\n"
5915 "Filter more specific routes from updates\n"
5916 "Generate AS set path information\n")
5919 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5920 char *prefix
= argv
[idx
]->arg
;
5922 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5924 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5925 ? AGGREGATE_SUMMARY_ONLY
5928 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
5929 summary_only
, as_set
);
5932 DEFUN (aggregate_address_mask
,
5933 aggregate_address_mask_cmd
,
5934 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5935 "Configure BGP aggregate entries\n"
5936 "Aggregate address\n"
5938 "Generate AS set path information\n"
5939 "Filter more specific routes from updates\n"
5940 "Filter more specific routes from updates\n"
5941 "Generate AS set path information\n")
5944 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5945 char *prefix
= argv
[idx
]->arg
;
5946 char *mask
= argv
[idx
+ 1]->arg
;
5948 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5950 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5951 ? AGGREGATE_SUMMARY_ONLY
5954 char prefix_str
[BUFSIZ
];
5955 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5958 vty_out(vty
, "%% Inconsistent address and mask\n");
5959 return CMD_WARNING_CONFIG_FAILED
;
5962 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5963 summary_only
, as_set
);
5966 DEFUN (no_aggregate_address
,
5967 no_aggregate_address_cmd
,
5968 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5970 "Configure BGP aggregate entries\n"
5971 "Aggregate prefix\n"
5972 "Generate AS set path information\n"
5973 "Filter more specific routes from updates\n"
5974 "Filter more specific routes from updates\n"
5975 "Generate AS set path information\n")
5978 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5979 char *prefix
= argv
[idx
]->arg
;
5980 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
5983 DEFUN (no_aggregate_address_mask
,
5984 no_aggregate_address_mask_cmd
,
5985 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5987 "Configure BGP aggregate entries\n"
5988 "Aggregate address\n"
5990 "Generate AS set path information\n"
5991 "Filter more specific routes from updates\n"
5992 "Filter more specific routes from updates\n"
5993 "Generate AS set path information\n")
5996 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5997 char *prefix
= argv
[idx
]->arg
;
5998 char *mask
= argv
[idx
+ 1]->arg
;
6000 char prefix_str
[BUFSIZ
];
6001 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6004 vty_out(vty
, "%% Inconsistent address and mask\n");
6005 return CMD_WARNING_CONFIG_FAILED
;
6008 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6011 DEFUN (ipv6_aggregate_address
,
6012 ipv6_aggregate_address_cmd
,
6013 "aggregate-address X:X::X:X/M [summary-only]",
6014 "Configure BGP aggregate entries\n"
6015 "Aggregate prefix\n"
6016 "Filter more specific routes from updates\n")
6019 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6020 char *prefix
= argv
[idx
]->arg
;
6021 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6022 ? AGGREGATE_SUMMARY_ONLY
6024 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6028 DEFUN (no_ipv6_aggregate_address
,
6029 no_ipv6_aggregate_address_cmd
,
6030 "no aggregate-address X:X::X:X/M [summary-only]",
6032 "Configure BGP aggregate entries\n"
6033 "Aggregate prefix\n"
6034 "Filter more specific routes from updates\n")
6037 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6038 char *prefix
= argv
[idx
]->arg
;
6039 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6042 /* Redistribute route treatment. */
6043 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6044 const struct in_addr
*nexthop
,
6045 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
6046 u_int32_t metric
, u_char type
, u_short instance
,
6049 struct bgp_info
*new;
6050 struct bgp_info
*bi
;
6051 struct bgp_info info
;
6052 struct bgp_node
*bn
;
6054 struct attr
*new_attr
;
6057 struct bgp_redist
*red
;
6059 /* Make default attribute. */
6060 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6062 attr
.nexthop
= *nexthop
;
6063 attr
.nh_ifindex
= ifindex
;
6066 attr
.mp_nexthop_global
= *nexthop6
;
6067 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6071 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6074 afi
= family2afi(p
->family
);
6076 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6078 struct attr attr_new
;
6080 /* Copy attribute for modification. */
6081 bgp_attr_dup(&attr_new
, &attr
);
6083 if (red
->redist_metric_flag
)
6084 attr_new
.med
= red
->redist_metric
;
6086 /* Apply route-map. */
6087 if (red
->rmap
.name
) {
6088 info
.peer
= bgp
->peer_self
;
6089 info
.attr
= &attr_new
;
6091 SET_FLAG(bgp
->peer_self
->rmap_type
,
6092 PEER_RMAP_TYPE_REDISTRIBUTE
);
6094 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6097 bgp
->peer_self
->rmap_type
= 0;
6099 if (ret
== RMAP_DENYMATCH
) {
6100 /* Free uninterned attribute. */
6101 bgp_attr_flush(&attr_new
);
6103 /* Unintern original. */
6104 aspath_unintern(&attr
.aspath
);
6105 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6110 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6111 SAFI_UNICAST
, p
, NULL
);
6113 new_attr
= bgp_attr_intern(&attr_new
);
6115 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6116 if (bi
->peer
== bgp
->peer_self
6117 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6121 /* Ensure the (source route) type is updated. */
6123 if (attrhash_cmp(bi
->attr
, new_attr
)
6124 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
6125 bgp_attr_unintern(&new_attr
);
6126 aspath_unintern(&attr
.aspath
);
6127 bgp_unlock_node(bn
);
6130 /* The attribute is changed. */
6131 bgp_info_set_flag(bn
, bi
,
6132 BGP_INFO_ATTR_CHANGED
);
6134 /* Rewrite BGP route information. */
6135 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6136 bgp_info_restore(bn
, bi
);
6138 bgp_aggregate_decrement(bgp
, p
, bi
, afi
,
6140 bgp_attr_unintern(&bi
->attr
);
6141 bi
->attr
= new_attr
;
6142 bi
->uptime
= bgp_clock();
6144 /* Process change. */
6145 bgp_aggregate_increment(bgp
, p
, bi
, afi
,
6147 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6148 bgp_unlock_node(bn
);
6149 aspath_unintern(&attr
.aspath
);
6154 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6155 bgp
->peer_self
, new_attr
, bn
);
6156 SET_FLAG(new->flags
, BGP_INFO_VALID
);
6158 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6159 bgp_info_add(bn
, new);
6160 bgp_unlock_node(bn
);
6161 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6164 /* Unintern original. */
6165 aspath_unintern(&attr
.aspath
);
6168 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, u_char type
,
6172 struct bgp_node
*rn
;
6173 struct bgp_info
*ri
;
6174 struct bgp_redist
*red
;
6176 afi
= family2afi(p
->family
);
6178 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6180 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6181 SAFI_UNICAST
, p
, NULL
);
6183 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6184 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
)
6188 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6189 bgp_info_delete(rn
, ri
);
6190 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6192 bgp_unlock_node(rn
);
6196 /* Withdraw specified route type's route. */
6197 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6200 struct bgp_node
*rn
;
6201 struct bgp_info
*ri
;
6202 struct bgp_table
*table
;
6204 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6206 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6207 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6208 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
6209 && ri
->instance
== instance
)
6213 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
6215 bgp_info_delete(rn
, ri
);
6216 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6221 /* Static function to display route. */
6222 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
)
6225 u_int32_t destination
;
6228 if (p
->family
== AF_INET
) {
6229 len
= vty_out(vty
, "%s",
6230 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6231 destination
= ntohl(p
->u
.prefix4
.s_addr
);
6233 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
6234 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
6235 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
6236 || p
->u
.prefix4
.s_addr
== 0) {
6237 /* When mask is natural, mask is not displayed. */
6239 len
+= vty_out(vty
, "/%d", p
->prefixlen
);
6240 } else if (p
->family
== AF_ETHERNET
) {
6241 #if defined(HAVE_CUMULUS)
6242 len
= vty_out(vty
, "%s",
6243 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6246 prefix2str(p
, buf
, PREFIX_STRLEN
);
6247 len
= vty_out(vty
, "%s", buf
);
6250 len
= vty_out(vty
, "%s/%d",
6251 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6256 vty_out(vty
, "\n%*s", 20, " ");
6258 vty_out(vty
, "%*s", len
, " ");
6261 enum bgp_display_type
{
6265 /* Print the short form route status for a bgp_info */
6266 static void route_vty_short_status_out(struct vty
*vty
, struct bgp_info
*binfo
,
6267 json_object
*json_path
)
6271 /* Route status display. */
6272 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6273 json_object_boolean_true_add(json_path
, "removed");
6275 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6276 json_object_boolean_true_add(json_path
, "stale");
6278 if (binfo
->extra
&& binfo
->extra
->suppress
)
6279 json_object_boolean_true_add(json_path
, "suppressed");
6281 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6282 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6283 json_object_boolean_true_add(json_path
, "valid");
6286 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6287 json_object_boolean_true_add(json_path
, "history");
6289 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6290 json_object_boolean_true_add(json_path
, "damped");
6292 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6293 json_object_boolean_true_add(json_path
, "bestpath");
6295 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6296 json_object_boolean_true_add(json_path
, "multipath");
6298 /* Internal route. */
6299 if ((binfo
->peer
->as
)
6300 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6301 json_object_string_add(json_path
, "pathFrom",
6304 json_object_string_add(json_path
, "pathFrom",
6310 /* Route status display. */
6311 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6313 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6315 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6317 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6318 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6324 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6326 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6328 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6330 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6335 /* Internal route. */
6336 if (binfo
->peer
&& (binfo
->peer
->as
)
6337 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6343 /* called from terminal list command */
6344 void route_vty_out(struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6345 int display
, safi_t safi
, json_object
*json_paths
)
6348 json_object
*json_path
= NULL
;
6349 json_object
*json_nexthops
= NULL
;
6350 json_object
*json_nexthop_global
= NULL
;
6351 json_object
*json_nexthop_ll
= NULL
;
6354 json_path
= json_object_new_object();
6356 /* short status lead text */
6357 route_vty_short_status_out(vty
, binfo
, json_path
);
6360 /* print prefix and mask */
6362 route_vty_out_route(p
, vty
);
6364 vty_out(vty
, "%*s", 17, " ");
6367 /* Print attribute */
6371 * For ENCAP and EVPN routes, nexthop address family is not
6372 * neccessarily the same as the prefix address family.
6373 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6374 * EVPN routes are also exchanged with a MP nexthop. Currently,
6376 * is only IPv4, the value will be present in either
6378 * attr->mp_nexthop_global_in
6380 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6382 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6388 &attr
->mp_nexthop_global_in
,
6393 inet_ntop(af
, &attr
->mp_nexthop_global
,
6400 } else if (safi
== SAFI_EVPN
) {
6402 json_nexthop_global
= json_object_new_object();
6404 json_object_string_add(
6405 json_nexthop_global
, "ip",
6406 inet_ntoa(attr
->nexthop
));
6407 json_object_string_add(json_nexthop_global
,
6409 json_object_boolean_true_add(
6410 json_nexthop_global
, "used");
6412 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6415 else if (p
->family
== AF_INET
6416 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6418 json_nexthop_global
= json_object_new_object();
6420 if ((safi
== SAFI_MPLS_VPN
)
6421 || (safi
== SAFI_EVPN
))
6422 json_object_string_add(
6423 json_nexthop_global
, "ip",
6425 attr
->mp_nexthop_global_in
));
6427 json_object_string_add(
6428 json_nexthop_global
, "ip",
6429 inet_ntoa(attr
->nexthop
));
6431 json_object_string_add(json_nexthop_global
,
6433 json_object_boolean_true_add(
6434 json_nexthop_global
, "used");
6436 if ((safi
== SAFI_MPLS_VPN
)
6437 || (safi
== SAFI_EVPN
))
6438 vty_out(vty
, "%-16s",
6440 attr
->mp_nexthop_global_in
));
6442 vty_out(vty
, "%-16s",
6443 inet_ntoa(attr
->nexthop
));
6448 else if (p
->family
== AF_INET6
6449 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6454 json_nexthop_global
= json_object_new_object();
6455 json_object_string_add(
6456 json_nexthop_global
, "ip",
6458 &attr
->mp_nexthop_global
, buf
,
6460 json_object_string_add(json_nexthop_global
,
6462 json_object_string_add(json_nexthop_global
,
6465 /* We display both LL & GL if both have been
6467 if ((attr
->mp_nexthop_len
== 32)
6468 || (binfo
->peer
->conf_if
)) {
6470 json_object_new_object();
6471 json_object_string_add(
6472 json_nexthop_ll
, "ip",
6475 &attr
->mp_nexthop_local
,
6477 json_object_string_add(json_nexthop_ll
,
6479 json_object_string_add(json_nexthop_ll
,
6484 &attr
->mp_nexthop_global
,
6485 &attr
->mp_nexthop_local
)
6487 && !attr
->mp_nexthop_prefer_global
)
6488 json_object_boolean_true_add(
6492 json_object_boolean_true_add(
6493 json_nexthop_global
,
6496 json_object_boolean_true_add(
6497 json_nexthop_global
, "used");
6499 /* Display LL if LL/Global both in table unless
6500 * prefer-global is set */
6501 if (((attr
->mp_nexthop_len
== 32)
6502 && !attr
->mp_nexthop_prefer_global
)
6503 || (binfo
->peer
->conf_if
)) {
6504 if (binfo
->peer
->conf_if
) {
6507 binfo
->peer
->conf_if
);
6509 7 - len
; /* len of IPv6
6515 vty_out(vty
, "\n%*s",
6518 vty_out(vty
, "%*s", len
,
6525 &attr
->mp_nexthop_local
,
6530 vty_out(vty
, "\n%*s",
6533 vty_out(vty
, "%*s", len
,
6541 &attr
->mp_nexthop_global
,
6546 vty_out(vty
, "\n%*s", 36, " ");
6548 vty_out(vty
, "%*s", len
, " ");
6554 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6556 json_object_int_add(json_path
, "med",
6559 vty_out(vty
, "%10u", attr
->med
);
6560 else if (!json_paths
)
6564 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6566 json_object_int_add(json_path
, "localpref",
6569 vty_out(vty
, "%7u", attr
->local_pref
);
6570 else if (!json_paths
)
6574 json_object_int_add(json_path
, "weight", attr
->weight
);
6576 vty_out(vty
, "%7u ", attr
->weight
);
6580 json_object_string_add(json_path
, "peerId",
6581 sockunion2str(&binfo
->peer
->su
,
6589 json_object_string_add(json_path
, "aspath",
6592 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6597 json_object_string_add(
6598 json_path
, "origin",
6599 bgp_origin_long_str
[attr
->origin
]);
6601 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6604 json_object_string_add(json_path
, "alert",
6607 vty_out(vty
, "No attributes to print\n");
6611 if (json_nexthop_global
|| json_nexthop_ll
) {
6612 json_nexthops
= json_object_new_array();
6614 if (json_nexthop_global
)
6615 json_object_array_add(json_nexthops
,
6616 json_nexthop_global
);
6618 if (json_nexthop_ll
)
6619 json_object_array_add(json_nexthops
,
6622 json_object_object_add(json_path
, "nexthops",
6626 json_object_array_add(json_paths
, json_path
);
6630 /* prints an additional line, indented, with VNC info, if
6632 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6633 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6638 /* called from terminal list command */
6639 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6640 safi_t safi
, u_char use_json
, json_object
*json_ar
)
6642 json_object
*json_status
= NULL
;
6643 json_object
*json_net
= NULL
;
6645 /* Route status display. */
6647 json_status
= json_object_new_object();
6648 json_net
= json_object_new_object();
6655 /* print prefix and mask */
6657 json_object_string_add(
6658 json_net
, "addrPrefix",
6659 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6661 route_vty_out_route(p
, vty
);
6663 /* Print attribute */
6666 if (p
->family
== AF_INET
6667 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6668 || safi
== SAFI_EVPN
6669 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6670 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6671 || safi
== SAFI_EVPN
)
6672 json_object_string_add(
6673 json_net
, "nextHop",
6675 attr
->mp_nexthop_global_in
));
6677 json_object_string_add(
6678 json_net
, "nextHop",
6679 inet_ntoa(attr
->nexthop
));
6680 } else if (p
->family
== AF_INET6
6681 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6684 json_object_string_add(
6685 json_net
, "netHopGloabal",
6687 &attr
->mp_nexthop_global
, buf
,
6692 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6693 json_object_int_add(json_net
, "metric",
6696 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6697 json_object_int_add(json_net
, "localPref",
6700 json_object_int_add(json_net
, "weight", attr
->weight
);
6704 json_object_string_add(json_net
, "asPath",
6708 json_object_string_add(json_net
, "bgpOriginCode",
6709 bgp_origin_str
[attr
->origin
]);
6711 if (p
->family
== AF_INET
6712 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6713 || safi
== SAFI_EVPN
6714 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6715 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6716 || safi
== SAFI_EVPN
)
6717 vty_out(vty
, "%-16s",
6719 attr
->mp_nexthop_global_in
));
6721 vty_out(vty
, "%-16s",
6722 inet_ntoa(attr
->nexthop
));
6723 } else if (p
->family
== AF_INET6
6724 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6731 &attr
->mp_nexthop_global
, buf
,
6735 vty_out(vty
, "\n%*s", 36, " ");
6737 vty_out(vty
, "%*s", len
, " ");
6740 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6741 vty_out(vty
, "%10u", attr
->med
);
6745 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6746 vty_out(vty
, "%7u", attr
->local_pref
);
6750 vty_out(vty
, "%7u ", attr
->weight
);
6754 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6757 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6761 json_object_boolean_true_add(json_status
, "*");
6762 json_object_boolean_true_add(json_status
, ">");
6763 json_object_object_add(json_net
, "appliedStatusSymbols",
6765 char buf_cut
[BUFSIZ
];
6766 json_object_object_add(
6768 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
6774 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
6775 struct bgp_info
*binfo
, int display
, safi_t safi
,
6778 json_object
*json_out
= NULL
;
6780 mpls_label_t label
= MPLS_INVALID_LABEL
;
6786 json_out
= json_object_new_object();
6788 /* short status lead text */
6789 route_vty_short_status_out(vty
, binfo
, json_out
);
6791 /* print prefix and mask */
6794 route_vty_out_route(p
, vty
);
6796 vty_out(vty
, "%*s", 17, " ");
6799 /* Print attribute */
6802 if (((p
->family
== AF_INET
)
6803 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6804 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
6805 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6806 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6807 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6808 || safi
== SAFI_EVPN
) {
6810 json_object_string_add(
6811 json_out
, "mpNexthopGlobalIn",
6813 attr
->mp_nexthop_global_in
));
6815 vty_out(vty
, "%-16s",
6817 attr
->mp_nexthop_global_in
));
6820 json_object_string_add(
6821 json_out
, "nexthop",
6822 inet_ntoa(attr
->nexthop
));
6824 vty_out(vty
, "%-16s",
6825 inet_ntoa(attr
->nexthop
));
6827 } else if (((p
->family
== AF_INET6
)
6828 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6829 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
6830 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6831 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6835 if (attr
->mp_nexthop_len
6836 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
6838 json_object_string_add(
6839 json_out
, "mpNexthopGlobalIn",
6842 &attr
->mp_nexthop_global
,
6848 &attr
->mp_nexthop_global
,
6850 } else if (attr
->mp_nexthop_len
6851 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
6854 &attr
->mp_nexthop_global
,
6857 &attr
->mp_nexthop_local
,
6859 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6860 json_object_string_add(
6862 "mpNexthopGlobalLocal", buf_c
);
6864 vty_out(vty
, "%s(%s)",
6867 &attr
->mp_nexthop_global
,
6871 &attr
->mp_nexthop_local
,
6877 label
= decode_label(&binfo
->extra
->label
);
6879 if (bgp_is_valid_label(&label
)) {
6881 json_object_int_add(json_out
, "notag", label
);
6882 json_object_array_add(json
, json_out
);
6884 vty_out(vty
, "notag/%d", label
);
6890 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
6891 struct bgp_info
*binfo
, int display
,
6892 json_object
*json_paths
)
6896 json_object
*json_path
= NULL
;
6899 json_path
= json_object_new_object();
6904 /* short status lead text */
6905 route_vty_short_status_out(vty
, binfo
, json_path
);
6907 /* print prefix and mask */
6909 route_vty_out_route(p
, vty
);
6911 vty_out(vty
, "%*s", 17, " ");
6913 /* Print attribute */
6917 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6921 vty_out(vty
, "%-16s",
6922 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6926 vty_out(vty
, "%s(%s)",
6927 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6929 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
6937 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
6938 char *str
= esi2str(id
);
6939 vty_out(vty
, "%s", str
);
6940 XFREE(MTYPE_TMP
, str
);
6941 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
)) {
6942 vty_out(vty
, "/%s", inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
6943 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
)) {
6945 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
6948 if (attr
->ecommunity
) {
6950 struct ecommunity_val
*routermac
= ecommunity_lookup(
6951 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
6952 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6954 mac
= ecom_mac2str((char *)routermac
->val
);
6956 vty_out(vty
, "/%s", (char *)mac
);
6957 XFREE(MTYPE_TMP
, mac
);
6963 /* dampening route */
6964 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
6965 struct bgp_info
*binfo
, int display
, safi_t safi
,
6966 u_char use_json
, json_object
*json
)
6970 char timebuf
[BGP_UPTIME_LEN
];
6972 /* short status lead text */
6973 route_vty_short_status_out(vty
, binfo
, json
);
6975 /* print prefix and mask */
6978 route_vty_out_route(p
, vty
);
6980 vty_out(vty
, "%*s", 17, " ");
6983 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
6987 vty_out(vty
, "\n%*s", 34, " ");
6990 json_object_int_add(json
, "peerHost", len
);
6992 vty_out(vty
, "%*s", len
, " ");
6996 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
, BGP_UPTIME_LEN
,
6999 vty_out(vty
, "%s ", bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7003 /* Print attribute */
7009 json_object_string_add(json
, "asPath",
7012 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7017 json_object_string_add(json
, "origin",
7018 bgp_origin_str
[attr
->origin
]);
7020 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7027 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7028 struct bgp_info
*binfo
, int display
, safi_t safi
,
7029 u_char use_json
, json_object
*json
)
7032 struct bgp_damp_info
*bdi
;
7033 char timebuf
[BGP_UPTIME_LEN
];
7039 bdi
= binfo
->extra
->damp_info
;
7041 /* short status lead text */
7042 route_vty_short_status_out(vty
, binfo
, json
);
7044 /* print prefix and mask */
7047 route_vty_out_route(p
, vty
);
7049 vty_out(vty
, "%*s", 17, " ");
7052 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7056 vty_out(vty
, "\n%*s", 33, " ");
7059 json_object_int_add(json
, "peerHost", len
);
7061 vty_out(vty
, "%*s", len
, " ");
7064 len
= vty_out(vty
, "%d", bdi
->flap
);
7071 json_object_int_add(json
, "bdiFlap", len
);
7073 vty_out(vty
, "%*s", len
, " ");
7077 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7080 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7081 BGP_UPTIME_LEN
, 0, NULL
));
7083 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)
7084 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7086 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7087 BGP_UPTIME_LEN
, use_json
, json
);
7090 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7095 vty_out(vty
, "%*s ", 8, " ");
7098 /* Print attribute */
7104 json_object_string_add(json
, "asPath",
7107 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7112 json_object_string_add(json
, "origin",
7113 bgp_origin_str
[attr
->origin
]);
7115 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7121 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7122 int *first
, const char *header
,
7123 json_object
*json_adv_to
)
7125 char buf1
[INET6_ADDRSTRLEN
];
7126 json_object
*json_peer
= NULL
;
7129 /* 'advertised-to' is a dictionary of peers we have advertised
7131 * prefix too. The key is the peer's IP or swpX, the value is
7133 * hostname if we know it and "" if not.
7135 json_peer
= json_object_new_object();
7138 json_object_string_add(json_peer
, "hostname",
7142 json_object_object_add(json_adv_to
, peer
->conf_if
,
7145 json_object_object_add(
7147 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7151 vty_out(vty
, "%s", header
);
7156 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7158 vty_out(vty
, " %s(%s)", peer
->hostname
,
7161 vty_out(vty
, " %s(%s)", peer
->hostname
,
7162 sockunion2str(&peer
->su
, buf1
,
7166 vty_out(vty
, " %s", peer
->conf_if
);
7169 sockunion2str(&peer
->su
, buf1
,
7175 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7176 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7177 json_object
*json_paths
)
7179 char buf
[INET6_ADDRSTRLEN
];
7181 #if defined(HAVE_CUMULUS)
7182 char buf2
[EVPN_ROUTE_STRLEN
];
7185 int sockunion_vty_out(struct vty
*, union sockunion
*);
7187 json_object
*json_bestpath
= NULL
;
7188 json_object
*json_cluster_list
= NULL
;
7189 json_object
*json_cluster_list_list
= NULL
;
7190 json_object
*json_ext_community
= NULL
;
7191 json_object
*json_last_update
= NULL
;
7192 json_object
*json_nexthop_global
= NULL
;
7193 json_object
*json_nexthop_ll
= NULL
;
7194 json_object
*json_nexthops
= NULL
;
7195 json_object
*json_path
= NULL
;
7196 json_object
*json_peer
= NULL
;
7197 json_object
*json_string
= NULL
;
7198 json_object
*json_adv_to
= NULL
;
7200 struct listnode
*node
, *nnode
;
7202 int addpath_capable
;
7204 unsigned int first_as
;
7207 json_path
= json_object_new_object();
7208 json_peer
= json_object_new_object();
7209 json_nexthop_global
= json_object_new_object();
7212 #if defined(HAVE_CUMULUS)
7213 if (!json_paths
&& safi
== SAFI_EVPN
) {
7216 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7217 vty_out(vty
, " Route %s", buf2
);
7220 bgp_evpn_label2str(&binfo
->extra
->label
, tag_buf
,
7222 vty_out(vty
, " VNI %s", tag_buf
);
7225 if (binfo
->extra
&& binfo
->extra
->parent
) {
7226 struct bgp_info
*parent_ri
;
7227 struct bgp_node
*rn
, *prn
;
7229 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7230 rn
= parent_ri
->net
;
7231 if (rn
&& rn
->prn
) {
7233 vty_out(vty
, " Imported from %s:%s\n",
7235 (struct prefix_rd
*)&prn
->p
,
7236 buf1
, RD_ADDRSTRLEN
),
7246 /* Line1 display AS-path, Aggregator */
7249 json_object_lock(attr
->aspath
->json
);
7250 json_object_object_add(json_path
, "aspath",
7251 attr
->aspath
->json
);
7253 if (attr
->aspath
->segments
)
7254 aspath_print_vty(vty
, " %s",
7257 vty_out(vty
, " Local");
7261 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
)) {
7263 json_object_boolean_true_add(json_path
,
7266 vty_out(vty
, ", (removed)");
7269 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
)) {
7271 json_object_boolean_true_add(json_path
,
7274 vty_out(vty
, ", (stale)");
7277 if (CHECK_FLAG(attr
->flag
,
7278 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7280 json_object_int_add(json_path
, "aggregatorAs",
7281 attr
->aggregator_as
);
7282 json_object_string_add(
7283 json_path
, "aggregatorId",
7284 inet_ntoa(attr
->aggregator_addr
));
7286 vty_out(vty
, ", (aggregated by %u %s)",
7287 attr
->aggregator_as
,
7288 inet_ntoa(attr
->aggregator_addr
));
7292 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7293 PEER_FLAG_REFLECTOR_CLIENT
)) {
7295 json_object_boolean_true_add(
7296 json_path
, "rxedFromRrClient");
7298 vty_out(vty
, ", (Received from a RR-client)");
7301 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7302 PEER_FLAG_RSERVER_CLIENT
)) {
7304 json_object_boolean_true_add(
7305 json_path
, "rxedFromRsClient");
7307 vty_out(vty
, ", (Received from a RS-client)");
7310 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7312 json_object_boolean_true_add(
7313 json_path
, "dampeningHistoryEntry");
7315 vty_out(vty
, ", (history entry)");
7316 } else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)) {
7318 json_object_boolean_true_add(
7319 json_path
, "dampeningSuppressed");
7321 vty_out(vty
, ", (suppressed due to dampening)");
7327 /* Line2 display Next-hop, Neighbor, Router-id */
7328 /* Display the nexthop */
7329 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
)
7330 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7331 || safi
== SAFI_EVPN
7332 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7333 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7334 || safi
== SAFI_EVPN
) {
7336 json_object_string_add(
7337 json_nexthop_global
, "ip",
7339 attr
->mp_nexthop_global_in
));
7343 attr
->mp_nexthop_global_in
));
7346 json_object_string_add(
7347 json_nexthop_global
, "ip",
7348 inet_ntoa(attr
->nexthop
));
7351 inet_ntoa(attr
->nexthop
));
7355 json_object_string_add(json_nexthop_global
,
7359 json_object_string_add(
7360 json_nexthop_global
, "ip",
7362 &attr
->mp_nexthop_global
, buf
,
7364 json_object_string_add(json_nexthop_global
,
7366 json_object_string_add(json_nexthop_global
,
7371 &attr
->mp_nexthop_global
, buf
,
7376 /* Display the IGP cost or 'inaccessible' */
7377 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7379 json_object_boolean_false_add(
7380 json_nexthop_global
, "accessible");
7382 vty_out(vty
, " (inaccessible)");
7384 if (binfo
->extra
&& binfo
->extra
->igpmetric
) {
7386 json_object_int_add(
7387 json_nexthop_global
, "metric",
7388 binfo
->extra
->igpmetric
);
7390 vty_out(vty
, " (metric %u)",
7391 binfo
->extra
->igpmetric
);
7394 /* IGP cost is 0, display this only for json */
7397 json_object_int_add(json_nexthop_global
,
7402 json_object_boolean_true_add(
7403 json_nexthop_global
, "accessible");
7406 /* Display peer "from" output */
7407 /* This path was originated locally */
7408 if (binfo
->peer
== bgp
->peer_self
) {
7410 if (safi
== SAFI_EVPN
7411 || (p
->family
== AF_INET
7412 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7414 json_object_string_add(
7415 json_peer
, "peerId", "0.0.0.0");
7417 vty_out(vty
, " from 0.0.0.0 ");
7420 json_object_string_add(json_peer
,
7423 vty_out(vty
, " from :: ");
7427 json_object_string_add(
7428 json_peer
, "routerId",
7429 inet_ntoa(bgp
->router_id
));
7431 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7434 /* We RXed this path from one of our peers */
7438 json_object_string_add(
7439 json_peer
, "peerId",
7440 sockunion2str(&binfo
->peer
->su
, buf
,
7442 json_object_string_add(
7443 json_peer
, "routerId",
7445 &binfo
->peer
->remote_id
, buf1
,
7448 if (binfo
->peer
->hostname
)
7449 json_object_string_add(
7450 json_peer
, "hostname",
7451 binfo
->peer
->hostname
);
7453 if (binfo
->peer
->domainname
)
7454 json_object_string_add(
7455 json_peer
, "domainname",
7456 binfo
->peer
->domainname
);
7458 if (binfo
->peer
->conf_if
)
7459 json_object_string_add(
7460 json_peer
, "interface",
7461 binfo
->peer
->conf_if
);
7463 if (binfo
->peer
->conf_if
) {
7464 if (binfo
->peer
->hostname
7467 BGP_FLAG_SHOW_HOSTNAME
))
7468 vty_out(vty
, " from %s(%s)",
7469 binfo
->peer
->hostname
,
7470 binfo
->peer
->conf_if
);
7472 vty_out(vty
, " from %s",
7473 binfo
->peer
->conf_if
);
7475 if (binfo
->peer
->hostname
7478 BGP_FLAG_SHOW_HOSTNAME
))
7479 vty_out(vty
, " from %s(%s)",
7480 binfo
->peer
->hostname
,
7483 vty_out(vty
, " from %s",
7492 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7493 vty_out(vty
, " (%s)",
7494 inet_ntoa(attr
->originator_id
));
7496 vty_out(vty
, " (%s)",
7499 &binfo
->peer
->remote_id
,
7507 /* display the link-local nexthop */
7508 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7510 json_nexthop_ll
= json_object_new_object();
7511 json_object_string_add(
7512 json_nexthop_ll
, "ip",
7514 &attr
->mp_nexthop_local
, buf
,
7516 json_object_string_add(json_nexthop_ll
, "afi",
7518 json_object_string_add(json_nexthop_ll
, "scope",
7521 json_object_boolean_true_add(json_nexthop_ll
,
7524 if (!attr
->mp_nexthop_prefer_global
)
7525 json_object_boolean_true_add(
7526 json_nexthop_ll
, "used");
7528 json_object_boolean_true_add(
7529 json_nexthop_global
, "used");
7531 vty_out(vty
, " (%s) %s\n",
7533 &attr
->mp_nexthop_local
, buf
,
7535 attr
->mp_nexthop_prefer_global
7540 /* If we do not have a link-local nexthop then we must flag the
7544 json_object_boolean_true_add(
7545 json_nexthop_global
, "used");
7548 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7549 * Int/Ext/Local, Atomic, best */
7551 json_object_string_add(
7552 json_path
, "origin",
7553 bgp_origin_long_str
[attr
->origin
]);
7555 vty_out(vty
, " Origin %s",
7556 bgp_origin_long_str
[attr
->origin
]);
7558 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7560 json_object_int_add(json_path
, "med",
7563 vty_out(vty
, ", metric %u", attr
->med
);
7566 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7568 json_object_int_add(json_path
, "localpref",
7571 vty_out(vty
, ", localpref %u",
7575 json_object_int_add(json_path
, "localpref",
7576 bgp
->default_local_pref
);
7578 vty_out(vty
, ", localpref %u",
7579 bgp
->default_local_pref
);
7582 if (attr
->weight
!= 0) {
7584 json_object_int_add(json_path
, "weight",
7587 vty_out(vty
, ", weight %u", attr
->weight
);
7590 if (attr
->tag
!= 0) {
7592 json_object_int_add(json_path
, "tag",
7595 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7599 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7601 json_object_boolean_false_add(json_path
,
7604 vty_out(vty
, ", invalid");
7605 } else if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7607 json_object_boolean_true_add(json_path
,
7610 vty_out(vty
, ", valid");
7613 if (binfo
->peer
!= bgp
->peer_self
) {
7614 if (binfo
->peer
->as
== binfo
->peer
->local_as
) {
7615 if (CHECK_FLAG(bgp
->config
,
7616 BGP_CONFIG_CONFEDERATION
)) {
7618 json_object_string_add(
7623 ", confed-internal");
7626 json_object_string_add(
7630 vty_out(vty
, ", internal");
7633 if (bgp_confederation_peers_check(
7634 bgp
, binfo
->peer
->as
)) {
7636 json_object_string_add(
7641 ", confed-external");
7644 json_object_string_add(
7648 vty_out(vty
, ", external");
7651 } else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
) {
7653 json_object_boolean_true_add(json_path
,
7655 json_object_boolean_true_add(json_path
,
7658 vty_out(vty
, ", aggregated, local");
7660 } else if (binfo
->type
!= ZEBRA_ROUTE_BGP
) {
7662 json_object_boolean_true_add(json_path
,
7665 vty_out(vty
, ", sourced");
7668 json_object_boolean_true_add(json_path
,
7670 json_object_boolean_true_add(json_path
,
7673 vty_out(vty
, ", sourced, local");
7677 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
7679 json_object_boolean_true_add(json_path
,
7682 vty_out(vty
, ", atomic-aggregate");
7685 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
)
7686 || (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)
7687 && bgp_info_mpath_count(binfo
))) {
7689 json_object_boolean_true_add(json_path
,
7692 vty_out(vty
, ", multipath");
7695 // Mark the bestpath(s)
7696 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DMED_SELECTED
)) {
7697 first_as
= aspath_get_first_as(attr
->aspath
);
7702 json_object_new_object();
7703 json_object_int_add(json_bestpath
,
7704 "bestpathFromAs", first_as
);
7707 vty_out(vty
, ", bestpath-from-AS %d",
7711 ", bestpath-from-AS Local");
7715 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)) {
7719 json_object_new_object();
7720 json_object_boolean_true_add(json_bestpath
,
7723 vty_out(vty
, ", best");
7727 json_object_object_add(json_path
, "bestpath",
7733 /* Line 4 display Community */
7734 if (attr
->community
) {
7736 json_object_lock(attr
->community
->json
);
7737 json_object_object_add(json_path
, "community",
7738 attr
->community
->json
);
7740 vty_out(vty
, " Community: %s\n",
7741 attr
->community
->str
);
7745 /* Line 5 display Extended-community */
7746 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
7748 json_ext_community
= json_object_new_object();
7749 json_object_string_add(json_ext_community
,
7751 attr
->ecommunity
->str
);
7752 json_object_object_add(json_path
,
7753 "extendedCommunity",
7754 json_ext_community
);
7756 vty_out(vty
, " Extended Community: %s\n",
7757 attr
->ecommunity
->str
);
7761 /* Line 6 display Large community */
7762 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7763 vty_out(vty
, " Large Community: %s\n",
7764 attr
->lcommunity
->str
);
7766 /* Line 7 display Originator, Cluster-id */
7767 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7768 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
7770 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
7772 json_object_string_add(
7773 json_path
, "originatorId",
7774 inet_ntoa(attr
->originator_id
));
7776 vty_out(vty
, " Originator: %s",
7777 inet_ntoa(attr
->originator_id
));
7780 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
7785 json_object_new_object();
7786 json_cluster_list_list
=
7787 json_object_new_array();
7790 i
< attr
->cluster
->length
/ 4;
7792 json_string
= json_object_new_string(
7796 json_object_array_add(
7797 json_cluster_list_list
,
7801 /* struct cluster_list does not have
7803 * aspath and community do. Add this
7806 json_object_string_add(json_cluster_list,
7807 "string", attr->cluster->str);
7809 json_object_object_add(
7810 json_cluster_list
, "list",
7811 json_cluster_list_list
);
7812 json_object_object_add(
7813 json_path
, "clusterList",
7816 vty_out(vty
, ", Cluster list: ");
7819 i
< attr
->cluster
->length
/ 4;
7833 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7834 bgp_damp_info_vty(vty
, binfo
, json_path
);
7837 #if defined(HAVE_CUMULUS)
7838 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
)
7839 && safi
!= SAFI_EVPN
)
7841 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
))
7844 mpls_label_t label
= label_pton(&binfo
->extra
->label
);
7846 json_object_int_add(json_path
, "remoteLabel",
7849 vty_out(vty
, " Remote label: %d\n", label
);
7853 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
7855 json_object_int_add(json_path
, "labelIndex",
7858 vty_out(vty
, " Label Index: %d\n",
7862 /* Line 8 display Addpath IDs */
7863 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
) {
7865 json_object_int_add(json_path
, "addpathRxId",
7866 binfo
->addpath_rx_id
);
7867 json_object_int_add(json_path
, "addpathTxId",
7868 binfo
->addpath_tx_id
);
7870 vty_out(vty
, " AddPath ID: RX %u, TX %u\n",
7871 binfo
->addpath_rx_id
,
7872 binfo
->addpath_tx_id
);
7876 /* If we used addpath to TX a non-bestpath we need to display
7877 * "Advertised to" on a path-by-path basis */
7878 if (bgp
->addpath_tx_used
[afi
][safi
]) {
7881 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7883 bgp_addpath_encode_tx(peer
, afi
, safi
);
7884 has_adj
= bgp_adj_out_lookup(
7885 peer
, binfo
->net
, binfo
->addpath_tx_id
);
7887 if ((addpath_capable
&& has_adj
)
7888 || (!addpath_capable
&& has_adj
7889 && CHECK_FLAG(binfo
->flags
,
7890 BGP_INFO_SELECTED
))) {
7891 if (json_path
&& !json_adv_to
)
7893 json_object_new_object();
7895 route_vty_out_advertised_to(
7904 json_object_object_add(json_path
,
7915 /* Line 9 display Uptime */
7916 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7918 json_last_update
= json_object_new_object();
7919 json_object_int_add(json_last_update
, "epoch", tbuf
);
7920 json_object_string_add(json_last_update
, "string",
7922 json_object_object_add(json_path
, "lastUpdate",
7925 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
7928 /* We've constructed the json object for this path, add it to the json
7932 if (json_nexthop_global
|| json_nexthop_ll
) {
7933 json_nexthops
= json_object_new_array();
7935 if (json_nexthop_global
)
7936 json_object_array_add(json_nexthops
,
7937 json_nexthop_global
);
7939 if (json_nexthop_ll
)
7940 json_object_array_add(json_nexthops
,
7943 json_object_object_add(json_path
, "nexthops",
7947 json_object_object_add(json_path
, "peer", json_peer
);
7948 json_object_array_add(json_paths
, json_path
);
7953 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
7954 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
7955 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
7957 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
7958 const char *prefix_list_str
, afi_t afi
,
7959 safi_t safi
, enum bgp_show_type type
);
7960 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
7961 const char *filter
, afi_t afi
, safi_t safi
,
7962 enum bgp_show_type type
);
7963 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
7964 const char *rmap_str
, afi_t afi
, safi_t safi
,
7965 enum bgp_show_type type
);
7966 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
7967 const char *com
, int exact
, afi_t afi
,
7969 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
7970 const char *prefix
, afi_t afi
, safi_t safi
,
7971 enum bgp_show_type type
);
7972 static int bgp_show_regexp(struct vty
*vty
, const char *regstr
, afi_t afi
,
7973 safi_t safi
, enum bgp_show_type type
);
7974 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
, int argc
,
7975 struct cmd_token
**argv
, int exact
, afi_t afi
,
7978 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
,
7979 struct bgp_table
*table
, enum bgp_show_type type
,
7980 void *output_arg
, u_char use_json
)
7982 struct bgp_info
*ri
;
7983 struct bgp_node
*rn
;
7986 unsigned long output_count
;
7987 unsigned long total_count
;
7991 json_object
*json_paths
= NULL
;
7996 "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
7997 ", \"routerId\": \"%s\", \"routes\": { ",
7998 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7999 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default"
8001 table
->version
, inet_ntoa(bgp
->router_id
));
8002 json_paths
= json_object_new_object();
8005 /* This is first entry point, so reset total line. */
8009 /* Start processing of routes. */
8010 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
8011 if (rn
->info
!= NULL
) {
8013 if (!first
&& use_json
) {
8017 json_paths
= json_object_new_array();
8021 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8023 if (type
== bgp_show_type_flap_statistics
8024 || type
== bgp_show_type_flap_neighbor
8025 || type
== bgp_show_type_dampend_paths
8026 || type
== bgp_show_type_damp_neighbor
) {
8028 && ri
->extra
->damp_info
))
8031 if (type
== bgp_show_type_regexp
) {
8032 regex_t
*regex
= output_arg
;
8034 if (bgp_regexec(regex
, ri
->attr
->aspath
)
8038 if (type
== bgp_show_type_prefix_list
) {
8039 struct prefix_list
*plist
= output_arg
;
8041 if (prefix_list_apply(plist
, &rn
->p
)
8045 if (type
== bgp_show_type_filter_list
) {
8046 struct as_list
*as_list
= output_arg
;
8048 if (as_list_apply(as_list
,
8050 != AS_FILTER_PERMIT
)
8053 if (type
== bgp_show_type_route_map
) {
8054 struct route_map
*rmap
= output_arg
;
8055 struct bgp_info binfo
;
8056 struct attr dummy_attr
;
8059 bgp_attr_dup(&dummy_attr
, ri
->attr
);
8061 binfo
.peer
= ri
->peer
;
8062 binfo
.attr
= &dummy_attr
;
8064 ret
= route_map_apply(rmap
, &rn
->p
,
8066 if (ret
== RMAP_DENYMATCH
)
8069 if (type
== bgp_show_type_neighbor
8070 || type
== bgp_show_type_flap_neighbor
8071 || type
== bgp_show_type_damp_neighbor
) {
8072 union sockunion
*su
= output_arg
;
8074 if (ri
->peer
== NULL
8075 || ri
->peer
->su_remote
== NULL
8077 ri
->peer
->su_remote
, su
))
8080 if (type
== bgp_show_type_cidr_only
) {
8081 u_int32_t destination
;
8084 ntohl(rn
->p
.u
.prefix4
.s_addr
);
8085 if (IN_CLASSC(destination
)
8086 && rn
->p
.prefixlen
== 24)
8088 if (IN_CLASSB(destination
)
8089 && rn
->p
.prefixlen
== 16)
8091 if (IN_CLASSA(destination
)
8092 && rn
->p
.prefixlen
== 8)
8095 if (type
== bgp_show_type_prefix_longer
) {
8096 struct prefix
*p
= output_arg
;
8098 if (!prefix_match(p
, &rn
->p
))
8101 if (type
== bgp_show_type_community_all
) {
8102 if (!ri
->attr
->community
)
8105 if (type
== bgp_show_type_community
) {
8106 struct community
*com
= output_arg
;
8108 if (!ri
->attr
->community
8109 || !community_match(
8110 ri
->attr
->community
,
8114 if (type
== bgp_show_type_community_exact
) {
8115 struct community
*com
= output_arg
;
8117 if (!ri
->attr
->community
8119 ri
->attr
->community
,
8123 if (type
== bgp_show_type_community_list
) {
8124 struct community_list
*list
=
8127 if (!community_list_match(
8128 ri
->attr
->community
, list
))
8132 == bgp_show_type_community_list_exact
) {
8133 struct community_list
*list
=
8136 if (!community_list_exact_match(
8137 ri
->attr
->community
, list
))
8140 if (type
== bgp_show_type_lcommunity
) {
8141 struct lcommunity
*lcom
= output_arg
;
8143 if (!ri
->attr
->lcommunity
8144 || !lcommunity_match(
8145 ri
->attr
->lcommunity
,
8149 if (type
== bgp_show_type_lcommunity_list
) {
8150 struct community_list
*list
=
8153 if (!lcommunity_list_match(
8154 ri
->attr
->lcommunity
, list
))
8157 if (type
== bgp_show_type_lcommunity_all
) {
8158 if (!ri
->attr
->lcommunity
)
8161 if (type
== bgp_show_type_dampend_paths
8162 || type
== bgp_show_type_damp_neighbor
) {
8163 if (!CHECK_FLAG(ri
->flags
,
8165 || CHECK_FLAG(ri
->flags
,
8170 if (!use_json
&& header
) {
8172 "BGP table version is %" PRIu64
8173 ", local router ID is %s\n",
8175 inet_ntoa(bgp
->router_id
));
8176 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8177 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8178 if (type
== bgp_show_type_dampend_paths
8179 || type
== bgp_show_type_damp_neighbor
)
8181 BGP_SHOW_DAMP_HEADER
);
8183 type
== bgp_show_type_flap_statistics
8184 || type
== bgp_show_type_flap_neighbor
)
8186 BGP_SHOW_FLAP_HEADER
);
8188 vty_out(vty
, BGP_SHOW_HEADER
);
8192 if (type
== bgp_show_type_dampend_paths
8193 || type
== bgp_show_type_damp_neighbor
)
8195 vty
, &rn
->p
, ri
, display
,
8196 SAFI_UNICAST
, use_json
,
8198 else if (type
== bgp_show_type_flap_statistics
8199 || type
== bgp_show_type_flap_neighbor
)
8201 vty
, &rn
->p
, ri
, display
,
8202 SAFI_UNICAST
, use_json
,
8205 route_vty_out(vty
, &rn
->p
, ri
, display
,
8206 SAFI_UNICAST
, json_paths
);
8214 sprintf(buf2
, "%s/%d",
8215 inet_ntop(p
->family
,
8219 vty_out(vty
, "\"%s\": ", buf2
);
8221 json_object_to_json_string(
8223 json_object_free(json_paths
);
8230 json_object_free(json_paths
);
8231 vty_out(vty
, " } }\n");
8233 /* No route is displayed */
8234 if (output_count
== 0) {
8235 if (type
== bgp_show_type_normal
)
8237 "No BGP prefixes displayed, %ld exist\n",
8241 "\nDisplayed %ld routes and %ld total paths\n",
8242 output_count
, total_count
);
8248 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8249 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8251 struct bgp_table
*table
;
8254 bgp
= bgp_get_default();
8259 vty_out(vty
, "No BGP process is configured\n");
8263 /* use MPLS and ENCAP specific shows until they are merged */
8264 if (safi
== SAFI_MPLS_VPN
) {
8265 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
, 0,
8268 /* labeled-unicast routes live in the unicast table */
8269 else if (safi
== SAFI_LABELED_UNICAST
)
8270 safi
= SAFI_UNICAST
;
8272 table
= bgp
->rib
[afi
][safi
];
8274 return bgp_show_table(vty
, bgp
, table
, type
, output_arg
, use_json
);
8277 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8278 safi_t safi
, u_char use_json
)
8280 struct listnode
*node
, *nnode
;
8285 vty_out(vty
, "{\n");
8287 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8290 vty_out(vty
, ",\n");
8294 vty_out(vty
, "\"%s\":",
8295 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8299 vty_out(vty
, "\nInstance %s:\n",
8300 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8304 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8309 vty_out(vty
, "}\n");
8312 /* Header of detailed BGP route information */
8313 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8314 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8315 afi_t afi
, safi_t safi
, json_object
*json
)
8317 struct bgp_info
*ri
;
8320 struct listnode
*node
, *nnode
;
8321 char buf1
[INET6_ADDRSTRLEN
];
8322 char buf2
[INET6_ADDRSTRLEN
];
8323 #if defined(HAVE_CUMULUS)
8324 char buf3
[EVPN_ROUTE_STRLEN
];
8330 int no_advertise
= 0;
8333 int has_valid_label
= 0;
8334 mpls_label_t label
= 0;
8335 json_object
*json_adv_to
= NULL
;
8338 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8340 if (has_valid_label
)
8341 label
= label_pton(&rn
->local_label
);
8344 if (has_valid_label
)
8345 json_object_int_add(json
, "localLabel", label
);
8347 json_object_string_add(json
, "prefix",
8348 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8350 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8352 #if defined(HAVE_CUMULUS)
8353 if (safi
== SAFI_EVPN
)
8354 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8355 prd
? prefix_rd2str(prd
, buf1
, RD_ADDRSTRLEN
)
8358 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8359 buf3
, sizeof(buf3
)));
8361 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8362 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8363 ? prefix_rd2str(prd
, buf1
,
8366 safi
== SAFI_MPLS_VPN
? ":" : "",
8367 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8371 if (p
->family
== AF_ETHERNET
)
8372 prefix2str(p
, buf2
, INET6_ADDRSTRLEN
);
8374 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8376 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8377 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8378 || safi
== SAFI_EVPN
)
8379 ? prefix_rd2str(prd
, buf1
, RD_ADDRSTRLEN
)
8381 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":"
8383 buf2
, p
->prefixlen
);
8386 if (has_valid_label
)
8387 vty_out(vty
, "Local label: %d\n", label
);
8388 #if defined(HAVE_CUMULUS)
8389 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8391 if (bgp_labeled_safi(safi
))
8393 vty_out(vty
, "not allocated\n");
8396 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8398 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
8400 if (ri
->extra
&& ri
->extra
->suppress
)
8402 if (ri
->attr
->community
!= NULL
) {
8403 if (community_include(ri
->attr
->community
,
8404 COMMUNITY_NO_ADVERTISE
))
8406 if (community_include(ri
->attr
->community
,
8407 COMMUNITY_NO_EXPORT
))
8409 if (community_include(ri
->attr
->community
,
8410 COMMUNITY_LOCAL_AS
))
8417 vty_out(vty
, "Paths: (%d available", count
);
8419 vty_out(vty
, ", best #%d", best
);
8420 if (safi
== SAFI_UNICAST
)
8421 vty_out(vty
, ", table %s",
8423 == BGP_INSTANCE_TYPE_DEFAULT
)
8424 ? "Default-IP-Routing-Table"
8427 vty_out(vty
, ", no best path");
8430 vty_out(vty
, ", not advertised to any peer");
8432 vty_out(vty
, ", not advertised to EBGP peer");
8434 vty_out(vty
, ", not advertised outside local AS");
8438 ", Advertisements suppressed by an aggregate.");
8439 vty_out(vty
, ")\n");
8442 /* If we are not using addpath then we can display Advertised to and
8444 * show what peers we advertised the bestpath to. If we are using
8446 * though then we must display Advertised to on a path-by-path basis. */
8447 if (!bgp
->addpath_tx_used
[afi
][safi
]) {
8448 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8449 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
8450 if (json
&& !json_adv_to
)
8451 json_adv_to
= json_object_new_object();
8453 route_vty_out_advertised_to(
8455 " Advertised to non peer-group peers:\n ",
8462 json_object_object_add(json
, "advertisedTo",
8467 vty_out(vty
, " Not advertised to any peer");
8473 /* Display specified route of BGP table. */
8474 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
8475 struct bgp_table
*rib
, const char *ip_str
,
8476 afi_t afi
, safi_t safi
,
8477 struct prefix_rd
*prd
, int prefix_check
,
8478 enum bgp_path_type pathtype
, u_char use_json
)
8483 struct prefix match
;
8484 struct bgp_node
*rn
;
8485 struct bgp_node
*rm
;
8486 struct bgp_info
*ri
;
8487 struct bgp_table
*table
;
8488 json_object
*json
= NULL
;
8489 json_object
*json_paths
= NULL
;
8491 /* Check IP address argument. */
8492 ret
= str2prefix(ip_str
, &match
);
8494 vty_out(vty
, "address is malformed\n");
8498 match
.family
= afi2family(afi
);
8501 json
= json_object_new_object();
8502 json_paths
= json_object_new_array();
8505 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
8506 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
8507 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
8510 if ((table
= rn
->info
) != NULL
) {
8513 if ((rm
= bgp_node_match(table
, &match
))
8517 != match
.prefixlen
) {
8518 bgp_unlock_node(rm
);
8522 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
8524 route_vty_out_detail_header(
8535 if (pathtype
== BGP_PATH_ALL
8537 == BGP_PATH_BESTPATH
8542 == BGP_PATH_MULTIPATH
8548 BGP_INFO_SELECTED
))))
8549 route_vty_out_detail(
8556 bgp_unlock_node(rm
);
8563 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
8565 || rn
->p
.prefixlen
== match
.prefixlen
) {
8566 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8568 route_vty_out_detail_header(
8569 vty
, bgp
, rn
, NULL
, afi
,
8575 if (pathtype
== BGP_PATH_ALL
8576 || (pathtype
== BGP_PATH_BESTPATH
8580 || (pathtype
== BGP_PATH_MULTIPATH
8586 BGP_INFO_SELECTED
))))
8587 route_vty_out_detail(
8588 vty
, bgp
, &rn
->p
, ri
,
8589 afi
, safi
, json_paths
);
8593 bgp_unlock_node(rn
);
8599 json_object_object_add(json
, "paths", json_paths
);
8601 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8602 json
, JSON_C_TO_STRING_PRETTY
));
8603 json_object_free(json
);
8606 vty_out(vty
, "%% Network not in table\n");
8614 /* Display specified route of Main RIB */
8615 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8616 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8617 int prefix_check
, enum bgp_path_type pathtype
,
8621 bgp
= bgp_get_default();
8624 vty_out(vty
, "No BGP process is configured\n");
8629 /* labeled-unicast routes live in the unicast table */
8630 if (safi
== SAFI_LABELED_UNICAST
)
8631 safi
= SAFI_UNICAST
;
8633 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8634 afi
, safi
, prd
, prefix_check
, pathtype
,
8638 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
8639 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
8642 struct lcommunity
*lcom
;
8648 b
= buffer_new(1024);
8649 for (i
= 0; i
< argc
; i
++) {
8651 buffer_putc(b
, ' ');
8653 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
8655 buffer_putstr(b
, argv
[i
]->arg
);
8659 buffer_putc(b
, '\0');
8661 str
= buffer_getstr(b
);
8664 lcom
= lcommunity_str2com(str
);
8665 XFREE(MTYPE_TMP
, str
);
8667 vty_out(vty
, "%% Large-community malformed\n");
8671 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
8675 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
8676 const char *lcom
, afi_t afi
, safi_t safi
,
8679 struct community_list
*list
;
8681 list
= community_list_lookup(bgp_clist
, lcom
,
8682 LARGE_COMMUNITY_LIST_MASTER
);
8684 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
8689 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
8693 DEFUN (show_ip_bgp_large_community_list
,
8694 show_ip_bgp_large_community_list_cmd
,
8695 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8699 BGP_INSTANCE_HELP_STR
8701 BGP_SAFI_WITH_LABEL_HELP_STR
8702 "Display routes matching the large-community-list\n"
8703 "large-community-list number\n"
8704 "large-community-list name\n"
8708 afi_t afi
= AFI_IP6
;
8709 safi_t safi
= SAFI_UNICAST
;
8712 if (argv_find(argv
, argc
, "ip", &idx
))
8714 if (argv_find(argv
, argc
, "view", &idx
)
8715 || argv_find(argv
, argc
, "vrf", &idx
))
8716 vrf
= argv
[++idx
]->arg
;
8717 if (argv_find(argv
, argc
, "ipv4", &idx
)
8718 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8719 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8720 if (argv_find(argv
, argc
, "unicast", &idx
)
8721 || argv_find(argv
, argc
, "multicast", &idx
))
8722 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8725 int uj
= use_json(argc
, argv
);
8727 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8729 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8733 argv_find(argv
, argc
, "large-community-list", &idx
);
8734 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
8737 DEFUN (show_ip_bgp_large_community
,
8738 show_ip_bgp_large_community_cmd
,
8739 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8743 BGP_INSTANCE_HELP_STR
8745 BGP_SAFI_WITH_LABEL_HELP_STR
8746 "Display routes matching the large-communities\n"
8747 "List of large-community numbers\n"
8751 afi_t afi
= AFI_IP6
;
8752 safi_t safi
= SAFI_UNICAST
;
8755 if (argv_find(argv
, argc
, "ip", &idx
))
8757 if (argv_find(argv
, argc
, "view", &idx
)
8758 || argv_find(argv
, argc
, "vrf", &idx
))
8759 vrf
= argv
[++idx
]->arg
;
8760 if (argv_find(argv
, argc
, "ipv4", &idx
)
8761 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8762 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8763 if (argv_find(argv
, argc
, "unicast", &idx
)
8764 || argv_find(argv
, argc
, "multicast", &idx
))
8765 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8768 int uj
= use_json(argc
, argv
);
8770 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8772 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8776 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
8777 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8779 return bgp_show(vty
, bgp
, afi
, safi
,
8780 bgp_show_type_lcommunity_all
, NULL
, uj
);
8783 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
8786 /* BGP route print out function. */
8789 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8792 |dampening <flap-statistics|dampened-paths|parameters>\
8797 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8798 |community-list <(1-500)|WORD> [exact-match]\
8799 |A.B.C.D/M longer-prefixes\
8800 |X:X::X:X/M longer-prefixes>\
8805 BGP_INSTANCE_HELP_STR
8807 BGP_SAFI_WITH_LABEL_HELP_STR
8808 "Display only routes with non-natural netmasks\n"
8809 "Display detailed information about dampening\n"
8810 "Display flap statistics of routes\n"
8811 "Display paths suppressed due to dampening\n"
8812 "Display detail of configured dampening parameters\n"
8813 "Display routes matching the route-map\n"
8814 "A route-map to match on\n"
8815 "Display routes conforming to the prefix-list\n"
8816 "Prefix-list name\n"
8817 "Display routes conforming to the filter-list\n"
8818 "Regular expression access list name\n"
8819 "BGP RIB advertisement statistics\n"
8820 "Display routes matching the communities\n"
8822 "Do not send outside local AS (well-known community)\n"
8823 "Do not advertise to any peer (well-known community)\n"
8824 "Do not export to next AS (well-known community)\n"
8825 "Exact match of the communities\n"
8826 "Display routes matching the community-list\n"
8827 "community-list number\n"
8828 "community-list name\n"
8829 "Exact match of the communities\n"
8831 "Display route and more specific routes\n"
8833 "Display route and more specific routes\n"
8836 afi_t afi
= AFI_IP6
;
8837 safi_t safi
= SAFI_UNICAST
;
8838 int exact_match
= 0;
8839 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8840 struct bgp
*bgp
= NULL
;
8843 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8848 int uj
= use_json(argc
, argv
);
8852 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8853 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
8856 if (argv_find(argv
, argc
, "dampening", &idx
)) {
8857 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
8858 return bgp_show(vty
, bgp
, afi
, safi
,
8859 bgp_show_type_dampend_paths
, NULL
, uj
);
8860 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
8861 return bgp_show(vty
, bgp
, afi
, safi
,
8862 bgp_show_type_flap_statistics
, NULL
,
8864 else if (argv_find(argv
, argc
, "parameters", &idx
))
8865 return bgp_show_dampening_parameters(vty
, afi
, safi
);
8868 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8869 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8870 safi
, bgp_show_type_prefix_list
);
8872 if (argv_find(argv
, argc
, "filter-list", &idx
))
8873 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8874 safi
, bgp_show_type_filter_list
);
8876 if (argv_find(argv
, argc
, "statistics", &idx
))
8877 return bgp_table_stats(vty
, bgp
, afi
, safi
);
8879 if (argv_find(argv
, argc
, "route-map", &idx
))
8880 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8881 safi
, bgp_show_type_route_map
);
8883 if (argv_find(argv
, argc
, "community", &idx
)) {
8884 /* show a specific community */
8885 if (argv_find(argv
, argc
, "local-AS", &idx
)
8886 || argv_find(argv
, argc
, "no-advertise", &idx
)
8887 || argv_find(argv
, argc
, "no-export", &idx
)) {
8888 if (argv_find(argv
, argc
, "exact_match", &idx
))
8890 return bgp_show_community(vty
, bgp
, argc
, argv
,
8891 exact_match
, afi
, safi
);
8893 /* show all communities */
8895 return bgp_show(vty
, bgp
, afi
, safi
,
8896 bgp_show_type_community_all
, NULL
, uj
);
8899 if (argv_find(argv
, argc
, "community-list", &idx
)) {
8900 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8901 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
8903 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
8904 exact_match
, afi
, safi
);
8907 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
8908 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8909 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
8911 bgp_show_type_prefix_longer
);
8913 if (safi
== SAFI_MPLS_VPN
)
8914 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
8917 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8920 DEFUN (show_ip_bgp_route
,
8921 show_ip_bgp_route_cmd
,
8922 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
8923 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8927 BGP_INSTANCE_HELP_STR
8929 BGP_SAFI_WITH_LABEL_HELP_STR
8930 "Network in the BGP routing table to display\n"
8932 "Network in the BGP routing table to display\n"
8934 "Display only the bestpath\n"
8935 "Display only multipaths\n"
8938 int prefix_check
= 0;
8940 afi_t afi
= AFI_IP6
;
8941 safi_t safi
= SAFI_UNICAST
;
8942 char *prefix
= NULL
;
8943 struct bgp
*bgp
= NULL
;
8944 enum bgp_path_type path_type
;
8945 u_char uj
= use_json(argc
, argv
);
8949 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8956 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
8960 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8961 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
8962 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
8964 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
8965 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8968 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
8969 && afi
!= AFI_IP6
) {
8971 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
8974 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
8977 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
8981 prefix
= argv
[idx
]->arg
;
8983 /* [<bestpath|multipath>] */
8984 if (argv_find(argv
, argc
, "bestpath", &idx
))
8985 path_type
= BGP_PATH_BESTPATH
;
8986 else if (argv_find(argv
, argc
, "multipath", &idx
))
8987 path_type
= BGP_PATH_MULTIPATH
;
8989 path_type
= BGP_PATH_ALL
;
8991 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
8995 DEFUN (show_ip_bgp_regexp
,
8996 show_ip_bgp_regexp_cmd
,
8997 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9001 BGP_INSTANCE_HELP_STR
9003 BGP_SAFI_WITH_LABEL_HELP_STR
9004 "Display routes matching the AS path regular expression\n"
9005 "A regular-expression to match the BGP AS paths\n")
9007 afi_t afi
= AFI_IP6
;
9008 safi_t safi
= SAFI_UNICAST
;
9009 struct bgp
*bgp
= NULL
;
9012 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9017 // get index of regex
9018 argv_find(argv
, argc
, "regexp", &idx
);
9021 char *regstr
= argv_concat(argv
, argc
, idx
);
9022 int rc
= bgp_show_regexp(vty
, (const char *)regstr
, afi
, safi
,
9023 bgp_show_type_regexp
);
9024 XFREE(MTYPE_TMP
, regstr
);
9028 DEFUN (show_ip_bgp_instance_all
,
9029 show_ip_bgp_instance_all_cmd
,
9030 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9034 BGP_INSTANCE_ALL_HELP_STR
9036 BGP_SAFI_WITH_LABEL_HELP_STR
9040 safi_t safi
= SAFI_UNICAST
;
9041 struct bgp
*bgp
= NULL
;
9044 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9049 int uj
= use_json(argc
, argv
);
9053 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9057 static int bgp_show_regexp(struct vty
*vty
, const char *regstr
, afi_t afi
,
9058 safi_t safi
, enum bgp_show_type type
)
9063 regex
= bgp_regcomp(regstr
);
9065 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9069 rc
= bgp_show(vty
, NULL
, afi
, safi
, type
, regex
, 0);
9070 bgp_regex_free(regex
);
9074 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9075 const char *prefix_list_str
, afi_t afi
,
9076 safi_t safi
, enum bgp_show_type type
)
9078 struct prefix_list
*plist
;
9080 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9081 if (plist
== NULL
) {
9082 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9087 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9090 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9091 const char *filter
, afi_t afi
, safi_t safi
,
9092 enum bgp_show_type type
)
9094 struct as_list
*as_list
;
9096 as_list
= as_list_lookup(filter
);
9097 if (as_list
== NULL
) {
9098 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9103 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9106 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9107 const char *rmap_str
, afi_t afi
, safi_t safi
,
9108 enum bgp_show_type type
)
9110 struct route_map
*rmap
;
9112 rmap
= route_map_lookup_by_name(rmap_str
);
9114 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9118 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9121 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
, int argc
,
9122 struct cmd_token
**argv
, int exact
, afi_t afi
,
9125 struct community
*com
;
9132 b
= buffer_new(1024);
9133 for (i
= 0; i
< argc
; i
++) {
9135 buffer_putc(b
, ' ');
9137 if (strmatch(argv
[i
]->text
, "unicast")
9138 || strmatch(argv
[i
]->text
, "multicast"))
9143 buffer_putstr(b
, argv
[i
]->arg
);
9145 buffer_putc(b
, '\0');
9147 str
= buffer_getstr(b
);
9150 com
= community_str2com(str
);
9151 XFREE(MTYPE_TMP
, str
);
9153 vty_out(vty
, "%% Community malformed: \n");
9157 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9158 (exact
? bgp_show_type_community_exact
9159 : bgp_show_type_community
),
9161 community_free(com
);
9166 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9167 const char *com
, int exact
, afi_t afi
,
9170 struct community_list
*list
;
9172 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9174 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9178 return bgp_show(vty
, bgp
, afi
, safi
,
9179 (exact
? bgp_show_type_community_list_exact
9180 : bgp_show_type_community_list
),
9184 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9185 const char *prefix
, afi_t afi
, safi_t safi
,
9186 enum bgp_show_type type
)
9193 ret
= str2prefix(prefix
, p
);
9195 vty_out(vty
, "%% Malformed Prefix\n");
9199 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9204 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9205 const char *ip_str
, u_char use_json
)
9211 /* Get peer sockunion. */
9212 ret
= str2sockunion(ip_str
, &su
);
9214 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9216 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9220 json_object
*json_no
= NULL
;
9221 json_no
= json_object_new_object();
9222 json_object_string_add(
9224 "malformedAddressOrName",
9226 vty_out(vty
, "%s\n",
9227 json_object_to_json_string(
9229 json_object_free(json_no
);
9232 "%% Malformed address or name: %s\n",
9240 /* Peer structure lookup. */
9241 peer
= peer_lookup(bgp
, &su
);
9244 json_object
*json_no
= NULL
;
9245 json_no
= json_object_new_object();
9246 json_object_string_add(json_no
, "warning",
9247 "No such neighbor");
9248 vty_out(vty
, "%s\n",
9249 json_object_to_json_string(json_no
));
9250 json_object_free(json_no
);
9252 vty_out(vty
, "No such neighbor\n");
9260 BGP_STATS_MAXBITLEN
= 0,
9264 BGP_STATS_UNAGGREGATEABLE
,
9265 BGP_STATS_MAX_AGGREGATEABLE
,
9266 BGP_STATS_AGGREGATES
,
9268 BGP_STATS_ASPATH_COUNT
,
9269 BGP_STATS_ASPATH_MAXHOPS
,
9270 BGP_STATS_ASPATH_TOTHOPS
,
9271 BGP_STATS_ASPATH_MAXSIZE
,
9272 BGP_STATS_ASPATH_TOTSIZE
,
9273 BGP_STATS_ASN_HIGHEST
,
9277 static const char *table_stats_strs
[] = {
9278 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9279 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9280 [BGP_STATS_RIB
] = "Total Advertisements",
9281 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9282 [BGP_STATS_MAX_AGGREGATEABLE
] =
9283 "Maximum aggregateable prefixes",
9284 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9285 [BGP_STATS_SPACE
] = "Address space advertised",
9286 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9287 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9288 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9289 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9290 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9291 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9292 [BGP_STATS_MAX
] = NULL
,
9295 struct bgp_table_stats
{
9296 struct bgp_table
*table
;
9297 unsigned long long counts
[BGP_STATS_MAX
];
9301 #define TALLY_SIGFIG 100000
9302 static unsigned long
9303 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9305 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9306 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9307 unsigned long ret
= newtot
/ count
;
9309 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9316 static int bgp_table_stats_walker(struct thread
*t
)
9318 struct bgp_node
*rn
;
9319 struct bgp_node
*top
;
9320 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9321 unsigned int space
= 0;
9323 if (!(top
= bgp_table_top(ts
->table
)))
9326 switch (top
->p
.family
) {
9328 space
= IPV4_MAX_BITLEN
;
9331 space
= IPV6_MAX_BITLEN
;
9335 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9337 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9338 struct bgp_info
*ri
;
9339 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9340 unsigned int rinum
= 0;
9348 ts
->counts
[BGP_STATS_PREFIXES
]++;
9349 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9352 ts
->counts
[BGP_STATS_AVGPLEN
]
9353 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9354 ts
->counts
[BGP_STATS_AVGPLEN
],
9358 /* check if the prefix is included by any other announcements */
9359 while (prn
&& !prn
->info
)
9360 prn
= bgp_node_parent_nolock(prn
);
9362 if (prn
== NULL
|| prn
== top
) {
9363 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9364 /* announced address space */
9366 ts
->counts
[BGP_STATS_SPACE
] +=
9367 1 << (space
- rn
->p
.prefixlen
);
9368 } else if (prn
->info
)
9369 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9371 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9373 ts
->counts
[BGP_STATS_RIB
]++;
9376 && (CHECK_FLAG(ri
->attr
->flag
,
9378 BGP_ATTR_ATOMIC_AGGREGATE
))))
9379 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9382 if (ri
->attr
&& ri
->attr
->aspath
) {
9384 aspath_count_hops(ri
->attr
->aspath
);
9386 aspath_size(ri
->attr
->aspath
);
9387 as_t highest
= aspath_highest(ri
->attr
->aspath
);
9389 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9391 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9392 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9395 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9396 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9399 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9400 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9402 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9403 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9404 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9406 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9407 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9408 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9411 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9412 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
9420 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9423 struct bgp_table_stats ts
;
9426 if (!bgp
->rib
[afi
][safi
]) {
9427 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9432 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
9434 /* labeled-unicast routes live in the unicast table */
9435 if (safi
== SAFI_LABELED_UNICAST
)
9436 safi
= SAFI_UNICAST
;
9438 memset(&ts
, 0, sizeof(ts
));
9439 ts
.table
= bgp
->rib
[afi
][safi
];
9440 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9442 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
9443 if (!table_stats_strs
[i
])
9448 case BGP_STATS_ASPATH_AVGHOPS
:
9449 case BGP_STATS_ASPATH_AVGSIZE
:
9450 case BGP_STATS_AVGPLEN
:
9451 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9452 vty_out (vty
, "%12.2f",
9453 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9456 case BGP_STATS_ASPATH_TOTHOPS
:
9457 case BGP_STATS_ASPATH_TOTSIZE
:
9458 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9459 vty_out(vty
, "%12.2f",
9461 ? (float)ts
.counts
[i
]
9463 [BGP_STATS_ASPATH_COUNT
]
9466 case BGP_STATS_TOTPLEN
:
9467 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9468 vty_out(vty
, "%12.2f",
9470 ? (float)ts
.counts
[i
]
9472 [BGP_STATS_PREFIXES
]
9475 case BGP_STATS_SPACE
:
9476 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9477 vty_out(vty
, "%12llu\n", ts
.counts
[i
]);
9478 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9480 vty_out(vty
, "%30s: ", "%% announced ");
9481 vty_out(vty
, "%12.2f\n",
9482 100 * (float)ts
.counts
[BGP_STATS_SPACE
]
9483 / (float)((uint64_t)1UL
9485 [BGP_STATS_MAXBITLEN
]));
9486 vty_out(vty
, "%30s: ", "/8 equivalent ");
9487 vty_out(vty
, "%12.2f\n",
9488 (float)ts
.counts
[BGP_STATS_SPACE
]
9491 [BGP_STATS_MAXBITLEN
]
9493 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9495 vty_out(vty
, "%30s: ", "/24 equivalent ");
9496 vty_out(vty
, "%12.2f",
9497 (float)ts
.counts
[BGP_STATS_SPACE
]
9500 [BGP_STATS_MAXBITLEN
]
9504 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9505 vty_out(vty
, "%12llu", ts
.counts
[i
]);
9522 PCOUNT_PFCNT
, /* the figure we display to users */
9526 static const char *pcount_strs
[] = {
9527 [PCOUNT_ADJ_IN
] = "Adj-in",
9528 [PCOUNT_DAMPED
] = "Damped",
9529 [PCOUNT_REMOVED
] = "Removed",
9530 [PCOUNT_HISTORY
] = "History",
9531 [PCOUNT_STALE
] = "Stale",
9532 [PCOUNT_VALID
] = "Valid",
9533 [PCOUNT_ALL
] = "All RIB",
9534 [PCOUNT_COUNTED
] = "PfxCt counted",
9535 [PCOUNT_PFCNT
] = "Useable",
9536 [PCOUNT_MAX
] = NULL
,
9539 struct peer_pcounts
{
9540 unsigned int count
[PCOUNT_MAX
];
9541 const struct peer
*peer
;
9542 const struct bgp_table
*table
;
9545 static int bgp_peer_count_walker(struct thread
*t
)
9547 struct bgp_node
*rn
;
9548 struct peer_pcounts
*pc
= THREAD_ARG(t
);
9549 const struct peer
*peer
= pc
->peer
;
9551 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
9552 struct bgp_adj_in
*ain
;
9553 struct bgp_info
*ri
;
9555 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9556 if (ain
->peer
== peer
)
9557 pc
->count
[PCOUNT_ADJ_IN
]++;
9559 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9560 char buf
[SU_ADDRSTRLEN
];
9562 if (ri
->peer
!= peer
)
9565 pc
->count
[PCOUNT_ALL
]++;
9567 if (CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
))
9568 pc
->count
[PCOUNT_DAMPED
]++;
9569 if (CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
9570 pc
->count
[PCOUNT_HISTORY
]++;
9571 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
9572 pc
->count
[PCOUNT_REMOVED
]++;
9573 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
9574 pc
->count
[PCOUNT_STALE
]++;
9575 if (CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
))
9576 pc
->count
[PCOUNT_VALID
]++;
9577 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9578 pc
->count
[PCOUNT_PFCNT
]++;
9580 if (CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
9581 pc
->count
[PCOUNT_COUNTED
]++;
9582 if (CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9584 "%s [pcount] %s/%d is counted but flags 0x%x",
9586 inet_ntop(rn
->p
.family
,
9587 &rn
->p
.u
.prefix
, buf
,
9589 rn
->p
.prefixlen
, ri
->flags
);
9591 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9593 "%s [pcount] %s/%d not counted but flags 0x%x",
9595 inet_ntop(rn
->p
.family
,
9596 &rn
->p
.u
.prefix
, buf
,
9598 rn
->p
.prefixlen
, ri
->flags
);
9605 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9606 safi_t safi
, u_char use_json
)
9608 struct peer_pcounts pcounts
= {.peer
= peer
};
9610 json_object
*json
= NULL
;
9611 json_object
*json_loop
= NULL
;
9614 json
= json_object_new_object();
9615 json_loop
= json_object_new_object();
9618 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9619 || !peer
->bgp
->rib
[afi
][safi
]) {
9621 json_object_string_add(
9623 "No such neighbor or address family");
9624 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9625 json_object_free(json
);
9627 vty_out(vty
, "%% No such neighbor or address family\n");
9632 memset(&pcounts
, 0, sizeof(pcounts
));
9633 pcounts
.peer
= peer
;
9634 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9636 /* in-place call via thread subsystem so as to record execution time
9637 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9638 * * on just vty_read()).
9640 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9643 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9644 json_object_string_add(json
, "multiProtocol",
9645 afi_safi_print(afi
, safi
));
9646 json_object_int_add(json
, "pfxCounter",
9647 peer
->pcount
[afi
][safi
]);
9649 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9650 json_object_int_add(json_loop
, pcount_strs
[i
],
9653 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9655 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9656 json_object_string_add(json
, "pfxctDriftFor",
9658 json_object_string_add(
9659 json
, "recommended",
9660 "Please report this bug, with the above command output");
9662 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9663 json_object_free(json
);
9667 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
9668 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
9669 peer
->hostname
, peer
->host
,
9670 afi_safi_print(afi
, safi
));
9672 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
9673 afi_safi_print(afi
, safi
));
9676 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9677 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
9679 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9680 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
9683 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9684 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
9686 "Please report this bug, with the above command output\n");
9693 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9694 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9695 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9696 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9700 BGP_INSTANCE_HELP_STR
9703 "Detailed information on TCP and BGP neighbor connections\n"
9704 "Neighbor to display information about\n"
9705 "Neighbor to display information about\n"
9706 "Neighbor on BGP configured interface\n"
9707 "Display detailed prefix count information\n"
9710 afi_t afi
= AFI_IP6
;
9711 safi_t safi
= SAFI_UNICAST
;
9714 struct bgp
*bgp
= NULL
;
9716 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9721 int uj
= use_json(argc
, argv
);
9725 argv_find(argv
, argc
, "neighbors", &idx
);
9726 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
9730 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9733 #ifdef KEEP_OLD_VPN_COMMANDS
9734 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9735 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9736 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9741 "Display information about all VPNv4 NLRIs\n"
9742 "Detailed information on TCP and BGP neighbor connections\n"
9743 "Neighbor to display information about\n"
9744 "Neighbor to display information about\n"
9745 "Neighbor on BGP configured interface\n"
9746 "Display detailed prefix count information\n"
9751 u_char uj
= use_json(argc
, argv
);
9753 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9757 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9760 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9761 show_ip_bgp_vpn_all_route_prefix_cmd
,
9762 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9767 "Display information about all VPNv4 NLRIs\n"
9768 "Network in the BGP routing table to display\n"
9769 "Network in the BGP routing table to display\n"
9773 char *network
= NULL
;
9774 struct bgp
*bgp
= bgp_get_default();
9776 vty_out(vty
, "Can't find default instance\n");
9780 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9781 network
= argv
[idx
]->arg
;
9782 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9783 network
= argv
[idx
]->arg
;
9785 vty_out(vty
, "Unable to figure out Network\n");
9789 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
9790 BGP_PATH_ALL
, use_json(argc
, argv
));
9792 #endif /* KEEP_OLD_VPN_COMMANDS */
9794 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9795 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9796 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9802 "Display information about all EVPN NLRIs\n"
9803 "Network in the BGP routing table to display\n"
9804 "Network in the BGP routing table to display\n"
9808 char *network
= NULL
;
9810 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9811 network
= argv
[idx
]->arg
;
9812 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9813 network
= argv
[idx
]->arg
;
9815 vty_out(vty
, "Unable to figure out Network\n");
9818 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
9819 BGP_PATH_ALL
, use_json(argc
, argv
));
9822 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9823 safi_t safi
, int in
, const char *rmap_name
,
9824 u_char use_json
, json_object
*json
)
9826 struct bgp_table
*table
;
9827 struct bgp_adj_in
*ain
;
9828 struct bgp_adj_out
*adj
;
9829 unsigned long output_count
;
9830 unsigned long filtered_count
;
9831 struct bgp_node
*rn
;
9837 struct update_subgroup
*subgrp
;
9838 json_object
*json_scode
= NULL
;
9839 json_object
*json_ocode
= NULL
;
9840 json_object
*json_ar
= NULL
;
9841 struct peer_af
*paf
;
9844 json_scode
= json_object_new_object();
9845 json_ocode
= json_object_new_object();
9846 json_ar
= json_object_new_object();
9848 json_object_string_add(json_scode
, "suppressed", "s");
9849 json_object_string_add(json_scode
, "damped", "d");
9850 json_object_string_add(json_scode
, "history", "h");
9851 json_object_string_add(json_scode
, "valid", "*");
9852 json_object_string_add(json_scode
, "best", ">");
9853 json_object_string_add(json_scode
, "multipath", "=");
9854 json_object_string_add(json_scode
, "internal", "i");
9855 json_object_string_add(json_scode
, "ribFailure", "r");
9856 json_object_string_add(json_scode
, "stale", "S");
9857 json_object_string_add(json_scode
, "removed", "R");
9859 json_object_string_add(json_ocode
, "igp", "i");
9860 json_object_string_add(json_ocode
, "egp", "e");
9861 json_object_string_add(json_ocode
, "incomplete", "?");
9868 json_object_string_add(json
, "alert", "no BGP");
9869 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9870 json_object_free(json
);
9872 vty_out(vty
, "%% No bgp\n");
9876 table
= bgp
->rib
[afi
][safi
];
9878 output_count
= filtered_count
= 0;
9879 subgrp
= peer_subgroup(peer
, afi
, safi
);
9882 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
9884 json_object_int_add(json
, "bgpTableVersion",
9886 json_object_string_add(json
, "bgpLocalRouterId",
9887 inet_ntoa(bgp
->router_id
));
9888 json_object_object_add(json
, "bgpStatusCodes",
9890 json_object_object_add(json
, "bgpOriginCodes",
9892 json_object_string_add(json
,
9893 "bgpOriginatingDefaultNetwork",
9896 vty_out(vty
, "BGP table version is %" PRIu64
9897 ", local router ID is %s\n",
9898 table
->version
, inet_ntoa(bgp
->router_id
));
9899 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
9900 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
9902 vty_out(vty
, "Originating default network 0.0.0.0\n\n");
9907 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
9909 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
9910 if (ain
->peer
== peer
) {
9913 json_object_int_add(
9917 json_object_string_add(
9922 json_object_object_add(
9926 json_object_object_add(
9932 "BGP table version is 0, local router ID is %s\n",
9936 BGP_SHOW_SCODE_HEADER
);
9938 BGP_SHOW_OCODE_HEADER
);
9949 bgp_attr_dup(&attr
, ain
->attr
);
9950 if (bgp_input_modifier(
9951 peer
, &rn
->p
, &attr
,
9967 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9968 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9969 if (paf
->peer
== peer
) {
9972 json_object_int_add(
9973 json
, "bgpTableVersion",
9975 json_object_string_add(
9980 json_object_object_add(
9981 json
, "bgpStatusCodes",
9983 json_object_object_add(
9984 json
, "bgpOriginCodes",
9988 "BGP table version is %" PRIu64
9989 ", local router ID is %s\n",
9994 BGP_SHOW_SCODE_HEADER
);
9996 BGP_SHOW_OCODE_HEADER
);
10003 vty_out(vty
, BGP_SHOW_HEADER
);
10008 bgp_attr_dup(&attr
, adj
->attr
);
10009 ret
= bgp_output_modifier(
10010 peer
, &rn
->p
, &attr
, afi
, safi
,
10012 if (ret
!= RMAP_DENY
) {
10013 route_vty_out_tmp(vty
, &rn
->p
,
10025 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10027 if (output_count
!= 0) {
10029 json_object_int_add(json
, "totalPrefixCounter",
10032 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10036 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10037 json_object_free(json
);
10041 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10042 safi_t safi
, int in
, const char *rmap_name
,
10045 json_object
*json
= NULL
;
10048 json
= json_object_new_object();
10050 /* labeled-unicast routes live in the unicast table */
10051 if (safi
== SAFI_LABELED_UNICAST
)
10052 safi
= SAFI_UNICAST
;
10054 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10056 json_object_string_add(
10058 "No such neighbor or address family");
10059 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10060 json_object_free(json
);
10062 vty_out(vty
, "%% No such neighbor or address family\n");
10064 return CMD_WARNING
;
10068 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10069 PEER_FLAG_SOFT_RECONFIG
)) {
10071 json_object_string_add(
10073 "Inbound soft reconfiguration not enabled");
10074 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10075 json_object_free(json
);
10078 "%% Inbound soft reconfiguration not enabled\n");
10080 return CMD_WARNING
;
10083 show_adj_route(vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10085 return CMD_SUCCESS
;
10088 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10089 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10090 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10091 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10095 BGP_INSTANCE_HELP_STR
10097 BGP_SAFI_WITH_LABEL_HELP_STR
10098 "Detailed information on TCP and BGP neighbor connections\n"
10099 "Neighbor to display information about\n"
10100 "Neighbor to display information about\n"
10101 "Neighbor on BGP configured interface\n"
10102 "Display the received routes from neighbor\n"
10103 "Display the routes advertised to a BGP neighbor\n"
10104 "Route-map to modify the attributes\n"
10105 "Name of the route map\n"
10108 afi_t afi
= AFI_IP6
;
10109 safi_t safi
= SAFI_UNICAST
;
10110 char *rmap_name
= NULL
;
10111 char *peerstr
= NULL
;
10113 struct bgp
*bgp
= NULL
;
10118 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10121 return CMD_WARNING
;
10123 int uj
= use_json(argc
, argv
);
10127 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10128 argv_find(argv
, argc
, "neighbors", &idx
);
10129 peerstr
= argv
[++idx
]->arg
;
10131 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10133 return CMD_WARNING
;
10135 if (argv_find(argv
, argc
, "received-routes", &idx
))
10137 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10139 if (argv_find(argv
, argc
, "route-map", &idx
))
10140 rmap_name
= argv
[++idx
]->arg
;
10142 return peer_adj_routes(vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10145 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10146 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10147 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10153 "Address Family modifier\n"
10154 "Detailed information on TCP and BGP neighbor connections\n"
10155 "Neighbor to display information about\n"
10156 "Neighbor to display information about\n"
10157 "Neighbor on BGP configured interface\n"
10158 "Display information received from a BGP neighbor\n"
10159 "Display the prefixlist filter\n"
10162 afi_t afi
= AFI_IP6
;
10163 safi_t safi
= SAFI_UNICAST
;
10164 char *peerstr
= NULL
;
10167 union sockunion su
;
10173 /* show [ip] bgp */
10174 if (argv_find(argv
, argc
, "ip", &idx
))
10176 /* [<ipv4|ipv6> [unicast]] */
10177 if (argv_find(argv
, argc
, "ipv4", &idx
))
10179 if (argv_find(argv
, argc
, "ipv6", &idx
))
10181 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10182 argv_find(argv
, argc
, "neighbors", &idx
);
10183 peerstr
= argv
[++idx
]->arg
;
10185 u_char uj
= use_json(argc
, argv
);
10187 ret
= str2sockunion(peerstr
, &su
);
10189 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10192 vty_out(vty
, "{}\n");
10195 "%% Malformed address or name: %s\n",
10197 return CMD_WARNING
;
10200 peer
= peer_lookup(NULL
, &su
);
10203 vty_out(vty
, "{}\n");
10205 vty_out(vty
, "No peer\n");
10206 return CMD_WARNING
;
10210 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10211 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10214 vty_out(vty
, "Address Family: %s\n",
10215 afi_safi_print(afi
, safi
));
10216 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10219 vty_out(vty
, "{}\n");
10221 vty_out(vty
, "No functional output\n");
10224 return CMD_SUCCESS
;
10227 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10228 afi_t afi
, safi_t safi
,
10229 enum bgp_show_type type
, u_char use_json
)
10231 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10233 json_object
*json_no
= NULL
;
10234 json_no
= json_object_new_object();
10235 json_object_string_add(
10236 json_no
, "warning",
10237 "No such neighbor or address family");
10238 vty_out(vty
, "%s\n",
10239 json_object_to_json_string(json_no
));
10240 json_object_free(json_no
);
10242 vty_out(vty
, "%% No such neighbor or address family\n");
10243 return CMD_WARNING
;
10246 /* labeled-unicast routes live in the unicast table */
10247 if (safi
== SAFI_LABELED_UNICAST
)
10248 safi
= SAFI_UNICAST
;
10250 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10253 DEFUN (show_ip_bgp_neighbor_routes
,
10254 show_ip_bgp_neighbor_routes_cmd
,
10255 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10256 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10260 BGP_INSTANCE_HELP_STR
10262 BGP_SAFI_WITH_LABEL_HELP_STR
10263 "Detailed information on TCP and BGP neighbor connections\n"
10264 "Neighbor to display information about\n"
10265 "Neighbor to display information about\n"
10266 "Neighbor on BGP configured interface\n"
10267 "Display flap statistics of the routes learned from neighbor\n"
10268 "Display the dampened routes received from neighbor\n"
10269 "Display routes learned from neighbor\n"
10272 char *peerstr
= NULL
;
10273 struct bgp
*bgp
= NULL
;
10274 afi_t afi
= AFI_IP6
;
10275 safi_t safi
= SAFI_UNICAST
;
10277 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10281 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10284 return CMD_WARNING
;
10286 int uj
= use_json(argc
, argv
);
10290 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10291 argv_find(argv
, argc
, "neighbors", &idx
);
10292 peerstr
= argv
[++idx
]->arg
;
10294 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10296 vty_out(vty
, "No such neighbor\n");
10297 return CMD_WARNING
;
10300 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10301 sh_type
= bgp_show_type_flap_neighbor
;
10302 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10303 sh_type
= bgp_show_type_damp_neighbor
;
10304 else if (argv_find(argv
, argc
, "routes", &idx
))
10305 sh_type
= bgp_show_type_neighbor
;
10307 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10310 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10312 struct bgp_distance
{
10313 /* Distance value for the IP source prefix. */
10316 /* Name of the access-list to be matched. */
10320 DEFUN (show_bgp_afi_vpn_rd_route
,
10321 show_bgp_afi_vpn_rd_route_cmd
,
10322 "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]",
10326 "Address Family modifier\n"
10327 "Display information for a route distinguisher\n"
10328 "Route Distinguisher\n"
10329 "Network in the BGP routing table to display\n"
10330 "Network in the BGP routing table to display\n"
10334 struct prefix_rd prd
;
10335 afi_t afi
= AFI_MAX
;
10338 argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
);
10339 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10341 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10342 return CMD_WARNING
;
10344 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10345 0, BGP_PATH_ALL
, use_json(argc
, argv
));
10348 static struct bgp_distance
*bgp_distance_new(void)
10350 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
10353 static void bgp_distance_free(struct bgp_distance
*bdistance
)
10355 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
10358 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
10359 const char *ip_str
, const char *access_list_str
)
10366 struct bgp_node
*rn
;
10367 struct bgp_distance
*bdistance
;
10369 afi
= bgp_node_afi(vty
);
10370 safi
= bgp_node_safi(vty
);
10372 ret
= str2prefix(ip_str
, &p
);
10374 vty_out(vty
, "Malformed prefix\n");
10375 return CMD_WARNING_CONFIG_FAILED
;
10378 distance
= atoi(distance_str
);
10380 /* Get BGP distance node. */
10381 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10383 bdistance
= rn
->info
;
10384 bgp_unlock_node(rn
);
10386 bdistance
= bgp_distance_new();
10387 rn
->info
= bdistance
;
10390 /* Set distance value. */
10391 bdistance
->distance
= distance
;
10393 /* Reset access-list configuration. */
10394 if (bdistance
->access_list
) {
10395 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10396 bdistance
->access_list
= NULL
;
10398 if (access_list_str
)
10399 bdistance
->access_list
=
10400 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10402 return CMD_SUCCESS
;
10405 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
10406 const char *ip_str
, const char *access_list_str
)
10413 struct bgp_node
*rn
;
10414 struct bgp_distance
*bdistance
;
10416 afi
= bgp_node_afi(vty
);
10417 safi
= bgp_node_safi(vty
);
10419 ret
= str2prefix(ip_str
, &p
);
10421 vty_out(vty
, "Malformed prefix\n");
10422 return CMD_WARNING_CONFIG_FAILED
;
10425 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
10426 (struct prefix
*)&p
);
10428 vty_out(vty
, "Can't find specified prefix\n");
10429 return CMD_WARNING_CONFIG_FAILED
;
10432 bdistance
= rn
->info
;
10433 distance
= atoi(distance_str
);
10435 if (bdistance
->distance
!= distance
) {
10436 vty_out(vty
, "Distance does not match configured\n");
10437 return CMD_WARNING_CONFIG_FAILED
;
10440 if (bdistance
->access_list
)
10441 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10442 bgp_distance_free(bdistance
);
10445 bgp_unlock_node(rn
);
10446 bgp_unlock_node(rn
);
10448 return CMD_SUCCESS
;
10451 /* Apply BGP information to distance method. */
10452 u_char
bgp_distance_apply(struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10453 safi_t safi
, struct bgp
*bgp
)
10455 struct bgp_node
*rn
;
10458 struct bgp_distance
*bdistance
;
10459 struct access_list
*alist
;
10460 struct bgp_static
*bgp_static
;
10465 peer
= rinfo
->peer
;
10467 /* Check source address. */
10468 sockunion2hostprefix(&peer
->su
, &q
);
10469 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
10471 bdistance
= rn
->info
;
10472 bgp_unlock_node(rn
);
10474 if (bdistance
->access_list
) {
10475 alist
= access_list_lookup(afi
, bdistance
->access_list
);
10477 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
10478 return bdistance
->distance
;
10480 return bdistance
->distance
;
10483 /* Backdoor check. */
10484 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
10486 bgp_static
= rn
->info
;
10487 bgp_unlock_node(rn
);
10489 if (bgp_static
->backdoor
) {
10490 if (bgp
->distance_local
[afi
][safi
])
10491 return bgp
->distance_local
[afi
][safi
];
10493 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10497 if (peer
->sort
== BGP_PEER_EBGP
) {
10498 if (bgp
->distance_ebgp
[afi
][safi
])
10499 return bgp
->distance_ebgp
[afi
][safi
];
10500 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10502 if (bgp
->distance_ibgp
[afi
][safi
])
10503 return bgp
->distance_ibgp
[afi
][safi
];
10504 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10508 DEFUN (bgp_distance
,
10510 "distance bgp (1-255) (1-255) (1-255)",
10511 "Define an administrative distance\n"
10513 "Distance for routes external to the AS\n"
10514 "Distance for routes internal to the AS\n"
10515 "Distance for local routes\n")
10517 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10518 int idx_number
= 2;
10519 int idx_number_2
= 3;
10520 int idx_number_3
= 4;
10524 afi
= bgp_node_afi(vty
);
10525 safi
= bgp_node_safi(vty
);
10527 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
10528 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
10529 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
10530 return CMD_SUCCESS
;
10533 DEFUN (no_bgp_distance
,
10534 no_bgp_distance_cmd
,
10535 "no distance bgp [(1-255) (1-255) (1-255)]",
10537 "Define an administrative distance\n"
10539 "Distance for routes external to the AS\n"
10540 "Distance for routes internal to the AS\n"
10541 "Distance for local routes\n")
10543 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10547 afi
= bgp_node_afi(vty
);
10548 safi
= bgp_node_safi(vty
);
10550 bgp
->distance_ebgp
[afi
][safi
] = 0;
10551 bgp
->distance_ibgp
[afi
][safi
] = 0;
10552 bgp
->distance_local
[afi
][safi
] = 0;
10553 return CMD_SUCCESS
;
10557 DEFUN (bgp_distance_source
,
10558 bgp_distance_source_cmd
,
10559 "distance (1-255) A.B.C.D/M",
10560 "Define an administrative distance\n"
10561 "Administrative distance\n"
10562 "IP source prefix\n")
10564 int idx_number
= 1;
10565 int idx_ipv4_prefixlen
= 2;
10566 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10567 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10568 return CMD_SUCCESS
;
10571 DEFUN (no_bgp_distance_source
,
10572 no_bgp_distance_source_cmd
,
10573 "no distance (1-255) A.B.C.D/M",
10575 "Define an administrative distance\n"
10576 "Administrative distance\n"
10577 "IP source prefix\n")
10579 int idx_number
= 2;
10580 int idx_ipv4_prefixlen
= 3;
10581 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10582 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10583 return CMD_SUCCESS
;
10586 DEFUN (bgp_distance_source_access_list
,
10587 bgp_distance_source_access_list_cmd
,
10588 "distance (1-255) A.B.C.D/M WORD",
10589 "Define an administrative distance\n"
10590 "Administrative distance\n"
10591 "IP source prefix\n"
10592 "Access list name\n")
10594 int idx_number
= 1;
10595 int idx_ipv4_prefixlen
= 2;
10597 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10598 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10599 return CMD_SUCCESS
;
10602 DEFUN (no_bgp_distance_source_access_list
,
10603 no_bgp_distance_source_access_list_cmd
,
10604 "no distance (1-255) A.B.C.D/M WORD",
10606 "Define an administrative distance\n"
10607 "Administrative distance\n"
10608 "IP source prefix\n"
10609 "Access list name\n")
10611 int idx_number
= 2;
10612 int idx_ipv4_prefixlen
= 3;
10614 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10615 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10616 return CMD_SUCCESS
;
10619 DEFUN (ipv6_bgp_distance_source
,
10620 ipv6_bgp_distance_source_cmd
,
10621 "distance (1-255) X:X::X:X/M",
10622 "Define an administrative distance\n"
10623 "Administrative distance\n"
10624 "IP source prefix\n")
10626 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10627 return CMD_SUCCESS
;
10630 DEFUN (no_ipv6_bgp_distance_source
,
10631 no_ipv6_bgp_distance_source_cmd
,
10632 "no distance (1-255) X:X::X:X/M",
10634 "Define an administrative distance\n"
10635 "Administrative distance\n"
10636 "IP source prefix\n")
10638 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10639 return CMD_SUCCESS
;
10642 DEFUN (ipv6_bgp_distance_source_access_list
,
10643 ipv6_bgp_distance_source_access_list_cmd
,
10644 "distance (1-255) X:X::X:X/M WORD",
10645 "Define an administrative distance\n"
10646 "Administrative distance\n"
10647 "IP source prefix\n"
10648 "Access list name\n")
10650 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10651 return CMD_SUCCESS
;
10654 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10655 no_ipv6_bgp_distance_source_access_list_cmd
,
10656 "no distance (1-255) X:X::X:X/M WORD",
10658 "Define an administrative distance\n"
10659 "Administrative distance\n"
10660 "IP source prefix\n"
10661 "Access list name\n")
10663 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10664 return CMD_SUCCESS
;
10667 DEFUN (bgp_damp_set
,
10669 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10670 "BGP Specific commands\n"
10671 "Enable route-flap dampening\n"
10672 "Half-life time for the penalty\n"
10673 "Value to start reusing a route\n"
10674 "Value to start suppressing a route\n"
10675 "Maximum duration to suppress a stable route\n")
10677 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10678 int idx_half_life
= 2;
10680 int idx_suppress
= 4;
10681 int idx_max_suppress
= 5;
10682 int half
= DEFAULT_HALF_LIFE
* 60;
10683 int reuse
= DEFAULT_REUSE
;
10684 int suppress
= DEFAULT_SUPPRESS
;
10685 int max
= 4 * half
;
10688 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10689 reuse
= atoi(argv
[idx_reuse
]->arg
);
10690 suppress
= atoi(argv
[idx_suppress
]->arg
);
10691 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
10692 } else if (argc
== 3) {
10693 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10697 if (suppress
< reuse
) {
10699 "Suppress value cannot be less than reuse value \n");
10703 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
10704 reuse
, suppress
, max
);
10707 DEFUN (bgp_damp_unset
,
10708 bgp_damp_unset_cmd
,
10709 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10711 "BGP Specific commands\n"
10712 "Enable route-flap dampening\n"
10713 "Half-life time for the penalty\n"
10714 "Value to start reusing a route\n"
10715 "Value to start suppressing a route\n"
10716 "Maximum duration to suppress a stable route\n")
10718 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10719 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
10722 /* Display specified route of BGP table. */
10723 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
10724 const char *ip_str
, afi_t afi
, safi_t safi
,
10725 struct prefix_rd
*prd
, int prefix_check
)
10728 struct prefix match
;
10729 struct bgp_node
*rn
;
10730 struct bgp_node
*rm
;
10731 struct bgp_info
*ri
;
10732 struct bgp_info
*ri_temp
;
10734 struct bgp_table
*table
;
10736 /* BGP structure lookup. */
10738 bgp
= bgp_lookup_by_name(view_name
);
10740 vty_out(vty
, "%% Can't find BGP instance %s\n",
10742 return CMD_WARNING
;
10745 bgp
= bgp_get_default();
10747 vty_out(vty
, "%% No BGP process is configured\n");
10748 return CMD_WARNING
;
10752 /* Check IP address argument. */
10753 ret
= str2prefix(ip_str
, &match
);
10755 vty_out(vty
, "%% address is malformed\n");
10756 return CMD_WARNING
;
10759 match
.family
= afi2family(afi
);
10761 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
10762 || (safi
== SAFI_EVPN
)) {
10763 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
10764 rn
= bgp_route_next(rn
)) {
10765 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
10768 if ((table
= rn
->info
) != NULL
)
10769 if ((rm
= bgp_node_match(table
, &match
))
10773 == match
.prefixlen
) {
10781 bgp_damp_info_free(
10791 bgp_unlock_node(rm
);
10795 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
10798 || rn
->p
.prefixlen
== match
.prefixlen
) {
10801 if (ri
->extra
&& ri
->extra
->damp_info
) {
10802 ri_temp
= ri
->next
;
10803 bgp_damp_info_free(
10804 ri
->extra
->damp_info
,
10812 bgp_unlock_node(rn
);
10816 return CMD_SUCCESS
;
10819 DEFUN (clear_ip_bgp_dampening
,
10820 clear_ip_bgp_dampening_cmd
,
10821 "clear ip bgp dampening",
10825 "Clear route flap dampening information\n")
10827 bgp_damp_info_clean();
10828 return CMD_SUCCESS
;
10831 DEFUN (clear_ip_bgp_dampening_prefix
,
10832 clear_ip_bgp_dampening_prefix_cmd
,
10833 "clear ip bgp dampening A.B.C.D/M",
10837 "Clear route flap dampening information\n"
10840 int idx_ipv4_prefixlen
= 4;
10841 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
10842 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
10845 DEFUN (clear_ip_bgp_dampening_address
,
10846 clear_ip_bgp_dampening_address_cmd
,
10847 "clear ip bgp dampening A.B.C.D",
10851 "Clear route flap dampening information\n"
10852 "Network to clear damping information\n")
10855 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10856 SAFI_UNICAST
, NULL
, 0);
10859 DEFUN (clear_ip_bgp_dampening_address_mask
,
10860 clear_ip_bgp_dampening_address_mask_cmd
,
10861 "clear ip bgp dampening A.B.C.D A.B.C.D",
10865 "Clear route flap dampening information\n"
10866 "Network to clear damping information\n"
10870 int idx_ipv4_2
= 5;
10872 char prefix_str
[BUFSIZ
];
10874 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
10877 vty_out(vty
, "%% Inconsistent address and mask\n");
10878 return CMD_WARNING
;
10881 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
10885 /* also used for encap safi */
10886 static int bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
10887 afi_t afi
, safi_t safi
, int *write
)
10889 struct bgp_node
*prn
;
10890 struct bgp_node
*rn
;
10891 struct bgp_table
*table
;
10893 struct prefix_rd
*prd
;
10894 struct bgp_static
*bgp_static
;
10895 mpls_label_t label
;
10896 char buf
[SU_ADDRSTRLEN
];
10897 char rdbuf
[RD_ADDRSTRLEN
];
10899 /* Network configuration. */
10900 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
10901 prn
= bgp_route_next(prn
))
10902 if ((table
= prn
->info
) != NULL
)
10903 for (rn
= bgp_table_top(table
); rn
;
10904 rn
= bgp_route_next(rn
))
10905 if ((bgp_static
= rn
->info
) != NULL
) {
10907 prd
= (struct prefix_rd
*)&prn
->p
;
10909 /* "address-family" display. */
10910 bgp_config_write_family_header(
10911 vty
, afi
, safi
, write
);
10913 /* "network" configuration display. */
10914 prefix_rd2str(prd
, rdbuf
,
10916 label
= decode_label(
10917 &bgp_static
->label
);
10919 vty_out(vty
, " network %s/%d rd %s",
10920 inet_ntop(p
->family
,
10923 p
->prefixlen
, rdbuf
);
10924 if (safi
== SAFI_MPLS_VPN
)
10925 vty_out(vty
, " label %u",
10928 if (bgp_static
->rmap
.name
)
10929 vty_out(vty
, " route-map %s",
10930 bgp_static
->rmap
.name
);
10932 if (bgp_static
->backdoor
)
10936 vty_out(vty
, "\n");
10941 static int bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
10942 afi_t afi
, safi_t safi
, int *write
)
10944 struct bgp_node
*prn
;
10945 struct bgp_node
*rn
;
10946 struct bgp_table
*table
;
10948 struct prefix_rd
*prd
;
10949 struct bgp_static
*bgp_static
;
10950 char buf
[PREFIX_STRLEN
];
10951 char buf2
[SU_ADDRSTRLEN
];
10952 char rdbuf
[RD_ADDRSTRLEN
];
10954 /* Network configuration. */
10955 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
10956 prn
= bgp_route_next(prn
))
10957 if ((table
= prn
->info
) != NULL
)
10958 for (rn
= bgp_table_top(table
); rn
;
10959 rn
= bgp_route_next(rn
))
10960 if ((bgp_static
= rn
->info
) != NULL
) {
10961 char *macrouter
= NULL
;
10964 if (bgp_static
->router_mac
)
10965 macrouter
= prefix_mac2str(
10966 bgp_static
->router_mac
,
10968 if (bgp_static
->eth_s_id
)
10970 bgp_static
->eth_s_id
);
10972 prd
= (struct prefix_rd
*)&prn
->p
;
10974 /* "address-family" display. */
10975 bgp_config_write_family_header(
10976 vty
, afi
, safi
, write
);
10978 /* "network" configuration display. */
10979 prefix_rd2str(prd
, rdbuf
,
10983 &bgp_static
->igpnexthop
, buf2
,
10986 prefix2str(p
, buf
, sizeof(buf
)),
10988 " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10995 esi
, buf2
, macrouter
);
10996 vty_out(vty
, "\n");
10998 XFREE(MTYPE_TMP
, macrouter
);
11000 XFREE(MTYPE_TMP
, esi
);
11005 /* Configuration of static route announcement and aggregate
11007 int bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11008 safi_t safi
, int *write
)
11010 struct bgp_node
*rn
;
11012 struct bgp_static
*bgp_static
;
11013 struct bgp_aggregate
*bgp_aggregate
;
11014 char buf
[SU_ADDRSTRLEN
];
11016 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
11017 return bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
, write
);
11019 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
11020 return bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
,
11023 /* Network configuration. */
11024 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11025 rn
= bgp_route_next(rn
))
11026 if ((bgp_static
= rn
->info
) != NULL
) {
11029 /* "address-family" display. */
11030 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11032 /* "network" configuration display. */
11033 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)
11034 && afi
== AFI_IP
) {
11035 u_int32_t destination
;
11036 struct in_addr netmask
;
11038 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11039 masklen2ip(p
->prefixlen
, &netmask
);
11040 vty_out(vty
, " network %s",
11041 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11044 if ((IN_CLASSC(destination
)
11045 && p
->prefixlen
== 24)
11046 || (IN_CLASSB(destination
)
11047 && p
->prefixlen
== 16)
11048 || (IN_CLASSA(destination
)
11049 && p
->prefixlen
== 8)
11050 || p
->u
.prefix4
.s_addr
== 0) {
11051 /* Natural mask is not display. */
11053 vty_out(vty
, " mask %s",
11054 inet_ntoa(netmask
));
11056 vty_out(vty
, " network %s/%d",
11057 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11062 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11063 vty_out(vty
, " label-index %u",
11064 bgp_static
->label_index
);
11066 if (bgp_static
->rmap
.name
)
11067 vty_out(vty
, " route-map %s",
11068 bgp_static
->rmap
.name
);
11070 if (bgp_static
->backdoor
)
11071 vty_out(vty
, " backdoor");
11074 vty_out(vty
, "\n");
11077 /* Aggregate-address configuration. */
11078 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11079 rn
= bgp_route_next(rn
))
11080 if ((bgp_aggregate
= rn
->info
) != NULL
) {
11083 /* "address-family" display. */
11084 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11086 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)
11087 && afi
== AFI_IP
) {
11088 struct in_addr netmask
;
11090 masklen2ip(p
->prefixlen
, &netmask
);
11091 vty_out(vty
, " aggregate-address %s %s",
11092 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11094 inet_ntoa(netmask
));
11096 vty_out(vty
, " aggregate-address %s/%d",
11097 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11102 if (bgp_aggregate
->as_set
)
11103 vty_out(vty
, " as-set");
11105 if (bgp_aggregate
->summary_only
)
11106 vty_out(vty
, " summary-only");
11108 vty_out(vty
, "\n");
11114 int bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11115 safi_t safi
, int *write
)
11117 struct bgp_node
*rn
;
11118 struct bgp_distance
*bdistance
;
11120 /* Distance configuration. */
11121 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11122 && bgp
->distance_local
[afi
][safi
]
11123 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11124 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11125 || bgp
->distance_local
[afi
][safi
]
11126 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11127 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11128 vty_out(vty
, " distance bgp %d %d %d\n",
11129 bgp
->distance_ebgp
[afi
][safi
],
11130 bgp
->distance_ibgp
[afi
][safi
],
11131 bgp
->distance_local
[afi
][safi
]);
11134 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11135 rn
= bgp_route_next(rn
))
11136 if ((bdistance
= rn
->info
) != NULL
) {
11137 char buf
[PREFIX_STRLEN
];
11139 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11140 vty_out(vty
, " distance %d %s %s\n",
11141 bdistance
->distance
,
11142 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11143 bdistance
->access_list
? bdistance
->access_list
11150 /* Allocate routing table structure and install commands. */
11151 void bgp_route_init(void)
11156 /* Init BGP distance table. */
11157 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11158 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11159 bgp_distance_table
[afi
][safi
] =
11160 bgp_table_init(afi
, safi
);
11162 /* IPv4 BGP commands. */
11163 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11164 install_element(BGP_NODE
, &bgp_network_cmd
);
11165 install_element(BGP_NODE
, &bgp_network_mask_cmd
);
11166 install_element(BGP_NODE
, &bgp_network_mask_natural_cmd
);
11167 install_element(BGP_NODE
, &bgp_network_route_map_cmd
);
11168 install_element(BGP_NODE
, &bgp_network_mask_route_map_cmd
);
11169 install_element(BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11170 install_element(BGP_NODE
, &bgp_network_backdoor_cmd
);
11171 install_element(BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
11172 install_element(BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
11173 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11174 install_element(BGP_NODE
, &no_bgp_network_cmd
);
11175 install_element(BGP_NODE
, &no_bgp_network_mask_cmd
);
11176 install_element(BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
11178 install_element(BGP_NODE
, &aggregate_address_cmd
);
11179 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11180 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11181 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11183 /* IPv4 unicast configuration. */
11184 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11185 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11186 install_element(BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
11187 install_element(BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
11188 install_element(BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
11189 install_element(BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
11190 install_element(BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11191 install_element(BGP_IPV4_NODE
, &bgp_network_label_index_cmd
);
11192 install_element(BGP_IPV4_NODE
, &bgp_network_label_index_route_map_cmd
);
11193 install_element(BGP_IPV4_NODE
, &no_bgp_network_label_index_cmd
);
11194 install_element(BGP_IPV4_NODE
,
11195 &no_bgp_network_label_index_route_map_cmd
);
11196 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11197 install_element(BGP_IPV4_NODE
, &no_bgp_network_cmd
);
11198 install_element(BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
11199 install_element(BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
11201 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11202 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11203 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11204 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11206 /* IPv4 multicast configuration. */
11207 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11208 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11209 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
11210 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
11211 install_element(BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
11212 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
11213 install_element(BGP_IPV4M_NODE
,
11214 &bgp_network_mask_natural_route_map_cmd
);
11215 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11216 install_element(BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
11217 install_element(BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
11218 install_element(BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
11219 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11220 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11221 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11222 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11224 /* IPv4 labeled-unicast configuration. */
11225 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11230 install_element(VIEW_NODE
,
11231 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11233 install_element(VIEW_NODE
,
11234 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11235 #ifdef KEEP_OLD_VPN_COMMANDS
11236 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11237 #endif /* KEEP_OLD_VPN_COMMANDS */
11238 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11239 install_element(VIEW_NODE
,
11240 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11242 /* BGP dampening clear commands */
11243 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11244 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11246 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11247 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11250 install_element(ENABLE_NODE
,
11251 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11252 #ifdef KEEP_OLD_VPN_COMMANDS
11253 install_element(ENABLE_NODE
,
11254 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11255 #endif /* KEEP_OLD_VPN_COMMANDS */
11257 /* New config IPv6 BGP commands. */
11258 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11259 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11260 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
11261 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11262 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
11263 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
11264 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
11265 install_element(BGP_IPV6_NODE
,
11266 &ipv6_bgp_network_label_index_route_map_cmd
);
11267 install_element(BGP_IPV6_NODE
,
11268 &no_ipv6_bgp_network_label_index_route_map_cmd
);
11270 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11271 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11273 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11274 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11276 install_element(BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11277 install_element(BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11278 install_element(BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11279 install_element(BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11280 install_element(BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11282 install_element(BGP_NODE
, &bgp_distance_cmd
);
11283 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11284 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11285 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11286 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11287 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11288 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11289 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11290 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11291 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11292 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11293 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11294 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11295 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11296 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11297 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11298 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11299 install_element(BGP_IPV4M_NODE
,
11300 &no_bgp_distance_source_access_list_cmd
);
11301 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11302 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11303 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11304 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11305 install_element(BGP_IPV6_NODE
,
11306 &ipv6_bgp_distance_source_access_list_cmd
);
11307 install_element(BGP_IPV6_NODE
,
11308 &no_ipv6_bgp_distance_source_access_list_cmd
);
11309 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11310 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11311 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11312 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11313 install_element(BGP_IPV6M_NODE
,
11314 &ipv6_bgp_distance_source_access_list_cmd
);
11315 install_element(BGP_IPV6M_NODE
,
11316 &no_ipv6_bgp_distance_source_access_list_cmd
);
11318 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11319 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11320 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11321 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11323 /* IPv4 Multicast Mode */
11324 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11325 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11327 /* Large Communities */
11328 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11329 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11332 void bgp_route_finish(void)
11337 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11338 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
11339 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11340 bgp_distance_table
[afi
][safi
] = NULL
;