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"
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_table.h"
44 #include "bgpd/bgp_route.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_regex.h"
49 #include "bgpd/bgp_community.h"
50 #include "bgpd/bgp_ecommunity.h"
51 #include "bgpd/bgp_lcommunity.h"
52 #include "bgpd/bgp_clist.h"
53 #include "bgpd/bgp_packet.h"
54 #include "bgpd/bgp_filter.h"
55 #include "bgpd/bgp_fsm.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_encap.h"
58 #include "bgpd/bgp_nexthop.h"
59 #include "bgpd/bgp_damp.h"
60 #include "bgpd/bgp_advertise.h"
61 #include "bgpd/bgp_zebra.h"
62 #include "bgpd/bgp_vty.h"
63 #include "bgpd/bgp_mpath.h"
64 #include "bgpd/bgp_nht.h"
65 #include "bgpd/bgp_updgrp.h"
66 #include "bgpd/bgp_label.h"
69 #include "bgpd/rfapi/rfapi_backend.h"
70 #include "bgpd/rfapi/vnc_import_bgp.h"
71 #include "bgpd/rfapi/vnc_export_bgp.h"
73 #include "bgpd/bgp_encap_types.h"
74 #include "bgpd/bgp_encap_tlv.h"
75 #include "bgpd/bgp_evpn.h"
76 #include "bgpd/bgp_evpn_vty.h"
79 /* Extern from bgp_dump.c */
80 extern const char *bgp_origin_str
[];
81 extern const char *bgp_origin_long_str
[];
84 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
85 struct prefix_rd
*prd
)
88 struct bgp_node
*prn
= NULL
;
94 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
97 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
99 if (prn
->info
== NULL
)
100 prn
->info
= bgp_table_init (afi
, safi
);
102 bgp_unlock_node (prn
);
106 rn
= bgp_node_get (table
, p
);
108 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
115 /* Allocate bgp_info_extra */
116 static struct bgp_info_extra
*
117 bgp_info_extra_new (void)
119 struct bgp_info_extra
*new;
120 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
125 bgp_info_extra_free (struct bgp_info_extra
**extra
)
129 if ((*extra
)->damp_info
)
130 bgp_damp_info_free ((*extra
)->damp_info
, 0);
132 (*extra
)->damp_info
= NULL
;
134 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
140 /* Get bgp_info extra information for the given bgp_info, lazy allocated
143 struct bgp_info_extra
*
144 bgp_info_extra_get (struct bgp_info
*ri
)
147 ri
->extra
= bgp_info_extra_new();
151 /* Allocate new bgp info structure. */
155 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
158 /* Free bgp route information. */
160 bgp_info_free (struct bgp_info
*binfo
)
163 bgp_attr_unintern (&binfo
->attr
);
165 bgp_unlink_nexthop(binfo
);
166 bgp_info_extra_free (&binfo
->extra
);
167 bgp_info_mpath_free (&binfo
->mpath
);
169 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
171 XFREE (MTYPE_BGP_ROUTE
, binfo
);
175 bgp_info_lock (struct bgp_info
*binfo
)
182 bgp_info_unlock (struct bgp_info
*binfo
)
184 assert (binfo
&& binfo
->lock
> 0);
187 if (binfo
->lock
== 0)
190 zlog_debug ("%s: unlocked and freeing", __func__
);
191 zlog_backtrace (LOG_DEBUG
);
193 bgp_info_free (binfo
);
198 if (binfo
->lock
== 1)
200 zlog_debug ("%s: unlocked to 1", __func__
);
201 zlog_backtrace (LOG_DEBUG
);
209 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
211 struct bgp_info
*top
;
223 peer_lock (ri
->peer
); /* bgp_info peer reference */
226 /* Do the actual removal of info from RIB, for use by bgp_process
227 completion callback *only* */
229 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
232 ri
->next
->prev
= ri
->prev
;
234 ri
->prev
->next
= ri
->next
;
238 bgp_info_mpath_dequeue (ri
);
239 bgp_info_unlock (ri
);
240 bgp_unlock_node (rn
);
244 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
246 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
247 /* set of previous already took care of pcount */
248 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
251 /* undo the effects of a previous call to bgp_info_delete; typically
252 called when a route is deleted and then quickly re-added before the
253 deletion has been processed */
255 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
257 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
258 /* unset of previous already took care of pcount */
259 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
262 /* Adjust pcount as required */
264 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
266 struct bgp_table
*table
;
268 assert (rn
&& bgp_node_table (rn
));
269 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
271 table
= bgp_node_table (rn
);
273 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
276 if (!BGP_INFO_COUNTABLE (ri
)
277 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
280 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
282 /* slight hack, but more robust against errors. */
283 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
284 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
287 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
288 __func__
, ri
->peer
->host
);
289 zlog_backtrace (LOG_WARNING
);
290 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
293 else if (BGP_INFO_COUNTABLE (ri
)
294 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
296 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
297 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
302 bgp_label_index_differs (struct bgp_info
*ri1
, struct bgp_info
*ri2
)
304 return (!(ri1
->attr
->extra
->label_index
== ri2
->attr
->extra
->label_index
));
307 /* Set/unset bgp_info flags, adjusting any other state as needed.
308 * This is here primarily to keep prefix-count in check.
311 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
313 SET_FLAG (ri
->flags
, flag
);
315 /* early bath if we know it's not a flag that changes countability state */
316 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
319 bgp_pcount_adjust (rn
, ri
);
323 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
325 UNSET_FLAG (ri
->flags
, flag
);
327 /* early bath if we know it's not a flag that changes countability state */
328 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
331 bgp_pcount_adjust (rn
, ri
);
334 /* Get MED value. If MED value is missing and "bgp bestpath
335 missing-as-worst" is specified, treat it as the worst value. */
337 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
339 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
343 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
351 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
353 if (ri
->addpath_rx_id
)
354 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
356 sprintf(buf
, "path %s", ri
->peer
->host
);
359 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
361 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
362 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
365 struct attr
*newattr
, *existattr
;
366 struct attr_extra
*newattre
, *existattre
;
367 bgp_peer_sort_t new_sort
;
368 bgp_peer_sort_t exist_sort
;
370 u_int32_t exist_pref
;
373 u_int32_t new_weight
;
374 u_int32_t exist_weight
;
375 uint32_t newm
, existm
;
376 struct in_addr new_id
;
377 struct in_addr exist_id
;
380 int internal_as_route
;
383 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
384 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
392 zlog_debug("%s: new is NULL", pfx_buf
);
397 bgp_info_path_with_addpath_rx_str (new, new_buf
);
402 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
408 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
409 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
410 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
414 existattr
= exist
->attr
;
415 newattre
= newattr
->extra
;
416 existattre
= existattr
->extra
;
418 /* 1. Weight check. */
419 new_weight
= exist_weight
= 0;
422 new_weight
= newattre
->weight
;
424 exist_weight
= existattre
->weight
;
426 if (new_weight
> exist_weight
)
429 zlog_debug("%s: %s wins over %s due to weight %d > %d",
430 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
434 if (new_weight
< exist_weight
)
437 zlog_debug("%s: %s loses to %s due to weight %d < %d",
438 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
442 /* 2. Local preference check. */
443 new_pref
= exist_pref
= bgp
->default_local_pref
;
445 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
446 new_pref
= newattr
->local_pref
;
447 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
448 exist_pref
= existattr
->local_pref
;
450 if (new_pref
> exist_pref
)
453 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
454 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
458 if (new_pref
< exist_pref
)
461 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
462 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
466 /* 3. Local route check. We prefer:
468 * - BGP_ROUTE_AGGREGATE
469 * - BGP_ROUTE_REDISTRIBUTE
471 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
474 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
475 pfx_buf
, new_buf
, exist_buf
);
479 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
482 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
483 pfx_buf
, new_buf
, exist_buf
);
487 /* 4. AS path length check. */
488 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
490 int exist_hops
= aspath_count_hops (existattr
->aspath
);
491 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
493 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
497 aspath_hops
= aspath_count_hops (newattr
->aspath
);
498 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
500 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
503 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
504 pfx_buf
, new_buf
, exist_buf
,
505 aspath_hops
, (exist_hops
+ exist_confeds
));
509 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
512 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
513 pfx_buf
, new_buf
, exist_buf
,
514 aspath_hops
, (exist_hops
+ exist_confeds
));
520 int newhops
= aspath_count_hops (newattr
->aspath
);
522 if (newhops
< exist_hops
)
525 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
526 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
530 if (newhops
> exist_hops
)
533 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
534 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
540 /* 5. Origin check. */
541 if (newattr
->origin
< existattr
->origin
)
544 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
545 pfx_buf
, new_buf
, exist_buf
,
546 bgp_origin_long_str
[newattr
->origin
],
547 bgp_origin_long_str
[existattr
->origin
]);
551 if (newattr
->origin
> existattr
->origin
)
554 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
555 pfx_buf
, new_buf
, exist_buf
,
556 bgp_origin_long_str
[newattr
->origin
],
557 bgp_origin_long_str
[existattr
->origin
]);
562 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
563 && aspath_count_hops (existattr
->aspath
) == 0);
564 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
565 && aspath_count_confeds (existattr
->aspath
) > 0
566 && aspath_count_hops (newattr
->aspath
) == 0
567 && aspath_count_hops (existattr
->aspath
) == 0);
569 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
570 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
572 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
573 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
574 || internal_as_route
)
576 new_med
= bgp_med_value (new->attr
, bgp
);
577 exist_med
= bgp_med_value (exist
->attr
, bgp
);
579 if (new_med
< exist_med
)
582 zlog_debug("%s: %s wins over %s due to MED %d < %d",
583 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
587 if (new_med
> exist_med
)
590 zlog_debug("%s: %s loses to %s due to MED %d > %d",
591 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
596 /* 7. Peer type check. */
597 new_sort
= new->peer
->sort
;
598 exist_sort
= exist
->peer
->sort
;
600 if (new_sort
== BGP_PEER_EBGP
601 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
604 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
605 pfx_buf
, new_buf
, exist_buf
);
609 if (exist_sort
== BGP_PEER_EBGP
610 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
613 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
614 pfx_buf
, new_buf
, exist_buf
);
618 /* 8. IGP metric check. */
622 newm
= new->extra
->igpmetric
;
624 existm
= exist
->extra
->igpmetric
;
629 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
630 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
637 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
638 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
642 /* 9. Same IGP metric. Compare the cluster list length as
643 representative of IGP hops metric. Rewrite the metric value
644 pair (newm, existm) with the cluster list length. Prefer the
645 path with smaller cluster list length. */
648 if (peer_sort (new->peer
) == BGP_PEER_IBGP
649 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
650 && (mpath_cfg
== NULL
||
651 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
652 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
654 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
655 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
660 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
661 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
668 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
669 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
675 /* 10. confed-external vs. confed-internal */
676 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
678 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
681 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
682 pfx_buf
, new_buf
, exist_buf
);
686 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
689 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
690 pfx_buf
, new_buf
, exist_buf
);
695 /* 11. Maximum path check. */
698 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
702 * For the two paths, all comparison steps till IGP metric
703 * have succeeded - including AS_PATH hop count. Since 'bgp
704 * bestpath as-path multipath-relax' knob is on, we don't need
705 * an exact match of AS_PATH. Thus, mark the paths are equal.
706 * That will trigger both these paths to get into the multipath
712 zlog_debug("%s: %s and %s are equal via multipath-relax",
713 pfx_buf
, new_buf
, exist_buf
);
715 else if (new->peer
->sort
== BGP_PEER_IBGP
)
717 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
722 zlog_debug("%s: %s and %s are equal via matching aspaths",
723 pfx_buf
, new_buf
, exist_buf
);
726 else if (new->peer
->as
== exist
->peer
->as
)
731 zlog_debug("%s: %s and %s are equal via same remote-as",
732 pfx_buf
, new_buf
, exist_buf
);
738 * TODO: If unequal cost ibgp multipath is enabled we can
739 * mark the paths as equal here instead of returning
744 zlog_debug("%s: %s wins over %s after IGP metric comparison",
745 pfx_buf
, new_buf
, exist_buf
);
747 zlog_debug("%s: %s loses to %s after IGP metric comparison",
748 pfx_buf
, new_buf
, exist_buf
);
753 /* 12. If both paths are external, prefer the path that was received
754 first (the oldest one). This step minimizes route-flap, since a
755 newer path won't displace an older one, even if it was the
756 preferred route based on the additional decision criteria below. */
757 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
758 && new_sort
== BGP_PEER_EBGP
759 && exist_sort
== BGP_PEER_EBGP
)
761 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
764 zlog_debug("%s: %s wins over %s due to oldest external",
765 pfx_buf
, new_buf
, exist_buf
);
769 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
772 zlog_debug("%s: %s loses to %s due to oldest external",
773 pfx_buf
, new_buf
, exist_buf
);
778 /* 13. Router-ID comparision. */
779 /* If one of the paths is "stale", the corresponding peer router-id will
780 * be 0 and would always win over the other path. If originator id is
781 * used for the comparision, it will decide which path is better.
783 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
784 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
786 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
787 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
788 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
790 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
792 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
795 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
796 pfx_buf
, new_buf
, exist_buf
);
800 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
803 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
804 pfx_buf
, new_buf
, exist_buf
);
808 /* 14. Cluster length comparision. */
809 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
810 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
812 if (new_cluster
< exist_cluster
)
815 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
816 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
820 if (new_cluster
> exist_cluster
)
823 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
824 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
828 /* 15. Neighbor address comparision. */
829 /* Do this only if neither path is "stale" as stale paths do not have
830 * valid peer information (as the connection may or may not be up).
832 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
835 zlog_debug("%s: %s wins over %s due to latter path being STALE",
836 pfx_buf
, new_buf
, exist_buf
);
840 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
843 zlog_debug("%s: %s loses to %s due to former path being STALE",
844 pfx_buf
, new_buf
, exist_buf
);
848 /* locally configured routes to advertise do not have su_remote */
849 if (new->peer
->su_remote
== NULL
)
851 if (exist
->peer
->su_remote
== NULL
)
854 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
859 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
860 pfx_buf
, new_buf
, exist_buf
);
867 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
868 pfx_buf
, new_buf
, exist_buf
);
873 zlog_debug("%s: %s wins over %s due to nothing left to compare",
874 pfx_buf
, new_buf
, exist_buf
);
879 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
880 * is preferred, or 0 if they are the same (usually will only occur if
881 * multipath is enabled
882 * This version is compatible with */
884 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
885 afi_t afi
, safi_t safi
)
889 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
903 static enum filter_type
904 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
905 afi_t afi
, safi_t safi
)
907 struct bgp_filter
*filter
;
909 filter
= &peer
->filter
[afi
][safi
];
911 #define FILTER_EXIST_WARN(F,f,filter) \
912 if (BGP_DEBUG (update, UPDATE_IN) \
913 && !(F ## _IN (filter))) \
914 zlog_warn ("%s: Could not find configured input %s-list %s!", \
915 peer->host, #f, F ## _IN_NAME(filter));
917 if (DISTRIBUTE_IN_NAME (filter
)) {
918 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
920 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
924 if (PREFIX_LIST_IN_NAME (filter
)) {
925 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
927 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
931 if (FILTER_LIST_IN_NAME (filter
)) {
932 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
934 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
938 return FILTER_PERMIT
;
939 #undef FILTER_EXIST_WARN
942 static enum filter_type
943 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
944 afi_t afi
, safi_t safi
)
946 struct bgp_filter
*filter
;
948 filter
= &peer
->filter
[afi
][safi
];
950 #define FILTER_EXIST_WARN(F,f,filter) \
951 if (BGP_DEBUG (update, UPDATE_OUT) \
952 && !(F ## _OUT (filter))) \
953 zlog_warn ("%s: Could not find configured output %s-list %s!", \
954 peer->host, #f, F ## _OUT_NAME(filter));
956 if (DISTRIBUTE_OUT_NAME (filter
)) {
957 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
959 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
963 if (PREFIX_LIST_OUT_NAME (filter
)) {
964 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
966 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
970 if (FILTER_LIST_OUT_NAME (filter
)) {
971 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
973 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
977 return FILTER_PERMIT
;
978 #undef FILTER_EXIST_WARN
981 /* If community attribute includes no_export then return 1. */
983 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
987 /* NO_ADVERTISE check. */
988 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
991 /* NO_EXPORT check. */
992 if (peer
->sort
== BGP_PEER_EBGP
&&
993 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
996 /* NO_EXPORT_SUBCONFED check. */
997 if (peer
->sort
== BGP_PEER_EBGP
998 || peer
->sort
== BGP_PEER_CONFED
)
999 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
1005 /* Route reflection loop check. */
1007 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1009 struct in_addr cluster_id
;
1011 if (attr
->extra
&& attr
->extra
->cluster
)
1013 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1014 cluster_id
= peer
->bgp
->cluster_id
;
1016 cluster_id
= peer
->bgp
->router_id
;
1018 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1025 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1026 afi_t afi
, safi_t safi
, const char *rmap_name
)
1028 struct bgp_filter
*filter
;
1029 struct bgp_info info
;
1030 route_map_result_t ret
;
1031 struct route_map
*rmap
= NULL
;
1033 filter
= &peer
->filter
[afi
][safi
];
1035 /* Apply default weight value. */
1036 if (peer
->weight
[afi
][safi
])
1037 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1041 rmap
= route_map_lookup_by_name(rmap_name
);
1048 if (ROUTE_MAP_IN_NAME(filter
))
1050 rmap
= ROUTE_MAP_IN (filter
);
1057 /* Route map apply. */
1060 /* Duplicate current value to new strucutre for modification. */
1064 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1066 /* Apply BGP route map to the attribute. */
1067 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1069 peer
->rmap_type
= 0;
1071 if (ret
== RMAP_DENYMATCH
)
1073 /* Free newly generated AS path and community by route-map. */
1074 bgp_attr_flush (attr
);
1082 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1083 afi_t afi
, safi_t safi
, const char *rmap_name
)
1085 struct bgp_filter
*filter
;
1086 struct bgp_info info
;
1087 route_map_result_t ret
;
1088 struct route_map
*rmap
= NULL
;
1090 filter
= &peer
->filter
[afi
][safi
];
1092 /* Apply default weight value. */
1093 if (peer
->weight
[afi
][safi
])
1094 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1098 rmap
= route_map_lookup_by_name(rmap_name
);
1105 if (ROUTE_MAP_OUT_NAME(filter
))
1107 rmap
= ROUTE_MAP_OUT (filter
);
1114 /* Route map apply. */
1117 /* Duplicate current value to new strucutre for modification. */
1121 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1123 /* Apply BGP route map to the attribute. */
1124 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1126 peer
->rmap_type
= 0;
1128 if (ret
== RMAP_DENYMATCH
)
1129 /* caller has multiple error paths with bgp_attr_flush() */
1135 /* If this is an EBGP peer with remove-private-AS */
1137 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1138 struct peer
*peer
, struct attr
*attr
)
1140 if (peer
->sort
== BGP_PEER_EBGP
&&
1141 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1142 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1143 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1144 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1146 // Take action on the entire aspath
1147 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1148 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1150 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1151 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1153 // The entire aspath consists of private ASNs so create an empty aspath
1154 else if (aspath_private_as_check (attr
->aspath
))
1155 attr
->aspath
= aspath_empty_get ();
1157 // There are some public and some private ASNs, remove the private ASNs
1159 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1162 // 'all' was not specified so the entire aspath must be private ASNs
1163 // for us to do anything
1164 else if (aspath_private_as_check (attr
->aspath
))
1166 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1167 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1169 attr
->aspath
= aspath_empty_get ();
1174 /* If this is an EBGP peer with as-override */
1176 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1177 struct peer
*peer
, struct attr
*attr
)
1179 if (peer
->sort
== BGP_PEER_EBGP
&&
1180 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1182 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1183 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1188 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1190 if (family
== AF_INET
)
1191 attr
->nexthop
.s_addr
= 0;
1192 if (family
== AF_INET6
)
1193 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1197 subgroup_announce_check (struct bgp_node
*rn
, struct bgp_info
*ri
,
1198 struct update_subgroup
*subgrp
,
1199 struct prefix
*p
, struct attr
*attr
)
1201 struct bgp_filter
*filter
;
1204 struct peer
*onlypeer
;
1206 struct attr
*riattr
;
1207 struct peer_af
*paf
;
1208 char buf
[PREFIX_STRLEN
];
1214 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1216 if (DISABLE_BGP_ANNOUNCE
)
1219 afi
= SUBGRP_AFI(subgrp
);
1220 safi
= SUBGRP_SAFI(subgrp
);
1221 peer
= SUBGRP_PEER(subgrp
);
1223 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1224 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1227 filter
= &peer
->filter
[afi
][safi
];
1228 bgp
= SUBGRP_INST(subgrp
);
1229 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1232 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1233 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1234 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1237 * direct and direct_ext type routes originate internally even
1238 * though they can have peer pointers that reference other systems
1240 prefix2str(p
, buf
, PREFIX_STRLEN
);
1241 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1246 /* With addpath we may be asked to TX all kinds of paths so make sure
1248 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1249 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1250 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1255 /* If this is not the bestpath then check to see if there is an enabled addpath
1256 * feature that requires us to advertise it */
1257 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1259 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1265 /* Aggregate-address suppress check. */
1266 if (ri
->extra
&& ri
->extra
->suppress
)
1267 if (! UNSUPPRESS_MAP_NAME (filter
))
1272 /* If it's labeled safi, make sure the route has a valid label. */
1273 if (safi
== SAFI_LABELED_UNICAST
)
1275 u_char
*tag
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1276 if (!bgp_is_valid_label(tag
))
1278 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1279 zlog_debug ("u%" PRIu64
":s%" PRIu64
" %s/%d is filtered - no label (%p)",
1280 subgrp
->update_group
->id
, subgrp
->id
,
1281 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1287 /* Do not send back route to sender. */
1288 if (onlypeer
&& from
== onlypeer
)
1293 /* Do not send the default route in the BGP table if the neighbor is
1294 * configured for default-originate */
1295 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1297 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1299 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1303 /* Transparency check. */
1304 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1305 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1310 /* If community is not disabled check the no-export and local. */
1311 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1313 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1314 zlog_debug ("subgrpannouncecheck: community filter check fail");
1318 /* If the attribute has originator-id and it is same as remote
1321 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1322 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1324 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1325 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1327 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1331 /* ORF prefix-list filter check */
1332 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1333 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1334 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1335 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1336 if (peer
->orf_plist
[afi
][safi
])
1338 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1340 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1341 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1342 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1347 /* Output filter check. */
1348 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1350 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1351 zlog_debug ("%s [Update:SEND] %s is filtered",
1352 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1356 #ifdef BGP_SEND_ASPATH_CHECK
1357 /* AS path loop check. */
1358 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1360 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1361 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1362 "that is part of AS path.",
1363 onlypeer
->host
, onlypeer
->as
);
1366 #endif /* BGP_SEND_ASPATH_CHECK */
1368 /* If we're a CONFED we need to loop check the CONFED ID too */
1369 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1371 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1373 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1374 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1382 /* Route-Reflect check. */
1383 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1388 /* IBGP reflection check. */
1389 if (reflect
&& !samepeer_safe
)
1391 /* A route from a Client peer. */
1392 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1394 /* Reflect to all the Non-Client peers and also to the
1395 Client peers other than the originator. Originator check
1396 is already done. So there is noting to do. */
1397 /* no bgp client-to-client reflection check. */
1398 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1399 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1400 PEER_FLAG_REFLECTOR_CLIENT
))
1405 /* A route from a Non-client peer. Reflect to all other
1407 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1408 PEER_FLAG_REFLECTOR_CLIENT
))
1413 /* For modify attribute, copy it to temporary structure. */
1414 bgp_attr_dup (attr
, riattr
);
1416 /* If local-preference is not set. */
1417 if ((peer
->sort
== BGP_PEER_IBGP
1418 || peer
->sort
== BGP_PEER_CONFED
)
1419 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1421 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1422 attr
->local_pref
= bgp
->default_local_pref
;
1425 /* If originator-id is not set and the route is to be reflected,
1426 set the originator id */
1427 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1429 attr
->extra
= bgp_attr_extra_get(attr
);
1430 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1431 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1434 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1435 if (peer
->sort
== BGP_PEER_EBGP
1436 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1438 if (from
!= bgp
->peer_self
&& ! transparent
1439 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1440 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1443 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1444 * in announce check, only certain flags and length (or number of nexthops
1445 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1446 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1447 * Typically, the source nexthop in the attribute is preserved but in the
1448 * scenarios where we know it will always be overwritten, we reset the
1449 * nexthop to "0" in an attempt to achieve better Update packing. An
1450 * example of this is when a prefix from each of 2 IBGP peers needs to be
1451 * announced to an EBGP peer (and they have the same attributes barring
1455 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1457 #define NEXTHOP_IS_V6 (\
1458 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1459 (p->family == AF_INET6 || peer_cap_enhe(peer, AFI_IP6, safi))) || \
1460 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1461 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1463 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1464 * the peer (group) is configured to receive link-local nexthop unchanged
1465 * and it is available in the prefix OR we're not reflecting the route and
1466 * the peer (group) to whom we're going to announce is on a shared network
1467 * and this is either a self-originated route or the peer is EBGP.
1471 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1472 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1473 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1474 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1475 (!reflect
&& peer
->shared_network
&&
1476 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1478 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1481 /* Clear off link-local nexthop in source, whenever it is not needed to
1482 * ensure more prefixes share the same attribute for announcement.
1484 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1485 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1486 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1489 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1490 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1492 /* Route map & unsuppress-map apply. */
1493 if (ROUTE_MAP_OUT_NAME (filter
)
1494 || (ri
->extra
&& ri
->extra
->suppress
) )
1496 struct bgp_info info
;
1497 struct attr dummy_attr
;
1498 struct attr_extra dummy_extra
;
1500 dummy_attr
.extra
= &dummy_extra
;
1504 /* don't confuse inbound and outbound setting */
1505 RESET_FLAG(attr
->rmap_change_flags
);
1508 * The route reflector is not allowed to modify the attributes
1509 * of the reflected IBGP routes unless explicitly allowed.
1511 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1512 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1514 bgp_attr_dup (&dummy_attr
, attr
);
1515 info
.attr
= &dummy_attr
;
1518 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1520 if (ri
->extra
&& ri
->extra
->suppress
)
1521 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1523 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1525 peer
->rmap_type
= 0;
1527 if (ret
== RMAP_DENYMATCH
)
1529 bgp_attr_flush (attr
);
1534 /* After route-map has been applied, we check to see if the nexthop to
1535 * be carried in the attribute (that is used for the announcement) can
1536 * be cleared off or not. We do this in all cases where we would be
1537 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1538 * the global nexthop here; the link-local nexthop would have been cleared
1539 * already, and if not, it is required by the update formation code.
1540 * Also see earlier comments in this function.
1543 * If route-map has performed some operation on the nexthop or the peer
1544 * configuration says to pass it unchanged, we cannot reset the nexthop
1545 * here, so only attempt to do it if these aren't true. Note that the
1546 * route-map handler itself might have cleared the nexthop, if for example,
1547 * it is configured as 'peer-address'.
1549 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1550 riattr
->rmap_change_flags
) &&
1552 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1554 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1555 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1556 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1559 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1560 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1561 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ?
1562 AF_INET6
: p
->family
), attr
);
1564 else if (peer
->sort
== BGP_PEER_EBGP
)
1566 /* Can also reset the nexthop if announcing to EBGP, but only if
1567 * no peer in the subgroup is on a shared subnet.
1568 * Note: 3rd party nexthop currently implemented for IPv4 only.
1570 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1572 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1576 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ? AF_INET6
: p
->family
), attr
);
1578 /* If IPv6/MP and nexthop does not have any override and happens to
1579 * be a link-local address, reset it so that we don't pass along the
1580 * source's link-local IPv6 address to recipients who may not be on
1581 * the same interface.
1583 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
))
1585 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1586 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1593 struct bgp_info_pair
1595 struct bgp_info
*old
;
1596 struct bgp_info
*new;
1600 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1601 struct bgp_maxpaths_cfg
*mpath_cfg
,
1602 struct bgp_info_pair
*result
)
1604 struct bgp_info
*new_select
;
1605 struct bgp_info
*old_select
;
1606 struct bgp_info
*ri
;
1607 struct bgp_info
*ri1
;
1608 struct bgp_info
*ri2
;
1609 struct bgp_info
*nextri
= NULL
;
1610 int paths_eq
, do_mpath
, debug
;
1611 struct list mp_list
;
1612 char pfx_buf
[PREFIX2STR_BUFFER
];
1613 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1615 bgp_mp_list_init (&mp_list
);
1616 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1618 debug
= bgp_debug_bestpath(&rn
->p
);
1621 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1623 /* bgp deterministic-med */
1625 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1628 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1629 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1630 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1632 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1634 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1636 if (BGP_INFO_HOLDDOWN (ri1
))
1638 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1639 if (ri1
->peer
->status
!= Established
)
1645 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1647 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1649 if (BGP_INFO_HOLDDOWN (ri2
))
1652 ri2
->peer
!= bgp
->peer_self
&&
1653 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1654 if (ri2
->peer
->status
!= Established
)
1657 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1658 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1661 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1662 mpath_cfg
, debug
, pfx_buf
))
1664 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1668 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1672 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1673 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1677 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1678 zlog_debug("%s: %s is the bestpath from AS %d",
1679 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1684 /* Check old selected route and new selected route. */
1687 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1689 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1692 if (BGP_INFO_HOLDDOWN (ri
))
1694 /* reap REMOVED routes, if needs be
1695 * selected route must stay for a while longer though
1697 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1698 && (ri
!= old_select
))
1699 bgp_info_reap (rn
, ri
);
1705 ri
->peer
!= bgp
->peer_self
&&
1706 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1707 if (ri
->peer
->status
!= Established
)
1710 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1711 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1713 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1717 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1719 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1725 /* Now that we know which path is the bestpath see if any of the other paths
1726 * qualify as multipaths
1731 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1733 sprintf (path_buf
, "NONE");
1734 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1736 old_select
? old_select
->peer
->host
: "NONE");
1739 if (do_mpath
&& new_select
)
1741 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1745 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1747 if (ri
== new_select
)
1750 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1752 bgp_mp_list_add (&mp_list
, ri
);
1756 if (BGP_INFO_HOLDDOWN (ri
))
1760 ri
->peer
!= bgp
->peer_self
&&
1761 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1762 if (ri
->peer
->status
!= Established
)
1765 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1768 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1773 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1778 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1780 bgp_mp_list_add (&mp_list
, ri
);
1785 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1786 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1787 bgp_mp_list_clear (&mp_list
);
1789 result
->old
= old_select
;
1790 result
->new = new_select
;
1796 * A new route/change in bestpath of an existing route. Evaluate the path
1797 * for advertisement to the subgroup.
1800 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1801 struct bgp_info
*selected
,
1802 struct bgp_node
*rn
,
1803 u_int32_t addpath_tx_id
)
1806 struct peer
*onlypeer
;
1808 struct attr_extra extra
;
1813 afi
= SUBGRP_AFI(subgrp
);
1814 safi
= SUBGRP_SAFI(subgrp
);
1815 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1816 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1818 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1819 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1820 PEER_STATUS_ORF_WAIT_REFRESH
))
1823 memset(&extra
, 0, sizeof(struct attr_extra
));
1824 /* It's initialized in bgp_announce_check() */
1825 attr
.extra
= &extra
;
1827 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1830 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1831 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1833 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1836 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1839 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1846 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1847 * This is called at the end of route processing.
1850 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1852 struct bgp_info
*ri
;
1854 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1856 if (BGP_INFO_HOLDDOWN (ri
))
1858 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1859 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1864 * Has the route changed from the RIB's perspective? This is invoked only
1865 * if the route selection returns the same best route as earlier - to
1866 * determine if we need to update zebra or not.
1869 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1871 struct bgp_info
*mpinfo
;
1873 /* If this is multipath, check all selected paths for any nexthop change or
1874 * attribute change. Some attribute changes (e.g., community) aren't of
1875 * relevance to the RIB, but we'll update zebra to ensure we handle the
1876 * case of BGP nexthop change. This is the behavior when the best path has
1877 * an attribute change anyway.
1879 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1880 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1883 /* If this is multipath, check all selected paths for any nexthop change */
1884 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1885 mpinfo
= bgp_info_mpath_next (mpinfo
))
1887 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1888 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1892 /* Nothing has changed from the RIB's perspective. */
1896 struct bgp_process_queue
1899 struct bgp_node
*rn
;
1904 static wq_item_status
1905 bgp_process_main (struct work_queue
*wq
, void *data
)
1907 struct bgp_process_queue
*pq
= data
;
1908 struct bgp
*bgp
= pq
->bgp
;
1909 struct bgp_node
*rn
= pq
->rn
;
1910 afi_t afi
= pq
->afi
;
1911 safi_t safi
= pq
->safi
;
1912 struct prefix
*p
= &rn
->p
;
1913 struct bgp_info
*new_select
;
1914 struct bgp_info
*old_select
;
1915 struct bgp_info_pair old_and_new
;
1917 /* Is it end of initial update? (after startup) */
1920 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1921 sizeof(bgp
->update_delay_zebra_resume_time
));
1923 bgp
->main_zebra_update_hold
= 0;
1924 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1925 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1927 bgp_zebra_announce_table(bgp
, afi
, safi
);
1929 bgp
->main_peers_update_hold
= 0;
1931 bgp_start_routeadv(bgp
);
1935 /* Best path selection. */
1936 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1937 old_select
= old_and_new
.old
;
1938 new_select
= old_and_new
.new;
1940 /* Do we need to allocate or free labels?
1941 * Right now, since we only deal with per-prefix labels, it is not necessary
1942 * to do this upon changes to best path except of the label index changes.
1944 if (safi
== SAFI_LABELED_UNICAST
)
1946 bgp_table_lock (bgp_node_table (rn
));
1950 bgp_label_index_differs (new_select
, old_select
) ||
1951 new_select
->sub_type
!= old_select
->sub_type
)
1953 if (new_select
->sub_type
== BGP_ROUTE_STATIC
&&
1954 new_select
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
) &&
1955 new_select
->attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
1957 if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1958 bgp_unregister_for_label (rn
);
1959 label_ntop (MPLS_IMP_NULL_LABEL
, 1, rn
->local_label
);
1960 bgp_set_valid_label(rn
->local_label
);
1963 bgp_register_for_label (rn
, new_select
);
1966 else if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1967 bgp_unregister_for_label (rn
);
1970 /* If best route remains the same and this is not due to user-initiated
1971 * clear, see exactly what needs to be done.
1974 if (old_select
&& old_select
== new_select
&&
1975 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1976 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1977 !bgp
->addpath_tx_used
[afi
][safi
])
1979 if (bgp_zebra_has_route_changed (rn
, old_select
))
1982 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1983 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1985 if (bgp_fibupd_safi(safi
) &&
1987 !bgp_option_check (BGP_OPT_NO_FIB
) &&
1988 new_select
->type
== ZEBRA_ROUTE_BGP
&&
1989 new_select
->sub_type
== BGP_ROUTE_NORMAL
)
1990 bgp_zebra_announce (rn
, p
, old_select
, bgp
, afi
, safi
);
1992 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1993 bgp_zebra_clear_route_change_flags (rn
);
1995 /* If there is a change of interest to peers, reannounce the route. */
1996 if (CHECK_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
) ||
1997 CHECK_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
))
1999 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2001 UNSET_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2002 UNSET_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2005 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2009 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
2010 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2012 /* bestpath has changed; bump version */
2013 if (old_select
|| new_select
)
2015 bgp_bump_version(rn
);
2017 if (!bgp
->t_rmap_def_originate_eval
)
2020 thread_add_timer(bm
->master
,
2021 update_group_refresh_default_originate_route_map
,
2022 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2023 &bgp
->t_rmap_def_originate_eval
);
2028 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
2031 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
2032 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2033 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2037 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2038 if (old_select
!= new_select
) {
2040 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
2041 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2044 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
2045 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2051 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2054 if (bgp_fibupd_safi(safi
) &&
2055 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
2056 !bgp_option_check (BGP_OPT_NO_FIB
))
2059 && new_select
->type
== ZEBRA_ROUTE_BGP
2060 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
2061 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2062 bgp_zebra_announce (rn
, p
, new_select
, bgp
, afi
, safi
);
2065 /* Withdraw the route from the kernel. */
2067 && old_select
->type
== ZEBRA_ROUTE_BGP
2068 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
2069 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2070 bgp_zebra_withdraw (p
, old_select
, safi
);
2074 /* Clear any route change flags. */
2075 bgp_zebra_clear_route_change_flags (rn
);
2077 /* Reap old select bgp_info, if it has been removed */
2078 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2079 bgp_info_reap (rn
, old_select
);
2081 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2086 bgp_processq_del (struct work_queue
*wq
, void *data
)
2088 struct bgp_process_queue
*pq
= data
;
2089 struct bgp_table
*table
;
2091 bgp_unlock (pq
->bgp
);
2094 table
= bgp_node_table (pq
->rn
);
2095 bgp_unlock_node (pq
->rn
);
2096 bgp_table_unlock (table
);
2098 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2102 bgp_process_queue_init (void)
2104 if (!bm
->process_main_queue
)
2106 bm
->process_main_queue
2107 = work_queue_new (bm
->master
, "process_main_queue");
2109 if ( !bm
->process_main_queue
)
2111 zlog_err ("%s: Failed to allocate work queue", __func__
);
2116 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2117 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2118 bm
->process_main_queue
->spec
.max_retries
= 0;
2119 bm
->process_main_queue
->spec
.hold
= 50;
2120 /* Use a higher yield value of 50ms for main queue processing */
2121 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2125 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2127 struct bgp_process_queue
*pqnode
;
2129 /* already scheduled for processing? */
2130 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2133 if (bm
->process_main_queue
== NULL
)
2136 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2137 sizeof (struct bgp_process_queue
));
2141 /* all unlocked in bgp_processq_del */
2142 bgp_table_lock (bgp_node_table (rn
));
2143 pqnode
->rn
= bgp_lock_node (rn
);
2147 pqnode
->safi
= safi
;
2148 work_queue_add (bm
->process_main_queue
, pqnode
);
2149 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2154 bgp_add_eoiu_mark (struct bgp
*bgp
)
2156 struct bgp_process_queue
*pqnode
;
2158 if (bm
->process_main_queue
== NULL
)
2161 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2162 sizeof (struct bgp_process_queue
));
2169 work_queue_add (bm
->process_main_queue
, pqnode
);
2173 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2177 peer
= THREAD_ARG (thread
);
2178 peer
->t_pmax_restart
= NULL
;
2180 if (bgp_debug_neighbor_events(peer
))
2181 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2184 peer_clear (peer
, NULL
);
2190 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2191 safi_t safi
, int always
)
2196 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2199 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2201 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2205 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2206 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2207 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2208 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2210 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2213 /* Convert AFI, SAFI to values for packet. */
2214 pkt_afi
= afi_int2iana (afi
);
2215 pkt_safi
= safi_int2iana (safi
);
2219 ndata
[0] = (pkt_afi
>> 8);
2221 ndata
[2] = pkt_safi
;
2222 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2223 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2224 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2225 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2227 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2228 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2229 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2232 /* Dynamic peers will just close their connection. */
2233 if (peer_dynamic_neighbor (peer
))
2236 /* restart timer start */
2237 if (peer
->pmax_restart
[afi
][safi
])
2239 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2241 if (bgp_debug_neighbor_events(peer
))
2242 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2243 peer
->host
, peer
->v_pmax_restart
);
2245 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2246 peer
->v_pmax_restart
);
2252 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2254 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2256 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2260 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2261 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2262 peer
->pmax
[afi
][safi
]);
2263 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2266 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2270 /* Unconditionally remove the route from the RIB, without taking
2271 * damping into consideration (eg, because the session went down)
2274 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2275 afi_t afi
, safi_t safi
)
2277 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2279 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2280 bgp_info_delete (rn
, ri
); /* keep historical info */
2282 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2286 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2287 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2289 int status
= BGP_DAMP_NONE
;
2291 /* apply dampening, if result is suppressed, we'll be retaining
2292 * the bgp_info in the RIB for historical reference.
2294 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2295 && peer
->sort
== BGP_PEER_EBGP
)
2296 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2297 == BGP_DAMP_SUPPRESSED
)
2299 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2304 if (safi
== SAFI_MPLS_VPN
) {
2305 struct bgp_node
*prn
= NULL
;
2306 struct bgp_table
*table
= NULL
;
2308 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2310 table
= (struct bgp_table
*)(prn
->info
);
2312 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2319 bgp_unlock_node(prn
);
2321 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2322 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2324 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2325 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2329 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2332 static struct bgp_info
*
2333 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2334 struct bgp_node
*rn
)
2336 struct bgp_info
*new;
2338 /* Make new BGP info. */
2339 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2341 new->instance
= instance
;
2342 new->sub_type
= sub_type
;
2345 new->uptime
= bgp_clock ();
2347 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2352 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2354 struct attr_extra
*extra
;
2358 extra
= bgp_attr_extra_get(attr
);
2360 if(eth_s_id
== NULL
)
2362 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2366 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2370 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2374 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2379 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2381 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2382 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2385 if(afi
!= AFI_L2VPN
)
2387 if (!info
->attr
|| !info
->attr
->extra
)
2389 memset(&temp
, 0, 16);
2390 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2391 info_gw_ip
= (union gw_addr
*)&temp
;
2392 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2397 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2398 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2401 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2403 info_gw_ip_remote
= gw_ip
;
2404 if(eth_s_id
== NULL
)
2405 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2407 info_eth_s_id_remote
= eth_s_id
;
2408 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2410 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2413 /* Check if received nexthop is valid or not. */
2415 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2417 struct attr_extra
*attre
= attr
->extra
;
2420 /* Only validated for unicast and multicast currently. */
2421 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2424 /* If NEXT_HOP is present, validate it. */
2425 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2427 if (attr
->nexthop
.s_addr
== 0 ||
2428 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2429 bgp_nexthop_self (bgp
, attr
))
2433 /* If MP_NEXTHOP is present, validate it. */
2434 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2435 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2436 * it is not an IPv6 link-local address.
2438 if (attre
&& attre
->mp_nexthop_len
)
2440 switch (attre
->mp_nexthop_len
)
2442 case BGP_ATTR_NHLEN_IPV4
:
2443 case BGP_ATTR_NHLEN_VPNV4
:
2444 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2445 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2448 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2449 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2450 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2451 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2452 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2453 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2466 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2467 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2468 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2469 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2472 int aspath_loop_count
= 0;
2473 struct bgp_node
*rn
;
2475 struct attr new_attr
;
2476 struct attr_extra new_extra
;
2477 struct attr
*attr_new
;
2478 struct bgp_info
*ri
;
2479 struct bgp_info
*new;
2481 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2484 int do_loop_check
= 1;
2486 int vnc_implicit_withdraw
= 0;
2489 memset (&new_attr
, 0, sizeof(struct attr
));
2490 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2493 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2494 label_buf
[0] = '\0';
2495 if (bgp_labeled_safi(safi
))
2496 sprintf (label_buf
, "label %u", label_pton(tag
));
2498 /* When peer's soft reconfiguration enabled. Record input packet in
2500 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2501 && peer
!= bgp
->peer_self
)
2502 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2504 /* Check previously received route. */
2505 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2506 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2507 ri
->addpath_rx_id
== addpath_id
)
2510 /* AS path local-as loop check. */
2511 if (peer
->change_local_as
)
2513 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2514 aspath_loop_count
= 1;
2516 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2518 reason
= "as-path contains our own AS;";
2523 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2524 * as-path is our ASN then we do not need to call aspath_loop_check
2526 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2527 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2530 /* AS path loop check. */
2533 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2534 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2535 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2537 reason
= "as-path contains our own AS;";
2542 /* Route reflector originator ID check. */
2543 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2544 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2546 reason
= "originator is us;";
2550 /* Route reflector cluster ID check. */
2551 if (bgp_cluster_filter (peer
, attr
))
2553 reason
= "reflected from the same cluster;";
2557 /* Apply incoming filter. */
2558 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2564 new_attr
.extra
= &new_extra
;
2565 bgp_attr_dup (&new_attr
, attr
);
2567 /* Apply incoming route-map.
2568 * NB: new_attr may now contain newly allocated values from route-map "set"
2569 * commands, so we need bgp_attr_flush in the error paths, until we intern
2570 * the attr (which takes over the memory references) */
2571 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2573 reason
= "route-map;";
2574 bgp_attr_flush (&new_attr
);
2578 /* next hop check. */
2579 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2581 reason
= "martian or self next-hop;";
2582 bgp_attr_flush (&new_attr
);
2586 attr_new
= bgp_attr_intern (&new_attr
);
2588 /* If the update is implicit withdraw. */
2591 ri
->uptime
= bgp_clock ();
2593 /* Same attribute comes in. */
2594 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2595 && attrhash_cmp (ri
->attr
, attr_new
)
2596 && (!bgp_labeled_safi(safi
) ||
2597 memcmp ((bgp_info_extra_get (ri
))->tag
, tag
, 3) == 0)
2598 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2599 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2601 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2602 && peer
->sort
== BGP_PEER_EBGP
2603 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2605 if (bgp_debug_update(peer
, p
, NULL
, 1))
2606 zlog_debug ("%s rcvd %s %s", peer
->host
,
2607 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2608 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2610 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2612 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2613 bgp_process (bgp
, rn
, afi
, safi
);
2616 else /* Duplicate - odd */
2618 if (bgp_debug_update(peer
, p
, NULL
, 1))
2620 if (!peer
->rcvd_attr_printed
)
2622 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2623 peer
->rcvd_attr_printed
= 1;
2626 zlog_debug ("%s rcvd %s %s...duplicate ignored",
2628 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2629 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2632 /* graceful restart STALE flag unset. */
2633 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2635 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2636 bgp_process (bgp
, rn
, afi
, safi
);
2640 bgp_unlock_node (rn
);
2641 bgp_attr_unintern (&attr_new
);
2646 /* Withdraw/Announce before we fully processed the withdraw */
2647 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2649 if (bgp_debug_update(peer
, p
, NULL
, 1))
2650 zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
2652 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2653 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2654 bgp_info_restore (rn
, ri
);
2657 /* Received Logging. */
2658 if (bgp_debug_update(peer
, p
, NULL
, 1))
2659 zlog_debug ("%s rcvd %s %s", peer
->host
,
2660 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2661 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2663 /* graceful restart STALE flag unset. */
2664 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2665 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2667 /* The attribute is changed. */
2668 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2670 /* implicit withdraw, decrement aggregate and pcount here.
2671 * only if update is accepted, they'll increment below.
2673 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2675 /* Update bgp route dampening information. */
2676 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2677 && peer
->sort
== BGP_PEER_EBGP
)
2679 /* This is implicit withdraw so we should update dampening
2681 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2682 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2685 if (safi
== SAFI_MPLS_VPN
) {
2686 struct bgp_node
*prn
= NULL
;
2687 struct bgp_table
*table
= NULL
;
2689 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2691 table
= (struct bgp_table
*)(prn
->info
);
2693 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2700 bgp_unlock_node(prn
);
2702 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2703 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2705 * Implicit withdraw case.
2707 ++vnc_implicit_withdraw
;
2708 vnc_import_bgp_del_route(bgp
, p
, ri
);
2709 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2714 /* Update to new attribute. */
2715 bgp_attr_unintern (&ri
->attr
);
2716 ri
->attr
= attr_new
;
2718 /* Update MPLS tag. */
2719 if (bgp_labeled_safi(safi
))
2720 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2723 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2725 if (vnc_implicit_withdraw
)
2728 * Add back the route with its new attributes (e.g., nexthop).
2729 * The route is still selected, until the route selection
2730 * queued by bgp_process actually runs. We have to make this
2731 * update to the VNC side immediately to avoid racing against
2732 * configuration changes (e.g., route-map changes) which
2733 * trigger re-importation of the entire RIB.
2735 vnc_import_bgp_add_route(bgp
, p
, ri
);
2736 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2740 /* Update Overlay Index */
2741 if(afi
== AFI_L2VPN
)
2743 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2744 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2747 /* Update bgp route dampening information. */
2748 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2749 && peer
->sort
== BGP_PEER_EBGP
)
2751 /* Now we do normal update dampening. */
2752 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2753 if (ret
== BGP_DAMP_SUPPRESSED
)
2755 bgp_unlock_node (rn
);
2760 /* Nexthop reachability check - for unicast and labeled-unicast.. */
2761 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2762 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2764 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2765 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2766 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2771 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2772 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2775 if (BGP_DEBUG(nht
, NHT
))
2777 char buf1
[INET6_ADDRSTRLEN
];
2778 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2779 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2781 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2785 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2788 if (safi
== SAFI_MPLS_VPN
)
2790 struct bgp_node
*prn
= NULL
;
2791 struct bgp_table
*table
= NULL
;
2793 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2796 table
= (struct bgp_table
*)(prn
->info
);
2798 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2805 bgp_unlock_node(prn
);
2809 /* Process change. */
2810 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2812 bgp_process (bgp
, rn
, afi
, safi
);
2813 bgp_unlock_node (rn
);
2816 if (SAFI_MPLS_VPN
== safi
)
2818 uint32_t label
= decode_label(tag
);
2820 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2823 if (SAFI_ENCAP
== safi
)
2825 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2831 } // End of implicit withdraw
2833 /* Received Logging. */
2834 if (bgp_debug_update(peer
, p
, NULL
, 1))
2836 if (!peer
->rcvd_attr_printed
)
2838 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2839 peer
->rcvd_attr_printed
= 1;
2842 zlog_debug ("%s rcvd %s%s ", peer
->host
,
2843 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2844 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2847 /* Make new BGP info. */
2848 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2850 /* Update MPLS tag. */
2851 if (bgp_labeled_safi(safi
))
2852 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2854 /* Update Overlay Index */
2855 if(afi
== AFI_L2VPN
)
2857 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2858 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2860 /* Nexthop reachability check. */
2861 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2862 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2864 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2865 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2866 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2871 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2872 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2875 if (BGP_DEBUG(nht
, NHT
))
2877 char buf1
[INET6_ADDRSTRLEN
];
2878 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2879 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2881 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2885 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2888 new->addpath_rx_id
= addpath_id
;
2890 /* Increment prefix */
2891 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2893 /* Register new BGP information. */
2894 bgp_info_add (rn
, new);
2896 /* route_node_get lock */
2897 bgp_unlock_node (rn
);
2900 if (safi
== SAFI_MPLS_VPN
)
2902 struct bgp_node
*prn
= NULL
;
2903 struct bgp_table
*table
= NULL
;
2905 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2908 table
= (struct bgp_table
*)(prn
->info
);
2910 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2917 bgp_unlock_node(prn
);
2921 /* If maximum prefix count is configured and current prefix
2923 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2926 /* Process change. */
2927 bgp_process (bgp
, rn
, afi
, safi
);
2930 if (SAFI_MPLS_VPN
== safi
)
2932 uint32_t label
= decode_label(tag
);
2934 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2937 if (SAFI_ENCAP
== safi
)
2939 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2946 /* This BGP update is filtered. Log the reason then update BGP
2949 if (bgp_debug_update(peer
, p
, NULL
, 1))
2951 if (!peer
->rcvd_attr_printed
)
2953 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2954 peer
->rcvd_attr_printed
= 1;
2957 zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
2959 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2960 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
, reason
);
2964 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2966 bgp_unlock_node (rn
);
2970 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2971 * a few lines above)
2973 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2975 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2983 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2984 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2985 struct prefix_rd
*prd
, u_char
*tag
, struct bgp_route_evpn
*evpn
)
2988 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2989 struct bgp_node
*rn
;
2990 struct bgp_info
*ri
;
2993 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2995 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3002 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3004 /* If peer is soft reconfiguration enabled. Record input packet for
3005 * further calculation.
3007 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3008 * routes that are filtered. This tanks out Quagga RS pretty badly due to
3009 * the iteration over all RS clients.
3010 * Since we need to remove the entry from adj_in anyway, do that first and
3011 * if there was no entry, we don't need to do anything more.
3013 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3014 && peer
!= bgp
->peer_self
)
3015 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
3017 if (bgp_debug_update (peer
, p
, NULL
, 1))
3018 zlog_debug ("%s withdrawing route %s not in adj-in",
3020 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3021 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3022 bgp_unlock_node (rn
);
3026 /* Lookup withdrawn route. */
3027 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3028 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
3029 ri
->addpath_rx_id
== addpath_id
)
3033 if (bgp_debug_update(peer
, p
, NULL
, 1))
3035 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
3037 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3038 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3041 /* Withdraw specified route from routing table. */
3042 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
3043 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
3044 else if (bgp_debug_update(peer
, p
, NULL
, 1))
3045 zlog_debug ("%s Can't find the route %s",
3047 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3048 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3050 /* Unlock bgp_node_get() lock. */
3051 bgp_unlock_node (rn
);
3057 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
3059 struct update_subgroup
*subgrp
;
3060 subgrp
= peer_subgroup(peer
, afi
, safi
);
3061 subgroup_default_originate(subgrp
, withdraw
);
3066 * bgp_stop_announce_route_timer
3069 bgp_stop_announce_route_timer (struct peer_af
*paf
)
3071 if (!paf
->t_announce_route
)
3074 THREAD_TIMER_OFF (paf
->t_announce_route
);
3078 * bgp_announce_route_timer_expired
3080 * Callback that is invoked when the route announcement timer for a
3084 bgp_announce_route_timer_expired (struct thread
*t
)
3086 struct peer_af
*paf
;
3089 paf
= THREAD_ARG (t
);
3092 if (peer
->status
!= Established
)
3095 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3098 peer_af_announce_route (paf
, 1);
3103 * bgp_announce_route
3105 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3108 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3110 struct peer_af
*paf
;
3111 struct update_subgroup
*subgrp
;
3113 paf
= peer_af_find (peer
, afi
, safi
);
3116 subgrp
= PAF_SUBGRP(paf
);
3119 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3120 * or a refresh has already been triggered.
3122 if (!subgrp
|| paf
->t_announce_route
)
3126 * Start a timer to stagger/delay the announce. This serves
3127 * two purposes - announcement can potentially be combined for
3128 * multiple peers and the announcement doesn't happen in the
3131 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3132 (subgrp
->peer_count
== 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
: BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3133 &paf
->t_announce_route
);
3137 * Announce routes from all AF tables to a peer.
3139 * This should ONLY be called when there is a need to refresh the
3140 * routes to the peer based on a policy change for this peer alone
3141 * or a route refresh request received from the peer.
3142 * The operation will result in splitting the peer from its existing
3143 * subgroups and putting it in new subgroups.
3146 bgp_announce_route_all (struct peer
*peer
)
3151 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3152 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3153 bgp_announce_route (peer
, afi
, safi
);
3157 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3158 struct bgp_table
*table
, struct prefix_rd
*prd
)
3161 struct bgp_node
*rn
;
3162 struct bgp_adj_in
*ain
;
3165 table
= peer
->bgp
->rib
[afi
][safi
];
3167 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3168 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3170 if (ain
->peer
== peer
)
3172 struct bgp_info
*ri
= rn
->info
;
3173 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3175 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3176 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3181 bgp_unlock_node (rn
);
3189 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3191 struct bgp_node
*rn
;
3192 struct bgp_table
*table
;
3194 if (peer
->status
!= Established
)
3197 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3198 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3200 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3201 rn
= bgp_route_next (rn
))
3202 if ((table
= rn
->info
) != NULL
)
3204 struct prefix_rd prd
;
3205 prd
.family
= AF_UNSPEC
;
3207 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3209 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3214 struct bgp_clear_node_queue
3216 struct bgp_node
*rn
;
3219 static wq_item_status
3220 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3222 struct bgp_clear_node_queue
*cnq
= data
;
3223 struct bgp_node
*rn
= cnq
->rn
;
3224 struct peer
*peer
= wq
->spec
.data
;
3225 struct bgp_info
*ri
;
3226 afi_t afi
= bgp_node_table (rn
)->afi
;
3227 safi_t safi
= bgp_node_table (rn
)->safi
;
3229 assert (rn
&& peer
);
3231 /* It is possible that we have multiple paths for a prefix from a peer
3232 * if that peer is using AddPath.
3234 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3235 if (ri
->peer
== peer
)
3237 /* graceful restart STALE flag set. */
3238 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3239 && peer
->nsf
[afi
][safi
]
3240 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3241 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3242 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3244 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3250 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3252 struct bgp_clear_node_queue
*cnq
= data
;
3253 struct bgp_node
*rn
= cnq
->rn
;
3254 struct bgp_table
*table
= bgp_node_table (rn
);
3256 bgp_unlock_node (rn
);
3257 bgp_table_unlock (table
);
3258 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3262 bgp_clear_node_complete (struct work_queue
*wq
)
3264 struct peer
*peer
= wq
->spec
.data
;
3266 /* Tickle FSM to start moving again */
3267 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3269 peer_unlock (peer
); /* bgp_clear_route */
3273 bgp_clear_node_queue_init (struct peer
*peer
)
3275 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3277 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3278 #undef CLEAR_QUEUE_NAME_LEN
3280 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3282 zlog_err ("%s: Failed to allocate work queue", __func__
);
3285 peer
->clear_node_queue
->spec
.hold
= 10;
3286 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3287 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3288 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3289 peer
->clear_node_queue
->spec
.max_retries
= 0;
3291 /* we only 'lock' this peer reference when the queue is actually active */
3292 peer
->clear_node_queue
->spec
.data
= peer
;
3296 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3297 struct bgp_table
*table
)
3299 struct bgp_node
*rn
;
3300 int force
= bm
->process_main_queue
? 0 : 1;
3303 table
= peer
->bgp
->rib
[afi
][safi
];
3305 /* If still no table => afi/safi isn't configured at all or smth. */
3309 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3311 struct bgp_info
*ri
, *next
;
3312 struct bgp_adj_in
*ain
;
3313 struct bgp_adj_in
*ain_next
;
3315 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3316 * queued for every clearing peer, regardless of whether it is
3317 * relevant to the peer at hand.
3319 * Overview: There are 3 different indices which need to be
3320 * scrubbed, potentially, when a peer is removed:
3322 * 1 peer's routes visible via the RIB (ie accepted routes)
3323 * 2 peer's routes visible by the (optional) peer's adj-in index
3324 * 3 other routes visible by the peer's adj-out index
3326 * 3 there is no hurry in scrubbing, once the struct peer is
3327 * removed from bgp->peer, we could just GC such deleted peer's
3328 * adj-outs at our leisure.
3330 * 1 and 2 must be 'scrubbed' in some way, at least made
3331 * invisible via RIB index before peer session is allowed to be
3332 * brought back up. So one needs to know when such a 'search' is
3337 * - there'd be a single global queue or a single RIB walker
3338 * - rather than tracking which route_nodes still need to be
3339 * examined on a peer basis, we'd track which peers still
3342 * Given that our per-peer prefix-counts now should be reliable,
3343 * this may actually be achievable. It doesn't seem to be a huge
3344 * problem at this time,
3346 * It is possible that we have multiple paths for a prefix from a peer
3347 * if that peer is using AddPath.
3352 ain_next
= ain
->next
;
3354 if (ain
->peer
== peer
)
3356 bgp_adj_in_remove (rn
, ain
);
3357 bgp_unlock_node (rn
);
3363 for (ri
= rn
->info
; ri
; ri
= next
)
3366 if (ri
->peer
!= peer
)
3370 bgp_info_reap (rn
, ri
);
3373 struct bgp_clear_node_queue
*cnq
;
3375 /* both unlocked in bgp_clear_node_queue_del */
3376 bgp_table_lock (bgp_node_table (rn
));
3378 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3379 sizeof (struct bgp_clear_node_queue
));
3381 work_queue_add (peer
->clear_node_queue
, cnq
);
3390 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3392 struct bgp_node
*rn
;
3393 struct bgp_table
*table
;
3395 if (peer
->clear_node_queue
== NULL
)
3396 bgp_clear_node_queue_init (peer
);
3398 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3399 * Idle until it receives a Clearing_Completed event. This protects
3400 * against peers which flap faster than we can we clear, which could
3403 * a) race with routes from the new session being installed before
3404 * clear_route_node visits the node (to delete the route of that
3406 * b) resource exhaustion, clear_route_node likely leads to an entry
3407 * on the process_main queue. Fast-flapping could cause that queue
3411 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3412 * the unlock will happen upon work-queue completion; other wise, the
3413 * unlock happens at the end of this function.
3415 if (!peer
->clear_node_queue
->thread
)
3418 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3419 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3421 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3422 rn
= bgp_route_next (rn
))
3423 if ((table
= rn
->info
) != NULL
)
3424 bgp_clear_route_table (peer
, afi
, safi
, table
);
3426 /* unlock if no nodes got added to the clear-node-queue. */
3427 if (!peer
->clear_node_queue
->thread
)
3433 bgp_clear_route_all (struct peer
*peer
)
3438 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3439 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3440 bgp_clear_route (peer
, afi
, safi
);
3443 rfapiProcessPeerDown(peer
);
3448 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3450 struct bgp_table
*table
;
3451 struct bgp_node
*rn
;
3452 struct bgp_adj_in
*ain
;
3453 struct bgp_adj_in
*ain_next
;
3455 table
= peer
->bgp
->rib
[afi
][safi
];
3457 /* It is possible that we have multiple paths for a prefix from a peer
3458 * if that peer is using AddPath.
3460 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3466 ain_next
= ain
->next
;
3468 if (ain
->peer
== peer
)
3470 bgp_adj_in_remove (rn
, ain
);
3471 bgp_unlock_node (rn
);
3480 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3482 struct bgp_node
*rn
;
3483 struct bgp_info
*ri
;
3484 struct bgp_table
*table
;
3486 if ( safi
== SAFI_MPLS_VPN
)
3488 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3490 struct bgp_node
*rm
;
3491 struct bgp_info
*ri
;
3493 /* look for neighbor in tables */
3494 if ((table
= rn
->info
) != NULL
)
3496 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3497 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3498 if (ri
->peer
== peer
)
3500 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3501 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3509 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3510 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3511 if (ri
->peer
== peer
)
3513 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3514 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3521 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3523 struct bgp_node
*rn
;
3524 struct bgp_info
*ri
;
3525 struct bgp_info
*next
;
3527 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3528 for (ri
= rn
->info
; ri
; ri
= next
)
3531 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3532 && ri
->type
== ZEBRA_ROUTE_BGP
3533 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3534 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3537 if (table
->owner
&& table
->owner
->bgp
)
3538 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3540 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3541 bgp_info_reap (rn
, ri
);
3546 /* Delete all kernel routes. */
3548 bgp_cleanup_routes (struct bgp
*bgp
)
3551 struct bgp_node
*rn
;
3553 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3555 if (afi
== AFI_L2VPN
)
3557 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3559 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3561 if (afi
!= AFI_L2VPN
)
3564 safi
= SAFI_MPLS_VPN
;
3565 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3566 rn
= bgp_route_next (rn
))
3570 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3571 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3573 bgp_unlock_node(rn
);
3577 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3578 rn
= bgp_route_next (rn
))
3582 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3583 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3585 bgp_unlock_node(rn
);
3590 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3591 rn
= bgp_route_next (rn
))
3595 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3596 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3598 bgp_unlock_node(rn
);
3607 bgp_zclient_reset ();
3608 access_list_reset ();
3609 prefix_list_reset ();
3613 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3615 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3616 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3619 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3622 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3623 struct bgp_nlri
*packet
)
3632 int addpath_encoded
;
3633 u_int32_t addpath_id
;
3635 /* Check peer status. */
3636 if (peer
->status
!= Established
)
3640 lim
= pnt
+ packet
->length
;
3642 safi
= packet
->safi
;
3644 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3646 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3647 syntactic validity. If the field is syntactically incorrect,
3648 then the Error Subcode is set to Invalid Network Field. */
3649 for (; pnt
< lim
; pnt
+= psize
)
3651 /* Clear prefix structure. */
3652 memset (&p
, 0, sizeof (struct prefix
));
3654 if (addpath_encoded
)
3657 /* When packet overflow occurs return immediately. */
3658 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3661 addpath_id
= ntohl(*((uint32_t*) pnt
));
3662 pnt
+= BGP_ADDPATH_ID_LEN
;
3665 /* Fetch prefix length. */
3666 p
.prefixlen
= *pnt
++;
3667 /* afi/safi validity already verified by caller, bgp_update_receive */
3668 p
.family
= afi2family (afi
);
3670 /* Prefix length check. */
3671 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3673 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3674 peer
->host
, p
.prefixlen
, packet
->afi
);
3678 /* Packet size overflow check. */
3679 psize
= PSIZE (p
.prefixlen
);
3681 /* When packet overflow occur return immediately. */
3682 if (pnt
+ psize
> lim
)
3684 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3685 peer
->host
, p
.prefixlen
);
3689 /* Defensive coding, double-check the psize fits in a struct prefix */
3690 if (psize
> (ssize_t
) sizeof(p
.u
))
3692 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3693 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3697 /* Fetch prefix from NLRI packet. */
3698 memcpy (&p
.u
.prefix
, pnt
, psize
);
3700 /* Check address. */
3701 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3703 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3705 /* From RFC4271 Section 6.3:
3707 * If a prefix in the NLRI field is semantically incorrect
3708 * (e.g., an unexpected multicast IP address), an error SHOULD
3709 * be logged locally, and the prefix SHOULD be ignored.
3711 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3712 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3717 /* Check address. */
3718 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3720 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3724 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3725 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3729 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3733 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3734 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3740 /* Normal process. */
3742 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3743 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3745 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3746 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3748 /* Address family configuration mismatch or maximum-prefix count
3754 /* Packet length consistency check. */
3757 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3765 static struct bgp_static
*
3766 bgp_static_new (void)
3768 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3772 bgp_static_free (struct bgp_static
*bgp_static
)
3774 if (bgp_static
->rmap
.name
)
3775 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3776 if(bgp_static
->eth_s_id
)
3777 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3778 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3782 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3783 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3785 struct bgp_node
*rn
;
3786 struct bgp_info
*ri
;
3787 struct bgp_info
*new;
3788 struct bgp_info info
;
3790 struct attr
*attr_new
;
3793 int vnc_implicit_withdraw
= 0;
3796 assert (bgp_static
);
3800 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3802 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3804 attr
.nexthop
= bgp_static
->igpnexthop
;
3805 attr
.med
= bgp_static
->igpmetric
;
3806 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3808 if (bgp_static
->atomic
)
3809 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3811 /* Store label index, if required. */
3812 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3814 (bgp_attr_extra_get (&attr
))->label_index
= bgp_static
->label_index
;
3815 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3818 /* Apply route-map. */
3819 if (bgp_static
->rmap
.name
)
3821 struct attr attr_tmp
= attr
;
3822 info
.peer
= bgp
->peer_self
;
3823 info
.attr
= &attr_tmp
;
3825 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3827 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3829 bgp
->peer_self
->rmap_type
= 0;
3831 if (ret
== RMAP_DENYMATCH
)
3833 /* Free uninterned attribute. */
3834 bgp_attr_flush (&attr_tmp
);
3836 /* Unintern original. */
3837 aspath_unintern (&attr
.aspath
);
3838 bgp_attr_extra_free (&attr
);
3839 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3842 attr_new
= bgp_attr_intern (&attr_tmp
);
3845 attr_new
= bgp_attr_intern (&attr
);
3847 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3848 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3849 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3854 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3855 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3856 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3858 bgp_unlock_node (rn
);
3859 bgp_attr_unintern (&attr_new
);
3860 aspath_unintern (&attr
.aspath
);
3861 bgp_attr_extra_free (&attr
);
3866 /* The attribute is changed. */
3867 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3869 /* Rewrite BGP route information. */
3870 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3871 bgp_info_restore(rn
, ri
);
3873 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3875 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3877 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3880 * Implicit withdraw case.
3881 * We have to do this before ri is changed
3883 ++vnc_implicit_withdraw
;
3884 vnc_import_bgp_del_route(bgp
, p
, ri
);
3885 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3889 bgp_attr_unintern (&ri
->attr
);
3890 ri
->attr
= attr_new
;
3891 ri
->uptime
= bgp_clock ();
3893 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3895 if (vnc_implicit_withdraw
)
3897 vnc_import_bgp_add_route(bgp
, p
, ri
);
3898 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3903 /* Nexthop reachability check. */
3904 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3905 safi
== SAFI_UNICAST
)
3907 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0) &&
3908 safi
== SAFI_UNICAST
)
3909 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3912 if (BGP_DEBUG(nht
, NHT
))
3914 char buf1
[INET6_ADDRSTRLEN
];
3915 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3917 zlog_debug("%s(%s): Route not in table, not advertising",
3918 __FUNCTION__
, buf1
);
3920 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3925 /* Delete the NHT structure if any, if we're toggling between
3926 * enabling/disabling import check. We deregister the route
3927 * from NHT to avoid overloading NHT and the process interaction
3929 bgp_unlink_nexthop(ri
);
3930 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3932 /* Process change. */
3933 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3934 bgp_process (bgp
, rn
, afi
, safi
);
3935 bgp_unlock_node (rn
);
3936 aspath_unintern (&attr
.aspath
);
3937 bgp_attr_extra_free (&attr
);
3942 /* Make new BGP info. */
3943 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3945 /* Nexthop reachability check. */
3946 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3948 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3949 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3952 if (BGP_DEBUG(nht
, NHT
))
3954 char buf1
[INET6_ADDRSTRLEN
];
3955 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3957 zlog_debug("%s(%s): Route not in table, not advertising",
3958 __FUNCTION__
, buf1
);
3960 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3965 /* Delete the NHT structure if any, if we're toggling between
3966 * enabling/disabling import check. We deregister the route
3967 * from NHT to avoid overloading NHT and the process interaction
3969 bgp_unlink_nexthop(new);
3971 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3974 /* Aggregate address increment. */
3975 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3977 /* Register new BGP information. */
3978 bgp_info_add (rn
, new);
3980 /* route_node_get lock */
3981 bgp_unlock_node (rn
);
3983 /* Process change. */
3984 bgp_process (bgp
, rn
, afi
, safi
);
3986 /* Unintern original. */
3987 aspath_unintern (&attr
.aspath
);
3988 bgp_attr_extra_free (&attr
);
3992 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3995 struct bgp_node
*rn
;
3996 struct bgp_info
*ri
;
3998 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4000 /* Check selected route and self inserted route. */
4001 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4002 if (ri
->peer
== bgp
->peer_self
4003 && ri
->type
== ZEBRA_ROUTE_BGP
4004 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4007 /* Withdraw static BGP route from routing table. */
4010 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4011 bgp_unlink_nexthop(ri
);
4012 bgp_info_delete (rn
, ri
);
4013 bgp_process (bgp
, rn
, afi
, safi
);
4016 /* Unlock bgp_node_lookup. */
4017 bgp_unlock_node (rn
);
4021 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4024 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4025 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
4027 struct bgp_node
*rn
;
4028 struct bgp_info
*ri
;
4030 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4032 /* Check selected route and self inserted route. */
4033 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4034 if (ri
->peer
== bgp
->peer_self
4035 && ri
->type
== ZEBRA_ROUTE_BGP
4036 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4039 /* Withdraw static BGP route from routing table. */
4043 rfapiProcessWithdraw(
4052 1); /* Kill, since it is an administrative change */
4054 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4055 bgp_info_delete (rn
, ri
);
4056 bgp_process (bgp
, rn
, afi
, safi
);
4059 /* Unlock bgp_node_lookup. */
4060 bgp_unlock_node (rn
);
4064 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4065 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4067 struct bgp_node
*rn
;
4068 struct bgp_info
*new;
4069 struct attr
*attr_new
;
4070 struct attr attr
= { 0 };
4071 struct bgp_info
*ri
;
4073 u_int32_t label
= 0;
4077 assert (bgp_static
);
4079 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4081 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4083 attr
.nexthop
= bgp_static
->igpnexthop
;
4084 attr
.med
= bgp_static
->igpmetric
;
4085 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4087 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4089 if (bgp_static
->igpnexthop
.s_addr
)
4091 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4092 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4095 if(afi
== AFI_L2VPN
)
4097 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4098 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4099 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4100 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4101 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4102 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4104 struct bgp_encap_type_vxlan bet
;
4105 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4106 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4107 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4109 if (bgp_static
->router_mac
)
4111 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4114 /* Apply route-map. */
4115 if (bgp_static
->rmap
.name
)
4117 struct attr attr_tmp
= attr
;
4118 struct bgp_info info
;
4121 info
.peer
= bgp
->peer_self
;
4122 info
.attr
= &attr_tmp
;
4124 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4126 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4128 bgp
->peer_self
->rmap_type
= 0;
4130 if (ret
== RMAP_DENYMATCH
)
4132 /* Free uninterned attribute. */
4133 bgp_attr_flush (&attr_tmp
);
4135 /* Unintern original. */
4136 aspath_unintern (&attr
.aspath
);
4137 bgp_attr_extra_free (&attr
);
4138 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4143 attr_new
= bgp_attr_intern (&attr_tmp
);
4147 attr_new
= bgp_attr_intern (&attr
);
4150 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4151 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4152 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4158 memset(&add
, 0, sizeof(union gw_addr
));
4159 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4160 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4161 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4163 bgp_unlock_node (rn
);
4164 bgp_attr_unintern (&attr_new
);
4165 aspath_unintern (&attr
.aspath
);
4166 bgp_attr_extra_free (&attr
);
4171 /* The attribute is changed. */
4172 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4174 /* Rewrite BGP route information. */
4175 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4176 bgp_info_restore(rn
, ri
);
4178 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4179 bgp_attr_unintern (&ri
->attr
);
4180 ri
->attr
= attr_new
;
4181 ri
->uptime
= bgp_clock ();
4184 label
= decode_label (ri
->extra
->tag
);
4187 /* Process change. */
4188 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4189 bgp_process (bgp
, rn
, afi
, safi
);
4191 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4192 ri
->attr
, afi
, safi
,
4193 ri
->type
, ri
->sub_type
, &label
);
4195 bgp_unlock_node (rn
);
4196 aspath_unintern (&attr
.aspath
);
4197 bgp_attr_extra_free (&attr
);
4203 /* Make new BGP info. */
4204 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4206 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4207 new->extra
= bgp_info_extra_new();
4208 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4210 label
= decode_label (bgp_static
->tag
);
4213 /* Aggregate address increment. */
4214 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4216 /* Register new BGP information. */
4217 bgp_info_add (rn
, new);
4218 /* route_node_get lock */
4219 bgp_unlock_node (rn
);
4221 /* Process change. */
4222 bgp_process (bgp
, rn
, afi
, safi
);
4225 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4226 new->attr
, afi
, safi
,
4227 new->type
, new->sub_type
, &label
);
4230 /* Unintern original. */
4231 aspath_unintern (&attr
.aspath
);
4232 bgp_attr_extra_free (&attr
);
4235 /* Configure static BGP network. When user don't run zebra, static
4236 route should be installed as valid. */
4238 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4239 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4240 u_int32_t label_index
)
4242 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4245 struct bgp_static
*bgp_static
;
4246 struct bgp_node
*rn
;
4247 u_char need_update
= 0;
4249 /* Convert IP prefix string to struct prefix. */
4250 ret
= str2prefix (ip_str
, &p
);
4253 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4256 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4258 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4265 /* Set BGP static route configuration. */
4266 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4270 /* Configuration change. */
4271 bgp_static
= rn
->info
;
4273 /* Label index cannot be changed. */
4274 if (bgp_static
->label_index
!= label_index
)
4276 vty_out (vty
, "%% Label index cannot be changed%s", VTY_NEWLINE
);
4280 /* Check previous routes are installed into BGP. */
4281 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4284 bgp_static
->backdoor
= backdoor
;
4288 if (bgp_static
->rmap
.name
)
4289 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4290 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4291 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4295 if (bgp_static
->rmap
.name
)
4296 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4297 bgp_static
->rmap
.name
= NULL
;
4298 bgp_static
->rmap
.map
= NULL
;
4299 bgp_static
->valid
= 0;
4301 bgp_unlock_node (rn
);
4305 /* New configuration. */
4306 bgp_static
= bgp_static_new ();
4307 bgp_static
->backdoor
= backdoor
;
4308 bgp_static
->valid
= 0;
4309 bgp_static
->igpmetric
= 0;
4310 bgp_static
->igpnexthop
.s_addr
= 0;
4311 bgp_static
->label_index
= label_index
;
4315 if (bgp_static
->rmap
.name
)
4316 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4317 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4318 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4320 rn
->info
= bgp_static
;
4323 bgp_static
->valid
= 1;
4325 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4327 if (! bgp_static
->backdoor
)
4328 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4333 /* Configure static BGP network. */
4335 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4336 afi_t afi
, safi_t safi
)
4338 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4341 struct bgp_static
*bgp_static
;
4342 struct bgp_node
*rn
;
4344 /* Convert IP prefix string to struct prefix. */
4345 ret
= str2prefix (ip_str
, &p
);
4348 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4351 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4353 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4360 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4363 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4368 bgp_static
= rn
->info
;
4370 /* Update BGP RIB. */
4371 if (! bgp_static
->backdoor
)
4372 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4374 /* Clear configuration. */
4375 bgp_static_free (bgp_static
);
4377 bgp_unlock_node (rn
);
4378 bgp_unlock_node (rn
);
4384 bgp_static_add (struct bgp
*bgp
)
4388 struct bgp_node
*rn
;
4389 struct bgp_node
*rm
;
4390 struct bgp_table
*table
;
4391 struct bgp_static
*bgp_static
;
4393 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4394 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4395 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4396 if (rn
->info
!= NULL
)
4398 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4402 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4404 bgp_static
= rm
->info
;
4405 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4410 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4415 /* Called from bgp_delete(). Delete all static routes from the BGP
4418 bgp_static_delete (struct bgp
*bgp
)
4422 struct bgp_node
*rn
;
4423 struct bgp_node
*rm
;
4424 struct bgp_table
*table
;
4425 struct bgp_static
*bgp_static
;
4427 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4428 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4429 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4430 if (rn
->info
!= NULL
)
4432 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4436 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4438 bgp_static
= rm
->info
;
4439 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4441 (struct prefix_rd
*)&rn
->p
,
4443 bgp_static_free (bgp_static
);
4445 bgp_unlock_node (rn
);
4450 bgp_static
= rn
->info
;
4451 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4452 bgp_static_free (bgp_static
);
4454 bgp_unlock_node (rn
);
4460 bgp_static_redo_import_check (struct bgp
*bgp
)
4464 struct bgp_node
*rn
;
4465 struct bgp_node
*rm
;
4466 struct bgp_table
*table
;
4467 struct bgp_static
*bgp_static
;
4469 /* Use this flag to force reprocessing of the route */
4470 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4471 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4472 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4473 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4474 if (rn
->info
!= NULL
)
4476 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4480 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4482 bgp_static
= rm
->info
;
4483 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4488 bgp_static
= rn
->info
;
4489 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4492 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4496 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4498 struct bgp_table
*table
;
4499 struct bgp_node
*rn
;
4500 struct bgp_info
*ri
;
4502 table
= bgp
->rib
[afi
][safi
];
4503 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4505 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4507 if (ri
->peer
== bgp
->peer_self
&&
4508 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4509 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4510 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4511 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4513 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4514 bgp_unlink_nexthop(ri
);
4515 bgp_info_delete (rn
, ri
);
4516 bgp_process (bgp
, rn
, afi
, safi
);
4523 * Purge all networks and redistributed routes from routing table.
4524 * Invoked upon the instance going down.
4527 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4532 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4533 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4534 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4539 * Currently this is used to set static routes for VPN and ENCAP.
4540 * I think it can probably be factored with bgp_static_set.
4543 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4544 const char *rd_str
, const char *tag_str
,
4545 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4546 const char *ethtag
, const char *routermac
)
4548 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4551 struct prefix_rd prd
;
4552 struct bgp_node
*prn
;
4553 struct bgp_node
*rn
;
4554 struct bgp_table
*table
;
4555 struct bgp_static
*bgp_static
;
4558 struct prefix gw_ip
;
4560 if(safi
== SAFI_EVPN
)
4565 /* validate ip prefix */
4566 ret
= str2prefix (ip_str
, &p
);
4569 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4573 if ( (afi
== AFI_L2VPN
) &&
4574 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4576 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4580 ret
= str2prefix_rd (rd_str
, &prd
);
4583 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4589 ret
= str2tag (tag_str
, tag
);
4592 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4598 encode_label (0, tag
);
4600 if (safi
== SAFI_EVPN
)
4602 if( esi
&& str2esi (esi
, NULL
) == 0)
4604 vty_out (vty
, "%% Malformed ESI%s", VTY_NEWLINE
);
4607 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4609 vty_out (vty
, "%% Malformed Router MAC%s", VTY_NEWLINE
);
4614 memset (&gw_ip
, 0, sizeof (struct prefix
));
4615 ret
= str2prefix (gwip
, &gw_ip
);
4618 vty_out (vty
, "%% Malformed GatewayIp%s", VTY_NEWLINE
);
4621 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4622 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4624 vty_out (vty
, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE
);
4629 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4630 (struct prefix
*)&prd
);
4631 if (prn
->info
== NULL
)
4632 prn
->info
= bgp_table_init (afi
, safi
);
4634 bgp_unlock_node (prn
);
4637 rn
= bgp_node_get (table
, &p
);
4641 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4642 bgp_unlock_node (rn
);
4646 /* New configuration. */
4647 bgp_static
= bgp_static_new ();
4648 bgp_static
->backdoor
= 0;
4649 bgp_static
->valid
= 0;
4650 bgp_static
->igpmetric
= 0;
4651 bgp_static
->igpnexthop
.s_addr
= 0;
4652 memcpy(bgp_static
->tag
, tag
, 3);
4653 bgp_static
->prd
= prd
;
4657 if (bgp_static
->rmap
.name
)
4658 free (bgp_static
->rmap
.name
);
4659 bgp_static
->rmap
.name
= strdup (rmap_str
);
4660 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4663 if (safi
== SAFI_EVPN
)
4667 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4668 str2esi (esi
, bgp_static
->eth_s_id
);
4672 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4673 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4676 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4678 rn
->info
= bgp_static
;
4680 bgp_static
->valid
= 1;
4681 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4687 /* Configure static BGP network. */
4689 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4690 const char *rd_str
, const char *tag_str
,
4691 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4693 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4696 struct prefix_rd prd
;
4697 struct bgp_node
*prn
;
4698 struct bgp_node
*rn
;
4699 struct bgp_table
*table
;
4700 struct bgp_static
*bgp_static
;
4704 if(safi
== SAFI_EVPN
)
4709 /* Convert IP prefix string to struct prefix. */
4710 ret
= str2prefix (ip_str
, &p
);
4713 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4717 if ( (afi
== AFI_L2VPN
) &&
4718 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4720 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4723 ret
= str2prefix_rd (rd_str
, &prd
);
4726 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4730 ret
= str2tag (tag_str
, tag
);
4733 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4737 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4738 (struct prefix
*)&prd
);
4739 if (prn
->info
== NULL
)
4740 prn
->info
= bgp_table_init (afi
, safi
);
4742 bgp_unlock_node (prn
);
4745 rn
= bgp_node_lookup (table
, &p
);
4749 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
, tag
);
4751 bgp_static
= rn
->info
;
4752 bgp_static_free (bgp_static
);
4754 bgp_unlock_node (rn
);
4755 bgp_unlock_node (rn
);
4758 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4764 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4765 const char *rmap_name
)
4767 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4768 struct bgp_rmap
*rmap
;
4770 rmap
= &bgp
->table_map
[afi
][safi
];
4774 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4775 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4776 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4781 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4786 bgp_zebra_announce_table(bgp
, afi
, safi
);
4792 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4793 const char *rmap_name
)
4795 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4796 struct bgp_rmap
*rmap
;
4798 rmap
= &bgp
->table_map
[afi
][safi
];
4800 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4804 bgp_zebra_announce_table(bgp
, afi
, safi
);
4810 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4811 safi_t safi
, int *write
)
4813 if (bgp
->table_map
[afi
][safi
].name
)
4815 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4816 vty_out (vty
, " table-map %s%s",
4817 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4823 DEFUN (bgp_table_map
,
4826 "BGP table to RIB route download filter\n"
4827 "Name of the route map\n")
4830 return bgp_table_map_set (vty
,
4831 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4833 DEFUN (no_bgp_table_map
,
4834 no_bgp_table_map_cmd
,
4835 "no table-map WORD",
4837 "BGP table to RIB route download filter\n"
4838 "Name of the route map\n")
4841 return bgp_table_map_unset (vty
,
4842 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4847 "network A.B.C.D/M",
4848 "Specify a network to announce via BGP\n"
4851 int idx_ipv4_prefixlen
= 1;
4852 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4853 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4854 BGP_INVALID_LABEL_INDEX
);
4857 DEFUN (bgp_network_route_map
,
4858 bgp_network_route_map_cmd
,
4859 "network A.B.C.D/M route-map WORD",
4860 "Specify a network to announce via BGP\n"
4862 "Route-map to modify the attributes\n"
4863 "Name of the route map\n")
4865 int idx_ipv4_prefixlen
= 1;
4867 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4868 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4869 BGP_INVALID_LABEL_INDEX
);
4872 DEFUN (bgp_network_backdoor
,
4873 bgp_network_backdoor_cmd
,
4874 "network A.B.C.D/M backdoor",
4875 "Specify a network to announce via BGP\n"
4877 "Specify a BGP backdoor route\n")
4879 int idx_ipv4_prefixlen
= 1;
4880 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4881 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4884 DEFUN (bgp_network_mask
,
4885 bgp_network_mask_cmd
,
4886 "network A.B.C.D mask A.B.C.D",
4887 "Specify a network to announce via BGP\n"
4895 char prefix_str
[BUFSIZ
];
4897 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4900 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4904 return bgp_static_set (vty
, prefix_str
,
4905 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
4908 DEFUN (bgp_network_mask_route_map
,
4909 bgp_network_mask_route_map_cmd
,
4910 "network A.B.C.D mask A.B.C.D route-map WORD",
4911 "Specify a network to announce via BGP\n"
4915 "Route-map to modify the attributes\n"
4916 "Name of the route map\n")
4922 char prefix_str
[BUFSIZ
];
4924 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4927 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4931 return bgp_static_set (vty
, prefix_str
,
4932 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
4935 DEFUN (bgp_network_mask_backdoor
,
4936 bgp_network_mask_backdoor_cmd
,
4937 "network A.B.C.D mask A.B.C.D backdoor",
4938 "Specify a network to announce via BGP\n"
4942 "Specify a BGP backdoor route\n")
4947 char prefix_str
[BUFSIZ
];
4949 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4952 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4956 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4958 BGP_INVALID_LABEL_INDEX
);
4961 DEFUN (bgp_network_mask_natural
,
4962 bgp_network_mask_natural_cmd
,
4964 "Specify a network to announce via BGP\n"
4969 char prefix_str
[BUFSIZ
];
4971 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4974 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4978 return bgp_static_set (vty
, prefix_str
,
4979 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4980 BGP_INVALID_LABEL_INDEX
);
4983 DEFUN (bgp_network_mask_natural_route_map
,
4984 bgp_network_mask_natural_route_map_cmd
,
4985 "network A.B.C.D route-map WORD",
4986 "Specify a network to announce via BGP\n"
4988 "Route-map to modify the attributes\n"
4989 "Name of the route map\n")
4994 char prefix_str
[BUFSIZ
];
4996 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4999 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5003 return bgp_static_set (vty
, prefix_str
,
5004 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5005 BGP_INVALID_LABEL_INDEX
);
5008 DEFUN (bgp_network_mask_natural_backdoor
,
5009 bgp_network_mask_natural_backdoor_cmd
,
5010 "network A.B.C.D backdoor",
5011 "Specify a network to announce via BGP\n"
5013 "Specify a BGP backdoor route\n")
5017 char prefix_str
[BUFSIZ
];
5019 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5022 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5026 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5027 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5030 DEFUN (bgp_network_label_index
,
5031 bgp_network_label_index_cmd
,
5032 "network A.B.C.D/M label-index (0-4294967294)",
5033 "Specify a network to announce via BGP\n"
5034 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5035 "Label index to associate with the prefix\n"
5036 "Label index value\n")
5038 u_int32_t label_index
;
5040 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5041 return bgp_static_set (vty
, argv
[1]->arg
,
5042 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5045 DEFUN (bgp_network_label_index_route_map
,
5046 bgp_network_label_index_route_map_cmd
,
5047 "network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5048 "Specify a network to announce via BGP\n"
5050 "Label index to associate with the prefix\n"
5051 "Label index value\n"
5052 "Route-map to modify the attributes\n"
5053 "Name of the route map\n")
5055 u_int32_t label_index
;
5057 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5058 return bgp_static_set (vty
, argv
[1]->arg
,
5059 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5062 DEFUN (no_bgp_network
,
5064 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5066 "Specify a network to announce via BGP\n"
5068 "Specify a BGP backdoor route\n"
5069 "Route-map to modify the attributes\n"
5070 "Name of the route map\n")
5072 int idx_ipv4_prefixlen
= 2;
5073 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5074 bgp_node_safi (vty
));
5077 DEFUN (no_bgp_network_mask
,
5078 no_bgp_network_mask_cmd
,
5079 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5081 "Specify a network to announce via BGP\n"
5085 "Specify a BGP backdoor route\n"
5086 "Route-map to modify the attributes\n"
5087 "Name of the route map\n")
5092 char prefix_str
[BUFSIZ
];
5094 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5097 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5101 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5102 bgp_node_safi (vty
));
5105 DEFUN (no_bgp_network_mask_natural
,
5106 no_bgp_network_mask_natural_cmd
,
5107 "no network A.B.C.D [<backdoor|route-map WORD>]",
5109 "Specify a network to announce via BGP\n"
5111 "Specify a BGP backdoor route\n"
5112 "Route-map to modify the attributes\n"
5113 "Name of the route map\n")
5117 char prefix_str
[BUFSIZ
];
5119 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5122 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5126 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5127 bgp_node_safi (vty
));
5130 ALIAS (no_bgp_network
,
5131 no_bgp_network_label_index_cmd
,
5132 "no network A.B.C.D/M label-index (0-4294967294)",
5134 "Specify a network to announce via BGP\n"
5135 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5136 "Label index to associate with the prefix\n"
5137 "Label index value\n")
5139 ALIAS (no_bgp_network
,
5140 no_bgp_network_label_index_route_map_cmd
,
5141 "no network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5143 "Specify a network to announce via BGP\n"
5145 "Label index to associate with the prefix\n"
5146 "Label index value\n"
5147 "Route-map to modify the attributes\n"
5148 "Name of the route map\n")
5150 DEFUN (ipv6_bgp_network
,
5151 ipv6_bgp_network_cmd
,
5152 "network X:X::X:X/M",
5153 "Specify a network to announce via BGP\n"
5156 int idx_ipv6_prefixlen
= 1;
5157 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5159 BGP_INVALID_LABEL_INDEX
);
5162 DEFUN (ipv6_bgp_network_route_map
,
5163 ipv6_bgp_network_route_map_cmd
,
5164 "network X:X::X:X/M route-map WORD",
5165 "Specify a network to announce via BGP\n"
5167 "Route-map to modify the attributes\n"
5168 "Name of the route map\n")
5170 int idx_ipv6_prefixlen
= 1;
5172 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5173 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5174 BGP_INVALID_LABEL_INDEX
);
5177 DEFUN (ipv6_bgp_network_label_index
,
5178 ipv6_bgp_network_label_index_cmd
,
5179 "network X:X::X:X/M label-index (0-4294967294)",
5180 "Specify a network to announce via BGP\n"
5181 "IPv6 prefix <network>/<length>\n"
5182 "Label index to associate with the prefix\n"
5183 "Label index value\n")
5185 u_int32_t label_index
;
5187 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5188 return bgp_static_set (vty
, argv
[1]->arg
,
5189 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5192 DEFUN (ipv6_bgp_network_label_index_route_map
,
5193 ipv6_bgp_network_label_index_route_map_cmd
,
5194 "network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5195 "Specify a network to announce via BGP\n"
5197 "Label index to associate with the prefix\n"
5198 "Label index value\n"
5199 "Route-map to modify the attributes\n"
5200 "Name of the route map\n")
5202 u_int32_t label_index
;
5204 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5205 return bgp_static_set (vty
, argv
[1]->arg
,
5206 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5209 DEFUN (no_ipv6_bgp_network
,
5210 no_ipv6_bgp_network_cmd
,
5211 "no network X:X::X:X/M [route-map WORD]",
5213 "Specify a network to announce via BGP\n"
5215 "Route-map to modify the attributes\n"
5216 "Name of the route map\n")
5218 int idx_ipv6_prefixlen
= 2;
5219 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5222 ALIAS (no_ipv6_bgp_network
,
5223 no_ipv6_bgp_network_label_index_cmd
,
5224 "no network X:X::X:X/M label-index (0-4294967294)",
5226 "Specify a network to announce via BGP\n"
5227 "IPv6 prefix <network>/<length>\n"
5228 "Label index to associate with the prefix\n"
5229 "Label index value\n")
5231 ALIAS (no_ipv6_bgp_network
,
5232 no_ipv6_bgp_network_label_index_route_map_cmd
,
5233 "no network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5235 "Specify a network to announce via BGP\n"
5237 "Label index to associate with the prefix\n"
5238 "Label index value\n"
5239 "Route-map to modify the attributes\n"
5240 "Name of the route map\n")
5242 /* Aggreagete address:
5244 advertise-map Set condition to advertise attribute
5245 as-set Generate AS set path information
5246 attribute-map Set attributes of aggregate
5247 route-map Set parameters of aggregate
5248 summary-only Filter more specific routes from updates
5249 suppress-map Conditionally filter more specific routes from updates
5252 struct bgp_aggregate
5254 /* Summary-only flag. */
5255 u_char summary_only
;
5257 /* AS set generation. */
5260 /* Route-map for aggregated route. */
5261 struct route_map
*map
;
5263 /* Suppress-count. */
5264 unsigned long count
;
5266 /* SAFI configuration. */
5270 static struct bgp_aggregate
*
5271 bgp_aggregate_new (void)
5273 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5277 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5279 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5282 /* Update an aggregate as routes are added/removed from the BGP table */
5284 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5285 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5286 struct bgp_aggregate
*aggregate
)
5288 struct bgp_table
*table
;
5289 struct bgp_node
*top
;
5290 struct bgp_node
*rn
;
5292 struct aspath
*aspath
= NULL
;
5293 struct aspath
*asmerge
= NULL
;
5294 struct community
*community
= NULL
;
5295 struct community
*commerge
= NULL
;
5296 #if defined(AGGREGATE_NEXTHOP_CHECK)
5297 struct in_addr nexthop
;
5300 struct bgp_info
*ri
;
5301 struct bgp_info
*new;
5303 unsigned long match
= 0;
5304 u_char atomic_aggregate
= 0;
5306 /* Record adding route's nexthop and med. */
5309 #if defined(AGGREGATE_NEXTHOP_CHECK)
5310 nexthop
= rinew
->attr
->nexthop
;
5311 med
= rinew
->attr
->med
;
5315 /* ORIGIN attribute: If at least one route among routes that are
5316 aggregated has ORIGIN with the value INCOMPLETE, then the
5317 aggregated route must have the ORIGIN attribute with the value
5318 INCOMPLETE. Otherwise, if at least one route among routes that
5319 are aggregated has ORIGIN with the value EGP, then the aggregated
5320 route must have the origin attribute with the value EGP. In all
5321 other case the value of the ORIGIN attribute of the aggregated
5322 route is INTERNAL. */
5323 origin
= BGP_ORIGIN_IGP
;
5325 table
= bgp
->rib
[afi
][safi
];
5327 top
= bgp_node_get (table
, p
);
5328 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5329 if (rn
->p
.prefixlen
> p
->prefixlen
)
5333 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5335 if (BGP_INFO_HOLDDOWN (ri
))
5338 if (del
&& ri
== del
)
5341 if (! rinew
&& first
)
5343 #if defined(AGGREGATE_NEXTHOP_CHECK)
5344 nexthop
= ri
->attr
->nexthop
;
5345 med
= ri
->attr
->med
;
5350 #ifdef AGGREGATE_NEXTHOP_CHECK
5351 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5352 || ri
->attr
->med
!= med
)
5355 aspath_free (aspath
);
5357 community_free (community
);
5358 bgp_unlock_node (rn
);
5359 bgp_unlock_node (top
);
5362 #endif /* AGGREGATE_NEXTHOP_CHECK */
5364 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5365 atomic_aggregate
= 1;
5367 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5369 if (aggregate
->summary_only
)
5371 (bgp_info_extra_get (ri
))->suppress
++;
5372 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5378 if (origin
< ri
->attr
->origin
)
5379 origin
= ri
->attr
->origin
;
5381 if (aggregate
->as_set
)
5385 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5386 aspath_free (aspath
);
5390 aspath
= aspath_dup (ri
->attr
->aspath
);
5392 if (ri
->attr
->community
)
5396 commerge
= community_merge (community
,
5397 ri
->attr
->community
);
5398 community
= community_uniq_sort (commerge
);
5399 community_free (commerge
);
5402 community
= community_dup (ri
->attr
->community
);
5408 bgp_process (bgp
, rn
, afi
, safi
);
5410 bgp_unlock_node (top
);
5416 if (aggregate
->summary_only
)
5417 (bgp_info_extra_get (rinew
))->suppress
++;
5419 if (origin
< rinew
->attr
->origin
)
5420 origin
= rinew
->attr
->origin
;
5422 if (aggregate
->as_set
)
5426 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5427 aspath_free (aspath
);
5431 aspath
= aspath_dup (rinew
->attr
->aspath
);
5433 if (rinew
->attr
->community
)
5437 commerge
= community_merge (community
,
5438 rinew
->attr
->community
);
5439 community
= community_uniq_sort (commerge
);
5440 community_free (commerge
);
5443 community
= community_dup (rinew
->attr
->community
);
5448 if (aggregate
->count
> 0)
5450 rn
= bgp_node_get (table
, p
);
5451 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5452 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5454 atomic_aggregate
), rn
);
5455 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5457 bgp_info_add (rn
, new);
5458 bgp_unlock_node (rn
);
5459 bgp_process (bgp
, rn
, afi
, safi
);
5464 aspath_free (aspath
);
5466 community_free (community
);
5470 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5471 struct bgp_aggregate
*);
5474 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5475 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5477 struct bgp_node
*child
;
5478 struct bgp_node
*rn
;
5479 struct bgp_aggregate
*aggregate
;
5480 struct bgp_table
*table
;
5482 /* MPLS-VPN aggregation is not yet supported. */
5483 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5486 table
= bgp
->aggregate
[afi
][safi
];
5488 /* No aggregates configured. */
5489 if (bgp_table_top_nolock (table
) == NULL
)
5492 if (p
->prefixlen
== 0)
5495 if (BGP_INFO_HOLDDOWN (ri
))
5498 child
= bgp_node_get (table
, p
);
5500 /* Aggregate address configuration check. */
5501 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5502 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5504 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5505 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5507 bgp_unlock_node (child
);
5511 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5512 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5514 struct bgp_node
*child
;
5515 struct bgp_node
*rn
;
5516 struct bgp_aggregate
*aggregate
;
5517 struct bgp_table
*table
;
5519 /* MPLS-VPN aggregation is not yet supported. */
5520 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5523 table
= bgp
->aggregate
[afi
][safi
];
5525 /* No aggregates configured. */
5526 if (bgp_table_top_nolock (table
) == NULL
)
5529 if (p
->prefixlen
== 0)
5532 child
= bgp_node_get (table
, p
);
5534 /* Aggregate address configuration check. */
5535 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5536 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5538 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5539 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5541 bgp_unlock_node (child
);
5544 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5546 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5547 struct bgp_aggregate
*aggregate
)
5549 struct bgp_table
*table
;
5550 struct bgp_node
*top
;
5551 struct bgp_node
*rn
;
5552 struct bgp_info
*new;
5553 struct bgp_info
*ri
;
5554 unsigned long match
;
5555 u_char origin
= BGP_ORIGIN_IGP
;
5556 struct aspath
*aspath
= NULL
;
5557 struct aspath
*asmerge
= NULL
;
5558 struct community
*community
= NULL
;
5559 struct community
*commerge
= NULL
;
5560 u_char atomic_aggregate
= 0;
5562 table
= bgp
->rib
[afi
][safi
];
5565 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5567 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5570 /* If routes exists below this node, generate aggregate routes. */
5571 top
= bgp_node_get (table
, p
);
5572 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5573 if (rn
->p
.prefixlen
> p
->prefixlen
)
5577 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5579 if (BGP_INFO_HOLDDOWN (ri
))
5582 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5583 atomic_aggregate
= 1;
5585 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5587 /* summary-only aggregate route suppress aggregated
5588 route announcement. */
5589 if (aggregate
->summary_only
)
5591 (bgp_info_extra_get (ri
))->suppress
++;
5592 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5596 /* If at least one route among routes that are aggregated has
5597 * ORIGIN with the value INCOMPLETE, then the aggregated route
5598 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5599 * Otherwise, if at least one route among routes that are
5600 * aggregated has ORIGIN with the value EGP, then the aggregated
5601 * route MUST have the ORIGIN attribute with the value EGP.
5603 if (origin
< ri
->attr
->origin
)
5604 origin
= ri
->attr
->origin
;
5606 /* as-set aggregate route generate origin, as path,
5607 community aggregation. */
5608 if (aggregate
->as_set
)
5612 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5613 aspath_free (aspath
);
5617 aspath
= aspath_dup (ri
->attr
->aspath
);
5619 if (ri
->attr
->community
)
5623 commerge
= community_merge (community
,
5624 ri
->attr
->community
);
5625 community
= community_uniq_sort (commerge
);
5626 community_free (commerge
);
5629 community
= community_dup (ri
->attr
->community
);
5636 /* If this node is suppressed, process the change. */
5638 bgp_process (bgp
, rn
, afi
, safi
);
5640 bgp_unlock_node (top
);
5642 /* Add aggregate route to BGP table. */
5643 if (aggregate
->count
)
5645 rn
= bgp_node_get (table
, p
);
5646 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5647 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5649 atomic_aggregate
), rn
);
5650 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5652 bgp_info_add (rn
, new);
5653 bgp_unlock_node (rn
);
5655 /* Process change. */
5656 bgp_process (bgp
, rn
, afi
, safi
);
5661 aspath_free (aspath
);
5663 community_free (community
);
5668 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5669 safi_t safi
, struct bgp_aggregate
*aggregate
)
5671 struct bgp_table
*table
;
5672 struct bgp_node
*top
;
5673 struct bgp_node
*rn
;
5674 struct bgp_info
*ri
;
5675 unsigned long match
;
5677 table
= bgp
->rib
[afi
][safi
];
5679 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5681 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5684 /* If routes exists below this node, generate aggregate routes. */
5685 top
= bgp_node_get (table
, p
);
5686 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5687 if (rn
->p
.prefixlen
> p
->prefixlen
)
5691 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5693 if (BGP_INFO_HOLDDOWN (ri
))
5696 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5698 if (aggregate
->summary_only
&& ri
->extra
)
5700 ri
->extra
->suppress
--;
5702 if (ri
->extra
->suppress
== 0)
5704 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5712 /* If this node was suppressed, process the change. */
5714 bgp_process (bgp
, rn
, afi
, safi
);
5716 bgp_unlock_node (top
);
5718 /* Delete aggregate route from BGP table. */
5719 rn
= bgp_node_get (table
, p
);
5721 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5722 if (ri
->peer
== bgp
->peer_self
5723 && ri
->type
== ZEBRA_ROUTE_BGP
5724 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5727 /* Withdraw static BGP route from routing table. */
5730 bgp_info_delete (rn
, ri
);
5731 bgp_process (bgp
, rn
, afi
, safi
);
5734 /* Unlock bgp_node_lookup. */
5735 bgp_unlock_node (rn
);
5738 /* Aggregate route attribute. */
5739 #define AGGREGATE_SUMMARY_ONLY 1
5740 #define AGGREGATE_AS_SET 1
5743 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5744 afi_t afi
, safi_t safi
)
5746 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5749 struct bgp_node
*rn
;
5750 struct bgp_aggregate
*aggregate
;
5752 /* Convert string to prefix structure. */
5753 ret
= str2prefix (prefix_str
, &p
);
5756 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5761 /* Old configuration check. */
5762 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5765 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5770 aggregate
= rn
->info
;
5771 if (aggregate
->safi
== SAFI_UNICAST
)
5772 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5773 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5774 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5775 if (aggregate
->safi
== SAFI_MULTICAST
)
5776 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5778 /* Unlock aggregate address configuration. */
5780 bgp_aggregate_free (aggregate
);
5781 bgp_unlock_node (rn
);
5782 bgp_unlock_node (rn
);
5788 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5789 afi_t afi
, safi_t safi
,
5790 u_char summary_only
, u_char as_set
)
5792 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5795 struct bgp_node
*rn
;
5796 struct bgp_aggregate
*aggregate
;
5798 /* Convert string to prefix structure. */
5799 ret
= str2prefix (prefix_str
, &p
);
5802 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5807 /* Old configuration check. */
5808 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5812 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5813 /* try to remove the old entry */
5814 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5817 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5818 bgp_unlock_node (rn
);
5823 /* Make aggregate address structure. */
5824 aggregate
= bgp_aggregate_new ();
5825 aggregate
->summary_only
= summary_only
;
5826 aggregate
->as_set
= as_set
;
5827 aggregate
->safi
= safi
;
5828 rn
->info
= aggregate
;
5830 /* Aggregate address insert into BGP routing table. */
5831 if (safi
== SAFI_UNICAST
)
5832 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5833 if (safi
== SAFI_LABELED_UNICAST
)
5834 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5835 if (safi
== SAFI_MULTICAST
)
5836 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5841 DEFUN (aggregate_address
,
5842 aggregate_address_cmd
,
5843 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5844 "Configure BGP aggregate entries\n"
5845 "Aggregate prefix\n"
5846 "Generate AS set path information\n"
5847 "Filter more specific routes from updates\n"
5848 "Filter more specific routes from updates\n"
5849 "Generate AS set path information\n")
5852 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5853 char *prefix
= argv
[idx
]->arg
;
5854 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5856 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5858 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5861 DEFUN (aggregate_address_mask
,
5862 aggregate_address_mask_cmd
,
5863 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5864 "Configure BGP aggregate entries\n"
5865 "Aggregate address\n"
5867 "Generate AS set path information\n"
5868 "Filter more specific routes from updates\n"
5869 "Filter more specific routes from updates\n"
5870 "Generate AS set path information\n")
5873 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5874 char *prefix
= argv
[idx
]->arg
;
5875 char *mask
= argv
[idx
+1]->arg
;
5876 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5878 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5880 char prefix_str
[BUFSIZ
];
5881 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5885 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5889 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5892 DEFUN (no_aggregate_address
,
5893 no_aggregate_address_cmd
,
5894 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5896 "Configure BGP aggregate entries\n"
5897 "Aggregate prefix\n"
5898 "Generate AS set path information\n"
5899 "Filter more specific routes from updates\n"
5900 "Filter more specific routes from updates\n"
5901 "Generate AS set path information\n")
5904 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5905 char *prefix
= argv
[idx
]->arg
;
5906 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5909 DEFUN (no_aggregate_address_mask
,
5910 no_aggregate_address_mask_cmd
,
5911 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5913 "Configure BGP aggregate entries\n"
5914 "Aggregate address\n"
5916 "Generate AS set path information\n"
5917 "Filter more specific routes from updates\n"
5918 "Filter more specific routes from updates\n"
5919 "Generate AS set path information\n")
5922 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5923 char *prefix
= argv
[idx
]->arg
;
5924 char *mask
= argv
[idx
+1]->arg
;
5926 char prefix_str
[BUFSIZ
];
5927 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5931 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5935 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5938 DEFUN (ipv6_aggregate_address
,
5939 ipv6_aggregate_address_cmd
,
5940 "aggregate-address X:X::X:X/M [summary-only]",
5941 "Configure BGP aggregate entries\n"
5942 "Aggregate prefix\n"
5943 "Filter more specific routes from updates\n")
5946 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5947 char *prefix
= argv
[idx
]->arg
;
5948 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5949 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5952 DEFUN (no_ipv6_aggregate_address
,
5953 no_ipv6_aggregate_address_cmd
,
5954 "no aggregate-address X:X::X:X/M [summary-only]",
5956 "Configure BGP aggregate entries\n"
5957 "Aggregate prefix\n"
5958 "Filter more specific routes from updates\n")
5961 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5962 char *prefix
= argv
[idx
]->arg
;
5963 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5966 /* Redistribute route treatment. */
5968 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5969 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5970 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5972 struct bgp_info
*new;
5973 struct bgp_info
*bi
;
5974 struct bgp_info info
;
5975 struct bgp_node
*bn
;
5977 struct attr
*new_attr
;
5980 struct bgp_redist
*red
;
5982 /* Make default attribute. */
5983 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5985 attr
.nexthop
= *nexthop
;
5986 attr
.nh_ifindex
= ifindex
;
5990 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5991 extra
->mp_nexthop_global
= *nexthop6
;
5992 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5996 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5997 attr
.extra
->tag
= tag
;
5999 afi
= family2afi (p
->family
);
6001 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6004 struct attr attr_new
;
6005 struct attr_extra extra_new
;
6007 /* Copy attribute for modification. */
6008 attr_new
.extra
= &extra_new
;
6009 bgp_attr_dup (&attr_new
, &attr
);
6011 if (red
->redist_metric_flag
)
6012 attr_new
.med
= red
->redist_metric
;
6014 /* Apply route-map. */
6017 info
.peer
= bgp
->peer_self
;
6018 info
.attr
= &attr_new
;
6020 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6022 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6024 bgp
->peer_self
->rmap_type
= 0;
6026 if (ret
== RMAP_DENYMATCH
)
6028 /* Free uninterned attribute. */
6029 bgp_attr_flush (&attr_new
);
6031 /* Unintern original. */
6032 aspath_unintern (&attr
.aspath
);
6033 bgp_attr_extra_free (&attr
);
6034 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6039 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6040 afi
, SAFI_UNICAST
, p
, NULL
);
6042 new_attr
= bgp_attr_intern (&attr_new
);
6044 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6045 if (bi
->peer
== bgp
->peer_self
6046 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6051 /* Ensure the (source route) type is updated. */
6053 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6054 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6056 bgp_attr_unintern (&new_attr
);
6057 aspath_unintern (&attr
.aspath
);
6058 bgp_attr_extra_free (&attr
);
6059 bgp_unlock_node (bn
);
6064 /* The attribute is changed. */
6065 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6067 /* Rewrite BGP route information. */
6068 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6069 bgp_info_restore(bn
, bi
);
6071 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6072 bgp_attr_unintern (&bi
->attr
);
6073 bi
->attr
= new_attr
;
6074 bi
->uptime
= bgp_clock ();
6076 /* Process change. */
6077 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6078 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6079 bgp_unlock_node (bn
);
6080 aspath_unintern (&attr
.aspath
);
6081 bgp_attr_extra_free (&attr
);
6086 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6088 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6090 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6091 bgp_info_add (bn
, new);
6092 bgp_unlock_node (bn
);
6093 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6096 /* Unintern original. */
6097 aspath_unintern (&attr
.aspath
);
6098 bgp_attr_extra_free (&attr
);
6102 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6105 struct bgp_node
*rn
;
6106 struct bgp_info
*ri
;
6107 struct bgp_redist
*red
;
6109 afi
= family2afi (p
->family
);
6111 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6114 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6116 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6117 if (ri
->peer
== bgp
->peer_self
6118 && ri
->type
== type
)
6123 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6124 bgp_info_delete (rn
, ri
);
6125 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6127 bgp_unlock_node (rn
);
6131 /* Withdraw specified route type's route. */
6133 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6135 struct bgp_node
*rn
;
6136 struct bgp_info
*ri
;
6137 struct bgp_table
*table
;
6139 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6141 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6143 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6144 if (ri
->peer
== bgp
->peer_self
6146 && ri
->instance
== instance
)
6151 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6152 bgp_info_delete (rn
, ri
);
6153 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6158 /* Static function to display route. */
6160 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6163 u_int32_t destination
;
6166 if (p
->family
== AF_INET
)
6168 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6169 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6171 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6172 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6173 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6174 || p
->u
.prefix4
.s_addr
== 0)
6176 /* When mask is natural, mask is not displayed. */
6179 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6181 else if (p
->family
== AF_ETHERNET
)
6183 prefix2str(p
, buf
, PREFIX_STRLEN
);
6184 len
= vty_out (vty
, "%s", buf
);
6187 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6192 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
6194 vty_out (vty
, "%*s", len
, " ");
6197 enum bgp_display_type
6202 /* Print the short form route status for a bgp_info */
6204 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6205 json_object
*json_path
)
6210 /* Route status display. */
6211 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6212 json_object_boolean_true_add(json_path
, "removed");
6214 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6215 json_object_boolean_true_add(json_path
, "stale");
6217 if (binfo
->extra
&& binfo
->extra
->suppress
)
6218 json_object_boolean_true_add(json_path
, "suppressed");
6220 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6221 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6222 json_object_boolean_true_add(json_path
, "valid");
6225 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6226 json_object_boolean_true_add(json_path
, "history");
6228 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6229 json_object_boolean_true_add(json_path
, "damped");
6231 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6232 json_object_boolean_true_add(json_path
, "bestpath");
6234 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6235 json_object_boolean_true_add(json_path
, "multipath");
6237 /* Internal route. */
6238 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6239 json_object_string_add(json_path
, "pathFrom", "internal");
6241 json_object_string_add(json_path
, "pathFrom", "external");
6246 /* Route status display. */
6247 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6249 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6251 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6253 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6254 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6260 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6262 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6264 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6266 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6271 /* Internal route. */
6273 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6279 /* called from terminal list command */
6281 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6282 struct bgp_info
*binfo
, int display
, safi_t safi
,
6283 json_object
*json_paths
)
6286 json_object
*json_path
= NULL
;
6287 json_object
*json_nexthops
= NULL
;
6288 json_object
*json_nexthop_global
= NULL
;
6289 json_object
*json_nexthop_ll
= NULL
;
6292 json_path
= json_object_new_object();
6294 /* short status lead text */
6295 route_vty_short_status_out (vty
, binfo
, json_path
);
6299 /* print prefix and mask */
6301 route_vty_out_route (p
, vty
);
6303 vty_out (vty
, "%*s", 17, " ");
6306 /* Print attribute */
6311 * For ENCAP routes, nexthop address family is not
6312 * neccessarily the same as the prefix address family.
6313 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6315 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6320 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6325 vty_out (vty
, "%s", inet_ntop(af
,
6326 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6329 vty_out (vty
, "%s", inet_ntop(af
,
6330 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6341 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6345 json_nexthop_global
= json_object_new_object();
6347 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6348 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6350 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6352 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6353 json_object_boolean_true_add(json_nexthop_global
, "used");
6357 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6358 vty_out (vty
, "%-16s",
6359 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6361 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6366 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6373 json_nexthop_global
= json_object_new_object();
6374 json_object_string_add(json_nexthop_global
, "ip",
6375 inet_ntop (AF_INET6
,
6376 &attr
->extra
->mp_nexthop_global
,
6378 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6379 json_object_string_add(json_nexthop_global
, "scope", "global");
6381 /* We display both LL & GL if both have been received */
6382 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6384 json_nexthop_ll
= json_object_new_object();
6385 json_object_string_add(json_nexthop_ll
, "ip",
6386 inet_ntop (AF_INET6
,
6387 &attr
->extra
->mp_nexthop_local
,
6389 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6390 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6392 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6393 &attr
->extra
->mp_nexthop_local
) != 0) &&
6394 !attr
->extra
->mp_nexthop_prefer_global
)
6395 json_object_boolean_true_add(json_nexthop_ll
, "used");
6397 json_object_boolean_true_add(json_nexthop_global
, "used");
6400 json_object_boolean_true_add(json_nexthop_global
, "used");
6404 /* Display LL if LL/Global both in table unless prefer-global is set */
6405 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6406 !attr
->extra
->mp_nexthop_prefer_global
) ||
6407 (binfo
->peer
->conf_if
))
6409 if (binfo
->peer
->conf_if
)
6411 len
= vty_out (vty
, "%s",
6412 binfo
->peer
->conf_if
);
6413 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6416 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6418 vty_out (vty
, "%*s", len
, " ");
6422 len
= vty_out (vty
, "%s",
6423 inet_ntop (AF_INET6
,
6424 &attr
->extra
->mp_nexthop_local
,
6429 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6431 vty_out (vty
, "%*s", len
, " ");
6436 len
= vty_out (vty
, "%s",
6437 inet_ntop (AF_INET6
,
6438 &attr
->extra
->mp_nexthop_global
,
6443 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6445 vty_out (vty
, "%*s", len
, " ");
6451 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6453 json_object_int_add(json_path
, "med", attr
->med
);
6455 vty_out (vty
, "%10u", attr
->med
);
6461 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6463 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6465 vty_out (vty
, "%7u", attr
->local_pref
);
6473 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6475 json_object_int_add(json_path
, "weight", 0);
6478 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6482 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6489 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6491 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6496 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6498 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6503 json_object_string_add(json_path
, "alert", "No attributes");
6505 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6510 if (json_nexthop_global
|| json_nexthop_ll
)
6512 json_nexthops
= json_object_new_array();
6514 if (json_nexthop_global
)
6515 json_object_array_add(json_nexthops
, json_nexthop_global
);
6517 if (json_nexthop_ll
)
6518 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6520 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6523 json_object_array_add(json_paths
, json_path
);
6527 vty_out (vty
, "%s", VTY_NEWLINE
);
6529 /* prints an additional line, indented, with VNC info, if present */
6530 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6531 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6536 /* called from terminal list command */
6538 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6539 u_char use_json
, json_object
*json_ar
)
6541 json_object
*json_status
= NULL
;
6542 json_object
*json_net
= NULL
;
6544 /* Route status display. */
6547 json_status
= json_object_new_object();
6548 json_net
= json_object_new_object();
6557 /* print prefix and mask */
6559 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6561 route_vty_out_route (p
, vty
);
6563 /* Print attribute */
6568 if (p
->family
== AF_INET
&&
6569 (safi
== SAFI_MPLS_VPN
||
6570 safi
== SAFI_ENCAP
||
6571 safi
== SAFI_EVPN
||
6572 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6574 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6575 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6577 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6579 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6583 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6587 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6588 json_object_int_add(json_net
, "metric", attr
->med
);
6590 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6591 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6594 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6596 json_object_int_add(json_net
, "weight", 0);
6600 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6603 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6607 if (p
->family
== AF_INET
&&
6608 (safi
== SAFI_MPLS_VPN
||
6609 safi
== SAFI_ENCAP
||
6610 safi
== SAFI_EVPN
||
6611 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6613 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6614 vty_out (vty
, "%-16s",
6615 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6617 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6619 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6624 assert (attr
->extra
);
6626 len
= vty_out (vty
, "%s",
6627 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6631 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6633 vty_out (vty
, "%*s", len
, " ");
6635 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6636 vty_out (vty
, "%10u", attr
->med
);
6640 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6641 vty_out (vty
, "%7u", attr
->local_pref
);
6645 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6649 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6652 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6657 json_object_boolean_true_add(json_status
, "*");
6658 json_object_boolean_true_add(json_status
, ">");
6659 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6660 char buf_cut
[BUFSIZ
];
6661 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6664 vty_out (vty
, "%s", VTY_NEWLINE
);
6668 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6669 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6671 json_object
*json_out
= NULL
;
6673 u_int32_t label
= 0;
6679 json_out
= json_object_new_object();
6681 /* short status lead text */
6682 route_vty_short_status_out (vty
, binfo
, json_out
);
6684 /* print prefix and mask */
6688 route_vty_out_route (p
, vty
);
6690 vty_out (vty
, "%*s", 17, " ");
6693 /* Print attribute */
6697 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6698 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6699 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6701 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6704 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6706 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6711 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6713 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6716 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6717 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6718 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6720 assert (attr
->extra
);
6724 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6727 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6728 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6731 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6734 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6738 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6740 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6742 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6743 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6746 vty_out (vty
, "%s(%s)",
6747 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6749 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6756 label
= decode_label (binfo
->extra
->tag
);
6761 json_object_int_add(json_out
, "notag", label
);
6762 json_object_array_add(json
, json_out
);
6766 vty_out (vty
, "notag/%d", label
);
6768 vty_out (vty
, "%s", VTY_NEWLINE
);
6773 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6774 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6778 json_object
*json_path
= NULL
;
6781 json_path
= json_object_new_object();
6786 /* short status lead text */
6787 route_vty_short_status_out (vty
, binfo
, json_path
);
6789 /* print prefix and mask */
6791 route_vty_out_route (p
, vty
);
6793 vty_out (vty
, "%*s", 17, " ");
6795 /* Print attribute */
6802 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6806 vty_out (vty
, "%-16s", inet_ntop(af
,
6807 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6810 vty_out (vty
, "%s(%s)",
6812 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6814 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6826 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6827 char *str
= esi2str(id
);
6828 vty_out (vty
, "%s", str
);
6829 XFREE (MTYPE_TMP
, str
);
6830 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6832 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6834 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6836 vty_out (vty
, "/%s",
6837 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6840 if(attr
->extra
->ecommunity
)
6843 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6844 ECOMMUNITY_ENCODE_EVPN
,
6845 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6847 mac
= ecom_mac2str((char *)routermac
->val
);
6850 vty_out (vty
, "/%s",(char *)mac
);
6851 XFREE(MTYPE_TMP
, mac
);
6855 vty_out (vty
, "%s", VTY_NEWLINE
);
6858 /* dampening route */
6860 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6861 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6865 char timebuf
[BGP_UPTIME_LEN
];
6867 /* short status lead text */
6868 route_vty_short_status_out (vty
, binfo
, json
);
6870 /* print prefix and mask */
6874 route_vty_out_route (p
, vty
);
6876 vty_out (vty
, "%*s", 17, " ");
6879 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6884 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6889 json_object_int_add(json
, "peerHost", len
);
6891 vty_out (vty
, "%*s", len
, " ");
6895 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6897 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6899 /* Print attribute */
6907 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6909 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6914 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6916 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6919 vty_out (vty
, "%s", VTY_NEWLINE
);
6924 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6925 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6928 struct bgp_damp_info
*bdi
;
6929 char timebuf
[BGP_UPTIME_LEN
];
6935 bdi
= binfo
->extra
->damp_info
;
6937 /* short status lead text */
6938 route_vty_short_status_out (vty
, binfo
, json
);
6940 /* print prefix and mask */
6944 route_vty_out_route (p
, vty
);
6946 vty_out (vty
, "%*s", 17, " ");
6949 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6954 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6959 json_object_int_add(json
, "peerHost", len
);
6961 vty_out (vty
, "%*s", len
, " ");
6964 len
= vty_out (vty
, "%d", bdi
->flap
);
6974 json_object_int_add(json
, "bdiFlap", len
);
6976 vty_out (vty
, "%*s", len
, " ");
6980 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6982 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6983 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6985 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6986 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6989 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6991 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6996 vty_out (vty
, "%*s ", 8, " ");
6999 /* Print attribute */
7007 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
7009 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7014 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7016 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7019 vty_out (vty
, "%s", VTY_NEWLINE
);
7023 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7024 const char *header
, json_object
*json_adv_to
)
7026 char buf1
[INET6_ADDRSTRLEN
];
7027 json_object
*json_peer
= NULL
;
7031 /* 'advertised-to' is a dictionary of peers we have advertised this
7032 * prefix too. The key is the peer's IP or swpX, the value is the
7033 * hostname if we know it and "" if not.
7035 json_peer
= json_object_new_object();
7038 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7041 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7043 json_object_object_add(json_adv_to
,
7044 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7051 vty_out (vty
, "%s", header
);
7055 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7058 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7060 vty_out (vty
, " %s(%s)", peer
->hostname
,
7061 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7066 vty_out (vty
, " %s", peer
->conf_if
);
7068 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7074 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7075 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7076 json_object
*json_paths
)
7078 char buf
[INET6_ADDRSTRLEN
];
7081 int sockunion_vty_out (struct vty
*, union sockunion
*);
7083 json_object
*json_bestpath
= NULL
;
7084 json_object
*json_cluster_list
= NULL
;
7085 json_object
*json_cluster_list_list
= NULL
;
7086 json_object
*json_ext_community
= NULL
;
7087 json_object
*json_last_update
= NULL
;
7088 json_object
*json_nexthop_global
= NULL
;
7089 json_object
*json_nexthop_ll
= NULL
;
7090 json_object
*json_nexthops
= NULL
;
7091 json_object
*json_path
= NULL
;
7092 json_object
*json_peer
= NULL
;
7093 json_object
*json_string
= NULL
;
7094 json_object
*json_adv_to
= NULL
;
7096 struct listnode
*node
, *nnode
;
7098 int addpath_capable
;
7100 unsigned int first_as
;
7104 json_path
= json_object_new_object();
7105 json_peer
= json_object_new_object();
7106 json_nexthop_global
= json_object_new_object();
7113 /* Line1 display AS-path, Aggregator */
7118 json_object_lock(attr
->aspath
->json
);
7119 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7123 if (attr
->aspath
->segments
)
7124 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7126 vty_out (vty
, " Local");
7130 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7133 json_object_boolean_true_add(json_path
, "removed");
7135 vty_out (vty
, ", (removed)");
7138 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7141 json_object_boolean_true_add(json_path
, "stale");
7143 vty_out (vty
, ", (stale)");
7146 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7150 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
7151 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
7155 vty_out (vty
, ", (aggregated by %u %s)",
7156 attr
->extra
->aggregator_as
,
7157 inet_ntoa (attr
->extra
->aggregator_addr
));
7161 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7164 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7166 vty_out (vty
, ", (Received from a RR-client)");
7169 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7172 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7174 vty_out (vty
, ", (Received from a RS-client)");
7177 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7180 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7182 vty_out (vty
, ", (history entry)");
7184 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7187 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7189 vty_out (vty
, ", (suppressed due to dampening)");
7193 vty_out (vty
, "%s", VTY_NEWLINE
);
7195 /* Line2 display Next-hop, Neighbor, Router-id */
7196 /* Display the nexthop */
7197 if (p
->family
== AF_INET
&&
7198 (safi
== SAFI_MPLS_VPN
||
7199 safi
== SAFI_ENCAP
||
7200 safi
== SAFI_EVPN
||
7201 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7203 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7206 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7208 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7213 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7215 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7219 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7223 assert (attr
->extra
);
7226 json_object_string_add(json_nexthop_global
, "ip",
7227 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7228 buf
, INET6_ADDRSTRLEN
));
7229 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7230 json_object_string_add(json_nexthop_global
, "scope", "global");
7234 vty_out (vty
, " %s",
7235 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7236 buf
, INET6_ADDRSTRLEN
));
7240 /* Display the IGP cost or 'inaccessible' */
7241 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7244 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7246 vty_out (vty
, " (inaccessible)");
7250 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7253 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7255 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7258 /* IGP cost is 0, display this only for json */
7262 json_object_int_add(json_nexthop_global
, "metric", 0);
7266 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7269 /* Display peer "from" output */
7270 /* This path was originated locally */
7271 if (binfo
->peer
== bgp
->peer_self
)
7274 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7277 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7279 vty_out (vty
, " from 0.0.0.0 ");
7284 json_object_string_add(json_peer
, "peerId", "::");
7286 vty_out (vty
, " from :: ");
7290 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7292 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7295 /* We RXed this path from one of our peers */
7301 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7302 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7304 if (binfo
->peer
->hostname
)
7305 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7307 if (binfo
->peer
->domainname
)
7308 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7310 if (binfo
->peer
->conf_if
)
7311 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7315 if (binfo
->peer
->conf_if
)
7317 if (binfo
->peer
->hostname
&&
7318 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7319 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7320 binfo
->peer
->conf_if
);
7322 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7326 if (binfo
->peer
->hostname
&&
7327 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7328 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7331 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7334 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7335 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7337 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7342 vty_out (vty
, "%s", VTY_NEWLINE
);
7344 /* display the link-local nexthop */
7345 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7349 json_nexthop_ll
= json_object_new_object();
7350 json_object_string_add(json_nexthop_ll
, "ip",
7351 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7352 buf
, INET6_ADDRSTRLEN
));
7353 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7354 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7356 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7358 if (!attr
->extra
->mp_nexthop_prefer_global
)
7359 json_object_boolean_true_add(json_nexthop_ll
, "used");
7361 json_object_boolean_true_add(json_nexthop_global
, "used");
7365 vty_out (vty
, " (%s) %s%s",
7366 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7367 buf
, INET6_ADDRSTRLEN
),
7368 attr
->extra
->mp_nexthop_prefer_global
?
7369 "(prefer-global)" : "(used)",
7373 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7377 json_object_boolean_true_add(json_nexthop_global
, "used");
7380 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7382 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7384 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7386 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7389 json_object_int_add(json_path
, "med", attr
->med
);
7391 vty_out (vty
, ", metric %u", attr
->med
);
7394 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7397 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7399 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7404 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7406 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7409 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7412 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7414 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7417 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7420 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7422 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7425 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7428 json_object_boolean_false_add(json_path
, "valid");
7430 vty_out (vty
, ", invalid");
7432 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7435 json_object_boolean_true_add(json_path
, "valid");
7437 vty_out (vty
, ", valid");
7440 if (binfo
->peer
!= bgp
->peer_self
)
7442 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7444 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7447 json_object_string_add(json_peer
, "type", "confed-internal");
7449 vty_out (vty
, ", confed-internal");
7454 json_object_string_add(json_peer
, "type", "internal");
7456 vty_out (vty
, ", internal");
7461 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7464 json_object_string_add(json_peer
, "type", "confed-external");
7466 vty_out (vty
, ", confed-external");
7471 json_object_string_add(json_peer
, "type", "external");
7473 vty_out (vty
, ", external");
7477 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7481 json_object_boolean_true_add(json_path
, "aggregated");
7482 json_object_boolean_true_add(json_path
, "local");
7486 vty_out (vty
, ", aggregated, local");
7489 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7492 json_object_boolean_true_add(json_path
, "sourced");
7494 vty_out (vty
, ", sourced");
7500 json_object_boolean_true_add(json_path
, "sourced");
7501 json_object_boolean_true_add(json_path
, "local");
7505 vty_out (vty
, ", sourced, local");
7509 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7512 json_object_boolean_true_add(json_path
, "atomicAggregate");
7514 vty_out (vty
, ", atomic-aggregate");
7517 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7518 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7519 bgp_info_mpath_count (binfo
)))
7522 json_object_boolean_true_add(json_path
, "multipath");
7524 vty_out (vty
, ", multipath");
7527 // Mark the bestpath(s)
7528 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7530 first_as
= aspath_get_first_as(attr
->aspath
);
7535 json_bestpath
= json_object_new_object();
7536 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7541 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7543 vty_out (vty
, ", bestpath-from-AS Local");
7547 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7552 json_bestpath
= json_object_new_object();
7553 json_object_boolean_true_add(json_bestpath
, "overall");
7556 vty_out (vty
, ", best");
7560 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7563 vty_out (vty
, "%s", VTY_NEWLINE
);
7565 /* Line 4 display Community */
7566 if (attr
->community
)
7570 json_object_lock(attr
->community
->json
);
7571 json_object_object_add(json_path
, "community", attr
->community
->json
);
7575 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7580 /* Line 5 display Extended-community */
7581 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7585 json_ext_community
= json_object_new_object();
7586 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7587 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7591 vty_out (vty
, " Extended Community: %s%s",
7592 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7596 /* Line 6 display Large community */
7597 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7598 vty_out (vty
, " Large Community: %s%s",
7599 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7601 /* Line 7 display Originator, Cluster-id */
7602 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7603 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7605 assert (attr
->extra
);
7606 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7609 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7611 vty_out (vty
, " Originator: %s",
7612 inet_ntoa (attr
->extra
->originator_id
));
7615 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7621 json_cluster_list
= json_object_new_object();
7622 json_cluster_list_list
= json_object_new_array();
7624 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7626 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7627 json_object_array_add(json_cluster_list_list
, json_string
);
7630 /* struct cluster_list does not have "str" variable like
7631 * aspath and community do. Add this someday if someone
7633 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7635 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7636 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7640 vty_out (vty
, ", Cluster list: ");
7642 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7644 vty_out (vty
, "%s ",
7645 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7651 vty_out (vty
, "%s", VTY_NEWLINE
);
7654 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7655 bgp_damp_info_vty (vty
, binfo
, json_path
);
7658 if (bgp_labeled_safi(safi
) && binfo
->extra
)
7660 uint32_t label
= label_pton(binfo
->extra
->tag
);
7662 json_object_int_add(json_path
, "remoteLabel", label
);
7664 vty_out(vty
, " Remote label: %d%s", label
, VTY_NEWLINE
);
7668 if (attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7671 json_object_int_add(json_path
, "labelIndex", attr
->extra
->label_index
);
7673 vty_out(vty
, " Label Index: %d%s", attr
->extra
->label_index
, VTY_NEWLINE
);
7676 /* Line 8 display Addpath IDs */
7677 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7681 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7682 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7686 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7687 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7692 /* If we used addpath to TX a non-bestpath we need to display
7693 * "Advertised to" on a path-by-path basis */
7694 if (bgp
->addpath_tx_used
[afi
][safi
])
7698 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7700 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7701 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7703 if ((addpath_capable
&& has_adj
) ||
7704 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7706 if (json_path
&& !json_adv_to
)
7707 json_adv_to
= json_object_new_object();
7709 route_vty_out_advertised_to(vty
, peer
, &first
,
7719 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7726 vty_out (vty
, "%s", VTY_NEWLINE
);
7731 /* Line 9 display Uptime */
7732 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7735 json_last_update
= json_object_new_object();
7736 json_object_int_add(json_last_update
, "epoch", tbuf
);
7737 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7738 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7741 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7744 /* We've constructed the json object for this path, add it to the json
7749 if (json_nexthop_global
|| json_nexthop_ll
)
7751 json_nexthops
= json_object_new_array();
7753 if (json_nexthop_global
)
7754 json_object_array_add(json_nexthops
, json_nexthop_global
);
7756 if (json_nexthop_ll
)
7757 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7759 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7762 json_object_object_add(json_path
, "peer", json_peer
);
7763 json_object_array_add(json_paths
, json_path
);
7766 vty_out (vty
, "%s", VTY_NEWLINE
);
7769 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7770 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7771 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7774 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7775 const char *prefix_list_str
, afi_t afi
,
7776 safi_t safi
, enum bgp_show_type type
);
7778 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7779 const char *filter
, afi_t afi
,
7780 safi_t safi
, enum bgp_show_type type
);
7782 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7783 const char *rmap_str
, afi_t afi
,
7784 safi_t safi
, enum bgp_show_type type
);
7786 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7787 const char *com
, int exact
,
7788 afi_t afi
, safi_t safi
);
7790 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7791 const char *prefix
, afi_t afi
,
7792 safi_t safi
, enum bgp_show_type type
);
7794 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7795 safi_t safi
, enum bgp_show_type type
);
7797 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7798 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7801 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7802 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7804 struct bgp_info
*ri
;
7805 struct bgp_node
*rn
;
7808 unsigned long output_count
;
7809 unsigned long total_count
;
7813 json_object
*json_paths
= NULL
;
7818 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7819 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7820 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7821 table
->version
, inet_ntoa (bgp
->router_id
));
7822 json_paths
= json_object_new_object();
7825 /* This is first entry point, so reset total line. */
7829 /* Start processing of routes. */
7830 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7831 if (rn
->info
!= NULL
)
7834 if (!first
&& use_json
)
7839 json_paths
= json_object_new_array();
7843 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7846 if (type
== bgp_show_type_flap_statistics
7847 || type
== bgp_show_type_flap_neighbor
7848 || type
== bgp_show_type_dampend_paths
7849 || type
== bgp_show_type_damp_neighbor
)
7851 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7854 if (type
== bgp_show_type_regexp
)
7856 regex_t
*regex
= output_arg
;
7858 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7861 if (type
== bgp_show_type_prefix_list
)
7863 struct prefix_list
*plist
= output_arg
;
7865 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7868 if (type
== bgp_show_type_filter_list
)
7870 struct as_list
*as_list
= output_arg
;
7872 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7875 if (type
== bgp_show_type_route_map
)
7877 struct route_map
*rmap
= output_arg
;
7878 struct bgp_info binfo
;
7879 struct attr dummy_attr
;
7880 struct attr_extra dummy_extra
;
7883 dummy_attr
.extra
= &dummy_extra
;
7884 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7886 binfo
.peer
= ri
->peer
;
7887 binfo
.attr
= &dummy_attr
;
7889 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7890 if (ret
== RMAP_DENYMATCH
)
7893 if (type
== bgp_show_type_neighbor
7894 || type
== bgp_show_type_flap_neighbor
7895 || type
== bgp_show_type_damp_neighbor
)
7897 union sockunion
*su
= output_arg
;
7899 if (ri
->peer
== NULL
||
7900 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7903 if (type
== bgp_show_type_cidr_only
)
7905 u_int32_t destination
;
7907 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7908 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7910 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7912 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7915 if (type
== bgp_show_type_prefix_longer
)
7917 struct prefix
*p
= output_arg
;
7919 if (! prefix_match (p
, &rn
->p
))
7922 if (type
== bgp_show_type_community_all
)
7924 if (! ri
->attr
->community
)
7927 if (type
== bgp_show_type_community
)
7929 struct community
*com
= output_arg
;
7931 if (! ri
->attr
->community
||
7932 ! community_match (ri
->attr
->community
, com
))
7935 if (type
== bgp_show_type_community_exact
)
7937 struct community
*com
= output_arg
;
7939 if (! ri
->attr
->community
||
7940 ! community_cmp (ri
->attr
->community
, com
))
7943 if (type
== bgp_show_type_community_list
)
7945 struct community_list
*list
= output_arg
;
7947 if (! community_list_match (ri
->attr
->community
, list
))
7950 if (type
== bgp_show_type_community_list_exact
)
7952 struct community_list
*list
= output_arg
;
7954 if (! community_list_exact_match (ri
->attr
->community
, list
))
7957 if (type
== bgp_show_type_lcommunity
)
7959 struct lcommunity
*lcom
= output_arg
;
7961 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7962 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7965 if (type
== bgp_show_type_lcommunity_list
)
7967 struct community_list
*list
= output_arg
;
7969 if (! ri
->attr
->extra
||
7970 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7973 if (type
== bgp_show_type_lcommunity_all
)
7975 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7978 if (type
== bgp_show_type_dampend_paths
7979 || type
== bgp_show_type_damp_neighbor
)
7981 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7982 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7986 if (!use_json
&& header
)
7988 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7989 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7990 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7991 if (type
== bgp_show_type_dampend_paths
7992 || type
== bgp_show_type_damp_neighbor
)
7993 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7994 else if (type
== bgp_show_type_flap_statistics
7995 || type
== bgp_show_type_flap_neighbor
)
7996 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7998 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
8002 if (type
== bgp_show_type_dampend_paths
8003 || type
== bgp_show_type_damp_neighbor
)
8004 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8005 else if (type
== bgp_show_type_flap_statistics
8006 || type
== bgp_show_type_flap_neighbor
)
8007 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8009 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8019 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8020 vty_out (vty
, "\"%s\": ", buf2
);
8021 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8022 json_object_free (json_paths
);
8031 json_object_free (json_paths
);
8032 vty_out (vty
, " } }%s", VTY_NEWLINE
);
8036 /* No route is displayed */
8037 if (output_count
== 0)
8039 if (type
== bgp_show_type_normal
)
8040 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
8043 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
8044 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
8051 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8052 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8054 struct bgp_table
*table
;
8058 bgp
= bgp_get_default ();
8064 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8067 /* use MPLS and ENCAP specific shows until they are merged */
8068 if (safi
== SAFI_MPLS_VPN
)
8070 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8073 if (safi
== SAFI_ENCAP
)
8075 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
8080 table
= bgp
->rib
[afi
][safi
];
8082 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8087 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8090 struct listnode
*node
, *nnode
;
8092 struct bgp_table
*table
;
8096 vty_out (vty
, "{%s", VTY_NEWLINE
);
8098 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8103 vty_out (vty
, ",%s", VTY_NEWLINE
);
8107 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8108 ? "Default" : bgp
->name
);
8112 vty_out (vty
, "%sInstance %s:%s",
8114 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8115 ? "Default" : bgp
->name
,
8118 table
= bgp
->rib
[afi
][safi
];
8119 bgp_show_table (vty
, bgp
, table
,
8120 bgp_show_type_normal
, NULL
, use_json
);
8125 vty_out (vty
, "}%s", VTY_NEWLINE
);
8128 /* Header of detailed BGP route information */
8130 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8131 struct bgp_node
*rn
,
8132 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8135 struct bgp_info
*ri
;
8138 struct listnode
*node
, *nnode
;
8139 char buf1
[INET6_ADDRSTRLEN
];
8140 char buf2
[INET6_ADDRSTRLEN
];
8145 int no_advertise
= 0;
8148 json_object
*json_adv_to
= NULL
;
8154 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8155 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8159 if (p
->family
== AF_ETHERNET
)
8160 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8162 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8163 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
8164 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8165 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8166 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8168 p
->prefixlen
, VTY_NEWLINE
);
8170 if (bgp_labeled_safi(safi
))
8172 vty_out(vty
, "Local label: ");
8173 if (!bgp_is_valid_label(rn
->local_label
))
8174 vty_out(vty
, "not allocated%s", VTY_NEWLINE
);
8177 uint32_t label
= label_pton(rn
->local_label
);
8178 vty_out(vty
, "%d%s", label
, VTY_NEWLINE
);
8183 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8186 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8189 if (ri
->extra
&& ri
->extra
->suppress
)
8191 if (ri
->attr
->community
!= NULL
)
8193 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8195 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8197 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8205 vty_out (vty
, "Paths: (%d available", count
);
8208 vty_out (vty
, ", best #%d", best
);
8209 if (safi
== SAFI_UNICAST
)
8210 vty_out (vty
, ", table %s",
8211 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8212 ? "Default-IP-Routing-Table" : bgp
->name
);
8215 vty_out (vty
, ", no best path");
8218 vty_out (vty
, ", not advertised to any peer");
8220 vty_out (vty
, ", not advertised to EBGP peer");
8222 vty_out (vty
, ", not advertised outside local AS");
8225 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8226 vty_out (vty
, ")%s", VTY_NEWLINE
);
8229 /* If we are not using addpath then we can display Advertised to and that will
8230 * show what peers we advertised the bestpath to. If we are using addpath
8231 * though then we must display Advertised to on a path-by-path basis. */
8232 if (!bgp
->addpath_tx_used
[afi
][safi
])
8234 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8236 if (bgp_adj_out_lookup (peer
, rn
, 0))
8238 if (json
&& !json_adv_to
)
8239 json_adv_to
= json_object_new_object();
8241 route_vty_out_advertised_to(vty
, peer
, &first
,
8242 " Advertised to non peer-group peers:\n ",
8251 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8257 vty_out (vty
, " Not advertised to any peer");
8258 vty_out (vty
, "%s", VTY_NEWLINE
);
8263 /* Display specified route of BGP table. */
8265 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8266 struct bgp_table
*rib
, const char *ip_str
,
8267 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8268 int prefix_check
, enum bgp_path_type pathtype
,
8274 struct prefix match
;
8275 struct bgp_node
*rn
;
8276 struct bgp_node
*rm
;
8277 struct bgp_info
*ri
;
8278 struct bgp_table
*table
;
8279 json_object
*json
= NULL
;
8280 json_object
*json_paths
= NULL
;
8282 /* Check IP address argument. */
8283 ret
= str2prefix (ip_str
, &match
);
8286 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
8290 match
.family
= afi2family (afi
);
8294 json
= json_object_new_object();
8295 json_paths
= json_object_new_array();
8298 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8300 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8302 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8305 if ((table
= rn
->info
) != NULL
)
8309 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8311 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8313 bgp_unlock_node (rm
);
8317 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8321 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8322 AFI_IP
, safi
, json
);
8327 if (pathtype
== BGP_PATH_ALL
||
8328 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8329 (pathtype
== BGP_PATH_MULTIPATH
&&
8330 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8331 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8334 bgp_unlock_node (rm
);
8343 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8345 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8347 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8351 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8356 if (pathtype
== BGP_PATH_ALL
||
8357 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8358 (pathtype
== BGP_PATH_MULTIPATH
&&
8359 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8360 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8364 bgp_unlock_node (rn
);
8371 json_object_object_add(json
, "paths", json_paths
);
8373 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8374 json_object_free(json
);
8380 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8388 /* Display specified route of Main RIB */
8390 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8391 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8392 int prefix_check
, enum bgp_path_type pathtype
,
8396 bgp
= bgp_get_default ();
8398 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8399 afi
, safi
, prd
, prefix_check
, pathtype
,
8404 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8405 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8407 struct lcommunity
*lcom
;
8413 b
= buffer_new (1024);
8414 for (i
= 0; i
< argc
; i
++)
8417 buffer_putc (b
, ' ');
8420 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8423 buffer_putstr (b
, argv
[i
]->arg
);
8427 buffer_putc (b
, '\0');
8429 str
= buffer_getstr (b
);
8432 lcom
= lcommunity_str2com (str
);
8433 XFREE (MTYPE_TMP
, str
);
8436 vty_out (vty
, "%% Large-community malformed%s", VTY_NEWLINE
);
8440 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8444 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8445 afi_t afi
, safi_t safi
, u_char uj
)
8447 struct community_list
*list
;
8449 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8452 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8457 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8460 DEFUN (show_ip_bgp_large_community_list
,
8461 show_ip_bgp_large_community_list_cmd
,
8462 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
8466 BGP_INSTANCE_HELP_STR
8469 "Address Family modifier\n"
8470 "Address Family modifier\n"
8471 "Address Family modifier\n"
8472 "Address Family modifier\n"
8473 "Address Family modifier\n"
8474 "Display routes matching the large-community-list\n"
8475 "large-community-list number\n"
8476 "large-community-list name\n"
8480 afi_t afi
= AFI_IP6
;
8481 safi_t safi
= SAFI_UNICAST
;
8484 if (argv_find (argv
, argc
, "ip", &idx
))
8486 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8487 vrf
= argv
[++idx
]->arg
;
8488 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8490 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8491 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8492 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8495 int uj
= use_json (argc
, argv
);
8497 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8500 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8504 argv_find (argv
, argc
, "large-community-list", &idx
);
8505 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8507 DEFUN (show_ip_bgp_large_community
,
8508 show_ip_bgp_large_community_cmd
,
8509 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community [AA:BB:CC] [json]",
8513 BGP_INSTANCE_HELP_STR
8516 "Address Family modifier\n"
8517 "Address Family modifier\n"
8518 "Address Family modifier\n"
8519 "Address Family modifier\n"
8520 "Address Family modifier\n"
8521 "Display routes matching the large-communities\n"
8522 "List of large-community numbers\n"
8526 afi_t afi
= AFI_IP6
;
8527 safi_t safi
= SAFI_UNICAST
;
8530 if (argv_find (argv
, argc
, "ip", &idx
))
8532 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8533 vrf
= argv
[++idx
]->arg
;
8534 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8536 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8537 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8538 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8541 int uj
= use_json (argc
, argv
);
8543 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8546 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8550 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8551 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8553 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8556 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8558 /* BGP route print out function. */
8561 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8564 |dampening <flap-statistics|dampened-paths|parameters>\
8569 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8570 |community-list <(1-500)|WORD> [exact-match]\
8571 |A.B.C.D/M longer-prefixes\
8572 |X:X::X:X/M longer-prefixes>\
8577 BGP_INSTANCE_HELP_STR
8580 "Display only routes with non-natural netmasks\n"
8581 "Display detailed information about dampening\n"
8582 "Display flap statistics of routes\n"
8583 "Display paths suppressed due to dampening\n"
8584 "Display detail of configured dampening parameters\n"
8585 "Display routes matching the route-map\n"
8586 "A route-map to match on\n"
8587 "Display routes conforming to the prefix-list\n"
8588 "Prefix-list name\n"
8589 "Display routes conforming to the filter-list\n"
8590 "Regular expression access list name\n"
8591 "BGP RIB advertisement statistics\n"
8592 "Display routes matching the communities\n"
8594 "Do not send outside local AS (well-known community)\n"
8595 "Do not advertise to any peer (well-known community)\n"
8596 "Do not export to next AS (well-known community)\n"
8597 "Exact match of the communities\n"
8598 "Display routes matching the community-list\n"
8599 "community-list number\n"
8600 "community-list name\n"
8601 "Exact match of the communities\n"
8603 "Display route and more specific routes\n"
8605 "Display route and more specific routes\n"
8608 afi_t afi
= AFI_IP6
;
8609 safi_t safi
= SAFI_UNICAST
;
8610 int exact_match
= 0;
8611 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8612 struct bgp
*bgp
= NULL
;
8615 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8619 int uj
= use_json (argc
, argv
);
8622 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8623 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8625 if (argv_find(argv
, argc
, "dampening", &idx
))
8627 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8628 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8629 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8630 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8631 else if (argv_find (argv
, argc
, "parameters", &idx
))
8632 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8635 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8636 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8638 if (argv_find(argv
, argc
, "filter-list", &idx
))
8639 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8641 if (argv_find(argv
, argc
, "statistics", &idx
))
8642 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8644 if (argv_find(argv
, argc
, "route-map", &idx
))
8645 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8647 if (argv_find(argv
, argc
, "community", &idx
))
8649 /* show a specific community */
8650 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8651 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8652 argv_find (argv
, argc
, "no-export", &idx
))
8654 if (argv_find (argv
, argc
, "exact_match", &idx
))
8656 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8658 /* show all communities */
8660 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8663 if (argv_find(argv
, argc
, "community-list", &idx
))
8665 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8666 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8668 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8671 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8672 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8674 if (safi
== SAFI_MPLS_VPN
)
8675 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8676 else if (safi
== SAFI_ENCAP
)
8677 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8679 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8682 DEFUN (show_ip_bgp_route
,
8683 show_ip_bgp_route_cmd
,
8684 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8685 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8689 BGP_INSTANCE_HELP_STR
8692 "Network in the BGP routing table to display\n"
8694 "Network in the BGP routing table to display\n"
8696 "Display only the bestpath\n"
8697 "Display only multipaths\n"
8700 int prefix_check
= 0;
8702 afi_t afi
= AFI_IP6
;
8703 safi_t safi
= SAFI_UNICAST
;
8704 char *prefix
= NULL
;
8705 struct bgp
*bgp
= NULL
;
8706 enum bgp_path_type path_type
;
8707 u_char uj
= use_json(argc
, argv
);
8711 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8717 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8721 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8722 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8724 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8727 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8729 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8732 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8734 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8738 prefix
= argv
[idx
]->arg
;
8740 /* [<bestpath|multipath>] */
8741 if (argv_find (argv
, argc
, "bestpath", &idx
))
8742 path_type
= BGP_PATH_BESTPATH
;
8743 else if (argv_find (argv
, argc
, "multipath", &idx
))
8744 path_type
= BGP_PATH_MULTIPATH
;
8746 path_type
= BGP_PATH_ALL
;
8748 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8751 DEFUN (show_ip_bgp_regexp
,
8752 show_ip_bgp_regexp_cmd
,
8753 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8757 BGP_INSTANCE_HELP_STR
8760 "Display routes matching the AS path regular expression\n"
8761 "A regular-expression to match the BGP AS paths\n")
8763 afi_t afi
= AFI_IP6
;
8764 safi_t safi
= SAFI_UNICAST
;
8765 struct bgp
*bgp
= NULL
;
8768 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8772 // get index of regex
8773 argv_find (argv
, argc
, "regexp", &idx
);
8776 char *regstr
= argv_concat (argv
, argc
, idx
);
8777 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8778 XFREE (MTYPE_TMP
, regstr
);
8782 DEFUN (show_ip_bgp_instance_all
,
8783 show_ip_bgp_instance_all_cmd
,
8784 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8788 BGP_INSTANCE_ALL_HELP_STR
8794 safi_t safi
= SAFI_UNICAST
;
8795 struct bgp
*bgp
= NULL
;
8798 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8802 int uj
= use_json (argc
, argv
);
8805 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8810 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8811 safi_t safi
, enum bgp_show_type type
)
8816 regex
= bgp_regcomp (regstr
);
8819 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8823 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8824 bgp_regex_free (regex
);
8829 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8830 const char *prefix_list_str
, afi_t afi
,
8831 safi_t safi
, enum bgp_show_type type
)
8833 struct prefix_list
*plist
;
8835 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8838 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8839 prefix_list_str
, VTY_NEWLINE
);
8843 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8847 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8848 const char *filter
, afi_t afi
,
8849 safi_t safi
, enum bgp_show_type type
)
8851 struct as_list
*as_list
;
8853 as_list
= as_list_lookup (filter
);
8854 if (as_list
== NULL
)
8856 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8860 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8864 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8865 const char *rmap_str
, afi_t afi
,
8866 safi_t safi
, enum bgp_show_type type
)
8868 struct route_map
*rmap
;
8870 rmap
= route_map_lookup_by_name (rmap_str
);
8873 vty_out (vty
, "%% %s is not a valid route-map name%s",
8874 rmap_str
, VTY_NEWLINE
);
8878 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8882 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8883 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8885 struct community
*com
;
8892 b
= buffer_new (1024);
8893 for (i
= 0; i
< argc
; i
++)
8896 buffer_putc (b
, ' ');
8899 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8904 buffer_putstr (b
, argv
[i
]->arg
);
8906 buffer_putc (b
, '\0');
8908 str
= buffer_getstr (b
);
8911 com
= community_str2com (str
);
8912 XFREE (MTYPE_TMP
, str
);
8915 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8919 ret
= bgp_show (vty
, bgp
, afi
, safi
,
8920 (exact
? bgp_show_type_community_exact
:
8921 bgp_show_type_community
), com
, 0);
8922 community_free (com
);
8928 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8929 const char *com
, int exact
,
8930 afi_t afi
, safi_t safi
)
8932 struct community_list
*list
;
8934 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8937 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8942 return bgp_show (vty
, bgp
, afi
, safi
,
8943 (exact
? bgp_show_type_community_list_exact
:
8944 bgp_show_type_community_list
), list
, 0);
8948 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8949 const char *prefix
, afi_t afi
,
8950 safi_t safi
, enum bgp_show_type type
)
8957 ret
= str2prefix (prefix
, p
);
8960 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8964 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8969 static struct peer
*
8970 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8971 const char *ip_str
, u_char use_json
)
8977 /* Get peer sockunion. */
8978 ret
= str2sockunion (ip_str
, &su
);
8981 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8984 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8990 json_object
*json_no
= NULL
;
8991 json_no
= json_object_new_object();
8992 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8993 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8994 json_object_free(json_no
);
8997 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
9004 /* Peer structure lookup. */
9005 peer
= peer_lookup (bgp
, &su
);
9010 json_object
*json_no
= NULL
;
9011 json_no
= json_object_new_object();
9012 json_object_string_add(json_no
, "warning","No such neighbor");
9013 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9014 json_object_free(json_no
);
9017 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9026 BGP_STATS_MAXBITLEN
= 0,
9030 BGP_STATS_UNAGGREGATEABLE
,
9031 BGP_STATS_MAX_AGGREGATEABLE
,
9032 BGP_STATS_AGGREGATES
,
9034 BGP_STATS_ASPATH_COUNT
,
9035 BGP_STATS_ASPATH_MAXHOPS
,
9036 BGP_STATS_ASPATH_TOTHOPS
,
9037 BGP_STATS_ASPATH_MAXSIZE
,
9038 BGP_STATS_ASPATH_TOTSIZE
,
9039 BGP_STATS_ASN_HIGHEST
,
9043 static const char *table_stats_strs
[] =
9045 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9046 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9047 [BGP_STATS_RIB
] = "Total Advertisements",
9048 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9049 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9050 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9051 [BGP_STATS_SPACE
] = "Address space advertised",
9052 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9053 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9054 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9055 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9056 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9057 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9058 [BGP_STATS_MAX
] = NULL
,
9061 struct bgp_table_stats
9063 struct bgp_table
*table
;
9064 unsigned long long counts
[BGP_STATS_MAX
];
9068 #define TALLY_SIGFIG 100000
9069 static unsigned long
9070 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9072 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9073 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9074 unsigned long ret
= newtot
/ count
;
9076 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9084 bgp_table_stats_walker (struct thread
*t
)
9086 struct bgp_node
*rn
;
9087 struct bgp_node
*top
;
9088 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9089 unsigned int space
= 0;
9091 if (!(top
= bgp_table_top (ts
->table
)))
9094 switch (top
->p
.family
)
9097 space
= IPV4_MAX_BITLEN
;
9100 space
= IPV6_MAX_BITLEN
;
9104 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9106 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9108 struct bgp_info
*ri
;
9109 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9110 unsigned int rinum
= 0;
9118 ts
->counts
[BGP_STATS_PREFIXES
]++;
9119 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9122 ts
->counts
[BGP_STATS_AVGPLEN
]
9123 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9124 ts
->counts
[BGP_STATS_AVGPLEN
],
9128 /* check if the prefix is included by any other announcements */
9129 while (prn
&& !prn
->info
)
9130 prn
= bgp_node_parent_nolock (prn
);
9132 if (prn
== NULL
|| prn
== top
)
9134 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9135 /* announced address space */
9137 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9140 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9142 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9145 ts
->counts
[BGP_STATS_RIB
]++;
9148 (CHECK_FLAG (ri
->attr
->flag
,
9149 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9150 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9153 if (ri
->attr
&& ri
->attr
->aspath
)
9155 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9156 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9157 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9159 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9161 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9162 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9164 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9165 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9167 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9168 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9170 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9171 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9172 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9174 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9175 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9176 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9179 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9180 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9188 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9190 struct bgp_table_stats ts
;
9193 if (!bgp
->rib
[afi
][safi
])
9195 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
9196 afi
, safi
, VTY_NEWLINE
);
9200 memset (&ts
, 0, sizeof (ts
));
9201 ts
.table
= bgp
->rib
[afi
][safi
];
9202 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9204 vty_out (vty
, "BGP %s RIB statistics%s%s",
9205 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
9207 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9209 if (!table_stats_strs
[i
])
9215 case BGP_STATS_ASPATH_AVGHOPS
:
9216 case BGP_STATS_ASPATH_AVGSIZE
:
9217 case BGP_STATS_AVGPLEN
:
9218 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9219 vty_out (vty
, "%12.2f",
9220 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9223 case BGP_STATS_ASPATH_TOTHOPS
:
9224 case BGP_STATS_ASPATH_TOTSIZE
:
9225 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9226 vty_out (vty
, "%12.2f",
9228 (float)ts
.counts
[i
] /
9229 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9232 case BGP_STATS_TOTPLEN
:
9233 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9234 vty_out (vty
, "%12.2f",
9236 (float)ts
.counts
[i
] /
9237 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9240 case BGP_STATS_SPACE
:
9241 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9242 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
9243 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9245 vty_out (vty
, "%30s: ", "%% announced ");
9246 vty_out (vty
, "%12.2f%s",
9247 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
9248 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
9250 vty_out (vty
, "%30s: ", "/8 equivalent ");
9251 vty_out (vty
, "%12.2f%s",
9252 (float)ts
.counts
[BGP_STATS_SPACE
] /
9253 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
9255 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9257 vty_out (vty
, "%30s: ", "/24 equivalent ");
9258 vty_out (vty
, "%12.2f",
9259 (float)ts
.counts
[BGP_STATS_SPACE
] /
9260 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9263 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9264 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9267 vty_out (vty
, "%s", VTY_NEWLINE
);
9282 PCOUNT_PFCNT
, /* the figure we display to users */
9286 static const char *pcount_strs
[] =
9288 [PCOUNT_ADJ_IN
] = "Adj-in",
9289 [PCOUNT_DAMPED
] = "Damped",
9290 [PCOUNT_REMOVED
] = "Removed",
9291 [PCOUNT_HISTORY
] = "History",
9292 [PCOUNT_STALE
] = "Stale",
9293 [PCOUNT_VALID
] = "Valid",
9294 [PCOUNT_ALL
] = "All RIB",
9295 [PCOUNT_COUNTED
] = "PfxCt counted",
9296 [PCOUNT_PFCNT
] = "Useable",
9297 [PCOUNT_MAX
] = NULL
,
9302 unsigned int count
[PCOUNT_MAX
];
9303 const struct peer
*peer
;
9304 const struct bgp_table
*table
;
9308 bgp_peer_count_walker (struct thread
*t
)
9310 struct bgp_node
*rn
;
9311 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9312 const struct peer
*peer
= pc
->peer
;
9314 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9316 struct bgp_adj_in
*ain
;
9317 struct bgp_info
*ri
;
9319 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9320 if (ain
->peer
== peer
)
9321 pc
->count
[PCOUNT_ADJ_IN
]++;
9323 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9325 char buf
[SU_ADDRSTRLEN
];
9327 if (ri
->peer
!= peer
)
9330 pc
->count
[PCOUNT_ALL
]++;
9332 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9333 pc
->count
[PCOUNT_DAMPED
]++;
9334 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9335 pc
->count
[PCOUNT_HISTORY
]++;
9336 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9337 pc
->count
[PCOUNT_REMOVED
]++;
9338 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9339 pc
->count
[PCOUNT_STALE
]++;
9340 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9341 pc
->count
[PCOUNT_VALID
]++;
9342 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9343 pc
->count
[PCOUNT_PFCNT
]++;
9345 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9347 pc
->count
[PCOUNT_COUNTED
]++;
9348 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9349 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9351 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9352 buf
, SU_ADDRSTRLEN
),
9358 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9359 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9361 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9362 buf
, SU_ADDRSTRLEN
),
9372 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9374 struct peer_pcounts pcounts
= { .peer
= peer
};
9376 json_object
*json
= NULL
;
9377 json_object
*json_loop
= NULL
;
9381 json
= json_object_new_object();
9382 json_loop
= json_object_new_object();
9385 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9386 || !peer
->bgp
->rib
[afi
][safi
])
9390 json_object_string_add(json
, "warning", "No such neighbor or address family");
9391 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9392 json_object_free(json
);
9395 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9400 memset (&pcounts
, 0, sizeof(pcounts
));
9401 pcounts
.peer
= peer
;
9402 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9404 /* in-place call via thread subsystem so as to record execution time
9405 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9406 * * on just vty_read()).
9408 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9412 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9413 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9414 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9416 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9417 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9419 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9421 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9423 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9424 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9426 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9427 json_object_free(json
);
9432 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9434 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9435 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9440 vty_out (vty
, "Prefix counts for %s, %s%s",
9441 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9444 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9445 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9446 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9448 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9449 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9451 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9453 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9454 peer
->host
, VTY_NEWLINE
);
9455 vty_out (vty
, "Please report this bug, with the above command output%s",
9463 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9464 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9465 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] "
9466 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9470 BGP_INSTANCE_HELP_STR
9473 "Address Family modifier\n"
9474 "Address Family modifier\n"
9475 "Address Family modifier\n"
9476 "Address Family modifier\n"
9477 "Address Family modifier\n"
9478 "Detailed information on TCP and BGP neighbor connections\n"
9479 "Neighbor to display information about\n"
9480 "Neighbor to display information about\n"
9481 "Neighbor on BGP configured interface\n"
9482 "Display detailed prefix count information\n"
9485 afi_t afi
= AFI_IP6
;
9486 safi_t safi
= SAFI_UNICAST
;
9489 struct bgp
*bgp
= NULL
;
9491 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9495 int uj
= use_json (argc
, argv
);
9498 argv_find (argv
, argc
, "neighbors", &idx
);
9499 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9503 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9506 #ifdef KEEP_OLD_VPN_COMMANDS
9507 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9508 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9509 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9514 "Display information about all VPNv4 NLRIs\n"
9515 "Detailed information on TCP and BGP neighbor connections\n"
9516 "Neighbor to display information about\n"
9517 "Neighbor to display information about\n"
9518 "Neighbor on BGP configured interface\n"
9519 "Display detailed prefix count information\n"
9524 u_char uj
= use_json(argc
, argv
);
9526 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9530 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9533 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9534 show_ip_bgp_vpn_all_route_prefix_cmd
,
9535 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9540 "Display information about all VPNv4 NLRIs\n"
9541 "Network in the BGP routing table to display\n"
9542 "Network in the BGP routing table to display\n"
9546 char *network
= NULL
;
9547 struct bgp
*bgp
= bgp_get_default();
9550 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9554 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9555 network
= argv
[idx
]->arg
;
9556 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9557 network
= argv
[idx
]->arg
;
9560 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9564 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9566 #endif /* KEEP_OLD_VPN_COMMANDS */
9568 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9569 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9570 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9576 "Display information about all EVPN NLRIs\n"
9577 "Network in the BGP routing table to display\n"
9578 "Network in the BGP routing table to display\n"
9582 char *network
= NULL
;
9584 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9585 network
= argv
[idx
]->arg
;
9586 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9587 network
= argv
[idx
]->arg
;
9590 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9593 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9597 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9598 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9600 struct bgp_table
*table
;
9601 struct bgp_adj_in
*ain
;
9602 struct bgp_adj_out
*adj
;
9603 unsigned long output_count
;
9604 unsigned long filtered_count
;
9605 struct bgp_node
*rn
;
9610 struct attr_extra extra
;
9612 struct update_subgroup
*subgrp
;
9613 json_object
*json_scode
= NULL
;
9614 json_object
*json_ocode
= NULL
;
9615 json_object
*json_ar
= NULL
;
9616 struct peer_af
*paf
;
9620 json_scode
= json_object_new_object();
9621 json_ocode
= json_object_new_object();
9622 json_ar
= json_object_new_object();
9624 json_object_string_add(json_scode
, "suppressed", "s");
9625 json_object_string_add(json_scode
, "damped", "d");
9626 json_object_string_add(json_scode
, "history", "h");
9627 json_object_string_add(json_scode
, "valid", "*");
9628 json_object_string_add(json_scode
, "best", ">");
9629 json_object_string_add(json_scode
, "multipath", "=");
9630 json_object_string_add(json_scode
, "internal", "i");
9631 json_object_string_add(json_scode
, "ribFailure", "r");
9632 json_object_string_add(json_scode
, "stale", "S");
9633 json_object_string_add(json_scode
, "removed", "R");
9635 json_object_string_add(json_ocode
, "igp", "i");
9636 json_object_string_add(json_ocode
, "egp", "e");
9637 json_object_string_add(json_ocode
, "incomplete", "?");
9646 json_object_string_add(json
, "alert", "no BGP");
9647 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9648 json_object_free(json
);
9651 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9655 table
= bgp
->rib
[afi
][safi
];
9657 output_count
= filtered_count
= 0;
9658 subgrp
= peer_subgroup(peer
, afi
, safi
);
9660 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9664 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9665 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9666 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9667 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9668 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9672 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9673 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9674 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9676 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9677 VTY_NEWLINE
, VTY_NEWLINE
);
9682 attr
.extra
= &extra
;
9683 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9687 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9689 if (ain
->peer
== peer
)
9695 json_object_int_add(json
, "bgpTableVersion", 0);
9696 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9697 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9698 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9702 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9703 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9704 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9711 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9716 bgp_attr_dup(&attr
, ain
->attr
);
9717 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9719 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9730 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9731 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9732 if (paf
->peer
== peer
)
9738 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9739 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9740 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9741 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9745 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9746 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9747 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9748 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9756 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9762 bgp_attr_dup(&attr
, adj
->attr
);
9763 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9764 if (ret
!= RMAP_DENY
)
9766 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9776 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9778 if (output_count
!= 0)
9781 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9783 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9784 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9788 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9789 json_object_free(json
);
9795 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9796 int in
, const char *rmap_name
, u_char use_json
)
9798 json_object
*json
= NULL
;
9801 json
= json_object_new_object();
9803 if (!peer
|| !peer
->afc
[afi
][safi
])
9807 json_object_string_add(json
, "warning", "No such neighbor or address family");
9808 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9809 json_object_free(json
);
9812 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9817 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9821 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9822 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9823 json_object_free(json
);
9826 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9831 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9836 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9837 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9838 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9839 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9843 BGP_INSTANCE_HELP_STR
9846 "Detailed information on TCP and BGP neighbor connections\n"
9847 "Neighbor to display information about\n"
9848 "Neighbor to display information about\n"
9849 "Neighbor on BGP configured interface\n"
9850 "Display the received routes from neighbor\n"
9851 "Display the routes advertised to a BGP neighbor\n"
9852 "Route-map to modify the attributes\n"
9853 "Name of the route map\n"
9856 afi_t afi
= AFI_IP6
;
9857 safi_t safi
= SAFI_UNICAST
;
9858 char *rmap_name
= NULL
;
9859 char *peerstr
= NULL
;
9861 struct bgp
*bgp
= NULL
;
9866 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9870 int uj
= use_json (argc
, argv
);
9873 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9874 argv_find (argv
, argc
, "neighbors", &idx
);
9875 peerstr
= argv
[++idx
]->arg
;
9877 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9881 if (argv_find (argv
, argc
, "received-routes", &idx
))
9883 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9885 if (argv_find (argv
, argc
, "route-map", &idx
))
9886 rmap_name
= argv
[++idx
]->arg
;
9888 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9891 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9892 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9893 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9899 "Address Family modifier\n"
9900 "Detailed information on TCP and BGP neighbor connections\n"
9901 "Neighbor to display information about\n"
9902 "Neighbor to display information about\n"
9903 "Neighbor on BGP configured interface\n"
9904 "Display information received from a BGP neighbor\n"
9905 "Display the prefixlist filter\n"
9908 afi_t afi
= AFI_IP6
;
9909 safi_t safi
= SAFI_UNICAST
;
9910 char *peerstr
= NULL
;
9920 if (argv_find (argv
, argc
, "ip", &idx
))
9922 /* [<ipv4|ipv6> [unicast]] */
9923 if (argv_find (argv
, argc
, "ipv4", &idx
))
9925 if (argv_find (argv
, argc
, "ipv6", &idx
))
9927 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9928 argv_find (argv
, argc
, "neighbors", &idx
);
9929 peerstr
= argv
[++idx
]->arg
;
9931 u_char uj
= use_json(argc
, argv
);
9933 ret
= str2sockunion (peerstr
, &su
);
9936 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9940 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9942 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9948 peer
= peer_lookup (NULL
, &su
);
9952 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9954 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9959 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9960 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9964 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9965 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9970 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9972 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9979 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9980 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9982 if (! peer
|| ! peer
->afc
[afi
][safi
])
9986 json_object
*json_no
= NULL
;
9987 json_no
= json_object_new_object();
9988 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9989 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9990 json_object_free(json_no
);
9993 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9997 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10000 DEFUN (show_ip_bgp_neighbor_routes
,
10001 show_ip_bgp_neighbor_routes_cmd
,
10002 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
10003 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10007 BGP_INSTANCE_HELP_STR
10010 "Detailed information on TCP and BGP neighbor connections\n"
10011 "Neighbor to display information about\n"
10012 "Neighbor to display information about\n"
10013 "Neighbor on BGP configured interface\n"
10014 "Display flap statistics of the routes learned from neighbor\n"
10015 "Display the dampened routes received from neighbor\n"
10016 "Display routes learned from neighbor\n"
10019 char *peerstr
= NULL
;
10020 struct bgp
*bgp
= NULL
;
10021 afi_t afi
= AFI_IP6
;
10022 safi_t safi
= SAFI_UNICAST
;
10024 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10028 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10030 return CMD_WARNING
;
10032 int uj
= use_json (argc
, argv
);
10035 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10036 argv_find (argv
, argc
, "neighbors", &idx
);
10037 peerstr
= argv
[++idx
]->arg
;
10039 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10042 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
10043 return CMD_WARNING
;
10046 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10047 sh_type
= bgp_show_type_flap_neighbor
;
10048 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10049 sh_type
= bgp_show_type_damp_neighbor
;
10050 else if (argv_find (argv
, argc
, "routes", &idx
))
10051 sh_type
= bgp_show_type_neighbor
;
10053 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10056 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10058 struct bgp_distance
10060 /* Distance value for the IP source prefix. */
10063 /* Name of the access-list to be matched. */
10067 DEFUN (show_bgp_afi_vpn_rd_route
,
10068 show_bgp_afi_vpn_rd_route_cmd
,
10069 "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]",
10073 "Address Family modifier\n"
10074 "Display information for a route distinguisher\n"
10075 "Route Distinguisher\n"
10076 "Network in the BGP routing table to display\n"
10077 "Network in the BGP routing table to display\n"
10081 struct prefix_rd prd
;
10082 afi_t afi
= AFI_MAX
;
10085 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10086 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10089 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
10090 return CMD_WARNING
;
10092 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10095 static struct bgp_distance
*
10096 bgp_distance_new (void)
10098 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10102 bgp_distance_free (struct bgp_distance
*bdistance
)
10104 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10108 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10109 const char *ip_str
, const char *access_list_str
)
10116 struct bgp_node
*rn
;
10117 struct bgp_distance
*bdistance
;
10119 afi
= bgp_node_afi (vty
);
10120 safi
= bgp_node_safi (vty
);
10122 ret
= str2prefix (ip_str
, &p
);
10125 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10126 return CMD_WARNING
;
10129 distance
= atoi (distance_str
);
10131 /* Get BGP distance node. */
10132 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10135 bdistance
= rn
->info
;
10136 bgp_unlock_node (rn
);
10140 bdistance
= bgp_distance_new ();
10141 rn
->info
= bdistance
;
10144 /* Set distance value. */
10145 bdistance
->distance
= distance
;
10147 /* Reset access-list configuration. */
10148 if (bdistance
->access_list
)
10150 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10151 bdistance
->access_list
= NULL
;
10153 if (access_list_str
)
10154 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10156 return CMD_SUCCESS
;
10160 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10161 const char *ip_str
, const char *access_list_str
)
10168 struct bgp_node
*rn
;
10169 struct bgp_distance
*bdistance
;
10171 afi
= bgp_node_afi (vty
);
10172 safi
= bgp_node_safi (vty
);
10174 ret
= str2prefix (ip_str
, &p
);
10177 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10178 return CMD_WARNING
;
10181 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10184 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
10185 return CMD_WARNING
;
10188 bdistance
= rn
->info
;
10189 distance
= atoi(distance_str
);
10191 if (bdistance
->distance
!= distance
)
10193 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
10194 return CMD_WARNING
;
10197 if (bdistance
->access_list
)
10198 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10199 bgp_distance_free (bdistance
);
10202 bgp_unlock_node (rn
);
10203 bgp_unlock_node (rn
);
10205 return CMD_SUCCESS
;
10208 /* Apply BGP information to distance method. */
10210 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10211 safi_t safi
, struct bgp
*bgp
)
10213 struct bgp_node
*rn
;
10216 struct bgp_distance
*bdistance
;
10217 struct access_list
*alist
;
10218 struct bgp_static
*bgp_static
;
10223 peer
= rinfo
->peer
;
10225 /* Check source address. */
10226 sockunion2hostprefix (&peer
->su
, &q
);
10227 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10230 bdistance
= rn
->info
;
10231 bgp_unlock_node (rn
);
10233 if (bdistance
->access_list
)
10235 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10236 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10237 return bdistance
->distance
;
10240 return bdistance
->distance
;
10243 /* Backdoor check. */
10244 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10247 bgp_static
= rn
->info
;
10248 bgp_unlock_node (rn
);
10250 if (bgp_static
->backdoor
)
10252 if (bgp
->distance_local
[afi
][safi
])
10253 return bgp
->distance_local
[afi
][safi
];
10255 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10259 if (peer
->sort
== BGP_PEER_EBGP
)
10261 if (bgp
->distance_ebgp
[afi
][safi
])
10262 return bgp
->distance_ebgp
[afi
][safi
];
10263 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10267 if (bgp
->distance_ibgp
[afi
][safi
])
10268 return bgp
->distance_ibgp
[afi
][safi
];
10269 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10273 DEFUN (bgp_distance
,
10275 "distance bgp (1-255) (1-255) (1-255)",
10276 "Define an administrative distance\n"
10278 "Distance for routes external to the AS\n"
10279 "Distance for routes internal to the AS\n"
10280 "Distance for local routes\n")
10282 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10283 int idx_number
= 2;
10284 int idx_number_2
= 3;
10285 int idx_number_3
= 4;
10289 afi
= bgp_node_afi (vty
);
10290 safi
= bgp_node_safi (vty
);
10292 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10293 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10294 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10295 return CMD_SUCCESS
;
10298 DEFUN (no_bgp_distance
,
10299 no_bgp_distance_cmd
,
10300 "no distance bgp [(1-255) (1-255) (1-255)]",
10302 "Define an administrative distance\n"
10304 "Distance for routes external to the AS\n"
10305 "Distance for routes internal to the AS\n"
10306 "Distance for local routes\n")
10308 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10312 afi
= bgp_node_afi (vty
);
10313 safi
= bgp_node_safi (vty
);
10315 bgp
->distance_ebgp
[afi
][safi
] = 0;
10316 bgp
->distance_ibgp
[afi
][safi
] = 0;
10317 bgp
->distance_local
[afi
][safi
] = 0;
10318 return CMD_SUCCESS
;
10322 DEFUN (bgp_distance_source
,
10323 bgp_distance_source_cmd
,
10324 "distance (1-255) A.B.C.D/M",
10325 "Define an administrative distance\n"
10326 "Administrative distance\n"
10327 "IP source prefix\n")
10329 int idx_number
= 1;
10330 int idx_ipv4_prefixlen
= 2;
10331 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10332 return CMD_SUCCESS
;
10335 DEFUN (no_bgp_distance_source
,
10336 no_bgp_distance_source_cmd
,
10337 "no distance (1-255) A.B.C.D/M",
10339 "Define an administrative distance\n"
10340 "Administrative distance\n"
10341 "IP source prefix\n")
10343 int idx_number
= 2;
10344 int idx_ipv4_prefixlen
= 3;
10345 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10346 return CMD_SUCCESS
;
10349 DEFUN (bgp_distance_source_access_list
,
10350 bgp_distance_source_access_list_cmd
,
10351 "distance (1-255) A.B.C.D/M WORD",
10352 "Define an administrative distance\n"
10353 "Administrative distance\n"
10354 "IP source prefix\n"
10355 "Access list name\n")
10357 int idx_number
= 1;
10358 int idx_ipv4_prefixlen
= 2;
10360 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10361 return CMD_SUCCESS
;
10364 DEFUN (no_bgp_distance_source_access_list
,
10365 no_bgp_distance_source_access_list_cmd
,
10366 "no distance (1-255) A.B.C.D/M WORD",
10368 "Define an administrative distance\n"
10369 "Administrative distance\n"
10370 "IP source prefix\n"
10371 "Access list name\n")
10373 int idx_number
= 2;
10374 int idx_ipv4_prefixlen
= 3;
10376 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10377 return CMD_SUCCESS
;
10380 DEFUN (ipv6_bgp_distance_source
,
10381 ipv6_bgp_distance_source_cmd
,
10382 "distance (1-255) X:X::X:X/M",
10383 "Define an administrative distance\n"
10384 "Administrative distance\n"
10385 "IP source prefix\n")
10387 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10388 return CMD_SUCCESS
;
10391 DEFUN (no_ipv6_bgp_distance_source
,
10392 no_ipv6_bgp_distance_source_cmd
,
10393 "no distance (1-255) X:X::X:X/M",
10395 "Define an administrative distance\n"
10396 "Administrative distance\n"
10397 "IP source prefix\n")
10399 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10400 return CMD_SUCCESS
;
10403 DEFUN (ipv6_bgp_distance_source_access_list
,
10404 ipv6_bgp_distance_source_access_list_cmd
,
10405 "distance (1-255) X:X::X:X/M WORD",
10406 "Define an administrative distance\n"
10407 "Administrative distance\n"
10408 "IP source prefix\n"
10409 "Access list name\n")
10411 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10412 return CMD_SUCCESS
;
10415 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10416 no_ipv6_bgp_distance_source_access_list_cmd
,
10417 "no distance (1-255) X:X::X:X/M WORD",
10419 "Define an administrative distance\n"
10420 "Administrative distance\n"
10421 "IP source prefix\n"
10422 "Access list name\n")
10424 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10425 return CMD_SUCCESS
;
10428 DEFUN (bgp_damp_set
,
10430 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10431 "BGP Specific commands\n"
10432 "Enable route-flap dampening\n"
10433 "Half-life time for the penalty\n"
10434 "Value to start reusing a route\n"
10435 "Value to start suppressing a route\n"
10436 "Maximum duration to suppress a stable route\n")
10438 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10439 int idx_half_life
= 2;
10441 int idx_suppress
= 4;
10442 int idx_max_suppress
= 5;
10443 int half
= DEFAULT_HALF_LIFE
* 60;
10444 int reuse
= DEFAULT_REUSE
;
10445 int suppress
= DEFAULT_SUPPRESS
;
10446 int max
= 4 * half
;
10450 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10451 reuse
= atoi (argv
[idx_reuse
]->arg
);
10452 suppress
= atoi (argv
[idx_suppress
]->arg
);
10453 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10455 else if (argc
== 3)
10457 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10461 if (suppress
< reuse
)
10463 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10468 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10469 half
, reuse
, suppress
, max
);
10472 DEFUN (bgp_damp_unset
,
10473 bgp_damp_unset_cmd
,
10474 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10476 "BGP Specific commands\n"
10477 "Enable route-flap dampening\n"
10478 "Half-life time for the penalty\n"
10479 "Value to start reusing a route\n"
10480 "Value to start suppressing a route\n"
10481 "Maximum duration to suppress a stable route\n")
10483 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10484 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10487 /* Display specified route of BGP table. */
10489 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10490 const char *ip_str
, afi_t afi
, safi_t safi
,
10491 struct prefix_rd
*prd
, int prefix_check
)
10494 struct prefix match
;
10495 struct bgp_node
*rn
;
10496 struct bgp_node
*rm
;
10497 struct bgp_info
*ri
;
10498 struct bgp_info
*ri_temp
;
10500 struct bgp_table
*table
;
10502 /* BGP structure lookup. */
10505 bgp
= bgp_lookup_by_name (view_name
);
10508 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10509 return CMD_WARNING
;
10514 bgp
= bgp_get_default ();
10517 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10518 return CMD_WARNING
;
10522 /* Check IP address argument. */
10523 ret
= str2prefix (ip_str
, &match
);
10526 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10527 return CMD_WARNING
;
10530 match
.family
= afi2family (afi
);
10532 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10534 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10536 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10539 if ((table
= rn
->info
) != NULL
)
10540 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10542 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10547 if (ri
->extra
&& ri
->extra
->damp_info
)
10549 ri_temp
= ri
->next
;
10550 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10558 bgp_unlock_node (rm
);
10564 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10566 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10571 if (ri
->extra
&& ri
->extra
->damp_info
)
10573 ri_temp
= ri
->next
;
10574 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10582 bgp_unlock_node (rn
);
10586 return CMD_SUCCESS
;
10589 DEFUN (clear_ip_bgp_dampening
,
10590 clear_ip_bgp_dampening_cmd
,
10591 "clear ip bgp dampening",
10595 "Clear route flap dampening information\n")
10597 bgp_damp_info_clean ();
10598 return CMD_SUCCESS
;
10601 DEFUN (clear_ip_bgp_dampening_prefix
,
10602 clear_ip_bgp_dampening_prefix_cmd
,
10603 "clear ip bgp dampening A.B.C.D/M",
10607 "Clear route flap dampening information\n"
10610 int idx_ipv4_prefixlen
= 4;
10611 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10612 SAFI_UNICAST
, NULL
, 1);
10615 DEFUN (clear_ip_bgp_dampening_address
,
10616 clear_ip_bgp_dampening_address_cmd
,
10617 "clear ip bgp dampening A.B.C.D",
10621 "Clear route flap dampening information\n"
10622 "Network to clear damping information\n")
10625 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10626 SAFI_UNICAST
, NULL
, 0);
10629 DEFUN (clear_ip_bgp_dampening_address_mask
,
10630 clear_ip_bgp_dampening_address_mask_cmd
,
10631 "clear ip bgp dampening A.B.C.D A.B.C.D",
10635 "Clear route flap dampening information\n"
10636 "Network to clear damping information\n"
10640 int idx_ipv4_2
= 5;
10642 char prefix_str
[BUFSIZ
];
10644 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10647 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10648 return CMD_WARNING
;
10651 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10652 SAFI_UNICAST
, NULL
, 0);
10655 /* also used for encap safi */
10657 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10658 afi_t afi
, safi_t safi
, int *write
)
10660 struct bgp_node
*prn
;
10661 struct bgp_node
*rn
;
10662 struct bgp_table
*table
;
10664 struct prefix_rd
*prd
;
10665 struct bgp_static
*bgp_static
;
10667 char buf
[SU_ADDRSTRLEN
];
10668 char rdbuf
[RD_ADDRSTRLEN
];
10670 /* Network configuration. */
10671 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10672 if ((table
= prn
->info
) != NULL
)
10673 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10674 if ((bgp_static
= rn
->info
) != NULL
)
10677 prd
= (struct prefix_rd
*) &prn
->p
;
10679 /* "address-family" display. */
10680 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10682 /* "network" configuration display. */
10683 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10684 label
= decode_label (bgp_static
->tag
);
10686 vty_out (vty
, " network %s/%d rd %s tag %d",
10687 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10690 vty_out (vty
, "%s", VTY_NEWLINE
);
10696 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10697 afi_t afi
, safi_t safi
, int *write
)
10699 struct bgp_node
*prn
;
10700 struct bgp_node
*rn
;
10701 struct bgp_table
*table
;
10703 struct prefix_rd
*prd
;
10704 struct bgp_static
*bgp_static
;
10705 char buf
[PREFIX_STRLEN
];
10706 char buf2
[SU_ADDRSTRLEN
];
10707 char rdbuf
[RD_ADDRSTRLEN
];
10709 /* Network configuration. */
10710 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10711 if ((table
= prn
->info
) != NULL
)
10712 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10713 if ((bgp_static
= rn
->info
) != NULL
)
10715 char *macrouter
= NULL
;
10718 if(bgp_static
->router_mac
)
10719 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10720 if(bgp_static
->eth_s_id
)
10721 esi
= esi2str(bgp_static
->eth_s_id
);
10723 prd
= (struct prefix_rd
*) &prn
->p
;
10725 /* "address-family" display. */
10726 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10728 /* "network" configuration display. */
10729 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10731 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10733 prefix2str (p
, buf
, sizeof (buf
)),
10734 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10735 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10736 decode_label (bgp_static
->tag
), esi
, buf2
, macrouter
);
10737 vty_out (vty
, "%s", VTY_NEWLINE
);
10739 XFREE (MTYPE_TMP
, macrouter
);
10741 XFREE (MTYPE_TMP
, esi
);
10746 /* Configuration of static route announcement and aggregate
10749 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10750 afi_t afi
, safi_t safi
, int *write
)
10752 struct bgp_node
*rn
;
10754 struct bgp_static
*bgp_static
;
10755 struct bgp_aggregate
*bgp_aggregate
;
10756 char buf
[SU_ADDRSTRLEN
];
10758 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10759 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10761 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10762 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10764 /* Network configuration. */
10765 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10766 if ((bgp_static
= rn
->info
) != NULL
)
10770 /* "address-family" display. */
10771 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10773 /* "network" configuration display. */
10774 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10776 u_int32_t destination
;
10777 struct in_addr netmask
;
10779 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10780 masklen2ip (p
->prefixlen
, &netmask
);
10781 vty_out (vty
, " network %s",
10782 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10784 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10785 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10786 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10787 || p
->u
.prefix4
.s_addr
== 0)
10789 /* Natural mask is not display. */
10792 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10796 vty_out (vty
, " network %s/%d",
10797 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10801 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10802 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10804 if (bgp_static
->rmap
.name
)
10805 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10808 if (bgp_static
->backdoor
)
10809 vty_out (vty
, " backdoor");
10812 vty_out (vty
, "%s", VTY_NEWLINE
);
10815 /* Aggregate-address configuration. */
10816 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10817 if ((bgp_aggregate
= rn
->info
) != NULL
)
10821 /* "address-family" display. */
10822 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10824 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10826 struct in_addr netmask
;
10828 masklen2ip (p
->prefixlen
, &netmask
);
10829 vty_out (vty
, " aggregate-address %s %s",
10830 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10831 inet_ntoa (netmask
));
10835 vty_out (vty
, " aggregate-address %s/%d",
10836 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10840 if (bgp_aggregate
->as_set
)
10841 vty_out (vty
, " as-set");
10843 if (bgp_aggregate
->summary_only
)
10844 vty_out (vty
, " summary-only");
10846 vty_out (vty
, "%s", VTY_NEWLINE
);
10853 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10854 safi_t safi
, int *write
)
10856 struct bgp_node
*rn
;
10857 struct bgp_distance
*bdistance
;
10859 /* Distance configuration. */
10860 if (bgp
->distance_ebgp
[afi
][safi
]
10861 && bgp
->distance_ibgp
[afi
][safi
]
10862 && bgp
->distance_local
[afi
][safi
]
10863 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10864 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10865 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10867 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10868 vty_out (vty
, " distance bgp %d %d %d%s",
10869 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10870 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10873 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10874 rn
= bgp_route_next (rn
))
10875 if ((bdistance
= rn
->info
) != NULL
)
10877 char buf
[PREFIX_STRLEN
];
10879 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10880 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10881 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10882 bdistance
->access_list
? bdistance
->access_list
: "",
10889 /* Allocate routing table structure and install commands. */
10891 bgp_route_init (void)
10896 /* Init BGP distance table. */
10897 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10898 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10899 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10901 /* IPv4 BGP commands. */
10902 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10903 install_element (BGP_NODE
, &bgp_network_cmd
);
10904 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10905 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10906 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10907 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10908 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10909 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10910 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10911 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10912 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10913 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10914 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10915 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10917 install_element (BGP_NODE
, &aggregate_address_cmd
);
10918 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10919 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10920 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10922 /* IPv4 unicast configuration. */
10923 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10924 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10925 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10926 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10927 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10928 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10929 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10930 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_cmd
);
10931 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_route_map_cmd
);
10932 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10933 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10934 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10935 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10937 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10938 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10939 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10940 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10942 /* IPv4 multicast configuration. */
10943 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10944 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10945 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10946 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10947 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10948 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10949 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10950 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10951 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10952 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10953 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10954 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10955 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10956 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10957 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10959 /* IPv4 labeled-unicast configuration. */
10960 install_element (BGP_IPV4L_NODE
, &bgp_table_map_cmd
);
10961 install_element (BGP_IPV4L_NODE
, &bgp_network_cmd
);
10962 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_cmd
);
10963 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_cmd
);
10964 install_element (BGP_IPV4L_NODE
, &bgp_network_route_map_cmd
);
10965 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_route_map_cmd
);
10966 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10967 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_cmd
);
10968 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_route_map_cmd
);
10969 install_element (BGP_IPV4L_NODE
, &no_bgp_table_map_cmd
);
10970 install_element (BGP_IPV4L_NODE
, &no_bgp_network_cmd
);
10971 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_cmd
);
10972 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_natural_cmd
);
10974 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10975 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10976 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10977 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10979 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10980 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10981 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10982 #ifdef KEEP_OLD_VPN_COMMANDS
10983 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10984 #endif /* KEEP_OLD_VPN_COMMANDS */
10985 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10986 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10988 /* BGP dampening clear commands */
10989 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10990 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10992 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10993 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10996 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10997 #ifdef KEEP_OLD_VPN_COMMANDS
10998 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10999 #endif /* KEEP_OLD_VPN_COMMANDS */
11001 /* New config IPv6 BGP commands. */
11002 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11003 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11004 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
11005 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11006 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
11007 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
11008 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
11009 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
11010 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
11012 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11013 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11015 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11016 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11018 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11019 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11020 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11021 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11022 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11024 install_element (BGP_NODE
, &bgp_distance_cmd
);
11025 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
11026 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
11027 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
11028 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11029 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11030 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11031 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11032 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11033 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11034 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11035 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11036 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11037 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11038 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11039 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11040 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11041 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11042 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11043 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11044 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11045 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11046 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11047 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11048 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11049 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11050 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11051 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11052 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11053 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11055 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11056 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11057 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11058 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11060 /* IPv4 Multicast Mode */
11061 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11062 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11064 /* Large Communities */
11065 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11066 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11070 bgp_route_finish (void)
11075 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11076 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11078 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11079 bgp_distance_table
[afi
][safi
] = NULL
;