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
18 along with GNU Zebra; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
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 (bgp_labeled_safi(safi
))
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 bgp_table_lock (bgp_node_table (rn
));
1945 if (bgp_labeled_safi (safi
))
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_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
2021 update_group_refresh_default_originate_route_map
,
2022 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
2027 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
2030 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
2031 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2032 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2036 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2037 if (old_select
!= new_select
) {
2039 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
2040 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2043 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
2044 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2050 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2053 if (bgp_fibupd_safi(safi
) &&
2054 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
2055 !bgp_option_check (BGP_OPT_NO_FIB
))
2058 && new_select
->type
== ZEBRA_ROUTE_BGP
2059 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
2060 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2061 bgp_zebra_announce (rn
, p
, new_select
, bgp
, afi
, safi
);
2064 /* Withdraw the route from the kernel. */
2066 && old_select
->type
== ZEBRA_ROUTE_BGP
2067 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
2068 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2069 bgp_zebra_withdraw (p
, old_select
, safi
);
2073 /* Clear any route change flags. */
2074 bgp_zebra_clear_route_change_flags (rn
);
2076 /* Reap old select bgp_info, if it has been removed */
2077 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2078 bgp_info_reap (rn
, old_select
);
2080 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2085 bgp_processq_del (struct work_queue
*wq
, void *data
)
2087 struct bgp_process_queue
*pq
= data
;
2088 struct bgp_table
*table
;
2090 bgp_unlock (pq
->bgp
);
2093 table
= bgp_node_table (pq
->rn
);
2094 bgp_unlock_node (pq
->rn
);
2095 bgp_table_unlock (table
);
2097 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2101 bgp_process_queue_init (void)
2103 if (!bm
->process_main_queue
)
2105 bm
->process_main_queue
2106 = work_queue_new (bm
->master
, "process_main_queue");
2108 if ( !bm
->process_main_queue
)
2110 zlog_err ("%s: Failed to allocate work queue", __func__
);
2115 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2116 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2117 bm
->process_main_queue
->spec
.max_retries
= 0;
2118 bm
->process_main_queue
->spec
.hold
= 50;
2119 /* Use a higher yield value of 50ms for main queue processing */
2120 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2124 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2126 struct bgp_process_queue
*pqnode
;
2128 /* already scheduled for processing? */
2129 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2132 if (bm
->process_main_queue
== NULL
)
2135 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2136 sizeof (struct bgp_process_queue
));
2140 /* all unlocked in bgp_processq_del */
2141 bgp_table_lock (bgp_node_table (rn
));
2142 pqnode
->rn
= bgp_lock_node (rn
);
2146 pqnode
->safi
= safi
;
2147 work_queue_add (bm
->process_main_queue
, pqnode
);
2148 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2153 bgp_add_eoiu_mark (struct bgp
*bgp
)
2155 struct bgp_process_queue
*pqnode
;
2157 if (bm
->process_main_queue
== NULL
)
2160 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2161 sizeof (struct bgp_process_queue
));
2168 work_queue_add (bm
->process_main_queue
, pqnode
);
2172 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2176 peer
= THREAD_ARG (thread
);
2177 peer
->t_pmax_restart
= NULL
;
2179 if (bgp_debug_neighbor_events(peer
))
2180 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2183 peer_clear (peer
, NULL
);
2189 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2190 safi_t safi
, int always
)
2195 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2198 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2200 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2204 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2205 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2206 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2207 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2209 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2212 /* Convert AFI, SAFI to values for packet. */
2213 pkt_afi
= afi_int2iana (afi
);
2214 pkt_safi
= safi_int2iana (safi
);
2218 ndata
[0] = (pkt_afi
>> 8);
2220 ndata
[2] = pkt_safi
;
2221 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2222 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2223 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2224 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2226 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2227 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2228 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2231 /* Dynamic peers will just close their connection. */
2232 if (peer_dynamic_neighbor (peer
))
2235 /* restart timer start */
2236 if (peer
->pmax_restart
[afi
][safi
])
2238 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2240 if (bgp_debug_neighbor_events(peer
))
2241 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2242 peer
->host
, peer
->v_pmax_restart
);
2244 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2245 peer
->v_pmax_restart
);
2251 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2253 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2255 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2259 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2260 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2261 peer
->pmax
[afi
][safi
]);
2262 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2265 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2269 /* Unconditionally remove the route from the RIB, without taking
2270 * damping into consideration (eg, because the session went down)
2273 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2274 afi_t afi
, safi_t safi
)
2276 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2278 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2279 bgp_info_delete (rn
, ri
); /* keep historical info */
2281 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2285 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2286 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2288 int status
= BGP_DAMP_NONE
;
2290 /* apply dampening, if result is suppressed, we'll be retaining
2291 * the bgp_info in the RIB for historical reference.
2293 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2294 && peer
->sort
== BGP_PEER_EBGP
)
2295 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2296 == BGP_DAMP_SUPPRESSED
)
2298 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2303 if (safi
== SAFI_MPLS_VPN
) {
2304 struct bgp_node
*prn
= NULL
;
2305 struct bgp_table
*table
= NULL
;
2307 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2309 table
= (struct bgp_table
*)(prn
->info
);
2311 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2318 bgp_unlock_node(prn
);
2320 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2321 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2323 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2324 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2328 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2331 static struct bgp_info
*
2332 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2333 struct bgp_node
*rn
)
2335 struct bgp_info
*new;
2337 /* Make new BGP info. */
2338 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2340 new->instance
= instance
;
2341 new->sub_type
= sub_type
;
2344 new->uptime
= bgp_clock ();
2346 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2351 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2353 struct attr_extra
*extra
;
2357 extra
= bgp_attr_extra_get(attr
);
2359 if(eth_s_id
== NULL
)
2361 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2365 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2369 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2373 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2378 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2380 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2381 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2384 if(afi
!= AFI_L2VPN
)
2386 if (!info
->attr
|| !info
->attr
->extra
)
2388 memset(&temp
, 0, 16);
2389 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2390 info_gw_ip
= (union gw_addr
*)&temp
;
2391 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2396 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2397 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2400 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2402 info_gw_ip_remote
= gw_ip
;
2403 if(eth_s_id
== NULL
)
2404 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2406 info_eth_s_id_remote
= eth_s_id
;
2407 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2409 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2412 /* Check if received nexthop is valid or not. */
2414 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2416 struct attr_extra
*attre
= attr
->extra
;
2419 /* Only validated for unicast and multicast currently. */
2420 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2423 /* If NEXT_HOP is present, validate it. */
2424 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2426 if (attr
->nexthop
.s_addr
== 0 ||
2427 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2428 bgp_nexthop_self (bgp
, attr
))
2432 /* If MP_NEXTHOP is present, validate it. */
2433 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2434 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2435 * it is not an IPv6 link-local address.
2437 if (attre
&& attre
->mp_nexthop_len
)
2439 switch (attre
->mp_nexthop_len
)
2441 case BGP_ATTR_NHLEN_IPV4
:
2442 case BGP_ATTR_NHLEN_VPNV4
:
2443 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2444 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2447 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2448 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2449 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2450 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2451 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2452 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2465 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2466 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2467 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2468 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2471 int aspath_loop_count
= 0;
2472 struct bgp_node
*rn
;
2474 struct attr new_attr
;
2475 struct attr_extra new_extra
;
2476 struct attr
*attr_new
;
2477 struct bgp_info
*ri
;
2478 struct bgp_info
*new;
2480 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2483 int do_loop_check
= 1;
2485 int vnc_implicit_withdraw
= 0;
2488 memset (&new_attr
, 0, sizeof(struct attr
));
2489 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2492 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2493 label_buf
[0] = '\0';
2494 if (bgp_labeled_safi(safi
))
2495 sprintf (label_buf
, "label %u", label_pton(tag
));
2497 /* When peer's soft reconfiguration enabled. Record input packet in
2499 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2500 && peer
!= bgp
->peer_self
)
2501 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2503 /* Check previously received route. */
2504 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2505 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2506 ri
->addpath_rx_id
== addpath_id
)
2509 /* AS path local-as loop check. */
2510 if (peer
->change_local_as
)
2512 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2513 aspath_loop_count
= 1;
2515 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2517 reason
= "as-path contains our own AS;";
2522 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2523 * as-path is our ASN then we do not need to call aspath_loop_check
2525 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2526 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2529 /* AS path loop check. */
2532 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2533 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2534 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2536 reason
= "as-path contains our own AS;";
2541 /* Route reflector originator ID check. */
2542 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2543 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2545 reason
= "originator is us;";
2549 /* Route reflector cluster ID check. */
2550 if (bgp_cluster_filter (peer
, attr
))
2552 reason
= "reflected from the same cluster;";
2556 /* Apply incoming filter. */
2557 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2563 new_attr
.extra
= &new_extra
;
2564 bgp_attr_dup (&new_attr
, attr
);
2566 /* Apply incoming route-map.
2567 * NB: new_attr may now contain newly allocated values from route-map "set"
2568 * commands, so we need bgp_attr_flush in the error paths, until we intern
2569 * the attr (which takes over the memory references) */
2570 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2572 reason
= "route-map;";
2573 bgp_attr_flush (&new_attr
);
2577 /* next hop check. */
2578 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2580 reason
= "martian or self next-hop;";
2581 bgp_attr_flush (&new_attr
);
2585 attr_new
= bgp_attr_intern (&new_attr
);
2587 /* If the update is implicit withdraw. */
2590 ri
->uptime
= bgp_clock ();
2592 /* Same attribute comes in. */
2593 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2594 && attrhash_cmp (ri
->attr
, attr_new
)
2595 && (!bgp_labeled_safi(safi
) ||
2596 memcmp ((bgp_info_extra_get (ri
))->tag
, tag
, 3) == 0)
2597 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2598 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2600 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2601 && peer
->sort
== BGP_PEER_EBGP
2602 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2604 if (bgp_debug_update(peer
, p
, NULL
, 1))
2605 zlog_debug ("%s rcvd %s %s", peer
->host
,
2606 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2607 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2609 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2611 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2612 bgp_process (bgp
, rn
, afi
, safi
);
2615 else /* Duplicate - odd */
2617 if (bgp_debug_update(peer
, p
, NULL
, 1))
2619 if (!peer
->rcvd_attr_printed
)
2621 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2622 peer
->rcvd_attr_printed
= 1;
2625 zlog_debug ("%s rcvd %s %s...duplicate ignored",
2627 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2628 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2631 /* graceful restart STALE flag unset. */
2632 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2634 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2635 bgp_process (bgp
, rn
, afi
, safi
);
2639 bgp_unlock_node (rn
);
2640 bgp_attr_unintern (&attr_new
);
2645 /* Withdraw/Announce before we fully processed the withdraw */
2646 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2648 if (bgp_debug_update(peer
, p
, NULL
, 1))
2649 zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
2651 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2652 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2653 bgp_info_restore (rn
, ri
);
2656 /* Received Logging. */
2657 if (bgp_debug_update(peer
, p
, NULL
, 1))
2658 zlog_debug ("%s rcvd %s %s", peer
->host
,
2659 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2660 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2662 /* graceful restart STALE flag unset. */
2663 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2664 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2666 /* The attribute is changed. */
2667 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2669 /* implicit withdraw, decrement aggregate and pcount here.
2670 * only if update is accepted, they'll increment below.
2672 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2674 /* Update bgp route dampening information. */
2675 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2676 && peer
->sort
== BGP_PEER_EBGP
)
2678 /* This is implicit withdraw so we should update dampening
2680 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2681 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2684 if (safi
== SAFI_MPLS_VPN
) {
2685 struct bgp_node
*prn
= NULL
;
2686 struct bgp_table
*table
= NULL
;
2688 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2690 table
= (struct bgp_table
*)(prn
->info
);
2692 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2699 bgp_unlock_node(prn
);
2701 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2702 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2704 * Implicit withdraw case.
2706 ++vnc_implicit_withdraw
;
2707 vnc_import_bgp_del_route(bgp
, p
, ri
);
2708 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2713 /* Update to new attribute. */
2714 bgp_attr_unintern (&ri
->attr
);
2715 ri
->attr
= attr_new
;
2717 /* Update MPLS tag. */
2718 if (bgp_labeled_safi(safi
))
2719 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2722 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2724 if (vnc_implicit_withdraw
)
2727 * Add back the route with its new attributes (e.g., nexthop).
2728 * The route is still selected, until the route selection
2729 * queued by bgp_process actually runs. We have to make this
2730 * update to the VNC side immediately to avoid racing against
2731 * configuration changes (e.g., route-map changes) which
2732 * trigger re-importation of the entire RIB.
2734 vnc_import_bgp_add_route(bgp
, p
, ri
);
2735 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2739 /* Update Overlay Index */
2740 if(afi
== AFI_L2VPN
)
2742 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2743 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2746 /* Update bgp route dampening information. */
2747 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2748 && peer
->sort
== BGP_PEER_EBGP
)
2750 /* Now we do normal update dampening. */
2751 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2752 if (ret
== BGP_DAMP_SUPPRESSED
)
2754 bgp_unlock_node (rn
);
2759 /* Nexthop reachability check - for unicast and labeled-unicast.. */
2760 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2761 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2763 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2764 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2765 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2770 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2771 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2774 if (BGP_DEBUG(nht
, NHT
))
2776 char buf1
[INET6_ADDRSTRLEN
];
2777 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2778 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2780 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2784 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2787 if (safi
== SAFI_MPLS_VPN
)
2789 struct bgp_node
*prn
= NULL
;
2790 struct bgp_table
*table
= NULL
;
2792 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2795 table
= (struct bgp_table
*)(prn
->info
);
2797 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2804 bgp_unlock_node(prn
);
2808 /* Process change. */
2809 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2811 bgp_process (bgp
, rn
, afi
, safi
);
2812 bgp_unlock_node (rn
);
2815 if (SAFI_MPLS_VPN
== safi
)
2817 uint32_t label
= decode_label(tag
);
2819 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2822 if (SAFI_ENCAP
== safi
)
2824 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2830 } // End of implicit withdraw
2832 /* Received Logging. */
2833 if (bgp_debug_update(peer
, p
, NULL
, 1))
2835 if (!peer
->rcvd_attr_printed
)
2837 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2838 peer
->rcvd_attr_printed
= 1;
2841 zlog_debug ("%s rcvd %s%s ", peer
->host
,
2842 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2843 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2846 /* Make new BGP info. */
2847 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2849 /* Update MPLS tag. */
2850 if (bgp_labeled_safi(safi
) || safi
== SAFI_EVPN
)
2851 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2853 /* Update Overlay Index */
2854 if(afi
== AFI_L2VPN
)
2856 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2857 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2859 /* Nexthop reachability check. */
2860 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2861 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2863 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2864 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2865 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2870 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2871 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2874 if (BGP_DEBUG(nht
, NHT
))
2876 char buf1
[INET6_ADDRSTRLEN
];
2877 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2878 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2880 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2884 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2887 new->addpath_rx_id
= addpath_id
;
2889 /* Increment prefix */
2890 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2892 /* Register new BGP information. */
2893 bgp_info_add (rn
, new);
2895 /* route_node_get lock */
2896 bgp_unlock_node (rn
);
2899 if (safi
== SAFI_MPLS_VPN
)
2901 struct bgp_node
*prn
= NULL
;
2902 struct bgp_table
*table
= NULL
;
2904 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2907 table
= (struct bgp_table
*)(prn
->info
);
2909 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2916 bgp_unlock_node(prn
);
2920 /* If maximum prefix count is configured and current prefix
2922 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2925 /* Process change. */
2926 bgp_process (bgp
, rn
, afi
, safi
);
2929 if (SAFI_MPLS_VPN
== safi
)
2931 uint32_t label
= decode_label(tag
);
2933 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2936 if (SAFI_ENCAP
== safi
)
2938 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2945 /* This BGP update is filtered. Log the reason then update BGP
2948 if (bgp_debug_update(peer
, p
, NULL
, 1))
2950 if (!peer
->rcvd_attr_printed
)
2952 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2953 peer
->rcvd_attr_printed
= 1;
2956 zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
2958 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2959 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
, reason
);
2963 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2965 bgp_unlock_node (rn
);
2969 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2970 * a few lines above)
2972 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2974 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2982 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2983 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2984 struct prefix_rd
*prd
, u_char
*tag
, struct bgp_route_evpn
*evpn
)
2987 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2988 struct bgp_node
*rn
;
2989 struct bgp_info
*ri
;
2992 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2994 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3001 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3003 /* If peer is soft reconfiguration enabled. Record input packet for
3004 * further calculation.
3006 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3007 * routes that are filtered. This tanks out Quagga RS pretty badly due to
3008 * the iteration over all RS clients.
3009 * Since we need to remove the entry from adj_in anyway, do that first and
3010 * if there was no entry, we don't need to do anything more.
3012 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3013 && peer
!= bgp
->peer_self
)
3014 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
3016 if (bgp_debug_update (peer
, p
, NULL
, 1))
3017 zlog_debug ("%s withdrawing route %s not in adj-in",
3019 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3020 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3021 bgp_unlock_node (rn
);
3025 /* Lookup withdrawn route. */
3026 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3027 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
3028 ri
->addpath_rx_id
== addpath_id
)
3032 if (bgp_debug_update(peer
, p
, NULL
, 1))
3034 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
3036 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3037 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3040 /* Withdraw specified route from routing table. */
3041 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
3042 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
3043 else if (bgp_debug_update(peer
, p
, NULL
, 1))
3044 zlog_debug ("%s Can't find the route %s",
3046 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3047 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3049 /* Unlock bgp_node_get() lock. */
3050 bgp_unlock_node (rn
);
3056 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
3058 struct update_subgroup
*subgrp
;
3059 subgrp
= peer_subgroup(peer
, afi
, safi
);
3060 subgroup_default_originate(subgrp
, withdraw
);
3065 * bgp_stop_announce_route_timer
3068 bgp_stop_announce_route_timer (struct peer_af
*paf
)
3070 if (!paf
->t_announce_route
)
3073 THREAD_TIMER_OFF (paf
->t_announce_route
);
3077 * bgp_announce_route_timer_expired
3079 * Callback that is invoked when the route announcement timer for a
3083 bgp_announce_route_timer_expired (struct thread
*t
)
3085 struct peer_af
*paf
;
3088 paf
= THREAD_ARG (t
);
3091 assert (paf
->t_announce_route
);
3092 paf
->t_announce_route
= NULL
;
3094 if (peer
->status
!= Established
)
3097 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3100 peer_af_announce_route (paf
, 1);
3105 * bgp_announce_route
3107 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3110 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3112 struct peer_af
*paf
;
3113 struct update_subgroup
*subgrp
;
3115 paf
= peer_af_find (peer
, afi
, safi
);
3118 subgrp
= PAF_SUBGRP(paf
);
3121 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3122 * or a refresh has already been triggered.
3124 if (!subgrp
|| paf
->t_announce_route
)
3128 * Start a timer to stagger/delay the announce. This serves
3129 * two purposes - announcement can potentially be combined for
3130 * multiple peers and the announcement doesn't happen in the
3133 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
3134 bgp_announce_route_timer_expired
, paf
,
3135 (subgrp
->peer_count
== 1) ?
3136 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
3137 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
3141 * Announce routes from all AF tables to a peer.
3143 * This should ONLY be called when there is a need to refresh the
3144 * routes to the peer based on a policy change for this peer alone
3145 * or a route refresh request received from the peer.
3146 * The operation will result in splitting the peer from its existing
3147 * subgroups and putting it in new subgroups.
3150 bgp_announce_route_all (struct peer
*peer
)
3155 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3156 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3157 bgp_announce_route (peer
, afi
, safi
);
3161 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3162 struct bgp_table
*table
, struct prefix_rd
*prd
)
3165 struct bgp_node
*rn
;
3166 struct bgp_adj_in
*ain
;
3169 table
= peer
->bgp
->rib
[afi
][safi
];
3171 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3172 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3174 if (ain
->peer
== peer
)
3176 struct bgp_info
*ri
= rn
->info
;
3177 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3179 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3180 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3185 bgp_unlock_node (rn
);
3193 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3195 struct bgp_node
*rn
;
3196 struct bgp_table
*table
;
3198 if (peer
->status
!= Established
)
3201 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3202 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3204 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3205 rn
= bgp_route_next (rn
))
3206 if ((table
= rn
->info
) != NULL
)
3208 struct prefix_rd prd
;
3209 prd
.family
= AF_UNSPEC
;
3211 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3213 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3218 struct bgp_clear_node_queue
3220 struct bgp_node
*rn
;
3223 static wq_item_status
3224 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3226 struct bgp_clear_node_queue
*cnq
= data
;
3227 struct bgp_node
*rn
= cnq
->rn
;
3228 struct peer
*peer
= wq
->spec
.data
;
3229 struct bgp_info
*ri
;
3230 afi_t afi
= bgp_node_table (rn
)->afi
;
3231 safi_t safi
= bgp_node_table (rn
)->safi
;
3233 assert (rn
&& peer
);
3235 /* It is possible that we have multiple paths for a prefix from a peer
3236 * if that peer is using AddPath.
3238 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3239 if (ri
->peer
== peer
)
3241 /* graceful restart STALE flag set. */
3242 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3243 && peer
->nsf
[afi
][safi
]
3244 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3245 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3246 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3248 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3254 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3256 struct bgp_clear_node_queue
*cnq
= data
;
3257 struct bgp_node
*rn
= cnq
->rn
;
3258 struct bgp_table
*table
= bgp_node_table (rn
);
3260 bgp_unlock_node (rn
);
3261 bgp_table_unlock (table
);
3262 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3266 bgp_clear_node_complete (struct work_queue
*wq
)
3268 struct peer
*peer
= wq
->spec
.data
;
3270 /* Tickle FSM to start moving again */
3271 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3273 peer_unlock (peer
); /* bgp_clear_route */
3277 bgp_clear_node_queue_init (struct peer
*peer
)
3279 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3281 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3282 #undef CLEAR_QUEUE_NAME_LEN
3284 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3286 zlog_err ("%s: Failed to allocate work queue", __func__
);
3289 peer
->clear_node_queue
->spec
.hold
= 10;
3290 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3291 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3292 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3293 peer
->clear_node_queue
->spec
.max_retries
= 0;
3295 /* we only 'lock' this peer reference when the queue is actually active */
3296 peer
->clear_node_queue
->spec
.data
= peer
;
3300 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3301 struct bgp_table
*table
)
3303 struct bgp_node
*rn
;
3304 int force
= bm
->process_main_queue
? 0 : 1;
3307 table
= peer
->bgp
->rib
[afi
][safi
];
3309 /* If still no table => afi/safi isn't configured at all or smth. */
3313 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3315 struct bgp_info
*ri
, *next
;
3316 struct bgp_adj_in
*ain
;
3317 struct bgp_adj_in
*ain_next
;
3319 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3320 * queued for every clearing peer, regardless of whether it is
3321 * relevant to the peer at hand.
3323 * Overview: There are 3 different indices which need to be
3324 * scrubbed, potentially, when a peer is removed:
3326 * 1 peer's routes visible via the RIB (ie accepted routes)
3327 * 2 peer's routes visible by the (optional) peer's adj-in index
3328 * 3 other routes visible by the peer's adj-out index
3330 * 3 there is no hurry in scrubbing, once the struct peer is
3331 * removed from bgp->peer, we could just GC such deleted peer's
3332 * adj-outs at our leisure.
3334 * 1 and 2 must be 'scrubbed' in some way, at least made
3335 * invisible via RIB index before peer session is allowed to be
3336 * brought back up. So one needs to know when such a 'search' is
3341 * - there'd be a single global queue or a single RIB walker
3342 * - rather than tracking which route_nodes still need to be
3343 * examined on a peer basis, we'd track which peers still
3346 * Given that our per-peer prefix-counts now should be reliable,
3347 * this may actually be achievable. It doesn't seem to be a huge
3348 * problem at this time,
3350 * It is possible that we have multiple paths for a prefix from a peer
3351 * if that peer is using AddPath.
3356 ain_next
= ain
->next
;
3358 if (ain
->peer
== peer
)
3360 bgp_adj_in_remove (rn
, ain
);
3361 bgp_unlock_node (rn
);
3367 for (ri
= rn
->info
; ri
; ri
= next
)
3370 if (ri
->peer
!= peer
)
3374 bgp_info_reap (rn
, ri
);
3377 struct bgp_clear_node_queue
*cnq
;
3379 /* both unlocked in bgp_clear_node_queue_del */
3380 bgp_table_lock (bgp_node_table (rn
));
3382 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3383 sizeof (struct bgp_clear_node_queue
));
3385 work_queue_add (peer
->clear_node_queue
, cnq
);
3394 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3396 struct bgp_node
*rn
;
3397 struct bgp_table
*table
;
3399 if (peer
->clear_node_queue
== NULL
)
3400 bgp_clear_node_queue_init (peer
);
3402 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3403 * Idle until it receives a Clearing_Completed event. This protects
3404 * against peers which flap faster than we can we clear, which could
3407 * a) race with routes from the new session being installed before
3408 * clear_route_node visits the node (to delete the route of that
3410 * b) resource exhaustion, clear_route_node likely leads to an entry
3411 * on the process_main queue. Fast-flapping could cause that queue
3415 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3416 * the unlock will happen upon work-queue completion; other wise, the
3417 * unlock happens at the end of this function.
3419 if (!peer
->clear_node_queue
->thread
)
3422 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3423 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3425 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3426 rn
= bgp_route_next (rn
))
3427 if ((table
= rn
->info
) != NULL
)
3428 bgp_clear_route_table (peer
, afi
, safi
, table
);
3430 /* unlock if no nodes got added to the clear-node-queue. */
3431 if (!peer
->clear_node_queue
->thread
)
3437 bgp_clear_route_all (struct peer
*peer
)
3442 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3443 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3444 bgp_clear_route (peer
, afi
, safi
);
3447 rfapiProcessPeerDown(peer
);
3452 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3454 struct bgp_table
*table
;
3455 struct bgp_node
*rn
;
3456 struct bgp_adj_in
*ain
;
3457 struct bgp_adj_in
*ain_next
;
3459 table
= peer
->bgp
->rib
[afi
][safi
];
3461 /* It is possible that we have multiple paths for a prefix from a peer
3462 * if that peer is using AddPath.
3464 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3470 ain_next
= ain
->next
;
3472 if (ain
->peer
== peer
)
3474 bgp_adj_in_remove (rn
, ain
);
3475 bgp_unlock_node (rn
);
3484 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3486 struct bgp_node
*rn
;
3487 struct bgp_info
*ri
;
3488 struct bgp_table
*table
;
3490 if ( safi
== SAFI_MPLS_VPN
)
3492 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3494 struct bgp_node
*rm
;
3495 struct bgp_info
*ri
;
3497 /* look for neighbor in tables */
3498 if ((table
= rn
->info
) != NULL
)
3500 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3501 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3502 if (ri
->peer
== peer
)
3504 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3505 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3513 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3514 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3515 if (ri
->peer
== peer
)
3517 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3518 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3525 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3527 struct bgp_node
*rn
;
3528 struct bgp_info
*ri
;
3529 struct bgp_info
*next
;
3531 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3532 for (ri
= rn
->info
; ri
; ri
= next
)
3535 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3536 && ri
->type
== ZEBRA_ROUTE_BGP
3537 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3538 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3541 if (table
->owner
&& table
->owner
->bgp
)
3542 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3544 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3545 bgp_info_reap (rn
, ri
);
3550 /* Delete all kernel routes. */
3552 bgp_cleanup_routes (struct bgp
*bgp
)
3555 struct bgp_node
*rn
;
3557 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3559 if (afi
== AFI_L2VPN
)
3561 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3563 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3565 if (afi
!= AFI_L2VPN
)
3568 safi
= SAFI_MPLS_VPN
;
3569 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3570 rn
= bgp_route_next (rn
))
3574 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3575 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3577 bgp_unlock_node(rn
);
3581 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3582 rn
= bgp_route_next (rn
))
3586 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3587 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3589 bgp_unlock_node(rn
);
3594 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3595 rn
= bgp_route_next (rn
))
3599 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3600 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3602 bgp_unlock_node(rn
);
3611 bgp_zclient_reset ();
3612 access_list_reset ();
3613 prefix_list_reset ();
3617 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3619 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3620 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3623 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3626 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3627 struct bgp_nlri
*packet
)
3636 int addpath_encoded
;
3637 u_int32_t addpath_id
;
3639 /* Check peer status. */
3640 if (peer
->status
!= Established
)
3644 lim
= pnt
+ packet
->length
;
3646 safi
= packet
->safi
;
3648 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3650 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3651 syntactic validity. If the field is syntactically incorrect,
3652 then the Error Subcode is set to Invalid Network Field. */
3653 for (; pnt
< lim
; pnt
+= psize
)
3655 /* Clear prefix structure. */
3656 memset (&p
, 0, sizeof (struct prefix
));
3658 if (addpath_encoded
)
3661 /* When packet overflow occurs return immediately. */
3662 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3665 addpath_id
= ntohl(*((uint32_t*) pnt
));
3666 pnt
+= BGP_ADDPATH_ID_LEN
;
3669 /* Fetch prefix length. */
3670 p
.prefixlen
= *pnt
++;
3671 /* afi/safi validity already verified by caller, bgp_update_receive */
3672 p
.family
= afi2family (afi
);
3674 /* Prefix length check. */
3675 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3677 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3678 peer
->host
, p
.prefixlen
, packet
->afi
);
3682 /* Packet size overflow check. */
3683 psize
= PSIZE (p
.prefixlen
);
3685 /* When packet overflow occur return immediately. */
3686 if (pnt
+ psize
> lim
)
3688 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3689 peer
->host
, p
.prefixlen
);
3693 /* Defensive coding, double-check the psize fits in a struct prefix */
3694 if (psize
> (ssize_t
) sizeof(p
.u
))
3696 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3697 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3701 /* Fetch prefix from NLRI packet. */
3702 memcpy (&p
.u
.prefix
, pnt
, psize
);
3704 /* Check address. */
3705 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3707 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3709 /* From RFC4271 Section 6.3:
3711 * If a prefix in the NLRI field is semantically incorrect
3712 * (e.g., an unexpected multicast IP address), an error SHOULD
3713 * be logged locally, and the prefix SHOULD be ignored.
3715 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3716 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3721 /* Check address. */
3722 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3724 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3728 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3729 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3733 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3737 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3738 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3744 /* Normal process. */
3746 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3747 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3749 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3750 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3752 /* Address family configuration mismatch or maximum-prefix count
3758 /* Packet length consistency check. */
3761 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3769 static struct bgp_static
*
3770 bgp_static_new (void)
3772 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3776 bgp_static_free (struct bgp_static
*bgp_static
)
3778 if (bgp_static
->rmap
.name
)
3779 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3780 if(bgp_static
->eth_s_id
)
3781 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3782 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3786 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3787 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3789 struct bgp_node
*rn
;
3790 struct bgp_info
*ri
;
3791 struct bgp_info
*new;
3792 struct bgp_info info
;
3794 struct attr
*attr_new
;
3797 int vnc_implicit_withdraw
= 0;
3800 assert (bgp_static
);
3804 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3806 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3808 attr
.nexthop
= bgp_static
->igpnexthop
;
3809 attr
.med
= bgp_static
->igpmetric
;
3810 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3812 if (bgp_static
->atomic
)
3813 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3815 /* Store label index, if required. */
3816 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3818 (bgp_attr_extra_get (&attr
))->label_index
= bgp_static
->label_index
;
3819 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3822 /* Apply route-map. */
3823 if (bgp_static
->rmap
.name
)
3825 struct attr attr_tmp
= attr
;
3826 info
.peer
= bgp
->peer_self
;
3827 info
.attr
= &attr_tmp
;
3829 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3831 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3833 bgp
->peer_self
->rmap_type
= 0;
3835 if (ret
== RMAP_DENYMATCH
)
3837 /* Free uninterned attribute. */
3838 bgp_attr_flush (&attr_tmp
);
3840 /* Unintern original. */
3841 aspath_unintern (&attr
.aspath
);
3842 bgp_attr_extra_free (&attr
);
3843 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3846 attr_new
= bgp_attr_intern (&attr_tmp
);
3849 attr_new
= bgp_attr_intern (&attr
);
3851 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3852 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3853 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3858 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3859 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3860 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3862 bgp_unlock_node (rn
);
3863 bgp_attr_unintern (&attr_new
);
3864 aspath_unintern (&attr
.aspath
);
3865 bgp_attr_extra_free (&attr
);
3870 /* The attribute is changed. */
3871 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3873 /* Rewrite BGP route information. */
3874 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3875 bgp_info_restore(rn
, ri
);
3877 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3879 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3881 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3884 * Implicit withdraw case.
3885 * We have to do this before ri is changed
3887 ++vnc_implicit_withdraw
;
3888 vnc_import_bgp_del_route(bgp
, p
, ri
);
3889 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3893 bgp_attr_unintern (&ri
->attr
);
3894 ri
->attr
= attr_new
;
3895 ri
->uptime
= bgp_clock ();
3897 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3899 if (vnc_implicit_withdraw
)
3901 vnc_import_bgp_add_route(bgp
, p
, ri
);
3902 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3907 /* Nexthop reachability check. */
3908 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3909 safi
== SAFI_UNICAST
)
3911 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0) &&
3912 safi
== SAFI_UNICAST
)
3913 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3916 if (BGP_DEBUG(nht
, NHT
))
3918 char buf1
[INET6_ADDRSTRLEN
];
3919 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3921 zlog_debug("%s(%s): Route not in table, not advertising",
3922 __FUNCTION__
, buf1
);
3924 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3929 /* Delete the NHT structure if any, if we're toggling between
3930 * enabling/disabling import check. We deregister the route
3931 * from NHT to avoid overloading NHT and the process interaction
3933 bgp_unlink_nexthop(ri
);
3934 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3936 /* Process change. */
3937 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3938 bgp_process (bgp
, rn
, afi
, safi
);
3939 bgp_unlock_node (rn
);
3940 aspath_unintern (&attr
.aspath
);
3941 bgp_attr_extra_free (&attr
);
3946 /* Make new BGP info. */
3947 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3949 /* Nexthop reachability check. */
3950 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3952 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3953 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3956 if (BGP_DEBUG(nht
, NHT
))
3958 char buf1
[INET6_ADDRSTRLEN
];
3959 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3961 zlog_debug("%s(%s): Route not in table, not advertising",
3962 __FUNCTION__
, buf1
);
3964 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3969 /* Delete the NHT structure if any, if we're toggling between
3970 * enabling/disabling import check. We deregister the route
3971 * from NHT to avoid overloading NHT and the process interaction
3973 bgp_unlink_nexthop(new);
3975 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3978 /* Aggregate address increment. */
3979 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3981 /* Register new BGP information. */
3982 bgp_info_add (rn
, new);
3984 /* route_node_get lock */
3985 bgp_unlock_node (rn
);
3987 /* Process change. */
3988 bgp_process (bgp
, rn
, afi
, safi
);
3990 /* Unintern original. */
3991 aspath_unintern (&attr
.aspath
);
3992 bgp_attr_extra_free (&attr
);
3996 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3999 struct bgp_node
*rn
;
4000 struct bgp_info
*ri
;
4002 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4004 /* Check selected route and self inserted route. */
4005 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4006 if (ri
->peer
== bgp
->peer_self
4007 && ri
->type
== ZEBRA_ROUTE_BGP
4008 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4011 /* Withdraw static BGP route from routing table. */
4014 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4015 bgp_unlink_nexthop(ri
);
4016 bgp_info_delete (rn
, ri
);
4017 bgp_process (bgp
, rn
, afi
, safi
);
4020 /* Unlock bgp_node_lookup. */
4021 bgp_unlock_node (rn
);
4025 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4028 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4029 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
4031 struct bgp_node
*rn
;
4032 struct bgp_info
*ri
;
4034 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4036 /* Check selected route and self inserted route. */
4037 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4038 if (ri
->peer
== bgp
->peer_self
4039 && ri
->type
== ZEBRA_ROUTE_BGP
4040 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4043 /* Withdraw static BGP route from routing table. */
4047 rfapiProcessWithdraw(
4056 1); /* Kill, since it is an administrative change */
4058 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4059 bgp_info_delete (rn
, ri
);
4060 bgp_process (bgp
, rn
, afi
, safi
);
4063 /* Unlock bgp_node_lookup. */
4064 bgp_unlock_node (rn
);
4068 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4069 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4071 struct bgp_node
*rn
;
4072 struct bgp_info
*new;
4073 struct attr
*attr_new
;
4074 struct attr attr
= { 0 };
4075 struct bgp_info
*ri
;
4077 u_int32_t label
= 0;
4081 assert (bgp_static
);
4083 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4085 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4087 attr
.nexthop
= bgp_static
->igpnexthop
;
4088 attr
.med
= bgp_static
->igpmetric
;
4089 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4091 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4093 if (bgp_static
->igpnexthop
.s_addr
)
4095 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4096 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4099 if(afi
== AFI_L2VPN
)
4101 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4102 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4103 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4104 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4105 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4106 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4108 struct bgp_encap_type_vxlan bet
;
4109 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4110 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4111 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4113 if (bgp_static
->router_mac
)
4115 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4118 /* Apply route-map. */
4119 if (bgp_static
->rmap
.name
)
4121 struct attr attr_tmp
= attr
;
4122 struct bgp_info info
;
4125 info
.peer
= bgp
->peer_self
;
4126 info
.attr
= &attr_tmp
;
4128 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4130 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4132 bgp
->peer_self
->rmap_type
= 0;
4134 if (ret
== RMAP_DENYMATCH
)
4136 /* Free uninterned attribute. */
4137 bgp_attr_flush (&attr_tmp
);
4139 /* Unintern original. */
4140 aspath_unintern (&attr
.aspath
);
4141 bgp_attr_extra_free (&attr
);
4142 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4147 attr_new
= bgp_attr_intern (&attr_tmp
);
4151 attr_new
= bgp_attr_intern (&attr
);
4154 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4155 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4156 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4162 memset(&add
, 0, sizeof(union gw_addr
));
4163 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4164 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4165 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4167 bgp_unlock_node (rn
);
4168 bgp_attr_unintern (&attr_new
);
4169 aspath_unintern (&attr
.aspath
);
4170 bgp_attr_extra_free (&attr
);
4175 /* The attribute is changed. */
4176 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4178 /* Rewrite BGP route information. */
4179 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4180 bgp_info_restore(rn
, ri
);
4182 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4183 bgp_attr_unintern (&ri
->attr
);
4184 ri
->attr
= attr_new
;
4185 ri
->uptime
= bgp_clock ();
4188 label
= decode_label (ri
->extra
->tag
);
4191 /* Process change. */
4192 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4193 bgp_process (bgp
, rn
, afi
, safi
);
4195 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4196 ri
->attr
, afi
, safi
,
4197 ri
->type
, ri
->sub_type
, &label
);
4199 bgp_unlock_node (rn
);
4200 aspath_unintern (&attr
.aspath
);
4201 bgp_attr_extra_free (&attr
);
4207 /* Make new BGP info. */
4208 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4210 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4211 new->extra
= bgp_info_extra_new();
4212 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4214 label
= decode_label (bgp_static
->tag
);
4217 /* Aggregate address increment. */
4218 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4220 /* Register new BGP information. */
4221 bgp_info_add (rn
, new);
4222 /* route_node_get lock */
4223 bgp_unlock_node (rn
);
4225 /* Process change. */
4226 bgp_process (bgp
, rn
, afi
, safi
);
4229 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4230 new->attr
, afi
, safi
,
4231 new->type
, new->sub_type
, &label
);
4234 /* Unintern original. */
4235 aspath_unintern (&attr
.aspath
);
4236 bgp_attr_extra_free (&attr
);
4239 /* Configure static BGP network. When user don't run zebra, static
4240 route should be installed as valid. */
4242 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4243 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4244 u_int32_t label_index
)
4246 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4249 struct bgp_static
*bgp_static
;
4250 struct bgp_node
*rn
;
4251 u_char need_update
= 0;
4253 /* Convert IP prefix string to struct prefix. */
4254 ret
= str2prefix (ip_str
, &p
);
4257 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4260 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4262 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4269 /* Set BGP static route configuration. */
4270 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4274 /* Configuration change. */
4275 bgp_static
= rn
->info
;
4277 /* Label index cannot be changed. */
4278 if (bgp_static
->label_index
!= label_index
)
4280 vty_out (vty
, "%% Label index cannot be changed%s", VTY_NEWLINE
);
4284 /* Check previous routes are installed into BGP. */
4285 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4288 bgp_static
->backdoor
= backdoor
;
4292 if (bgp_static
->rmap
.name
)
4293 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4294 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4295 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4299 if (bgp_static
->rmap
.name
)
4300 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4301 bgp_static
->rmap
.name
= NULL
;
4302 bgp_static
->rmap
.map
= NULL
;
4303 bgp_static
->valid
= 0;
4305 bgp_unlock_node (rn
);
4309 /* New configuration. */
4310 bgp_static
= bgp_static_new ();
4311 bgp_static
->backdoor
= backdoor
;
4312 bgp_static
->valid
= 0;
4313 bgp_static
->igpmetric
= 0;
4314 bgp_static
->igpnexthop
.s_addr
= 0;
4315 bgp_static
->label_index
= label_index
;
4319 if (bgp_static
->rmap
.name
)
4320 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4321 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4322 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4324 rn
->info
= bgp_static
;
4327 bgp_static
->valid
= 1;
4329 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4331 if (! bgp_static
->backdoor
)
4332 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4337 /* Configure static BGP network. */
4339 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4340 afi_t afi
, safi_t safi
)
4342 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4345 struct bgp_static
*bgp_static
;
4346 struct bgp_node
*rn
;
4348 /* Convert IP prefix string to struct prefix. */
4349 ret
= str2prefix (ip_str
, &p
);
4352 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4355 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4357 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4364 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4367 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4372 bgp_static
= rn
->info
;
4374 /* Update BGP RIB. */
4375 if (! bgp_static
->backdoor
)
4376 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4378 /* Clear configuration. */
4379 bgp_static_free (bgp_static
);
4381 bgp_unlock_node (rn
);
4382 bgp_unlock_node (rn
);
4388 bgp_static_add (struct bgp
*bgp
)
4392 struct bgp_node
*rn
;
4393 struct bgp_node
*rm
;
4394 struct bgp_table
*table
;
4395 struct bgp_static
*bgp_static
;
4397 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4398 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4399 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4400 if (rn
->info
!= NULL
)
4402 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4406 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4408 bgp_static
= rn
->info
;
4409 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4414 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4419 /* Called from bgp_delete(). Delete all static routes from the BGP
4422 bgp_static_delete (struct bgp
*bgp
)
4426 struct bgp_node
*rn
;
4427 struct bgp_node
*rm
;
4428 struct bgp_table
*table
;
4429 struct bgp_static
*bgp_static
;
4431 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4432 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4433 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4434 if (rn
->info
!= NULL
)
4436 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4440 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4442 bgp_static
= rn
->info
;
4443 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4445 (struct prefix_rd
*)&rn
->p
,
4447 bgp_static_free (bgp_static
);
4449 bgp_unlock_node (rn
);
4454 bgp_static
= rn
->info
;
4455 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4456 bgp_static_free (bgp_static
);
4458 bgp_unlock_node (rn
);
4464 bgp_static_redo_import_check (struct bgp
*bgp
)
4468 struct bgp_node
*rn
;
4469 struct bgp_static
*bgp_static
;
4471 /* Use this flag to force reprocessing of the route */
4472 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4473 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4474 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4475 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4476 if (rn
->info
!= NULL
)
4478 bgp_static
= rn
->info
;
4479 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4481 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4485 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4487 struct bgp_table
*table
;
4488 struct bgp_node
*rn
;
4489 struct bgp_info
*ri
;
4491 table
= bgp
->rib
[afi
][safi
];
4492 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4494 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4496 if (ri
->peer
== bgp
->peer_self
&&
4497 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4498 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4499 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4500 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4502 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4503 bgp_unlink_nexthop(ri
);
4504 bgp_info_delete (rn
, ri
);
4505 bgp_process (bgp
, rn
, afi
, safi
);
4512 * Purge all networks and redistributed routes from routing table.
4513 * Invoked upon the instance going down.
4516 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4521 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4522 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4523 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4528 * Currently this is used to set static routes for VPN and ENCAP.
4529 * I think it can probably be factored with bgp_static_set.
4532 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4533 const char *rd_str
, const char *tag_str
,
4534 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4535 const char *ethtag
, const char *routermac
)
4537 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4540 struct prefix_rd prd
;
4541 struct bgp_node
*prn
;
4542 struct bgp_node
*rn
;
4543 struct bgp_table
*table
;
4544 struct bgp_static
*bgp_static
;
4547 struct prefix gw_ip
;
4549 if(safi
== SAFI_EVPN
)
4554 /* validate ip prefix */
4555 ret
= str2prefix (ip_str
, &p
);
4558 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4562 if ( (afi
== AFI_L2VPN
) &&
4563 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4565 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4569 ret
= str2prefix_rd (rd_str
, &prd
);
4572 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4578 ret
= str2tag (tag_str
, tag
);
4581 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4587 encode_label (0, tag
);
4589 if (safi
== SAFI_EVPN
)
4591 if( esi
&& str2esi (esi
, NULL
) == 0)
4593 vty_out (vty
, "%% Malformed ESI%s", VTY_NEWLINE
);
4596 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4598 vty_out (vty
, "%% Malformed Router MAC%s", VTY_NEWLINE
);
4603 memset (&gw_ip
, 0, sizeof (struct prefix
));
4604 ret
= str2prefix (gwip
, &gw_ip
);
4607 vty_out (vty
, "%% Malformed GatewayIp%s", VTY_NEWLINE
);
4610 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4611 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4613 vty_out (vty
, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE
);
4618 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4619 (struct prefix
*)&prd
);
4620 if (prn
->info
== NULL
)
4621 prn
->info
= bgp_table_init (afi
, safi
);
4623 bgp_unlock_node (prn
);
4626 rn
= bgp_node_get (table
, &p
);
4630 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4631 bgp_unlock_node (rn
);
4635 /* New configuration. */
4636 bgp_static
= bgp_static_new ();
4637 bgp_static
->backdoor
= 0;
4638 bgp_static
->valid
= 0;
4639 bgp_static
->igpmetric
= 0;
4640 bgp_static
->igpnexthop
.s_addr
= 0;
4641 memcpy(bgp_static
->tag
, tag
, 3);
4642 bgp_static
->prd
= prd
;
4646 if (bgp_static
->rmap
.name
)
4647 free (bgp_static
->rmap
.name
);
4648 bgp_static
->rmap
.name
= strdup (rmap_str
);
4649 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4652 if (safi
== SAFI_EVPN
)
4656 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4657 str2esi (esi
, bgp_static
->eth_s_id
);
4661 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4662 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4665 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4667 rn
->info
= bgp_static
;
4669 bgp_static
->valid
= 1;
4670 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4676 /* Configure static BGP network. */
4678 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4679 const char *rd_str
, const char *tag_str
,
4680 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4682 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4685 struct prefix_rd prd
;
4686 struct bgp_node
*prn
;
4687 struct bgp_node
*rn
;
4688 struct bgp_table
*table
;
4689 struct bgp_static
*bgp_static
;
4693 if(safi
== SAFI_EVPN
)
4698 /* Convert IP prefix string to struct prefix. */
4699 ret
= str2prefix (ip_str
, &p
);
4702 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4706 if ( (afi
== AFI_L2VPN
) &&
4707 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4709 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4712 ret
= str2prefix_rd (rd_str
, &prd
);
4715 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4719 ret
= str2tag (tag_str
, tag
);
4722 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4726 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4727 (struct prefix
*)&prd
);
4728 if (prn
->info
== NULL
)
4729 prn
->info
= bgp_table_init (afi
, safi
);
4731 bgp_unlock_node (prn
);
4734 rn
= bgp_node_lookup (table
, &p
);
4738 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
, tag
);
4740 bgp_static
= rn
->info
;
4741 bgp_static_free (bgp_static
);
4743 bgp_unlock_node (rn
);
4744 bgp_unlock_node (rn
);
4747 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4753 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4754 const char *rmap_name
)
4756 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4757 struct bgp_rmap
*rmap
;
4759 rmap
= &bgp
->table_map
[afi
][safi
];
4763 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4764 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4765 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4770 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4775 bgp_zebra_announce_table(bgp
, afi
, safi
);
4781 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4782 const char *rmap_name
)
4784 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4785 struct bgp_rmap
*rmap
;
4787 rmap
= &bgp
->table_map
[afi
][safi
];
4789 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4793 bgp_zebra_announce_table(bgp
, afi
, safi
);
4799 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4800 safi_t safi
, int *write
)
4802 if (bgp
->table_map
[afi
][safi
].name
)
4804 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4805 vty_out (vty
, " table-map %s%s",
4806 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4812 DEFUN (bgp_table_map
,
4815 "BGP table to RIB route download filter\n"
4816 "Name of the route map\n")
4819 return bgp_table_map_set (vty
,
4820 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4822 DEFUN (no_bgp_table_map
,
4823 no_bgp_table_map_cmd
,
4824 "no table-map WORD",
4826 "BGP table to RIB route download filter\n"
4827 "Name of the route map\n")
4830 return bgp_table_map_unset (vty
,
4831 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4836 "network A.B.C.D/M",
4837 "Specify a network to announce via BGP\n"
4840 int idx_ipv4_prefixlen
= 1;
4841 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4842 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4843 BGP_INVALID_LABEL_INDEX
);
4846 DEFUN (bgp_network_route_map
,
4847 bgp_network_route_map_cmd
,
4848 "network A.B.C.D/M route-map WORD",
4849 "Specify a network to announce via BGP\n"
4851 "Route-map to modify the attributes\n"
4852 "Name of the route map\n")
4854 int idx_ipv4_prefixlen
= 1;
4856 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4857 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4858 BGP_INVALID_LABEL_INDEX
);
4861 DEFUN (bgp_network_backdoor
,
4862 bgp_network_backdoor_cmd
,
4863 "network A.B.C.D/M backdoor",
4864 "Specify a network to announce via BGP\n"
4866 "Specify a BGP backdoor route\n")
4868 int idx_ipv4_prefixlen
= 1;
4869 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4870 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4873 DEFUN (bgp_network_mask
,
4874 bgp_network_mask_cmd
,
4875 "network A.B.C.D mask A.B.C.D",
4876 "Specify a network to announce via BGP\n"
4884 char prefix_str
[BUFSIZ
];
4886 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4889 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4893 return bgp_static_set (vty
, prefix_str
,
4894 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
4897 DEFUN (bgp_network_mask_route_map
,
4898 bgp_network_mask_route_map_cmd
,
4899 "network A.B.C.D mask A.B.C.D route-map WORD",
4900 "Specify a network to announce via BGP\n"
4904 "Route-map to modify the attributes\n"
4905 "Name of the route map\n")
4911 char prefix_str
[BUFSIZ
];
4913 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4916 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4920 return bgp_static_set (vty
, prefix_str
,
4921 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
4924 DEFUN (bgp_network_mask_backdoor
,
4925 bgp_network_mask_backdoor_cmd
,
4926 "network A.B.C.D mask A.B.C.D backdoor",
4927 "Specify a network to announce via BGP\n"
4931 "Specify a BGP backdoor route\n")
4936 char prefix_str
[BUFSIZ
];
4938 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4941 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4945 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4947 BGP_INVALID_LABEL_INDEX
);
4950 DEFUN (bgp_network_mask_natural
,
4951 bgp_network_mask_natural_cmd
,
4953 "Specify a network to announce via BGP\n"
4958 char prefix_str
[BUFSIZ
];
4960 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4963 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4967 return bgp_static_set (vty
, prefix_str
,
4968 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4969 BGP_INVALID_LABEL_INDEX
);
4972 DEFUN (bgp_network_mask_natural_route_map
,
4973 bgp_network_mask_natural_route_map_cmd
,
4974 "network A.B.C.D route-map WORD",
4975 "Specify a network to announce via BGP\n"
4977 "Route-map to modify the attributes\n"
4978 "Name of the route map\n")
4983 char prefix_str
[BUFSIZ
];
4985 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4988 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4992 return bgp_static_set (vty
, prefix_str
,
4993 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4994 BGP_INVALID_LABEL_INDEX
);
4997 DEFUN (bgp_network_mask_natural_backdoor
,
4998 bgp_network_mask_natural_backdoor_cmd
,
4999 "network A.B.C.D backdoor",
5000 "Specify a network to announce via BGP\n"
5002 "Specify a BGP backdoor route\n")
5006 char prefix_str
[BUFSIZ
];
5008 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5011 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5015 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5016 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5019 DEFUN (bgp_network_label_index
,
5020 bgp_network_label_index_cmd
,
5021 "network A.B.C.D/M label-index (0-4294967294)",
5022 "Specify a network to announce via BGP\n"
5023 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5024 "Label index to associate with the prefix\n"
5025 "Label index value\n")
5027 u_int32_t label_index
;
5029 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5030 return bgp_static_set (vty
, argv
[1]->arg
,
5031 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5034 DEFUN (bgp_network_label_index_route_map
,
5035 bgp_network_label_index_route_map_cmd
,
5036 "network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5037 "Specify a network to announce via BGP\n"
5039 "Label index to associate with the prefix\n"
5040 "Label index value\n"
5041 "Route-map to modify the attributes\n"
5042 "Name of the route map\n")
5044 u_int32_t label_index
;
5046 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5047 return bgp_static_set (vty
, argv
[1]->arg
,
5048 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5051 DEFUN (no_bgp_network
,
5053 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5055 "Specify a network to announce via BGP\n"
5057 "Specify a BGP backdoor route\n"
5058 "Route-map to modify the attributes\n"
5059 "Name of the route map\n")
5061 int idx_ipv4_prefixlen
= 2;
5062 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5063 bgp_node_safi (vty
));
5066 DEFUN (no_bgp_network_mask
,
5067 no_bgp_network_mask_cmd
,
5068 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5070 "Specify a network to announce via BGP\n"
5074 "Specify a BGP backdoor route\n"
5075 "Route-map to modify the attributes\n"
5076 "Name of the route map\n")
5081 char prefix_str
[BUFSIZ
];
5083 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5086 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5090 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5091 bgp_node_safi (vty
));
5094 DEFUN (no_bgp_network_mask_natural
,
5095 no_bgp_network_mask_natural_cmd
,
5096 "no network A.B.C.D [<backdoor|route-map WORD>]",
5098 "Specify a network to announce via BGP\n"
5100 "Specify a BGP backdoor route\n"
5101 "Route-map to modify the attributes\n"
5102 "Name of the route map\n")
5106 char prefix_str
[BUFSIZ
];
5108 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5111 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5115 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5116 bgp_node_safi (vty
));
5119 ALIAS (no_bgp_network
,
5120 no_bgp_network_label_index_cmd
,
5121 "no network A.B.C.D/M label-index (0-4294967294)",
5123 "Specify a network to announce via BGP\n"
5124 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5125 "Label index to associate with the prefix\n"
5126 "Label index value\n")
5128 ALIAS (no_bgp_network
,
5129 no_bgp_network_label_index_route_map_cmd
,
5130 "no network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5132 "Specify a network to announce via BGP\n"
5134 "Label index to associate with the prefix\n"
5135 "Label index value\n"
5136 "Route-map to modify the attributes\n"
5137 "Name of the route map\n")
5139 DEFUN (ipv6_bgp_network
,
5140 ipv6_bgp_network_cmd
,
5141 "network X:X::X:X/M",
5142 "Specify a network to announce via BGP\n"
5145 int idx_ipv6_prefixlen
= 1;
5146 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5148 BGP_INVALID_LABEL_INDEX
);
5151 DEFUN (ipv6_bgp_network_route_map
,
5152 ipv6_bgp_network_route_map_cmd
,
5153 "network X:X::X:X/M route-map WORD",
5154 "Specify a network to announce via BGP\n"
5156 "Route-map to modify the attributes\n"
5157 "Name of the route map\n")
5159 int idx_ipv6_prefixlen
= 1;
5161 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5162 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5163 BGP_INVALID_LABEL_INDEX
);
5166 DEFUN (ipv6_bgp_network_label_index
,
5167 ipv6_bgp_network_label_index_cmd
,
5168 "network X:X::X:X/M label-index (0-4294967294)",
5169 "Specify a network to announce via BGP\n"
5170 "IPv6 prefix <network>/<length>\n"
5171 "Label index to associate with the prefix\n"
5172 "Label index value\n")
5174 u_int32_t label_index
;
5176 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5177 return bgp_static_set (vty
, argv
[1]->arg
,
5178 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5181 DEFUN (ipv6_bgp_network_label_index_route_map
,
5182 ipv6_bgp_network_label_index_route_map_cmd
,
5183 "network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5184 "Specify a network to announce via BGP\n"
5186 "Label index to associate with the prefix\n"
5187 "Label index value\n"
5188 "Route-map to modify the attributes\n"
5189 "Name of the route map\n")
5191 u_int32_t label_index
;
5193 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5194 return bgp_static_set (vty
, argv
[1]->arg
,
5195 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5198 DEFUN (no_ipv6_bgp_network
,
5199 no_ipv6_bgp_network_cmd
,
5200 "no network X:X::X:X/M [route-map WORD]",
5202 "Specify a network to announce via BGP\n"
5204 "Route-map to modify the attributes\n"
5205 "Name of the route map\n")
5207 int idx_ipv6_prefixlen
= 2;
5208 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5211 ALIAS (no_ipv6_bgp_network
,
5212 no_ipv6_bgp_network_label_index_cmd
,
5213 "no network X:X::X:X/M label-index (0-4294967294)",
5215 "Specify a network to announce via BGP\n"
5216 "IPv6 prefix <network>/<length>\n"
5217 "Label index to associate with the prefix\n"
5218 "Label index value\n")
5220 ALIAS (no_ipv6_bgp_network
,
5221 no_ipv6_bgp_network_label_index_route_map_cmd
,
5222 "no network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5224 "Specify a network to announce via BGP\n"
5226 "Label index to associate with the prefix\n"
5227 "Label index value\n"
5228 "Route-map to modify the attributes\n"
5229 "Name of the route map\n")
5231 /* Aggreagete address:
5233 advertise-map Set condition to advertise attribute
5234 as-set Generate AS set path information
5235 attribute-map Set attributes of aggregate
5236 route-map Set parameters of aggregate
5237 summary-only Filter more specific routes from updates
5238 suppress-map Conditionally filter more specific routes from updates
5241 struct bgp_aggregate
5243 /* Summary-only flag. */
5244 u_char summary_only
;
5246 /* AS set generation. */
5249 /* Route-map for aggregated route. */
5250 struct route_map
*map
;
5252 /* Suppress-count. */
5253 unsigned long count
;
5255 /* SAFI configuration. */
5259 static struct bgp_aggregate
*
5260 bgp_aggregate_new (void)
5262 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5266 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5268 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5271 /* Update an aggregate as routes are added/removed from the BGP table */
5273 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5274 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5275 struct bgp_aggregate
*aggregate
)
5277 struct bgp_table
*table
;
5278 struct bgp_node
*top
;
5279 struct bgp_node
*rn
;
5281 struct aspath
*aspath
= NULL
;
5282 struct aspath
*asmerge
= NULL
;
5283 struct community
*community
= NULL
;
5284 struct community
*commerge
= NULL
;
5285 #if defined(AGGREGATE_NEXTHOP_CHECK)
5286 struct in_addr nexthop
;
5289 struct bgp_info
*ri
;
5290 struct bgp_info
*new;
5292 unsigned long match
= 0;
5293 u_char atomic_aggregate
= 0;
5295 /* Record adding route's nexthop and med. */
5298 #if defined(AGGREGATE_NEXTHOP_CHECK)
5299 nexthop
= rinew
->attr
->nexthop
;
5300 med
= rinew
->attr
->med
;
5304 /* ORIGIN attribute: If at least one route among routes that are
5305 aggregated has ORIGIN with the value INCOMPLETE, then the
5306 aggregated route must have the ORIGIN attribute with the value
5307 INCOMPLETE. Otherwise, if at least one route among routes that
5308 are aggregated has ORIGIN with the value EGP, then the aggregated
5309 route must have the origin attribute with the value EGP. In all
5310 other case the value of the ORIGIN attribute of the aggregated
5311 route is INTERNAL. */
5312 origin
= BGP_ORIGIN_IGP
;
5314 table
= bgp
->rib
[afi
][safi
];
5316 top
= bgp_node_get (table
, p
);
5317 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5318 if (rn
->p
.prefixlen
> p
->prefixlen
)
5322 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5324 if (BGP_INFO_HOLDDOWN (ri
))
5327 if (del
&& ri
== del
)
5330 if (! rinew
&& first
)
5332 #if defined(AGGREGATE_NEXTHOP_CHECK)
5333 nexthop
= ri
->attr
->nexthop
;
5334 med
= ri
->attr
->med
;
5339 #ifdef AGGREGATE_NEXTHOP_CHECK
5340 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5341 || ri
->attr
->med
!= med
)
5344 aspath_free (aspath
);
5346 community_free (community
);
5347 bgp_unlock_node (rn
);
5348 bgp_unlock_node (top
);
5351 #endif /* AGGREGATE_NEXTHOP_CHECK */
5353 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5354 atomic_aggregate
= 1;
5356 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5358 if (aggregate
->summary_only
)
5360 (bgp_info_extra_get (ri
))->suppress
++;
5361 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5367 if (origin
< ri
->attr
->origin
)
5368 origin
= ri
->attr
->origin
;
5370 if (aggregate
->as_set
)
5374 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5375 aspath_free (aspath
);
5379 aspath
= aspath_dup (ri
->attr
->aspath
);
5381 if (ri
->attr
->community
)
5385 commerge
= community_merge (community
,
5386 ri
->attr
->community
);
5387 community
= community_uniq_sort (commerge
);
5388 community_free (commerge
);
5391 community
= community_dup (ri
->attr
->community
);
5397 bgp_process (bgp
, rn
, afi
, safi
);
5399 bgp_unlock_node (top
);
5405 if (aggregate
->summary_only
)
5406 (bgp_info_extra_get (rinew
))->suppress
++;
5408 if (origin
< rinew
->attr
->origin
)
5409 origin
= rinew
->attr
->origin
;
5411 if (aggregate
->as_set
)
5415 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5416 aspath_free (aspath
);
5420 aspath
= aspath_dup (rinew
->attr
->aspath
);
5422 if (rinew
->attr
->community
)
5426 commerge
= community_merge (community
,
5427 rinew
->attr
->community
);
5428 community
= community_uniq_sort (commerge
);
5429 community_free (commerge
);
5432 community
= community_dup (rinew
->attr
->community
);
5437 if (aggregate
->count
> 0)
5439 rn
= bgp_node_get (table
, p
);
5440 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5441 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5443 atomic_aggregate
), rn
);
5444 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5446 bgp_info_add (rn
, new);
5447 bgp_unlock_node (rn
);
5448 bgp_process (bgp
, rn
, afi
, safi
);
5453 aspath_free (aspath
);
5455 community_free (community
);
5459 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5460 struct bgp_aggregate
*);
5463 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5464 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5466 struct bgp_node
*child
;
5467 struct bgp_node
*rn
;
5468 struct bgp_aggregate
*aggregate
;
5469 struct bgp_table
*table
;
5471 /* MPLS-VPN aggregation is not yet supported. */
5472 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5475 table
= bgp
->aggregate
[afi
][safi
];
5477 /* No aggregates configured. */
5478 if (bgp_table_top_nolock (table
) == NULL
)
5481 if (p
->prefixlen
== 0)
5484 if (BGP_INFO_HOLDDOWN (ri
))
5487 child
= bgp_node_get (table
, p
);
5489 /* Aggregate address configuration check. */
5490 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5491 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5493 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5494 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5496 bgp_unlock_node (child
);
5500 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5501 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5503 struct bgp_node
*child
;
5504 struct bgp_node
*rn
;
5505 struct bgp_aggregate
*aggregate
;
5506 struct bgp_table
*table
;
5508 /* MPLS-VPN aggregation is not yet supported. */
5509 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5512 table
= bgp
->aggregate
[afi
][safi
];
5514 /* No aggregates configured. */
5515 if (bgp_table_top_nolock (table
) == NULL
)
5518 if (p
->prefixlen
== 0)
5521 child
= bgp_node_get (table
, p
);
5523 /* Aggregate address configuration check. */
5524 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5525 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5527 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5528 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5530 bgp_unlock_node (child
);
5533 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5535 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5536 struct bgp_aggregate
*aggregate
)
5538 struct bgp_table
*table
;
5539 struct bgp_node
*top
;
5540 struct bgp_node
*rn
;
5541 struct bgp_info
*new;
5542 struct bgp_info
*ri
;
5543 unsigned long match
;
5544 u_char origin
= BGP_ORIGIN_IGP
;
5545 struct aspath
*aspath
= NULL
;
5546 struct aspath
*asmerge
= NULL
;
5547 struct community
*community
= NULL
;
5548 struct community
*commerge
= NULL
;
5549 u_char atomic_aggregate
= 0;
5551 table
= bgp
->rib
[afi
][safi
];
5554 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5556 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5559 /* If routes exists below this node, generate aggregate routes. */
5560 top
= bgp_node_get (table
, p
);
5561 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5562 if (rn
->p
.prefixlen
> p
->prefixlen
)
5566 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5568 if (BGP_INFO_HOLDDOWN (ri
))
5571 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5572 atomic_aggregate
= 1;
5574 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5576 /* summary-only aggregate route suppress aggregated
5577 route announcement. */
5578 if (aggregate
->summary_only
)
5580 (bgp_info_extra_get (ri
))->suppress
++;
5581 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5585 /* If at least one route among routes that are aggregated has
5586 * ORIGIN with the value INCOMPLETE, then the aggregated route
5587 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5588 * Otherwise, if at least one route among routes that are
5589 * aggregated has ORIGIN with the value EGP, then the aggregated
5590 * route MUST have the ORIGIN attribute with the value EGP.
5592 if (origin
< ri
->attr
->origin
)
5593 origin
= ri
->attr
->origin
;
5595 /* as-set aggregate route generate origin, as path,
5596 community aggregation. */
5597 if (aggregate
->as_set
)
5601 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5602 aspath_free (aspath
);
5606 aspath
= aspath_dup (ri
->attr
->aspath
);
5608 if (ri
->attr
->community
)
5612 commerge
= community_merge (community
,
5613 ri
->attr
->community
);
5614 community
= community_uniq_sort (commerge
);
5615 community_free (commerge
);
5618 community
= community_dup (ri
->attr
->community
);
5625 /* If this node is suppressed, process the change. */
5627 bgp_process (bgp
, rn
, afi
, safi
);
5629 bgp_unlock_node (top
);
5631 /* Add aggregate route to BGP table. */
5632 if (aggregate
->count
)
5634 rn
= bgp_node_get (table
, p
);
5635 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5636 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5638 atomic_aggregate
), rn
);
5639 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5641 bgp_info_add (rn
, new);
5642 bgp_unlock_node (rn
);
5644 /* Process change. */
5645 bgp_process (bgp
, rn
, afi
, safi
);
5650 aspath_free (aspath
);
5652 community_free (community
);
5657 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5658 safi_t safi
, struct bgp_aggregate
*aggregate
)
5660 struct bgp_table
*table
;
5661 struct bgp_node
*top
;
5662 struct bgp_node
*rn
;
5663 struct bgp_info
*ri
;
5664 unsigned long match
;
5666 table
= bgp
->rib
[afi
][safi
];
5668 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5670 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5673 /* If routes exists below this node, generate aggregate routes. */
5674 top
= bgp_node_get (table
, p
);
5675 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5676 if (rn
->p
.prefixlen
> p
->prefixlen
)
5680 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5682 if (BGP_INFO_HOLDDOWN (ri
))
5685 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5687 if (aggregate
->summary_only
&& ri
->extra
)
5689 ri
->extra
->suppress
--;
5691 if (ri
->extra
->suppress
== 0)
5693 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5701 /* If this node was suppressed, process the change. */
5703 bgp_process (bgp
, rn
, afi
, safi
);
5705 bgp_unlock_node (top
);
5707 /* Delete aggregate route from BGP table. */
5708 rn
= bgp_node_get (table
, p
);
5710 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5711 if (ri
->peer
== bgp
->peer_self
5712 && ri
->type
== ZEBRA_ROUTE_BGP
5713 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5716 /* Withdraw static BGP route from routing table. */
5719 bgp_info_delete (rn
, ri
);
5720 bgp_process (bgp
, rn
, afi
, safi
);
5723 /* Unlock bgp_node_lookup. */
5724 bgp_unlock_node (rn
);
5727 /* Aggregate route attribute. */
5728 #define AGGREGATE_SUMMARY_ONLY 1
5729 #define AGGREGATE_AS_SET 1
5732 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5733 afi_t afi
, safi_t safi
)
5735 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5738 struct bgp_node
*rn
;
5739 struct bgp_aggregate
*aggregate
;
5741 /* Convert string to prefix structure. */
5742 ret
= str2prefix (prefix_str
, &p
);
5745 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5750 /* Old configuration check. */
5751 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5754 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5759 aggregate
= rn
->info
;
5760 if (aggregate
->safi
== SAFI_UNICAST
)
5761 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5762 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5763 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5764 if (aggregate
->safi
== SAFI_MULTICAST
)
5765 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5767 /* Unlock aggregate address configuration. */
5769 bgp_aggregate_free (aggregate
);
5770 bgp_unlock_node (rn
);
5771 bgp_unlock_node (rn
);
5777 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5778 afi_t afi
, safi_t safi
,
5779 u_char summary_only
, u_char as_set
)
5781 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5784 struct bgp_node
*rn
;
5785 struct bgp_aggregate
*aggregate
;
5787 /* Convert string to prefix structure. */
5788 ret
= str2prefix (prefix_str
, &p
);
5791 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5796 /* Old configuration check. */
5797 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5801 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5802 /* try to remove the old entry */
5803 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5806 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5807 bgp_unlock_node (rn
);
5812 /* Make aggregate address structure. */
5813 aggregate
= bgp_aggregate_new ();
5814 aggregate
->summary_only
= summary_only
;
5815 aggregate
->as_set
= as_set
;
5816 aggregate
->safi
= safi
;
5817 rn
->info
= aggregate
;
5819 /* Aggregate address insert into BGP routing table. */
5820 if (safi
== SAFI_UNICAST
)
5821 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5822 if (safi
== SAFI_LABELED_UNICAST
)
5823 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5824 if (safi
== SAFI_MULTICAST
)
5825 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5830 DEFUN (aggregate_address
,
5831 aggregate_address_cmd
,
5832 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5833 "Configure BGP aggregate entries\n"
5834 "Aggregate prefix\n"
5835 "Generate AS set path information\n"
5836 "Filter more specific routes from updates\n"
5837 "Filter more specific routes from updates\n"
5838 "Generate AS set path information\n")
5841 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5842 char *prefix
= argv
[idx
]->arg
;
5843 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5845 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5847 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5850 DEFUN (aggregate_address_mask
,
5851 aggregate_address_mask_cmd
,
5852 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5853 "Configure BGP aggregate entries\n"
5854 "Aggregate address\n"
5856 "Generate AS set path information\n"
5857 "Filter more specific routes from updates\n"
5858 "Filter more specific routes from updates\n"
5859 "Generate AS set path information\n")
5862 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5863 char *prefix
= argv
[idx
]->arg
;
5864 char *mask
= argv
[idx
+1]->arg
;
5865 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5867 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5869 char prefix_str
[BUFSIZ
];
5870 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5874 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5878 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5881 DEFUN (no_aggregate_address
,
5882 no_aggregate_address_cmd
,
5883 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5885 "Configure BGP aggregate entries\n"
5886 "Aggregate prefix\n"
5887 "Generate AS set path information\n"
5888 "Filter more specific routes from updates\n"
5889 "Filter more specific routes from updates\n"
5890 "Generate AS set path information\n")
5893 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5894 char *prefix
= argv
[idx
]->arg
;
5895 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5898 DEFUN (no_aggregate_address_mask
,
5899 no_aggregate_address_mask_cmd
,
5900 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5902 "Configure BGP aggregate entries\n"
5903 "Aggregate address\n"
5905 "Generate AS set path information\n"
5906 "Filter more specific routes from updates\n"
5907 "Filter more specific routes from updates\n"
5908 "Generate AS set path information\n")
5911 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5912 char *prefix
= argv
[idx
]->arg
;
5913 char *mask
= argv
[idx
+1]->arg
;
5915 char prefix_str
[BUFSIZ
];
5916 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5920 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5924 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5927 DEFUN (ipv6_aggregate_address
,
5928 ipv6_aggregate_address_cmd
,
5929 "aggregate-address X:X::X:X/M [summary-only]",
5930 "Configure BGP aggregate entries\n"
5931 "Aggregate prefix\n"
5932 "Filter more specific routes from updates\n")
5935 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5936 char *prefix
= argv
[idx
]->arg
;
5937 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5938 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5941 DEFUN (no_ipv6_aggregate_address
,
5942 no_ipv6_aggregate_address_cmd
,
5943 "no aggregate-address X:X::X:X/M [summary-only]",
5945 "Configure BGP aggregate entries\n"
5946 "Aggregate prefix\n"
5947 "Filter more specific routes from updates\n")
5950 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5951 char *prefix
= argv
[idx
]->arg
;
5952 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5955 /* Redistribute route treatment. */
5957 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5958 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5959 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5961 struct bgp_info
*new;
5962 struct bgp_info
*bi
;
5963 struct bgp_info info
;
5964 struct bgp_node
*bn
;
5966 struct attr
*new_attr
;
5969 struct bgp_redist
*red
;
5971 /* Make default attribute. */
5972 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5974 attr
.nexthop
= *nexthop
;
5975 attr
.nh_ifindex
= ifindex
;
5979 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5980 extra
->mp_nexthop_global
= *nexthop6
;
5981 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5985 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5986 attr
.extra
->tag
= tag
;
5988 afi
= family2afi (p
->family
);
5990 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5993 struct attr attr_new
;
5994 struct attr_extra extra_new
;
5996 /* Copy attribute for modification. */
5997 attr_new
.extra
= &extra_new
;
5998 bgp_attr_dup (&attr_new
, &attr
);
6000 if (red
->redist_metric_flag
)
6001 attr_new
.med
= red
->redist_metric
;
6003 /* Apply route-map. */
6006 info
.peer
= bgp
->peer_self
;
6007 info
.attr
= &attr_new
;
6009 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6011 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6013 bgp
->peer_self
->rmap_type
= 0;
6015 if (ret
== RMAP_DENYMATCH
)
6017 /* Free uninterned attribute. */
6018 bgp_attr_flush (&attr_new
);
6020 /* Unintern original. */
6021 aspath_unintern (&attr
.aspath
);
6022 bgp_attr_extra_free (&attr
);
6023 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6028 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6029 afi
, SAFI_UNICAST
, p
, NULL
);
6031 new_attr
= bgp_attr_intern (&attr_new
);
6033 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6034 if (bi
->peer
== bgp
->peer_self
6035 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6040 /* Ensure the (source route) type is updated. */
6042 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6043 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6045 bgp_attr_unintern (&new_attr
);
6046 aspath_unintern (&attr
.aspath
);
6047 bgp_attr_extra_free (&attr
);
6048 bgp_unlock_node (bn
);
6053 /* The attribute is changed. */
6054 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6056 /* Rewrite BGP route information. */
6057 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6058 bgp_info_restore(bn
, bi
);
6060 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6061 bgp_attr_unintern (&bi
->attr
);
6062 bi
->attr
= new_attr
;
6063 bi
->uptime
= bgp_clock ();
6065 /* Process change. */
6066 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6067 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6068 bgp_unlock_node (bn
);
6069 aspath_unintern (&attr
.aspath
);
6070 bgp_attr_extra_free (&attr
);
6075 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6077 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6079 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6080 bgp_info_add (bn
, new);
6081 bgp_unlock_node (bn
);
6082 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6085 /* Unintern original. */
6086 aspath_unintern (&attr
.aspath
);
6087 bgp_attr_extra_free (&attr
);
6091 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6094 struct bgp_node
*rn
;
6095 struct bgp_info
*ri
;
6096 struct bgp_redist
*red
;
6098 afi
= family2afi (p
->family
);
6100 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6103 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6105 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6106 if (ri
->peer
== bgp
->peer_self
6107 && ri
->type
== type
)
6112 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6113 bgp_info_delete (rn
, ri
);
6114 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6116 bgp_unlock_node (rn
);
6120 /* Withdraw specified route type's route. */
6122 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6124 struct bgp_node
*rn
;
6125 struct bgp_info
*ri
;
6126 struct bgp_table
*table
;
6128 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6130 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6132 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6133 if (ri
->peer
== bgp
->peer_self
6135 && ri
->instance
== instance
)
6140 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6141 bgp_info_delete (rn
, ri
);
6142 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6147 /* Static function to display route. */
6149 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6152 u_int32_t destination
;
6155 if (p
->family
== AF_INET
)
6157 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6158 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6160 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6161 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6162 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6163 || p
->u
.prefix4
.s_addr
== 0)
6165 /* When mask is natural, mask is not displayed. */
6168 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6170 else if (p
->family
== AF_ETHERNET
)
6172 prefix2str(p
, buf
, PREFIX_STRLEN
);
6173 len
= vty_out (vty
, "%s", buf
);
6176 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6181 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
6183 vty_out (vty
, "%*s", len
, " ");
6186 enum bgp_display_type
6191 /* Print the short form route status for a bgp_info */
6193 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6194 json_object
*json_path
)
6199 /* Route status display. */
6200 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6201 json_object_boolean_true_add(json_path
, "removed");
6203 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6204 json_object_boolean_true_add(json_path
, "stale");
6206 if (binfo
->extra
&& binfo
->extra
->suppress
)
6207 json_object_boolean_true_add(json_path
, "suppressed");
6209 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6210 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6211 json_object_boolean_true_add(json_path
, "valid");
6214 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6215 json_object_boolean_true_add(json_path
, "history");
6217 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6218 json_object_boolean_true_add(json_path
, "damped");
6220 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6221 json_object_boolean_true_add(json_path
, "bestpath");
6223 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6224 json_object_boolean_true_add(json_path
, "multipath");
6226 /* Internal route. */
6227 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6228 json_object_string_add(json_path
, "pathFrom", "internal");
6230 json_object_string_add(json_path
, "pathFrom", "external");
6235 /* Route status display. */
6236 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6238 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6240 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6242 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6243 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6249 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6251 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6253 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6255 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6260 /* Internal route. */
6262 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6268 /* called from terminal list command */
6270 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6271 struct bgp_info
*binfo
, int display
, safi_t safi
,
6272 json_object
*json_paths
)
6275 json_object
*json_path
= NULL
;
6276 json_object
*json_nexthops
= NULL
;
6277 json_object
*json_nexthop_global
= NULL
;
6278 json_object
*json_nexthop_ll
= NULL
;
6281 json_path
= json_object_new_object();
6283 /* short status lead text */
6284 route_vty_short_status_out (vty
, binfo
, json_path
);
6288 /* print prefix and mask */
6290 route_vty_out_route (p
, vty
);
6292 vty_out (vty
, "%*s", 17, " ");
6295 /* Print attribute */
6300 * For ENCAP routes, nexthop address family is not
6301 * neccessarily the same as the prefix address family.
6302 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6304 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6309 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6314 vty_out (vty
, "%s", inet_ntop(af
,
6315 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6318 vty_out (vty
, "%s", inet_ntop(af
,
6319 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6330 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6334 json_nexthop_global
= json_object_new_object();
6336 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6337 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6339 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6341 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6342 json_object_boolean_true_add(json_nexthop_global
, "used");
6346 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6347 vty_out (vty
, "%-16s",
6348 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6350 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6355 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6362 json_nexthop_global
= json_object_new_object();
6363 json_object_string_add(json_nexthop_global
, "ip",
6364 inet_ntop (AF_INET6
,
6365 &attr
->extra
->mp_nexthop_global
,
6367 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6368 json_object_string_add(json_nexthop_global
, "scope", "global");
6370 /* We display both LL & GL if both have been received */
6371 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6373 json_nexthop_ll
= json_object_new_object();
6374 json_object_string_add(json_nexthop_ll
, "ip",
6375 inet_ntop (AF_INET6
,
6376 &attr
->extra
->mp_nexthop_local
,
6378 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6379 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6381 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6382 &attr
->extra
->mp_nexthop_local
) != 0) &&
6383 !attr
->extra
->mp_nexthop_prefer_global
)
6384 json_object_boolean_true_add(json_nexthop_ll
, "used");
6386 json_object_boolean_true_add(json_nexthop_global
, "used");
6389 json_object_boolean_true_add(json_nexthop_global
, "used");
6393 /* Display LL if LL/Global both in table unless prefer-global is set */
6394 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6395 !attr
->extra
->mp_nexthop_prefer_global
) ||
6396 (binfo
->peer
->conf_if
))
6398 if (binfo
->peer
->conf_if
)
6400 len
= vty_out (vty
, "%s",
6401 binfo
->peer
->conf_if
);
6402 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6405 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6407 vty_out (vty
, "%*s", len
, " ");
6411 len
= vty_out (vty
, "%s",
6412 inet_ntop (AF_INET6
,
6413 &attr
->extra
->mp_nexthop_local
,
6418 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6420 vty_out (vty
, "%*s", len
, " ");
6425 len
= vty_out (vty
, "%s",
6426 inet_ntop (AF_INET6
,
6427 &attr
->extra
->mp_nexthop_global
,
6432 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6434 vty_out (vty
, "%*s", len
, " ");
6440 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6442 json_object_int_add(json_path
, "med", attr
->med
);
6444 vty_out (vty
, "%10u", attr
->med
);
6450 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6452 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6454 vty_out (vty
, "%7u", attr
->local_pref
);
6462 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6464 json_object_int_add(json_path
, "weight", 0);
6467 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6471 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6478 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6480 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6485 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6487 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6492 json_object_string_add(json_path
, "alert", "No attributes");
6494 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6499 if (json_nexthop_global
|| json_nexthop_ll
)
6501 json_nexthops
= json_object_new_array();
6503 if (json_nexthop_global
)
6504 json_object_array_add(json_nexthops
, json_nexthop_global
);
6506 if (json_nexthop_ll
)
6507 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6509 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6512 json_object_array_add(json_paths
, json_path
);
6516 vty_out (vty
, "%s", VTY_NEWLINE
);
6518 /* prints an additional line, indented, with VNC info, if present */
6519 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6520 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6525 /* called from terminal list command */
6527 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6528 u_char use_json
, json_object
*json_ar
)
6530 json_object
*json_status
= NULL
;
6531 json_object
*json_net
= NULL
;
6533 /* Route status display. */
6536 json_status
= json_object_new_object();
6537 json_net
= json_object_new_object();
6546 /* print prefix and mask */
6548 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6550 route_vty_out_route (p
, vty
);
6552 /* Print attribute */
6557 if (p
->family
== AF_INET
&&
6558 (safi
== SAFI_MPLS_VPN
||
6559 safi
== SAFI_ENCAP
||
6560 safi
== SAFI_EVPN
||
6561 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6563 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6564 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6566 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6568 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6572 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6576 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6577 json_object_int_add(json_net
, "metric", attr
->med
);
6579 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6580 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6583 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6585 json_object_int_add(json_net
, "weight", 0);
6589 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6592 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6596 if (p
->family
== AF_INET
&&
6597 (safi
== SAFI_MPLS_VPN
||
6598 safi
== SAFI_ENCAP
||
6599 safi
== SAFI_EVPN
||
6600 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6602 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6603 vty_out (vty
, "%-16s",
6604 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6606 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6608 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6613 assert (attr
->extra
);
6615 len
= vty_out (vty
, "%s",
6616 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6620 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6622 vty_out (vty
, "%*s", len
, " ");
6624 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6625 vty_out (vty
, "%10u", attr
->med
);
6629 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6630 vty_out (vty
, "%7u", attr
->local_pref
);
6634 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6638 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6641 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6646 json_object_boolean_true_add(json_status
, "*");
6647 json_object_boolean_true_add(json_status
, ">");
6648 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6649 char buf_cut
[BUFSIZ
];
6650 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6653 vty_out (vty
, "%s", VTY_NEWLINE
);
6657 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6658 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6660 json_object
*json_out
= NULL
;
6662 u_int32_t label
= 0;
6668 json_out
= json_object_new_object();
6670 /* short status lead text */
6671 route_vty_short_status_out (vty
, binfo
, json_out
);
6673 /* print prefix and mask */
6677 route_vty_out_route (p
, vty
);
6679 vty_out (vty
, "%*s", 17, " ");
6682 /* Print attribute */
6686 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6687 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6688 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6690 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6693 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6695 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6700 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6702 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6705 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6706 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6707 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6709 assert (attr
->extra
);
6713 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6716 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6717 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6720 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6723 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6727 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6729 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6731 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6732 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6735 vty_out (vty
, "%s(%s)",
6736 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6738 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6745 label
= decode_label (binfo
->extra
->tag
);
6750 json_object_int_add(json_out
, "notag", label
);
6751 json_object_array_add(json
, json_out
);
6755 vty_out (vty
, "notag/%d", label
);
6757 vty_out (vty
, "%s", VTY_NEWLINE
);
6762 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6763 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6767 json_object
*json_path
= NULL
;
6770 json_path
= json_object_new_object();
6775 /* short status lead text */
6776 route_vty_short_status_out (vty
, binfo
, json_path
);
6778 /* print prefix and mask */
6780 route_vty_out_route (p
, vty
);
6782 vty_out (vty
, "%*s", 17, " ");
6784 /* Print attribute */
6791 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6795 vty_out (vty
, "%-16s", inet_ntop(af
,
6796 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6799 vty_out (vty
, "%s(%s)",
6801 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6803 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6815 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6816 char *str
= esi2str(id
);
6817 vty_out (vty
, "%s", str
);
6818 XFREE (MTYPE_TMP
, str
);
6819 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6821 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6823 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6825 vty_out (vty
, "/%s",
6826 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6829 if(attr
->extra
->ecommunity
)
6832 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6833 ECOMMUNITY_ENCODE_EVPN
,
6834 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6836 mac
= ecom_mac2str((char *)routermac
->val
);
6839 vty_out (vty
, "/%s",(char *)mac
);
6840 XFREE(MTYPE_TMP
, mac
);
6844 vty_out (vty
, "%s", VTY_NEWLINE
);
6847 /* dampening route */
6849 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6850 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6854 char timebuf
[BGP_UPTIME_LEN
];
6856 /* short status lead text */
6857 route_vty_short_status_out (vty
, binfo
, json
);
6859 /* print prefix and mask */
6863 route_vty_out_route (p
, vty
);
6865 vty_out (vty
, "%*s", 17, " ");
6868 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6873 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6878 json_object_int_add(json
, "peerHost", len
);
6880 vty_out (vty
, "%*s", len
, " ");
6884 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6886 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6888 /* Print attribute */
6896 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6898 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6903 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6905 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6908 vty_out (vty
, "%s", VTY_NEWLINE
);
6913 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6914 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6917 struct bgp_damp_info
*bdi
;
6918 char timebuf
[BGP_UPTIME_LEN
];
6924 bdi
= binfo
->extra
->damp_info
;
6926 /* short status lead text */
6927 route_vty_short_status_out (vty
, binfo
, json
);
6929 /* print prefix and mask */
6933 route_vty_out_route (p
, vty
);
6935 vty_out (vty
, "%*s", 17, " ");
6938 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6943 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6948 json_object_int_add(json
, "peerHost", len
);
6950 vty_out (vty
, "%*s", len
, " ");
6953 len
= vty_out (vty
, "%d", bdi
->flap
);
6963 json_object_int_add(json
, "bdiFlap", len
);
6965 vty_out (vty
, "%*s", len
, " ");
6969 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6971 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6972 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6974 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6975 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6978 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6980 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6985 vty_out (vty
, "%*s ", 8, " ");
6988 /* Print attribute */
6996 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6998 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7003 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7005 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7008 vty_out (vty
, "%s", VTY_NEWLINE
);
7012 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7013 const char *header
, json_object
*json_adv_to
)
7015 char buf1
[INET6_ADDRSTRLEN
];
7016 json_object
*json_peer
= NULL
;
7020 /* 'advertised-to' is a dictionary of peers we have advertised this
7021 * prefix too. The key is the peer's IP or swpX, the value is the
7022 * hostname if we know it and "" if not.
7024 json_peer
= json_object_new_object();
7027 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7030 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7032 json_object_object_add(json_adv_to
,
7033 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7040 vty_out (vty
, "%s", header
);
7044 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7047 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7049 vty_out (vty
, " %s(%s)", peer
->hostname
,
7050 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7055 vty_out (vty
, " %s", peer
->conf_if
);
7057 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7063 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7064 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7065 json_object
*json_paths
)
7067 char buf
[INET6_ADDRSTRLEN
];
7070 int sockunion_vty_out (struct vty
*, union sockunion
*);
7072 json_object
*json_bestpath
= NULL
;
7073 json_object
*json_cluster_list
= NULL
;
7074 json_object
*json_cluster_list_list
= NULL
;
7075 json_object
*json_ext_community
= NULL
;
7076 json_object
*json_last_update
= NULL
;
7077 json_object
*json_nexthop_global
= NULL
;
7078 json_object
*json_nexthop_ll
= NULL
;
7079 json_object
*json_nexthops
= NULL
;
7080 json_object
*json_path
= NULL
;
7081 json_object
*json_peer
= NULL
;
7082 json_object
*json_string
= NULL
;
7083 json_object
*json_adv_to
= NULL
;
7085 struct listnode
*node
, *nnode
;
7087 int addpath_capable
;
7089 unsigned int first_as
;
7093 json_path
= json_object_new_object();
7094 json_peer
= json_object_new_object();
7095 json_nexthop_global
= json_object_new_object();
7102 /* Line1 display AS-path, Aggregator */
7107 json_object_lock(attr
->aspath
->json
);
7108 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7112 if (attr
->aspath
->segments
)
7113 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7115 vty_out (vty
, " Local");
7119 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7122 json_object_boolean_true_add(json_path
, "removed");
7124 vty_out (vty
, ", (removed)");
7127 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7130 json_object_boolean_true_add(json_path
, "stale");
7132 vty_out (vty
, ", (stale)");
7135 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7139 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
7140 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
7144 vty_out (vty
, ", (aggregated by %u %s)",
7145 attr
->extra
->aggregator_as
,
7146 inet_ntoa (attr
->extra
->aggregator_addr
));
7150 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7153 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7155 vty_out (vty
, ", (Received from a RR-client)");
7158 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7161 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7163 vty_out (vty
, ", (Received from a RS-client)");
7166 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7169 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7171 vty_out (vty
, ", (history entry)");
7173 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7176 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7178 vty_out (vty
, ", (suppressed due to dampening)");
7182 vty_out (vty
, "%s", VTY_NEWLINE
);
7184 /* Line2 display Next-hop, Neighbor, Router-id */
7185 /* Display the nexthop */
7186 if (p
->family
== AF_INET
&&
7187 (safi
== SAFI_MPLS_VPN
||
7188 safi
== SAFI_ENCAP
||
7189 safi
== SAFI_EVPN
||
7190 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7192 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7195 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7197 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7202 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7204 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7208 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7212 assert (attr
->extra
);
7215 json_object_string_add(json_nexthop_global
, "ip",
7216 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7217 buf
, INET6_ADDRSTRLEN
));
7218 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7219 json_object_string_add(json_nexthop_global
, "scope", "global");
7223 vty_out (vty
, " %s",
7224 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7225 buf
, INET6_ADDRSTRLEN
));
7229 /* Display the IGP cost or 'inaccessible' */
7230 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7233 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7235 vty_out (vty
, " (inaccessible)");
7239 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7242 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7244 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7247 /* IGP cost is 0, display this only for json */
7251 json_object_int_add(json_nexthop_global
, "metric", 0);
7255 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7258 /* Display peer "from" output */
7259 /* This path was originated locally */
7260 if (binfo
->peer
== bgp
->peer_self
)
7263 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7266 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7268 vty_out (vty
, " from 0.0.0.0 ");
7273 json_object_string_add(json_peer
, "peerId", "::");
7275 vty_out (vty
, " from :: ");
7279 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7281 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7284 /* We RXed this path from one of our peers */
7290 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7291 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7293 if (binfo
->peer
->hostname
)
7294 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7296 if (binfo
->peer
->domainname
)
7297 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7299 if (binfo
->peer
->conf_if
)
7300 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7304 if (binfo
->peer
->conf_if
)
7306 if (binfo
->peer
->hostname
&&
7307 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7308 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7309 binfo
->peer
->conf_if
);
7311 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7315 if (binfo
->peer
->hostname
&&
7316 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7317 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7320 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7323 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7324 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7326 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7331 vty_out (vty
, "%s", VTY_NEWLINE
);
7333 /* display the link-local nexthop */
7334 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7338 json_nexthop_ll
= json_object_new_object();
7339 json_object_string_add(json_nexthop_ll
, "ip",
7340 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7341 buf
, INET6_ADDRSTRLEN
));
7342 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7343 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7345 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7347 if (!attr
->extra
->mp_nexthop_prefer_global
)
7348 json_object_boolean_true_add(json_nexthop_ll
, "used");
7350 json_object_boolean_true_add(json_nexthop_global
, "used");
7354 vty_out (vty
, " (%s) %s%s",
7355 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7356 buf
, INET6_ADDRSTRLEN
),
7357 attr
->extra
->mp_nexthop_prefer_global
?
7358 "(prefer-global)" : "(used)",
7362 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7366 json_object_boolean_true_add(json_nexthop_global
, "used");
7369 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7371 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7373 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7375 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7378 json_object_int_add(json_path
, "med", attr
->med
);
7380 vty_out (vty
, ", metric %u", attr
->med
);
7383 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7386 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7388 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7393 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7395 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7398 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7401 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7403 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7406 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7409 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7411 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7414 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7417 json_object_boolean_false_add(json_path
, "valid");
7419 vty_out (vty
, ", invalid");
7421 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7424 json_object_boolean_true_add(json_path
, "valid");
7426 vty_out (vty
, ", valid");
7429 if (binfo
->peer
!= bgp
->peer_self
)
7431 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7433 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7436 json_object_string_add(json_peer
, "type", "confed-internal");
7438 vty_out (vty
, ", confed-internal");
7443 json_object_string_add(json_peer
, "type", "internal");
7445 vty_out (vty
, ", internal");
7450 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7453 json_object_string_add(json_peer
, "type", "confed-external");
7455 vty_out (vty
, ", confed-external");
7460 json_object_string_add(json_peer
, "type", "external");
7462 vty_out (vty
, ", external");
7466 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7470 json_object_boolean_true_add(json_path
, "aggregated");
7471 json_object_boolean_true_add(json_path
, "local");
7475 vty_out (vty
, ", aggregated, local");
7478 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7481 json_object_boolean_true_add(json_path
, "sourced");
7483 vty_out (vty
, ", sourced");
7489 json_object_boolean_true_add(json_path
, "sourced");
7490 json_object_boolean_true_add(json_path
, "local");
7494 vty_out (vty
, ", sourced, local");
7498 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7501 json_object_boolean_true_add(json_path
, "atomicAggregate");
7503 vty_out (vty
, ", atomic-aggregate");
7506 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7507 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7508 bgp_info_mpath_count (binfo
)))
7511 json_object_boolean_true_add(json_path
, "multipath");
7513 vty_out (vty
, ", multipath");
7516 // Mark the bestpath(s)
7517 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7519 first_as
= aspath_get_first_as(attr
->aspath
);
7524 json_bestpath
= json_object_new_object();
7525 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7530 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7532 vty_out (vty
, ", bestpath-from-AS Local");
7536 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7541 json_bestpath
= json_object_new_object();
7542 json_object_boolean_true_add(json_bestpath
, "overall");
7545 vty_out (vty
, ", best");
7549 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7552 vty_out (vty
, "%s", VTY_NEWLINE
);
7554 /* Line 4 display Community */
7555 if (attr
->community
)
7559 json_object_lock(attr
->community
->json
);
7560 json_object_object_add(json_path
, "community", attr
->community
->json
);
7564 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7569 /* Line 5 display Extended-community */
7570 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7574 json_ext_community
= json_object_new_object();
7575 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7576 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7580 vty_out (vty
, " Extended Community: %s%s",
7581 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7585 /* Line 6 display Large community */
7586 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7587 vty_out (vty
, " Large Community: %s%s",
7588 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7590 /* Line 7 display Originator, Cluster-id */
7591 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7592 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7594 assert (attr
->extra
);
7595 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7598 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7600 vty_out (vty
, " Originator: %s",
7601 inet_ntoa (attr
->extra
->originator_id
));
7604 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7610 json_cluster_list
= json_object_new_object();
7611 json_cluster_list_list
= json_object_new_array();
7613 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7615 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7616 json_object_array_add(json_cluster_list_list
, json_string
);
7619 /* struct cluster_list does not have "str" variable like
7620 * aspath and community do. Add this someday if someone
7622 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7624 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7625 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7629 vty_out (vty
, ", Cluster list: ");
7631 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7633 vty_out (vty
, "%s ",
7634 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7640 vty_out (vty
, "%s", VTY_NEWLINE
);
7643 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7644 bgp_damp_info_vty (vty
, binfo
, json_path
);
7647 if (bgp_labeled_safi(safi
) && binfo
->extra
)
7649 uint32_t label
= label_pton(binfo
->extra
->tag
);
7651 json_object_int_add(json_path
, "remoteLabel", label
);
7653 vty_out(vty
, " Remote label: %d%s", label
, VTY_NEWLINE
);
7657 if (attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7660 json_object_int_add(json_path
, "labelIndex", attr
->extra
->label_index
);
7662 vty_out(vty
, " Label Index: %d%s", attr
->extra
->label_index
, VTY_NEWLINE
);
7665 /* Line 8 display Addpath IDs */
7666 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7670 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7671 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7675 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7676 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7681 /* If we used addpath to TX a non-bestpath we need to display
7682 * "Advertised to" on a path-by-path basis */
7683 if (bgp
->addpath_tx_used
[afi
][safi
])
7687 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7689 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7690 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7692 if ((addpath_capable
&& has_adj
) ||
7693 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7695 if (json_path
&& !json_adv_to
)
7696 json_adv_to
= json_object_new_object();
7698 route_vty_out_advertised_to(vty
, peer
, &first
,
7708 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7715 vty_out (vty
, "%s", VTY_NEWLINE
);
7720 /* Line 9 display Uptime */
7721 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7724 json_last_update
= json_object_new_object();
7725 json_object_int_add(json_last_update
, "epoch", tbuf
);
7726 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7727 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7730 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7733 /* We've constructed the json object for this path, add it to the json
7738 if (json_nexthop_global
|| json_nexthop_ll
)
7740 json_nexthops
= json_object_new_array();
7742 if (json_nexthop_global
)
7743 json_object_array_add(json_nexthops
, json_nexthop_global
);
7745 if (json_nexthop_ll
)
7746 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7748 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7751 json_object_object_add(json_path
, "peer", json_peer
);
7752 json_object_array_add(json_paths
, json_path
);
7755 vty_out (vty
, "%s", VTY_NEWLINE
);
7758 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7759 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7760 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7763 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7764 const char *prefix_list_str
, afi_t afi
,
7765 safi_t safi
, enum bgp_show_type type
);
7767 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7768 const char *filter
, afi_t afi
,
7769 safi_t safi
, enum bgp_show_type type
);
7771 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7772 const char *rmap_str
, afi_t afi
,
7773 safi_t safi
, enum bgp_show_type type
);
7775 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7776 const char *com
, int exact
,
7777 afi_t afi
, safi_t safi
);
7779 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7780 const char *prefix
, afi_t afi
,
7781 safi_t safi
, enum bgp_show_type type
);
7783 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7784 safi_t safi
, enum bgp_show_type type
);
7786 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7787 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7790 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7791 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7793 struct bgp_info
*ri
;
7794 struct bgp_node
*rn
;
7797 unsigned long output_count
;
7798 unsigned long total_count
;
7802 json_object
*json_paths
= NULL
;
7807 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7808 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7809 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7810 table
->version
, inet_ntoa (bgp
->router_id
));
7811 json_paths
= json_object_new_object();
7814 /* This is first entry point, so reset total line. */
7818 /* Start processing of routes. */
7819 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7820 if (rn
->info
!= NULL
)
7823 if (!first
&& use_json
)
7828 json_paths
= json_object_new_array();
7832 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7835 if (type
== bgp_show_type_flap_statistics
7836 || type
== bgp_show_type_flap_neighbor
7837 || type
== bgp_show_type_dampend_paths
7838 || type
== bgp_show_type_damp_neighbor
)
7840 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7843 if (type
== bgp_show_type_regexp
)
7845 regex_t
*regex
= output_arg
;
7847 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7850 if (type
== bgp_show_type_prefix_list
)
7852 struct prefix_list
*plist
= output_arg
;
7854 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7857 if (type
== bgp_show_type_filter_list
)
7859 struct as_list
*as_list
= output_arg
;
7861 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7864 if (type
== bgp_show_type_route_map
)
7866 struct route_map
*rmap
= output_arg
;
7867 struct bgp_info binfo
;
7868 struct attr dummy_attr
;
7869 struct attr_extra dummy_extra
;
7872 dummy_attr
.extra
= &dummy_extra
;
7873 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7875 binfo
.peer
= ri
->peer
;
7876 binfo
.attr
= &dummy_attr
;
7878 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7879 if (ret
== RMAP_DENYMATCH
)
7882 if (type
== bgp_show_type_neighbor
7883 || type
== bgp_show_type_flap_neighbor
7884 || type
== bgp_show_type_damp_neighbor
)
7886 union sockunion
*su
= output_arg
;
7888 if (ri
->peer
== NULL
||
7889 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7892 if (type
== bgp_show_type_cidr_only
)
7894 u_int32_t destination
;
7896 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7897 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7899 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7901 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7904 if (type
== bgp_show_type_prefix_longer
)
7906 struct prefix
*p
= output_arg
;
7908 if (! prefix_match (p
, &rn
->p
))
7911 if (type
== bgp_show_type_community_all
)
7913 if (! ri
->attr
->community
)
7916 if (type
== bgp_show_type_community
)
7918 struct community
*com
= output_arg
;
7920 if (! ri
->attr
->community
||
7921 ! community_match (ri
->attr
->community
, com
))
7924 if (type
== bgp_show_type_community_exact
)
7926 struct community
*com
= output_arg
;
7928 if (! ri
->attr
->community
||
7929 ! community_cmp (ri
->attr
->community
, com
))
7932 if (type
== bgp_show_type_community_list
)
7934 struct community_list
*list
= output_arg
;
7936 if (! community_list_match (ri
->attr
->community
, list
))
7939 if (type
== bgp_show_type_community_list_exact
)
7941 struct community_list
*list
= output_arg
;
7943 if (! community_list_exact_match (ri
->attr
->community
, list
))
7946 if (type
== bgp_show_type_lcommunity
)
7948 struct lcommunity
*lcom
= output_arg
;
7950 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7951 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7954 if (type
== bgp_show_type_lcommunity_list
)
7956 struct community_list
*list
= output_arg
;
7958 if (! ri
->attr
->extra
||
7959 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7962 if (type
== bgp_show_type_lcommunity_all
)
7964 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7967 if (type
== bgp_show_type_dampend_paths
7968 || type
== bgp_show_type_damp_neighbor
)
7970 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7971 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7975 if (!use_json
&& header
)
7977 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7978 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7979 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7980 if (type
== bgp_show_type_dampend_paths
7981 || type
== bgp_show_type_damp_neighbor
)
7982 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7983 else if (type
== bgp_show_type_flap_statistics
7984 || type
== bgp_show_type_flap_neighbor
)
7985 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7987 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7991 if (type
== bgp_show_type_dampend_paths
7992 || type
== bgp_show_type_damp_neighbor
)
7993 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7994 else if (type
== bgp_show_type_flap_statistics
7995 || type
== bgp_show_type_flap_neighbor
)
7996 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7998 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8008 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8009 vty_out (vty
, "\"%s\": ", buf2
);
8010 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8011 json_object_free (json_paths
);
8020 json_object_free (json_paths
);
8021 vty_out (vty
, " } }%s", VTY_NEWLINE
);
8025 /* No route is displayed */
8026 if (output_count
== 0)
8028 if (type
== bgp_show_type_normal
)
8029 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
8032 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
8033 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
8040 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8041 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8043 struct bgp_table
*table
;
8047 bgp
= bgp_get_default ();
8053 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8056 /* use MPLS and ENCAP specific shows until they are merged */
8057 if (safi
== SAFI_MPLS_VPN
)
8059 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8062 if (safi
== SAFI_ENCAP
)
8064 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
8069 table
= bgp
->rib
[afi
][safi
];
8071 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8076 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8079 struct listnode
*node
, *nnode
;
8081 struct bgp_table
*table
;
8085 vty_out (vty
, "{%s", VTY_NEWLINE
);
8087 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8092 vty_out (vty
, ",%s", VTY_NEWLINE
);
8096 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8097 ? "Default" : bgp
->name
);
8101 vty_out (vty
, "%sInstance %s:%s",
8103 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8104 ? "Default" : bgp
->name
,
8107 table
= bgp
->rib
[afi
][safi
];
8108 bgp_show_table (vty
, bgp
, table
,
8109 bgp_show_type_normal
, NULL
, use_json
);
8114 vty_out (vty
, "}%s", VTY_NEWLINE
);
8117 /* Header of detailed BGP route information */
8119 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8120 struct bgp_node
*rn
,
8121 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8124 struct bgp_info
*ri
;
8127 struct listnode
*node
, *nnode
;
8128 char buf1
[INET6_ADDRSTRLEN
];
8129 char buf2
[INET6_ADDRSTRLEN
];
8134 int no_advertise
= 0;
8137 json_object
*json_adv_to
= NULL
;
8143 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8144 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8148 if (p
->family
== AF_ETHERNET
)
8149 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8151 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8152 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
8153 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8154 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8155 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8157 p
->prefixlen
, VTY_NEWLINE
);
8159 if (bgp_labeled_safi(safi
))
8161 vty_out(vty
, "Local label: ");
8162 if (!bgp_is_valid_label(rn
->local_label
))
8163 vty_out(vty
, "not allocated%s", VTY_NEWLINE
);
8166 uint32_t label
= label_pton(rn
->local_label
);
8167 vty_out(vty
, "%d%s", label
, VTY_NEWLINE
);
8172 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8175 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8178 if (ri
->extra
&& ri
->extra
->suppress
)
8180 if (ri
->attr
->community
!= NULL
)
8182 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8184 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8186 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8194 vty_out (vty
, "Paths: (%d available", count
);
8197 vty_out (vty
, ", best #%d", best
);
8198 if (safi
== SAFI_UNICAST
)
8199 vty_out (vty
, ", table %s",
8200 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8201 ? "Default-IP-Routing-Table" : bgp
->name
);
8204 vty_out (vty
, ", no best path");
8207 vty_out (vty
, ", not advertised to any peer");
8209 vty_out (vty
, ", not advertised to EBGP peer");
8211 vty_out (vty
, ", not advertised outside local AS");
8214 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8215 vty_out (vty
, ")%s", VTY_NEWLINE
);
8218 /* If we are not using addpath then we can display Advertised to and that will
8219 * show what peers we advertised the bestpath to. If we are using addpath
8220 * though then we must display Advertised to on a path-by-path basis. */
8221 if (!bgp
->addpath_tx_used
[afi
][safi
])
8223 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8225 if (bgp_adj_out_lookup (peer
, rn
, 0))
8227 if (json
&& !json_adv_to
)
8228 json_adv_to
= json_object_new_object();
8230 route_vty_out_advertised_to(vty
, peer
, &first
,
8231 " Advertised to non peer-group peers:\n ",
8240 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8246 vty_out (vty
, " Not advertised to any peer");
8247 vty_out (vty
, "%s", VTY_NEWLINE
);
8252 /* Display specified route of BGP table. */
8254 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8255 struct bgp_table
*rib
, const char *ip_str
,
8256 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8257 int prefix_check
, enum bgp_path_type pathtype
,
8263 struct prefix match
;
8264 struct bgp_node
*rn
;
8265 struct bgp_node
*rm
;
8266 struct bgp_info
*ri
;
8267 struct bgp_table
*table
;
8268 json_object
*json
= NULL
;
8269 json_object
*json_paths
= NULL
;
8271 /* Check IP address argument. */
8272 ret
= str2prefix (ip_str
, &match
);
8275 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
8279 match
.family
= afi2family (afi
);
8283 json
= json_object_new_object();
8284 json_paths
= json_object_new_array();
8287 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8289 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8291 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8294 if ((table
= rn
->info
) != NULL
)
8298 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8300 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8302 bgp_unlock_node (rm
);
8306 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8310 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8311 AFI_IP
, safi
, json
);
8316 if (pathtype
== BGP_PATH_ALL
||
8317 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8318 (pathtype
== BGP_PATH_MULTIPATH
&&
8319 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8320 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8323 bgp_unlock_node (rm
);
8332 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8334 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8336 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8340 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8345 if (pathtype
== BGP_PATH_ALL
||
8346 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8347 (pathtype
== BGP_PATH_MULTIPATH
&&
8348 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8349 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8353 bgp_unlock_node (rn
);
8360 json_object_object_add(json
, "paths", json_paths
);
8362 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8363 json_object_free(json
);
8369 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8377 /* Display specified route of Main RIB */
8379 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8380 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8381 int prefix_check
, enum bgp_path_type pathtype
,
8385 bgp
= bgp_get_default ();
8387 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8388 afi
, safi
, prd
, prefix_check
, pathtype
,
8393 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8394 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8396 struct lcommunity
*lcom
;
8402 b
= buffer_new (1024);
8403 for (i
= 0; i
< argc
; i
++)
8406 buffer_putc (b
, ' ');
8409 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8412 buffer_putstr (b
, argv
[i
]->arg
);
8416 buffer_putc (b
, '\0');
8418 str
= buffer_getstr (b
);
8421 lcom
= lcommunity_str2com (str
);
8422 XFREE (MTYPE_TMP
, str
);
8425 vty_out (vty
, "%% Large-community malformed%s", VTY_NEWLINE
);
8429 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8433 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8434 afi_t afi
, safi_t safi
, u_char uj
)
8436 struct community_list
*list
;
8438 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8441 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8446 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8449 DEFUN (show_ip_bgp_large_community_list
,
8450 show_ip_bgp_large_community_list_cmd
,
8451 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
8455 BGP_INSTANCE_HELP_STR
8458 "Address Family modifier\n"
8459 "Address Family modifier\n"
8460 "Address Family modifier\n"
8461 "Address Family modifier\n"
8462 "Address Family modifier\n"
8463 "Display routes matching the large-community-list\n"
8464 "large-community-list number\n"
8465 "large-community-list name\n"
8469 afi_t afi
= AFI_IP6
;
8470 safi_t safi
= SAFI_UNICAST
;
8473 if (argv_find (argv
, argc
, "ip", &idx
))
8475 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8476 vrf
= argv
[++idx
]->arg
;
8477 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8479 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8480 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8481 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8484 int uj
= use_json (argc
, argv
);
8486 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8489 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8493 argv_find (argv
, argc
, "large-community-list", &idx
);
8494 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8496 DEFUN (show_ip_bgp_large_community
,
8497 show_ip_bgp_large_community_cmd
,
8498 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community [AA:BB:CC] [json]",
8502 BGP_INSTANCE_HELP_STR
8505 "Address Family modifier\n"
8506 "Address Family modifier\n"
8507 "Address Family modifier\n"
8508 "Address Family modifier\n"
8509 "Address Family modifier\n"
8510 "Display routes matching the large-communities\n"
8511 "List of large-community numbers\n"
8515 afi_t afi
= AFI_IP6
;
8516 safi_t safi
= SAFI_UNICAST
;
8519 if (argv_find (argv
, argc
, "ip", &idx
))
8521 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8522 vrf
= argv
[++idx
]->arg
;
8523 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8525 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8526 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8527 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8530 int uj
= use_json (argc
, argv
);
8532 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8535 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8539 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8540 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8542 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8545 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8547 /* BGP route print out function. */
8550 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8553 |dampening <flap-statistics|dampened-paths|parameters>\
8558 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8559 |community-list <(1-500)|WORD> [exact-match]\
8560 |A.B.C.D/M longer-prefixes\
8561 |X:X::X:X/M longer-prefixes>\
8566 BGP_INSTANCE_HELP_STR
8569 "Display only routes with non-natural netmasks\n"
8570 "Display detailed information about dampening\n"
8571 "Display flap statistics of routes\n"
8572 "Display paths suppressed due to dampening\n"
8573 "Display detail of configured dampening parameters\n"
8574 "Display routes matching the route-map\n"
8575 "A route-map to match on\n"
8576 "Display routes conforming to the prefix-list\n"
8577 "Prefix-list name\n"
8578 "Display routes conforming to the filter-list\n"
8579 "Regular expression access list name\n"
8580 "BGP RIB advertisement statistics\n"
8581 "Display routes matching the communities\n"
8583 "Do not send outside local AS (well-known community)\n"
8584 "Do not advertise to any peer (well-known community)\n"
8585 "Do not export to next AS (well-known community)\n"
8586 "Exact match of the communities\n"
8587 "Display routes matching the community-list\n"
8588 "community-list number\n"
8589 "community-list name\n"
8590 "Exact match of the communities\n"
8592 "Display route and more specific routes\n"
8594 "Display route and more specific routes\n"
8597 afi_t afi
= AFI_IP6
;
8598 safi_t safi
= SAFI_UNICAST
;
8599 int exact_match
= 0;
8600 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8601 struct bgp
*bgp
= NULL
;
8604 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8608 int uj
= use_json (argc
, argv
);
8611 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8612 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8614 if (argv_find(argv
, argc
, "dampening", &idx
))
8616 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8617 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8618 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8619 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8620 else if (argv_find (argv
, argc
, "parameters", &idx
))
8621 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8624 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8625 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8627 if (argv_find(argv
, argc
, "filter-list", &idx
))
8628 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8630 if (argv_find(argv
, argc
, "statistics", &idx
))
8631 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8633 if (argv_find(argv
, argc
, "route-map", &idx
))
8634 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8636 if (argv_find(argv
, argc
, "community", &idx
))
8638 /* show a specific community */
8639 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8640 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8641 argv_find (argv
, argc
, "no-export", &idx
))
8643 if (argv_find (argv
, argc
, "exact_match", &idx
))
8645 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8647 /* show all communities */
8649 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8652 if (argv_find(argv
, argc
, "community-list", &idx
))
8654 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8655 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8657 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8660 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8661 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8663 if (safi
== SAFI_MPLS_VPN
)
8664 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8665 else if (safi
== SAFI_ENCAP
)
8666 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8668 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8671 DEFUN (show_ip_bgp_route
,
8672 show_ip_bgp_route_cmd
,
8673 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8674 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8678 BGP_INSTANCE_HELP_STR
8681 "Network in the BGP routing table to display\n"
8683 "Network in the BGP routing table to display\n"
8685 "Display only the bestpath\n"
8686 "Display only multipaths\n"
8689 int prefix_check
= 0;
8691 afi_t afi
= AFI_IP6
;
8692 safi_t safi
= SAFI_UNICAST
;
8693 char *prefix
= NULL
;
8694 struct bgp
*bgp
= NULL
;
8695 enum bgp_path_type path_type
;
8696 u_char uj
= use_json(argc
, argv
);
8700 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8706 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8710 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8711 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8713 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8716 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8718 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8721 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8723 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8727 prefix
= argv
[idx
]->arg
;
8729 /* [<bestpath|multipath>] */
8730 if (argv_find (argv
, argc
, "bestpath", &idx
))
8731 path_type
= BGP_PATH_BESTPATH
;
8732 else if (argv_find (argv
, argc
, "multipath", &idx
))
8733 path_type
= BGP_PATH_MULTIPATH
;
8735 path_type
= BGP_PATH_ALL
;
8737 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8740 DEFUN (show_ip_bgp_regexp
,
8741 show_ip_bgp_regexp_cmd
,
8742 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8746 BGP_INSTANCE_HELP_STR
8749 "Display routes matching the AS path regular expression\n"
8750 "A regular-expression to match the BGP AS paths\n")
8752 afi_t afi
= AFI_IP6
;
8753 safi_t safi
= SAFI_UNICAST
;
8754 struct bgp
*bgp
= NULL
;
8757 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8761 // get index of regex
8762 argv_find (argv
, argc
, "regexp", &idx
);
8765 char *regstr
= argv_concat (argv
, argc
, idx
);
8766 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8767 XFREE (MTYPE_TMP
, regstr
);
8771 DEFUN (show_ip_bgp_instance_all
,
8772 show_ip_bgp_instance_all_cmd
,
8773 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8777 BGP_INSTANCE_ALL_HELP_STR
8783 safi_t safi
= SAFI_UNICAST
;
8784 struct bgp
*bgp
= NULL
;
8787 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8791 int uj
= use_json (argc
, argv
);
8794 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8799 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8800 safi_t safi
, enum bgp_show_type type
)
8805 regex
= bgp_regcomp (regstr
);
8808 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8812 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8813 bgp_regex_free (regex
);
8818 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8819 const char *prefix_list_str
, afi_t afi
,
8820 safi_t safi
, enum bgp_show_type type
)
8822 struct prefix_list
*plist
;
8824 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8827 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8828 prefix_list_str
, VTY_NEWLINE
);
8832 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8836 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8837 const char *filter
, afi_t afi
,
8838 safi_t safi
, enum bgp_show_type type
)
8840 struct as_list
*as_list
;
8842 as_list
= as_list_lookup (filter
);
8843 if (as_list
== NULL
)
8845 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8849 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8853 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8854 const char *rmap_str
, afi_t afi
,
8855 safi_t safi
, enum bgp_show_type type
)
8857 struct route_map
*rmap
;
8859 rmap
= route_map_lookup_by_name (rmap_str
);
8862 vty_out (vty
, "%% %s is not a valid route-map name%s",
8863 rmap_str
, VTY_NEWLINE
);
8867 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8871 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8872 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8874 struct community
*com
;
8880 b
= buffer_new (1024);
8881 for (i
= 0; i
< argc
; i
++)
8884 buffer_putc (b
, ' ');
8887 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8892 buffer_putstr (b
, argv
[i
]->arg
);
8894 buffer_putc (b
, '\0');
8896 str
= buffer_getstr (b
);
8899 com
= community_str2com (str
);
8900 XFREE (MTYPE_TMP
, str
);
8903 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8907 return bgp_show (vty
, bgp
, afi
, safi
,
8908 (exact
? bgp_show_type_community_exact
:
8909 bgp_show_type_community
), com
, 0);
8913 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8914 const char *com
, int exact
,
8915 afi_t afi
, safi_t safi
)
8917 struct community_list
*list
;
8919 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8922 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8927 return bgp_show (vty
, bgp
, afi
, safi
,
8928 (exact
? bgp_show_type_community_list_exact
:
8929 bgp_show_type_community_list
), list
, 0);
8933 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8934 const char *prefix
, afi_t afi
,
8935 safi_t safi
, enum bgp_show_type type
)
8942 ret
= str2prefix (prefix
, p
);
8945 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8949 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8954 static struct peer
*
8955 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8956 const char *ip_str
, u_char use_json
)
8962 /* Get peer sockunion. */
8963 ret
= str2sockunion (ip_str
, &su
);
8966 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8969 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8975 json_object
*json_no
= NULL
;
8976 json_no
= json_object_new_object();
8977 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8978 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8979 json_object_free(json_no
);
8982 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8989 /* Peer structure lookup. */
8990 peer
= peer_lookup (bgp
, &su
);
8995 json_object
*json_no
= NULL
;
8996 json_no
= json_object_new_object();
8997 json_object_string_add(json_no
, "warning","No such neighbor");
8998 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8999 json_object_free(json_no
);
9002 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9011 BGP_STATS_MAXBITLEN
= 0,
9015 BGP_STATS_UNAGGREGATEABLE
,
9016 BGP_STATS_MAX_AGGREGATEABLE
,
9017 BGP_STATS_AGGREGATES
,
9019 BGP_STATS_ASPATH_COUNT
,
9020 BGP_STATS_ASPATH_MAXHOPS
,
9021 BGP_STATS_ASPATH_TOTHOPS
,
9022 BGP_STATS_ASPATH_MAXSIZE
,
9023 BGP_STATS_ASPATH_TOTSIZE
,
9024 BGP_STATS_ASN_HIGHEST
,
9028 static const char *table_stats_strs
[] =
9030 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9031 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9032 [BGP_STATS_RIB
] = "Total Advertisements",
9033 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9034 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9035 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9036 [BGP_STATS_SPACE
] = "Address space advertised",
9037 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9038 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9039 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9040 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9041 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9042 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9043 [BGP_STATS_MAX
] = NULL
,
9046 struct bgp_table_stats
9048 struct bgp_table
*table
;
9049 unsigned long long counts
[BGP_STATS_MAX
];
9053 #define TALLY_SIGFIG 100000
9054 static unsigned long
9055 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9057 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9058 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9059 unsigned long ret
= newtot
/ count
;
9061 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9069 bgp_table_stats_walker (struct thread
*t
)
9071 struct bgp_node
*rn
;
9072 struct bgp_node
*top
;
9073 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9074 unsigned int space
= 0;
9076 if (!(top
= bgp_table_top (ts
->table
)))
9079 switch (top
->p
.family
)
9082 space
= IPV4_MAX_BITLEN
;
9085 space
= IPV6_MAX_BITLEN
;
9089 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9091 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9093 struct bgp_info
*ri
;
9094 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9095 unsigned int rinum
= 0;
9103 ts
->counts
[BGP_STATS_PREFIXES
]++;
9104 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9107 ts
->counts
[BGP_STATS_AVGPLEN
]
9108 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9109 ts
->counts
[BGP_STATS_AVGPLEN
],
9113 /* check if the prefix is included by any other announcements */
9114 while (prn
&& !prn
->info
)
9115 prn
= bgp_node_parent_nolock (prn
);
9117 if (prn
== NULL
|| prn
== top
)
9119 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9120 /* announced address space */
9122 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9125 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9127 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9130 ts
->counts
[BGP_STATS_RIB
]++;
9133 (CHECK_FLAG (ri
->attr
->flag
,
9134 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9135 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9138 if (ri
->attr
&& ri
->attr
->aspath
)
9140 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9141 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9142 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9144 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9146 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9147 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9149 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9150 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9152 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9153 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9155 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9156 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9157 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9159 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9160 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9161 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9164 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9165 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9173 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9175 struct bgp_table_stats ts
;
9178 if (!bgp
->rib
[afi
][safi
])
9180 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
9181 afi
, safi
, VTY_NEWLINE
);
9185 memset (&ts
, 0, sizeof (ts
));
9186 ts
.table
= bgp
->rib
[afi
][safi
];
9187 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9189 vty_out (vty
, "BGP %s RIB statistics%s%s",
9190 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
9192 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9194 if (!table_stats_strs
[i
])
9200 case BGP_STATS_ASPATH_AVGHOPS
:
9201 case BGP_STATS_ASPATH_AVGSIZE
:
9202 case BGP_STATS_AVGPLEN
:
9203 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9204 vty_out (vty
, "%12.2f",
9205 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9208 case BGP_STATS_ASPATH_TOTHOPS
:
9209 case BGP_STATS_ASPATH_TOTSIZE
:
9210 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9211 vty_out (vty
, "%12.2f",
9213 (float)ts
.counts
[i
] /
9214 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9217 case BGP_STATS_TOTPLEN
:
9218 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9219 vty_out (vty
, "%12.2f",
9221 (float)ts
.counts
[i
] /
9222 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9225 case BGP_STATS_SPACE
:
9226 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9227 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
9228 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9230 vty_out (vty
, "%30s: ", "%% announced ");
9231 vty_out (vty
, "%12.2f%s",
9232 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
9233 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
9235 vty_out (vty
, "%30s: ", "/8 equivalent ");
9236 vty_out (vty
, "%12.2f%s",
9237 (float)ts
.counts
[BGP_STATS_SPACE
] /
9238 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
9240 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9242 vty_out (vty
, "%30s: ", "/24 equivalent ");
9243 vty_out (vty
, "%12.2f",
9244 (float)ts
.counts
[BGP_STATS_SPACE
] /
9245 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9248 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9249 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9252 vty_out (vty
, "%s", VTY_NEWLINE
);
9267 PCOUNT_PFCNT
, /* the figure we display to users */
9271 static const char *pcount_strs
[] =
9273 [PCOUNT_ADJ_IN
] = "Adj-in",
9274 [PCOUNT_DAMPED
] = "Damped",
9275 [PCOUNT_REMOVED
] = "Removed",
9276 [PCOUNT_HISTORY
] = "History",
9277 [PCOUNT_STALE
] = "Stale",
9278 [PCOUNT_VALID
] = "Valid",
9279 [PCOUNT_ALL
] = "All RIB",
9280 [PCOUNT_COUNTED
] = "PfxCt counted",
9281 [PCOUNT_PFCNT
] = "Useable",
9282 [PCOUNT_MAX
] = NULL
,
9287 unsigned int count
[PCOUNT_MAX
];
9288 const struct peer
*peer
;
9289 const struct bgp_table
*table
;
9293 bgp_peer_count_walker (struct thread
*t
)
9295 struct bgp_node
*rn
;
9296 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9297 const struct peer
*peer
= pc
->peer
;
9299 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9301 struct bgp_adj_in
*ain
;
9302 struct bgp_info
*ri
;
9304 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9305 if (ain
->peer
== peer
)
9306 pc
->count
[PCOUNT_ADJ_IN
]++;
9308 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9310 char buf
[SU_ADDRSTRLEN
];
9312 if (ri
->peer
!= peer
)
9315 pc
->count
[PCOUNT_ALL
]++;
9317 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9318 pc
->count
[PCOUNT_DAMPED
]++;
9319 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9320 pc
->count
[PCOUNT_HISTORY
]++;
9321 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9322 pc
->count
[PCOUNT_REMOVED
]++;
9323 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9324 pc
->count
[PCOUNT_STALE
]++;
9325 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9326 pc
->count
[PCOUNT_VALID
]++;
9327 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9328 pc
->count
[PCOUNT_PFCNT
]++;
9330 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9332 pc
->count
[PCOUNT_COUNTED
]++;
9333 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9334 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9336 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9337 buf
, SU_ADDRSTRLEN
),
9343 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9344 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9346 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9347 buf
, SU_ADDRSTRLEN
),
9357 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9359 struct peer_pcounts pcounts
= { .peer
= peer
};
9361 json_object
*json
= NULL
;
9362 json_object
*json_loop
= NULL
;
9366 json
= json_object_new_object();
9367 json_loop
= json_object_new_object();
9370 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9371 || !peer
->bgp
->rib
[afi
][safi
])
9375 json_object_string_add(json
, "warning", "No such neighbor or address family");
9376 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9377 json_object_free(json
);
9380 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9385 memset (&pcounts
, 0, sizeof(pcounts
));
9386 pcounts
.peer
= peer
;
9387 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9389 /* in-place call via thread subsystem so as to record execution time
9390 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9391 * * on just vty_read()).
9393 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9397 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9398 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9399 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9401 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9402 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9404 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9406 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9408 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9409 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9411 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9412 json_object_free(json
);
9417 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9419 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9420 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9425 vty_out (vty
, "Prefix counts for %s, %s%s",
9426 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9429 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9430 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9431 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9433 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9434 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9436 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9438 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9439 peer
->host
, VTY_NEWLINE
);
9440 vty_out (vty
, "Please report this bug, with the above command output%s",
9448 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9449 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9450 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] "
9451 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9455 BGP_INSTANCE_HELP_STR
9458 "Address Family modifier\n"
9459 "Address Family modifier\n"
9460 "Address Family modifier\n"
9461 "Address Family modifier\n"
9462 "Address Family modifier\n"
9463 "Detailed information on TCP and BGP neighbor connections\n"
9464 "Neighbor to display information about\n"
9465 "Neighbor to display information about\n"
9466 "Neighbor on BGP configured interface\n"
9467 "Display detailed prefix count information\n"
9470 afi_t afi
= AFI_IP6
;
9471 safi_t safi
= SAFI_UNICAST
;
9474 struct bgp
*bgp
= NULL
;
9476 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9480 int uj
= use_json (argc
, argv
);
9483 argv_find (argv
, argc
, "neighbors", &idx
);
9484 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9488 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9491 #ifdef KEEP_OLD_VPN_COMMANDS
9492 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9493 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9494 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9499 "Display information about all VPNv4 NLRIs\n"
9500 "Detailed information on TCP and BGP neighbor connections\n"
9501 "Neighbor to display information about\n"
9502 "Neighbor to display information about\n"
9503 "Neighbor on BGP configured interface\n"
9504 "Display detailed prefix count information\n"
9509 u_char uj
= use_json(argc
, argv
);
9511 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9515 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9518 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9519 show_ip_bgp_vpn_all_route_prefix_cmd
,
9520 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9525 "Display information about all VPNv4 NLRIs\n"
9526 "Network in the BGP routing table to display\n"
9527 "Network in the BGP routing table to display\n"
9531 char *network
= NULL
;
9532 struct bgp
*bgp
= bgp_get_default();
9535 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9539 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9540 network
= argv
[idx
]->arg
;
9541 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9542 network
= argv
[idx
]->arg
;
9545 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9549 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9551 #endif /* KEEP_OLD_VPN_COMMANDS */
9553 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9554 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9555 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9561 "Display information about all EVPN NLRIs\n"
9562 "Network in the BGP routing table to display\n"
9563 "Network in the BGP routing table to display\n"
9567 char *network
= NULL
;
9569 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9570 network
= argv
[idx
]->arg
;
9571 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9572 network
= argv
[idx
]->arg
;
9575 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9578 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9582 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9583 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9585 struct bgp_table
*table
;
9586 struct bgp_adj_in
*ain
;
9587 struct bgp_adj_out
*adj
;
9588 unsigned long output_count
;
9589 unsigned long filtered_count
;
9590 struct bgp_node
*rn
;
9595 struct attr_extra extra
;
9597 struct update_subgroup
*subgrp
;
9598 json_object
*json_scode
= NULL
;
9599 json_object
*json_ocode
= NULL
;
9600 json_object
*json_ar
= NULL
;
9601 struct peer_af
*paf
;
9605 json_scode
= json_object_new_object();
9606 json_ocode
= json_object_new_object();
9607 json_ar
= json_object_new_object();
9609 json_object_string_add(json_scode
, "suppressed", "s");
9610 json_object_string_add(json_scode
, "damped", "d");
9611 json_object_string_add(json_scode
, "history", "h");
9612 json_object_string_add(json_scode
, "valid", "*");
9613 json_object_string_add(json_scode
, "best", ">");
9614 json_object_string_add(json_scode
, "multipath", "=");
9615 json_object_string_add(json_scode
, "internal", "i");
9616 json_object_string_add(json_scode
, "ribFailure", "r");
9617 json_object_string_add(json_scode
, "stale", "S");
9618 json_object_string_add(json_scode
, "removed", "R");
9620 json_object_string_add(json_ocode
, "igp", "i");
9621 json_object_string_add(json_ocode
, "egp", "e");
9622 json_object_string_add(json_ocode
, "incomplete", "?");
9631 json_object_string_add(json
, "alert", "no BGP");
9632 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9633 json_object_free(json
);
9636 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9640 table
= bgp
->rib
[afi
][safi
];
9642 output_count
= filtered_count
= 0;
9643 subgrp
= peer_subgroup(peer
, afi
, safi
);
9645 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9649 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9650 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9651 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9652 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9653 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9657 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9658 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9659 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9661 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9662 VTY_NEWLINE
, VTY_NEWLINE
);
9667 attr
.extra
= &extra
;
9668 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9672 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9674 if (ain
->peer
== peer
)
9680 json_object_int_add(json
, "bgpTableVersion", 0);
9681 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9682 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9683 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9687 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9688 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9689 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9696 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9701 bgp_attr_dup(&attr
, ain
->attr
);
9702 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9704 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9715 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9716 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9717 if (paf
->peer
== peer
)
9723 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9724 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9725 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9726 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9730 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9731 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9732 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9733 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9741 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9747 bgp_attr_dup(&attr
, adj
->attr
);
9748 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9749 if (ret
!= RMAP_DENY
)
9751 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9761 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9763 if (output_count
!= 0)
9766 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9768 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9769 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9773 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9774 json_object_free(json
);
9780 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9781 int in
, const char *rmap_name
, u_char use_json
)
9783 json_object
*json
= NULL
;
9786 json
= json_object_new_object();
9788 if (!peer
|| !peer
->afc
[afi
][safi
])
9792 json_object_string_add(json
, "warning", "No such neighbor or address family");
9793 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9794 json_object_free(json
);
9797 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9802 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9806 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9807 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9808 json_object_free(json
);
9811 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9816 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9821 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9822 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9823 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9824 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9828 BGP_INSTANCE_HELP_STR
9831 "Detailed information on TCP and BGP neighbor connections\n"
9832 "Neighbor to display information about\n"
9833 "Neighbor to display information about\n"
9834 "Neighbor on BGP configured interface\n"
9835 "Display the received routes from neighbor\n"
9836 "Display the routes advertised to a BGP neighbor\n"
9837 "Route-map to modify the attributes\n"
9838 "Name of the route map\n"
9841 afi_t afi
= AFI_IP6
;
9842 safi_t safi
= SAFI_UNICAST
;
9843 char *rmap_name
= NULL
;
9844 char *peerstr
= NULL
;
9846 struct bgp
*bgp
= NULL
;
9851 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9855 int uj
= use_json (argc
, argv
);
9858 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9859 argv_find (argv
, argc
, "neighbors", &idx
);
9860 peerstr
= argv
[++idx
]->arg
;
9862 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9866 if (argv_find (argv
, argc
, "received-routes", &idx
))
9868 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9870 if (argv_find (argv
, argc
, "route-map", &idx
))
9871 rmap_name
= argv
[++idx
]->arg
;
9873 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9876 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9877 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9878 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9884 "Address Family modifier\n"
9885 "Detailed information on TCP and BGP neighbor connections\n"
9886 "Neighbor to display information about\n"
9887 "Neighbor to display information about\n"
9888 "Neighbor on BGP configured interface\n"
9889 "Display information received from a BGP neighbor\n"
9890 "Display the prefixlist filter\n"
9893 afi_t afi
= AFI_IP6
;
9894 safi_t safi
= SAFI_UNICAST
;
9895 char *peerstr
= NULL
;
9905 if (argv_find (argv
, argc
, "ip", &idx
))
9907 /* [<ipv4|ipv6> [unicast]] */
9908 if (argv_find (argv
, argc
, "ipv4", &idx
))
9910 if (argv_find (argv
, argc
, "ipv6", &idx
))
9912 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9913 argv_find (argv
, argc
, "neighbors", &idx
);
9914 peerstr
= argv
[++idx
]->arg
;
9916 u_char uj
= use_json(argc
, argv
);
9918 ret
= str2sockunion (peerstr
, &su
);
9921 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9925 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9927 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9933 peer
= peer_lookup (NULL
, &su
);
9937 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9939 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9944 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9945 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9949 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9950 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9955 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9957 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9964 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9965 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9967 if (! peer
|| ! peer
->afc
[afi
][safi
])
9971 json_object
*json_no
= NULL
;
9972 json_no
= json_object_new_object();
9973 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9974 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9975 json_object_free(json_no
);
9978 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9982 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9985 DEFUN (show_ip_bgp_neighbor_routes
,
9986 show_ip_bgp_neighbor_routes_cmd
,
9987 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9988 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9992 BGP_INSTANCE_HELP_STR
9995 "Detailed information on TCP and BGP neighbor connections\n"
9996 "Neighbor to display information about\n"
9997 "Neighbor to display information about\n"
9998 "Neighbor on BGP configured interface\n"
9999 "Display flap statistics of the routes learned from neighbor\n"
10000 "Display the dampened routes received from neighbor\n"
10001 "Display routes learned from neighbor\n"
10004 char *peerstr
= NULL
;
10005 struct bgp
*bgp
= NULL
;
10006 afi_t afi
= AFI_IP6
;
10007 safi_t safi
= SAFI_UNICAST
;
10009 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10013 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10015 return CMD_WARNING
;
10017 int uj
= use_json (argc
, argv
);
10020 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10021 argv_find (argv
, argc
, "neighbors", &idx
);
10022 peerstr
= argv
[++idx
]->arg
;
10024 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10027 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
10028 return CMD_WARNING
;
10031 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10032 sh_type
= bgp_show_type_flap_neighbor
;
10033 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10034 sh_type
= bgp_show_type_damp_neighbor
;
10035 else if (argv_find (argv
, argc
, "routes", &idx
))
10036 sh_type
= bgp_show_type_neighbor
;
10038 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10041 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10043 struct bgp_distance
10045 /* Distance value for the IP source prefix. */
10048 /* Name of the access-list to be matched. */
10052 DEFUN (show_bgp_afi_vpn_rd_route
,
10053 show_bgp_afi_vpn_rd_route_cmd
,
10054 "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]",
10058 "Address Family modifier\n"
10059 "Display information for a route distinguisher\n"
10060 "Route Distinguisher\n"
10061 "Network in the BGP routing table to display\n"
10062 "Network in the BGP routing table to display\n"
10066 struct prefix_rd prd
;
10067 afi_t afi
= AFI_MAX
;
10070 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10071 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10074 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
10075 return CMD_WARNING
;
10077 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10080 static struct bgp_distance
*
10081 bgp_distance_new (void)
10083 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10087 bgp_distance_free (struct bgp_distance
*bdistance
)
10089 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10093 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10094 const char *ip_str
, const char *access_list_str
)
10101 struct bgp_node
*rn
;
10102 struct bgp_distance
*bdistance
;
10104 afi
= bgp_node_afi (vty
);
10105 safi
= bgp_node_safi (vty
);
10107 ret
= str2prefix (ip_str
, &p
);
10110 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10111 return CMD_WARNING
;
10114 distance
= atoi (distance_str
);
10116 /* Get BGP distance node. */
10117 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10120 bdistance
= rn
->info
;
10121 bgp_unlock_node (rn
);
10125 bdistance
= bgp_distance_new ();
10126 rn
->info
= bdistance
;
10129 /* Set distance value. */
10130 bdistance
->distance
= distance
;
10132 /* Reset access-list configuration. */
10133 if (bdistance
->access_list
)
10135 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10136 bdistance
->access_list
= NULL
;
10138 if (access_list_str
)
10139 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10141 return CMD_SUCCESS
;
10145 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10146 const char *ip_str
, const char *access_list_str
)
10153 struct bgp_node
*rn
;
10154 struct bgp_distance
*bdistance
;
10156 afi
= bgp_node_afi (vty
);
10157 safi
= bgp_node_safi (vty
);
10159 ret
= str2prefix (ip_str
, &p
);
10162 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10163 return CMD_WARNING
;
10166 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10169 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
10170 return CMD_WARNING
;
10173 bdistance
= rn
->info
;
10174 distance
= atoi(distance_str
);
10176 if (bdistance
->distance
!= distance
)
10178 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
10179 return CMD_WARNING
;
10182 if (bdistance
->access_list
)
10183 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10184 bgp_distance_free (bdistance
);
10187 bgp_unlock_node (rn
);
10188 bgp_unlock_node (rn
);
10190 return CMD_SUCCESS
;
10193 /* Apply BGP information to distance method. */
10195 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10196 safi_t safi
, struct bgp
*bgp
)
10198 struct bgp_node
*rn
;
10201 struct bgp_distance
*bdistance
;
10202 struct access_list
*alist
;
10203 struct bgp_static
*bgp_static
;
10208 peer
= rinfo
->peer
;
10210 /* Check source address. */
10211 sockunion2hostprefix (&peer
->su
, &q
);
10212 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10215 bdistance
= rn
->info
;
10216 bgp_unlock_node (rn
);
10218 if (bdistance
->access_list
)
10220 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10221 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10222 return bdistance
->distance
;
10225 return bdistance
->distance
;
10228 /* Backdoor check. */
10229 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10232 bgp_static
= rn
->info
;
10233 bgp_unlock_node (rn
);
10235 if (bgp_static
->backdoor
)
10237 if (bgp
->distance_local
[afi
][safi
])
10238 return bgp
->distance_local
[afi
][safi
];
10240 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10244 if (peer
->sort
== BGP_PEER_EBGP
)
10246 if (bgp
->distance_ebgp
[afi
][safi
])
10247 return bgp
->distance_ebgp
[afi
][safi
];
10248 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10252 if (bgp
->distance_ibgp
[afi
][safi
])
10253 return bgp
->distance_ibgp
[afi
][safi
];
10254 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10258 DEFUN (bgp_distance
,
10260 "distance bgp (1-255) (1-255) (1-255)",
10261 "Define an administrative distance\n"
10263 "Distance for routes external to the AS\n"
10264 "Distance for routes internal to the AS\n"
10265 "Distance for local routes\n")
10267 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10268 int idx_number
= 2;
10269 int idx_number_2
= 3;
10270 int idx_number_3
= 4;
10274 afi
= bgp_node_afi (vty
);
10275 safi
= bgp_node_safi (vty
);
10277 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10278 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10279 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10280 return CMD_SUCCESS
;
10283 DEFUN (no_bgp_distance
,
10284 no_bgp_distance_cmd
,
10285 "no distance bgp [(1-255) (1-255) (1-255)]",
10287 "Define an administrative distance\n"
10289 "Distance for routes external to the AS\n"
10290 "Distance for routes internal to the AS\n"
10291 "Distance for local routes\n")
10293 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10297 afi
= bgp_node_afi (vty
);
10298 safi
= bgp_node_safi (vty
);
10300 bgp
->distance_ebgp
[afi
][safi
] = 0;
10301 bgp
->distance_ibgp
[afi
][safi
] = 0;
10302 bgp
->distance_local
[afi
][safi
] = 0;
10303 return CMD_SUCCESS
;
10307 DEFUN (bgp_distance_source
,
10308 bgp_distance_source_cmd
,
10309 "distance (1-255) A.B.C.D/M",
10310 "Define an administrative distance\n"
10311 "Administrative distance\n"
10312 "IP source prefix\n")
10314 int idx_number
= 1;
10315 int idx_ipv4_prefixlen
= 2;
10316 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10317 return CMD_SUCCESS
;
10320 DEFUN (no_bgp_distance_source
,
10321 no_bgp_distance_source_cmd
,
10322 "no distance (1-255) A.B.C.D/M",
10324 "Define an administrative distance\n"
10325 "Administrative distance\n"
10326 "IP source prefix\n")
10328 int idx_number
= 2;
10329 int idx_ipv4_prefixlen
= 3;
10330 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10331 return CMD_SUCCESS
;
10334 DEFUN (bgp_distance_source_access_list
,
10335 bgp_distance_source_access_list_cmd
,
10336 "distance (1-255) A.B.C.D/M WORD",
10337 "Define an administrative distance\n"
10338 "Administrative distance\n"
10339 "IP source prefix\n"
10340 "Access list name\n")
10342 int idx_number
= 1;
10343 int idx_ipv4_prefixlen
= 2;
10345 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10346 return CMD_SUCCESS
;
10349 DEFUN (no_bgp_distance_source_access_list
,
10350 no_bgp_distance_source_access_list_cmd
,
10351 "no distance (1-255) A.B.C.D/M WORD",
10353 "Define an administrative distance\n"
10354 "Administrative distance\n"
10355 "IP source prefix\n"
10356 "Access list name\n")
10358 int idx_number
= 2;
10359 int idx_ipv4_prefixlen
= 3;
10361 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10362 return CMD_SUCCESS
;
10365 DEFUN (ipv6_bgp_distance_source
,
10366 ipv6_bgp_distance_source_cmd
,
10367 "distance (1-255) X:X::X:X/M",
10368 "Define an administrative distance\n"
10369 "Administrative distance\n"
10370 "IP source prefix\n")
10372 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10373 return CMD_SUCCESS
;
10376 DEFUN (no_ipv6_bgp_distance_source
,
10377 no_ipv6_bgp_distance_source_cmd
,
10378 "no distance (1-255) X:X::X:X/M",
10380 "Define an administrative distance\n"
10381 "Administrative distance\n"
10382 "IP source prefix\n")
10384 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10385 return CMD_SUCCESS
;
10388 DEFUN (ipv6_bgp_distance_source_access_list
,
10389 ipv6_bgp_distance_source_access_list_cmd
,
10390 "distance (1-255) X:X::X:X/M WORD",
10391 "Define an administrative distance\n"
10392 "Administrative distance\n"
10393 "IP source prefix\n"
10394 "Access list name\n")
10396 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10397 return CMD_SUCCESS
;
10400 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10401 no_ipv6_bgp_distance_source_access_list_cmd
,
10402 "no distance (1-255) X:X::X:X/M WORD",
10404 "Define an administrative distance\n"
10405 "Administrative distance\n"
10406 "IP source prefix\n"
10407 "Access list name\n")
10409 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10410 return CMD_SUCCESS
;
10413 DEFUN (bgp_damp_set
,
10415 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10416 "BGP Specific commands\n"
10417 "Enable route-flap dampening\n"
10418 "Half-life time for the penalty\n"
10419 "Value to start reusing a route\n"
10420 "Value to start suppressing a route\n"
10421 "Maximum duration to suppress a stable route\n")
10423 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10424 int idx_half_life
= 2;
10426 int idx_suppress
= 4;
10427 int idx_max_suppress
= 5;
10428 int half
= DEFAULT_HALF_LIFE
* 60;
10429 int reuse
= DEFAULT_REUSE
;
10430 int suppress
= DEFAULT_SUPPRESS
;
10431 int max
= 4 * half
;
10435 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10436 reuse
= atoi (argv
[idx_reuse
]->arg
);
10437 suppress
= atoi (argv
[idx_suppress
]->arg
);
10438 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10440 else if (argc
== 3)
10442 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10446 if (suppress
< reuse
)
10448 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10453 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10454 half
, reuse
, suppress
, max
);
10457 DEFUN (bgp_damp_unset
,
10458 bgp_damp_unset_cmd
,
10459 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10461 "BGP Specific commands\n"
10462 "Enable route-flap dampening\n"
10463 "Half-life time for the penalty\n"
10464 "Value to start reusing a route\n"
10465 "Value to start suppressing a route\n"
10466 "Maximum duration to suppress a stable route\n")
10468 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10469 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10472 /* Display specified route of BGP table. */
10474 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10475 const char *ip_str
, afi_t afi
, safi_t safi
,
10476 struct prefix_rd
*prd
, int prefix_check
)
10479 struct prefix match
;
10480 struct bgp_node
*rn
;
10481 struct bgp_node
*rm
;
10482 struct bgp_info
*ri
;
10483 struct bgp_info
*ri_temp
;
10485 struct bgp_table
*table
;
10487 /* BGP structure lookup. */
10490 bgp
= bgp_lookup_by_name (view_name
);
10493 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10494 return CMD_WARNING
;
10499 bgp
= bgp_get_default ();
10502 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10503 return CMD_WARNING
;
10507 /* Check IP address argument. */
10508 ret
= str2prefix (ip_str
, &match
);
10511 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10512 return CMD_WARNING
;
10515 match
.family
= afi2family (afi
);
10517 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10519 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10521 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10524 if ((table
= rn
->info
) != NULL
)
10525 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10527 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10532 if (ri
->extra
&& ri
->extra
->damp_info
)
10534 ri_temp
= ri
->next
;
10535 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10543 bgp_unlock_node (rm
);
10549 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10551 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10556 if (ri
->extra
&& ri
->extra
->damp_info
)
10558 ri_temp
= ri
->next
;
10559 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10567 bgp_unlock_node (rn
);
10571 return CMD_SUCCESS
;
10574 DEFUN (clear_ip_bgp_dampening
,
10575 clear_ip_bgp_dampening_cmd
,
10576 "clear ip bgp dampening",
10580 "Clear route flap dampening information\n")
10582 bgp_damp_info_clean ();
10583 return CMD_SUCCESS
;
10586 DEFUN (clear_ip_bgp_dampening_prefix
,
10587 clear_ip_bgp_dampening_prefix_cmd
,
10588 "clear ip bgp dampening A.B.C.D/M",
10592 "Clear route flap dampening information\n"
10595 int idx_ipv4_prefixlen
= 4;
10596 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10597 SAFI_UNICAST
, NULL
, 1);
10600 DEFUN (clear_ip_bgp_dampening_address
,
10601 clear_ip_bgp_dampening_address_cmd
,
10602 "clear ip bgp dampening A.B.C.D",
10606 "Clear route flap dampening information\n"
10607 "Network to clear damping information\n")
10610 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10611 SAFI_UNICAST
, NULL
, 0);
10614 DEFUN (clear_ip_bgp_dampening_address_mask
,
10615 clear_ip_bgp_dampening_address_mask_cmd
,
10616 "clear ip bgp dampening A.B.C.D A.B.C.D",
10620 "Clear route flap dampening information\n"
10621 "Network to clear damping information\n"
10625 int idx_ipv4_2
= 5;
10627 char prefix_str
[BUFSIZ
];
10629 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10632 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10633 return CMD_WARNING
;
10636 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10637 SAFI_UNICAST
, NULL
, 0);
10640 /* also used for encap safi */
10642 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10643 afi_t afi
, safi_t safi
, int *write
)
10645 struct bgp_node
*prn
;
10646 struct bgp_node
*rn
;
10647 struct bgp_table
*table
;
10649 struct prefix_rd
*prd
;
10650 struct bgp_static
*bgp_static
;
10652 char buf
[SU_ADDRSTRLEN
];
10653 char rdbuf
[RD_ADDRSTRLEN
];
10655 /* Network configuration. */
10656 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10657 if ((table
= prn
->info
) != NULL
)
10658 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10659 if ((bgp_static
= rn
->info
) != NULL
)
10662 prd
= (struct prefix_rd
*) &prn
->p
;
10664 /* "address-family" display. */
10665 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10667 /* "network" configuration display. */
10668 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10669 label
= decode_label (bgp_static
->tag
);
10671 vty_out (vty
, " network %s/%d rd %s tag %d",
10672 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10675 vty_out (vty
, "%s", VTY_NEWLINE
);
10681 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10682 afi_t afi
, safi_t safi
, int *write
)
10684 struct bgp_node
*prn
;
10685 struct bgp_node
*rn
;
10686 struct bgp_table
*table
;
10688 struct prefix_rd
*prd
;
10689 struct bgp_static
*bgp_static
;
10690 char buf
[PREFIX_STRLEN
];
10691 char buf2
[SU_ADDRSTRLEN
];
10692 char rdbuf
[RD_ADDRSTRLEN
];
10694 /* Network configuration. */
10695 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10696 if ((table
= prn
->info
) != NULL
)
10697 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10698 if ((bgp_static
= rn
->info
) != NULL
)
10700 char *macrouter
= NULL
;
10703 if(bgp_static
->router_mac
)
10704 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10705 if(bgp_static
->eth_s_id
)
10706 esi
= esi2str(bgp_static
->eth_s_id
);
10708 prd
= (struct prefix_rd
*) &prn
->p
;
10710 /* "address-family" display. */
10711 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10713 /* "network" configuration display. */
10714 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10716 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10718 prefix2str (p
, buf
, sizeof (buf
)),
10719 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10720 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10721 decode_label (bgp_static
->tag
), esi
, buf2
, macrouter
);
10722 vty_out (vty
, "%s", VTY_NEWLINE
);
10724 XFREE (MTYPE_TMP
, macrouter
);
10726 XFREE (MTYPE_TMP
, esi
);
10731 /* Configuration of static route announcement and aggregate
10734 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10735 afi_t afi
, safi_t safi
, int *write
)
10737 struct bgp_node
*rn
;
10739 struct bgp_static
*bgp_static
;
10740 struct bgp_aggregate
*bgp_aggregate
;
10741 char buf
[SU_ADDRSTRLEN
];
10743 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10744 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10746 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10747 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10749 /* Network configuration. */
10750 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10751 if ((bgp_static
= rn
->info
) != NULL
)
10755 /* "address-family" display. */
10756 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10758 /* "network" configuration display. */
10759 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10761 u_int32_t destination
;
10762 struct in_addr netmask
;
10764 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10765 masklen2ip (p
->prefixlen
, &netmask
);
10766 vty_out (vty
, " network %s",
10767 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10769 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10770 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10771 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10772 || p
->u
.prefix4
.s_addr
== 0)
10774 /* Natural mask is not display. */
10777 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10781 vty_out (vty
, " network %s/%d",
10782 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10786 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10787 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10789 if (bgp_static
->rmap
.name
)
10790 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10793 if (bgp_static
->backdoor
)
10794 vty_out (vty
, " backdoor");
10797 vty_out (vty
, "%s", VTY_NEWLINE
);
10800 /* Aggregate-address configuration. */
10801 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10802 if ((bgp_aggregate
= rn
->info
) != NULL
)
10806 /* "address-family" display. */
10807 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10809 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10811 struct in_addr netmask
;
10813 masklen2ip (p
->prefixlen
, &netmask
);
10814 vty_out (vty
, " aggregate-address %s %s",
10815 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10816 inet_ntoa (netmask
));
10820 vty_out (vty
, " aggregate-address %s/%d",
10821 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10825 if (bgp_aggregate
->as_set
)
10826 vty_out (vty
, " as-set");
10828 if (bgp_aggregate
->summary_only
)
10829 vty_out (vty
, " summary-only");
10831 vty_out (vty
, "%s", VTY_NEWLINE
);
10838 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10839 safi_t safi
, int *write
)
10841 struct bgp_node
*rn
;
10842 struct bgp_distance
*bdistance
;
10844 /* Distance configuration. */
10845 if (bgp
->distance_ebgp
[afi
][safi
]
10846 && bgp
->distance_ibgp
[afi
][safi
]
10847 && bgp
->distance_local
[afi
][safi
]
10848 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10849 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10850 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10852 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10853 vty_out (vty
, " distance bgp %d %d %d%s",
10854 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10855 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10858 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10859 rn
= bgp_route_next (rn
))
10860 if ((bdistance
= rn
->info
) != NULL
)
10862 char buf
[PREFIX_STRLEN
];
10864 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10865 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10866 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10867 bdistance
->access_list
? bdistance
->access_list
: "",
10874 /* Allocate routing table structure and install commands. */
10876 bgp_route_init (void)
10881 /* Init BGP distance table. */
10882 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10883 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10884 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10886 /* IPv4 BGP commands. */
10887 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10888 install_element (BGP_NODE
, &bgp_network_cmd
);
10889 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10890 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10891 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10892 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10893 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10894 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10895 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10896 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10897 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10898 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10899 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10900 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10902 install_element (BGP_NODE
, &aggregate_address_cmd
);
10903 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10904 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10905 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10907 /* IPv4 unicast configuration. */
10908 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10909 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10910 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10911 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10912 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10913 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10914 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10915 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_cmd
);
10916 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_route_map_cmd
);
10917 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10918 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10919 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10920 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10922 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10923 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10924 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10925 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10927 /* IPv4 multicast configuration. */
10928 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10929 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10930 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10931 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10932 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10933 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10934 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10935 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10936 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10937 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10938 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10939 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10940 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10941 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10942 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10944 /* IPv4 labeled-unicast configuration. */
10945 install_element (BGP_IPV4L_NODE
, &bgp_table_map_cmd
);
10946 install_element (BGP_IPV4L_NODE
, &bgp_network_cmd
);
10947 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_cmd
);
10948 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_cmd
);
10949 install_element (BGP_IPV4L_NODE
, &bgp_network_route_map_cmd
);
10950 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_route_map_cmd
);
10951 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10952 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_cmd
);
10953 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_route_map_cmd
);
10954 install_element (BGP_IPV4L_NODE
, &no_bgp_table_map_cmd
);
10955 install_element (BGP_IPV4L_NODE
, &no_bgp_network_cmd
);
10956 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_cmd
);
10957 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_natural_cmd
);
10959 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10960 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10961 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10962 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10964 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10965 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10966 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10967 #ifdef KEEP_OLD_VPN_COMMANDS
10968 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10969 #endif /* KEEP_OLD_VPN_COMMANDS */
10970 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10971 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10973 /* BGP dampening clear commands */
10974 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10975 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10977 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10978 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10981 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10982 #ifdef KEEP_OLD_VPN_COMMANDS
10983 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10984 #endif /* KEEP_OLD_VPN_COMMANDS */
10986 /* New config IPv6 BGP commands. */
10987 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10988 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10989 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10990 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10991 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10992 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
10993 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
10994 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
10995 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
10997 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10998 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11000 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11001 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11003 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11004 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11005 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11006 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11007 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11009 install_element (BGP_NODE
, &bgp_distance_cmd
);
11010 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
11011 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
11012 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
11013 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11014 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11015 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11016 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11017 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11018 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11019 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11020 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11021 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11022 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11023 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11024 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11025 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11026 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11027 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11028 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11029 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11030 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11031 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11032 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11033 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11034 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11035 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11036 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11037 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11038 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11040 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11041 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11042 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11043 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11045 /* IPv4 Multicast Mode */
11046 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11047 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11049 /* Large Communities */
11050 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11051 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11055 bgp_route_finish (void)
11060 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11061 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11063 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11064 bgp_distance_table
[afi
][safi
] = NULL
;