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
))
3535 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3536 bgp_info_reap (rn
, ri
);
3541 /* Delete all kernel routes. */
3543 bgp_cleanup_routes (struct bgp
*bgp
)
3546 struct bgp_node
*rn
;
3548 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3550 if (afi
== AFI_L2VPN
)
3552 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3554 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3556 if (afi
!= AFI_L2VPN
)
3559 safi
= SAFI_MPLS_VPN
;
3560 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3561 rn
= bgp_route_next (rn
))
3565 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3566 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3568 bgp_unlock_node(rn
);
3572 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3573 rn
= bgp_route_next (rn
))
3577 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3578 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3580 bgp_unlock_node(rn
);
3585 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3586 rn
= bgp_route_next (rn
))
3590 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3591 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3593 bgp_unlock_node(rn
);
3602 bgp_zclient_reset ();
3603 access_list_reset ();
3604 prefix_list_reset ();
3608 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3610 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3611 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3614 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3617 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3618 struct bgp_nlri
*packet
)
3627 int addpath_encoded
;
3628 u_int32_t addpath_id
;
3630 /* Check peer status. */
3631 if (peer
->status
!= Established
)
3635 lim
= pnt
+ packet
->length
;
3637 safi
= packet
->safi
;
3639 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3641 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3642 syntactic validity. If the field is syntactically incorrect,
3643 then the Error Subcode is set to Invalid Network Field. */
3644 for (; pnt
< lim
; pnt
+= psize
)
3646 /* Clear prefix structure. */
3647 memset (&p
, 0, sizeof (struct prefix
));
3649 if (addpath_encoded
)
3652 /* When packet overflow occurs return immediately. */
3653 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3656 addpath_id
= ntohl(*((uint32_t*) pnt
));
3657 pnt
+= BGP_ADDPATH_ID_LEN
;
3660 /* Fetch prefix length. */
3661 p
.prefixlen
= *pnt
++;
3662 /* afi/safi validity already verified by caller, bgp_update_receive */
3663 p
.family
= afi2family (afi
);
3665 /* Prefix length check. */
3666 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3668 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3669 peer
->host
, p
.prefixlen
, packet
->afi
);
3673 /* Packet size overflow check. */
3674 psize
= PSIZE (p
.prefixlen
);
3676 /* When packet overflow occur return immediately. */
3677 if (pnt
+ psize
> lim
)
3679 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3680 peer
->host
, p
.prefixlen
);
3684 /* Defensive coding, double-check the psize fits in a struct prefix */
3685 if (psize
> (ssize_t
) sizeof(p
.u
))
3687 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3688 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3692 /* Fetch prefix from NLRI packet. */
3693 memcpy (&p
.u
.prefix
, pnt
, psize
);
3695 /* Check address. */
3696 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3698 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3700 /* From RFC4271 Section 6.3:
3702 * If a prefix in the NLRI field is semantically incorrect
3703 * (e.g., an unexpected multicast IP address), an error SHOULD
3704 * be logged locally, and the prefix SHOULD be ignored.
3706 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3707 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3712 /* Check address. */
3713 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3715 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3719 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3720 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3724 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3728 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3729 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3735 /* Normal process. */
3737 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3738 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3740 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3741 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3743 /* Address family configuration mismatch or maximum-prefix count
3749 /* Packet length consistency check. */
3752 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3760 static struct bgp_static
*
3761 bgp_static_new (void)
3763 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3767 bgp_static_free (struct bgp_static
*bgp_static
)
3769 if (bgp_static
->rmap
.name
)
3770 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3771 if(bgp_static
->eth_s_id
)
3772 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3773 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3777 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3778 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3780 struct bgp_node
*rn
;
3781 struct bgp_info
*ri
;
3782 struct bgp_info
*new;
3783 struct bgp_info info
;
3785 struct attr
*attr_new
;
3788 int vnc_implicit_withdraw
= 0;
3791 assert (bgp_static
);
3795 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3797 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3799 attr
.nexthop
= bgp_static
->igpnexthop
;
3800 attr
.med
= bgp_static
->igpmetric
;
3801 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3803 if (bgp_static
->atomic
)
3804 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3806 /* Store label index, if required. */
3807 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3809 (bgp_attr_extra_get (&attr
))->label_index
= bgp_static
->label_index
;
3810 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3813 /* Apply route-map. */
3814 if (bgp_static
->rmap
.name
)
3816 struct attr attr_tmp
= attr
;
3817 info
.peer
= bgp
->peer_self
;
3818 info
.attr
= &attr_tmp
;
3820 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3822 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3824 bgp
->peer_self
->rmap_type
= 0;
3826 if (ret
== RMAP_DENYMATCH
)
3828 /* Free uninterned attribute. */
3829 bgp_attr_flush (&attr_tmp
);
3831 /* Unintern original. */
3832 aspath_unintern (&attr
.aspath
);
3833 bgp_attr_extra_free (&attr
);
3834 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3837 attr_new
= bgp_attr_intern (&attr_tmp
);
3840 attr_new
= bgp_attr_intern (&attr
);
3842 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3843 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3844 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3849 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3850 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3851 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3853 bgp_unlock_node (rn
);
3854 bgp_attr_unintern (&attr_new
);
3855 aspath_unintern (&attr
.aspath
);
3856 bgp_attr_extra_free (&attr
);
3861 /* The attribute is changed. */
3862 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3864 /* Rewrite BGP route information. */
3865 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3866 bgp_info_restore(rn
, ri
);
3868 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3870 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3872 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3875 * Implicit withdraw case.
3876 * We have to do this before ri is changed
3878 ++vnc_implicit_withdraw
;
3879 vnc_import_bgp_del_route(bgp
, p
, ri
);
3880 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3884 bgp_attr_unintern (&ri
->attr
);
3885 ri
->attr
= attr_new
;
3886 ri
->uptime
= bgp_clock ();
3888 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3890 if (vnc_implicit_withdraw
)
3892 vnc_import_bgp_add_route(bgp
, p
, ri
);
3893 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3898 /* Nexthop reachability check. */
3899 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3900 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3902 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3903 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3906 if (BGP_DEBUG(nht
, NHT
))
3908 char buf1
[INET6_ADDRSTRLEN
];
3909 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3911 zlog_debug("%s(%s): Route not in table, not advertising",
3912 __FUNCTION__
, buf1
);
3914 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3919 /* Delete the NHT structure if any, if we're toggling between
3920 * enabling/disabling import check. We deregister the route
3921 * from NHT to avoid overloading NHT and the process interaction
3923 bgp_unlink_nexthop(ri
);
3924 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3926 /* Process change. */
3927 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3928 bgp_process (bgp
, rn
, afi
, safi
);
3929 bgp_unlock_node (rn
);
3930 aspath_unintern (&attr
.aspath
);
3931 bgp_attr_extra_free (&attr
);
3936 /* Make new BGP info. */
3937 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3939 /* Nexthop reachability check. */
3940 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3941 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3943 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3944 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3947 if (BGP_DEBUG(nht
, NHT
))
3949 char buf1
[INET6_ADDRSTRLEN
];
3950 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3952 zlog_debug("%s(%s): Route not in table, not advertising",
3953 __FUNCTION__
, buf1
);
3955 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3960 /* Delete the NHT structure if any, if we're toggling between
3961 * enabling/disabling import check. We deregister the route
3962 * from NHT to avoid overloading NHT and the process interaction
3964 bgp_unlink_nexthop(new);
3966 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3969 /* Aggregate address increment. */
3970 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3972 /* Register new BGP information. */
3973 bgp_info_add (rn
, new);
3975 /* route_node_get lock */
3976 bgp_unlock_node (rn
);
3978 /* Process change. */
3979 bgp_process (bgp
, rn
, afi
, safi
);
3981 /* Unintern original. */
3982 aspath_unintern (&attr
.aspath
);
3983 bgp_attr_extra_free (&attr
);
3987 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3990 struct bgp_node
*rn
;
3991 struct bgp_info
*ri
;
3993 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3995 /* Check selected route and self inserted route. */
3996 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3997 if (ri
->peer
== bgp
->peer_self
3998 && ri
->type
== ZEBRA_ROUTE_BGP
3999 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4002 /* Withdraw static BGP route from routing table. */
4005 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4006 bgp_unlink_nexthop(ri
);
4007 bgp_info_delete (rn
, ri
);
4008 bgp_process (bgp
, rn
, afi
, safi
);
4011 /* Unlock bgp_node_lookup. */
4012 bgp_unlock_node (rn
);
4016 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4019 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4020 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
4022 struct bgp_node
*rn
;
4023 struct bgp_info
*ri
;
4025 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4027 /* Check selected route and self inserted route. */
4028 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4029 if (ri
->peer
== bgp
->peer_self
4030 && ri
->type
== ZEBRA_ROUTE_BGP
4031 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4034 /* Withdraw static BGP route from routing table. */
4038 rfapiProcessWithdraw(
4047 1); /* Kill, since it is an administrative change */
4049 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4050 bgp_info_delete (rn
, ri
);
4051 bgp_process (bgp
, rn
, afi
, safi
);
4054 /* Unlock bgp_node_lookup. */
4055 bgp_unlock_node (rn
);
4059 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4060 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4062 struct bgp_node
*rn
;
4063 struct bgp_info
*new;
4064 struct attr
*attr_new
;
4065 struct attr attr
= { 0 };
4066 struct bgp_info
*ri
;
4068 u_int32_t label
= 0;
4072 assert (bgp_static
);
4074 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4076 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4078 attr
.nexthop
= bgp_static
->igpnexthop
;
4079 attr
.med
= bgp_static
->igpmetric
;
4080 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4082 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4086 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4087 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4090 if(afi
== AFI_L2VPN
)
4092 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4093 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4094 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4095 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4096 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4097 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4099 struct bgp_encap_type_vxlan bet
;
4100 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4101 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4102 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4104 if (bgp_static
->router_mac
)
4106 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4109 /* Apply route-map. */
4110 if (bgp_static
->rmap
.name
)
4112 struct attr attr_tmp
= attr
;
4113 struct bgp_info info
;
4116 info
.peer
= bgp
->peer_self
;
4117 info
.attr
= &attr_tmp
;
4119 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4121 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4123 bgp
->peer_self
->rmap_type
= 0;
4125 if (ret
== RMAP_DENYMATCH
)
4127 /* Free uninterned attribute. */
4128 bgp_attr_flush (&attr_tmp
);
4130 /* Unintern original. */
4131 aspath_unintern (&attr
.aspath
);
4132 bgp_attr_extra_free (&attr
);
4133 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4138 attr_new
= bgp_attr_intern (&attr_tmp
);
4142 attr_new
= bgp_attr_intern (&attr
);
4145 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4146 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4147 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4153 memset(&add
, 0, sizeof(union gw_addr
));
4154 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4155 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4156 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4158 bgp_unlock_node (rn
);
4159 bgp_attr_unintern (&attr_new
);
4160 aspath_unintern (&attr
.aspath
);
4161 bgp_attr_extra_free (&attr
);
4166 /* The attribute is changed. */
4167 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4169 /* Rewrite BGP route information. */
4170 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4171 bgp_info_restore(rn
, ri
);
4173 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4174 bgp_attr_unintern (&ri
->attr
);
4175 ri
->attr
= attr_new
;
4176 ri
->uptime
= bgp_clock ();
4179 label
= decode_label (ri
->extra
->tag
);
4182 /* Process change. */
4183 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4184 bgp_process (bgp
, rn
, afi
, safi
);
4186 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4187 ri
->attr
, afi
, safi
,
4188 ri
->type
, ri
->sub_type
, &label
);
4190 bgp_unlock_node (rn
);
4191 aspath_unintern (&attr
.aspath
);
4192 bgp_attr_extra_free (&attr
);
4198 /* Make new BGP info. */
4199 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4201 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4202 new->extra
= bgp_info_extra_new();
4203 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4205 label
= decode_label (bgp_static
->tag
);
4208 /* Aggregate address increment. */
4209 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4211 /* Register new BGP information. */
4212 bgp_info_add (rn
, new);
4213 /* route_node_get lock */
4214 bgp_unlock_node (rn
);
4216 /* Process change. */
4217 bgp_process (bgp
, rn
, afi
, safi
);
4220 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4221 new->attr
, afi
, safi
,
4222 new->type
, new->sub_type
, &label
);
4225 /* Unintern original. */
4226 aspath_unintern (&attr
.aspath
);
4227 bgp_attr_extra_free (&attr
);
4230 /* Configure static BGP network. When user don't run zebra, static
4231 route should be installed as valid. */
4233 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4234 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4235 u_int32_t label_index
)
4237 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4240 struct bgp_static
*bgp_static
;
4241 struct bgp_node
*rn
;
4242 u_char need_update
= 0;
4244 /* Convert IP prefix string to struct prefix. */
4245 ret
= str2prefix (ip_str
, &p
);
4248 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4251 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4253 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4260 /* Set BGP static route configuration. */
4261 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4265 /* Configuration change. */
4266 bgp_static
= rn
->info
;
4268 /* Label index cannot be changed. */
4269 if (bgp_static
->label_index
!= label_index
)
4271 vty_out (vty
, "%% Label index cannot be changed%s", VTY_NEWLINE
);
4275 /* Check previous routes are installed into BGP. */
4276 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4279 bgp_static
->backdoor
= backdoor
;
4283 if (bgp_static
->rmap
.name
)
4284 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4285 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4286 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4290 if (bgp_static
->rmap
.name
)
4291 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4292 bgp_static
->rmap
.name
= NULL
;
4293 bgp_static
->rmap
.map
= NULL
;
4294 bgp_static
->valid
= 0;
4296 bgp_unlock_node (rn
);
4300 /* New configuration. */
4301 bgp_static
= bgp_static_new ();
4302 bgp_static
->backdoor
= backdoor
;
4303 bgp_static
->valid
= 0;
4304 bgp_static
->igpmetric
= 0;
4305 bgp_static
->igpnexthop
.s_addr
= 0;
4306 bgp_static
->label_index
= label_index
;
4310 if (bgp_static
->rmap
.name
)
4311 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4312 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4313 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4315 rn
->info
= bgp_static
;
4318 bgp_static
->valid
= 1;
4320 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4322 if (! bgp_static
->backdoor
)
4323 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4328 /* Configure static BGP network. */
4330 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4331 afi_t afi
, safi_t safi
)
4333 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4336 struct bgp_static
*bgp_static
;
4337 struct bgp_node
*rn
;
4339 /* Convert IP prefix string to struct prefix. */
4340 ret
= str2prefix (ip_str
, &p
);
4343 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4346 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4348 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4355 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4358 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4363 bgp_static
= rn
->info
;
4365 /* Update BGP RIB. */
4366 if (! bgp_static
->backdoor
)
4367 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4369 /* Clear configuration. */
4370 bgp_static_free (bgp_static
);
4372 bgp_unlock_node (rn
);
4373 bgp_unlock_node (rn
);
4379 bgp_static_add (struct bgp
*bgp
)
4383 struct bgp_node
*rn
;
4384 struct bgp_node
*rm
;
4385 struct bgp_table
*table
;
4386 struct bgp_static
*bgp_static
;
4388 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4389 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4390 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4391 if (rn
->info
!= NULL
)
4393 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4397 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4399 bgp_static
= rm
->info
;
4400 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4405 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4410 /* Called from bgp_delete(). Delete all static routes from the BGP
4413 bgp_static_delete (struct bgp
*bgp
)
4417 struct bgp_node
*rn
;
4418 struct bgp_node
*rm
;
4419 struct bgp_table
*table
;
4420 struct bgp_static
*bgp_static
;
4422 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4423 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4424 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4425 if (rn
->info
!= NULL
)
4427 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4431 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4433 bgp_static
= rm
->info
;
4434 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4436 (struct prefix_rd
*)&rn
->p
,
4438 bgp_static_free (bgp_static
);
4440 bgp_unlock_node (rn
);
4445 bgp_static
= rn
->info
;
4446 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4447 bgp_static_free (bgp_static
);
4449 bgp_unlock_node (rn
);
4455 bgp_static_redo_import_check (struct bgp
*bgp
)
4459 struct bgp_node
*rn
;
4460 struct bgp_node
*rm
;
4461 struct bgp_table
*table
;
4462 struct bgp_static
*bgp_static
;
4464 /* Use this flag to force reprocessing of the route */
4465 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4466 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4467 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4468 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4469 if (rn
->info
!= NULL
)
4471 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4475 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4477 bgp_static
= rm
->info
;
4478 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4483 bgp_static
= rn
->info
;
4484 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4487 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4491 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4493 struct bgp_table
*table
;
4494 struct bgp_node
*rn
;
4495 struct bgp_info
*ri
;
4497 table
= bgp
->rib
[afi
][safi
];
4498 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4500 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4502 if (ri
->peer
== bgp
->peer_self
&&
4503 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4504 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4505 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4506 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4508 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4509 bgp_unlink_nexthop(ri
);
4510 bgp_info_delete (rn
, ri
);
4511 bgp_process (bgp
, rn
, afi
, safi
);
4518 * Purge all networks and redistributed routes from routing table.
4519 * Invoked upon the instance going down.
4522 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4527 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4528 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4529 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4534 * Currently this is used to set static routes for VPN and ENCAP.
4535 * I think it can probably be factored with bgp_static_set.
4538 bgp_static_set_safi (afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4539 const char *rd_str
, const char *label_str
,
4540 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4541 const char *ethtag
, const char *routermac
)
4543 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4546 struct prefix_rd prd
;
4547 struct bgp_node
*prn
;
4548 struct bgp_node
*rn
;
4549 struct bgp_table
*table
;
4550 struct bgp_static
*bgp_static
;
4552 struct prefix gw_ip
;
4554 /* validate ip prefix */
4555 ret
= str2prefix (ip_str
, &p
);
4558 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4562 if ( (afi
== AFI_L2VPN
) &&
4563 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4565 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4569 ret
= str2prefix_rd (rd_str
, &prd
);
4572 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4578 unsigned long label_val
;
4579 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, 16777215);
4580 encode_label (label_val
, tag
);
4584 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4586 if (safi
== SAFI_EVPN
)
4588 if( esi
&& str2esi (esi
, NULL
) == 0)
4590 vty_out (vty
, "%% Malformed ESI%s", VTY_NEWLINE
);
4593 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4595 vty_out (vty
, "%% Malformed Router MAC%s", VTY_NEWLINE
);
4600 memset (&gw_ip
, 0, sizeof (struct prefix
));
4601 ret
= str2prefix (gwip
, &gw_ip
);
4604 vty_out (vty
, "%% Malformed GatewayIp%s", VTY_NEWLINE
);
4607 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4608 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4610 vty_out (vty
, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE
);
4615 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4616 (struct prefix
*)&prd
);
4617 if (prn
->info
== NULL
)
4618 prn
->info
= bgp_table_init (afi
, safi
);
4620 bgp_unlock_node (prn
);
4623 rn
= bgp_node_get (table
, &p
);
4627 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4628 bgp_unlock_node (rn
);
4632 /* New configuration. */
4633 bgp_static
= bgp_static_new ();
4634 bgp_static
->backdoor
= 0;
4635 bgp_static
->valid
= 0;
4636 bgp_static
->igpmetric
= 0;
4637 bgp_static
->igpnexthop
.s_addr
= 0;
4638 memcpy(bgp_static
->tag
, tag
, 3);
4639 bgp_static
->prd
= prd
;
4643 if (bgp_static
->rmap
.name
)
4644 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4645 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4646 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4649 if (safi
== SAFI_EVPN
)
4653 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4654 str2esi (esi
, bgp_static
->eth_s_id
);
4658 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4659 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4662 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4664 rn
->info
= bgp_static
;
4666 bgp_static
->valid
= 1;
4667 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4673 /* Configure static BGP network. */
4675 bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4676 const char *rd_str
, const char *label_str
,
4677 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4679 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4682 struct prefix_rd prd
;
4683 struct bgp_node
*prn
;
4684 struct bgp_node
*rn
;
4685 struct bgp_table
*table
;
4686 struct bgp_static
*bgp_static
;
4689 /* Convert IP prefix string to struct prefix. */
4690 ret
= str2prefix (ip_str
, &p
);
4693 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4697 if ( (afi
== AFI_L2VPN
) &&
4698 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4700 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4703 ret
= str2prefix_rd (rd_str
, &prd
);
4706 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4712 unsigned long label_val
;
4713 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, MPLS_LABEL_MAX
);
4714 encode_label (label_val
, tag
);
4718 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4721 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4722 (struct prefix
*)&prd
);
4723 if (prn
->info
== NULL
)
4724 prn
->info
= bgp_table_init (afi
, safi
);
4726 bgp_unlock_node (prn
);
4729 rn
= bgp_node_lookup (table
, &p
);
4733 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
, tag
);
4735 bgp_static
= rn
->info
;
4736 bgp_static_free (bgp_static
);
4738 bgp_unlock_node (rn
);
4739 bgp_unlock_node (rn
);
4742 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4748 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4749 const char *rmap_name
)
4751 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4752 struct bgp_rmap
*rmap
;
4754 rmap
= &bgp
->table_map
[afi
][safi
];
4758 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4759 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4760 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4765 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4770 bgp_zebra_announce_table(bgp
, afi
, safi
);
4776 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4777 const char *rmap_name
)
4779 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4780 struct bgp_rmap
*rmap
;
4782 rmap
= &bgp
->table_map
[afi
][safi
];
4784 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4788 bgp_zebra_announce_table(bgp
, afi
, safi
);
4794 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4795 safi_t safi
, int *write
)
4797 if (bgp
->table_map
[afi
][safi
].name
)
4799 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4800 vty_out (vty
, " table-map %s%s",
4801 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4807 DEFUN (bgp_table_map
,
4810 "BGP table to RIB route download filter\n"
4811 "Name of the route map\n")
4814 return bgp_table_map_set (vty
,
4815 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4817 DEFUN (no_bgp_table_map
,
4818 no_bgp_table_map_cmd
,
4819 "no table-map WORD",
4821 "BGP table to RIB route download filter\n"
4822 "Name of the route map\n")
4825 return bgp_table_map_unset (vty
,
4826 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4831 "network A.B.C.D/M",
4832 "Specify a network to announce via BGP\n"
4835 int idx_ipv4_prefixlen
= 1;
4836 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4837 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4838 BGP_INVALID_LABEL_INDEX
);
4841 DEFUN (bgp_network_route_map
,
4842 bgp_network_route_map_cmd
,
4843 "network A.B.C.D/M route-map WORD",
4844 "Specify a network to announce via BGP\n"
4846 "Route-map to modify the attributes\n"
4847 "Name of the route map\n")
4849 int idx_ipv4_prefixlen
= 1;
4851 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4852 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4853 BGP_INVALID_LABEL_INDEX
);
4856 DEFUN (bgp_network_backdoor
,
4857 bgp_network_backdoor_cmd
,
4858 "network A.B.C.D/M backdoor",
4859 "Specify a network to announce via BGP\n"
4861 "Specify a BGP backdoor route\n")
4863 int idx_ipv4_prefixlen
= 1;
4864 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4865 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4868 DEFUN (bgp_network_mask
,
4869 bgp_network_mask_cmd
,
4870 "network A.B.C.D mask A.B.C.D",
4871 "Specify a network to announce via BGP\n"
4879 char prefix_str
[BUFSIZ
];
4881 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4884 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4888 return bgp_static_set (vty
, prefix_str
,
4889 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
4892 DEFUN (bgp_network_mask_route_map
,
4893 bgp_network_mask_route_map_cmd
,
4894 "network A.B.C.D mask A.B.C.D route-map WORD",
4895 "Specify a network to announce via BGP\n"
4899 "Route-map to modify the attributes\n"
4900 "Name of the route map\n")
4906 char prefix_str
[BUFSIZ
];
4908 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4911 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4915 return bgp_static_set (vty
, prefix_str
,
4916 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
4919 DEFUN (bgp_network_mask_backdoor
,
4920 bgp_network_mask_backdoor_cmd
,
4921 "network A.B.C.D mask A.B.C.D backdoor",
4922 "Specify a network to announce via BGP\n"
4926 "Specify a BGP backdoor route\n")
4931 char prefix_str
[BUFSIZ
];
4933 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4936 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4940 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4942 BGP_INVALID_LABEL_INDEX
);
4945 DEFUN (bgp_network_mask_natural
,
4946 bgp_network_mask_natural_cmd
,
4948 "Specify a network to announce via BGP\n"
4953 char prefix_str
[BUFSIZ
];
4955 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4958 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4962 return bgp_static_set (vty
, prefix_str
,
4963 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4964 BGP_INVALID_LABEL_INDEX
);
4967 DEFUN (bgp_network_mask_natural_route_map
,
4968 bgp_network_mask_natural_route_map_cmd
,
4969 "network A.B.C.D route-map WORD",
4970 "Specify a network to announce via BGP\n"
4972 "Route-map to modify the attributes\n"
4973 "Name of the route map\n")
4978 char prefix_str
[BUFSIZ
];
4980 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4983 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4987 return bgp_static_set (vty
, prefix_str
,
4988 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4989 BGP_INVALID_LABEL_INDEX
);
4992 DEFUN (bgp_network_mask_natural_backdoor
,
4993 bgp_network_mask_natural_backdoor_cmd
,
4994 "network A.B.C.D backdoor",
4995 "Specify a network to announce via BGP\n"
4997 "Specify a BGP backdoor route\n")
5001 char prefix_str
[BUFSIZ
];
5003 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5006 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5010 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5011 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5014 DEFUN (bgp_network_label_index
,
5015 bgp_network_label_index_cmd
,
5016 "network A.B.C.D/M label-index (0-1048560)",
5017 "Specify a network to announce via BGP\n"
5018 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5019 "Label index to associate with the prefix\n"
5020 "Label index value\n")
5022 u_int32_t label_index
;
5024 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5025 return bgp_static_set (vty
, argv
[1]->arg
,
5026 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5029 DEFUN (bgp_network_label_index_route_map
,
5030 bgp_network_label_index_route_map_cmd
,
5031 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5032 "Specify a network to announce via BGP\n"
5034 "Label index to associate with the prefix\n"
5035 "Label index value\n"
5036 "Route-map to modify the attributes\n"
5037 "Name of the route map\n")
5039 u_int32_t label_index
;
5041 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5042 return bgp_static_set (vty
, argv
[1]->arg
,
5043 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5046 DEFUN (no_bgp_network
,
5048 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5050 "Specify a network to announce via BGP\n"
5052 "Specify a BGP backdoor route\n"
5053 "Route-map to modify the attributes\n"
5054 "Name of the route map\n")
5056 int idx_ipv4_prefixlen
= 2;
5057 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5058 bgp_node_safi (vty
));
5061 DEFUN (no_bgp_network_mask
,
5062 no_bgp_network_mask_cmd
,
5063 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5065 "Specify a network to announce via BGP\n"
5069 "Specify a BGP backdoor route\n"
5070 "Route-map to modify the attributes\n"
5071 "Name of the route map\n")
5076 char prefix_str
[BUFSIZ
];
5078 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5081 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5085 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5086 bgp_node_safi (vty
));
5089 DEFUN (no_bgp_network_mask_natural
,
5090 no_bgp_network_mask_natural_cmd
,
5091 "no network A.B.C.D [<backdoor|route-map WORD>]",
5093 "Specify a network to announce via BGP\n"
5095 "Specify a BGP backdoor route\n"
5096 "Route-map to modify the attributes\n"
5097 "Name of the route map\n")
5101 char prefix_str
[BUFSIZ
];
5103 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5106 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5110 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5111 bgp_node_safi (vty
));
5114 ALIAS (no_bgp_network
,
5115 no_bgp_network_label_index_cmd
,
5116 "no network A.B.C.D/M label-index (0-1048560)",
5118 "Specify a network to announce via BGP\n"
5119 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5120 "Label index to associate with the prefix\n"
5121 "Label index value\n")
5123 ALIAS (no_bgp_network
,
5124 no_bgp_network_label_index_route_map_cmd
,
5125 "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
5127 "Specify a network to announce via BGP\n"
5129 "Label index to associate with the prefix\n"
5130 "Label index value\n"
5131 "Route-map to modify the attributes\n"
5132 "Name of the route map\n")
5134 DEFUN (ipv6_bgp_network
,
5135 ipv6_bgp_network_cmd
,
5136 "network X:X::X:X/M",
5137 "Specify a network to announce via BGP\n"
5140 int idx_ipv6_prefixlen
= 1;
5141 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5143 BGP_INVALID_LABEL_INDEX
);
5146 DEFUN (ipv6_bgp_network_route_map
,
5147 ipv6_bgp_network_route_map_cmd
,
5148 "network X:X::X:X/M route-map WORD",
5149 "Specify a network to announce via BGP\n"
5151 "Route-map to modify the attributes\n"
5152 "Name of the route map\n")
5154 int idx_ipv6_prefixlen
= 1;
5156 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5157 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5158 BGP_INVALID_LABEL_INDEX
);
5161 DEFUN (ipv6_bgp_network_label_index
,
5162 ipv6_bgp_network_label_index_cmd
,
5163 "network X:X::X:X/M label-index (0-1048560)",
5164 "Specify a network to announce via BGP\n"
5165 "IPv6 prefix <network>/<length>\n"
5166 "Label index to associate with the prefix\n"
5167 "Label index value\n")
5169 u_int32_t label_index
;
5171 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5172 return bgp_static_set (vty
, argv
[1]->arg
,
5173 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5176 DEFUN (ipv6_bgp_network_label_index_route_map
,
5177 ipv6_bgp_network_label_index_route_map_cmd
,
5178 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5179 "Specify a network to announce via BGP\n"
5181 "Label index to associate with the prefix\n"
5182 "Label index value\n"
5183 "Route-map to modify the attributes\n"
5184 "Name of the route map\n")
5186 u_int32_t label_index
;
5188 VTY_GET_INTEGER ("label-index", label_index
, argv
[3]->arg
);
5189 return bgp_static_set (vty
, argv
[1]->arg
,
5190 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5193 DEFUN (no_ipv6_bgp_network
,
5194 no_ipv6_bgp_network_cmd
,
5195 "no network X:X::X:X/M [route-map WORD]",
5197 "Specify a network to announce via BGP\n"
5199 "Route-map to modify the attributes\n"
5200 "Name of the route map\n")
5202 int idx_ipv6_prefixlen
= 2;
5203 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5206 ALIAS (no_ipv6_bgp_network
,
5207 no_ipv6_bgp_network_label_index_cmd
,
5208 "no network X:X::X:X/M label-index (0-1048560)",
5210 "Specify a network to announce via BGP\n"
5211 "IPv6 prefix <network>/<length>\n"
5212 "Label index to associate with the prefix\n"
5213 "Label index value\n")
5215 ALIAS (no_ipv6_bgp_network
,
5216 no_ipv6_bgp_network_label_index_route_map_cmd
,
5217 "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
5219 "Specify a network to announce via BGP\n"
5221 "Label index to associate with the prefix\n"
5222 "Label index value\n"
5223 "Route-map to modify the attributes\n"
5224 "Name of the route map\n")
5226 /* Aggreagete address:
5228 advertise-map Set condition to advertise attribute
5229 as-set Generate AS set path information
5230 attribute-map Set attributes of aggregate
5231 route-map Set parameters of aggregate
5232 summary-only Filter more specific routes from updates
5233 suppress-map Conditionally filter more specific routes from updates
5236 struct bgp_aggregate
5238 /* Summary-only flag. */
5239 u_char summary_only
;
5241 /* AS set generation. */
5244 /* Route-map for aggregated route. */
5245 struct route_map
*map
;
5247 /* Suppress-count. */
5248 unsigned long count
;
5250 /* SAFI configuration. */
5254 static struct bgp_aggregate
*
5255 bgp_aggregate_new (void)
5257 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5261 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5263 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5266 /* Update an aggregate as routes are added/removed from the BGP table */
5268 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5269 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5270 struct bgp_aggregate
*aggregate
)
5272 struct bgp_table
*table
;
5273 struct bgp_node
*top
;
5274 struct bgp_node
*rn
;
5276 struct aspath
*aspath
= NULL
;
5277 struct aspath
*asmerge
= NULL
;
5278 struct community
*community
= NULL
;
5279 struct community
*commerge
= NULL
;
5280 #if defined(AGGREGATE_NEXTHOP_CHECK)
5281 struct in_addr nexthop
;
5284 struct bgp_info
*ri
;
5285 struct bgp_info
*new;
5287 unsigned long match
= 0;
5288 u_char atomic_aggregate
= 0;
5290 /* Record adding route's nexthop and med. */
5293 #if defined(AGGREGATE_NEXTHOP_CHECK)
5294 nexthop
= rinew
->attr
->nexthop
;
5295 med
= rinew
->attr
->med
;
5299 /* ORIGIN attribute: If at least one route among routes that are
5300 aggregated has ORIGIN with the value INCOMPLETE, then the
5301 aggregated route must have the ORIGIN attribute with the value
5302 INCOMPLETE. Otherwise, if at least one route among routes that
5303 are aggregated has ORIGIN with the value EGP, then the aggregated
5304 route must have the origin attribute with the value EGP. In all
5305 other case the value of the ORIGIN attribute of the aggregated
5306 route is INTERNAL. */
5307 origin
= BGP_ORIGIN_IGP
;
5309 table
= bgp
->rib
[afi
][safi
];
5311 top
= bgp_node_get (table
, p
);
5312 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5313 if (rn
->p
.prefixlen
> p
->prefixlen
)
5317 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5319 if (BGP_INFO_HOLDDOWN (ri
))
5322 if (del
&& ri
== del
)
5325 if (! rinew
&& first
)
5327 #if defined(AGGREGATE_NEXTHOP_CHECK)
5328 nexthop
= ri
->attr
->nexthop
;
5329 med
= ri
->attr
->med
;
5334 #ifdef AGGREGATE_NEXTHOP_CHECK
5335 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5336 || ri
->attr
->med
!= med
)
5339 aspath_free (aspath
);
5341 community_free (community
);
5342 bgp_unlock_node (rn
);
5343 bgp_unlock_node (top
);
5346 #endif /* AGGREGATE_NEXTHOP_CHECK */
5348 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5349 atomic_aggregate
= 1;
5351 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5353 if (aggregate
->summary_only
)
5355 (bgp_info_extra_get (ri
))->suppress
++;
5356 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5362 if (origin
< ri
->attr
->origin
)
5363 origin
= ri
->attr
->origin
;
5365 if (aggregate
->as_set
)
5369 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5370 aspath_free (aspath
);
5374 aspath
= aspath_dup (ri
->attr
->aspath
);
5376 if (ri
->attr
->community
)
5380 commerge
= community_merge (community
,
5381 ri
->attr
->community
);
5382 community
= community_uniq_sort (commerge
);
5383 community_free (commerge
);
5386 community
= community_dup (ri
->attr
->community
);
5392 bgp_process (bgp
, rn
, afi
, safi
);
5394 bgp_unlock_node (top
);
5400 if (aggregate
->summary_only
)
5401 (bgp_info_extra_get (rinew
))->suppress
++;
5403 if (origin
< rinew
->attr
->origin
)
5404 origin
= rinew
->attr
->origin
;
5406 if (aggregate
->as_set
)
5410 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5411 aspath_free (aspath
);
5415 aspath
= aspath_dup (rinew
->attr
->aspath
);
5417 if (rinew
->attr
->community
)
5421 commerge
= community_merge (community
,
5422 rinew
->attr
->community
);
5423 community
= community_uniq_sort (commerge
);
5424 community_free (commerge
);
5427 community
= community_dup (rinew
->attr
->community
);
5432 if (aggregate
->count
> 0)
5434 rn
= bgp_node_get (table
, p
);
5435 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5436 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5438 atomic_aggregate
), rn
);
5439 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5441 bgp_info_add (rn
, new);
5442 bgp_unlock_node (rn
);
5443 bgp_process (bgp
, rn
, afi
, safi
);
5448 aspath_free (aspath
);
5450 community_free (community
);
5454 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5455 struct bgp_aggregate
*);
5458 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5459 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5461 struct bgp_node
*child
;
5462 struct bgp_node
*rn
;
5463 struct bgp_aggregate
*aggregate
;
5464 struct bgp_table
*table
;
5466 /* MPLS-VPN aggregation is not yet supported. */
5467 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5470 table
= bgp
->aggregate
[afi
][safi
];
5472 /* No aggregates configured. */
5473 if (bgp_table_top_nolock (table
) == NULL
)
5476 if (p
->prefixlen
== 0)
5479 if (BGP_INFO_HOLDDOWN (ri
))
5482 child
= bgp_node_get (table
, p
);
5484 /* Aggregate address configuration check. */
5485 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5486 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5488 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5489 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5491 bgp_unlock_node (child
);
5495 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5496 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5498 struct bgp_node
*child
;
5499 struct bgp_node
*rn
;
5500 struct bgp_aggregate
*aggregate
;
5501 struct bgp_table
*table
;
5503 /* MPLS-VPN aggregation is not yet supported. */
5504 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5507 table
= bgp
->aggregate
[afi
][safi
];
5509 /* No aggregates configured. */
5510 if (bgp_table_top_nolock (table
) == NULL
)
5513 if (p
->prefixlen
== 0)
5516 child
= bgp_node_get (table
, p
);
5518 /* Aggregate address configuration check. */
5519 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5520 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5522 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5523 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5525 bgp_unlock_node (child
);
5528 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5530 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5531 struct bgp_aggregate
*aggregate
)
5533 struct bgp_table
*table
;
5534 struct bgp_node
*top
;
5535 struct bgp_node
*rn
;
5536 struct bgp_info
*new;
5537 struct bgp_info
*ri
;
5538 unsigned long match
;
5539 u_char origin
= BGP_ORIGIN_IGP
;
5540 struct aspath
*aspath
= NULL
;
5541 struct aspath
*asmerge
= NULL
;
5542 struct community
*community
= NULL
;
5543 struct community
*commerge
= NULL
;
5544 u_char atomic_aggregate
= 0;
5546 table
= bgp
->rib
[afi
][safi
];
5549 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5551 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5554 /* If routes exists below this node, generate aggregate routes. */
5555 top
= bgp_node_get (table
, p
);
5556 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5557 if (rn
->p
.prefixlen
> p
->prefixlen
)
5561 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5563 if (BGP_INFO_HOLDDOWN (ri
))
5566 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5567 atomic_aggregate
= 1;
5569 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5571 /* summary-only aggregate route suppress aggregated
5572 route announcement. */
5573 if (aggregate
->summary_only
)
5575 (bgp_info_extra_get (ri
))->suppress
++;
5576 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5580 /* If at least one route among routes that are aggregated has
5581 * ORIGIN with the value INCOMPLETE, then the aggregated route
5582 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5583 * Otherwise, if at least one route among routes that are
5584 * aggregated has ORIGIN with the value EGP, then the aggregated
5585 * route MUST have the ORIGIN attribute with the value EGP.
5587 if (origin
< ri
->attr
->origin
)
5588 origin
= ri
->attr
->origin
;
5590 /* as-set aggregate route generate origin, as path,
5591 community aggregation. */
5592 if (aggregate
->as_set
)
5596 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5597 aspath_free (aspath
);
5601 aspath
= aspath_dup (ri
->attr
->aspath
);
5603 if (ri
->attr
->community
)
5607 commerge
= community_merge (community
,
5608 ri
->attr
->community
);
5609 community
= community_uniq_sort (commerge
);
5610 community_free (commerge
);
5613 community
= community_dup (ri
->attr
->community
);
5620 /* If this node is suppressed, process the change. */
5622 bgp_process (bgp
, rn
, afi
, safi
);
5624 bgp_unlock_node (top
);
5626 /* Add aggregate route to BGP table. */
5627 if (aggregate
->count
)
5629 rn
= bgp_node_get (table
, p
);
5630 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5631 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5633 atomic_aggregate
), rn
);
5634 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5636 bgp_info_add (rn
, new);
5637 bgp_unlock_node (rn
);
5639 /* Process change. */
5640 bgp_process (bgp
, rn
, afi
, safi
);
5645 aspath_free (aspath
);
5647 community_free (community
);
5652 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5653 safi_t safi
, struct bgp_aggregate
*aggregate
)
5655 struct bgp_table
*table
;
5656 struct bgp_node
*top
;
5657 struct bgp_node
*rn
;
5658 struct bgp_info
*ri
;
5659 unsigned long match
;
5661 table
= bgp
->rib
[afi
][safi
];
5663 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5665 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5668 /* If routes exists below this node, generate aggregate routes. */
5669 top
= bgp_node_get (table
, p
);
5670 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5671 if (rn
->p
.prefixlen
> p
->prefixlen
)
5675 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5677 if (BGP_INFO_HOLDDOWN (ri
))
5680 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5682 if (aggregate
->summary_only
&& ri
->extra
)
5684 ri
->extra
->suppress
--;
5686 if (ri
->extra
->suppress
== 0)
5688 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5696 /* If this node was suppressed, process the change. */
5698 bgp_process (bgp
, rn
, afi
, safi
);
5700 bgp_unlock_node (top
);
5702 /* Delete aggregate route from BGP table. */
5703 rn
= bgp_node_get (table
, p
);
5705 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5706 if (ri
->peer
== bgp
->peer_self
5707 && ri
->type
== ZEBRA_ROUTE_BGP
5708 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5711 /* Withdraw static BGP route from routing table. */
5714 bgp_info_delete (rn
, ri
);
5715 bgp_process (bgp
, rn
, afi
, safi
);
5718 /* Unlock bgp_node_lookup. */
5719 bgp_unlock_node (rn
);
5722 /* Aggregate route attribute. */
5723 #define AGGREGATE_SUMMARY_ONLY 1
5724 #define AGGREGATE_AS_SET 1
5727 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5728 afi_t afi
, safi_t safi
)
5730 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5733 struct bgp_node
*rn
;
5734 struct bgp_aggregate
*aggregate
;
5736 /* Convert string to prefix structure. */
5737 ret
= str2prefix (prefix_str
, &p
);
5740 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5745 /* Old configuration check. */
5746 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5749 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5754 aggregate
= rn
->info
;
5755 if (aggregate
->safi
== SAFI_UNICAST
)
5756 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5757 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5758 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5759 if (aggregate
->safi
== SAFI_MULTICAST
)
5760 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5762 /* Unlock aggregate address configuration. */
5764 bgp_aggregate_free (aggregate
);
5765 bgp_unlock_node (rn
);
5766 bgp_unlock_node (rn
);
5772 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5773 afi_t afi
, safi_t safi
,
5774 u_char summary_only
, u_char as_set
)
5776 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5779 struct bgp_node
*rn
;
5780 struct bgp_aggregate
*aggregate
;
5782 /* Convert string to prefix structure. */
5783 ret
= str2prefix (prefix_str
, &p
);
5786 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5791 /* Old configuration check. */
5792 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5796 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5797 /* try to remove the old entry */
5798 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5801 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5802 bgp_unlock_node (rn
);
5807 /* Make aggregate address structure. */
5808 aggregate
= bgp_aggregate_new ();
5809 aggregate
->summary_only
= summary_only
;
5810 aggregate
->as_set
= as_set
;
5811 aggregate
->safi
= safi
;
5812 rn
->info
= aggregate
;
5814 /* Aggregate address insert into BGP routing table. */
5815 if (safi
== SAFI_UNICAST
)
5816 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5817 if (safi
== SAFI_LABELED_UNICAST
)
5818 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5819 if (safi
== SAFI_MULTICAST
)
5820 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5825 DEFUN (aggregate_address
,
5826 aggregate_address_cmd
,
5827 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5828 "Configure BGP aggregate entries\n"
5829 "Aggregate prefix\n"
5830 "Generate AS set path information\n"
5831 "Filter more specific routes from updates\n"
5832 "Filter more specific routes from updates\n"
5833 "Generate AS set path information\n")
5836 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5837 char *prefix
= argv
[idx
]->arg
;
5838 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5840 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5842 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5845 DEFUN (aggregate_address_mask
,
5846 aggregate_address_mask_cmd
,
5847 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5848 "Configure BGP aggregate entries\n"
5849 "Aggregate address\n"
5851 "Generate AS set path information\n"
5852 "Filter more specific routes from updates\n"
5853 "Filter more specific routes from updates\n"
5854 "Generate AS set path information\n")
5857 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5858 char *prefix
= argv
[idx
]->arg
;
5859 char *mask
= argv
[idx
+1]->arg
;
5860 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5862 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5864 char prefix_str
[BUFSIZ
];
5865 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5869 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5873 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5876 DEFUN (no_aggregate_address
,
5877 no_aggregate_address_cmd
,
5878 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5880 "Configure BGP aggregate entries\n"
5881 "Aggregate prefix\n"
5882 "Generate AS set path information\n"
5883 "Filter more specific routes from updates\n"
5884 "Filter more specific routes from updates\n"
5885 "Generate AS set path information\n")
5888 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5889 char *prefix
= argv
[idx
]->arg
;
5890 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5893 DEFUN (no_aggregate_address_mask
,
5894 no_aggregate_address_mask_cmd
,
5895 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5897 "Configure BGP aggregate entries\n"
5898 "Aggregate address\n"
5900 "Generate AS set path information\n"
5901 "Filter more specific routes from updates\n"
5902 "Filter more specific routes from updates\n"
5903 "Generate AS set path information\n")
5906 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5907 char *prefix
= argv
[idx
]->arg
;
5908 char *mask
= argv
[idx
+1]->arg
;
5910 char prefix_str
[BUFSIZ
];
5911 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5915 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5919 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5922 DEFUN (ipv6_aggregate_address
,
5923 ipv6_aggregate_address_cmd
,
5924 "aggregate-address X:X::X:X/M [summary-only]",
5925 "Configure BGP aggregate entries\n"
5926 "Aggregate prefix\n"
5927 "Filter more specific routes from updates\n")
5930 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5931 char *prefix
= argv
[idx
]->arg
;
5932 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5933 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5936 DEFUN (no_ipv6_aggregate_address
,
5937 no_ipv6_aggregate_address_cmd
,
5938 "no aggregate-address X:X::X:X/M [summary-only]",
5940 "Configure BGP aggregate entries\n"
5941 "Aggregate prefix\n"
5942 "Filter more specific routes from updates\n")
5945 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5946 char *prefix
= argv
[idx
]->arg
;
5947 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5950 /* Redistribute route treatment. */
5952 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5953 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5954 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5956 struct bgp_info
*new;
5957 struct bgp_info
*bi
;
5958 struct bgp_info info
;
5959 struct bgp_node
*bn
;
5961 struct attr
*new_attr
;
5964 struct bgp_redist
*red
;
5966 /* Make default attribute. */
5967 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5969 attr
.nexthop
= *nexthop
;
5970 attr
.nh_ifindex
= ifindex
;
5974 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5975 extra
->mp_nexthop_global
= *nexthop6
;
5976 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5980 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5981 attr
.extra
->tag
= tag
;
5983 afi
= family2afi (p
->family
);
5985 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5988 struct attr attr_new
;
5989 struct attr_extra extra_new
;
5991 /* Copy attribute for modification. */
5992 attr_new
.extra
= &extra_new
;
5993 bgp_attr_dup (&attr_new
, &attr
);
5995 if (red
->redist_metric_flag
)
5996 attr_new
.med
= red
->redist_metric
;
5998 /* Apply route-map. */
6001 info
.peer
= bgp
->peer_self
;
6002 info
.attr
= &attr_new
;
6004 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6006 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6008 bgp
->peer_self
->rmap_type
= 0;
6010 if (ret
== RMAP_DENYMATCH
)
6012 /* Free uninterned attribute. */
6013 bgp_attr_flush (&attr_new
);
6015 /* Unintern original. */
6016 aspath_unintern (&attr
.aspath
);
6017 bgp_attr_extra_free (&attr
);
6018 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6023 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6024 afi
, SAFI_UNICAST
, p
, NULL
);
6026 new_attr
= bgp_attr_intern (&attr_new
);
6028 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6029 if (bi
->peer
== bgp
->peer_self
6030 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6035 /* Ensure the (source route) type is updated. */
6037 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6038 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6040 bgp_attr_unintern (&new_attr
);
6041 aspath_unintern (&attr
.aspath
);
6042 bgp_attr_extra_free (&attr
);
6043 bgp_unlock_node (bn
);
6048 /* The attribute is changed. */
6049 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6051 /* Rewrite BGP route information. */
6052 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6053 bgp_info_restore(bn
, bi
);
6055 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6056 bgp_attr_unintern (&bi
->attr
);
6057 bi
->attr
= new_attr
;
6058 bi
->uptime
= bgp_clock ();
6060 /* Process change. */
6061 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6062 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6063 bgp_unlock_node (bn
);
6064 aspath_unintern (&attr
.aspath
);
6065 bgp_attr_extra_free (&attr
);
6070 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6072 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6074 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6075 bgp_info_add (bn
, new);
6076 bgp_unlock_node (bn
);
6077 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6080 /* Unintern original. */
6081 aspath_unintern (&attr
.aspath
);
6082 bgp_attr_extra_free (&attr
);
6086 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6089 struct bgp_node
*rn
;
6090 struct bgp_info
*ri
;
6091 struct bgp_redist
*red
;
6093 afi
= family2afi (p
->family
);
6095 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6098 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6100 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6101 if (ri
->peer
== bgp
->peer_self
6102 && ri
->type
== type
)
6107 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6108 bgp_info_delete (rn
, ri
);
6109 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6111 bgp_unlock_node (rn
);
6115 /* Withdraw specified route type's route. */
6117 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6119 struct bgp_node
*rn
;
6120 struct bgp_info
*ri
;
6121 struct bgp_table
*table
;
6123 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6125 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6127 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6128 if (ri
->peer
== bgp
->peer_self
6130 && ri
->instance
== instance
)
6135 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6136 bgp_info_delete (rn
, ri
);
6137 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6142 /* Static function to display route. */
6144 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6147 u_int32_t destination
;
6150 if (p
->family
== AF_INET
)
6152 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6153 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6155 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6156 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6157 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6158 || p
->u
.prefix4
.s_addr
== 0)
6160 /* When mask is natural, mask is not displayed. */
6163 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6165 else if (p
->family
== AF_ETHERNET
)
6167 prefix2str(p
, buf
, PREFIX_STRLEN
);
6168 len
= vty_out (vty
, "%s", buf
);
6171 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6176 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
6178 vty_out (vty
, "%*s", len
, " ");
6181 enum bgp_display_type
6186 /* Print the short form route status for a bgp_info */
6188 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6189 json_object
*json_path
)
6194 /* Route status display. */
6195 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6196 json_object_boolean_true_add(json_path
, "removed");
6198 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6199 json_object_boolean_true_add(json_path
, "stale");
6201 if (binfo
->extra
&& binfo
->extra
->suppress
)
6202 json_object_boolean_true_add(json_path
, "suppressed");
6204 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6205 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6206 json_object_boolean_true_add(json_path
, "valid");
6209 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6210 json_object_boolean_true_add(json_path
, "history");
6212 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6213 json_object_boolean_true_add(json_path
, "damped");
6215 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6216 json_object_boolean_true_add(json_path
, "bestpath");
6218 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6219 json_object_boolean_true_add(json_path
, "multipath");
6221 /* Internal route. */
6222 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6223 json_object_string_add(json_path
, "pathFrom", "internal");
6225 json_object_string_add(json_path
, "pathFrom", "external");
6230 /* Route status display. */
6231 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6233 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6235 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6237 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6238 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6244 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6246 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6248 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6250 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6255 /* Internal route. */
6257 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6263 /* called from terminal list command */
6265 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6266 struct bgp_info
*binfo
, int display
, safi_t safi
,
6267 json_object
*json_paths
)
6270 json_object
*json_path
= NULL
;
6271 json_object
*json_nexthops
= NULL
;
6272 json_object
*json_nexthop_global
= NULL
;
6273 json_object
*json_nexthop_ll
= NULL
;
6276 json_path
= json_object_new_object();
6278 /* short status lead text */
6279 route_vty_short_status_out (vty
, binfo
, json_path
);
6283 /* print prefix and mask */
6285 route_vty_out_route (p
, vty
);
6287 vty_out (vty
, "%*s", 17, " ");
6290 /* Print attribute */
6295 * For ENCAP routes, nexthop address family is not
6296 * neccessarily the same as the prefix address family.
6297 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6299 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6304 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6309 vty_out (vty
, "%s", inet_ntop(af
,
6310 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6313 vty_out (vty
, "%s", inet_ntop(af
,
6314 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6325 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6329 json_nexthop_global
= json_object_new_object();
6331 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6332 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6334 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6336 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6337 json_object_boolean_true_add(json_nexthop_global
, "used");
6341 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6342 vty_out (vty
, "%-16s",
6343 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6345 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6350 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6357 json_nexthop_global
= json_object_new_object();
6358 json_object_string_add(json_nexthop_global
, "ip",
6359 inet_ntop (AF_INET6
,
6360 &attr
->extra
->mp_nexthop_global
,
6362 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6363 json_object_string_add(json_nexthop_global
, "scope", "global");
6365 /* We display both LL & GL if both have been received */
6366 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6368 json_nexthop_ll
= json_object_new_object();
6369 json_object_string_add(json_nexthop_ll
, "ip",
6370 inet_ntop (AF_INET6
,
6371 &attr
->extra
->mp_nexthop_local
,
6373 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6374 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6376 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6377 &attr
->extra
->mp_nexthop_local
) != 0) &&
6378 !attr
->extra
->mp_nexthop_prefer_global
)
6379 json_object_boolean_true_add(json_nexthop_ll
, "used");
6381 json_object_boolean_true_add(json_nexthop_global
, "used");
6384 json_object_boolean_true_add(json_nexthop_global
, "used");
6388 /* Display LL if LL/Global both in table unless prefer-global is set */
6389 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6390 !attr
->extra
->mp_nexthop_prefer_global
) ||
6391 (binfo
->peer
->conf_if
))
6393 if (binfo
->peer
->conf_if
)
6395 len
= vty_out (vty
, "%s",
6396 binfo
->peer
->conf_if
);
6397 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6400 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6402 vty_out (vty
, "%*s", len
, " ");
6406 len
= vty_out (vty
, "%s",
6407 inet_ntop (AF_INET6
,
6408 &attr
->extra
->mp_nexthop_local
,
6413 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6415 vty_out (vty
, "%*s", len
, " ");
6420 len
= vty_out (vty
, "%s",
6421 inet_ntop (AF_INET6
,
6422 &attr
->extra
->mp_nexthop_global
,
6427 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6429 vty_out (vty
, "%*s", len
, " ");
6435 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6437 json_object_int_add(json_path
, "med", attr
->med
);
6439 vty_out (vty
, "%10u", attr
->med
);
6445 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6447 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6449 vty_out (vty
, "%7u", attr
->local_pref
);
6457 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6459 json_object_int_add(json_path
, "weight", 0);
6462 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6466 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6473 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6475 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6480 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6482 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6487 json_object_string_add(json_path
, "alert", "No attributes");
6489 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6494 if (json_nexthop_global
|| json_nexthop_ll
)
6496 json_nexthops
= json_object_new_array();
6498 if (json_nexthop_global
)
6499 json_object_array_add(json_nexthops
, json_nexthop_global
);
6501 if (json_nexthop_ll
)
6502 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6504 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6507 json_object_array_add(json_paths
, json_path
);
6511 vty_out (vty
, "%s", VTY_NEWLINE
);
6513 /* prints an additional line, indented, with VNC info, if present */
6514 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6515 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6520 /* called from terminal list command */
6522 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6523 u_char use_json
, json_object
*json_ar
)
6525 json_object
*json_status
= NULL
;
6526 json_object
*json_net
= NULL
;
6528 /* Route status display. */
6531 json_status
= json_object_new_object();
6532 json_net
= json_object_new_object();
6541 /* print prefix and mask */
6543 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6545 route_vty_out_route (p
, vty
);
6547 /* Print attribute */
6552 if (p
->family
== AF_INET
&&
6553 (safi
== SAFI_MPLS_VPN
||
6554 safi
== SAFI_ENCAP
||
6555 safi
== SAFI_EVPN
||
6556 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6558 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6559 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6561 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6563 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6567 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6571 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6572 json_object_int_add(json_net
, "metric", attr
->med
);
6574 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6575 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6578 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6580 json_object_int_add(json_net
, "weight", 0);
6584 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6587 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6591 if (p
->family
== AF_INET
&&
6592 (safi
== SAFI_MPLS_VPN
||
6593 safi
== SAFI_ENCAP
||
6594 safi
== SAFI_EVPN
||
6595 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6597 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6598 vty_out (vty
, "%-16s",
6599 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6601 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6603 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6608 assert (attr
->extra
);
6610 len
= vty_out (vty
, "%s",
6611 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6615 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6617 vty_out (vty
, "%*s", len
, " ");
6619 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6620 vty_out (vty
, "%10u", attr
->med
);
6624 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6625 vty_out (vty
, "%7u", attr
->local_pref
);
6629 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6633 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6636 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6641 json_object_boolean_true_add(json_status
, "*");
6642 json_object_boolean_true_add(json_status
, ">");
6643 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6644 char buf_cut
[BUFSIZ
];
6645 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6648 vty_out (vty
, "%s", VTY_NEWLINE
);
6652 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6653 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6655 json_object
*json_out
= NULL
;
6657 u_int32_t label
= 0;
6663 json_out
= json_object_new_object();
6665 /* short status lead text */
6666 route_vty_short_status_out (vty
, binfo
, json_out
);
6668 /* print prefix and mask */
6672 route_vty_out_route (p
, vty
);
6674 vty_out (vty
, "%*s", 17, " ");
6677 /* Print attribute */
6681 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6682 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6683 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6685 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6688 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6690 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6695 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6697 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6700 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6701 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6702 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6704 assert (attr
->extra
);
6708 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6711 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6712 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6715 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6718 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6722 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6724 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6726 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6727 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6730 vty_out (vty
, "%s(%s)",
6731 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6733 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6740 label
= decode_label (binfo
->extra
->tag
);
6745 json_object_int_add(json_out
, "notag", label
);
6746 json_object_array_add(json
, json_out
);
6750 vty_out (vty
, "notag/%d", label
);
6752 vty_out (vty
, "%s", VTY_NEWLINE
);
6757 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6758 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6762 json_object
*json_path
= NULL
;
6765 json_path
= json_object_new_object();
6770 /* short status lead text */
6771 route_vty_short_status_out (vty
, binfo
, json_path
);
6773 /* print prefix and mask */
6775 route_vty_out_route (p
, vty
);
6777 vty_out (vty
, "%*s", 17, " ");
6779 /* Print attribute */
6786 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6790 vty_out (vty
, "%-16s", inet_ntop(af
,
6791 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6794 vty_out (vty
, "%s(%s)",
6796 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6798 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6810 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6811 char *str
= esi2str(id
);
6812 vty_out (vty
, "%s", str
);
6813 XFREE (MTYPE_TMP
, str
);
6814 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6816 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6818 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6820 vty_out (vty
, "/%s",
6821 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6824 if(attr
->extra
->ecommunity
)
6827 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6828 ECOMMUNITY_ENCODE_EVPN
,
6829 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6831 mac
= ecom_mac2str((char *)routermac
->val
);
6834 vty_out (vty
, "/%s",(char *)mac
);
6835 XFREE(MTYPE_TMP
, mac
);
6839 vty_out (vty
, "%s", VTY_NEWLINE
);
6842 /* dampening route */
6844 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6845 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6849 char timebuf
[BGP_UPTIME_LEN
];
6851 /* short status lead text */
6852 route_vty_short_status_out (vty
, binfo
, json
);
6854 /* print prefix and mask */
6858 route_vty_out_route (p
, vty
);
6860 vty_out (vty
, "%*s", 17, " ");
6863 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6868 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6873 json_object_int_add(json
, "peerHost", len
);
6875 vty_out (vty
, "%*s", len
, " ");
6879 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6881 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6883 /* Print attribute */
6891 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6893 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6898 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6900 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6903 vty_out (vty
, "%s", VTY_NEWLINE
);
6908 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6909 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6912 struct bgp_damp_info
*bdi
;
6913 char timebuf
[BGP_UPTIME_LEN
];
6919 bdi
= binfo
->extra
->damp_info
;
6921 /* short status lead text */
6922 route_vty_short_status_out (vty
, binfo
, json
);
6924 /* print prefix and mask */
6928 route_vty_out_route (p
, vty
);
6930 vty_out (vty
, "%*s", 17, " ");
6933 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6938 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6943 json_object_int_add(json
, "peerHost", len
);
6945 vty_out (vty
, "%*s", len
, " ");
6948 len
= vty_out (vty
, "%d", bdi
->flap
);
6958 json_object_int_add(json
, "bdiFlap", len
);
6960 vty_out (vty
, "%*s", len
, " ");
6964 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6966 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6967 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6969 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6970 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6973 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6975 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6980 vty_out (vty
, "%*s ", 8, " ");
6983 /* Print attribute */
6991 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6993 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6998 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7000 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7003 vty_out (vty
, "%s", VTY_NEWLINE
);
7007 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7008 const char *header
, json_object
*json_adv_to
)
7010 char buf1
[INET6_ADDRSTRLEN
];
7011 json_object
*json_peer
= NULL
;
7015 /* 'advertised-to' is a dictionary of peers we have advertised this
7016 * prefix too. The key is the peer's IP or swpX, the value is the
7017 * hostname if we know it and "" if not.
7019 json_peer
= json_object_new_object();
7022 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7025 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7027 json_object_object_add(json_adv_to
,
7028 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7035 vty_out (vty
, "%s", header
);
7039 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7042 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7044 vty_out (vty
, " %s(%s)", peer
->hostname
,
7045 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7050 vty_out (vty
, " %s", peer
->conf_if
);
7052 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7058 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7059 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7060 json_object
*json_paths
)
7062 char buf
[INET6_ADDRSTRLEN
];
7065 int sockunion_vty_out (struct vty
*, union sockunion
*);
7067 json_object
*json_bestpath
= NULL
;
7068 json_object
*json_cluster_list
= NULL
;
7069 json_object
*json_cluster_list_list
= NULL
;
7070 json_object
*json_ext_community
= NULL
;
7071 json_object
*json_last_update
= NULL
;
7072 json_object
*json_nexthop_global
= NULL
;
7073 json_object
*json_nexthop_ll
= NULL
;
7074 json_object
*json_nexthops
= NULL
;
7075 json_object
*json_path
= NULL
;
7076 json_object
*json_peer
= NULL
;
7077 json_object
*json_string
= NULL
;
7078 json_object
*json_adv_to
= NULL
;
7080 struct listnode
*node
, *nnode
;
7082 int addpath_capable
;
7084 unsigned int first_as
;
7088 json_path
= json_object_new_object();
7089 json_peer
= json_object_new_object();
7090 json_nexthop_global
= json_object_new_object();
7097 /* Line1 display AS-path, Aggregator */
7102 json_object_lock(attr
->aspath
->json
);
7103 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7107 if (attr
->aspath
->segments
)
7108 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7110 vty_out (vty
, " Local");
7114 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7117 json_object_boolean_true_add(json_path
, "removed");
7119 vty_out (vty
, ", (removed)");
7122 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7125 json_object_boolean_true_add(json_path
, "stale");
7127 vty_out (vty
, ", (stale)");
7130 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7134 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
7135 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
7139 vty_out (vty
, ", (aggregated by %u %s)",
7140 attr
->extra
->aggregator_as
,
7141 inet_ntoa (attr
->extra
->aggregator_addr
));
7145 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7148 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7150 vty_out (vty
, ", (Received from a RR-client)");
7153 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7156 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7158 vty_out (vty
, ", (Received from a RS-client)");
7161 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7164 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7166 vty_out (vty
, ", (history entry)");
7168 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7171 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7173 vty_out (vty
, ", (suppressed due to dampening)");
7177 vty_out (vty
, "%s", VTY_NEWLINE
);
7179 /* Line2 display Next-hop, Neighbor, Router-id */
7180 /* Display the nexthop */
7181 if (p
->family
== AF_INET
&&
7182 (safi
== SAFI_MPLS_VPN
||
7183 safi
== SAFI_ENCAP
||
7184 safi
== SAFI_EVPN
||
7185 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7187 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7190 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7192 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7197 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7199 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7203 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7207 assert (attr
->extra
);
7210 json_object_string_add(json_nexthop_global
, "ip",
7211 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7212 buf
, INET6_ADDRSTRLEN
));
7213 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7214 json_object_string_add(json_nexthop_global
, "scope", "global");
7218 vty_out (vty
, " %s",
7219 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7220 buf
, INET6_ADDRSTRLEN
));
7224 /* Display the IGP cost or 'inaccessible' */
7225 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7228 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7230 vty_out (vty
, " (inaccessible)");
7234 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7237 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7239 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7242 /* IGP cost is 0, display this only for json */
7246 json_object_int_add(json_nexthop_global
, "metric", 0);
7250 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7253 /* Display peer "from" output */
7254 /* This path was originated locally */
7255 if (binfo
->peer
== bgp
->peer_self
)
7258 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7261 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7263 vty_out (vty
, " from 0.0.0.0 ");
7268 json_object_string_add(json_peer
, "peerId", "::");
7270 vty_out (vty
, " from :: ");
7274 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7276 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7279 /* We RXed this path from one of our peers */
7285 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7286 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7288 if (binfo
->peer
->hostname
)
7289 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7291 if (binfo
->peer
->domainname
)
7292 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7294 if (binfo
->peer
->conf_if
)
7295 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7299 if (binfo
->peer
->conf_if
)
7301 if (binfo
->peer
->hostname
&&
7302 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7303 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7304 binfo
->peer
->conf_if
);
7306 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7310 if (binfo
->peer
->hostname
&&
7311 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7312 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7315 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7318 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7319 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7321 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7326 vty_out (vty
, "%s", VTY_NEWLINE
);
7328 /* display the link-local nexthop */
7329 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7333 json_nexthop_ll
= json_object_new_object();
7334 json_object_string_add(json_nexthop_ll
, "ip",
7335 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7336 buf
, INET6_ADDRSTRLEN
));
7337 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7338 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7340 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7342 if (!attr
->extra
->mp_nexthop_prefer_global
)
7343 json_object_boolean_true_add(json_nexthop_ll
, "used");
7345 json_object_boolean_true_add(json_nexthop_global
, "used");
7349 vty_out (vty
, " (%s) %s%s",
7350 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7351 buf
, INET6_ADDRSTRLEN
),
7352 attr
->extra
->mp_nexthop_prefer_global
?
7353 "(prefer-global)" : "(used)",
7357 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7361 json_object_boolean_true_add(json_nexthop_global
, "used");
7364 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7366 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7368 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7370 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7373 json_object_int_add(json_path
, "med", attr
->med
);
7375 vty_out (vty
, ", metric %u", attr
->med
);
7378 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7381 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7383 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7388 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7390 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7393 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7396 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7398 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7401 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7404 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7406 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7409 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7412 json_object_boolean_false_add(json_path
, "valid");
7414 vty_out (vty
, ", invalid");
7416 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7419 json_object_boolean_true_add(json_path
, "valid");
7421 vty_out (vty
, ", valid");
7424 if (binfo
->peer
!= bgp
->peer_self
)
7426 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7428 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7431 json_object_string_add(json_peer
, "type", "confed-internal");
7433 vty_out (vty
, ", confed-internal");
7438 json_object_string_add(json_peer
, "type", "internal");
7440 vty_out (vty
, ", internal");
7445 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7448 json_object_string_add(json_peer
, "type", "confed-external");
7450 vty_out (vty
, ", confed-external");
7455 json_object_string_add(json_peer
, "type", "external");
7457 vty_out (vty
, ", external");
7461 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7465 json_object_boolean_true_add(json_path
, "aggregated");
7466 json_object_boolean_true_add(json_path
, "local");
7470 vty_out (vty
, ", aggregated, local");
7473 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7476 json_object_boolean_true_add(json_path
, "sourced");
7478 vty_out (vty
, ", sourced");
7484 json_object_boolean_true_add(json_path
, "sourced");
7485 json_object_boolean_true_add(json_path
, "local");
7489 vty_out (vty
, ", sourced, local");
7493 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7496 json_object_boolean_true_add(json_path
, "atomicAggregate");
7498 vty_out (vty
, ", atomic-aggregate");
7501 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7502 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7503 bgp_info_mpath_count (binfo
)))
7506 json_object_boolean_true_add(json_path
, "multipath");
7508 vty_out (vty
, ", multipath");
7511 // Mark the bestpath(s)
7512 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7514 first_as
= aspath_get_first_as(attr
->aspath
);
7519 json_bestpath
= json_object_new_object();
7520 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7525 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7527 vty_out (vty
, ", bestpath-from-AS Local");
7531 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7536 json_bestpath
= json_object_new_object();
7537 json_object_boolean_true_add(json_bestpath
, "overall");
7540 vty_out (vty
, ", best");
7544 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7547 vty_out (vty
, "%s", VTY_NEWLINE
);
7549 /* Line 4 display Community */
7550 if (attr
->community
)
7554 json_object_lock(attr
->community
->json
);
7555 json_object_object_add(json_path
, "community", attr
->community
->json
);
7559 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7564 /* Line 5 display Extended-community */
7565 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7569 json_ext_community
= json_object_new_object();
7570 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7571 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7575 vty_out (vty
, " Extended Community: %s%s",
7576 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7580 /* Line 6 display Large community */
7581 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7582 vty_out (vty
, " Large Community: %s%s",
7583 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7585 /* Line 7 display Originator, Cluster-id */
7586 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7587 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7589 assert (attr
->extra
);
7590 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7593 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7595 vty_out (vty
, " Originator: %s",
7596 inet_ntoa (attr
->extra
->originator_id
));
7599 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7605 json_cluster_list
= json_object_new_object();
7606 json_cluster_list_list
= json_object_new_array();
7608 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7610 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7611 json_object_array_add(json_cluster_list_list
, json_string
);
7614 /* struct cluster_list does not have "str" variable like
7615 * aspath and community do. Add this someday if someone
7617 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7619 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7620 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7624 vty_out (vty
, ", Cluster list: ");
7626 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7628 vty_out (vty
, "%s ",
7629 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7635 vty_out (vty
, "%s", VTY_NEWLINE
);
7638 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7639 bgp_damp_info_vty (vty
, binfo
, json_path
);
7642 if (bgp_labeled_safi(safi
) && binfo
->extra
)
7644 uint32_t label
= label_pton(binfo
->extra
->tag
);
7646 json_object_int_add(json_path
, "remoteLabel", label
);
7648 vty_out(vty
, " Remote label: %d%s", label
, VTY_NEWLINE
);
7652 if (attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7655 json_object_int_add(json_path
, "labelIndex", attr
->extra
->label_index
);
7657 vty_out(vty
, " Label Index: %d%s", attr
->extra
->label_index
, VTY_NEWLINE
);
7660 /* Line 8 display Addpath IDs */
7661 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7665 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7666 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7670 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7671 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7676 /* If we used addpath to TX a non-bestpath we need to display
7677 * "Advertised to" on a path-by-path basis */
7678 if (bgp
->addpath_tx_used
[afi
][safi
])
7682 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7684 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7685 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7687 if ((addpath_capable
&& has_adj
) ||
7688 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7690 if (json_path
&& !json_adv_to
)
7691 json_adv_to
= json_object_new_object();
7693 route_vty_out_advertised_to(vty
, peer
, &first
,
7703 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7710 vty_out (vty
, "%s", VTY_NEWLINE
);
7715 /* Line 9 display Uptime */
7716 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7719 json_last_update
= json_object_new_object();
7720 json_object_int_add(json_last_update
, "epoch", tbuf
);
7721 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7722 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7725 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7728 /* We've constructed the json object for this path, add it to the json
7733 if (json_nexthop_global
|| json_nexthop_ll
)
7735 json_nexthops
= json_object_new_array();
7737 if (json_nexthop_global
)
7738 json_object_array_add(json_nexthops
, json_nexthop_global
);
7740 if (json_nexthop_ll
)
7741 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7743 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7746 json_object_object_add(json_path
, "peer", json_peer
);
7747 json_object_array_add(json_paths
, json_path
);
7750 vty_out (vty
, "%s", VTY_NEWLINE
);
7753 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7754 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7755 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7758 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7759 const char *prefix_list_str
, afi_t afi
,
7760 safi_t safi
, enum bgp_show_type type
);
7762 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7763 const char *filter
, afi_t afi
,
7764 safi_t safi
, enum bgp_show_type type
);
7766 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7767 const char *rmap_str
, afi_t afi
,
7768 safi_t safi
, enum bgp_show_type type
);
7770 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7771 const char *com
, int exact
,
7772 afi_t afi
, safi_t safi
);
7774 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7775 const char *prefix
, afi_t afi
,
7776 safi_t safi
, enum bgp_show_type type
);
7778 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7779 safi_t safi
, enum bgp_show_type type
);
7781 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7782 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7785 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7786 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7788 struct bgp_info
*ri
;
7789 struct bgp_node
*rn
;
7792 unsigned long output_count
;
7793 unsigned long total_count
;
7797 json_object
*json_paths
= NULL
;
7802 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7803 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7804 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7805 table
->version
, inet_ntoa (bgp
->router_id
));
7806 json_paths
= json_object_new_object();
7809 /* This is first entry point, so reset total line. */
7813 /* Start processing of routes. */
7814 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7815 if (rn
->info
!= NULL
)
7818 if (!first
&& use_json
)
7823 json_paths
= json_object_new_array();
7827 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7830 if (type
== bgp_show_type_flap_statistics
7831 || type
== bgp_show_type_flap_neighbor
7832 || type
== bgp_show_type_dampend_paths
7833 || type
== bgp_show_type_damp_neighbor
)
7835 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7838 if (type
== bgp_show_type_regexp
)
7840 regex_t
*regex
= output_arg
;
7842 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7845 if (type
== bgp_show_type_prefix_list
)
7847 struct prefix_list
*plist
= output_arg
;
7849 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7852 if (type
== bgp_show_type_filter_list
)
7854 struct as_list
*as_list
= output_arg
;
7856 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7859 if (type
== bgp_show_type_route_map
)
7861 struct route_map
*rmap
= output_arg
;
7862 struct bgp_info binfo
;
7863 struct attr dummy_attr
;
7864 struct attr_extra dummy_extra
;
7867 dummy_attr
.extra
= &dummy_extra
;
7868 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7870 binfo
.peer
= ri
->peer
;
7871 binfo
.attr
= &dummy_attr
;
7873 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7874 if (ret
== RMAP_DENYMATCH
)
7877 if (type
== bgp_show_type_neighbor
7878 || type
== bgp_show_type_flap_neighbor
7879 || type
== bgp_show_type_damp_neighbor
)
7881 union sockunion
*su
= output_arg
;
7883 if (ri
->peer
== NULL
||
7884 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7887 if (type
== bgp_show_type_cidr_only
)
7889 u_int32_t destination
;
7891 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7892 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7894 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7896 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7899 if (type
== bgp_show_type_prefix_longer
)
7901 struct prefix
*p
= output_arg
;
7903 if (! prefix_match (p
, &rn
->p
))
7906 if (type
== bgp_show_type_community_all
)
7908 if (! ri
->attr
->community
)
7911 if (type
== bgp_show_type_community
)
7913 struct community
*com
= output_arg
;
7915 if (! ri
->attr
->community
||
7916 ! community_match (ri
->attr
->community
, com
))
7919 if (type
== bgp_show_type_community_exact
)
7921 struct community
*com
= output_arg
;
7923 if (! ri
->attr
->community
||
7924 ! community_cmp (ri
->attr
->community
, com
))
7927 if (type
== bgp_show_type_community_list
)
7929 struct community_list
*list
= output_arg
;
7931 if (! community_list_match (ri
->attr
->community
, list
))
7934 if (type
== bgp_show_type_community_list_exact
)
7936 struct community_list
*list
= output_arg
;
7938 if (! community_list_exact_match (ri
->attr
->community
, list
))
7941 if (type
== bgp_show_type_lcommunity
)
7943 struct lcommunity
*lcom
= output_arg
;
7945 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7946 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7949 if (type
== bgp_show_type_lcommunity_list
)
7951 struct community_list
*list
= output_arg
;
7953 if (! ri
->attr
->extra
||
7954 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7957 if (type
== bgp_show_type_lcommunity_all
)
7959 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7962 if (type
== bgp_show_type_dampend_paths
7963 || type
== bgp_show_type_damp_neighbor
)
7965 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7966 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7970 if (!use_json
&& header
)
7972 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7973 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7974 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7975 if (type
== bgp_show_type_dampend_paths
7976 || type
== bgp_show_type_damp_neighbor
)
7977 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7978 else if (type
== bgp_show_type_flap_statistics
7979 || type
== bgp_show_type_flap_neighbor
)
7980 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7982 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7986 if (type
== bgp_show_type_dampend_paths
7987 || type
== bgp_show_type_damp_neighbor
)
7988 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7989 else if (type
== bgp_show_type_flap_statistics
7990 || type
== bgp_show_type_flap_neighbor
)
7991 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7993 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8003 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8004 vty_out (vty
, "\"%s\": ", buf2
);
8005 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8006 json_object_free (json_paths
);
8015 json_object_free (json_paths
);
8016 vty_out (vty
, " } }%s", VTY_NEWLINE
);
8020 /* No route is displayed */
8021 if (output_count
== 0)
8023 if (type
== bgp_show_type_normal
)
8024 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
8027 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
8028 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
8035 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8036 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8038 struct bgp_table
*table
;
8042 bgp
= bgp_get_default ();
8048 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8051 /* use MPLS and ENCAP specific shows until they are merged */
8052 if (safi
== SAFI_MPLS_VPN
)
8054 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8058 table
= bgp
->rib
[afi
][safi
];
8060 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8065 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8068 struct listnode
*node
, *nnode
;
8073 vty_out (vty
, "{%s", VTY_NEWLINE
);
8075 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8080 vty_out (vty
, ",%s", VTY_NEWLINE
);
8084 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8085 ? "Default" : bgp
->name
);
8089 vty_out (vty
, "%sInstance %s:%s",
8091 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8092 ? "Default" : bgp
->name
,
8095 bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
, use_json
);
8100 vty_out (vty
, "}%s", VTY_NEWLINE
);
8103 /* Header of detailed BGP route information */
8105 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8106 struct bgp_node
*rn
,
8107 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8110 struct bgp_info
*ri
;
8113 struct listnode
*node
, *nnode
;
8114 char buf1
[INET6_ADDRSTRLEN
];
8115 char buf2
[INET6_ADDRSTRLEN
];
8120 int no_advertise
= 0;
8123 json_object
*json_adv_to
= NULL
;
8129 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8130 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8134 if (p
->family
== AF_ETHERNET
)
8135 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8137 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8138 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
8139 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8140 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8141 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8143 p
->prefixlen
, VTY_NEWLINE
);
8145 if (bgp_labeled_safi(safi
))
8147 vty_out(vty
, "Local label: ");
8148 if (!bgp_is_valid_label(rn
->local_label
))
8149 vty_out(vty
, "not allocated%s", VTY_NEWLINE
);
8152 uint32_t label
= label_pton(rn
->local_label
);
8153 vty_out(vty
, "%d%s", label
, VTY_NEWLINE
);
8158 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8161 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8164 if (ri
->extra
&& ri
->extra
->suppress
)
8166 if (ri
->attr
->community
!= NULL
)
8168 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8170 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8172 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8180 vty_out (vty
, "Paths: (%d available", count
);
8183 vty_out (vty
, ", best #%d", best
);
8184 if (safi
== SAFI_UNICAST
)
8185 vty_out (vty
, ", table %s",
8186 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8187 ? "Default-IP-Routing-Table" : bgp
->name
);
8190 vty_out (vty
, ", no best path");
8193 vty_out (vty
, ", not advertised to any peer");
8195 vty_out (vty
, ", not advertised to EBGP peer");
8197 vty_out (vty
, ", not advertised outside local AS");
8200 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8201 vty_out (vty
, ")%s", VTY_NEWLINE
);
8204 /* If we are not using addpath then we can display Advertised to and that will
8205 * show what peers we advertised the bestpath to. If we are using addpath
8206 * though then we must display Advertised to on a path-by-path basis. */
8207 if (!bgp
->addpath_tx_used
[afi
][safi
])
8209 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8211 if (bgp_adj_out_lookup (peer
, rn
, 0))
8213 if (json
&& !json_adv_to
)
8214 json_adv_to
= json_object_new_object();
8216 route_vty_out_advertised_to(vty
, peer
, &first
,
8217 " Advertised to non peer-group peers:\n ",
8226 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8232 vty_out (vty
, " Not advertised to any peer");
8233 vty_out (vty
, "%s", VTY_NEWLINE
);
8238 /* Display specified route of BGP table. */
8240 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8241 struct bgp_table
*rib
, const char *ip_str
,
8242 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8243 int prefix_check
, enum bgp_path_type pathtype
,
8249 struct prefix match
;
8250 struct bgp_node
*rn
;
8251 struct bgp_node
*rm
;
8252 struct bgp_info
*ri
;
8253 struct bgp_table
*table
;
8254 json_object
*json
= NULL
;
8255 json_object
*json_paths
= NULL
;
8257 /* Check IP address argument. */
8258 ret
= str2prefix (ip_str
, &match
);
8261 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
8265 match
.family
= afi2family (afi
);
8269 json
= json_object_new_object();
8270 json_paths
= json_object_new_array();
8273 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8275 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8277 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8280 if ((table
= rn
->info
) != NULL
)
8284 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8286 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8288 bgp_unlock_node (rm
);
8292 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8296 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8297 AFI_IP
, safi
, json
);
8302 if (pathtype
== BGP_PATH_ALL
||
8303 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8304 (pathtype
== BGP_PATH_MULTIPATH
&&
8305 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8306 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8309 bgp_unlock_node (rm
);
8318 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8320 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8322 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8326 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8331 if (pathtype
== BGP_PATH_ALL
||
8332 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8333 (pathtype
== BGP_PATH_MULTIPATH
&&
8334 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8335 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8339 bgp_unlock_node (rn
);
8346 json_object_object_add(json
, "paths", json_paths
);
8348 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8349 json_object_free(json
);
8355 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8363 /* Display specified route of Main RIB */
8365 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8366 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8367 int prefix_check
, enum bgp_path_type pathtype
,
8371 bgp
= bgp_get_default ();
8373 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8374 afi
, safi
, prd
, prefix_check
, pathtype
,
8379 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8380 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8382 struct lcommunity
*lcom
;
8388 b
= buffer_new (1024);
8389 for (i
= 0; i
< argc
; i
++)
8392 buffer_putc (b
, ' ');
8395 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8398 buffer_putstr (b
, argv
[i
]->arg
);
8402 buffer_putc (b
, '\0');
8404 str
= buffer_getstr (b
);
8407 lcom
= lcommunity_str2com (str
);
8408 XFREE (MTYPE_TMP
, str
);
8411 vty_out (vty
, "%% Large-community malformed%s", VTY_NEWLINE
);
8415 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8419 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8420 afi_t afi
, safi_t safi
, u_char uj
)
8422 struct community_list
*list
;
8424 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8427 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8432 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8435 DEFUN (show_ip_bgp_large_community_list
,
8436 show_ip_bgp_large_community_list_cmd
,
8437 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
8441 BGP_INSTANCE_HELP_STR
8444 "Address Family modifier\n"
8445 "Address Family modifier\n"
8446 "Address Family modifier\n"
8447 "Address Family modifier\n"
8448 "Display routes matching the large-community-list\n"
8449 "large-community-list number\n"
8450 "large-community-list name\n"
8454 afi_t afi
= AFI_IP6
;
8455 safi_t safi
= SAFI_UNICAST
;
8458 if (argv_find (argv
, argc
, "ip", &idx
))
8460 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8461 vrf
= argv
[++idx
]->arg
;
8462 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8464 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8465 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8466 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8469 int uj
= use_json (argc
, argv
);
8471 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8474 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8478 argv_find (argv
, argc
, "large-community-list", &idx
);
8479 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8481 DEFUN (show_ip_bgp_large_community
,
8482 show_ip_bgp_large_community_cmd
,
8483 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]",
8487 BGP_INSTANCE_HELP_STR
8490 "Address Family modifier\n"
8491 "Address Family modifier\n"
8492 "Address Family modifier\n"
8493 "Address Family modifier\n"
8494 "Display routes matching the large-communities\n"
8495 "List of large-community numbers\n"
8499 afi_t afi
= AFI_IP6
;
8500 safi_t safi
= SAFI_UNICAST
;
8503 if (argv_find (argv
, argc
, "ip", &idx
))
8505 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8506 vrf
= argv
[++idx
]->arg
;
8507 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8509 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8510 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8511 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8514 int uj
= use_json (argc
, argv
);
8516 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8519 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8523 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8524 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8526 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8529 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8531 /* BGP route print out function. */
8534 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8537 |dampening <flap-statistics|dampened-paths|parameters>\
8542 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8543 |community-list <(1-500)|WORD> [exact-match]\
8544 |A.B.C.D/M longer-prefixes\
8545 |X:X::X:X/M longer-prefixes>\
8550 BGP_INSTANCE_HELP_STR
8553 "Display only routes with non-natural netmasks\n"
8554 "Display detailed information about dampening\n"
8555 "Display flap statistics of routes\n"
8556 "Display paths suppressed due to dampening\n"
8557 "Display detail of configured dampening parameters\n"
8558 "Display routes matching the route-map\n"
8559 "A route-map to match on\n"
8560 "Display routes conforming to the prefix-list\n"
8561 "Prefix-list name\n"
8562 "Display routes conforming to the filter-list\n"
8563 "Regular expression access list name\n"
8564 "BGP RIB advertisement statistics\n"
8565 "Display routes matching the communities\n"
8567 "Do not send outside local AS (well-known community)\n"
8568 "Do not advertise to any peer (well-known community)\n"
8569 "Do not export to next AS (well-known community)\n"
8570 "Exact match of the communities\n"
8571 "Display routes matching the community-list\n"
8572 "community-list number\n"
8573 "community-list name\n"
8574 "Exact match of the communities\n"
8576 "Display route and more specific routes\n"
8578 "Display route and more specific routes\n"
8581 afi_t afi
= AFI_IP6
;
8582 safi_t safi
= SAFI_UNICAST
;
8583 int exact_match
= 0;
8584 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8585 struct bgp
*bgp
= NULL
;
8588 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8592 int uj
= use_json (argc
, argv
);
8595 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8596 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8598 if (argv_find(argv
, argc
, "dampening", &idx
))
8600 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8601 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8602 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8603 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8604 else if (argv_find (argv
, argc
, "parameters", &idx
))
8605 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8608 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8609 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8611 if (argv_find(argv
, argc
, "filter-list", &idx
))
8612 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8614 if (argv_find(argv
, argc
, "statistics", &idx
))
8615 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8617 if (argv_find(argv
, argc
, "route-map", &idx
))
8618 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8620 if (argv_find(argv
, argc
, "community", &idx
))
8622 /* show a specific community */
8623 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8624 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8625 argv_find (argv
, argc
, "no-export", &idx
))
8627 if (argv_find (argv
, argc
, "exact_match", &idx
))
8629 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8631 /* show all communities */
8633 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8636 if (argv_find(argv
, argc
, "community-list", &idx
))
8638 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8639 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8641 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8644 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8645 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8647 if (safi
== SAFI_MPLS_VPN
)
8648 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8650 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8653 DEFUN (show_ip_bgp_route
,
8654 show_ip_bgp_route_cmd
,
8655 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8656 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8660 BGP_INSTANCE_HELP_STR
8663 "Network in the BGP routing table to display\n"
8665 "Network in the BGP routing table to display\n"
8667 "Display only the bestpath\n"
8668 "Display only multipaths\n"
8671 int prefix_check
= 0;
8673 afi_t afi
= AFI_IP6
;
8674 safi_t safi
= SAFI_UNICAST
;
8675 char *prefix
= NULL
;
8676 struct bgp
*bgp
= NULL
;
8677 enum bgp_path_type path_type
;
8678 u_char uj
= use_json(argc
, argv
);
8682 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8688 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8692 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8693 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8695 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8698 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8700 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8703 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8705 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8709 prefix
= argv
[idx
]->arg
;
8711 /* [<bestpath|multipath>] */
8712 if (argv_find (argv
, argc
, "bestpath", &idx
))
8713 path_type
= BGP_PATH_BESTPATH
;
8714 else if (argv_find (argv
, argc
, "multipath", &idx
))
8715 path_type
= BGP_PATH_MULTIPATH
;
8717 path_type
= BGP_PATH_ALL
;
8719 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8722 DEFUN (show_ip_bgp_regexp
,
8723 show_ip_bgp_regexp_cmd
,
8724 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8728 BGP_INSTANCE_HELP_STR
8731 "Display routes matching the AS path regular expression\n"
8732 "A regular-expression to match the BGP AS paths\n")
8734 afi_t afi
= AFI_IP6
;
8735 safi_t safi
= SAFI_UNICAST
;
8736 struct bgp
*bgp
= NULL
;
8739 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8743 // get index of regex
8744 argv_find (argv
, argc
, "regexp", &idx
);
8747 char *regstr
= argv_concat (argv
, argc
, idx
);
8748 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8749 XFREE (MTYPE_TMP
, regstr
);
8753 DEFUN (show_ip_bgp_instance_all
,
8754 show_ip_bgp_instance_all_cmd
,
8755 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8759 BGP_INSTANCE_ALL_HELP_STR
8765 safi_t safi
= SAFI_UNICAST
;
8766 struct bgp
*bgp
= NULL
;
8769 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8773 int uj
= use_json (argc
, argv
);
8776 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8781 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8782 safi_t safi
, enum bgp_show_type type
)
8787 regex
= bgp_regcomp (regstr
);
8790 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8794 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8795 bgp_regex_free (regex
);
8800 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8801 const char *prefix_list_str
, afi_t afi
,
8802 safi_t safi
, enum bgp_show_type type
)
8804 struct prefix_list
*plist
;
8806 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8809 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8810 prefix_list_str
, VTY_NEWLINE
);
8814 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8818 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8819 const char *filter
, afi_t afi
,
8820 safi_t safi
, enum bgp_show_type type
)
8822 struct as_list
*as_list
;
8824 as_list
= as_list_lookup (filter
);
8825 if (as_list
== NULL
)
8827 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8831 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8835 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8836 const char *rmap_str
, afi_t afi
,
8837 safi_t safi
, enum bgp_show_type type
)
8839 struct route_map
*rmap
;
8841 rmap
= route_map_lookup_by_name (rmap_str
);
8844 vty_out (vty
, "%% %s is not a valid route-map name%s",
8845 rmap_str
, VTY_NEWLINE
);
8849 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8853 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8854 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8856 struct community
*com
;
8863 b
= buffer_new (1024);
8864 for (i
= 0; i
< argc
; i
++)
8867 buffer_putc (b
, ' ');
8870 if (strmatch(argv
[i
]->text
, "unicast") || strmatch(argv
[i
]->text
, "multicast"))
8875 buffer_putstr (b
, argv
[i
]->arg
);
8877 buffer_putc (b
, '\0');
8879 str
= buffer_getstr (b
);
8882 com
= community_str2com (str
);
8883 XFREE (MTYPE_TMP
, str
);
8886 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8890 ret
= bgp_show (vty
, bgp
, afi
, safi
,
8891 (exact
? bgp_show_type_community_exact
:
8892 bgp_show_type_community
), com
, 0);
8893 community_free (com
);
8899 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8900 const char *com
, int exact
,
8901 afi_t afi
, safi_t safi
)
8903 struct community_list
*list
;
8905 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8908 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8913 return bgp_show (vty
, bgp
, afi
, safi
,
8914 (exact
? bgp_show_type_community_list_exact
:
8915 bgp_show_type_community_list
), list
, 0);
8919 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8920 const char *prefix
, afi_t afi
,
8921 safi_t safi
, enum bgp_show_type type
)
8928 ret
= str2prefix (prefix
, p
);
8931 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8935 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8940 static struct peer
*
8941 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8942 const char *ip_str
, u_char use_json
)
8948 /* Get peer sockunion. */
8949 ret
= str2sockunion (ip_str
, &su
);
8952 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8955 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8961 json_object
*json_no
= NULL
;
8962 json_no
= json_object_new_object();
8963 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8964 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8965 json_object_free(json_no
);
8968 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8975 /* Peer structure lookup. */
8976 peer
= peer_lookup (bgp
, &su
);
8981 json_object
*json_no
= NULL
;
8982 json_no
= json_object_new_object();
8983 json_object_string_add(json_no
, "warning","No such neighbor");
8984 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8985 json_object_free(json_no
);
8988 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8997 BGP_STATS_MAXBITLEN
= 0,
9001 BGP_STATS_UNAGGREGATEABLE
,
9002 BGP_STATS_MAX_AGGREGATEABLE
,
9003 BGP_STATS_AGGREGATES
,
9005 BGP_STATS_ASPATH_COUNT
,
9006 BGP_STATS_ASPATH_MAXHOPS
,
9007 BGP_STATS_ASPATH_TOTHOPS
,
9008 BGP_STATS_ASPATH_MAXSIZE
,
9009 BGP_STATS_ASPATH_TOTSIZE
,
9010 BGP_STATS_ASN_HIGHEST
,
9014 static const char *table_stats_strs
[] =
9016 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9017 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9018 [BGP_STATS_RIB
] = "Total Advertisements",
9019 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9020 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9021 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9022 [BGP_STATS_SPACE
] = "Address space advertised",
9023 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9024 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9025 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9026 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9027 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9028 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9029 [BGP_STATS_MAX
] = NULL
,
9032 struct bgp_table_stats
9034 struct bgp_table
*table
;
9035 unsigned long long counts
[BGP_STATS_MAX
];
9039 #define TALLY_SIGFIG 100000
9040 static unsigned long
9041 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9043 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9044 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9045 unsigned long ret
= newtot
/ count
;
9047 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9055 bgp_table_stats_walker (struct thread
*t
)
9057 struct bgp_node
*rn
;
9058 struct bgp_node
*top
;
9059 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9060 unsigned int space
= 0;
9062 if (!(top
= bgp_table_top (ts
->table
)))
9065 switch (top
->p
.family
)
9068 space
= IPV4_MAX_BITLEN
;
9071 space
= IPV6_MAX_BITLEN
;
9075 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9077 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9079 struct bgp_info
*ri
;
9080 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9081 unsigned int rinum
= 0;
9089 ts
->counts
[BGP_STATS_PREFIXES
]++;
9090 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9093 ts
->counts
[BGP_STATS_AVGPLEN
]
9094 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9095 ts
->counts
[BGP_STATS_AVGPLEN
],
9099 /* check if the prefix is included by any other announcements */
9100 while (prn
&& !prn
->info
)
9101 prn
= bgp_node_parent_nolock (prn
);
9103 if (prn
== NULL
|| prn
== top
)
9105 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9106 /* announced address space */
9108 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9111 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9113 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9116 ts
->counts
[BGP_STATS_RIB
]++;
9119 (CHECK_FLAG (ri
->attr
->flag
,
9120 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9121 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9124 if (ri
->attr
&& ri
->attr
->aspath
)
9126 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9127 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9128 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9130 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9132 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9133 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9135 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9136 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9138 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9139 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9141 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9142 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9143 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9145 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9146 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9147 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9150 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9151 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9159 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9161 struct bgp_table_stats ts
;
9164 if (!bgp
->rib
[afi
][safi
])
9166 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
9167 afi
, safi
, VTY_NEWLINE
);
9171 memset (&ts
, 0, sizeof (ts
));
9172 ts
.table
= bgp
->rib
[afi
][safi
];
9173 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9175 vty_out (vty
, "BGP %s RIB statistics%s%s",
9176 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
9178 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9180 if (!table_stats_strs
[i
])
9186 case BGP_STATS_ASPATH_AVGHOPS
:
9187 case BGP_STATS_ASPATH_AVGSIZE
:
9188 case BGP_STATS_AVGPLEN
:
9189 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9190 vty_out (vty
, "%12.2f",
9191 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9194 case BGP_STATS_ASPATH_TOTHOPS
:
9195 case BGP_STATS_ASPATH_TOTSIZE
:
9196 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9197 vty_out (vty
, "%12.2f",
9199 (float)ts
.counts
[i
] /
9200 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9203 case BGP_STATS_TOTPLEN
:
9204 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9205 vty_out (vty
, "%12.2f",
9207 (float)ts
.counts
[i
] /
9208 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9211 case BGP_STATS_SPACE
:
9212 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9213 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
9214 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9216 vty_out (vty
, "%30s: ", "%% announced ");
9217 vty_out (vty
, "%12.2f%s",
9218 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
9219 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
9221 vty_out (vty
, "%30s: ", "/8 equivalent ");
9222 vty_out (vty
, "%12.2f%s",
9223 (float)ts
.counts
[BGP_STATS_SPACE
] /
9224 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
9226 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9228 vty_out (vty
, "%30s: ", "/24 equivalent ");
9229 vty_out (vty
, "%12.2f",
9230 (float)ts
.counts
[BGP_STATS_SPACE
] /
9231 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9234 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9235 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9238 vty_out (vty
, "%s", VTY_NEWLINE
);
9253 PCOUNT_PFCNT
, /* the figure we display to users */
9257 static const char *pcount_strs
[] =
9259 [PCOUNT_ADJ_IN
] = "Adj-in",
9260 [PCOUNT_DAMPED
] = "Damped",
9261 [PCOUNT_REMOVED
] = "Removed",
9262 [PCOUNT_HISTORY
] = "History",
9263 [PCOUNT_STALE
] = "Stale",
9264 [PCOUNT_VALID
] = "Valid",
9265 [PCOUNT_ALL
] = "All RIB",
9266 [PCOUNT_COUNTED
] = "PfxCt counted",
9267 [PCOUNT_PFCNT
] = "Useable",
9268 [PCOUNT_MAX
] = NULL
,
9273 unsigned int count
[PCOUNT_MAX
];
9274 const struct peer
*peer
;
9275 const struct bgp_table
*table
;
9279 bgp_peer_count_walker (struct thread
*t
)
9281 struct bgp_node
*rn
;
9282 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9283 const struct peer
*peer
= pc
->peer
;
9285 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9287 struct bgp_adj_in
*ain
;
9288 struct bgp_info
*ri
;
9290 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9291 if (ain
->peer
== peer
)
9292 pc
->count
[PCOUNT_ADJ_IN
]++;
9294 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9296 char buf
[SU_ADDRSTRLEN
];
9298 if (ri
->peer
!= peer
)
9301 pc
->count
[PCOUNT_ALL
]++;
9303 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9304 pc
->count
[PCOUNT_DAMPED
]++;
9305 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9306 pc
->count
[PCOUNT_HISTORY
]++;
9307 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9308 pc
->count
[PCOUNT_REMOVED
]++;
9309 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9310 pc
->count
[PCOUNT_STALE
]++;
9311 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9312 pc
->count
[PCOUNT_VALID
]++;
9313 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9314 pc
->count
[PCOUNT_PFCNT
]++;
9316 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9318 pc
->count
[PCOUNT_COUNTED
]++;
9319 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9320 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9322 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9323 buf
, SU_ADDRSTRLEN
),
9329 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9330 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9332 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9333 buf
, SU_ADDRSTRLEN
),
9343 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9345 struct peer_pcounts pcounts
= { .peer
= peer
};
9347 json_object
*json
= NULL
;
9348 json_object
*json_loop
= NULL
;
9352 json
= json_object_new_object();
9353 json_loop
= json_object_new_object();
9356 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9357 || !peer
->bgp
->rib
[afi
][safi
])
9361 json_object_string_add(json
, "warning", "No such neighbor or address family");
9362 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9363 json_object_free(json
);
9366 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9371 memset (&pcounts
, 0, sizeof(pcounts
));
9372 pcounts
.peer
= peer
;
9373 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9375 /* in-place call via thread subsystem so as to record execution time
9376 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9377 * * on just vty_read()).
9379 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9383 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9384 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9385 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9387 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9388 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9390 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9392 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9394 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9395 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9397 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9398 json_object_free(json
);
9403 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9405 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9406 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9411 vty_out (vty
, "Prefix counts for %s, %s%s",
9412 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9415 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9416 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9417 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9419 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9420 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9422 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9424 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9425 peer
->host
, VTY_NEWLINE
);
9426 vty_out (vty
, "Please report this bug, with the above command output%s",
9434 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9435 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9436 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] "
9437 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9441 BGP_INSTANCE_HELP_STR
9444 "Address Family modifier\n"
9445 "Address Family modifier\n"
9446 "Address Family modifier\n"
9447 "Address Family modifier\n"
9448 "Address Family modifier\n"
9449 "Detailed information on TCP and BGP neighbor connections\n"
9450 "Neighbor to display information about\n"
9451 "Neighbor to display information about\n"
9452 "Neighbor on BGP configured interface\n"
9453 "Display detailed prefix count information\n"
9456 afi_t afi
= AFI_IP6
;
9457 safi_t safi
= SAFI_UNICAST
;
9460 struct bgp
*bgp
= NULL
;
9462 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9466 int uj
= use_json (argc
, argv
);
9469 argv_find (argv
, argc
, "neighbors", &idx
);
9470 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9474 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9477 #ifdef KEEP_OLD_VPN_COMMANDS
9478 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9479 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9480 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9485 "Display information about all VPNv4 NLRIs\n"
9486 "Detailed information on TCP and BGP neighbor connections\n"
9487 "Neighbor to display information about\n"
9488 "Neighbor to display information about\n"
9489 "Neighbor on BGP configured interface\n"
9490 "Display detailed prefix count information\n"
9495 u_char uj
= use_json(argc
, argv
);
9497 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9501 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9504 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9505 show_ip_bgp_vpn_all_route_prefix_cmd
,
9506 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9511 "Display information about all VPNv4 NLRIs\n"
9512 "Network in the BGP routing table to display\n"
9513 "Network in the BGP routing table to display\n"
9517 char *network
= NULL
;
9518 struct bgp
*bgp
= bgp_get_default();
9521 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9525 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9526 network
= argv
[idx
]->arg
;
9527 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9528 network
= argv
[idx
]->arg
;
9531 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9535 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9537 #endif /* KEEP_OLD_VPN_COMMANDS */
9539 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9540 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9541 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9547 "Display information about all EVPN NLRIs\n"
9548 "Network in the BGP routing table to display\n"
9549 "Network in the BGP routing table to display\n"
9553 char *network
= NULL
;
9555 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9556 network
= argv
[idx
]->arg
;
9557 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9558 network
= argv
[idx
]->arg
;
9561 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9564 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9568 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9569 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9571 struct bgp_table
*table
;
9572 struct bgp_adj_in
*ain
;
9573 struct bgp_adj_out
*adj
;
9574 unsigned long output_count
;
9575 unsigned long filtered_count
;
9576 struct bgp_node
*rn
;
9581 struct attr_extra extra
;
9583 struct update_subgroup
*subgrp
;
9584 json_object
*json_scode
= NULL
;
9585 json_object
*json_ocode
= NULL
;
9586 json_object
*json_ar
= NULL
;
9587 struct peer_af
*paf
;
9591 json_scode
= json_object_new_object();
9592 json_ocode
= json_object_new_object();
9593 json_ar
= json_object_new_object();
9595 json_object_string_add(json_scode
, "suppressed", "s");
9596 json_object_string_add(json_scode
, "damped", "d");
9597 json_object_string_add(json_scode
, "history", "h");
9598 json_object_string_add(json_scode
, "valid", "*");
9599 json_object_string_add(json_scode
, "best", ">");
9600 json_object_string_add(json_scode
, "multipath", "=");
9601 json_object_string_add(json_scode
, "internal", "i");
9602 json_object_string_add(json_scode
, "ribFailure", "r");
9603 json_object_string_add(json_scode
, "stale", "S");
9604 json_object_string_add(json_scode
, "removed", "R");
9606 json_object_string_add(json_ocode
, "igp", "i");
9607 json_object_string_add(json_ocode
, "egp", "e");
9608 json_object_string_add(json_ocode
, "incomplete", "?");
9617 json_object_string_add(json
, "alert", "no BGP");
9618 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9619 json_object_free(json
);
9622 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9626 table
= bgp
->rib
[afi
][safi
];
9628 output_count
= filtered_count
= 0;
9629 subgrp
= peer_subgroup(peer
, afi
, safi
);
9631 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9635 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9636 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9637 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9638 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9639 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9643 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9644 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9645 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9647 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9648 VTY_NEWLINE
, VTY_NEWLINE
);
9653 attr
.extra
= &extra
;
9654 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9658 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9660 if (ain
->peer
== peer
)
9666 json_object_int_add(json
, "bgpTableVersion", 0);
9667 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9668 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9669 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9673 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9674 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9675 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9682 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9687 bgp_attr_dup(&attr
, ain
->attr
);
9688 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9690 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9701 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9702 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9703 if (paf
->peer
== peer
)
9709 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9710 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9711 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9712 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9716 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9717 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9718 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9719 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9727 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9733 bgp_attr_dup(&attr
, adj
->attr
);
9734 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9735 if (ret
!= RMAP_DENY
)
9737 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9747 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9749 if (output_count
!= 0)
9752 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9754 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9755 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9759 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9760 json_object_free(json
);
9766 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9767 int in
, const char *rmap_name
, u_char use_json
)
9769 json_object
*json
= NULL
;
9772 json
= json_object_new_object();
9774 if (!peer
|| !peer
->afc
[afi
][safi
])
9778 json_object_string_add(json
, "warning", "No such neighbor or address family");
9779 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9780 json_object_free(json
);
9783 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9788 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9792 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9793 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9794 json_object_free(json
);
9797 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9802 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9807 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9808 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9809 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9810 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9814 BGP_INSTANCE_HELP_STR
9817 "Detailed information on TCP and BGP neighbor connections\n"
9818 "Neighbor to display information about\n"
9819 "Neighbor to display information about\n"
9820 "Neighbor on BGP configured interface\n"
9821 "Display the received routes from neighbor\n"
9822 "Display the routes advertised to a BGP neighbor\n"
9823 "Route-map to modify the attributes\n"
9824 "Name of the route map\n"
9827 afi_t afi
= AFI_IP6
;
9828 safi_t safi
= SAFI_UNICAST
;
9829 char *rmap_name
= NULL
;
9830 char *peerstr
= NULL
;
9832 struct bgp
*bgp
= NULL
;
9837 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9841 int uj
= use_json (argc
, argv
);
9844 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9845 argv_find (argv
, argc
, "neighbors", &idx
);
9846 peerstr
= argv
[++idx
]->arg
;
9848 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9852 if (argv_find (argv
, argc
, "received-routes", &idx
))
9854 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9856 if (argv_find (argv
, argc
, "route-map", &idx
))
9857 rmap_name
= argv
[++idx
]->arg
;
9859 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9862 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9863 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9864 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9870 "Address Family modifier\n"
9871 "Detailed information on TCP and BGP neighbor connections\n"
9872 "Neighbor to display information about\n"
9873 "Neighbor to display information about\n"
9874 "Neighbor on BGP configured interface\n"
9875 "Display information received from a BGP neighbor\n"
9876 "Display the prefixlist filter\n"
9879 afi_t afi
= AFI_IP6
;
9880 safi_t safi
= SAFI_UNICAST
;
9881 char *peerstr
= NULL
;
9891 if (argv_find (argv
, argc
, "ip", &idx
))
9893 /* [<ipv4|ipv6> [unicast]] */
9894 if (argv_find (argv
, argc
, "ipv4", &idx
))
9896 if (argv_find (argv
, argc
, "ipv6", &idx
))
9898 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9899 argv_find (argv
, argc
, "neighbors", &idx
);
9900 peerstr
= argv
[++idx
]->arg
;
9902 u_char uj
= use_json(argc
, argv
);
9904 ret
= str2sockunion (peerstr
, &su
);
9907 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9911 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9913 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9919 peer
= peer_lookup (NULL
, &su
);
9923 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9925 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9930 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9931 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9935 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9936 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9941 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9943 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9950 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9951 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9953 if (! peer
|| ! peer
->afc
[afi
][safi
])
9957 json_object
*json_no
= NULL
;
9958 json_no
= json_object_new_object();
9959 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9960 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9961 json_object_free(json_no
);
9964 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9968 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9971 DEFUN (show_ip_bgp_neighbor_routes
,
9972 show_ip_bgp_neighbor_routes_cmd
,
9973 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9974 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9978 BGP_INSTANCE_HELP_STR
9981 "Detailed information on TCP and BGP neighbor connections\n"
9982 "Neighbor to display information about\n"
9983 "Neighbor to display information about\n"
9984 "Neighbor on BGP configured interface\n"
9985 "Display flap statistics of the routes learned from neighbor\n"
9986 "Display the dampened routes received from neighbor\n"
9987 "Display routes learned from neighbor\n"
9990 char *peerstr
= NULL
;
9991 struct bgp
*bgp
= NULL
;
9992 afi_t afi
= AFI_IP6
;
9993 safi_t safi
= SAFI_UNICAST
;
9995 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9999 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10001 return CMD_WARNING
;
10003 int uj
= use_json (argc
, argv
);
10006 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10007 argv_find (argv
, argc
, "neighbors", &idx
);
10008 peerstr
= argv
[++idx
]->arg
;
10010 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10013 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
10014 return CMD_WARNING
;
10017 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10018 sh_type
= bgp_show_type_flap_neighbor
;
10019 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10020 sh_type
= bgp_show_type_damp_neighbor
;
10021 else if (argv_find (argv
, argc
, "routes", &idx
))
10022 sh_type
= bgp_show_type_neighbor
;
10024 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10027 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10029 struct bgp_distance
10031 /* Distance value for the IP source prefix. */
10034 /* Name of the access-list to be matched. */
10038 DEFUN (show_bgp_afi_vpn_rd_route
,
10039 show_bgp_afi_vpn_rd_route_cmd
,
10040 "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]",
10044 "Address Family modifier\n"
10045 "Display information for a route distinguisher\n"
10046 "Route Distinguisher\n"
10047 "Network in the BGP routing table to display\n"
10048 "Network in the BGP routing table to display\n"
10052 struct prefix_rd prd
;
10053 afi_t afi
= AFI_MAX
;
10056 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10057 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10060 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
10061 return CMD_WARNING
;
10063 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10066 static struct bgp_distance
*
10067 bgp_distance_new (void)
10069 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10073 bgp_distance_free (struct bgp_distance
*bdistance
)
10075 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10079 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10080 const char *ip_str
, const char *access_list_str
)
10087 struct bgp_node
*rn
;
10088 struct bgp_distance
*bdistance
;
10090 afi
= bgp_node_afi (vty
);
10091 safi
= bgp_node_safi (vty
);
10093 ret
= str2prefix (ip_str
, &p
);
10096 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10097 return CMD_WARNING
;
10100 distance
= atoi (distance_str
);
10102 /* Get BGP distance node. */
10103 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10106 bdistance
= rn
->info
;
10107 bgp_unlock_node (rn
);
10111 bdistance
= bgp_distance_new ();
10112 rn
->info
= bdistance
;
10115 /* Set distance value. */
10116 bdistance
->distance
= distance
;
10118 /* Reset access-list configuration. */
10119 if (bdistance
->access_list
)
10121 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10122 bdistance
->access_list
= NULL
;
10124 if (access_list_str
)
10125 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10127 return CMD_SUCCESS
;
10131 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10132 const char *ip_str
, const char *access_list_str
)
10139 struct bgp_node
*rn
;
10140 struct bgp_distance
*bdistance
;
10142 afi
= bgp_node_afi (vty
);
10143 safi
= bgp_node_safi (vty
);
10145 ret
= str2prefix (ip_str
, &p
);
10148 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
10149 return CMD_WARNING
;
10152 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10155 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
10156 return CMD_WARNING
;
10159 bdistance
= rn
->info
;
10160 distance
= atoi(distance_str
);
10162 if (bdistance
->distance
!= distance
)
10164 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
10165 return CMD_WARNING
;
10168 if (bdistance
->access_list
)
10169 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10170 bgp_distance_free (bdistance
);
10173 bgp_unlock_node (rn
);
10174 bgp_unlock_node (rn
);
10176 return CMD_SUCCESS
;
10179 /* Apply BGP information to distance method. */
10181 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10182 safi_t safi
, struct bgp
*bgp
)
10184 struct bgp_node
*rn
;
10187 struct bgp_distance
*bdistance
;
10188 struct access_list
*alist
;
10189 struct bgp_static
*bgp_static
;
10194 peer
= rinfo
->peer
;
10196 /* Check source address. */
10197 sockunion2hostprefix (&peer
->su
, &q
);
10198 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10201 bdistance
= rn
->info
;
10202 bgp_unlock_node (rn
);
10204 if (bdistance
->access_list
)
10206 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10207 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10208 return bdistance
->distance
;
10211 return bdistance
->distance
;
10214 /* Backdoor check. */
10215 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10218 bgp_static
= rn
->info
;
10219 bgp_unlock_node (rn
);
10221 if (bgp_static
->backdoor
)
10223 if (bgp
->distance_local
[afi
][safi
])
10224 return bgp
->distance_local
[afi
][safi
];
10226 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10230 if (peer
->sort
== BGP_PEER_EBGP
)
10232 if (bgp
->distance_ebgp
[afi
][safi
])
10233 return bgp
->distance_ebgp
[afi
][safi
];
10234 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10238 if (bgp
->distance_ibgp
[afi
][safi
])
10239 return bgp
->distance_ibgp
[afi
][safi
];
10240 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10244 DEFUN (bgp_distance
,
10246 "distance bgp (1-255) (1-255) (1-255)",
10247 "Define an administrative distance\n"
10249 "Distance for routes external to the AS\n"
10250 "Distance for routes internal to the AS\n"
10251 "Distance for local routes\n")
10253 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10254 int idx_number
= 2;
10255 int idx_number_2
= 3;
10256 int idx_number_3
= 4;
10260 afi
= bgp_node_afi (vty
);
10261 safi
= bgp_node_safi (vty
);
10263 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10264 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10265 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10266 return CMD_SUCCESS
;
10269 DEFUN (no_bgp_distance
,
10270 no_bgp_distance_cmd
,
10271 "no distance bgp [(1-255) (1-255) (1-255)]",
10273 "Define an administrative distance\n"
10275 "Distance for routes external to the AS\n"
10276 "Distance for routes internal to the AS\n"
10277 "Distance for local routes\n")
10279 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10283 afi
= bgp_node_afi (vty
);
10284 safi
= bgp_node_safi (vty
);
10286 bgp
->distance_ebgp
[afi
][safi
] = 0;
10287 bgp
->distance_ibgp
[afi
][safi
] = 0;
10288 bgp
->distance_local
[afi
][safi
] = 0;
10289 return CMD_SUCCESS
;
10293 DEFUN (bgp_distance_source
,
10294 bgp_distance_source_cmd
,
10295 "distance (1-255) A.B.C.D/M",
10296 "Define an administrative distance\n"
10297 "Administrative distance\n"
10298 "IP source prefix\n")
10300 int idx_number
= 1;
10301 int idx_ipv4_prefixlen
= 2;
10302 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10303 return CMD_SUCCESS
;
10306 DEFUN (no_bgp_distance_source
,
10307 no_bgp_distance_source_cmd
,
10308 "no distance (1-255) A.B.C.D/M",
10310 "Define an administrative distance\n"
10311 "Administrative distance\n"
10312 "IP source prefix\n")
10314 int idx_number
= 2;
10315 int idx_ipv4_prefixlen
= 3;
10316 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10317 return CMD_SUCCESS
;
10320 DEFUN (bgp_distance_source_access_list
,
10321 bgp_distance_source_access_list_cmd
,
10322 "distance (1-255) A.B.C.D/M WORD",
10323 "Define an administrative distance\n"
10324 "Administrative distance\n"
10325 "IP source prefix\n"
10326 "Access list name\n")
10328 int idx_number
= 1;
10329 int idx_ipv4_prefixlen
= 2;
10331 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10332 return CMD_SUCCESS
;
10335 DEFUN (no_bgp_distance_source_access_list
,
10336 no_bgp_distance_source_access_list_cmd
,
10337 "no distance (1-255) A.B.C.D/M WORD",
10339 "Define an administrative distance\n"
10340 "Administrative distance\n"
10341 "IP source prefix\n"
10342 "Access list name\n")
10344 int idx_number
= 2;
10345 int idx_ipv4_prefixlen
= 3;
10347 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10348 return CMD_SUCCESS
;
10351 DEFUN (ipv6_bgp_distance_source
,
10352 ipv6_bgp_distance_source_cmd
,
10353 "distance (1-255) X:X::X:X/M",
10354 "Define an administrative distance\n"
10355 "Administrative distance\n"
10356 "IP source prefix\n")
10358 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10359 return CMD_SUCCESS
;
10362 DEFUN (no_ipv6_bgp_distance_source
,
10363 no_ipv6_bgp_distance_source_cmd
,
10364 "no distance (1-255) X:X::X:X/M",
10366 "Define an administrative distance\n"
10367 "Administrative distance\n"
10368 "IP source prefix\n")
10370 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10371 return CMD_SUCCESS
;
10374 DEFUN (ipv6_bgp_distance_source_access_list
,
10375 ipv6_bgp_distance_source_access_list_cmd
,
10376 "distance (1-255) X:X::X:X/M WORD",
10377 "Define an administrative distance\n"
10378 "Administrative distance\n"
10379 "IP source prefix\n"
10380 "Access list name\n")
10382 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10383 return CMD_SUCCESS
;
10386 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10387 no_ipv6_bgp_distance_source_access_list_cmd
,
10388 "no distance (1-255) X:X::X:X/M WORD",
10390 "Define an administrative distance\n"
10391 "Administrative distance\n"
10392 "IP source prefix\n"
10393 "Access list name\n")
10395 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10396 return CMD_SUCCESS
;
10399 DEFUN (bgp_damp_set
,
10401 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10402 "BGP Specific commands\n"
10403 "Enable route-flap dampening\n"
10404 "Half-life time for the penalty\n"
10405 "Value to start reusing a route\n"
10406 "Value to start suppressing a route\n"
10407 "Maximum duration to suppress a stable route\n")
10409 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10410 int idx_half_life
= 2;
10412 int idx_suppress
= 4;
10413 int idx_max_suppress
= 5;
10414 int half
= DEFAULT_HALF_LIFE
* 60;
10415 int reuse
= DEFAULT_REUSE
;
10416 int suppress
= DEFAULT_SUPPRESS
;
10417 int max
= 4 * half
;
10421 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10422 reuse
= atoi (argv
[idx_reuse
]->arg
);
10423 suppress
= atoi (argv
[idx_suppress
]->arg
);
10424 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10426 else if (argc
== 3)
10428 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10432 if (suppress
< reuse
)
10434 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10439 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10440 half
, reuse
, suppress
, max
);
10443 DEFUN (bgp_damp_unset
,
10444 bgp_damp_unset_cmd
,
10445 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10447 "BGP Specific commands\n"
10448 "Enable route-flap dampening\n"
10449 "Half-life time for the penalty\n"
10450 "Value to start reusing a route\n"
10451 "Value to start suppressing a route\n"
10452 "Maximum duration to suppress a stable route\n")
10454 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10455 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10458 /* Display specified route of BGP table. */
10460 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10461 const char *ip_str
, afi_t afi
, safi_t safi
,
10462 struct prefix_rd
*prd
, int prefix_check
)
10465 struct prefix match
;
10466 struct bgp_node
*rn
;
10467 struct bgp_node
*rm
;
10468 struct bgp_info
*ri
;
10469 struct bgp_info
*ri_temp
;
10471 struct bgp_table
*table
;
10473 /* BGP structure lookup. */
10476 bgp
= bgp_lookup_by_name (view_name
);
10479 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10480 return CMD_WARNING
;
10485 bgp
= bgp_get_default ();
10488 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10489 return CMD_WARNING
;
10493 /* Check IP address argument. */
10494 ret
= str2prefix (ip_str
, &match
);
10497 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10498 return CMD_WARNING
;
10501 match
.family
= afi2family (afi
);
10503 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10505 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10507 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10510 if ((table
= rn
->info
) != NULL
)
10511 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10513 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10518 if (ri
->extra
&& ri
->extra
->damp_info
)
10520 ri_temp
= ri
->next
;
10521 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10529 bgp_unlock_node (rm
);
10535 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10537 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10542 if (ri
->extra
&& ri
->extra
->damp_info
)
10544 ri_temp
= ri
->next
;
10545 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10553 bgp_unlock_node (rn
);
10557 return CMD_SUCCESS
;
10560 DEFUN (clear_ip_bgp_dampening
,
10561 clear_ip_bgp_dampening_cmd
,
10562 "clear ip bgp dampening",
10566 "Clear route flap dampening information\n")
10568 bgp_damp_info_clean ();
10569 return CMD_SUCCESS
;
10572 DEFUN (clear_ip_bgp_dampening_prefix
,
10573 clear_ip_bgp_dampening_prefix_cmd
,
10574 "clear ip bgp dampening A.B.C.D/M",
10578 "Clear route flap dampening information\n"
10581 int idx_ipv4_prefixlen
= 4;
10582 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10583 SAFI_UNICAST
, NULL
, 1);
10586 DEFUN (clear_ip_bgp_dampening_address
,
10587 clear_ip_bgp_dampening_address_cmd
,
10588 "clear ip bgp dampening A.B.C.D",
10592 "Clear route flap dampening information\n"
10593 "Network to clear damping information\n")
10596 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10597 SAFI_UNICAST
, NULL
, 0);
10600 DEFUN (clear_ip_bgp_dampening_address_mask
,
10601 clear_ip_bgp_dampening_address_mask_cmd
,
10602 "clear ip bgp dampening A.B.C.D A.B.C.D",
10606 "Clear route flap dampening information\n"
10607 "Network to clear damping information\n"
10611 int idx_ipv4_2
= 5;
10613 char prefix_str
[BUFSIZ
];
10615 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10618 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10619 return CMD_WARNING
;
10622 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10623 SAFI_UNICAST
, NULL
, 0);
10626 /* also used for encap safi */
10628 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10629 afi_t afi
, safi_t safi
, int *write
)
10631 struct bgp_node
*prn
;
10632 struct bgp_node
*rn
;
10633 struct bgp_table
*table
;
10635 struct prefix_rd
*prd
;
10636 struct bgp_static
*bgp_static
;
10638 char buf
[SU_ADDRSTRLEN
];
10639 char rdbuf
[RD_ADDRSTRLEN
];
10641 /* Network configuration. */
10642 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10643 if ((table
= prn
->info
) != NULL
)
10644 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10645 if ((bgp_static
= rn
->info
) != NULL
)
10648 prd
= (struct prefix_rd
*) &prn
->p
;
10650 /* "address-family" display. */
10651 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10653 /* "network" configuration display. */
10654 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10655 label
= decode_label (bgp_static
->tag
);
10657 vty_out (vty
, " network %s/%d rd %s",
10658 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10659 p
->prefixlen
, rdbuf
);
10660 if (safi
== SAFI_MPLS_VPN
)
10661 vty_out (vty
, " label %u", label
);
10663 if (bgp_static
->rmap
.name
)
10664 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10667 if (bgp_static
->backdoor
)
10668 vty_out (vty
, " backdoor");
10670 vty_out (vty
, "%s", VTY_NEWLINE
);
10676 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10677 afi_t afi
, safi_t safi
, int *write
)
10679 struct bgp_node
*prn
;
10680 struct bgp_node
*rn
;
10681 struct bgp_table
*table
;
10683 struct prefix_rd
*prd
;
10684 struct bgp_static
*bgp_static
;
10685 char buf
[PREFIX_STRLEN
];
10686 char buf2
[SU_ADDRSTRLEN
];
10687 char rdbuf
[RD_ADDRSTRLEN
];
10689 /* Network configuration. */
10690 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10691 if ((table
= prn
->info
) != NULL
)
10692 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10693 if ((bgp_static
= rn
->info
) != NULL
)
10695 char *macrouter
= NULL
;
10698 if(bgp_static
->router_mac
)
10699 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10700 if(bgp_static
->eth_s_id
)
10701 esi
= esi2str(bgp_static
->eth_s_id
);
10703 prd
= (struct prefix_rd
*) &prn
->p
;
10705 /* "address-family" display. */
10706 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10708 /* "network" configuration display. */
10709 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10711 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10713 prefix2str (p
, buf
, sizeof (buf
)),
10714 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10715 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10716 decode_label (bgp_static
->tag
), esi
, buf2
, macrouter
);
10717 vty_out (vty
, "%s", VTY_NEWLINE
);
10719 XFREE (MTYPE_TMP
, macrouter
);
10721 XFREE (MTYPE_TMP
, esi
);
10726 /* Configuration of static route announcement and aggregate
10729 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10730 afi_t afi
, safi_t safi
, int *write
)
10732 struct bgp_node
*rn
;
10734 struct bgp_static
*bgp_static
;
10735 struct bgp_aggregate
*bgp_aggregate
;
10736 char buf
[SU_ADDRSTRLEN
];
10738 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10739 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10741 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10742 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10744 /* Network configuration. */
10745 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10746 if ((bgp_static
= rn
->info
) != NULL
)
10750 /* "address-family" display. */
10751 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10753 /* "network" configuration display. */
10754 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10756 u_int32_t destination
;
10757 struct in_addr netmask
;
10759 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10760 masklen2ip (p
->prefixlen
, &netmask
);
10761 vty_out (vty
, " network %s",
10762 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10764 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10765 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10766 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10767 || p
->u
.prefix4
.s_addr
== 0)
10769 /* Natural mask is not display. */
10772 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10776 vty_out (vty
, " network %s/%d",
10777 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10781 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10782 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10784 if (bgp_static
->rmap
.name
)
10785 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10788 if (bgp_static
->backdoor
)
10789 vty_out (vty
, " backdoor");
10792 vty_out (vty
, "%s", VTY_NEWLINE
);
10795 /* Aggregate-address configuration. */
10796 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10797 if ((bgp_aggregate
= rn
->info
) != NULL
)
10801 /* "address-family" display. */
10802 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10804 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10806 struct in_addr netmask
;
10808 masklen2ip (p
->prefixlen
, &netmask
);
10809 vty_out (vty
, " aggregate-address %s %s",
10810 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10811 inet_ntoa (netmask
));
10815 vty_out (vty
, " aggregate-address %s/%d",
10816 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10820 if (bgp_aggregate
->as_set
)
10821 vty_out (vty
, " as-set");
10823 if (bgp_aggregate
->summary_only
)
10824 vty_out (vty
, " summary-only");
10826 vty_out (vty
, "%s", VTY_NEWLINE
);
10833 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10834 safi_t safi
, int *write
)
10836 struct bgp_node
*rn
;
10837 struct bgp_distance
*bdistance
;
10839 /* Distance configuration. */
10840 if (bgp
->distance_ebgp
[afi
][safi
]
10841 && bgp
->distance_ibgp
[afi
][safi
]
10842 && bgp
->distance_local
[afi
][safi
]
10843 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10844 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10845 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10847 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10848 vty_out (vty
, " distance bgp %d %d %d%s",
10849 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10850 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10853 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10854 rn
= bgp_route_next (rn
))
10855 if ((bdistance
= rn
->info
) != NULL
)
10857 char buf
[PREFIX_STRLEN
];
10859 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10860 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10861 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10862 bdistance
->access_list
? bdistance
->access_list
: "",
10869 /* Allocate routing table structure and install commands. */
10871 bgp_route_init (void)
10876 /* Init BGP distance table. */
10877 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10878 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10879 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10881 /* IPv4 BGP commands. */
10882 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10883 install_element (BGP_NODE
, &bgp_network_cmd
);
10884 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10885 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10886 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10887 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10888 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10889 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10890 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10891 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10892 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10893 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10894 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10895 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10897 install_element (BGP_NODE
, &aggregate_address_cmd
);
10898 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10899 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10900 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10902 /* IPv4 unicast configuration. */
10903 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10904 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10905 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10906 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10907 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10908 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10909 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10910 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_cmd
);
10911 install_element (BGP_IPV4L_NODE
, &no_bgp_network_label_index_route_map_cmd
);
10912 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10913 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10914 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10915 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10917 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10918 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10919 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10920 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10922 /* IPv4 multicast configuration. */
10923 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10924 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10925 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10926 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10927 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10928 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10929 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10930 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10931 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10932 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10933 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10934 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10935 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10936 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10937 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10939 /* IPv4 labeled-unicast configuration. */
10940 install_element (BGP_IPV4L_NODE
, &bgp_table_map_cmd
);
10941 install_element (BGP_IPV4L_NODE
, &bgp_network_cmd
);
10942 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_cmd
);
10943 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_cmd
);
10944 install_element (BGP_IPV4L_NODE
, &bgp_network_route_map_cmd
);
10945 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_route_map_cmd
);
10946 install_element (BGP_IPV4L_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10947 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_cmd
);
10948 install_element (BGP_IPV4L_NODE
, &bgp_network_label_index_route_map_cmd
);
10949 install_element (BGP_IPV4L_NODE
, &no_bgp_table_map_cmd
);
10950 install_element (BGP_IPV4L_NODE
, &no_bgp_network_cmd
);
10951 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_cmd
);
10952 install_element (BGP_IPV4L_NODE
, &no_bgp_network_mask_natural_cmd
);
10954 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10955 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10956 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10957 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10959 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10960 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10961 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10962 #ifdef KEEP_OLD_VPN_COMMANDS
10963 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10964 #endif /* KEEP_OLD_VPN_COMMANDS */
10965 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10966 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10968 /* BGP dampening clear commands */
10969 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10970 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10972 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10973 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10976 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10977 #ifdef KEEP_OLD_VPN_COMMANDS
10978 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10979 #endif /* KEEP_OLD_VPN_COMMANDS */
10981 /* New config IPv6 BGP commands. */
10982 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10983 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10984 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10985 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10986 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10987 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_label_index_cmd
);
10988 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
10989 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
10990 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
10992 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10993 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10995 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10996 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10998 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
10999 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11000 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11001 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11002 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11004 install_element (BGP_NODE
, &bgp_distance_cmd
);
11005 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
11006 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
11007 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
11008 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11009 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11010 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11011 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11012 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11013 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11014 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11015 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11016 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11017 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11018 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11019 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11020 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11021 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11022 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11023 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11024 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11025 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11026 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11027 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11028 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11029 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11030 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11031 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11032 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11033 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11035 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11036 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11037 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11038 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11040 /* IPv4 Multicast Mode */
11041 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11042 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11044 /* Large Communities */
11045 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11046 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11050 bgp_route_finish (void)
11055 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11056 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11058 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11059 bgp_distance_table
[afi
][safi
] = NULL
;