1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "sockunion.h"
36 #include "workqueue.h"
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_table.h"
44 #include "bgpd/bgp_route.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_regex.h"
49 #include "bgpd/bgp_community.h"
50 #include "bgpd/bgp_ecommunity.h"
51 #include "bgpd/bgp_lcommunity.h"
52 #include "bgpd/bgp_clist.h"
53 #include "bgpd/bgp_packet.h"
54 #include "bgpd/bgp_filter.h"
55 #include "bgpd/bgp_fsm.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_nexthop.h"
58 #include "bgpd/bgp_damp.h"
59 #include "bgpd/bgp_advertise.h"
60 #include "bgpd/bgp_zebra.h"
61 #include "bgpd/bgp_vty.h"
62 #include "bgpd/bgp_mpath.h"
63 #include "bgpd/bgp_nht.h"
64 #include "bgpd/bgp_updgrp.h"
65 #include "bgpd/bgp_label.h"
68 #include "bgpd/rfapi/rfapi_backend.h"
69 #include "bgpd/rfapi/vnc_import_bgp.h"
70 #include "bgpd/rfapi/vnc_export_bgp.h"
72 #include "bgpd/bgp_encap_types.h"
73 #include "bgpd/bgp_encap_tlv.h"
74 #include "bgpd/bgp_evpn.h"
75 #include "bgpd/bgp_evpn_vty.h"
78 /* Extern from bgp_dump.c */
79 extern const char *bgp_origin_str
[];
80 extern const char *bgp_origin_long_str
[];
83 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
84 struct prefix_rd
*prd
)
87 struct bgp_node
*prn
= NULL
;
93 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
96 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
98 if (prn
->info
== NULL
)
99 prn
->info
= bgp_table_init (afi
, safi
);
101 bgp_unlock_node (prn
);
105 rn
= bgp_node_get (table
, p
);
107 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
114 /* Allocate bgp_info_extra */
115 static struct bgp_info_extra
*
116 bgp_info_extra_new (void)
118 struct bgp_info_extra
*new;
119 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
124 bgp_info_extra_free (struct bgp_info_extra
**extra
)
128 if ((*extra
)->damp_info
)
129 bgp_damp_info_free ((*extra
)->damp_info
, 0);
131 (*extra
)->damp_info
= NULL
;
133 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
139 /* Get bgp_info extra information for the given bgp_info, lazy allocated
142 struct bgp_info_extra
*
143 bgp_info_extra_get (struct bgp_info
*ri
)
146 ri
->extra
= bgp_info_extra_new();
150 /* Allocate new bgp info structure. */
154 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
157 /* Free bgp route information. */
159 bgp_info_free (struct bgp_info
*binfo
)
162 bgp_attr_unintern (&binfo
->attr
);
164 bgp_unlink_nexthop(binfo
);
165 bgp_info_extra_free (&binfo
->extra
);
166 bgp_info_mpath_free (&binfo
->mpath
);
168 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
170 XFREE (MTYPE_BGP_ROUTE
, binfo
);
174 bgp_info_lock (struct bgp_info
*binfo
)
181 bgp_info_unlock (struct bgp_info
*binfo
)
183 assert (binfo
&& binfo
->lock
> 0);
186 if (binfo
->lock
== 0)
189 zlog_debug ("%s: unlocked and freeing", __func__
);
190 zlog_backtrace (LOG_DEBUG
);
192 bgp_info_free (binfo
);
197 if (binfo
->lock
== 1)
199 zlog_debug ("%s: unlocked to 1", __func__
);
200 zlog_backtrace (LOG_DEBUG
);
208 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
210 struct bgp_info
*top
;
222 peer_lock (ri
->peer
); /* bgp_info peer reference */
225 /* Do the actual removal of info from RIB, for use by bgp_process
226 completion callback *only* */
228 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
231 ri
->next
->prev
= ri
->prev
;
233 ri
->prev
->next
= ri
->next
;
237 bgp_info_mpath_dequeue (ri
);
238 bgp_info_unlock (ri
);
239 bgp_unlock_node (rn
);
243 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
245 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
246 /* set of previous already took care of pcount */
247 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
250 /* undo the effects of a previous call to bgp_info_delete; typically
251 called when a route is deleted and then quickly re-added before the
252 deletion has been processed */
254 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
256 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
257 /* unset of previous already took care of pcount */
258 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
261 /* Adjust pcount as required */
263 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
265 struct bgp_table
*table
;
267 assert (rn
&& bgp_node_table (rn
));
268 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
270 table
= bgp_node_table (rn
);
272 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
275 if (!BGP_INFO_COUNTABLE (ri
)
276 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
279 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
281 /* slight hack, but more robust against errors. */
282 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
283 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
286 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
287 __func__
, ri
->peer
->host
);
288 zlog_backtrace (LOG_WARNING
);
289 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
292 else if (BGP_INFO_COUNTABLE (ri
)
293 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
295 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
296 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
301 bgp_label_index_differs (struct bgp_info
*ri1
, struct bgp_info
*ri2
)
303 return (!(ri1
->attr
->extra
->label_index
== ri2
->attr
->extra
->label_index
));
306 /* Set/unset bgp_info flags, adjusting any other state as needed.
307 * This is here primarily to keep prefix-count in check.
310 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
312 SET_FLAG (ri
->flags
, flag
);
314 /* early bath if we know it's not a flag that changes countability state */
315 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
318 bgp_pcount_adjust (rn
, ri
);
322 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
324 UNSET_FLAG (ri
->flags
, flag
);
326 /* early bath if we know it's not a flag that changes countability state */
327 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
330 bgp_pcount_adjust (rn
, ri
);
333 /* Get MED value. If MED value is missing and "bgp bestpath
334 missing-as-worst" is specified, treat it as the worst value. */
336 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
338 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
342 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
350 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
352 if (ri
->addpath_rx_id
)
353 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
355 sprintf(buf
, "path %s", ri
->peer
->host
);
358 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
360 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
361 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
364 struct attr
*newattr
, *existattr
;
365 struct attr_extra
*newattre
, *existattre
;
366 bgp_peer_sort_t new_sort
;
367 bgp_peer_sort_t exist_sort
;
369 u_int32_t exist_pref
;
372 u_int32_t new_weight
;
373 u_int32_t exist_weight
;
374 uint32_t newm
, existm
;
375 struct in_addr new_id
;
376 struct in_addr exist_id
;
379 int internal_as_route
;
382 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
383 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
391 zlog_debug("%s: new is NULL", pfx_buf
);
396 bgp_info_path_with_addpath_rx_str (new, new_buf
);
401 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
407 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
408 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
409 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
413 existattr
= exist
->attr
;
414 newattre
= newattr
->extra
;
415 existattre
= existattr
->extra
;
417 /* 1. Weight check. */
418 new_weight
= exist_weight
= 0;
421 new_weight
= newattre
->weight
;
423 exist_weight
= existattre
->weight
;
425 if (new_weight
> exist_weight
)
428 zlog_debug("%s: %s wins over %s due to weight %d > %d",
429 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
433 if (new_weight
< exist_weight
)
436 zlog_debug("%s: %s loses to %s due to weight %d < %d",
437 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
441 /* 2. Local preference check. */
442 new_pref
= exist_pref
= bgp
->default_local_pref
;
444 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
445 new_pref
= newattr
->local_pref
;
446 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
447 exist_pref
= existattr
->local_pref
;
449 if (new_pref
> exist_pref
)
452 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
453 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
457 if (new_pref
< exist_pref
)
460 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
461 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
465 /* 3. Local route check. We prefer:
467 * - BGP_ROUTE_AGGREGATE
468 * - BGP_ROUTE_REDISTRIBUTE
470 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
473 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
474 pfx_buf
, new_buf
, exist_buf
);
478 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
481 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
482 pfx_buf
, new_buf
, exist_buf
);
486 /* 4. AS path length check. */
487 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
489 int exist_hops
= aspath_count_hops (existattr
->aspath
);
490 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
492 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
496 aspath_hops
= aspath_count_hops (newattr
->aspath
);
497 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
499 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
502 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
503 pfx_buf
, new_buf
, exist_buf
,
504 aspath_hops
, (exist_hops
+ exist_confeds
));
508 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
511 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
512 pfx_buf
, new_buf
, exist_buf
,
513 aspath_hops
, (exist_hops
+ exist_confeds
));
519 int newhops
= aspath_count_hops (newattr
->aspath
);
521 if (newhops
< exist_hops
)
524 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
525 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
529 if (newhops
> exist_hops
)
532 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
533 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
539 /* 5. Origin check. */
540 if (newattr
->origin
< existattr
->origin
)
543 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
544 pfx_buf
, new_buf
, exist_buf
,
545 bgp_origin_long_str
[newattr
->origin
],
546 bgp_origin_long_str
[existattr
->origin
]);
550 if (newattr
->origin
> existattr
->origin
)
553 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
554 pfx_buf
, new_buf
, exist_buf
,
555 bgp_origin_long_str
[newattr
->origin
],
556 bgp_origin_long_str
[existattr
->origin
]);
561 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
562 && aspath_count_hops (existattr
->aspath
) == 0);
563 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
564 && aspath_count_confeds (existattr
->aspath
) > 0
565 && aspath_count_hops (newattr
->aspath
) == 0
566 && aspath_count_hops (existattr
->aspath
) == 0);
568 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
569 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
571 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
572 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
573 || internal_as_route
)
575 new_med
= bgp_med_value (new->attr
, bgp
);
576 exist_med
= bgp_med_value (exist
->attr
, bgp
);
578 if (new_med
< exist_med
)
581 zlog_debug("%s: %s wins over %s due to MED %d < %d",
582 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
586 if (new_med
> exist_med
)
589 zlog_debug("%s: %s loses to %s due to MED %d > %d",
590 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
595 /* 7. Peer type check. */
596 new_sort
= new->peer
->sort
;
597 exist_sort
= exist
->peer
->sort
;
599 if (new_sort
== BGP_PEER_EBGP
600 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
603 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
604 pfx_buf
, new_buf
, exist_buf
);
608 if (exist_sort
== BGP_PEER_EBGP
609 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
612 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
613 pfx_buf
, new_buf
, exist_buf
);
617 /* 8. IGP metric check. */
621 newm
= new->extra
->igpmetric
;
623 existm
= exist
->extra
->igpmetric
;
628 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
629 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
636 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
637 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
641 /* 9. Same IGP metric. Compare the cluster list length as
642 representative of IGP hops metric. Rewrite the metric value
643 pair (newm, existm) with the cluster list length. Prefer the
644 path with smaller cluster list length. */
647 if (peer_sort (new->peer
) == BGP_PEER_IBGP
648 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
649 && (mpath_cfg
== NULL
||
650 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
651 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
653 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
654 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
659 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
660 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
667 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
668 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
674 /* 10. confed-external vs. confed-internal */
675 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
677 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
680 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
681 pfx_buf
, new_buf
, exist_buf
);
685 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
688 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
689 pfx_buf
, new_buf
, exist_buf
);
694 /* 11. Maximum path check. */
697 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
701 * For the two paths, all comparison steps till IGP metric
702 * have succeeded - including AS_PATH hop count. Since 'bgp
703 * bestpath as-path multipath-relax' knob is on, we don't need
704 * an exact match of AS_PATH. Thus, mark the paths are equal.
705 * That will trigger both these paths to get into the multipath
711 zlog_debug("%s: %s and %s are equal via multipath-relax",
712 pfx_buf
, new_buf
, exist_buf
);
714 else if (new->peer
->sort
== BGP_PEER_IBGP
)
716 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
721 zlog_debug("%s: %s and %s are equal via matching aspaths",
722 pfx_buf
, new_buf
, exist_buf
);
725 else if (new->peer
->as
== exist
->peer
->as
)
730 zlog_debug("%s: %s and %s are equal via same remote-as",
731 pfx_buf
, new_buf
, exist_buf
);
737 * TODO: If unequal cost ibgp multipath is enabled we can
738 * mark the paths as equal here instead of returning
743 zlog_debug("%s: %s wins over %s after IGP metric comparison",
744 pfx_buf
, new_buf
, exist_buf
);
746 zlog_debug("%s: %s loses to %s after IGP metric comparison",
747 pfx_buf
, new_buf
, exist_buf
);
752 /* 12. If both paths are external, prefer the path that was received
753 first (the oldest one). This step minimizes route-flap, since a
754 newer path won't displace an older one, even if it was the
755 preferred route based on the additional decision criteria below. */
756 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
757 && new_sort
== BGP_PEER_EBGP
758 && exist_sort
== BGP_PEER_EBGP
)
760 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
763 zlog_debug("%s: %s wins over %s due to oldest external",
764 pfx_buf
, new_buf
, exist_buf
);
768 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
771 zlog_debug("%s: %s loses to %s due to oldest external",
772 pfx_buf
, new_buf
, exist_buf
);
777 /* 13. Router-ID comparision. */
778 /* If one of the paths is "stale", the corresponding peer router-id will
779 * be 0 and would always win over the other path. If originator id is
780 * used for the comparision, it will decide which path is better.
782 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
783 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
785 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
786 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
787 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
789 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
791 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
794 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
795 pfx_buf
, new_buf
, exist_buf
);
799 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
802 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
803 pfx_buf
, new_buf
, exist_buf
);
807 /* 14. Cluster length comparision. */
808 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
809 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
811 if (new_cluster
< exist_cluster
)
814 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
815 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
819 if (new_cluster
> exist_cluster
)
822 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
823 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
827 /* 15. Neighbor address comparision. */
828 /* Do this only if neither path is "stale" as stale paths do not have
829 * valid peer information (as the connection may or may not be up).
831 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
834 zlog_debug("%s: %s wins over %s due to latter path being STALE",
835 pfx_buf
, new_buf
, exist_buf
);
839 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
842 zlog_debug("%s: %s loses to %s due to former path being STALE",
843 pfx_buf
, new_buf
, exist_buf
);
847 /* locally configured routes to advertise do not have su_remote */
848 if (new->peer
->su_remote
== NULL
)
850 if (exist
->peer
->su_remote
== NULL
)
853 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
858 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
859 pfx_buf
, new_buf
, exist_buf
);
866 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
867 pfx_buf
, new_buf
, exist_buf
);
872 zlog_debug("%s: %s wins over %s due to nothing left to compare",
873 pfx_buf
, new_buf
, exist_buf
);
878 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
879 * is preferred, or 0 if they are the same (usually will only occur if
880 * multipath is enabled
881 * This version is compatible with */
883 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
884 afi_t afi
, safi_t safi
)
888 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
902 static enum filter_type
903 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
904 afi_t afi
, safi_t safi
)
906 struct bgp_filter
*filter
;
908 filter
= &peer
->filter
[afi
][safi
];
910 #define FILTER_EXIST_WARN(F,f,filter) \
911 if (BGP_DEBUG (update, UPDATE_IN) \
912 && !(F ## _IN (filter))) \
913 zlog_warn ("%s: Could not find configured input %s-list %s!", \
914 peer->host, #f, F ## _IN_NAME(filter));
916 if (DISTRIBUTE_IN_NAME (filter
)) {
917 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
919 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
923 if (PREFIX_LIST_IN_NAME (filter
)) {
924 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
926 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
930 if (FILTER_LIST_IN_NAME (filter
)) {
931 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
933 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
937 return FILTER_PERMIT
;
938 #undef FILTER_EXIST_WARN
941 static enum filter_type
942 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
943 afi_t afi
, safi_t safi
)
945 struct bgp_filter
*filter
;
947 filter
= &peer
->filter
[afi
][safi
];
949 #define FILTER_EXIST_WARN(F,f,filter) \
950 if (BGP_DEBUG (update, UPDATE_OUT) \
951 && !(F ## _OUT (filter))) \
952 zlog_warn ("%s: Could not find configured output %s-list %s!", \
953 peer->host, #f, F ## _OUT_NAME(filter));
955 if (DISTRIBUTE_OUT_NAME (filter
)) {
956 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
958 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
962 if (PREFIX_LIST_OUT_NAME (filter
)) {
963 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
965 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
969 if (FILTER_LIST_OUT_NAME (filter
)) {
970 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
972 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
976 return FILTER_PERMIT
;
977 #undef FILTER_EXIST_WARN
980 /* If community attribute includes no_export then return 1. */
982 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
986 /* NO_ADVERTISE check. */
987 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
990 /* NO_EXPORT check. */
991 if (peer
->sort
== BGP_PEER_EBGP
&&
992 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
995 /* NO_EXPORT_SUBCONFED check. */
996 if (peer
->sort
== BGP_PEER_EBGP
997 || peer
->sort
== BGP_PEER_CONFED
)
998 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
1004 /* Route reflection loop check. */
1006 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1008 struct in_addr cluster_id
;
1010 if (attr
->extra
&& attr
->extra
->cluster
)
1012 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1013 cluster_id
= peer
->bgp
->cluster_id
;
1015 cluster_id
= peer
->bgp
->router_id
;
1017 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1024 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1025 afi_t afi
, safi_t safi
, const char *rmap_name
)
1027 struct bgp_filter
*filter
;
1028 struct bgp_info info
;
1029 route_map_result_t ret
;
1030 struct route_map
*rmap
= NULL
;
1032 filter
= &peer
->filter
[afi
][safi
];
1034 /* Apply default weight value. */
1035 if (peer
->weight
[afi
][safi
])
1036 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1040 rmap
= route_map_lookup_by_name(rmap_name
);
1047 if (ROUTE_MAP_IN_NAME(filter
))
1049 rmap
= ROUTE_MAP_IN (filter
);
1056 /* Route map apply. */
1059 /* Duplicate current value to new strucutre for modification. */
1063 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1065 /* Apply BGP route map to the attribute. */
1066 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1068 peer
->rmap_type
= 0;
1070 if (ret
== RMAP_DENYMATCH
)
1072 /* Free newly generated AS path and community by route-map. */
1073 bgp_attr_flush (attr
);
1081 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1082 afi_t afi
, safi_t safi
, const char *rmap_name
)
1084 struct bgp_filter
*filter
;
1085 struct bgp_info info
;
1086 route_map_result_t ret
;
1087 struct route_map
*rmap
= NULL
;
1089 filter
= &peer
->filter
[afi
][safi
];
1091 /* Apply default weight value. */
1092 if (peer
->weight
[afi
][safi
])
1093 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1097 rmap
= route_map_lookup_by_name(rmap_name
);
1104 if (ROUTE_MAP_OUT_NAME(filter
))
1106 rmap
= ROUTE_MAP_OUT (filter
);
1113 /* Route map apply. */
1116 /* Duplicate current value to new strucutre for modification. */
1120 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1122 /* Apply BGP route map to the attribute. */
1123 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1125 peer
->rmap_type
= 0;
1127 if (ret
== RMAP_DENYMATCH
)
1128 /* caller has multiple error paths with bgp_attr_flush() */
1134 /* If this is an EBGP peer with remove-private-AS */
1136 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1137 struct peer
*peer
, struct attr
*attr
)
1139 if (peer
->sort
== BGP_PEER_EBGP
&&
1140 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1141 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1142 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1143 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1145 // Take action on the entire aspath
1146 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1147 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1149 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1150 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1152 // The entire aspath consists of private ASNs so create an empty aspath
1153 else if (aspath_private_as_check (attr
->aspath
))
1154 attr
->aspath
= aspath_empty_get ();
1156 // There are some public and some private ASNs, remove the private ASNs
1158 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1161 // 'all' was not specified so the entire aspath must be private ASNs
1162 // for us to do anything
1163 else if (aspath_private_as_check (attr
->aspath
))
1165 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1166 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1168 attr
->aspath
= aspath_empty_get ();
1173 /* If this is an EBGP peer with as-override */
1175 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1176 struct peer
*peer
, struct attr
*attr
)
1178 if (peer
->sort
== BGP_PEER_EBGP
&&
1179 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1181 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1182 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1187 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1189 if (family
== AF_INET
)
1190 attr
->nexthop
.s_addr
= 0;
1191 if (family
== AF_INET6
)
1192 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1196 subgroup_announce_check (struct bgp_node
*rn
, struct bgp_info
*ri
,
1197 struct update_subgroup
*subgrp
,
1198 struct prefix
*p
, struct attr
*attr
)
1200 struct bgp_filter
*filter
;
1203 struct peer
*onlypeer
;
1205 struct attr
*riattr
;
1206 struct peer_af
*paf
;
1207 char buf
[PREFIX_STRLEN
];
1213 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1215 if (DISABLE_BGP_ANNOUNCE
)
1218 afi
= SUBGRP_AFI(subgrp
);
1219 safi
= SUBGRP_SAFI(subgrp
);
1220 peer
= SUBGRP_PEER(subgrp
);
1222 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1223 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1226 filter
= &peer
->filter
[afi
][safi
];
1227 bgp
= SUBGRP_INST(subgrp
);
1228 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1231 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1232 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1233 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1236 * direct and direct_ext type routes originate internally even
1237 * though they can have peer pointers that reference other systems
1239 prefix2str(p
, buf
, PREFIX_STRLEN
);
1240 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1245 /* With addpath we may be asked to TX all kinds of paths so make sure
1247 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1248 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1249 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1254 /* If this is not the bestpath then check to see if there is an enabled addpath
1255 * feature that requires us to advertise it */
1256 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1258 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1264 /* Aggregate-address suppress check. */
1265 if (ri
->extra
&& ri
->extra
->suppress
)
1266 if (! UNSUPPRESS_MAP_NAME (filter
))
1271 /* If it's labeled safi, make sure the route has a valid label. */
1272 if (safi
== SAFI_LABELED_UNICAST
)
1274 u_char
*tag
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1275 if (!bgp_is_valid_label(tag
))
1277 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1278 zlog_debug ("u%" PRIu64
":s%" PRIu64
" %s/%d is filtered - no label (%p)",
1279 subgrp
->update_group
->id
, subgrp
->id
,
1280 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1286 /* Do not send back route to sender. */
1287 if (onlypeer
&& from
== onlypeer
)
1292 /* Do not send the default route in the BGP table if the neighbor is
1293 * configured for default-originate */
1294 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1296 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1298 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1302 /* Transparency check. */
1303 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1304 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1309 /* If community is not disabled check the no-export and local. */
1310 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1312 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1313 zlog_debug ("subgrpannouncecheck: community filter check fail");
1317 /* If the attribute has originator-id and it is same as remote
1320 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1321 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1323 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1324 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1326 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1330 /* ORF prefix-list filter check */
1331 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1332 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1333 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1334 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1335 if (peer
->orf_plist
[afi
][safi
])
1337 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1339 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1340 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1341 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1346 /* Output filter check. */
1347 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1349 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1350 zlog_debug ("%s [Update:SEND] %s is filtered",
1351 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1355 #ifdef BGP_SEND_ASPATH_CHECK
1356 /* AS path loop check. */
1357 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1359 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1360 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1361 "that is part of AS path.",
1362 onlypeer
->host
, onlypeer
->as
);
1365 #endif /* BGP_SEND_ASPATH_CHECK */
1367 /* If we're a CONFED we need to loop check the CONFED ID too */
1368 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1370 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1372 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1373 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1381 /* Route-Reflect check. */
1382 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1387 /* IBGP reflection check. */
1388 if (reflect
&& !samepeer_safe
)
1390 /* A route from a Client peer. */
1391 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1393 /* Reflect to all the Non-Client peers and also to the
1394 Client peers other than the originator. Originator check
1395 is already done. So there is noting to do. */
1396 /* no bgp client-to-client reflection check. */
1397 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1398 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1399 PEER_FLAG_REFLECTOR_CLIENT
))
1404 /* A route from a Non-client peer. Reflect to all other
1406 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1407 PEER_FLAG_REFLECTOR_CLIENT
))
1412 /* For modify attribute, copy it to temporary structure. */
1413 bgp_attr_dup (attr
, riattr
);
1415 /* If local-preference is not set. */
1416 if ((peer
->sort
== BGP_PEER_IBGP
1417 || peer
->sort
== BGP_PEER_CONFED
)
1418 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1420 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1421 attr
->local_pref
= bgp
->default_local_pref
;
1424 /* If originator-id is not set and the route is to be reflected,
1425 set the originator id */
1426 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1428 attr
->extra
= bgp_attr_extra_get(attr
);
1429 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1430 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1433 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1434 if (peer
->sort
== BGP_PEER_EBGP
1435 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1437 if (from
!= bgp
->peer_self
&& ! transparent
1438 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1439 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1442 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1443 * in announce check, only certain flags and length (or number of nexthops
1444 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1445 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1446 * Typically, the source nexthop in the attribute is preserved but in the
1447 * scenarios where we know it will always be overwritten, we reset the
1448 * nexthop to "0" in an attempt to achieve better Update packing. An
1449 * example of this is when a prefix from each of 2 IBGP peers needs to be
1450 * announced to an EBGP peer (and they have the same attributes barring
1454 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1456 #define NEXTHOP_IS_V6 (\
1457 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1458 (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) || \
1459 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1460 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1462 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1463 * the peer (group) is configured to receive link-local nexthop unchanged
1464 * and it is available in the prefix OR we're not reflecting the route and
1465 * the peer (group) to whom we're going to announce is on a shared network
1466 * and this is either a self-originated route or the peer is EBGP.
1470 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1471 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1472 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1473 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1474 (!reflect
&& peer
->shared_network
&&
1475 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1477 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1480 /* Clear off link-local nexthop in source, whenever it is not needed to
1481 * ensure more prefixes share the same attribute for announcement.
1483 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1484 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1485 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1488 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1489 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1491 /* Route map & unsuppress-map apply. */
1492 if (ROUTE_MAP_OUT_NAME (filter
)
1493 || (ri
->extra
&& ri
->extra
->suppress
) )
1495 struct bgp_info info
;
1496 struct attr dummy_attr
;
1497 struct attr_extra dummy_extra
;
1499 dummy_attr
.extra
= &dummy_extra
;
1503 /* don't confuse inbound and outbound setting */
1504 RESET_FLAG(attr
->rmap_change_flags
);
1507 * The route reflector is not allowed to modify the attributes
1508 * of the reflected IBGP routes unless explicitly allowed.
1510 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1511 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1513 bgp_attr_dup (&dummy_attr
, attr
);
1514 info
.attr
= &dummy_attr
;
1517 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1519 if (ri
->extra
&& ri
->extra
->suppress
)
1520 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1522 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1524 peer
->rmap_type
= 0;
1526 if (ret
== RMAP_DENYMATCH
)
1528 bgp_attr_flush (attr
);
1533 /* After route-map has been applied, we check to see if the nexthop to
1534 * be carried in the attribute (that is used for the announcement) can
1535 * be cleared off or not. We do this in all cases where we would be
1536 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1537 * the global nexthop here; the link-local nexthop would have been cleared
1538 * already, and if not, it is required by the update formation code.
1539 * Also see earlier comments in this function.
1542 * If route-map has performed some operation on the nexthop or the peer
1543 * configuration says to pass it unchanged, we cannot reset the nexthop
1544 * here, so only attempt to do it if these aren't true. Note that the
1545 * route-map handler itself might have cleared the nexthop, if for example,
1546 * it is configured as 'peer-address'.
1548 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1549 riattr
->rmap_change_flags
) &&
1551 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1553 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1554 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1555 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1558 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1559 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1560 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ?
1561 AF_INET6
: p
->family
), attr
);
1563 else if (peer
->sort
== BGP_PEER_EBGP
)
1565 /* Can also reset the nexthop if announcing to EBGP, but only if
1566 * no peer in the subgroup is on a shared subnet.
1567 * Note: 3rd party nexthop currently implemented for IPv4 only.
1569 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1571 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1575 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ? AF_INET6
: p
->family
), attr
);
1577 /* If IPv6/MP and nexthop does not have any override and happens to
1578 * be a link-local address, reset it so that we don't pass along the
1579 * source's link-local IPv6 address to recipients who may not be on
1580 * the same interface.
1582 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
))
1584 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1585 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1592 struct bgp_info_pair
1594 struct bgp_info
*old
;
1595 struct bgp_info
*new;
1599 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1600 struct bgp_maxpaths_cfg
*mpath_cfg
,
1601 struct bgp_info_pair
*result
)
1603 struct bgp_info
*new_select
;
1604 struct bgp_info
*old_select
;
1605 struct bgp_info
*ri
;
1606 struct bgp_info
*ri1
;
1607 struct bgp_info
*ri2
;
1608 struct bgp_info
*nextri
= NULL
;
1609 int paths_eq
, do_mpath
, debug
;
1610 struct list mp_list
;
1611 char pfx_buf
[PREFIX2STR_BUFFER
];
1612 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1614 bgp_mp_list_init (&mp_list
);
1615 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1617 debug
= bgp_debug_bestpath(&rn
->p
);
1620 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1622 /* bgp deterministic-med */
1624 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1627 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1628 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1629 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1631 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1633 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1635 if (BGP_INFO_HOLDDOWN (ri1
))
1637 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1638 if (ri1
->peer
->status
!= Established
)
1644 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1646 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1648 if (BGP_INFO_HOLDDOWN (ri2
))
1651 ri2
->peer
!= bgp
->peer_self
&&
1652 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1653 if (ri2
->peer
->status
!= Established
)
1656 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1657 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1660 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1661 mpath_cfg
, debug
, pfx_buf
))
1663 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1667 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1671 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1672 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1676 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1677 zlog_debug("%s: %s is the bestpath from AS %d",
1678 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1683 /* Check old selected route and new selected route. */
1686 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1688 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1691 if (BGP_INFO_HOLDDOWN (ri
))
1693 /* reap REMOVED routes, if needs be
1694 * selected route must stay for a while longer though
1696 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1697 && (ri
!= old_select
))
1698 bgp_info_reap (rn
, ri
);
1704 ri
->peer
!= bgp
->peer_self
&&
1705 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1706 if (ri
->peer
->status
!= Established
)
1709 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1710 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1712 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1716 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1718 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1724 /* Now that we know which path is the bestpath see if any of the other paths
1725 * qualify as multipaths
1730 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1732 sprintf (path_buf
, "NONE");
1733 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1735 old_select
? old_select
->peer
->host
: "NONE");
1738 if (do_mpath
&& new_select
)
1740 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1744 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1746 if (ri
== new_select
)
1749 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1751 bgp_mp_list_add (&mp_list
, ri
);
1755 if (BGP_INFO_HOLDDOWN (ri
))
1759 ri
->peer
!= bgp
->peer_self
&&
1760 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1761 if (ri
->peer
->status
!= Established
)
1764 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1767 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1772 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1777 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1779 bgp_mp_list_add (&mp_list
, ri
);
1784 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1785 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1786 bgp_mp_list_clear (&mp_list
);
1788 result
->old
= old_select
;
1789 result
->new = new_select
;
1795 * A new route/change in bestpath of an existing route. Evaluate the path
1796 * for advertisement to the subgroup.
1799 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1800 struct bgp_info
*selected
,
1801 struct bgp_node
*rn
,
1802 u_int32_t addpath_tx_id
)
1805 struct peer
*onlypeer
;
1807 struct attr_extra extra
;
1812 afi
= SUBGRP_AFI(subgrp
);
1813 safi
= SUBGRP_SAFI(subgrp
);
1814 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1815 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1817 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1818 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1819 PEER_STATUS_ORF_WAIT_REFRESH
))
1822 memset(&extra
, 0, sizeof(struct attr_extra
));
1823 /* It's initialized in bgp_announce_check() */
1824 attr
.extra
= &extra
;
1826 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1829 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1830 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1832 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1835 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1838 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1845 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1846 * This is called at the end of route processing.
1849 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1851 struct bgp_info
*ri
;
1853 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1855 if (BGP_INFO_HOLDDOWN (ri
))
1857 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1858 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1863 * Has the route changed from the RIB's perspective? This is invoked only
1864 * if the route selection returns the same best route as earlier - to
1865 * determine if we need to update zebra or not.
1868 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1870 struct bgp_info
*mpinfo
;
1872 /* If this is multipath, check all selected paths for any nexthop change or
1873 * attribute change. Some attribute changes (e.g., community) aren't of
1874 * relevance to the RIB, but we'll update zebra to ensure we handle the
1875 * case of BGP nexthop change. This is the behavior when the best path has
1876 * an attribute change anyway.
1878 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1879 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1882 /* If this is multipath, check all selected paths for any nexthop change */
1883 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1884 mpinfo
= bgp_info_mpath_next (mpinfo
))
1886 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1887 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1891 /* Nothing has changed from the RIB's perspective. */
1895 struct bgp_process_queue
1898 struct bgp_node
*rn
;
1903 static wq_item_status
1904 bgp_process_main (struct work_queue
*wq
, void *data
)
1906 struct bgp_process_queue
*pq
= data
;
1907 struct bgp
*bgp
= pq
->bgp
;
1908 struct bgp_node
*rn
= pq
->rn
;
1909 afi_t afi
= pq
->afi
;
1910 safi_t safi
= pq
->safi
;
1911 struct prefix
*p
= &rn
->p
;
1912 struct bgp_info
*new_select
;
1913 struct bgp_info
*old_select
;
1914 struct bgp_info_pair old_and_new
;
1916 /* Is it end of initial update? (after startup) */
1919 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1920 sizeof(bgp
->update_delay_zebra_resume_time
));
1922 bgp
->main_zebra_update_hold
= 0;
1923 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1924 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1926 bgp_zebra_announce_table(bgp
, afi
, safi
);
1928 bgp
->main_peers_update_hold
= 0;
1930 bgp_start_routeadv(bgp
);
1934 /* Best path selection. */
1935 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1936 old_select
= old_and_new
.old
;
1937 new_select
= old_and_new
.new;
1939 /* Do we need to allocate or free labels?
1940 * Right now, since we only deal with per-prefix labels, it is not necessary
1941 * to do this upon changes to best path except of the label index changes.
1943 if (safi
== SAFI_LABELED_UNICAST
)
1945 bgp_table_lock (bgp_node_table (rn
));
1949 bgp_label_index_differs (new_select
, old_select
) ||
1950 new_select
->sub_type
!= old_select
->sub_type
)
1952 if (new_select
->sub_type
== BGP_ROUTE_STATIC
&&
1953 new_select
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
) &&
1954 new_select
->attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
1956 if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1957 bgp_unregister_for_label (rn
);
1958 label_ntop (MPLS_IMP_NULL_LABEL
, 1, rn
->local_label
);
1959 bgp_set_valid_label(rn
->local_label
);
1962 bgp_register_for_label (rn
, new_select
);
1965 else if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1966 bgp_unregister_for_label (rn
);
1969 /* If best route remains the same and this is not due to user-initiated
1970 * clear, see exactly what needs to be done.
1973 if (old_select
&& old_select
== new_select
&&
1974 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1975 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1976 !bgp
->addpath_tx_used
[afi
][safi
])
1978 if (bgp_zebra_has_route_changed (rn
, old_select
))
1981 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1982 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1984 if (bgp_fibupd_safi(safi
) &&
1986 !bgp_option_check (BGP_OPT_NO_FIB
) &&
1987 new_select
->type
== ZEBRA_ROUTE_BGP
&&
1988 new_select
->sub_type
== BGP_ROUTE_NORMAL
)
1989 bgp_zebra_announce (rn
, p
, old_select
, bgp
, afi
, safi
);
1991 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1992 bgp_zebra_clear_route_change_flags (rn
);
1994 /* If there is a change of interest to peers, reannounce the route. */
1995 if (CHECK_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
) ||
1996 CHECK_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
))
1998 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2000 UNSET_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2001 UNSET_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2004 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2008 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
2009 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2011 /* bestpath has changed; bump version */
2012 if (old_select
|| new_select
)
2014 bgp_bump_version(rn
);
2016 if (!bgp
->t_rmap_def_originate_eval
)
2019 thread_add_timer(bm
->master
,
2020 update_group_refresh_default_originate_route_map
,
2021 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2022 &bgp
->t_rmap_def_originate_eval
);
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
))
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 if (peer
->status
!= Established
)
3094 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3097 peer_af_announce_route (paf
, 1);
3102 * bgp_announce_route
3104 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3107 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3109 struct peer_af
*paf
;
3110 struct update_subgroup
*subgrp
;
3112 paf
= peer_af_find (peer
, afi
, safi
);
3115 subgrp
= PAF_SUBGRP(paf
);
3118 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3119 * or a refresh has already been triggered.
3121 if (!subgrp
|| paf
->t_announce_route
)
3125 * Start a timer to stagger/delay the announce. This serves
3126 * two purposes - announcement can potentially be combined for
3127 * multiple peers and the announcement doesn't happen in the
3130 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3131 (subgrp
->peer_count
== 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
: BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3132 &paf
->t_announce_route
);
3136 * Announce routes from all AF tables to a peer.
3138 * This should ONLY be called when there is a need to refresh the
3139 * routes to the peer based on a policy change for this peer alone
3140 * or a route refresh request received from the peer.
3141 * The operation will result in splitting the peer from its existing
3142 * subgroups and putting it in new subgroups.
3145 bgp_announce_route_all (struct peer
*peer
)
3150 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3151 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3152 bgp_announce_route (peer
, afi
, safi
);
3156 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3157 struct bgp_table
*table
, struct prefix_rd
*prd
)
3160 struct bgp_node
*rn
;
3161 struct bgp_adj_in
*ain
;
3164 table
= peer
->bgp
->rib
[afi
][safi
];
3166 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3167 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3169 if (ain
->peer
== peer
)
3171 struct bgp_info
*ri
= rn
->info
;
3172 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3174 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3175 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3180 bgp_unlock_node (rn
);
3188 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3190 struct bgp_node
*rn
;
3191 struct bgp_table
*table
;
3193 if (peer
->status
!= Established
)
3196 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3197 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3199 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3200 rn
= bgp_route_next (rn
))
3201 if ((table
= rn
->info
) != NULL
)
3203 struct prefix_rd prd
;
3204 prd
.family
= AF_UNSPEC
;
3206 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3208 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3213 struct bgp_clear_node_queue
3215 struct bgp_node
*rn
;
3218 static wq_item_status
3219 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3221 struct bgp_clear_node_queue
*cnq
= data
;
3222 struct bgp_node
*rn
= cnq
->rn
;
3223 struct peer
*peer
= wq
->spec
.data
;
3224 struct bgp_info
*ri
;
3225 afi_t afi
= bgp_node_table (rn
)->afi
;
3226 safi_t safi
= bgp_node_table (rn
)->safi
;
3228 assert (rn
&& peer
);
3230 /* It is possible that we have multiple paths for a prefix from a peer
3231 * if that peer is using AddPath.
3233 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3234 if (ri
->peer
== peer
)
3236 /* graceful restart STALE flag set. */
3237 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3238 && peer
->nsf
[afi
][safi
]
3239 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3240 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3241 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3243 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3249 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3251 struct bgp_clear_node_queue
*cnq
= data
;
3252 struct bgp_node
*rn
= cnq
->rn
;
3253 struct bgp_table
*table
= bgp_node_table (rn
);
3255 bgp_unlock_node (rn
);
3256 bgp_table_unlock (table
);
3257 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3261 bgp_clear_node_complete (struct work_queue
*wq
)
3263 struct peer
*peer
= wq
->spec
.data
;
3265 /* Tickle FSM to start moving again */
3266 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3268 peer_unlock (peer
); /* bgp_clear_route */
3272 bgp_clear_node_queue_init (struct peer
*peer
)
3274 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3276 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3277 #undef CLEAR_QUEUE_NAME_LEN
3279 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3281 zlog_err ("%s: Failed to allocate work queue", __func__
);
3284 peer
->clear_node_queue
->spec
.hold
= 10;
3285 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3286 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3287 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3288 peer
->clear_node_queue
->spec
.max_retries
= 0;
3290 /* we only 'lock' this peer reference when the queue is actually active */
3291 peer
->clear_node_queue
->spec
.data
= peer
;
3295 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3296 struct bgp_table
*table
)
3298 struct bgp_node
*rn
;
3299 int force
= bm
->process_main_queue
? 0 : 1;
3302 table
= peer
->bgp
->rib
[afi
][safi
];
3304 /* If still no table => afi/safi isn't configured at all or smth. */
3308 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3310 struct bgp_info
*ri
, *next
;
3311 struct bgp_adj_in
*ain
;
3312 struct bgp_adj_in
*ain_next
;
3314 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3315 * queued for every clearing peer, regardless of whether it is
3316 * relevant to the peer at hand.
3318 * Overview: There are 3 different indices which need to be
3319 * scrubbed, potentially, when a peer is removed:
3321 * 1 peer's routes visible via the RIB (ie accepted routes)
3322 * 2 peer's routes visible by the (optional) peer's adj-in index
3323 * 3 other routes visible by the peer's adj-out index
3325 * 3 there is no hurry in scrubbing, once the struct peer is
3326 * removed from bgp->peer, we could just GC such deleted peer's
3327 * adj-outs at our leisure.
3329 * 1 and 2 must be 'scrubbed' in some way, at least made
3330 * invisible via RIB index before peer session is allowed to be
3331 * brought back up. So one needs to know when such a 'search' is
3336 * - there'd be a single global queue or a single RIB walker
3337 * - rather than tracking which route_nodes still need to be
3338 * examined on a peer basis, we'd track which peers still
3341 * Given that our per-peer prefix-counts now should be reliable,
3342 * this may actually be achievable. It doesn't seem to be a huge
3343 * problem at this time,
3345 * It is possible that we have multiple paths for a prefix from a peer
3346 * if that peer is using AddPath.
3351 ain_next
= ain
->next
;
3353 if (ain
->peer
== peer
)
3355 bgp_adj_in_remove (rn
, ain
);
3356 bgp_unlock_node (rn
);
3362 for (ri
= rn
->info
; ri
; ri
= next
)
3365 if (ri
->peer
!= peer
)
3369 bgp_info_reap (rn
, ri
);
3372 struct bgp_clear_node_queue
*cnq
;
3374 /* both unlocked in bgp_clear_node_queue_del */
3375 bgp_table_lock (bgp_node_table (rn
));
3377 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3378 sizeof (struct bgp_clear_node_queue
));
3380 work_queue_add (peer
->clear_node_queue
, cnq
);
3389 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3391 struct bgp_node
*rn
;
3392 struct bgp_table
*table
;
3394 if (peer
->clear_node_queue
== NULL
)
3395 bgp_clear_node_queue_init (peer
);
3397 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3398 * Idle until it receives a Clearing_Completed event. This protects
3399 * against peers which flap faster than we can we clear, which could
3402 * a) race with routes from the new session being installed before
3403 * clear_route_node visits the node (to delete the route of that
3405 * b) resource exhaustion, clear_route_node likely leads to an entry
3406 * on the process_main queue. Fast-flapping could cause that queue
3410 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3411 * the unlock will happen upon work-queue completion; other wise, the
3412 * unlock happens at the end of this function.
3414 if (!peer
->clear_node_queue
->thread
)
3417 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3418 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3420 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3421 rn
= bgp_route_next (rn
))
3422 if ((table
= rn
->info
) != NULL
)
3423 bgp_clear_route_table (peer
, afi
, safi
, table
);
3425 /* unlock if no nodes got added to the clear-node-queue. */
3426 if (!peer
->clear_node_queue
->thread
)
3432 bgp_clear_route_all (struct peer
*peer
)
3437 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3438 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3439 bgp_clear_route (peer
, afi
, safi
);
3442 rfapiProcessPeerDown(peer
);
3447 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3449 struct bgp_table
*table
;
3450 struct bgp_node
*rn
;
3451 struct bgp_adj_in
*ain
;
3452 struct bgp_adj_in
*ain_next
;
3454 table
= peer
->bgp
->rib
[afi
][safi
];
3456 /* It is possible that we have multiple paths for a prefix from a peer
3457 * if that peer is using AddPath.
3459 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3465 ain_next
= ain
->next
;
3467 if (ain
->peer
== peer
)
3469 bgp_adj_in_remove (rn
, ain
);
3470 bgp_unlock_node (rn
);
3479 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3481 struct bgp_node
*rn
;
3482 struct bgp_info
*ri
;
3483 struct bgp_table
*table
;
3485 if ( safi
== SAFI_MPLS_VPN
)
3487 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3489 struct bgp_node
*rm
;
3490 struct bgp_info
*ri
;
3492 /* look for neighbor in tables */
3493 if ((table
= rn
->info
) != NULL
)
3495 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3496 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3497 if (ri
->peer
== peer
)
3499 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3500 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3508 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3509 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3510 if (ri
->peer
== peer
)
3512 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3513 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3520 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3522 struct bgp_node
*rn
;
3523 struct bgp_info
*ri
;
3524 struct bgp_info
*next
;
3526 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3527 for (ri
= rn
->info
; ri
; ri
= next
)
3530 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3531 && ri
->type
== ZEBRA_ROUTE_BGP
3532 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3533 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3536 if (table
->owner
&& table
->owner
->bgp
)
3537 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3539 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3540 bgp_info_reap (rn
, ri
);
3545 /* Delete all kernel routes. */
3547 bgp_cleanup_routes (struct bgp
*bgp
)
3550 struct bgp_node
*rn
;
3552 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3554 if (afi
== AFI_L2VPN
)
3556 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3558 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3560 if (afi
!= AFI_L2VPN
)
3563 safi
= SAFI_MPLS_VPN
;
3564 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3565 rn
= bgp_route_next (rn
))
3569 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3570 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3572 bgp_unlock_node(rn
);
3576 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3577 rn
= bgp_route_next (rn
))
3581 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3582 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3584 bgp_unlock_node(rn
);
3589 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3590 rn
= bgp_route_next (rn
))
3594 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3595 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3597 bgp_unlock_node(rn
);
3606 bgp_zclient_reset ();
3607 access_list_reset ();
3608 prefix_list_reset ();
3612 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3614 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3615 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3618 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3621 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3622 struct bgp_nlri
*packet
)
3631 int addpath_encoded
;
3632 u_int32_t addpath_id
;
3634 /* Check peer status. */
3635 if (peer
->status
!= Established
)
3639 lim
= pnt
+ packet
->length
;
3641 safi
= packet
->safi
;
3643 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3645 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3646 syntactic validity. If the field is syntactically incorrect,
3647 then the Error Subcode is set to Invalid Network Field. */
3648 for (; pnt
< lim
; pnt
+= psize
)
3650 /* Clear prefix structure. */
3651 memset (&p
, 0, sizeof (struct prefix
));
3653 if (addpath_encoded
)
3656 /* When packet overflow occurs return immediately. */
3657 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3660 addpath_id
= ntohl(*((uint32_t*) pnt
));
3661 pnt
+= BGP_ADDPATH_ID_LEN
;
3664 /* Fetch prefix length. */
3665 p
.prefixlen
= *pnt
++;
3666 /* afi/safi validity already verified by caller, bgp_update_receive */
3667 p
.family
= afi2family (afi
);
3669 /* Prefix length check. */
3670 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3672 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3673 peer
->host
, p
.prefixlen
, packet
->afi
);
3677 /* Packet size overflow check. */
3678 psize
= PSIZE (p
.prefixlen
);
3680 /* When packet overflow occur return immediately. */
3681 if (pnt
+ psize
> lim
)
3683 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3684 peer
->host
, p
.prefixlen
);
3688 /* Defensive coding, double-check the psize fits in a struct prefix */
3689 if (psize
> (ssize_t
) sizeof(p
.u
))
3691 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3692 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3696 /* Fetch prefix from NLRI packet. */
3697 memcpy (&p
.u
.prefix
, pnt
, psize
);
3699 /* Check address. */
3700 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3702 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3704 /* From RFC4271 Section 6.3:
3706 * If a prefix in the NLRI field is semantically incorrect
3707 * (e.g., an unexpected multicast IP address), an error SHOULD
3708 * be logged locally, and the prefix SHOULD be ignored.
3710 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3711 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3716 /* Check address. */
3717 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3719 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3723 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3724 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3728 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3732 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3733 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3739 /* Normal process. */
3741 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3742 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3744 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3745 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3747 /* Address family configuration mismatch or maximum-prefix count
3753 /* Packet length consistency check. */
3756 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3764 static struct bgp_static
*
3765 bgp_static_new (void)
3767 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3771 bgp_static_free (struct bgp_static
*bgp_static
)
3773 if (bgp_static
->rmap
.name
)
3774 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3775 if(bgp_static
->eth_s_id
)
3776 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3777 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3781 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3782 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3784 struct bgp_node
*rn
;
3785 struct bgp_info
*ri
;
3786 struct bgp_info
*new;
3787 struct bgp_info info
;
3789 struct attr
*attr_new
;
3792 int vnc_implicit_withdraw
= 0;
3795 assert (bgp_static
);
3799 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3801 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3803 attr
.nexthop
= bgp_static
->igpnexthop
;
3804 attr
.med
= bgp_static
->igpmetric
;
3805 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3807 if (bgp_static
->atomic
)
3808 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3810 /* Store label index, if required. */
3811 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3813 (bgp_attr_extra_get (&attr
))->label_index
= bgp_static
->label_index
;
3814 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3817 /* Apply route-map. */
3818 if (bgp_static
->rmap
.name
)
3820 struct attr attr_tmp
= attr
;
3821 info
.peer
= bgp
->peer_self
;
3822 info
.attr
= &attr_tmp
;
3824 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3826 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3828 bgp
->peer_self
->rmap_type
= 0;
3830 if (ret
== RMAP_DENYMATCH
)
3832 /* Free uninterned attribute. */
3833 bgp_attr_flush (&attr_tmp
);
3835 /* Unintern original. */
3836 aspath_unintern (&attr
.aspath
);
3837 bgp_attr_extra_free (&attr
);
3838 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3841 attr_new
= bgp_attr_intern (&attr_tmp
);
3844 attr_new
= bgp_attr_intern (&attr
);
3846 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3847 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3848 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3853 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3854 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3855 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3857 bgp_unlock_node (rn
);
3858 bgp_attr_unintern (&attr_new
);
3859 aspath_unintern (&attr
.aspath
);
3860 bgp_attr_extra_free (&attr
);
3865 /* The attribute is changed. */
3866 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3868 /* Rewrite BGP route information. */
3869 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3870 bgp_info_restore(rn
, ri
);
3872 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3874 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3876 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3879 * Implicit withdraw case.
3880 * We have to do this before ri is changed
3882 ++vnc_implicit_withdraw
;
3883 vnc_import_bgp_del_route(bgp
, p
, ri
);
3884 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3888 bgp_attr_unintern (&ri
->attr
);
3889 ri
->attr
= attr_new
;
3890 ri
->uptime
= bgp_clock ();
3892 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3894 if (vnc_implicit_withdraw
)
3896 vnc_import_bgp_add_route(bgp
, p
, ri
);
3897 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3902 /* Nexthop reachability check. */
3903 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3904 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3906 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3907 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3910 if (BGP_DEBUG(nht
, NHT
))
3912 char buf1
[INET6_ADDRSTRLEN
];
3913 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3915 zlog_debug("%s(%s): Route not in table, not advertising",
3916 __FUNCTION__
, buf1
);
3918 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3923 /* Delete the NHT structure if any, if we're toggling between
3924 * enabling/disabling import check. We deregister the route
3925 * from NHT to avoid overloading NHT and the process interaction
3927 bgp_unlink_nexthop(ri
);
3928 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3930 /* Process change. */
3931 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3932 bgp_process (bgp
, rn
, afi
, safi
);
3933 bgp_unlock_node (rn
);
3934 aspath_unintern (&attr
.aspath
);
3935 bgp_attr_extra_free (&attr
);
3940 /* Make new BGP info. */
3941 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3943 /* Nexthop reachability check. */
3944 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3945 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3947 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3948 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3951 if (BGP_DEBUG(nht
, NHT
))
3953 char buf1
[INET6_ADDRSTRLEN
];
3954 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3956 zlog_debug("%s(%s): Route not in table, not advertising",
3957 __FUNCTION__
, buf1
);
3959 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3964 /* Delete the NHT structure if any, if we're toggling between
3965 * enabling/disabling import check. We deregister the route
3966 * from NHT to avoid overloading NHT and the process interaction
3968 bgp_unlink_nexthop(new);
3970 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3973 /* Aggregate address increment. */
3974 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3976 /* Register new BGP information. */
3977 bgp_info_add (rn
, new);
3979 /* route_node_get lock */
3980 bgp_unlock_node (rn
);
3982 /* Process change. */
3983 bgp_process (bgp
, rn
, afi
, safi
);
3985 /* Unintern original. */
3986 aspath_unintern (&attr
.aspath
);
3987 bgp_attr_extra_free (&attr
);
3991 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3994 struct bgp_node
*rn
;
3995 struct bgp_info
*ri
;
3997 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3999 /* Check selected route and self inserted route. */
4000 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4001 if (ri
->peer
== bgp
->peer_self
4002 && ri
->type
== ZEBRA_ROUTE_BGP
4003 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4006 /* Withdraw static BGP route from routing table. */
4009 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4010 bgp_unlink_nexthop(ri
);
4011 bgp_info_delete (rn
, ri
);
4012 bgp_process (bgp
, rn
, afi
, safi
);
4015 /* Unlock bgp_node_lookup. */
4016 bgp_unlock_node (rn
);
4020 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4023 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4024 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
4026 struct bgp_node
*rn
;
4027 struct bgp_info
*ri
;
4029 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4031 /* Check selected route and self inserted route. */
4032 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4033 if (ri
->peer
== bgp
->peer_self
4034 && ri
->type
== ZEBRA_ROUTE_BGP
4035 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4038 /* Withdraw static BGP route from routing table. */
4042 rfapiProcessWithdraw(
4051 1); /* Kill, since it is an administrative change */
4053 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4054 bgp_info_delete (rn
, ri
);
4055 bgp_process (bgp
, rn
, afi
, safi
);
4058 /* Unlock bgp_node_lookup. */
4059 bgp_unlock_node (rn
);
4063 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4064 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4066 struct bgp_node
*rn
;
4067 struct bgp_info
*new;
4068 struct attr
*attr_new
;
4069 struct attr attr
= { 0 };
4070 struct bgp_info
*ri
;
4072 u_int32_t label
= 0;
4076 assert (bgp_static
);
4078 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4080 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4082 attr
.nexthop
= bgp_static
->igpnexthop
;
4083 attr
.med
= bgp_static
->igpmetric
;
4084 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4086 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4090 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4091 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4094 if(afi
== AFI_L2VPN
)
4096 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4097 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4098 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4099 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4100 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4101 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4103 struct bgp_encap_type_vxlan bet
;
4104 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4105 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4106 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4108 if (bgp_static
->router_mac
)
4110 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4113 /* Apply route-map. */
4114 if (bgp_static
->rmap
.name
)
4116 struct attr attr_tmp
= attr
;
4117 struct bgp_info info
;
4120 info
.peer
= bgp
->peer_self
;
4121 info
.attr
= &attr_tmp
;
4123 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4125 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4127 bgp
->peer_self
->rmap_type
= 0;
4129 if (ret
== RMAP_DENYMATCH
)
4131 /* Free uninterned attribute. */
4132 bgp_attr_flush (&attr_tmp
);
4134 /* Unintern original. */
4135 aspath_unintern (&attr
.aspath
);
4136 bgp_attr_extra_free (&attr
);
4137 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4142 attr_new
= bgp_attr_intern (&attr_tmp
);
4146 attr_new
= bgp_attr_intern (&attr
);
4149 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4150 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4151 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4157 memset(&add
, 0, sizeof(union gw_addr
));
4158 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4159 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4160 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4162 bgp_unlock_node (rn
);
4163 bgp_attr_unintern (&attr_new
);
4164 aspath_unintern (&attr
.aspath
);
4165 bgp_attr_extra_free (&attr
);
4170 /* The attribute is changed. */
4171 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4173 /* Rewrite BGP route information. */
4174 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4175 bgp_info_restore(rn
, ri
);
4177 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4178 bgp_attr_unintern (&ri
->attr
);
4179 ri
->attr
= attr_new
;
4180 ri
->uptime
= bgp_clock ();
4183 label
= decode_label (ri
->extra
->tag
);
4186 /* Process change. */
4187 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4188 bgp_process (bgp
, rn
, afi
, safi
);
4190 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4191 ri
->attr
, afi
, safi
,
4192 ri
->type
, ri
->sub_type
, &label
);
4194 bgp_unlock_node (rn
);
4195 aspath_unintern (&attr
.aspath
);
4196 bgp_attr_extra_free (&attr
);
4202 /* Make new BGP info. */
4203 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4205 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4206 new->extra
= bgp_info_extra_new();
4207 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4209 label
= decode_label (bgp_static
->tag
);
4212 /* Aggregate address increment. */
4213 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4215 /* Register new BGP information. */
4216 bgp_info_add (rn
, new);
4217 /* route_node_get lock */
4218 bgp_unlock_node (rn
);
4220 /* Process change. */
4221 bgp_process (bgp
, rn
, afi
, safi
);
4224 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4225 new->attr
, afi
, safi
,
4226 new->type
, new->sub_type
, &label
);
4229 /* Unintern original. */
4230 aspath_unintern (&attr
.aspath
);
4231 bgp_attr_extra_free (&attr
);
4234 /* Configure static BGP network. When user don't run zebra, static
4235 route should be installed as valid. */
4237 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4238 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4239 u_int32_t label_index
)
4241 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4244 struct bgp_static
*bgp_static
;
4245 struct bgp_node
*rn
;
4246 u_char need_update
= 0;
4248 /* Convert IP prefix string to struct prefix. */
4249 ret
= str2prefix (ip_str
, &p
);
4252 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4255 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4257 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4264 /* Set BGP static route configuration. */
4265 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4269 /* Configuration change. */
4270 bgp_static
= rn
->info
;
4272 /* Label index cannot be changed. */
4273 if (bgp_static
->label_index
!= label_index
)
4275 vty_out (vty
, "%% Label index cannot be changed%s", VTY_NEWLINE
);
4279 /* Check previous routes are installed into BGP. */
4280 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4283 bgp_static
->backdoor
= backdoor
;
4287 if (bgp_static
->rmap
.name
)
4288 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4289 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4290 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4294 if (bgp_static
->rmap
.name
)
4295 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4296 bgp_static
->rmap
.name
= NULL
;
4297 bgp_static
->rmap
.map
= NULL
;
4298 bgp_static
->valid
= 0;
4300 bgp_unlock_node (rn
);
4304 /* New configuration. */
4305 bgp_static
= bgp_static_new ();
4306 bgp_static
->backdoor
= backdoor
;
4307 bgp_static
->valid
= 0;
4308 bgp_static
->igpmetric
= 0;
4309 bgp_static
->igpnexthop
.s_addr
= 0;
4310 bgp_static
->label_index
= label_index
;
4314 if (bgp_static
->rmap
.name
)
4315 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4316 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4317 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4319 rn
->info
= bgp_static
;
4322 bgp_static
->valid
= 1;
4324 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4326 if (! bgp_static
->backdoor
)
4327 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4332 /* Configure static BGP network. */
4334 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4335 afi_t afi
, safi_t safi
)
4337 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4340 struct bgp_static
*bgp_static
;
4341 struct bgp_node
*rn
;
4343 /* Convert IP prefix string to struct prefix. */
4344 ret
= str2prefix (ip_str
, &p
);
4347 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4350 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4352 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4359 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4362 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4367 bgp_static
= rn
->info
;
4369 /* Update BGP RIB. */
4370 if (! bgp_static
->backdoor
)
4371 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4373 /* Clear configuration. */
4374 bgp_static_free (bgp_static
);
4376 bgp_unlock_node (rn
);
4377 bgp_unlock_node (rn
);
4383 bgp_static_add (struct bgp
*bgp
)
4387 struct bgp_node
*rn
;
4388 struct bgp_node
*rm
;
4389 struct bgp_table
*table
;
4390 struct bgp_static
*bgp_static
;
4392 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4393 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4394 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4395 if (rn
->info
!= NULL
)
4397 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4401 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4403 bgp_static
= rm
->info
;
4404 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4409 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4414 /* Called from bgp_delete(). Delete all static routes from the BGP
4417 bgp_static_delete (struct bgp
*bgp
)
4421 struct bgp_node
*rn
;
4422 struct bgp_node
*rm
;
4423 struct bgp_table
*table
;
4424 struct bgp_static
*bgp_static
;
4426 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4427 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4428 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4429 if (rn
->info
!= NULL
)
4431 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4435 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4437 bgp_static
= rm
->info
;
4438 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4440 (struct prefix_rd
*)&rn
->p
,
4442 bgp_static_free (bgp_static
);
4444 bgp_unlock_node (rn
);
4449 bgp_static
= rn
->info
;
4450 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4451 bgp_static_free (bgp_static
);
4453 bgp_unlock_node (rn
);
4459 bgp_static_redo_import_check (struct bgp
*bgp
)
4463 struct bgp_node
*rn
;
4464 struct bgp_node
*rm
;
4465 struct bgp_table
*table
;
4466 struct bgp_static
*bgp_static
;
4468 /* Use this flag to force reprocessing of the route */
4469 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4470 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4471 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4472 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4473 if (rn
->info
!= NULL
)
4475 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4479 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4481 bgp_static
= rm
->info
;
4482 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4487 bgp_static
= rn
->info
;
4488 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4491 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4495 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4497 struct bgp_table
*table
;
4498 struct bgp_node
*rn
;
4499 struct bgp_info
*ri
;
4501 table
= bgp
->rib
[afi
][safi
];
4502 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4504 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4506 if (ri
->peer
== bgp
->peer_self
&&
4507 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4508 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4509 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4510 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4512 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4513 bgp_unlink_nexthop(ri
);
4514 bgp_info_delete (rn
, ri
);
4515 bgp_process (bgp
, rn
, afi
, safi
);
4522 * Purge all networks and redistributed routes from routing table.
4523 * Invoked upon the instance going down.
4526 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4531 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4532 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4533 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4538 * Currently this is used to set static routes for VPN and ENCAP.
4539 * I think it can probably be factored with bgp_static_set.
4542 bgp_static_set_safi (afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4543 const char *rd_str
, const char *label_str
,
4544 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4545 const char *ethtag
, const char *routermac
)
4547 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4550 struct prefix_rd prd
;
4551 struct bgp_node
*prn
;
4552 struct bgp_node
*rn
;
4553 struct bgp_table
*table
;
4554 struct bgp_static
*bgp_static
;
4556 struct prefix gw_ip
;
4558 /* validate ip prefix */
4559 ret
= str2prefix (ip_str
, &p
);
4562 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4566 if ( (afi
== AFI_L2VPN
) &&
4567 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4569 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4573 ret
= str2prefix_rd (rd_str
, &prd
);
4576 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4582 unsigned long label_val
;
4583 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, 16777215);
4584 encode_label (label_val
, tag
);
4588 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4590 if (safi
== SAFI_EVPN
)
4592 if( esi
&& str2esi (esi
, NULL
) == 0)
4594 vty_out (vty
, "%% Malformed ESI%s", VTY_NEWLINE
);
4597 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4599 vty_out (vty
, "%% Malformed Router MAC%s", VTY_NEWLINE
);
4604 memset (&gw_ip
, 0, sizeof (struct prefix
));
4605 ret
= str2prefix (gwip
, &gw_ip
);
4608 vty_out (vty
, "%% Malformed GatewayIp%s", VTY_NEWLINE
);
4611 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4612 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4614 vty_out (vty
, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE
);
4619 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4620 (struct prefix
*)&prd
);
4621 if (prn
->info
== NULL
)
4622 prn
->info
= bgp_table_init (afi
, safi
);
4624 bgp_unlock_node (prn
);
4627 rn
= bgp_node_get (table
, &p
);
4631 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4632 bgp_unlock_node (rn
);
4636 /* New configuration. */
4637 bgp_static
= bgp_static_new ();
4638 bgp_static
->backdoor
= 0;
4639 bgp_static
->valid
= 0;
4640 bgp_static
->igpmetric
= 0;
4641 bgp_static
->igpnexthop
.s_addr
= 0;
4642 memcpy(bgp_static
->tag
, tag
, 3);
4643 bgp_static
->prd
= prd
;
4647 if (bgp_static
->rmap
.name
)
4648 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4649 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4650 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4653 if (safi
== SAFI_EVPN
)
4657 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4658 str2esi (esi
, bgp_static
->eth_s_id
);
4662 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4663 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4666 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4668 rn
->info
= bgp_static
;
4670 bgp_static
->valid
= 1;
4671 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4677 /* Configure static BGP network. */
4679 bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4680 const char *rd_str
, const char *label_str
,
4681 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4683 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4686 struct prefix_rd prd
;
4687 struct bgp_node
*prn
;
4688 struct bgp_node
*rn
;
4689 struct bgp_table
*table
;
4690 struct bgp_static
*bgp_static
;
4693 /* Convert IP prefix string to struct prefix. */
4694 ret
= str2prefix (ip_str
, &p
);
4697 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4701 if ( (afi
== AFI_L2VPN
) &&
4702 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4704 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4707 ret
= str2prefix_rd (rd_str
, &prd
);
4710 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4716 unsigned long label_val
;
4717 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, MPLS_LABEL_MAX
);
4718 encode_label (label_val
, tag
);
4722 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4725 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4726 (struct prefix
*)&prd
);
4727 if (prn
->info
== NULL
)
4728 prn
->info
= bgp_table_init (afi
, safi
);
4730 bgp_unlock_node (prn
);
4733 rn
= bgp_node_lookup (table
, &p
);
4737 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
, tag
);
4739 bgp_static
= rn
->info
;
4740 bgp_static_free (bgp_static
);
4742 bgp_unlock_node (rn
);
4743 bgp_unlock_node (rn
);
4746 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4752 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4753 const char *rmap_name
)
4755 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4756 struct bgp_rmap
*rmap
;
4758 rmap
= &bgp
->table_map
[afi
][safi
];
4762 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4763 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4764 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4769 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4774 bgp_zebra_announce_table(bgp
, afi
, safi
);
4780 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4781 const char *rmap_name
)
4783 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4784 struct bgp_rmap
*rmap
;
4786 rmap
= &bgp
->table_map
[afi
][safi
];
4788 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4792 bgp_zebra_announce_table(bgp
, afi
, safi
);
4798 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4799 safi_t safi
, int *write
)
4801 if (bgp
->table_map
[afi
][safi
].name
)
4803 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4804 vty_out (vty
, " table-map %s%s",
4805 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4811 DEFUN (bgp_table_map
,
4814 "BGP table to RIB route download filter\n"
4815 "Name of the route map\n")
4818 return bgp_table_map_set (vty
,
4819 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4821 DEFUN (no_bgp_table_map
,
4822 no_bgp_table_map_cmd
,
4823 "no table-map WORD",
4825 "BGP table to RIB route download filter\n"
4826 "Name of the route map\n")
4829 return bgp_table_map_unset (vty
,
4830 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4835 "network A.B.C.D/M",
4836 "Specify a network to announce via BGP\n"
4839 int idx_ipv4_prefixlen
= 1;
4840 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4841 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4842 BGP_INVALID_LABEL_INDEX
);
4845 DEFUN (bgp_network_route_map
,
4846 bgp_network_route_map_cmd
,
4847 "network A.B.C.D/M route-map WORD",
4848 "Specify a network to announce via BGP\n"
4850 "Route-map to modify the attributes\n"
4851 "Name of the route map\n")
4853 int idx_ipv4_prefixlen
= 1;
4855 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4856 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4857 BGP_INVALID_LABEL_INDEX
);
4860 DEFUN (bgp_network_backdoor
,
4861 bgp_network_backdoor_cmd
,
4862 "network A.B.C.D/M backdoor",
4863 "Specify a network to announce via BGP\n"
4865 "Specify a BGP backdoor route\n")
4867 int idx_ipv4_prefixlen
= 1;
4868 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4869 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4872 DEFUN (bgp_network_mask
,
4873 bgp_network_mask_cmd
,
4874 "network A.B.C.D mask A.B.C.D",
4875 "Specify a network to announce via BGP\n"
4883 char prefix_str
[BUFSIZ
];
4885 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4888 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4892 return bgp_static_set (vty
, prefix_str
,
4893 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
4896 DEFUN (bgp_network_mask_route_map
,
4897 bgp_network_mask_route_map_cmd
,
4898 "network A.B.C.D mask A.B.C.D route-map WORD",
4899 "Specify a network to announce via BGP\n"
4903 "Route-map to modify the attributes\n"
4904 "Name of the route map\n")
4910 char prefix_str
[BUFSIZ
];
4912 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4915 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4919 return bgp_static_set (vty
, prefix_str
,
4920 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
4923 DEFUN (bgp_network_mask_backdoor
,
4924 bgp_network_mask_backdoor_cmd
,
4925 "network A.B.C.D mask A.B.C.D backdoor",
4926 "Specify a network to announce via BGP\n"
4930 "Specify a BGP backdoor route\n")
4935 char prefix_str
[BUFSIZ
];
4937 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4940 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4944 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4946 BGP_INVALID_LABEL_INDEX
);
4949 DEFUN (bgp_network_mask_natural
,
4950 bgp_network_mask_natural_cmd
,
4952 "Specify a network to announce via BGP\n"
4957 char prefix_str
[BUFSIZ
];
4959 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4962 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4966 return bgp_static_set (vty
, prefix_str
,
4967 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4968 BGP_INVALID_LABEL_INDEX
);
4971 DEFUN (bgp_network_mask_natural_route_map
,
4972 bgp_network_mask_natural_route_map_cmd
,
4973 "network A.B.C.D route-map WORD",
4974 "Specify a network to announce via BGP\n"
4976 "Route-map to modify the attributes\n"
4977 "Name of the route map\n")
4982 char prefix_str
[BUFSIZ
];
4984 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4987 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4991 return bgp_static_set (vty
, prefix_str
,
4992 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4993 BGP_INVALID_LABEL_INDEX
);
4996 DEFUN (bgp_network_mask_natural_backdoor
,
4997 bgp_network_mask_natural_backdoor_cmd
,
4998 "network A.B.C.D backdoor",
4999 "Specify a network to announce via BGP\n"
5001 "Specify a BGP backdoor route\n")
5005 char prefix_str
[BUFSIZ
];
5007 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5010 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5014 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5015 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5018 DEFUN (bgp_network_label_index
,
5019 bgp_network_label_index_cmd
,
5020 "network A.B.C.D/M label-index (0-1048560)",
5021 "Specify a network to announce via BGP\n"
5022 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5023 "Label index to associate with the prefix\n"
5024 "Label index value\n")
5026 u_int32_t label_index
;
5028 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5029 return bgp_static_set (vty
, argv
[1]->arg
,
5030 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5033 DEFUN (bgp_network_label_index_route_map
,
5034 bgp_network_label_index_route_map_cmd
,
5035 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5036 "Specify a network to announce via BGP\n"
5038 "Label index to associate with the prefix\n"
5039 "Label index value\n"
5040 "Route-map to modify the attributes\n"
5041 "Name of the route map\n")
5043 u_int32_t label_index
;
5045 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5046 return bgp_static_set (vty
, argv
[1]->arg
,
5047 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5050 DEFUN (no_bgp_network
,
5052 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5054 "Specify a network to announce via BGP\n"
5056 "Specify a BGP backdoor route\n"
5057 "Route-map to modify the attributes\n"
5058 "Name of the route map\n")
5060 int idx_ipv4_prefixlen
= 2;
5061 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5062 bgp_node_safi (vty
));
5065 DEFUN (no_bgp_network_mask
,
5066 no_bgp_network_mask_cmd
,
5067 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5069 "Specify a network to announce via BGP\n"
5073 "Specify a BGP backdoor route\n"
5074 "Route-map to modify the attributes\n"
5075 "Name of the route map\n")
5080 char prefix_str
[BUFSIZ
];
5082 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5085 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5089 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5090 bgp_node_safi (vty
));
5093 DEFUN (no_bgp_network_mask_natural
,
5094 no_bgp_network_mask_natural_cmd
,
5095 "no network A.B.C.D [<backdoor|route-map WORD>]",
5097 "Specify a network to announce via BGP\n"
5099 "Specify a BGP backdoor route\n"
5100 "Route-map to modify the attributes\n"
5101 "Name of the route map\n")
5105 char prefix_str
[BUFSIZ
];
5107 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5110 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5114 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5115 bgp_node_safi (vty
));
5118 ALIAS (no_bgp_network
,
5119 no_bgp_network_label_index_cmd
,
5120 "no network A.B.C.D/M label-index (0-1048560)",
5122 "Specify a network to announce via BGP\n"
5123 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5124 "Label index to associate with the prefix\n"
5125 "Label index value\n")
5127 ALIAS (no_bgp_network
,
5128 no_bgp_network_label_index_route_map_cmd
,
5129 "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
5131 "Specify a network to announce via BGP\n"
5133 "Label index to associate with the prefix\n"
5134 "Label index value\n"
5135 "Route-map to modify the attributes\n"
5136 "Name of the route map\n")
5138 DEFUN (ipv6_bgp_network
,
5139 ipv6_bgp_network_cmd
,
5140 "network X:X::X:X/M",
5141 "Specify a network to announce via BGP\n"
5144 int idx_ipv6_prefixlen
= 1;
5145 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5147 BGP_INVALID_LABEL_INDEX
);
5150 DEFUN (ipv6_bgp_network_route_map
,
5151 ipv6_bgp_network_route_map_cmd
,
5152 "network X:X::X:X/M route-map WORD",
5153 "Specify a network to announce via BGP\n"
5155 "Route-map to modify the attributes\n"
5156 "Name of the route map\n")
5158 int idx_ipv6_prefixlen
= 1;
5160 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5161 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5162 BGP_INVALID_LABEL_INDEX
);
5165 DEFUN (ipv6_bgp_network_label_index
,
5166 ipv6_bgp_network_label_index_cmd
,
5167 "network X:X::X:X/M label-index (0-1048560)",
5168 "Specify a network to announce via BGP\n"
5169 "IPv6 prefix <network>/<length>\n"
5170 "Label index to associate with the prefix\n"
5171 "Label index value\n")
5173 u_int32_t label_index
;
5175 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5176 return bgp_static_set (vty
, argv
[1]->arg
,
5177 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5180 DEFUN (ipv6_bgp_network_label_index_route_map
,
5181 ipv6_bgp_network_label_index_route_map_cmd
,
5182 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5183 "Specify a network to announce via BGP\n"
5185 "Label index to associate with the prefix\n"
5186 "Label index value\n"
5187 "Route-map to modify the attributes\n"
5188 "Name of the route map\n")
5190 u_int32_t label_index
;
5192 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5193 return bgp_static_set (vty
, argv
[1]->arg
,
5194 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5197 DEFUN (no_ipv6_bgp_network
,
5198 no_ipv6_bgp_network_cmd
,
5199 "no network X:X::X:X/M [route-map WORD]",
5201 "Specify a network to announce via BGP\n"
5203 "Route-map to modify the attributes\n"
5204 "Name of the route map\n")
5206 int idx_ipv6_prefixlen
= 2;
5207 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5210 ALIAS (no_ipv6_bgp_network
,
5211 no_ipv6_bgp_network_label_index_cmd
,
5212 "no network X:X::X:X/M label-index (0-1048560)",
5214 "Specify a network to announce via BGP\n"
5215 "IPv6 prefix <network>/<length>\n"
5216 "Label index to associate with the prefix\n"
5217 "Label index value\n")
5219 ALIAS (no_ipv6_bgp_network
,
5220 no_ipv6_bgp_network_label_index_route_map_cmd
,
5221 "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
5223 "Specify a network to announce via BGP\n"
5225 "Label index to associate with the prefix\n"
5226 "Label index value\n"
5227 "Route-map to modify the attributes\n"
5228 "Name of the route map\n")
5230 /* Aggreagete address:
5232 advertise-map Set condition to advertise attribute
5233 as-set Generate AS set path information
5234 attribute-map Set attributes of aggregate
5235 route-map Set parameters of aggregate
5236 summary-only Filter more specific routes from updates
5237 suppress-map Conditionally filter more specific routes from updates
5240 struct bgp_aggregate
5242 /* Summary-only flag. */
5243 u_char summary_only
;
5245 /* AS set generation. */
5248 /* Route-map for aggregated route. */
5249 struct route_map
*map
;
5251 /* Suppress-count. */
5252 unsigned long count
;
5254 /* SAFI configuration. */
5258 static struct bgp_aggregate
*
5259 bgp_aggregate_new (void)
5261 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5265 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5267 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5270 /* Update an aggregate as routes are added/removed from the BGP table */
5272 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5273 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5274 struct bgp_aggregate
*aggregate
)
5276 struct bgp_table
*table
;
5277 struct bgp_node
*top
;
5278 struct bgp_node
*rn
;
5280 struct aspath
*aspath
= NULL
;
5281 struct aspath
*asmerge
= NULL
;
5282 struct community
*community
= NULL
;
5283 struct community
*commerge
= NULL
;
5284 #if defined(AGGREGATE_NEXTHOP_CHECK)
5285 struct in_addr nexthop
;
5288 struct bgp_info
*ri
;
5289 struct bgp_info
*new;
5291 unsigned long match
= 0;
5292 u_char atomic_aggregate
= 0;
5294 /* Record adding route's nexthop and med. */
5297 #if defined(AGGREGATE_NEXTHOP_CHECK)
5298 nexthop
= rinew
->attr
->nexthop
;
5299 med
= rinew
->attr
->med
;
5303 /* ORIGIN attribute: If at least one route among routes that are
5304 aggregated has ORIGIN with the value INCOMPLETE, then the
5305 aggregated route must have the ORIGIN attribute with the value
5306 INCOMPLETE. Otherwise, if at least one route among routes that
5307 are aggregated has ORIGIN with the value EGP, then the aggregated
5308 route must have the origin attribute with the value EGP. In all
5309 other case the value of the ORIGIN attribute of the aggregated
5310 route is INTERNAL. */
5311 origin
= BGP_ORIGIN_IGP
;
5313 table
= bgp
->rib
[afi
][safi
];
5315 top
= bgp_node_get (table
, p
);
5316 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5317 if (rn
->p
.prefixlen
> p
->prefixlen
)
5321 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5323 if (BGP_INFO_HOLDDOWN (ri
))
5326 if (del
&& ri
== del
)
5329 if (! rinew
&& first
)
5331 #if defined(AGGREGATE_NEXTHOP_CHECK)
5332 nexthop
= ri
->attr
->nexthop
;
5333 med
= ri
->attr
->med
;
5338 #ifdef AGGREGATE_NEXTHOP_CHECK
5339 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5340 || ri
->attr
->med
!= med
)
5343 aspath_free (aspath
);
5345 community_free (community
);
5346 bgp_unlock_node (rn
);
5347 bgp_unlock_node (top
);
5350 #endif /* AGGREGATE_NEXTHOP_CHECK */
5352 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5353 atomic_aggregate
= 1;
5355 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5357 if (aggregate
->summary_only
)
5359 (bgp_info_extra_get (ri
))->suppress
++;
5360 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5366 if (origin
< ri
->attr
->origin
)
5367 origin
= ri
->attr
->origin
;
5369 if (aggregate
->as_set
)
5373 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5374 aspath_free (aspath
);
5378 aspath
= aspath_dup (ri
->attr
->aspath
);
5380 if (ri
->attr
->community
)
5384 commerge
= community_merge (community
,
5385 ri
->attr
->community
);
5386 community
= community_uniq_sort (commerge
);
5387 community_free (commerge
);
5390 community
= community_dup (ri
->attr
->community
);
5396 bgp_process (bgp
, rn
, afi
, safi
);
5398 bgp_unlock_node (top
);
5404 if (aggregate
->summary_only
)
5405 (bgp_info_extra_get (rinew
))->suppress
++;
5407 if (origin
< rinew
->attr
->origin
)
5408 origin
= rinew
->attr
->origin
;
5410 if (aggregate
->as_set
)
5414 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5415 aspath_free (aspath
);
5419 aspath
= aspath_dup (rinew
->attr
->aspath
);
5421 if (rinew
->attr
->community
)
5425 commerge
= community_merge (community
,
5426 rinew
->attr
->community
);
5427 community
= community_uniq_sort (commerge
);
5428 community_free (commerge
);
5431 community
= community_dup (rinew
->attr
->community
);
5436 if (aggregate
->count
> 0)
5438 rn
= bgp_node_get (table
, p
);
5439 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5440 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5442 atomic_aggregate
), rn
);
5443 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5445 bgp_info_add (rn
, new);
5446 bgp_unlock_node (rn
);
5447 bgp_process (bgp
, rn
, afi
, safi
);
5452 aspath_free (aspath
);
5454 community_free (community
);
5458 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5459 struct bgp_aggregate
*);
5462 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5463 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5465 struct bgp_node
*child
;
5466 struct bgp_node
*rn
;
5467 struct bgp_aggregate
*aggregate
;
5468 struct bgp_table
*table
;
5470 /* MPLS-VPN aggregation is not yet supported. */
5471 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5474 table
= bgp
->aggregate
[afi
][safi
];
5476 /* No aggregates configured. */
5477 if (bgp_table_top_nolock (table
) == NULL
)
5480 if (p
->prefixlen
== 0)
5483 if (BGP_INFO_HOLDDOWN (ri
))
5486 child
= bgp_node_get (table
, p
);
5488 /* Aggregate address configuration check. */
5489 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5490 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5492 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5493 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5495 bgp_unlock_node (child
);
5499 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5500 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5502 struct bgp_node
*child
;
5503 struct bgp_node
*rn
;
5504 struct bgp_aggregate
*aggregate
;
5505 struct bgp_table
*table
;
5507 /* MPLS-VPN aggregation is not yet supported. */
5508 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5511 table
= bgp
->aggregate
[afi
][safi
];
5513 /* No aggregates configured. */
5514 if (bgp_table_top_nolock (table
) == NULL
)
5517 if (p
->prefixlen
== 0)
5520 child
= bgp_node_get (table
, p
);
5522 /* Aggregate address configuration check. */
5523 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5524 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5526 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5527 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5529 bgp_unlock_node (child
);
5532 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5534 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5535 struct bgp_aggregate
*aggregate
)
5537 struct bgp_table
*table
;
5538 struct bgp_node
*top
;
5539 struct bgp_node
*rn
;
5540 struct bgp_info
*new;
5541 struct bgp_info
*ri
;
5542 unsigned long match
;
5543 u_char origin
= BGP_ORIGIN_IGP
;
5544 struct aspath
*aspath
= NULL
;
5545 struct aspath
*asmerge
= NULL
;
5546 struct community
*community
= NULL
;
5547 struct community
*commerge
= NULL
;
5548 u_char atomic_aggregate
= 0;
5550 table
= bgp
->rib
[afi
][safi
];
5553 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5555 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5558 /* If routes exists below this node, generate aggregate routes. */
5559 top
= bgp_node_get (table
, p
);
5560 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5561 if (rn
->p
.prefixlen
> p
->prefixlen
)
5565 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5567 if (BGP_INFO_HOLDDOWN (ri
))
5570 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5571 atomic_aggregate
= 1;
5573 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5575 /* summary-only aggregate route suppress aggregated
5576 route announcement. */
5577 if (aggregate
->summary_only
)
5579 (bgp_info_extra_get (ri
))->suppress
++;
5580 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5584 /* If at least one route among routes that are aggregated has
5585 * ORIGIN with the value INCOMPLETE, then the aggregated route
5586 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5587 * Otherwise, if at least one route among routes that are
5588 * aggregated has ORIGIN with the value EGP, then the aggregated
5589 * route MUST have the ORIGIN attribute with the value EGP.
5591 if (origin
< ri
->attr
->origin
)
5592 origin
= ri
->attr
->origin
;
5594 /* as-set aggregate route generate origin, as path,
5595 community aggregation. */
5596 if (aggregate
->as_set
)
5600 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5601 aspath_free (aspath
);
5605 aspath
= aspath_dup (ri
->attr
->aspath
);
5607 if (ri
->attr
->community
)
5611 commerge
= community_merge (community
,
5612 ri
->attr
->community
);
5613 community
= community_uniq_sort (commerge
);
5614 community_free (commerge
);
5617 community
= community_dup (ri
->attr
->community
);
5624 /* If this node is suppressed, process the change. */
5626 bgp_process (bgp
, rn
, afi
, safi
);
5628 bgp_unlock_node (top
);
5630 /* Add aggregate route to BGP table. */
5631 if (aggregate
->count
)
5633 rn
= bgp_node_get (table
, p
);
5634 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5635 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5637 atomic_aggregate
), rn
);
5638 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5640 bgp_info_add (rn
, new);
5641 bgp_unlock_node (rn
);
5643 /* Process change. */
5644 bgp_process (bgp
, rn
, afi
, safi
);
5649 aspath_free (aspath
);
5651 community_free (community
);
5656 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5657 safi_t safi
, struct bgp_aggregate
*aggregate
)
5659 struct bgp_table
*table
;
5660 struct bgp_node
*top
;
5661 struct bgp_node
*rn
;
5662 struct bgp_info
*ri
;
5663 unsigned long match
;
5665 table
= bgp
->rib
[afi
][safi
];
5667 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5669 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5672 /* If routes exists below this node, generate aggregate routes. */
5673 top
= bgp_node_get (table
, p
);
5674 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5675 if (rn
->p
.prefixlen
> p
->prefixlen
)
5679 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5681 if (BGP_INFO_HOLDDOWN (ri
))
5684 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5686 if (aggregate
->summary_only
&& ri
->extra
)
5688 ri
->extra
->suppress
--;
5690 if (ri
->extra
->suppress
== 0)
5692 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5700 /* If this node was suppressed, process the change. */
5702 bgp_process (bgp
, rn
, afi
, safi
);
5704 bgp_unlock_node (top
);
5706 /* Delete aggregate route from BGP table. */
5707 rn
= bgp_node_get (table
, p
);
5709 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5710 if (ri
->peer
== bgp
->peer_self
5711 && ri
->type
== ZEBRA_ROUTE_BGP
5712 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5715 /* Withdraw static BGP route from routing table. */
5718 bgp_info_delete (rn
, ri
);
5719 bgp_process (bgp
, rn
, afi
, safi
);
5722 /* Unlock bgp_node_lookup. */
5723 bgp_unlock_node (rn
);
5726 /* Aggregate route attribute. */
5727 #define AGGREGATE_SUMMARY_ONLY 1
5728 #define AGGREGATE_AS_SET 1
5731 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5732 afi_t afi
, safi_t safi
)
5734 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5737 struct bgp_node
*rn
;
5738 struct bgp_aggregate
*aggregate
;
5740 /* Convert string to prefix structure. */
5741 ret
= str2prefix (prefix_str
, &p
);
5744 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5749 /* Old configuration check. */
5750 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5753 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5758 aggregate
= rn
->info
;
5759 if (aggregate
->safi
== SAFI_UNICAST
)
5760 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5761 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5762 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5763 if (aggregate
->safi
== SAFI_MULTICAST
)
5764 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5766 /* Unlock aggregate address configuration. */
5768 bgp_aggregate_free (aggregate
);
5769 bgp_unlock_node (rn
);
5770 bgp_unlock_node (rn
);
5776 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5777 afi_t afi
, safi_t safi
,
5778 u_char summary_only
, u_char as_set
)
5780 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5783 struct bgp_node
*rn
;
5784 struct bgp_aggregate
*aggregate
;
5786 /* Convert string to prefix structure. */
5787 ret
= str2prefix (prefix_str
, &p
);
5790 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5795 /* Old configuration check. */
5796 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5800 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5801 /* try to remove the old entry */
5802 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5805 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5806 bgp_unlock_node (rn
);
5811 /* Make aggregate address structure. */
5812 aggregate
= bgp_aggregate_new ();
5813 aggregate
->summary_only
= summary_only
;
5814 aggregate
->as_set
= as_set
;
5815 aggregate
->safi
= safi
;
5816 rn
->info
= aggregate
;
5818 /* Aggregate address insert into BGP routing table. */
5819 if (safi
== SAFI_UNICAST
)
5820 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5821 if (safi
== SAFI_LABELED_UNICAST
)
5822 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5823 if (safi
== SAFI_MULTICAST
)
5824 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5829 DEFUN (aggregate_address
,
5830 aggregate_address_cmd
,
5831 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5832 "Configure BGP aggregate entries\n"
5833 "Aggregate prefix\n"
5834 "Generate AS set path information\n"
5835 "Filter more specific routes from updates\n"
5836 "Filter more specific routes from updates\n"
5837 "Generate AS set path information\n")
5840 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5841 char *prefix
= argv
[idx
]->arg
;
5842 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5844 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5846 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5849 DEFUN (aggregate_address_mask
,
5850 aggregate_address_mask_cmd
,
5851 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5852 "Configure BGP aggregate entries\n"
5853 "Aggregate address\n"
5855 "Generate AS set path information\n"
5856 "Filter more specific routes from updates\n"
5857 "Filter more specific routes from updates\n"
5858 "Generate AS set path information\n")
5861 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5862 char *prefix
= argv
[idx
]->arg
;
5863 char *mask
= argv
[idx
+1]->arg
;
5864 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5866 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5868 char prefix_str
[BUFSIZ
];
5869 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5873 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5877 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5880 DEFUN (no_aggregate_address
,
5881 no_aggregate_address_cmd
,
5882 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5884 "Configure BGP aggregate entries\n"
5885 "Aggregate prefix\n"
5886 "Generate AS set path information\n"
5887 "Filter more specific routes from updates\n"
5888 "Filter more specific routes from updates\n"
5889 "Generate AS set path information\n")
5892 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5893 char *prefix
= argv
[idx
]->arg
;
5894 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5897 DEFUN (no_aggregate_address_mask
,
5898 no_aggregate_address_mask_cmd
,
5899 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5901 "Configure BGP aggregate entries\n"
5902 "Aggregate address\n"
5904 "Generate AS set path information\n"
5905 "Filter more specific routes from updates\n"
5906 "Filter more specific routes from updates\n"
5907 "Generate AS set path information\n")
5910 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5911 char *prefix
= argv
[idx
]->arg
;
5912 char *mask
= argv
[idx
+1]->arg
;
5914 char prefix_str
[BUFSIZ
];
5915 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5919 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5923 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5926 DEFUN (ipv6_aggregate_address
,
5927 ipv6_aggregate_address_cmd
,
5928 "aggregate-address X:X::X:X/M [summary-only]",
5929 "Configure BGP aggregate entries\n"
5930 "Aggregate prefix\n"
5931 "Filter more specific routes from updates\n")
5934 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5935 char *prefix
= argv
[idx
]->arg
;
5936 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5937 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5940 DEFUN (no_ipv6_aggregate_address
,
5941 no_ipv6_aggregate_address_cmd
,
5942 "no aggregate-address X:X::X:X/M [summary-only]",
5944 "Configure BGP aggregate entries\n"
5945 "Aggregate prefix\n"
5946 "Filter more specific routes from updates\n")
5949 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5950 char *prefix
= argv
[idx
]->arg
;
5951 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5954 /* Redistribute route treatment. */
5956 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5957 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5958 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5960 struct bgp_info
*new;
5961 struct bgp_info
*bi
;
5962 struct bgp_info info
;
5963 struct bgp_node
*bn
;
5965 struct attr
*new_attr
;
5968 struct bgp_redist
*red
;
5970 /* Make default attribute. */
5971 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5973 attr
.nexthop
= *nexthop
;
5974 attr
.nh_ifindex
= ifindex
;
5978 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5979 extra
->mp_nexthop_global
= *nexthop6
;
5980 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5984 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5985 attr
.extra
->tag
= tag
;
5987 afi
= family2afi (p
->family
);
5989 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5992 struct attr attr_new
;
5993 struct attr_extra extra_new
;
5995 /* Copy attribute for modification. */
5996 attr_new
.extra
= &extra_new
;
5997 bgp_attr_dup (&attr_new
, &attr
);
5999 if (red
->redist_metric_flag
)
6000 attr_new
.med
= red
->redist_metric
;
6002 /* Apply route-map. */
6005 info
.peer
= bgp
->peer_self
;
6006 info
.attr
= &attr_new
;
6008 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6010 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6012 bgp
->peer_self
->rmap_type
= 0;
6014 if (ret
== RMAP_DENYMATCH
)
6016 /* Free uninterned attribute. */
6017 bgp_attr_flush (&attr_new
);
6019 /* Unintern original. */
6020 aspath_unintern (&attr
.aspath
);
6021 bgp_attr_extra_free (&attr
);
6022 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6027 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6028 afi
, SAFI_UNICAST
, p
, NULL
);
6030 new_attr
= bgp_attr_intern (&attr_new
);
6032 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6033 if (bi
->peer
== bgp
->peer_self
6034 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6039 /* Ensure the (source route) type is updated. */
6041 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6042 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6044 bgp_attr_unintern (&new_attr
);
6045 aspath_unintern (&attr
.aspath
);
6046 bgp_attr_extra_free (&attr
);
6047 bgp_unlock_node (bn
);
6052 /* The attribute is changed. */
6053 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6055 /* Rewrite BGP route information. */
6056 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6057 bgp_info_restore(bn
, bi
);
6059 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6060 bgp_attr_unintern (&bi
->attr
);
6061 bi
->attr
= new_attr
;
6062 bi
->uptime
= bgp_clock ();
6064 /* Process change. */
6065 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6066 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6067 bgp_unlock_node (bn
);
6068 aspath_unintern (&attr
.aspath
);
6069 bgp_attr_extra_free (&attr
);
6074 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6076 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6078 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6079 bgp_info_add (bn
, new);
6080 bgp_unlock_node (bn
);
6081 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6084 /* Unintern original. */
6085 aspath_unintern (&attr
.aspath
);
6086 bgp_attr_extra_free (&attr
);
6090 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6093 struct bgp_node
*rn
;
6094 struct bgp_info
*ri
;
6095 struct bgp_redist
*red
;
6097 afi
= family2afi (p
->family
);
6099 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6102 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6104 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6105 if (ri
->peer
== bgp
->peer_self
6106 && ri
->type
== type
)
6111 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6112 bgp_info_delete (rn
, ri
);
6113 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6115 bgp_unlock_node (rn
);
6119 /* Withdraw specified route type's route. */
6121 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6123 struct bgp_node
*rn
;
6124 struct bgp_info
*ri
;
6125 struct bgp_table
*table
;
6127 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6129 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6131 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6132 if (ri
->peer
== bgp
->peer_self
6134 && ri
->instance
== instance
)
6139 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6140 bgp_info_delete (rn
, ri
);
6141 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6146 /* Static function to display route. */
6148 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6151 u_int32_t destination
;
6154 if (p
->family
== AF_INET
)
6156 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6157 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6159 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6160 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6161 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6162 || p
->u
.prefix4
.s_addr
== 0)
6164 /* When mask is natural, mask is not displayed. */
6167 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6169 else if (p
->family
== AF_ETHERNET
)
6171 prefix2str(p
, buf
, PREFIX_STRLEN
);
6172 len
= vty_out (vty
, "%s", buf
);
6175 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6180 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
6182 vty_out (vty
, "%*s", len
, " ");
6185 enum bgp_display_type
6190 /* Print the short form route status for a bgp_info */
6192 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6193 json_object
*json_path
)
6198 /* Route status display. */
6199 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6200 json_object_boolean_true_add(json_path
, "removed");
6202 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6203 json_object_boolean_true_add(json_path
, "stale");
6205 if (binfo
->extra
&& binfo
->extra
->suppress
)
6206 json_object_boolean_true_add(json_path
, "suppressed");
6208 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6209 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6210 json_object_boolean_true_add(json_path
, "valid");
6213 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6214 json_object_boolean_true_add(json_path
, "history");
6216 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6217 json_object_boolean_true_add(json_path
, "damped");
6219 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6220 json_object_boolean_true_add(json_path
, "bestpath");
6222 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6223 json_object_boolean_true_add(json_path
, "multipath");
6225 /* Internal route. */
6226 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6227 json_object_string_add(json_path
, "pathFrom", "internal");
6229 json_object_string_add(json_path
, "pathFrom", "external");
6234 /* Route status display. */
6235 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6237 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6239 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6241 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6242 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6248 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6250 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6252 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6254 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6259 /* Internal route. */
6261 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6267 /* called from terminal list command */
6269 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6270 struct bgp_info
*binfo
, int display
, safi_t safi
,
6271 json_object
*json_paths
)
6274 json_object
*json_path
= NULL
;
6275 json_object
*json_nexthops
= NULL
;
6276 json_object
*json_nexthop_global
= NULL
;
6277 json_object
*json_nexthop_ll
= NULL
;
6280 json_path
= json_object_new_object();
6282 /* short status lead text */
6283 route_vty_short_status_out (vty
, binfo
, json_path
);
6287 /* print prefix and mask */
6289 route_vty_out_route (p
, vty
);
6291 vty_out (vty
, "%*s", 17, " ");
6294 /* Print attribute */
6299 * For ENCAP routes, nexthop address family is not
6300 * neccessarily the same as the prefix address family.
6301 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6303 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6308 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6313 vty_out (vty
, "%s", inet_ntop(af
,
6314 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6317 vty_out (vty
, "%s", inet_ntop(af
,
6318 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6329 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6333 json_nexthop_global
= json_object_new_object();
6335 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6336 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6338 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6340 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6341 json_object_boolean_true_add(json_nexthop_global
, "used");
6345 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6346 vty_out (vty
, "%-16s",
6347 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6349 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6354 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6361 json_nexthop_global
= json_object_new_object();
6362 json_object_string_add(json_nexthop_global
, "ip",
6363 inet_ntop (AF_INET6
,
6364 &attr
->extra
->mp_nexthop_global
,
6366 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6367 json_object_string_add(json_nexthop_global
, "scope", "global");
6369 /* We display both LL & GL if both have been received */
6370 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6372 json_nexthop_ll
= json_object_new_object();
6373 json_object_string_add(json_nexthop_ll
, "ip",
6374 inet_ntop (AF_INET6
,
6375 &attr
->extra
->mp_nexthop_local
,
6377 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6378 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6380 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6381 &attr
->extra
->mp_nexthop_local
) != 0) &&
6382 !attr
->extra
->mp_nexthop_prefer_global
)
6383 json_object_boolean_true_add(json_nexthop_ll
, "used");
6385 json_object_boolean_true_add(json_nexthop_global
, "used");
6388 json_object_boolean_true_add(json_nexthop_global
, "used");
6392 /* Display LL if LL/Global both in table unless prefer-global is set */
6393 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6394 !attr
->extra
->mp_nexthop_prefer_global
) ||
6395 (binfo
->peer
->conf_if
))
6397 if (binfo
->peer
->conf_if
)
6399 len
= vty_out (vty
, "%s",
6400 binfo
->peer
->conf_if
);
6401 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6404 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6406 vty_out (vty
, "%*s", len
, " ");
6410 len
= vty_out (vty
, "%s",
6411 inet_ntop (AF_INET6
,
6412 &attr
->extra
->mp_nexthop_local
,
6417 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6419 vty_out (vty
, "%*s", len
, " ");
6424 len
= vty_out (vty
, "%s",
6425 inet_ntop (AF_INET6
,
6426 &attr
->extra
->mp_nexthop_global
,
6431 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6433 vty_out (vty
, "%*s", len
, " ");
6439 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6441 json_object_int_add(json_path
, "med", attr
->med
);
6443 vty_out (vty
, "%10u", attr
->med
);
6449 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6451 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6453 vty_out (vty
, "%7u", attr
->local_pref
);
6461 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6463 json_object_int_add(json_path
, "weight", 0);
6466 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6470 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6477 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6479 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6484 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6486 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6491 json_object_string_add(json_path
, "alert", "No attributes");
6493 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6498 if (json_nexthop_global
|| json_nexthop_ll
)
6500 json_nexthops
= json_object_new_array();
6502 if (json_nexthop_global
)
6503 json_object_array_add(json_nexthops
, json_nexthop_global
);
6505 if (json_nexthop_ll
)
6506 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6508 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6511 json_object_array_add(json_paths
, json_path
);
6515 vty_out (vty
, "%s", VTY_NEWLINE
);
6517 /* prints an additional line, indented, with VNC info, if present */
6518 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6519 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6524 /* called from terminal list command */
6526 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6527 u_char use_json
, json_object
*json_ar
)
6529 json_object
*json_status
= NULL
;
6530 json_object
*json_net
= NULL
;
6532 /* Route status display. */
6535 json_status
= json_object_new_object();
6536 json_net
= json_object_new_object();
6545 /* print prefix and mask */
6547 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6549 route_vty_out_route (p
, vty
);
6551 /* Print attribute */
6556 if (p
->family
== AF_INET
&&
6557 (safi
== SAFI_MPLS_VPN
||
6558 safi
== SAFI_ENCAP
||
6559 safi
== SAFI_EVPN
||
6560 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6562 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6563 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6565 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6567 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6571 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6575 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6576 json_object_int_add(json_net
, "metric", attr
->med
);
6578 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6579 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6582 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6584 json_object_int_add(json_net
, "weight", 0);
6588 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6591 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6595 if (p
->family
== AF_INET
&&
6596 (safi
== SAFI_MPLS_VPN
||
6597 safi
== SAFI_ENCAP
||
6598 safi
== SAFI_EVPN
||
6599 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6601 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6602 vty_out (vty
, "%-16s",
6603 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6605 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6607 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6612 assert (attr
->extra
);
6614 len
= vty_out (vty
, "%s",
6615 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6619 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6621 vty_out (vty
, "%*s", len
, " ");
6623 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6624 vty_out (vty
, "%10u", attr
->med
);
6628 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6629 vty_out (vty
, "%7u", attr
->local_pref
);
6633 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6637 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6640 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6645 json_object_boolean_true_add(json_status
, "*");
6646 json_object_boolean_true_add(json_status
, ">");
6647 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6648 char buf_cut
[BUFSIZ
];
6649 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6652 vty_out (vty
, "%s", VTY_NEWLINE
);
6656 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6657 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6659 json_object
*json_out
= NULL
;
6661 u_int32_t label
= 0;
6667 json_out
= json_object_new_object();
6669 /* short status lead text */
6670 route_vty_short_status_out (vty
, binfo
, json_out
);
6672 /* print prefix and mask */
6676 route_vty_out_route (p
, vty
);
6678 vty_out (vty
, "%*s", 17, " ");
6681 /* Print attribute */
6685 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6686 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6687 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6689 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6692 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6694 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6699 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6701 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6704 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6705 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6706 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6708 assert (attr
->extra
);
6712 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6715 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6716 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6719 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6722 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6726 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6728 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6730 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6731 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6734 vty_out (vty
, "%s(%s)",
6735 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6737 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6744 label
= decode_label (binfo
->extra
->tag
);
6749 json_object_int_add(json_out
, "notag", label
);
6750 json_object_array_add(json
, json_out
);
6754 vty_out (vty
, "notag/%d", label
);
6756 vty_out (vty
, "%s", VTY_NEWLINE
);
6761 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6762 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6766 json_object
*json_path
= NULL
;
6769 json_path
= json_object_new_object();
6774 /* short status lead text */
6775 route_vty_short_status_out (vty
, binfo
, json_path
);
6777 /* print prefix and mask */
6779 route_vty_out_route (p
, vty
);
6781 vty_out (vty
, "%*s", 17, " ");
6783 /* Print attribute */
6790 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6794 vty_out (vty
, "%-16s", inet_ntop(af
,
6795 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6798 vty_out (vty
, "%s(%s)",
6800 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6802 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6814 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6815 char *str
= esi2str(id
);
6816 vty_out (vty
, "%s", str
);
6817 XFREE (MTYPE_TMP
, str
);
6818 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6820 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6822 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6824 vty_out (vty
, "/%s",
6825 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6828 if(attr
->extra
->ecommunity
)
6831 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6832 ECOMMUNITY_ENCODE_EVPN
,
6833 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6835 mac
= ecom_mac2str((char *)routermac
->val
);
6838 vty_out (vty
, "/%s",(char *)mac
);
6839 XFREE(MTYPE_TMP
, mac
);
6843 vty_out (vty
, "%s", VTY_NEWLINE
);
6846 /* dampening route */
6848 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6849 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6853 char timebuf
[BGP_UPTIME_LEN
];
6855 /* short status lead text */
6856 route_vty_short_status_out (vty
, binfo
, json
);
6858 /* print prefix and mask */
6862 route_vty_out_route (p
, vty
);
6864 vty_out (vty
, "%*s", 17, " ");
6867 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6872 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6877 json_object_int_add(json
, "peerHost", len
);
6879 vty_out (vty
, "%*s", len
, " ");
6883 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6885 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6887 /* Print attribute */
6895 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6897 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6902 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6904 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6907 vty_out (vty
, "%s", VTY_NEWLINE
);
6912 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6913 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6916 struct bgp_damp_info
*bdi
;
6917 char timebuf
[BGP_UPTIME_LEN
];
6923 bdi
= binfo
->extra
->damp_info
;
6925 /* short status lead text */
6926 route_vty_short_status_out (vty
, binfo
, json
);
6928 /* print prefix and mask */
6932 route_vty_out_route (p
, vty
);
6934 vty_out (vty
, "%*s", 17, " ");
6937 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6942 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6947 json_object_int_add(json
, "peerHost", len
);
6949 vty_out (vty
, "%*s", len
, " ");
6952 len
= vty_out (vty
, "%d", bdi
->flap
);
6962 json_object_int_add(json
, "bdiFlap", len
);
6964 vty_out (vty
, "%*s", len
, " ");
6968 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6970 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6971 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6973 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6974 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6977 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6979 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6984 vty_out (vty
, "%*s ", 8, " ");
6987 /* Print attribute */
6995 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6997 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7002 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7004 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7007 vty_out (vty
, "%s", VTY_NEWLINE
);
7011 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7012 const char *header
, json_object
*json_adv_to
)
7014 char buf1
[INET6_ADDRSTRLEN
];
7015 json_object
*json_peer
= NULL
;
7019 /* 'advertised-to' is a dictionary of peers we have advertised this
7020 * prefix too. The key is the peer's IP or swpX, the value is the
7021 * hostname if we know it and "" if not.
7023 json_peer
= json_object_new_object();
7026 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7029 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7031 json_object_object_add(json_adv_to
,
7032 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7039 vty_out (vty
, "%s", header
);
7043 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7046 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7048 vty_out (vty
, " %s(%s)", peer
->hostname
,
7049 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7054 vty_out (vty
, " %s", peer
->conf_if
);
7056 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7062 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7063 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7064 json_object
*json_paths
)
7066 char buf
[INET6_ADDRSTRLEN
];
7069 int sockunion_vty_out (struct vty
*, union sockunion
*);
7071 json_object
*json_bestpath
= NULL
;
7072 json_object
*json_cluster_list
= NULL
;
7073 json_object
*json_cluster_list_list
= NULL
;
7074 json_object
*json_ext_community
= NULL
;
7075 json_object
*json_last_update
= NULL
;
7076 json_object
*json_nexthop_global
= NULL
;
7077 json_object
*json_nexthop_ll
= NULL
;
7078 json_object
*json_nexthops
= NULL
;
7079 json_object
*json_path
= NULL
;
7080 json_object
*json_peer
= NULL
;
7081 json_object
*json_string
= NULL
;
7082 json_object
*json_adv_to
= NULL
;
7084 struct listnode
*node
, *nnode
;
7086 int addpath_capable
;
7088 unsigned int first_as
;
7092 json_path
= json_object_new_object();
7093 json_peer
= json_object_new_object();
7094 json_nexthop_global
= json_object_new_object();
7101 /* Line1 display AS-path, Aggregator */
7106 json_object_lock(attr
->aspath
->json
);
7107 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7111 if (attr
->aspath
->segments
)
7112 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7114 vty_out (vty
, " Local");
7118 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7121 json_object_boolean_true_add(json_path
, "removed");
7123 vty_out (vty
, ", (removed)");
7126 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7129 json_object_boolean_true_add(json_path
, "stale");
7131 vty_out (vty
, ", (stale)");
7134 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7138 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
7139 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
7143 vty_out (vty
, ", (aggregated by %u %s)",
7144 attr
->extra
->aggregator_as
,
7145 inet_ntoa (attr
->extra
->aggregator_addr
));
7149 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7152 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7154 vty_out (vty
, ", (Received from a RR-client)");
7157 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7160 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7162 vty_out (vty
, ", (Received from a RS-client)");
7165 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7168 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7170 vty_out (vty
, ", (history entry)");
7172 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7175 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7177 vty_out (vty
, ", (suppressed due to dampening)");
7181 vty_out (vty
, "%s", VTY_NEWLINE
);
7183 /* Line2 display Next-hop, Neighbor, Router-id */
7184 /* Display the nexthop */
7185 if (p
->family
== AF_INET
&&
7186 (safi
== SAFI_MPLS_VPN
||
7187 safi
== SAFI_ENCAP
||
7188 safi
== SAFI_EVPN
||
7189 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7191 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7194 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7196 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7201 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7203 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7207 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7211 assert (attr
->extra
);
7214 json_object_string_add(json_nexthop_global
, "ip",
7215 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7216 buf
, INET6_ADDRSTRLEN
));
7217 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7218 json_object_string_add(json_nexthop_global
, "scope", "global");
7222 vty_out (vty
, " %s",
7223 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7224 buf
, INET6_ADDRSTRLEN
));
7228 /* Display the IGP cost or 'inaccessible' */
7229 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7232 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7234 vty_out (vty
, " (inaccessible)");
7238 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7241 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7243 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7246 /* IGP cost is 0, display this only for json */
7250 json_object_int_add(json_nexthop_global
, "metric", 0);
7254 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7257 /* Display peer "from" output */
7258 /* This path was originated locally */
7259 if (binfo
->peer
== bgp
->peer_self
)
7262 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7265 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7267 vty_out (vty
, " from 0.0.0.0 ");
7272 json_object_string_add(json_peer
, "peerId", "::");
7274 vty_out (vty
, " from :: ");
7278 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7280 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7283 /* We RXed this path from one of our peers */
7289 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7290 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7292 if (binfo
->peer
->hostname
)
7293 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7295 if (binfo
->peer
->domainname
)
7296 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7298 if (binfo
->peer
->conf_if
)
7299 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7303 if (binfo
->peer
->conf_if
)
7305 if (binfo
->peer
->hostname
&&
7306 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7307 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7308 binfo
->peer
->conf_if
);
7310 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7314 if (binfo
->peer
->hostname
&&
7315 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7316 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7319 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7322 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7323 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7325 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7330 vty_out (vty
, "%s", VTY_NEWLINE
);
7332 /* display the link-local nexthop */
7333 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7337 json_nexthop_ll
= json_object_new_object();
7338 json_object_string_add(json_nexthop_ll
, "ip",
7339 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7340 buf
, INET6_ADDRSTRLEN
));
7341 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7342 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7344 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7346 if (!attr
->extra
->mp_nexthop_prefer_global
)
7347 json_object_boolean_true_add(json_nexthop_ll
, "used");
7349 json_object_boolean_true_add(json_nexthop_global
, "used");
7353 vty_out (vty
, " (%s) %s%s",
7354 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7355 buf
, INET6_ADDRSTRLEN
),
7356 attr
->extra
->mp_nexthop_prefer_global
?
7357 "(prefer-global)" : "(used)",
7361 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7365 json_object_boolean_true_add(json_nexthop_global
, "used");
7368 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7370 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7372 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7374 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7377 json_object_int_add(json_path
, "med", attr
->med
);
7379 vty_out (vty
, ", metric %u", attr
->med
);
7382 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7385 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7387 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7392 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7394 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7397 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7400 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7402 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7405 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7408 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7410 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7413 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7416 json_object_boolean_false_add(json_path
, "valid");
7418 vty_out (vty
, ", invalid");
7420 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7423 json_object_boolean_true_add(json_path
, "valid");
7425 vty_out (vty
, ", valid");
7428 if (binfo
->peer
!= bgp
->peer_self
)
7430 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7432 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7435 json_object_string_add(json_peer
, "type", "confed-internal");
7437 vty_out (vty
, ", confed-internal");
7442 json_object_string_add(json_peer
, "type", "internal");
7444 vty_out (vty
, ", internal");
7449 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7452 json_object_string_add(json_peer
, "type", "confed-external");
7454 vty_out (vty
, ", confed-external");
7459 json_object_string_add(json_peer
, "type", "external");
7461 vty_out (vty
, ", external");
7465 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7469 json_object_boolean_true_add(json_path
, "aggregated");
7470 json_object_boolean_true_add(json_path
, "local");
7474 vty_out (vty
, ", aggregated, local");
7477 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7480 json_object_boolean_true_add(json_path
, "sourced");
7482 vty_out (vty
, ", sourced");
7488 json_object_boolean_true_add(json_path
, "sourced");
7489 json_object_boolean_true_add(json_path
, "local");
7493 vty_out (vty
, ", sourced, local");
7497 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7500 json_object_boolean_true_add(json_path
, "atomicAggregate");
7502 vty_out (vty
, ", atomic-aggregate");
7505 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7506 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7507 bgp_info_mpath_count (binfo
)))
7510 json_object_boolean_true_add(json_path
, "multipath");
7512 vty_out (vty
, ", multipath");
7515 // Mark the bestpath(s)
7516 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7518 first_as
= aspath_get_first_as(attr
->aspath
);
7523 json_bestpath
= json_object_new_object();
7524 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7529 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7531 vty_out (vty
, ", bestpath-from-AS Local");
7535 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7540 json_bestpath
= json_object_new_object();
7541 json_object_boolean_true_add(json_bestpath
, "overall");
7544 vty_out (vty
, ", best");
7548 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7551 vty_out (vty
, "%s", VTY_NEWLINE
);
7553 /* Line 4 display Community */
7554 if (attr
->community
)
7558 json_object_lock(attr
->community
->json
);
7559 json_object_object_add(json_path
, "community", attr
->community
->json
);
7563 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7568 /* Line 5 display Extended-community */
7569 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7573 json_ext_community
= json_object_new_object();
7574 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7575 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7579 vty_out (vty
, " Extended Community: %s%s",
7580 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7584 /* Line 6 display Large community */
7585 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7586 vty_out (vty
, " Large Community: %s%s",
7587 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7589 /* Line 7 display Originator, Cluster-id */
7590 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7591 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7593 assert (attr
->extra
);
7594 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7597 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7599 vty_out (vty
, " Originator: %s",
7600 inet_ntoa (attr
->extra
->originator_id
));
7603 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7609 json_cluster_list
= json_object_new_object();
7610 json_cluster_list_list
= json_object_new_array();
7612 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7614 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7615 json_object_array_add(json_cluster_list_list
, json_string
);
7618 /* struct cluster_list does not have "str" variable like
7619 * aspath and community do. Add this someday if someone
7621 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7623 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7624 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7628 vty_out (vty
, ", Cluster list: ");
7630 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7632 vty_out (vty
, "%s ",
7633 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7639 vty_out (vty
, "%s", VTY_NEWLINE
);
7642 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7643 bgp_damp_info_vty (vty
, binfo
, json_path
);
7646 if (bgp_labeled_safi(safi
) && binfo
->extra
)
7648 uint32_t label
= label_pton(binfo
->extra
->tag
);
7650 json_object_int_add(json_path
, "remoteLabel", label
);
7652 vty_out(vty
, " Remote label: %d%s", label
, VTY_NEWLINE
);
7656 if (attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7659 json_object_int_add(json_path
, "labelIndex", attr
->extra
->label_index
);
7661 vty_out(vty
, " Label Index: %d%s", attr
->extra
->label_index
, VTY_NEWLINE
);
7664 /* Line 8 display Addpath IDs */
7665 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7669 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7670 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7674 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7675 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7680 /* If we used addpath to TX a non-bestpath we need to display
7681 * "Advertised to" on a path-by-path basis */
7682 if (bgp
->addpath_tx_used
[afi
][safi
])
7686 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7688 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7689 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7691 if ((addpath_capable
&& has_adj
) ||
7692 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7694 if (json_path
&& !json_adv_to
)
7695 json_adv_to
= json_object_new_object();
7697 route_vty_out_advertised_to(vty
, peer
, &first
,
7707 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7714 vty_out (vty
, "%s", VTY_NEWLINE
);
7719 /* Line 9 display Uptime */
7720 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7723 json_last_update
= json_object_new_object();
7724 json_object_int_add(json_last_update
, "epoch", tbuf
);
7725 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7726 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7729 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7732 /* We've constructed the json object for this path, add it to the json
7737 if (json_nexthop_global
|| json_nexthop_ll
)
7739 json_nexthops
= json_object_new_array();
7741 if (json_nexthop_global
)
7742 json_object_array_add(json_nexthops
, json_nexthop_global
);
7744 if (json_nexthop_ll
)
7745 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7747 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7750 json_object_object_add(json_path
, "peer", json_peer
);
7751 json_object_array_add(json_paths
, json_path
);
7754 vty_out (vty
, "%s", VTY_NEWLINE
);
7757 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7758 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7759 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7762 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7763 const char *prefix_list_str
, afi_t afi
,
7764 safi_t safi
, enum bgp_show_type type
);
7766 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7767 const char *filter
, afi_t afi
,
7768 safi_t safi
, enum bgp_show_type type
);
7770 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7771 const char *rmap_str
, afi_t afi
,
7772 safi_t safi
, enum bgp_show_type type
);
7774 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7775 const char *com
, int exact
,
7776 afi_t afi
, safi_t safi
);
7778 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7779 const char *prefix
, afi_t afi
,
7780 safi_t safi
, enum bgp_show_type type
);
7782 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7783 safi_t safi
, enum bgp_show_type type
);
7785 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7786 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7789 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7790 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7792 struct bgp_info
*ri
;
7793 struct bgp_node
*rn
;
7796 unsigned long output_count
;
7797 unsigned long total_count
;
7801 json_object
*json_paths
= NULL
;
7806 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7807 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7808 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7809 table
->version
, inet_ntoa (bgp
->router_id
));
7810 json_paths
= json_object_new_object();
7813 /* This is first entry point, so reset total line. */
7817 /* Start processing of routes. */
7818 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7819 if (rn
->info
!= NULL
)
7822 if (!first
&& use_json
)
7827 json_paths
= json_object_new_array();
7831 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7834 if (type
== bgp_show_type_flap_statistics
7835 || type
== bgp_show_type_flap_neighbor
7836 || type
== bgp_show_type_dampend_paths
7837 || type
== bgp_show_type_damp_neighbor
)
7839 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7842 if (type
== bgp_show_type_regexp
)
7844 regex_t
*regex
= output_arg
;
7846 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7849 if (type
== bgp_show_type_prefix_list
)
7851 struct prefix_list
*plist
= output_arg
;
7853 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7856 if (type
== bgp_show_type_filter_list
)
7858 struct as_list
*as_list
= output_arg
;
7860 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7863 if (type
== bgp_show_type_route_map
)
7865 struct route_map
*rmap
= output_arg
;
7866 struct bgp_info binfo
;
7867 struct attr dummy_attr
;
7868 struct attr_extra dummy_extra
;
7871 dummy_attr
.extra
= &dummy_extra
;
7872 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7874 binfo
.peer
= ri
->peer
;
7875 binfo
.attr
= &dummy_attr
;
7877 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7878 if (ret
== RMAP_DENYMATCH
)
7881 if (type
== bgp_show_type_neighbor
7882 || type
== bgp_show_type_flap_neighbor
7883 || type
== bgp_show_type_damp_neighbor
)
7885 union sockunion
*su
= output_arg
;
7887 if (ri
->peer
== NULL
||
7888 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7891 if (type
== bgp_show_type_cidr_only
)
7893 u_int32_t destination
;
7895 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7896 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7898 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7900 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7903 if (type
== bgp_show_type_prefix_longer
)
7905 struct prefix
*p
= output_arg
;
7907 if (! prefix_match (p
, &rn
->p
))
7910 if (type
== bgp_show_type_community_all
)
7912 if (! ri
->attr
->community
)
7915 if (type
== bgp_show_type_community
)
7917 struct community
*com
= output_arg
;
7919 if (! ri
->attr
->community
||
7920 ! community_match (ri
->attr
->community
, com
))
7923 if (type
== bgp_show_type_community_exact
)
7925 struct community
*com
= output_arg
;
7927 if (! ri
->attr
->community
||
7928 ! community_cmp (ri
->attr
->community
, com
))
7931 if (type
== bgp_show_type_community_list
)
7933 struct community_list
*list
= output_arg
;
7935 if (! community_list_match (ri
->attr
->community
, list
))
7938 if (type
== bgp_show_type_community_list_exact
)
7940 struct community_list
*list
= output_arg
;
7942 if (! community_list_exact_match (ri
->attr
->community
, list
))
7945 if (type
== bgp_show_type_lcommunity
)
7947 struct lcommunity
*lcom
= output_arg
;
7949 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7950 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7953 if (type
== bgp_show_type_lcommunity_list
)
7955 struct community_list
*list
= output_arg
;
7957 if (! ri
->attr
->extra
||
7958 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7961 if (type
== bgp_show_type_lcommunity_all
)
7963 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7966 if (type
== bgp_show_type_dampend_paths
7967 || type
== bgp_show_type_damp_neighbor
)
7969 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7970 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7974 if (!use_json
&& header
)
7976 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7977 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7978 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7979 if (type
== bgp_show_type_dampend_paths
7980 || type
== bgp_show_type_damp_neighbor
)
7981 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7982 else if (type
== bgp_show_type_flap_statistics
7983 || type
== bgp_show_type_flap_neighbor
)
7984 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7986 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7990 if (type
== bgp_show_type_dampend_paths
7991 || type
== bgp_show_type_damp_neighbor
)
7992 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7993 else if (type
== bgp_show_type_flap_statistics
7994 || type
== bgp_show_type_flap_neighbor
)
7995 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7997 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8007 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8008 vty_out (vty
, "\"%s\": ", buf2
);
8009 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8010 json_object_free (json_paths
);
8019 json_object_free (json_paths
);
8020 vty_out (vty
, " } }%s", VTY_NEWLINE
);
8024 /* No route is displayed */
8025 if (output_count
== 0)
8027 if (type
== bgp_show_type_normal
)
8028 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
8031 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
8032 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
8039 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8040 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8042 struct bgp_table
*table
;
8046 bgp
= bgp_get_default ();
8052 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8055 /* use MPLS and ENCAP specific shows until they are merged */
8056 if (safi
== SAFI_MPLS_VPN
)
8058 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8062 table
= bgp
->rib
[afi
][safi
];
8064 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8069 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8072 struct listnode
*node
, *nnode
;
8077 vty_out (vty
, "{%s", VTY_NEWLINE
);
8079 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8084 vty_out (vty
, ",%s", VTY_NEWLINE
);
8088 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8089 ? "Default" : bgp
->name
);
8093 vty_out (vty
, "%sInstance %s:%s",
8095 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8096 ? "Default" : bgp
->name
,
8099 bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
, use_json
);
8104 vty_out (vty
, "}%s", VTY_NEWLINE
);
8107 /* Header of detailed BGP route information */
8109 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8110 struct bgp_node
*rn
,
8111 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8114 struct bgp_info
*ri
;
8117 struct listnode
*node
, *nnode
;
8118 char buf1
[INET6_ADDRSTRLEN
];
8119 char buf2
[INET6_ADDRSTRLEN
];
8124 int no_advertise
= 0;
8127 json_object
*json_adv_to
= NULL
;
8133 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8134 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8138 if (p
->family
== AF_ETHERNET
)
8139 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8141 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8142 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
8143 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8144 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8145 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8147 p
->prefixlen
, VTY_NEWLINE
);
8149 if (bgp_labeled_safi(safi
))
8151 vty_out(vty
, "Local label: ");
8152 if (!bgp_is_valid_label(rn
->local_label
))
8153 vty_out(vty
, "not allocated%s", VTY_NEWLINE
);
8156 uint32_t label
= label_pton(rn
->local_label
);
8157 vty_out(vty
, "%d%s", label
, VTY_NEWLINE
);
8162 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8165 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8168 if (ri
->extra
&& ri
->extra
->suppress
)
8170 if (ri
->attr
->community
!= NULL
)
8172 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8174 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8176 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8184 vty_out (vty
, "Paths: (%d available", count
);
8187 vty_out (vty
, ", best #%d", best
);
8188 if (safi
== SAFI_UNICAST
)
8189 vty_out (vty
, ", table %s",
8190 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8191 ? "Default-IP-Routing-Table" : bgp
->name
);
8194 vty_out (vty
, ", no best path");
8197 vty_out (vty
, ", not advertised to any peer");
8199 vty_out (vty
, ", not advertised to EBGP peer");
8201 vty_out (vty
, ", not advertised outside local AS");
8204 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8205 vty_out (vty
, ")%s", VTY_NEWLINE
);
8208 /* If we are not using addpath then we can display Advertised to and that will
8209 * show what peers we advertised the bestpath to. If we are using addpath
8210 * though then we must display Advertised to on a path-by-path basis. */
8211 if (!bgp
->addpath_tx_used
[afi
][safi
])
8213 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8215 if (bgp_adj_out_lookup (peer
, rn
, 0))
8217 if (json
&& !json_adv_to
)
8218 json_adv_to
= json_object_new_object();
8220 route_vty_out_advertised_to(vty
, peer
, &first
,
8221 " Advertised to non peer-group peers:\n ",
8230 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8236 vty_out (vty
, " Not advertised to any peer");
8237 vty_out (vty
, "%s", VTY_NEWLINE
);
8242 /* Display specified route of BGP table. */
8244 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8245 struct bgp_table
*rib
, const char *ip_str
,
8246 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8247 int prefix_check
, enum bgp_path_type pathtype
,
8253 struct prefix match
;
8254 struct bgp_node
*rn
;
8255 struct bgp_node
*rm
;
8256 struct bgp_info
*ri
;
8257 struct bgp_table
*table
;
8258 json_object
*json
= NULL
;
8259 json_object
*json_paths
= NULL
;
8261 /* Check IP address argument. */
8262 ret
= str2prefix (ip_str
, &match
);
8265 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
8269 match
.family
= afi2family (afi
);
8273 json
= json_object_new_object();
8274 json_paths
= json_object_new_array();
8277 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8279 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8281 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8284 if ((table
= rn
->info
) != NULL
)
8288 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8290 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8292 bgp_unlock_node (rm
);
8296 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8300 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8301 AFI_IP
, safi
, json
);
8306 if (pathtype
== BGP_PATH_ALL
||
8307 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8308 (pathtype
== BGP_PATH_MULTIPATH
&&
8309 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8310 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8313 bgp_unlock_node (rm
);
8322 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8324 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8326 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8330 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8335 if (pathtype
== BGP_PATH_ALL
||
8336 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8337 (pathtype
== BGP_PATH_MULTIPATH
&&
8338 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8339 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8343 bgp_unlock_node (rn
);
8350 json_object_object_add(json
, "paths", json_paths
);
8352 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8353 json_object_free(json
);
8359 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8367 /* Display specified route of Main RIB */
8369 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8370 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8371 int prefix_check
, enum bgp_path_type pathtype
,
8375 bgp
= bgp_get_default ();
8377 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8378 afi
, safi
, prd
, prefix_check
, pathtype
,
8383 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8384 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8386 struct lcommunity
*lcom
;
8392 b
= buffer_new (1024);
8393 for (i
= 0; i
< argc
; i
++)
8396 buffer_putc (b
, ' ');
8399 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8402 buffer_putstr (b
, argv
[i
]->arg
);
8406 buffer_putc (b
, '\0');
8408 str
= buffer_getstr (b
);
8411 lcom
= lcommunity_str2com (str
);
8412 XFREE (MTYPE_TMP
, str
);
8415 vty_out (vty
, "%% Large-community malformed%s", VTY_NEWLINE
);
8419 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8423 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8424 afi_t afi
, safi_t safi
, u_char uj
)
8426 struct community_list
*list
;
8428 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8431 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8436 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8439 DEFUN (show_ip_bgp_large_community_list
,
8440 show_ip_bgp_large_community_list_cmd
,
8441 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
8445 BGP_INSTANCE_HELP_STR
8448 "Address Family modifier\n"
8449 "Address Family modifier\n"
8450 "Address Family modifier\n"
8451 "Address Family modifier\n"
8452 "Display routes matching the large-community-list\n"
8453 "large-community-list number\n"
8454 "large-community-list name\n"
8458 afi_t afi
= AFI_IP6
;
8459 safi_t safi
= SAFI_UNICAST
;
8462 if (argv_find (argv
, argc
, "ip", &idx
))
8464 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8465 vrf
= argv
[++idx
]->arg
;
8466 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8468 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8469 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8470 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8473 int uj
= use_json (argc
, argv
);
8475 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8478 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8482 argv_find (argv
, argc
, "large-community-list", &idx
);
8483 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8485 DEFUN (show_ip_bgp_large_community
,
8486 show_ip_bgp_large_community_cmd
,
8487 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]",
8491 BGP_INSTANCE_HELP_STR
8494 "Address Family modifier\n"
8495 "Address Family modifier\n"
8496 "Address Family modifier\n"
8497 "Address Family modifier\n"
8498 "Display routes matching the large-communities\n"
8499 "List of large-community numbers\n"
8503 afi_t afi
= AFI_IP6
;
8504 safi_t safi
= SAFI_UNICAST
;
8507 if (argv_find (argv
, argc
, "ip", &idx
))
8509 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8510 vrf
= argv
[++idx
]->arg
;
8511 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8513 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8514 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8515 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8518 int uj
= use_json (argc
, argv
);
8520 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8523 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8527 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8528 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8530 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8533 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8535 /* BGP route print out function. */
8538 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8541 |dampening <flap-statistics|dampened-paths|parameters>\
8546 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8547 |community-list <(1-500)|WORD> [exact-match]\
8548 |A.B.C.D/M longer-prefixes\
8549 |X:X::X:X/M longer-prefixes>\
8554 BGP_INSTANCE_HELP_STR
8557 "Display only routes with non-natural netmasks\n"
8558 "Display detailed information about dampening\n"
8559 "Display flap statistics of routes\n"
8560 "Display paths suppressed due to dampening\n"
8561 "Display detail of configured dampening parameters\n"
8562 "Display routes matching the route-map\n"
8563 "A route-map to match on\n"
8564 "Display routes conforming to the prefix-list\n"
8565 "Prefix-list name\n"
8566 "Display routes conforming to the filter-list\n"
8567 "Regular expression access list name\n"
8568 "BGP RIB advertisement statistics\n"
8569 "Display routes matching the communities\n"
8571 "Do not send outside local AS (well-known community)\n"
8572 "Do not advertise to any peer (well-known community)\n"
8573 "Do not export to next AS (well-known community)\n"
8574 "Exact match of the communities\n"
8575 "Display routes matching the community-list\n"
8576 "community-list number\n"
8577 "community-list name\n"
8578 "Exact match of the communities\n"
8580 "Display route and more specific routes\n"
8582 "Display route and more specific routes\n"
8585 afi_t afi
= AFI_IP6
;
8586 safi_t safi
= SAFI_UNICAST
;
8587 int exact_match
= 0;
8588 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8589 struct bgp
*bgp
= NULL
;
8592 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8596 int uj
= use_json (argc
, argv
);
8599 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8600 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8602 if (argv_find(argv
, argc
, "dampening", &idx
))
8604 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8605 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8606 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8607 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8608 else if (argv_find (argv
, argc
, "parameters", &idx
))
8609 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8612 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8613 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8615 if (argv_find(argv
, argc
, "filter-list", &idx
))
8616 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8618 if (argv_find(argv
, argc
, "statistics", &idx
))
8619 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8621 if (argv_find(argv
, argc
, "route-map", &idx
))
8622 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8624 if (argv_find(argv
, argc
, "community", &idx
))
8626 /* show a specific community */
8627 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8628 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8629 argv_find (argv
, argc
, "no-export", &idx
))
8631 if (argv_find (argv
, argc
, "exact_match", &idx
))
8633 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8635 /* show all communities */
8637 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8640 if (argv_find(argv
, argc
, "community-list", &idx
))
8642 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8643 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8645 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8648 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8649 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8651 if (safi
== SAFI_MPLS_VPN
)
8652 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8654 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8657 DEFUN (show_ip_bgp_route
,
8658 show_ip_bgp_route_cmd
,
8659 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8660 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8664 BGP_INSTANCE_HELP_STR
8667 "Network in the BGP routing table to display\n"
8669 "Network in the BGP routing table to display\n"
8671 "Display only the bestpath\n"
8672 "Display only multipaths\n"
8675 int prefix_check
= 0;
8677 afi_t afi
= AFI_IP6
;
8678 safi_t safi
= SAFI_UNICAST
;
8679 char *prefix
= NULL
;
8680 struct bgp
*bgp
= NULL
;
8681 enum bgp_path_type path_type
;
8682 u_char uj
= use_json(argc
, argv
);
8686 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8692 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8696 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8697 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8699 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8702 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8704 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8707 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8709 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8713 prefix
= argv
[idx
]->arg
;
8715 /* [<bestpath|multipath>] */
8716 if (argv_find (argv
, argc
, "bestpath", &idx
))
8717 path_type
= BGP_PATH_BESTPATH
;
8718 else if (argv_find (argv
, argc
, "multipath", &idx
))
8719 path_type
= BGP_PATH_MULTIPATH
;
8721 path_type
= BGP_PATH_ALL
;
8723 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8726 DEFUN (show_ip_bgp_regexp
,
8727 show_ip_bgp_regexp_cmd
,
8728 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8732 BGP_INSTANCE_HELP_STR
8735 "Display routes matching the AS path regular expression\n"
8736 "A regular-expression to match the BGP AS paths\n")
8738 afi_t afi
= AFI_IP6
;
8739 safi_t safi
= SAFI_UNICAST
;
8740 struct bgp
*bgp
= NULL
;
8743 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8747 // get index of regex
8748 argv_find (argv
, argc
, "regexp", &idx
);
8751 char *regstr
= argv_concat (argv
, argc
, idx
);
8752 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8753 XFREE (MTYPE_TMP
, regstr
);
8757 DEFUN (show_ip_bgp_instance_all
,
8758 show_ip_bgp_instance_all_cmd
,
8759 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8763 BGP_INSTANCE_ALL_HELP_STR
8769 safi_t safi
= SAFI_UNICAST
;
8770 struct bgp
*bgp
= NULL
;
8773 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8777 int uj
= use_json (argc
, argv
);
8780 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8785 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8786 safi_t safi
, enum bgp_show_type type
)
8791 regex
= bgp_regcomp (regstr
);
8794 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8798 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8799 bgp_regex_free (regex
);
8804 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8805 const char *prefix_list_str
, afi_t afi
,
8806 safi_t safi
, enum bgp_show_type type
)
8808 struct prefix_list
*plist
;
8810 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8813 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8814 prefix_list_str
, VTY_NEWLINE
);
8818 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8822 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8823 const char *filter
, afi_t afi
,
8824 safi_t safi
, enum bgp_show_type type
)
8826 struct as_list
*as_list
;
8828 as_list
= as_list_lookup (filter
);
8829 if (as_list
== NULL
)
8831 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8835 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8839 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8840 const char *rmap_str
, afi_t afi
,
8841 safi_t safi
, enum bgp_show_type type
)
8843 struct route_map
*rmap
;
8845 rmap
= route_map_lookup_by_name (rmap_str
);
8848 vty_out (vty
, "%% %s is not a valid route-map name%s",
8849 rmap_str
, VTY_NEWLINE
);
8853 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8857 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8858 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8860 struct community
*com
;
8867 b
= buffer_new (1024);
8868 for (i
= 0; i
< argc
; i
++)
8871 buffer_putc (b
, ' ');
8874 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8879 buffer_putstr (b
, argv
[i
]->arg
);
8881 buffer_putc (b
, '\0');
8883 str
= buffer_getstr (b
);
8886 com
= community_str2com (str
);
8887 XFREE (MTYPE_TMP
, str
);
8890 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8894 ret
= bgp_show (vty
, bgp
, afi
, safi
,
8895 (exact
? bgp_show_type_community_exact
:
8896 bgp_show_type_community
), com
, 0);
8897 community_free (com
);
8903 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8904 const char *com
, int exact
,
8905 afi_t afi
, safi_t safi
)
8907 struct community_list
*list
;
8909 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8912 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8917 return bgp_show (vty
, bgp
, afi
, safi
,
8918 (exact
? bgp_show_type_community_list_exact
:
8919 bgp_show_type_community_list
), list
, 0);
8923 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8924 const char *prefix
, afi_t afi
,
8925 safi_t safi
, enum bgp_show_type type
)
8932 ret
= str2prefix (prefix
, p
);
8935 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8939 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8944 static struct peer
*
8945 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8946 const char *ip_str
, u_char use_json
)
8952 /* Get peer sockunion. */
8953 ret
= str2sockunion (ip_str
, &su
);
8956 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8959 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8965 json_object
*json_no
= NULL
;
8966 json_no
= json_object_new_object();
8967 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8968 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8969 json_object_free(json_no
);
8972 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8979 /* Peer structure lookup. */
8980 peer
= peer_lookup (bgp
, &su
);
8985 json_object
*json_no
= NULL
;
8986 json_no
= json_object_new_object();
8987 json_object_string_add(json_no
, "warning","No such neighbor");
8988 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8989 json_object_free(json_no
);
8992 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9001 BGP_STATS_MAXBITLEN
= 0,
9005 BGP_STATS_UNAGGREGATEABLE
,
9006 BGP_STATS_MAX_AGGREGATEABLE
,
9007 BGP_STATS_AGGREGATES
,
9009 BGP_STATS_ASPATH_COUNT
,
9010 BGP_STATS_ASPATH_MAXHOPS
,
9011 BGP_STATS_ASPATH_TOTHOPS
,
9012 BGP_STATS_ASPATH_MAXSIZE
,
9013 BGP_STATS_ASPATH_TOTSIZE
,
9014 BGP_STATS_ASN_HIGHEST
,
9018 static const char *table_stats_strs
[] =
9020 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9021 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9022 [BGP_STATS_RIB
] = "Total Advertisements",
9023 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9024 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9025 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9026 [BGP_STATS_SPACE
] = "Address space advertised",
9027 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9028 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9029 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9030 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9031 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9032 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9033 [BGP_STATS_MAX
] = NULL
,
9036 struct bgp_table_stats
9038 struct bgp_table
*table
;
9039 unsigned long long counts
[BGP_STATS_MAX
];
9043 #define TALLY_SIGFIG 100000
9044 static unsigned long
9045 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9047 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9048 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9049 unsigned long ret
= newtot
/ count
;
9051 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9059 bgp_table_stats_walker (struct thread
*t
)
9061 struct bgp_node
*rn
;
9062 struct bgp_node
*top
;
9063 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9064 unsigned int space
= 0;
9066 if (!(top
= bgp_table_top (ts
->table
)))
9069 switch (top
->p
.family
)
9072 space
= IPV4_MAX_BITLEN
;
9075 space
= IPV6_MAX_BITLEN
;
9079 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9081 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9083 struct bgp_info
*ri
;
9084 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9085 unsigned int rinum
= 0;
9093 ts
->counts
[BGP_STATS_PREFIXES
]++;
9094 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9097 ts
->counts
[BGP_STATS_AVGPLEN
]
9098 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9099 ts
->counts
[BGP_STATS_AVGPLEN
],
9103 /* check if the prefix is included by any other announcements */
9104 while (prn
&& !prn
->info
)
9105 prn
= bgp_node_parent_nolock (prn
);
9107 if (prn
== NULL
|| prn
== top
)
9109 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9110 /* announced address space */
9112 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9115 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9117 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9120 ts
->counts
[BGP_STATS_RIB
]++;
9123 (CHECK_FLAG (ri
->attr
->flag
,
9124 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9125 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9128 if (ri
->attr
&& ri
->attr
->aspath
)
9130 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9131 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9132 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9134 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9136 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9137 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9139 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9140 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9142 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9143 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9145 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9146 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9147 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9149 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9150 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9151 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9154 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9155 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9163 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9165 struct bgp_table_stats ts
;
9168 if (!bgp
->rib
[afi
][safi
])
9170 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
9171 afi
, safi
, VTY_NEWLINE
);
9175 memset (&ts
, 0, sizeof (ts
));
9176 ts
.table
= bgp
->rib
[afi
][safi
];
9177 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9179 vty_out (vty
, "BGP %s RIB statistics%s%s",
9180 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
9182 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9184 if (!table_stats_strs
[i
])
9190 case BGP_STATS_ASPATH_AVGHOPS
:
9191 case BGP_STATS_ASPATH_AVGSIZE
:
9192 case BGP_STATS_AVGPLEN
:
9193 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9194 vty_out (vty
, "%12.2f",
9195 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9198 case BGP_STATS_ASPATH_TOTHOPS
:
9199 case BGP_STATS_ASPATH_TOTSIZE
:
9200 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9201 vty_out (vty
, "%12.2f",
9203 (float)ts
.counts
[i
] /
9204 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9207 case BGP_STATS_TOTPLEN
:
9208 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9209 vty_out (vty
, "%12.2f",
9211 (float)ts
.counts
[i
] /
9212 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9215 case BGP_STATS_SPACE
:
9216 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9217 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
9218 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9220 vty_out (vty
, "%30s: ", "%% announced ");
9221 vty_out (vty
, "%12.2f%s",
9222 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
9223 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
9225 vty_out (vty
, "%30s: ", "/8 equivalent ");
9226 vty_out (vty
, "%12.2f%s",
9227 (float)ts
.counts
[BGP_STATS_SPACE
] /
9228 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
9230 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9232 vty_out (vty
, "%30s: ", "/24 equivalent ");
9233 vty_out (vty
, "%12.2f",
9234 (float)ts
.counts
[BGP_STATS_SPACE
] /
9235 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9238 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9239 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9242 vty_out (vty
, "%s", VTY_NEWLINE
);
9257 PCOUNT_PFCNT
, /* the figure we display to users */
9261 static const char *pcount_strs
[] =
9263 [PCOUNT_ADJ_IN
] = "Adj-in",
9264 [PCOUNT_DAMPED
] = "Damped",
9265 [PCOUNT_REMOVED
] = "Removed",
9266 [PCOUNT_HISTORY
] = "History",
9267 [PCOUNT_STALE
] = "Stale",
9268 [PCOUNT_VALID
] = "Valid",
9269 [PCOUNT_ALL
] = "All RIB",
9270 [PCOUNT_COUNTED
] = "PfxCt counted",
9271 [PCOUNT_PFCNT
] = "Useable",
9272 [PCOUNT_MAX
] = NULL
,
9277 unsigned int count
[PCOUNT_MAX
];
9278 const struct peer
*peer
;
9279 const struct bgp_table
*table
;
9283 bgp_peer_count_walker (struct thread
*t
)
9285 struct bgp_node
*rn
;
9286 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9287 const struct peer
*peer
= pc
->peer
;
9289 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9291 struct bgp_adj_in
*ain
;
9292 struct bgp_info
*ri
;
9294 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9295 if (ain
->peer
== peer
)
9296 pc
->count
[PCOUNT_ADJ_IN
]++;
9298 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9300 char buf
[SU_ADDRSTRLEN
];
9302 if (ri
->peer
!= peer
)
9305 pc
->count
[PCOUNT_ALL
]++;
9307 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9308 pc
->count
[PCOUNT_DAMPED
]++;
9309 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9310 pc
->count
[PCOUNT_HISTORY
]++;
9311 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9312 pc
->count
[PCOUNT_REMOVED
]++;
9313 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9314 pc
->count
[PCOUNT_STALE
]++;
9315 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9316 pc
->count
[PCOUNT_VALID
]++;
9317 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9318 pc
->count
[PCOUNT_PFCNT
]++;
9320 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9322 pc
->count
[PCOUNT_COUNTED
]++;
9323 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9324 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9326 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9327 buf
, SU_ADDRSTRLEN
),
9333 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9334 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9336 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9337 buf
, SU_ADDRSTRLEN
),
9347 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9349 struct peer_pcounts pcounts
= { .peer
= peer
};
9351 json_object
*json
= NULL
;
9352 json_object
*json_loop
= NULL
;
9356 json
= json_object_new_object();
9357 json_loop
= json_object_new_object();
9360 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9361 || !peer
->bgp
->rib
[afi
][safi
])
9365 json_object_string_add(json
, "warning", "No such neighbor or address family");
9366 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9367 json_object_free(json
);
9370 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9375 memset (&pcounts
, 0, sizeof(pcounts
));
9376 pcounts
.peer
= peer
;
9377 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9379 /* in-place call via thread subsystem so as to record execution time
9380 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9381 * * on just vty_read()).
9383 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9387 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9388 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9389 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9391 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9392 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9394 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9396 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9398 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9399 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9401 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9402 json_object_free(json
);
9407 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9409 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9410 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9415 vty_out (vty
, "Prefix counts for %s, %s%s",
9416 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9419 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9420 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9421 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9423 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9424 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9426 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9428 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9429 peer
->host
, VTY_NEWLINE
);
9430 vty_out (vty
, "Please report this bug, with the above command output%s",
9438 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9439 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9440 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] "
9441 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9445 BGP_INSTANCE_HELP_STR
9448 "Address Family modifier\n"
9449 "Address Family modifier\n"
9450 "Address Family modifier\n"
9451 "Address Family modifier\n"
9452 "Address Family modifier\n"
9453 "Detailed information on TCP and BGP neighbor connections\n"
9454 "Neighbor to display information about\n"
9455 "Neighbor to display information about\n"
9456 "Neighbor on BGP configured interface\n"
9457 "Display detailed prefix count information\n"
9460 afi_t afi
= AFI_IP6
;
9461 safi_t safi
= SAFI_UNICAST
;
9464 struct bgp
*bgp
= NULL
;
9466 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9470 int uj
= use_json (argc
, argv
);
9473 argv_find (argv
, argc
, "neighbors", &idx
);
9474 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9478 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9481 #ifdef KEEP_OLD_VPN_COMMANDS
9482 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9483 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9484 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9489 "Display information about all VPNv4 NLRIs\n"
9490 "Detailed information on TCP and BGP neighbor connections\n"
9491 "Neighbor to display information about\n"
9492 "Neighbor to display information about\n"
9493 "Neighbor on BGP configured interface\n"
9494 "Display detailed prefix count information\n"
9499 u_char uj
= use_json(argc
, argv
);
9501 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9505 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9508 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9509 show_ip_bgp_vpn_all_route_prefix_cmd
,
9510 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9515 "Display information about all VPNv4 NLRIs\n"
9516 "Network in the BGP routing table to display\n"
9517 "Network in the BGP routing table to display\n"
9521 char *network
= NULL
;
9522 struct bgp
*bgp
= bgp_get_default();
9525 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9529 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9530 network
= argv
[idx
]->arg
;
9531 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9532 network
= argv
[idx
]->arg
;
9535 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9539 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9541 #endif /* KEEP_OLD_VPN_COMMANDS */
9543 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9544 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9545 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9551 "Display information about all EVPN NLRIs\n"
9552 "Network in the BGP routing table to display\n"
9553 "Network in the BGP routing table to display\n"
9557 char *network
= NULL
;
9559 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9560 network
= argv
[idx
]->arg
;
9561 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9562 network
= argv
[idx
]->arg
;
9565 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9568 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9572 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9573 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9575 struct bgp_table
*table
;
9576 struct bgp_adj_in
*ain
;
9577 struct bgp_adj_out
*adj
;
9578 unsigned long output_count
;
9579 unsigned long filtered_count
;
9580 struct bgp_node
*rn
;
9585 struct attr_extra extra
;
9587 struct update_subgroup
*subgrp
;
9588 json_object
*json_scode
= NULL
;
9589 json_object
*json_ocode
= NULL
;
9590 json_object
*json_ar
= NULL
;
9591 struct peer_af
*paf
;
9595 json_scode
= json_object_new_object();
9596 json_ocode
= json_object_new_object();
9597 json_ar
= json_object_new_object();
9599 json_object_string_add(json_scode
, "suppressed", "s");
9600 json_object_string_add(json_scode
, "damped", "d");
9601 json_object_string_add(json_scode
, "history", "h");
9602 json_object_string_add(json_scode
, "valid", "*");
9603 json_object_string_add(json_scode
, "best", ">");
9604 json_object_string_add(json_scode
, "multipath", "=");
9605 json_object_string_add(json_scode
, "internal", "i");
9606 json_object_string_add(json_scode
, "ribFailure", "r");
9607 json_object_string_add(json_scode
, "stale", "S");
9608 json_object_string_add(json_scode
, "removed", "R");
9610 json_object_string_add(json_ocode
, "igp", "i");
9611 json_object_string_add(json_ocode
, "egp", "e");
9612 json_object_string_add(json_ocode
, "incomplete", "?");
9621 json_object_string_add(json
, "alert", "no BGP");
9622 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9623 json_object_free(json
);
9626 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9630 table
= bgp
->rib
[afi
][safi
];
9632 output_count
= filtered_count
= 0;
9633 subgrp
= peer_subgroup(peer
, afi
, safi
);
9635 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9639 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9640 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9641 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9642 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9643 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9647 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9648 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9649 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9651 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9652 VTY_NEWLINE
, VTY_NEWLINE
);
9657 attr
.extra
= &extra
;
9658 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9662 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9664 if (ain
->peer
== peer
)
9670 json_object_int_add(json
, "bgpTableVersion", 0);
9671 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9672 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9673 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9677 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9678 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9679 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9686 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9691 bgp_attr_dup(&attr
, ain
->attr
);
9692 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9694 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9705 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9706 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9707 if (paf
->peer
== peer
)
9713 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9714 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9715 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9716 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9720 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9721 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9722 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9723 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9731 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9737 bgp_attr_dup(&attr
, adj
->attr
);
9738 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9739 if (ret
!= RMAP_DENY
)
9741 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9751 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9753 if (output_count
!= 0)
9756 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9758 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9759 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9763 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9764 json_object_free(json
);
9770 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9771 int in
, const char *rmap_name
, u_char use_json
)
9773 json_object
*json
= NULL
;
9776 json
= json_object_new_object();
9778 if (!peer
|| !peer
->afc
[afi
][safi
])
9782 json_object_string_add(json
, "warning", "No such neighbor or address family");
9783 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9784 json_object_free(json
);
9787 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9792 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9796 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9797 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9798 json_object_free(json
);
9801 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9806 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9811 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9812 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9813 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9814 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9818 BGP_INSTANCE_HELP_STR
9821 "Detailed information on TCP and BGP neighbor connections\n"
9822 "Neighbor to display information about\n"
9823 "Neighbor to display information about\n"
9824 "Neighbor on BGP configured interface\n"
9825 "Display the received routes from neighbor\n"
9826 "Display the routes advertised to a BGP neighbor\n"
9827 "Route-map to modify the attributes\n"
9828 "Name of the route map\n"
9831 afi_t afi
= AFI_IP6
;
9832 safi_t safi
= SAFI_UNICAST
;
9833 char *rmap_name
= NULL
;
9834 char *peerstr
= NULL
;
9836 struct bgp
*bgp
= NULL
;
9841 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9845 int uj
= use_json (argc
, argv
);
9848 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9849 argv_find (argv
, argc
, "neighbors", &idx
);
9850 peerstr
= argv
[++idx
]->arg
;
9852 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9856 if (argv_find (argv
, argc
, "received-routes", &idx
))
9858 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9860 if (argv_find (argv
, argc
, "route-map", &idx
))
9861 rmap_name
= argv
[++idx
]->arg
;
9863 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9866 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9867 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9868 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9874 "Address Family modifier\n"
9875 "Detailed information on TCP and BGP neighbor connections\n"
9876 "Neighbor to display information about\n"
9877 "Neighbor to display information about\n"
9878 "Neighbor on BGP configured interface\n"
9879 "Display information received from a BGP neighbor\n"
9880 "Display the prefixlist filter\n"
9883 afi_t afi
= AFI_IP6
;
9884 safi_t safi
= SAFI_UNICAST
;
9885 char *peerstr
= NULL
;
9895 if (argv_find (argv
, argc
, "ip", &idx
))
9897 /* [<ipv4|ipv6> [unicast]] */
9898 if (argv_find (argv
, argc
, "ipv4", &idx
))
9900 if (argv_find (argv
, argc
, "ipv6", &idx
))
9902 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9903 argv_find (argv
, argc
, "neighbors", &idx
);
9904 peerstr
= argv
[++idx
]->arg
;
9906 u_char uj
= use_json(argc
, argv
);
9908 ret
= str2sockunion (peerstr
, &su
);
9911 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9915 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9917 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9923 peer
= peer_lookup (NULL
, &su
);
9927 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9929 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9934 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9935 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9939 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9940 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9945 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9947 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9954 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9955 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9957 if (! peer
|| ! peer
->afc
[afi
][safi
])
9961 json_object
*json_no
= NULL
;
9962 json_no
= json_object_new_object();
9963 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9964 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9965 json_object_free(json_no
);
9968 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9972 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9975 DEFUN (show_ip_bgp_neighbor_routes
,
9976 show_ip_bgp_neighbor_routes_cmd
,
9977 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9978 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9982 BGP_INSTANCE_HELP_STR
9985 "Detailed information on TCP and BGP neighbor connections\n"
9986 "Neighbor to display information about\n"
9987 "Neighbor to display information about\n"
9988 "Neighbor on BGP configured interface\n"
9989 "Display flap statistics of the routes learned from neighbor\n"
9990 "Display the dampened routes received from neighbor\n"
9991 "Display routes learned from neighbor\n"
9994 char *peerstr
= NULL
;
9995 struct bgp
*bgp
= NULL
;
9996 afi_t afi
= AFI_IP6
;
9997 safi_t safi
= SAFI_UNICAST
;
9999 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10003 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10005 return CMD_WARNING
;
10007 int uj
= use_json (argc
, argv
);
10010 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10011 argv_find (argv
, argc
, "neighbors", &idx
);
10012 peerstr
= argv
[++idx
]->arg
;
10014 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10017 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
10018 return CMD_WARNING
;
10021 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10022 sh_type
= bgp_show_type_flap_neighbor
;
10023 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10024 sh_type
= bgp_show_type_damp_neighbor
;
10025 else if (argv_find (argv
, argc
, "routes", &idx
))
10026 sh_type
= bgp_show_type_neighbor
;
10028 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10031 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10033 struct bgp_distance
10035 /* Distance value for the IP source prefix. */
10038 /* Name of the access-list to be matched. */
10042 DEFUN (show_bgp_afi_vpn_rd_route
,
10043 show_bgp_afi_vpn_rd_route_cmd
,
10044 "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]",
10048 "Address Family modifier\n"
10049 "Display information for a route distinguisher\n"
10050 "Route Distinguisher\n"
10051 "Network in the BGP routing table to display\n"
10052 "Network in the BGP routing table to display\n"
10056 struct prefix_rd prd
;
10057 afi_t afi
= AFI_MAX
;
10060 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10061 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10064 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
10065 return CMD_WARNING
;
10067 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10070 static struct bgp_distance
*
10071 bgp_distance_new (void)
10073 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10077 bgp_distance_free (struct bgp_distance
*bdistance
)
10079 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10083 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10084 const char *ip_str
, const char *access_list_str
)
10091 struct bgp_node
*rn
;
10092 struct bgp_distance
*bdistance
;
10094 afi
= bgp_node_afi (vty
);
10095 safi
= bgp_node_safi (vty
);
10097 ret
= str2prefix (ip_str
, &p
);
10100 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10101 return CMD_WARNING
;
10104 distance
= atoi (distance_str
);
10106 /* Get BGP distance node. */
10107 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10110 bdistance
= rn
->info
;
10111 bgp_unlock_node (rn
);
10115 bdistance
= bgp_distance_new ();
10116 rn
->info
= bdistance
;
10119 /* Set distance value. */
10120 bdistance
->distance
= distance
;
10122 /* Reset access-list configuration. */
10123 if (bdistance
->access_list
)
10125 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10126 bdistance
->access_list
= NULL
;
10128 if (access_list_str
)
10129 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10131 return CMD_SUCCESS
;
10135 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10136 const char *ip_str
, const char *access_list_str
)
10143 struct bgp_node
*rn
;
10144 struct bgp_distance
*bdistance
;
10146 afi
= bgp_node_afi (vty
);
10147 safi
= bgp_node_safi (vty
);
10149 ret
= str2prefix (ip_str
, &p
);
10152 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10153 return CMD_WARNING
;
10156 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10159 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
10160 return CMD_WARNING
;
10163 bdistance
= rn
->info
;
10164 distance
= atoi(distance_str
);
10166 if (bdistance
->distance
!= distance
)
10168 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
10169 return CMD_WARNING
;
10172 if (bdistance
->access_list
)
10173 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10174 bgp_distance_free (bdistance
);
10177 bgp_unlock_node (rn
);
10178 bgp_unlock_node (rn
);
10180 return CMD_SUCCESS
;
10183 /* Apply BGP information to distance method. */
10185 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10186 safi_t safi
, struct bgp
*bgp
)
10188 struct bgp_node
*rn
;
10191 struct bgp_distance
*bdistance
;
10192 struct access_list
*alist
;
10193 struct bgp_static
*bgp_static
;
10198 peer
= rinfo
->peer
;
10200 /* Check source address. */
10201 sockunion2hostprefix (&peer
->su
, &q
);
10202 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10205 bdistance
= rn
->info
;
10206 bgp_unlock_node (rn
);
10208 if (bdistance
->access_list
)
10210 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10211 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10212 return bdistance
->distance
;
10215 return bdistance
->distance
;
10218 /* Backdoor check. */
10219 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10222 bgp_static
= rn
->info
;
10223 bgp_unlock_node (rn
);
10225 if (bgp_static
->backdoor
)
10227 if (bgp
->distance_local
[afi
][safi
])
10228 return bgp
->distance_local
[afi
][safi
];
10230 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10234 if (peer
->sort
== BGP_PEER_EBGP
)
10236 if (bgp
->distance_ebgp
[afi
][safi
])
10237 return bgp
->distance_ebgp
[afi
][safi
];
10238 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10242 if (bgp
->distance_ibgp
[afi
][safi
])
10243 return bgp
->distance_ibgp
[afi
][safi
];
10244 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10248 DEFUN (bgp_distance
,
10250 "distance bgp (1-255) (1-255) (1-255)",
10251 "Define an administrative distance\n"
10253 "Distance for routes external to the AS\n"
10254 "Distance for routes internal to the AS\n"
10255 "Distance for local routes\n")
10257 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10258 int idx_number
= 2;
10259 int idx_number_2
= 3;
10260 int idx_number_3
= 4;
10264 afi
= bgp_node_afi (vty
);
10265 safi
= bgp_node_safi (vty
);
10267 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10268 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10269 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10270 return CMD_SUCCESS
;
10273 DEFUN (no_bgp_distance
,
10274 no_bgp_distance_cmd
,
10275 "no distance bgp [(1-255) (1-255) (1-255)]",
10277 "Define an administrative distance\n"
10279 "Distance for routes external to the AS\n"
10280 "Distance for routes internal to the AS\n"
10281 "Distance for local routes\n")
10283 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10287 afi
= bgp_node_afi (vty
);
10288 safi
= bgp_node_safi (vty
);
10290 bgp
->distance_ebgp
[afi
][safi
] = 0;
10291 bgp
->distance_ibgp
[afi
][safi
] = 0;
10292 bgp
->distance_local
[afi
][safi
] = 0;
10293 return CMD_SUCCESS
;
10297 DEFUN (bgp_distance_source
,
10298 bgp_distance_source_cmd
,
10299 "distance (1-255) A.B.C.D/M",
10300 "Define an administrative distance\n"
10301 "Administrative distance\n"
10302 "IP source prefix\n")
10304 int idx_number
= 1;
10305 int idx_ipv4_prefixlen
= 2;
10306 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10307 return CMD_SUCCESS
;
10310 DEFUN (no_bgp_distance_source
,
10311 no_bgp_distance_source_cmd
,
10312 "no distance (1-255) A.B.C.D/M",
10314 "Define an administrative distance\n"
10315 "Administrative distance\n"
10316 "IP source prefix\n")
10318 int idx_number
= 2;
10319 int idx_ipv4_prefixlen
= 3;
10320 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10321 return CMD_SUCCESS
;
10324 DEFUN (bgp_distance_source_access_list
,
10325 bgp_distance_source_access_list_cmd
,
10326 "distance (1-255) A.B.C.D/M WORD",
10327 "Define an administrative distance\n"
10328 "Administrative distance\n"
10329 "IP source prefix\n"
10330 "Access list name\n")
10332 int idx_number
= 1;
10333 int idx_ipv4_prefixlen
= 2;
10335 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10336 return CMD_SUCCESS
;
10339 DEFUN (no_bgp_distance_source_access_list
,
10340 no_bgp_distance_source_access_list_cmd
,
10341 "no distance (1-255) A.B.C.D/M WORD",
10343 "Define an administrative distance\n"
10344 "Administrative distance\n"
10345 "IP source prefix\n"
10346 "Access list name\n")
10348 int idx_number
= 2;
10349 int idx_ipv4_prefixlen
= 3;
10351 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10352 return CMD_SUCCESS
;
10355 DEFUN (ipv6_bgp_distance_source
,
10356 ipv6_bgp_distance_source_cmd
,
10357 "distance (1-255) X:X::X:X/M",
10358 "Define an administrative distance\n"
10359 "Administrative distance\n"
10360 "IP source prefix\n")
10362 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10363 return CMD_SUCCESS
;
10366 DEFUN (no_ipv6_bgp_distance_source
,
10367 no_ipv6_bgp_distance_source_cmd
,
10368 "no distance (1-255) X:X::X:X/M",
10370 "Define an administrative distance\n"
10371 "Administrative distance\n"
10372 "IP source prefix\n")
10374 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10375 return CMD_SUCCESS
;
10378 DEFUN (ipv6_bgp_distance_source_access_list
,
10379 ipv6_bgp_distance_source_access_list_cmd
,
10380 "distance (1-255) X:X::X:X/M WORD",
10381 "Define an administrative distance\n"
10382 "Administrative distance\n"
10383 "IP source prefix\n"
10384 "Access list name\n")
10386 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10387 return CMD_SUCCESS
;
10390 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10391 no_ipv6_bgp_distance_source_access_list_cmd
,
10392 "no distance (1-255) X:X::X:X/M WORD",
10394 "Define an administrative distance\n"
10395 "Administrative distance\n"
10396 "IP source prefix\n"
10397 "Access list name\n")
10399 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10400 return CMD_SUCCESS
;
10403 DEFUN (bgp_damp_set
,
10405 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10406 "BGP Specific commands\n"
10407 "Enable route-flap dampening\n"
10408 "Half-life time for the penalty\n"
10409 "Value to start reusing a route\n"
10410 "Value to start suppressing a route\n"
10411 "Maximum duration to suppress a stable route\n")
10413 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10414 int idx_half_life
= 2;
10416 int idx_suppress
= 4;
10417 int idx_max_suppress
= 5;
10418 int half
= DEFAULT_HALF_LIFE
* 60;
10419 int reuse
= DEFAULT_REUSE
;
10420 int suppress
= DEFAULT_SUPPRESS
;
10421 int max
= 4 * half
;
10425 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10426 reuse
= atoi (argv
[idx_reuse
]->arg
);
10427 suppress
= atoi (argv
[idx_suppress
]->arg
);
10428 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10430 else if (argc
== 3)
10432 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10436 if (suppress
< reuse
)
10438 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10443 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10444 half
, reuse
, suppress
, max
);
10447 DEFUN (bgp_damp_unset
,
10448 bgp_damp_unset_cmd
,
10449 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10451 "BGP Specific commands\n"
10452 "Enable route-flap dampening\n"
10453 "Half-life time for the penalty\n"
10454 "Value to start reusing a route\n"
10455 "Value to start suppressing a route\n"
10456 "Maximum duration to suppress a stable route\n")
10458 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10459 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10462 /* Display specified route of BGP table. */
10464 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10465 const char *ip_str
, afi_t afi
, safi_t safi
,
10466 struct prefix_rd
*prd
, int prefix_check
)
10469 struct prefix match
;
10470 struct bgp_node
*rn
;
10471 struct bgp_node
*rm
;
10472 struct bgp_info
*ri
;
10473 struct bgp_info
*ri_temp
;
10475 struct bgp_table
*table
;
10477 /* BGP structure lookup. */
10480 bgp
= bgp_lookup_by_name (view_name
);
10483 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10484 return CMD_WARNING
;
10489 bgp
= bgp_get_default ();
10492 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10493 return CMD_WARNING
;
10497 /* Check IP address argument. */
10498 ret
= str2prefix (ip_str
, &match
);
10501 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10502 return CMD_WARNING
;
10505 match
.family
= afi2family (afi
);
10507 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10509 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10511 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10514 if ((table
= rn
->info
) != NULL
)
10515 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10517 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10522 if (ri
->extra
&& ri
->extra
->damp_info
)
10524 ri_temp
= ri
->next
;
10525 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10533 bgp_unlock_node (rm
);
10539 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10541 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10546 if (ri
->extra
&& ri
->extra
->damp_info
)
10548 ri_temp
= ri
->next
;
10549 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10557 bgp_unlock_node (rn
);
10561 return CMD_SUCCESS
;
10564 DEFUN (clear_ip_bgp_dampening
,
10565 clear_ip_bgp_dampening_cmd
,
10566 "clear ip bgp dampening",
10570 "Clear route flap dampening information\n")
10572 bgp_damp_info_clean ();
10573 return CMD_SUCCESS
;
10576 DEFUN (clear_ip_bgp_dampening_prefix
,
10577 clear_ip_bgp_dampening_prefix_cmd
,
10578 "clear ip bgp dampening A.B.C.D/M",
10582 "Clear route flap dampening information\n"
10585 int idx_ipv4_prefixlen
= 4;
10586 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10587 SAFI_UNICAST
, NULL
, 1);
10590 DEFUN (clear_ip_bgp_dampening_address
,
10591 clear_ip_bgp_dampening_address_cmd
,
10592 "clear ip bgp dampening A.B.C.D",
10596 "Clear route flap dampening information\n"
10597 "Network to clear damping information\n")
10600 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10601 SAFI_UNICAST
, NULL
, 0);
10604 DEFUN (clear_ip_bgp_dampening_address_mask
,
10605 clear_ip_bgp_dampening_address_mask_cmd
,
10606 "clear ip bgp dampening A.B.C.D A.B.C.D",
10610 "Clear route flap dampening information\n"
10611 "Network to clear damping information\n"
10615 int idx_ipv4_2
= 5;
10617 char prefix_str
[BUFSIZ
];
10619 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10622 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10623 return CMD_WARNING
;
10626 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10627 SAFI_UNICAST
, NULL
, 0);
10630 /* also used for encap safi */
10632 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10633 afi_t afi
, safi_t safi
, int *write
)
10635 struct bgp_node
*prn
;
10636 struct bgp_node
*rn
;
10637 struct bgp_table
*table
;
10639 struct prefix_rd
*prd
;
10640 struct bgp_static
*bgp_static
;
10642 char buf
[SU_ADDRSTRLEN
];
10643 char rdbuf
[RD_ADDRSTRLEN
];
10645 /* Network configuration. */
10646 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10647 if ((table
= prn
->info
) != NULL
)
10648 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10649 if ((bgp_static
= rn
->info
) != NULL
)
10652 prd
= (struct prefix_rd
*) &prn
->p
;
10654 /* "address-family" display. */
10655 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10657 /* "network" configuration display. */
10658 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10659 label
= decode_label (bgp_static
->tag
);
10661 vty_out (vty
, " network %s/%d rd %s",
10662 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10663 p
->prefixlen
, rdbuf
);
10664 if (safi
== SAFI_MPLS_VPN
)
10665 vty_out (vty
, " label %u", label
);
10667 if (bgp_static
->rmap
.name
)
10668 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10671 if (bgp_static
->backdoor
)
10672 vty_out (vty
, " backdoor");
10674 vty_out (vty
, "%s", VTY_NEWLINE
);
10680 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10681 afi_t afi
, safi_t safi
, int *write
)
10683 struct bgp_node
*prn
;
10684 struct bgp_node
*rn
;
10685 struct bgp_table
*table
;
10687 struct prefix_rd
*prd
;
10688 struct bgp_static
*bgp_static
;
10689 char buf
[PREFIX_STRLEN
];
10690 char buf2
[SU_ADDRSTRLEN
];
10691 char rdbuf
[RD_ADDRSTRLEN
];
10693 /* Network configuration. */
10694 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10695 if ((table
= prn
->info
) != NULL
)
10696 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10697 if ((bgp_static
= rn
->info
) != NULL
)
10699 char *macrouter
= NULL
;
10702 if(bgp_static
->router_mac
)
10703 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10704 if(bgp_static
->eth_s_id
)
10705 esi
= esi2str(bgp_static
->eth_s_id
);
10707 prd
= (struct prefix_rd
*) &prn
->p
;
10709 /* "address-family" display. */
10710 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10712 /* "network" configuration display. */
10713 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10715 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10717 prefix2str (p
, buf
, sizeof (buf
)),
10718 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10719 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10720 decode_label (bgp_static
->tag
), esi
, buf2
, macrouter
);
10721 vty_out (vty
, "%s", VTY_NEWLINE
);
10723 XFREE (MTYPE_TMP
, macrouter
);
10725 XFREE (MTYPE_TMP
, esi
);
10730 /* Configuration of static route announcement and aggregate
10733 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10734 afi_t afi
, safi_t safi
, int *write
)
10736 struct bgp_node
*rn
;
10738 struct bgp_static
*bgp_static
;
10739 struct bgp_aggregate
*bgp_aggregate
;
10740 char buf
[SU_ADDRSTRLEN
];
10742 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10743 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10745 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10746 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10748 /* Network configuration. */
10749 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10750 if ((bgp_static
= rn
->info
) != NULL
)
10754 /* "address-family" display. */
10755 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10757 /* "network" configuration display. */
10758 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10760 u_int32_t destination
;
10761 struct in_addr netmask
;
10763 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10764 masklen2ip (p
->prefixlen
, &netmask
);
10765 vty_out (vty
, " network %s",
10766 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10768 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10769 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10770 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10771 || p
->u
.prefix4
.s_addr
== 0)
10773 /* Natural mask is not display. */
10776 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10780 vty_out (vty
, " network %s/%d",
10781 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10785 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10786 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10788 if (bgp_static
->rmap
.name
)
10789 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10792 if (bgp_static
->backdoor
)
10793 vty_out (vty
, " backdoor");
10796 vty_out (vty
, "%s", VTY_NEWLINE
);
10799 /* Aggregate-address configuration. */
10800 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10801 if ((bgp_aggregate
= rn
->info
) != NULL
)
10805 /* "address-family" display. */
10806 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10808 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10810 struct in_addr netmask
;
10812 masklen2ip (p
->prefixlen
, &netmask
);
10813 vty_out (vty
, " aggregate-address %s %s",
10814 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10815 inet_ntoa (netmask
));
10819 vty_out (vty
, " aggregate-address %s/%d",
10820 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10824 if (bgp_aggregate
->as_set
)
10825 vty_out (vty
, " as-set");
10827 if (bgp_aggregate
->summary_only
)
10828 vty_out (vty
, " summary-only");
10830 vty_out (vty
, "%s", VTY_NEWLINE
);
10837 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10838 safi_t safi
, int *write
)
10840 struct bgp_node
*rn
;
10841 struct bgp_distance
*bdistance
;
10843 /* Distance configuration. */
10844 if (bgp
->distance_ebgp
[afi
][safi
]
10845 && bgp
->distance_ibgp
[afi
][safi
]
10846 && bgp
->distance_local
[afi
][safi
]
10847 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10848 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10849 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10851 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10852 vty_out (vty
, " distance bgp %d %d %d%s",
10853 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10854 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10857 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10858 rn
= bgp_route_next (rn
))
10859 if ((bdistance
= rn
->info
) != NULL
)
10861 char buf
[PREFIX_STRLEN
];
10863 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10864 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10865 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10866 bdistance
->access_list
? bdistance
->access_list
: "",
10873 /* Allocate routing table structure and install commands. */
10875 bgp_route_init (void)
10880 /* Init BGP distance table. */
10881 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10882 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10883 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10885 /* IPv4 BGP commands. */
10886 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10887 install_element (BGP_NODE
, &bgp_network_cmd
);
10888 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10889 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10890 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10891 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10892 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10893 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10894 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10895 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10896 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10897 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10898 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10899 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10901 install_element (BGP_NODE
, &aggregate_address_cmd
);
10902 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10903 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10904 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10906 /* IPv4 unicast configuration. */
10907 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10908 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10909 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10910 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10911 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10912 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10913 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10914 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_cmd
);
10915 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_route_map_cmd
);
10916 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10917 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10918 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10919 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10921 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10922 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10923 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10924 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10926 /* IPv4 multicast configuration. */
10927 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10928 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10929 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10930 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10931 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10932 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10933 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10934 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10935 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10936 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10937 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10938 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10939 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10940 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10941 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10943 /* IPv4 labeled-unicast configuration. */
10944 install_element (BGP_IPV4L_NODE
, &bgp_table_map_cmd
);
10945 install_element (BGP_IPV4L_NODE
, &bgp_network_cmd
);
10946 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_cmd
);
10947 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_cmd
);
10948 install_element (BGP_IPV4L_NODE
, &bgp_network_route_map_cmd
);
10949 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_route_map_cmd
);
10950 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10951 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_cmd
);
10952 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_route_map_cmd
);
10953 install_element (BGP_IPV4L_NODE
, &no_bgp_table_map_cmd
);
10954 install_element (BGP_IPV4L_NODE
, &no_bgp_network_cmd
);
10955 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_cmd
);
10956 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_natural_cmd
);
10958 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10959 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10960 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10961 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10963 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10964 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10965 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10966 #ifdef KEEP_OLD_VPN_COMMANDS
10967 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10968 #endif /* KEEP_OLD_VPN_COMMANDS */
10969 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10970 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10972 /* BGP dampening clear commands */
10973 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10974 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10976 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10977 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10980 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10981 #ifdef KEEP_OLD_VPN_COMMANDS
10982 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10983 #endif /* KEEP_OLD_VPN_COMMANDS */
10985 /* New config IPv6 BGP commands. */
10986 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10987 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10988 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10989 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10990 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10991 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_label_index_cmd
);
10992 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
10993 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
10994 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
10996 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10997 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10999 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11000 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11002 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11003 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11004 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11005 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11006 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11008 install_element (BGP_NODE
, &bgp_distance_cmd
);
11009 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
11010 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
11011 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
11012 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11013 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11014 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11015 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11016 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11017 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11018 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11019 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11020 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11021 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11022 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11023 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11024 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11025 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11026 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11027 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11028 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11029 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11030 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11031 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11032 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11033 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11034 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11035 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11036 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11037 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11039 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11040 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11041 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11042 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11044 /* IPv4 Multicast Mode */
11045 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11046 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11048 /* Large Communities */
11049 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11050 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11054 bgp_route_finish (void)
11059 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11060 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11062 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11063 bgp_distance_table
[afi
][safi
] = NULL
;