1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "sockunion.h"
36 #include "workqueue.h"
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_route.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_debug.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_regex.h"
48 #include "bgpd/bgp_community.h"
49 #include "bgpd/bgp_ecommunity.h"
50 #include "bgpd/bgp_lcommunity.h"
51 #include "bgpd/bgp_clist.h"
52 #include "bgpd/bgp_packet.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_fsm.h"
55 #include "bgpd/bgp_mplsvpn.h"
56 #include "bgpd/bgp_nexthop.h"
57 #include "bgpd/bgp_damp.h"
58 #include "bgpd/bgp_advertise.h"
59 #include "bgpd/bgp_zebra.h"
60 #include "bgpd/bgp_vty.h"
61 #include "bgpd/bgp_mpath.h"
62 #include "bgpd/bgp_nht.h"
63 #include "bgpd/bgp_updgrp.h"
64 #include "bgpd/bgp_label.h"
67 #include "bgpd/rfapi/rfapi_backend.h"
68 #include "bgpd/rfapi/vnc_import_bgp.h"
69 #include "bgpd/rfapi/vnc_export_bgp.h"
71 #include "bgpd/bgp_encap_types.h"
72 #include "bgpd/bgp_encap_tlv.h"
73 #include "bgpd/bgp_evpn.h"
74 #include "bgpd/bgp_evpn_vty.h"
77 /* Extern from bgp_dump.c */
78 extern const char *bgp_origin_str
[];
79 extern const char *bgp_origin_long_str
[];
82 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
83 struct prefix_rd
*prd
)
86 struct bgp_node
*prn
= NULL
;
92 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
95 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
97 if (prn
->info
== NULL
)
98 prn
->info
= bgp_table_init (afi
, safi
);
100 bgp_unlock_node (prn
);
104 rn
= bgp_node_get (table
, p
);
106 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
113 /* Allocate bgp_info_extra */
114 static struct bgp_info_extra
*
115 bgp_info_extra_new (void)
117 struct bgp_info_extra
*new;
118 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
119 new->label
= MPLS_INVALID_LABEL
;
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 one path has a label but the other does not, do not treat
698 * them as equals for multipath
700 if ((new->extra
&& bgp_is_valid_label(&new->extra
->label
)) !=
701 (exist
->extra
&& bgp_is_valid_label(&exist
->extra
->label
)))
704 zlog_debug("%s: %s and %s cannot be multipath, one has a label while the other does not",
705 pfx_buf
, new_buf
, exist_buf
);
707 else if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
711 * For the two paths, all comparison steps till IGP metric
712 * have succeeded - including AS_PATH hop count. Since 'bgp
713 * bestpath as-path multipath-relax' knob is on, we don't need
714 * an exact match of AS_PATH. Thus, mark the paths are equal.
715 * That will trigger both these paths to get into the multipath
721 zlog_debug("%s: %s and %s are equal via multipath-relax",
722 pfx_buf
, new_buf
, exist_buf
);
724 else if (new->peer
->sort
== BGP_PEER_IBGP
)
726 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
731 zlog_debug("%s: %s and %s are equal via matching aspaths",
732 pfx_buf
, new_buf
, exist_buf
);
735 else if (new->peer
->as
== exist
->peer
->as
)
740 zlog_debug("%s: %s and %s are equal via same remote-as",
741 pfx_buf
, new_buf
, exist_buf
);
747 * TODO: If unequal cost ibgp multipath is enabled we can
748 * mark the paths as equal here instead of returning
753 zlog_debug("%s: %s wins over %s after IGP metric comparison",
754 pfx_buf
, new_buf
, exist_buf
);
756 zlog_debug("%s: %s loses to %s after IGP metric comparison",
757 pfx_buf
, new_buf
, exist_buf
);
762 /* 12. If both paths are external, prefer the path that was received
763 first (the oldest one). This step minimizes route-flap, since a
764 newer path won't displace an older one, even if it was the
765 preferred route based on the additional decision criteria below. */
766 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
767 && new_sort
== BGP_PEER_EBGP
768 && exist_sort
== BGP_PEER_EBGP
)
770 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
773 zlog_debug("%s: %s wins over %s due to oldest external",
774 pfx_buf
, new_buf
, exist_buf
);
778 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
781 zlog_debug("%s: %s loses to %s due to oldest external",
782 pfx_buf
, new_buf
, exist_buf
);
787 /* 13. Router-ID comparision. */
788 /* If one of the paths is "stale", the corresponding peer router-id will
789 * be 0 and would always win over the other path. If originator id is
790 * used for the comparision, it will decide which path is better.
792 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
793 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
795 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
796 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
797 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
799 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
801 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
804 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
805 pfx_buf
, new_buf
, exist_buf
);
809 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
812 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
813 pfx_buf
, new_buf
, exist_buf
);
817 /* 14. Cluster length comparision. */
818 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
819 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
821 if (new_cluster
< exist_cluster
)
824 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
825 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
829 if (new_cluster
> exist_cluster
)
832 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
833 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
837 /* 15. Neighbor address comparision. */
838 /* Do this only if neither path is "stale" as stale paths do not have
839 * valid peer information (as the connection may or may not be up).
841 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
844 zlog_debug("%s: %s wins over %s due to latter path being STALE",
845 pfx_buf
, new_buf
, exist_buf
);
849 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
852 zlog_debug("%s: %s loses to %s due to former path being STALE",
853 pfx_buf
, new_buf
, exist_buf
);
857 /* locally configured routes to advertise do not have su_remote */
858 if (new->peer
->su_remote
== NULL
)
860 if (exist
->peer
->su_remote
== NULL
)
863 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
868 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
869 pfx_buf
, new_buf
, exist_buf
);
876 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
877 pfx_buf
, new_buf
, exist_buf
);
882 zlog_debug("%s: %s wins over %s due to nothing left to compare",
883 pfx_buf
, new_buf
, exist_buf
);
888 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
889 * is preferred, or 0 if they are the same (usually will only occur if
890 * multipath is enabled
891 * This version is compatible with */
893 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
894 afi_t afi
, safi_t safi
)
898 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
912 static enum filter_type
913 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
914 afi_t afi
, safi_t safi
)
916 struct bgp_filter
*filter
;
918 filter
= &peer
->filter
[afi
][safi
];
920 #define FILTER_EXIST_WARN(F,f,filter) \
921 if (BGP_DEBUG (update, UPDATE_IN) \
922 && !(F ## _IN (filter))) \
923 zlog_warn ("%s: Could not find configured input %s-list %s!", \
924 peer->host, #f, F ## _IN_NAME(filter));
926 if (DISTRIBUTE_IN_NAME (filter
)) {
927 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
929 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
933 if (PREFIX_LIST_IN_NAME (filter
)) {
934 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
936 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
940 if (FILTER_LIST_IN_NAME (filter
)) {
941 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
943 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
947 return FILTER_PERMIT
;
948 #undef FILTER_EXIST_WARN
951 static enum filter_type
952 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
953 afi_t afi
, safi_t safi
)
955 struct bgp_filter
*filter
;
957 filter
= &peer
->filter
[afi
][safi
];
959 #define FILTER_EXIST_WARN(F,f,filter) \
960 if (BGP_DEBUG (update, UPDATE_OUT) \
961 && !(F ## _OUT (filter))) \
962 zlog_warn ("%s: Could not find configured output %s-list %s!", \
963 peer->host, #f, F ## _OUT_NAME(filter));
965 if (DISTRIBUTE_OUT_NAME (filter
)) {
966 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
968 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
972 if (PREFIX_LIST_OUT_NAME (filter
)) {
973 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
975 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
979 if (FILTER_LIST_OUT_NAME (filter
)) {
980 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
982 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
986 return FILTER_PERMIT
;
987 #undef FILTER_EXIST_WARN
990 /* If community attribute includes no_export then return 1. */
992 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
996 /* NO_ADVERTISE check. */
997 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
1000 /* NO_EXPORT check. */
1001 if (peer
->sort
== BGP_PEER_EBGP
&&
1002 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
1005 /* NO_EXPORT_SUBCONFED check. */
1006 if (peer
->sort
== BGP_PEER_EBGP
1007 || peer
->sort
== BGP_PEER_CONFED
)
1008 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
1014 /* Route reflection loop check. */
1016 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1018 struct in_addr cluster_id
;
1020 if (attr
->extra
&& attr
->extra
->cluster
)
1022 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1023 cluster_id
= peer
->bgp
->cluster_id
;
1025 cluster_id
= peer
->bgp
->router_id
;
1027 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1034 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1035 afi_t afi
, safi_t safi
, const char *rmap_name
)
1037 struct bgp_filter
*filter
;
1038 struct bgp_info info
;
1039 route_map_result_t ret
;
1040 struct route_map
*rmap
= NULL
;
1042 filter
= &peer
->filter
[afi
][safi
];
1044 /* Apply default weight value. */
1045 if (peer
->weight
[afi
][safi
])
1046 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1050 rmap
= route_map_lookup_by_name(rmap_name
);
1057 if (ROUTE_MAP_IN_NAME(filter
))
1059 rmap
= ROUTE_MAP_IN (filter
);
1066 /* Route map apply. */
1069 /* Duplicate current value to new strucutre for modification. */
1073 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1075 /* Apply BGP route map to the attribute. */
1076 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1078 peer
->rmap_type
= 0;
1080 if (ret
== RMAP_DENYMATCH
)
1082 /* Free newly generated AS path and community by route-map. */
1083 bgp_attr_flush (attr
);
1091 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1092 afi_t afi
, safi_t safi
, const char *rmap_name
)
1094 struct bgp_filter
*filter
;
1095 struct bgp_info info
;
1096 route_map_result_t ret
;
1097 struct route_map
*rmap
= NULL
;
1099 filter
= &peer
->filter
[afi
][safi
];
1101 /* Apply default weight value. */
1102 if (peer
->weight
[afi
][safi
])
1103 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1107 rmap
= route_map_lookup_by_name(rmap_name
);
1114 if (ROUTE_MAP_OUT_NAME(filter
))
1116 rmap
= ROUTE_MAP_OUT (filter
);
1123 /* Route map apply. */
1126 /* Duplicate current value to new strucutre for modification. */
1130 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1132 /* Apply BGP route map to the attribute. */
1133 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1135 peer
->rmap_type
= 0;
1137 if (ret
== RMAP_DENYMATCH
)
1138 /* caller has multiple error paths with bgp_attr_flush() */
1144 /* If this is an EBGP peer with remove-private-AS */
1146 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1147 struct peer
*peer
, struct attr
*attr
)
1149 if (peer
->sort
== BGP_PEER_EBGP
&&
1150 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1151 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1152 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1153 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1155 // Take action on the entire aspath
1156 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1157 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1159 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1160 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1162 // The entire aspath consists of private ASNs so create an empty aspath
1163 else if (aspath_private_as_check (attr
->aspath
))
1164 attr
->aspath
= aspath_empty_get ();
1166 // There are some public and some private ASNs, remove the private ASNs
1168 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1171 // 'all' was not specified so the entire aspath must be private ASNs
1172 // for us to do anything
1173 else if (aspath_private_as_check (attr
->aspath
))
1175 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1176 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1178 attr
->aspath
= aspath_empty_get ();
1183 /* If this is an EBGP peer with as-override */
1185 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1186 struct peer
*peer
, struct attr
*attr
)
1188 if (peer
->sort
== BGP_PEER_EBGP
&&
1189 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1191 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1192 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1197 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1199 if (family
== AF_INET
)
1200 attr
->nexthop
.s_addr
= 0;
1201 if (family
== AF_INET6
)
1202 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1206 subgroup_announce_check (struct bgp_node
*rn
, struct bgp_info
*ri
,
1207 struct update_subgroup
*subgrp
,
1208 struct prefix
*p
, struct attr
*attr
)
1210 struct bgp_filter
*filter
;
1213 struct peer
*onlypeer
;
1215 struct attr
*riattr
;
1216 struct peer_af
*paf
;
1217 char buf
[PREFIX_STRLEN
];
1223 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1225 if (DISABLE_BGP_ANNOUNCE
)
1228 afi
= SUBGRP_AFI(subgrp
);
1229 safi
= SUBGRP_SAFI(subgrp
);
1230 peer
= SUBGRP_PEER(subgrp
);
1232 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1233 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1236 filter
= &peer
->filter
[afi
][safi
];
1237 bgp
= SUBGRP_INST(subgrp
);
1238 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1241 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1242 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1243 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1246 * direct and direct_ext type routes originate internally even
1247 * though they can have peer pointers that reference other systems
1249 prefix2str(p
, buf
, PREFIX_STRLEN
);
1250 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1255 /* With addpath we may be asked to TX all kinds of paths so make sure
1257 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1258 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1259 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1264 /* If this is not the bestpath then check to see if there is an enabled addpath
1265 * feature that requires us to advertise it */
1266 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1268 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1274 /* Aggregate-address suppress check. */
1275 if (ri
->extra
&& ri
->extra
->suppress
)
1276 if (! UNSUPPRESS_MAP_NAME (filter
))
1281 /* If it's labeled safi, make sure the route has a valid label. */
1282 if (safi
== SAFI_LABELED_UNICAST
)
1284 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1285 if (!bgp_is_valid_label(&label
))
1287 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1288 zlog_debug ("u%" PRIu64
":s%" PRIu64
" %s/%d is filtered - no label (%p)",
1289 subgrp
->update_group
->id
, subgrp
->id
,
1290 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1291 p
->prefixlen
, &label
);
1296 /* Do not send back route to sender. */
1297 if (onlypeer
&& from
== onlypeer
)
1302 /* Do not send the default route in the BGP table if the neighbor is
1303 * configured for default-originate */
1304 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1306 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1308 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1312 /* Transparency check. */
1313 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1314 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1319 /* If community is not disabled check the no-export and local. */
1320 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1322 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1323 zlog_debug ("subgrpannouncecheck: community filter check fail");
1327 /* If the attribute has originator-id and it is same as remote
1330 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1331 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1333 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1334 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1336 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1340 /* ORF prefix-list filter check */
1341 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1342 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1343 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1344 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1345 if (peer
->orf_plist
[afi
][safi
])
1347 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1349 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1350 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1351 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1356 /* Output filter check. */
1357 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1359 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1360 zlog_debug ("%s [Update:SEND] %s is filtered",
1361 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1365 #ifdef BGP_SEND_ASPATH_CHECK
1366 /* AS path loop check. */
1367 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1369 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1370 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1371 "that is part of AS path.",
1372 onlypeer
->host
, onlypeer
->as
);
1375 #endif /* BGP_SEND_ASPATH_CHECK */
1377 /* If we're a CONFED we need to loop check the CONFED ID too */
1378 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1380 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1382 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1383 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1391 /* Route-Reflect check. */
1392 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1397 /* IBGP reflection check. */
1398 if (reflect
&& !samepeer_safe
)
1400 /* A route from a Client peer. */
1401 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1403 /* Reflect to all the Non-Client peers and also to the
1404 Client peers other than the originator. Originator check
1405 is already done. So there is noting to do. */
1406 /* no bgp client-to-client reflection check. */
1407 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1408 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1409 PEER_FLAG_REFLECTOR_CLIENT
))
1414 /* A route from a Non-client peer. Reflect to all other
1416 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1417 PEER_FLAG_REFLECTOR_CLIENT
))
1422 /* For modify attribute, copy it to temporary structure. */
1423 bgp_attr_dup (attr
, riattr
);
1425 /* If local-preference is not set. */
1426 if ((peer
->sort
== BGP_PEER_IBGP
1427 || peer
->sort
== BGP_PEER_CONFED
)
1428 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1430 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1431 attr
->local_pref
= bgp
->default_local_pref
;
1434 /* If originator-id is not set and the route is to be reflected,
1435 set the originator id */
1436 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1438 attr
->extra
= bgp_attr_extra_get(attr
);
1439 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1440 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1443 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1444 if (peer
->sort
== BGP_PEER_EBGP
1445 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1447 if (from
!= bgp
->peer_self
&& ! transparent
1448 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1449 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1452 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1453 * in announce check, only certain flags and length (or number of nexthops
1454 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1455 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1456 * Typically, the source nexthop in the attribute is preserved but in the
1457 * scenarios where we know it will always be overwritten, we reset the
1458 * nexthop to "0" in an attempt to achieve better Update packing. An
1459 * example of this is when a prefix from each of 2 IBGP peers needs to be
1460 * announced to an EBGP peer (and they have the same attributes barring
1464 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1466 #define NEXTHOP_IS_V6 (\
1467 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1468 (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) || \
1469 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1470 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1472 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1473 * the peer (group) is configured to receive link-local nexthop unchanged
1474 * and it is available in the prefix OR we're not reflecting the route and
1475 * the peer (group) to whom we're going to announce is on a shared network
1476 * and this is either a self-originated route or the peer is EBGP.
1480 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1481 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1482 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1483 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1484 (!reflect
&& peer
->shared_network
&&
1485 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1487 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1490 /* Clear off link-local nexthop in source, whenever it is not needed to
1491 * ensure more prefixes share the same attribute for announcement.
1493 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1494 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1495 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1498 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1499 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1501 /* Route map & unsuppress-map apply. */
1502 if (ROUTE_MAP_OUT_NAME (filter
)
1503 || (ri
->extra
&& ri
->extra
->suppress
) )
1505 struct bgp_info info
;
1506 struct attr dummy_attr
;
1507 struct attr_extra dummy_extra
;
1509 dummy_attr
.extra
= &dummy_extra
;
1513 /* don't confuse inbound and outbound setting */
1514 RESET_FLAG(attr
->rmap_change_flags
);
1517 * The route reflector is not allowed to modify the attributes
1518 * of the reflected IBGP routes unless explicitly allowed.
1520 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1521 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1523 bgp_attr_dup (&dummy_attr
, attr
);
1524 info
.attr
= &dummy_attr
;
1527 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1529 if (ri
->extra
&& ri
->extra
->suppress
)
1530 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1532 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1534 peer
->rmap_type
= 0;
1536 if (ret
== RMAP_DENYMATCH
)
1538 bgp_attr_flush (attr
);
1543 /* After route-map has been applied, we check to see if the nexthop to
1544 * be carried in the attribute (that is used for the announcement) can
1545 * be cleared off or not. We do this in all cases where we would be
1546 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1547 * the global nexthop here; the link-local nexthop would have been cleared
1548 * already, and if not, it is required by the update formation code.
1549 * Also see earlier comments in this function.
1552 * If route-map has performed some operation on the nexthop or the peer
1553 * configuration says to pass it unchanged, we cannot reset the nexthop
1554 * here, so only attempt to do it if these aren't true. Note that the
1555 * route-map handler itself might have cleared the nexthop, if for example,
1556 * it is configured as 'peer-address'.
1558 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1559 riattr
->rmap_change_flags
) &&
1561 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1563 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1564 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1565 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1568 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1569 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1570 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ?
1571 AF_INET6
: p
->family
), attr
);
1573 else if (peer
->sort
== BGP_PEER_EBGP
)
1575 /* Can also reset the nexthop if announcing to EBGP, but only if
1576 * no peer in the subgroup is on a shared subnet.
1577 * Note: 3rd party nexthop currently implemented for IPv4 only.
1579 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1581 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1585 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ? AF_INET6
: p
->family
), attr
);
1587 /* If IPv6/MP and nexthop does not have any override and happens to
1588 * be a link-local address, reset it so that we don't pass along the
1589 * source's link-local IPv6 address to recipients who may not be on
1590 * the same interface.
1592 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
))
1594 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1595 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1602 struct bgp_info_pair
1604 struct bgp_info
*old
;
1605 struct bgp_info
*new;
1609 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1610 struct bgp_maxpaths_cfg
*mpath_cfg
,
1611 struct bgp_info_pair
*result
)
1613 struct bgp_info
*new_select
;
1614 struct bgp_info
*old_select
;
1615 struct bgp_info
*ri
;
1616 struct bgp_info
*ri1
;
1617 struct bgp_info
*ri2
;
1618 struct bgp_info
*nextri
= NULL
;
1619 int paths_eq
, do_mpath
, debug
;
1620 struct list mp_list
;
1621 char pfx_buf
[PREFIX2STR_BUFFER
];
1622 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1624 bgp_mp_list_init (&mp_list
);
1625 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1627 debug
= bgp_debug_bestpath(&rn
->p
);
1630 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1632 /* bgp deterministic-med */
1634 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1637 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1638 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1639 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1641 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1643 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1645 if (BGP_INFO_HOLDDOWN (ri1
))
1647 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1648 if (ri1
->peer
->status
!= Established
)
1654 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1656 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1658 if (BGP_INFO_HOLDDOWN (ri2
))
1661 ri2
->peer
!= bgp
->peer_self
&&
1662 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1663 if (ri2
->peer
->status
!= Established
)
1666 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1667 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1670 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1671 mpath_cfg
, debug
, pfx_buf
))
1673 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1677 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1681 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1682 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1686 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1687 zlog_debug("%s: %s is the bestpath from AS %d",
1688 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1693 /* Check old selected route and new selected route. */
1696 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1698 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1701 if (BGP_INFO_HOLDDOWN (ri
))
1703 /* reap REMOVED routes, if needs be
1704 * selected route must stay for a while longer though
1706 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1707 && (ri
!= old_select
))
1708 bgp_info_reap (rn
, ri
);
1714 ri
->peer
!= bgp
->peer_self
&&
1715 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1716 if (ri
->peer
->status
!= Established
)
1719 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1720 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1722 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1726 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1728 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1734 /* Now that we know which path is the bestpath see if any of the other paths
1735 * qualify as multipaths
1740 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1742 sprintf (path_buf
, "NONE");
1743 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1745 old_select
? old_select
->peer
->host
: "NONE");
1748 if (do_mpath
&& new_select
)
1750 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1754 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1756 if (ri
== new_select
)
1759 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1761 bgp_mp_list_add (&mp_list
, ri
);
1765 if (BGP_INFO_HOLDDOWN (ri
))
1769 ri
->peer
!= bgp
->peer_self
&&
1770 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1771 if (ri
->peer
->status
!= Established
)
1774 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1777 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1782 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1787 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1789 bgp_mp_list_add (&mp_list
, ri
);
1794 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1795 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1796 bgp_mp_list_clear (&mp_list
);
1798 result
->old
= old_select
;
1799 result
->new = new_select
;
1805 * A new route/change in bestpath of an existing route. Evaluate the path
1806 * for advertisement to the subgroup.
1809 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1810 struct bgp_info
*selected
,
1811 struct bgp_node
*rn
,
1812 u_int32_t addpath_tx_id
)
1815 struct peer
*onlypeer
;
1817 struct attr_extra extra
;
1822 afi
= SUBGRP_AFI(subgrp
);
1823 safi
= SUBGRP_SAFI(subgrp
);
1824 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1825 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1827 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1828 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1829 PEER_STATUS_ORF_WAIT_REFRESH
))
1832 memset(&extra
, 0, sizeof(struct attr_extra
));
1833 /* It's initialized in bgp_announce_check() */
1834 attr
.extra
= &extra
;
1836 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1839 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1840 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1842 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1845 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1848 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1855 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1856 * This is called at the end of route processing.
1859 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1861 struct bgp_info
*ri
;
1863 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1865 if (BGP_INFO_HOLDDOWN (ri
))
1867 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1868 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1873 * Has the route changed from the RIB's perspective? This is invoked only
1874 * if the route selection returns the same best route as earlier - to
1875 * determine if we need to update zebra or not.
1878 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1880 struct bgp_info
*mpinfo
;
1882 /* If this is multipath, check all selected paths for any nexthop change or
1883 * attribute change. Some attribute changes (e.g., community) aren't of
1884 * relevance to the RIB, but we'll update zebra to ensure we handle the
1885 * case of BGP nexthop change. This is the behavior when the best path has
1886 * an attribute change anyway.
1888 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1889 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1892 /* If this is multipath, check all selected paths for any nexthop change */
1893 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1894 mpinfo
= bgp_info_mpath_next (mpinfo
))
1896 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1897 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1901 /* Nothing has changed from the RIB's perspective. */
1905 struct bgp_process_queue
1908 struct bgp_node
*rn
;
1913 static wq_item_status
1914 bgp_process_main (struct work_queue
*wq
, void *data
)
1916 struct bgp_process_queue
*pq
= data
;
1917 struct bgp
*bgp
= pq
->bgp
;
1918 struct bgp_node
*rn
= pq
->rn
;
1919 afi_t afi
= pq
->afi
;
1920 safi_t safi
= pq
->safi
;
1921 struct prefix
*p
= &rn
->p
;
1922 struct bgp_info
*new_select
;
1923 struct bgp_info
*old_select
;
1924 struct bgp_info_pair old_and_new
;
1926 /* Is it end of initial update? (after startup) */
1929 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1930 sizeof(bgp
->update_delay_zebra_resume_time
));
1932 bgp
->main_zebra_update_hold
= 0;
1933 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1934 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1936 bgp_zebra_announce_table(bgp
, afi
, safi
);
1938 bgp
->main_peers_update_hold
= 0;
1940 bgp_start_routeadv(bgp
);
1944 /* Best path selection. */
1945 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1946 old_select
= old_and_new
.old
;
1947 new_select
= old_and_new
.new;
1949 /* Do we need to allocate or free labels?
1950 * Right now, since we only deal with per-prefix labels, it is not necessary
1951 * to do this upon changes to best path except of the label index changes.
1953 if (safi
== SAFI_UNICAST
)
1958 bgp_label_index_differs (new_select
, old_select
) ||
1959 new_select
->sub_type
!= old_select
->sub_type
)
1961 if (new_select
->sub_type
== BGP_ROUTE_STATIC
&&
1962 new_select
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
) &&
1963 new_select
->attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
1965 if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1966 bgp_unregister_for_label (rn
);
1967 label_ntop (MPLS_IMP_NULL_LABEL
, 1, &rn
->local_label
);
1968 bgp_set_valid_label(&rn
->local_label
);
1971 bgp_register_for_label (rn
, new_select
);
1974 else if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
1975 bgp_unregister_for_label (rn
);
1978 /* If best route remains the same and this is not due to user-initiated
1979 * clear, see exactly what needs to be done.
1982 if (old_select
&& old_select
== new_select
&&
1983 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1984 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1985 !bgp
->addpath_tx_used
[afi
][safi
])
1987 if (bgp_zebra_has_route_changed (rn
, old_select
))
1990 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1991 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1993 if (bgp_fibupd_safi(safi
) &&
1995 !bgp_option_check (BGP_OPT_NO_FIB
) &&
1996 new_select
->type
== ZEBRA_ROUTE_BGP
&&
1997 new_select
->sub_type
== BGP_ROUTE_NORMAL
)
1998 bgp_zebra_announce (rn
, p
, old_select
, bgp
, afi
, safi
);
2000 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2001 bgp_zebra_clear_route_change_flags (rn
);
2003 /* If there is a change of interest to peers, reannounce the route. */
2004 if (CHECK_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
) ||
2005 CHECK_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
))
2007 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2009 /* unicast routes must also be annouced to labeled-unicast update-groups */
2010 if (safi
== SAFI_UNICAST
)
2011 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
, new_select
);
2013 UNSET_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2014 UNSET_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2017 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2021 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
2022 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2024 /* bestpath has changed; bump version */
2025 if (old_select
|| new_select
)
2027 bgp_bump_version(rn
);
2029 if (!bgp
->t_rmap_def_originate_eval
)
2032 thread_add_timer(bm
->master
,
2033 update_group_refresh_default_originate_route_map
,
2034 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2035 &bgp
->t_rmap_def_originate_eval
);
2040 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
2043 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
2044 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2045 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2049 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2050 if (old_select
!= new_select
) {
2052 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
2053 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2056 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
2057 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2063 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2065 /* unicast routes must also be annouced to labeled-unicast update-groups */
2066 if (safi
== SAFI_UNICAST
)
2067 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
, new_select
);
2070 if (bgp_fibupd_safi(safi
) &&
2071 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
2072 !bgp_option_check (BGP_OPT_NO_FIB
))
2075 && new_select
->type
== ZEBRA_ROUTE_BGP
2076 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
2077 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2078 bgp_zebra_announce (rn
, p
, new_select
, bgp
, afi
, safi
);
2081 /* Withdraw the route from the kernel. */
2083 && old_select
->type
== ZEBRA_ROUTE_BGP
2084 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
2085 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2086 bgp_zebra_withdraw (p
, old_select
, safi
);
2090 /* Clear any route change flags. */
2091 bgp_zebra_clear_route_change_flags (rn
);
2093 /* Reap old select bgp_info, if it has been removed */
2094 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2095 bgp_info_reap (rn
, old_select
);
2097 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2102 bgp_processq_del (struct work_queue
*wq
, void *data
)
2104 struct bgp_process_queue
*pq
= data
;
2105 struct bgp_table
*table
;
2107 bgp_unlock (pq
->bgp
);
2110 table
= bgp_node_table (pq
->rn
);
2111 bgp_unlock_node (pq
->rn
);
2112 bgp_table_unlock (table
);
2114 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2118 bgp_process_queue_init (void)
2120 if (!bm
->process_main_queue
)
2122 bm
->process_main_queue
2123 = work_queue_new (bm
->master
, "process_main_queue");
2125 if ( !bm
->process_main_queue
)
2127 zlog_err ("%s: Failed to allocate work queue", __func__
);
2132 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2133 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2134 bm
->process_main_queue
->spec
.max_retries
= 0;
2135 bm
->process_main_queue
->spec
.hold
= 50;
2136 /* Use a higher yield value of 50ms for main queue processing */
2137 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2141 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2143 struct bgp_process_queue
*pqnode
;
2145 /* already scheduled for processing? */
2146 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2149 if (bm
->process_main_queue
== NULL
)
2152 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2153 sizeof (struct bgp_process_queue
));
2157 /* all unlocked in bgp_processq_del */
2158 bgp_table_lock (bgp_node_table (rn
));
2159 pqnode
->rn
= bgp_lock_node (rn
);
2163 pqnode
->safi
= safi
;
2164 work_queue_add (bm
->process_main_queue
, pqnode
);
2165 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2170 bgp_add_eoiu_mark (struct bgp
*bgp
)
2172 struct bgp_process_queue
*pqnode
;
2174 if (bm
->process_main_queue
== NULL
)
2177 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2178 sizeof (struct bgp_process_queue
));
2185 work_queue_add (bm
->process_main_queue
, pqnode
);
2189 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2193 peer
= THREAD_ARG (thread
);
2194 peer
->t_pmax_restart
= NULL
;
2196 if (bgp_debug_neighbor_events(peer
))
2197 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2200 peer_clear (peer
, NULL
);
2206 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2207 safi_t safi
, int always
)
2212 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2215 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2217 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2221 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2222 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2223 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2224 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2226 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2229 /* Convert AFI, SAFI to values for packet. */
2230 pkt_afi
= afi_int2iana (afi
);
2231 pkt_safi
= safi_int2iana (safi
);
2235 ndata
[0] = (pkt_afi
>> 8);
2237 ndata
[2] = pkt_safi
;
2238 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2239 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2240 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2241 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2243 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2244 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2245 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2248 /* Dynamic peers will just close their connection. */
2249 if (peer_dynamic_neighbor (peer
))
2252 /* restart timer start */
2253 if (peer
->pmax_restart
[afi
][safi
])
2255 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2257 if (bgp_debug_neighbor_events(peer
))
2258 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2259 peer
->host
, peer
->v_pmax_restart
);
2261 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2262 peer
->v_pmax_restart
);
2268 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2270 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2272 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2276 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2277 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2278 peer
->pmax
[afi
][safi
]);
2279 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2282 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2286 /* Unconditionally remove the route from the RIB, without taking
2287 * damping into consideration (eg, because the session went down)
2290 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2291 afi_t afi
, safi_t safi
)
2293 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2295 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2296 bgp_info_delete (rn
, ri
); /* keep historical info */
2298 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2302 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2303 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2305 int status
= BGP_DAMP_NONE
;
2307 /* apply dampening, if result is suppressed, we'll be retaining
2308 * the bgp_info in the RIB for historical reference.
2310 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2311 && peer
->sort
== BGP_PEER_EBGP
)
2312 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2313 == BGP_DAMP_SUPPRESSED
)
2315 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2320 if (safi
== SAFI_MPLS_VPN
) {
2321 struct bgp_node
*prn
= NULL
;
2322 struct bgp_table
*table
= NULL
;
2324 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2326 table
= (struct bgp_table
*)(prn
->info
);
2328 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2335 bgp_unlock_node(prn
);
2337 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2338 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2340 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2341 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2345 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2348 static struct bgp_info
*
2349 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2350 struct bgp_node
*rn
)
2352 struct bgp_info
*new;
2354 /* Make new BGP info. */
2355 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2357 new->instance
= instance
;
2358 new->sub_type
= sub_type
;
2361 new->uptime
= bgp_clock ();
2363 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2368 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2370 struct attr_extra
*extra
;
2374 extra
= bgp_attr_extra_get(attr
);
2376 if(eth_s_id
== NULL
)
2378 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2382 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2386 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2390 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2395 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2397 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2398 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2401 if(afi
!= AFI_L2VPN
)
2403 if (!info
->attr
|| !info
->attr
->extra
)
2405 memset(&temp
, 0, 16);
2406 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2407 info_gw_ip
= (union gw_addr
*)&temp
;
2408 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2413 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2414 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2417 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2419 info_gw_ip_remote
= gw_ip
;
2420 if(eth_s_id
== NULL
)
2421 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2423 info_eth_s_id_remote
= eth_s_id
;
2424 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2426 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2429 /* Check if received nexthop is valid or not. */
2431 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2433 struct attr_extra
*attre
= attr
->extra
;
2436 /* Only validated for unicast and multicast currently. */
2437 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2440 /* If NEXT_HOP is present, validate it. */
2441 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2443 if (attr
->nexthop
.s_addr
== 0 ||
2444 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2445 bgp_nexthop_self (bgp
, attr
))
2449 /* If MP_NEXTHOP is present, validate it. */
2450 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2451 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2452 * it is not an IPv6 link-local address.
2454 if (attre
&& attre
->mp_nexthop_len
)
2456 switch (attre
->mp_nexthop_len
)
2458 case BGP_ATTR_NHLEN_IPV4
:
2459 case BGP_ATTR_NHLEN_VPNV4
:
2460 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2461 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2464 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2465 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2466 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2467 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2468 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2469 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2482 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2483 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2484 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2485 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2488 int aspath_loop_count
= 0;
2489 struct bgp_node
*rn
;
2491 struct attr new_attr
;
2492 struct attr_extra new_extra
;
2493 struct attr
*attr_new
;
2494 struct bgp_info
*ri
;
2495 struct bgp_info
*new;
2497 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2500 int do_loop_check
= 1;
2501 int has_valid_label
= 0;
2503 int vnc_implicit_withdraw
= 0;
2506 memset (&new_attr
, 0, sizeof(struct attr
));
2507 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2508 new_extra
.label_index
= BGP_INVALID_LABEL_INDEX
;
2509 new_extra
.label
= MPLS_INVALID_LABEL
;
2512 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2513 label_buf
[0] = '\0';
2515 has_valid_label
= bgp_is_valid_label(label
);
2517 if (has_valid_label
)
2518 sprintf (label_buf
, "label %u", label_pton(label
));
2520 /* When peer's soft reconfiguration enabled. Record input packet in
2522 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2523 && peer
!= bgp
->peer_self
)
2524 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2526 /* Check previously received route. */
2527 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2528 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2529 ri
->addpath_rx_id
== addpath_id
)
2532 /* AS path local-as loop check. */
2533 if (peer
->change_local_as
)
2535 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2536 aspath_loop_count
= 1;
2538 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2540 reason
= "as-path contains our own AS;";
2545 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2546 * as-path is our ASN then we do not need to call aspath_loop_check
2548 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2549 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2552 /* AS path loop check. */
2555 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2556 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2557 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2559 reason
= "as-path contains our own AS;";
2564 /* Route reflector originator ID check. */
2565 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2566 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2568 reason
= "originator is us;";
2572 /* Route reflector cluster ID check. */
2573 if (bgp_cluster_filter (peer
, attr
))
2575 reason
= "reflected from the same cluster;";
2579 /* Apply incoming filter. */
2580 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2586 new_attr
.extra
= &new_extra
;
2587 bgp_attr_dup (&new_attr
, attr
);
2589 /* Apply incoming route-map.
2590 * NB: new_attr may now contain newly allocated values from route-map "set"
2591 * commands, so we need bgp_attr_flush in the error paths, until we intern
2592 * the attr (which takes over the memory references) */
2593 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2595 reason
= "route-map;";
2596 bgp_attr_flush (&new_attr
);
2600 /* next hop check. */
2601 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2603 reason
= "martian or self next-hop;";
2604 bgp_attr_flush (&new_attr
);
2608 attr_new
= bgp_attr_intern (&new_attr
);
2610 /* If the update is implicit withdraw. */
2613 ri
->uptime
= bgp_clock ();
2615 /* Same attribute comes in. */
2616 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2617 && attrhash_cmp (ri
->attr
, attr_new
)
2618 && (!has_valid_label
||
2619 memcmp (&(bgp_info_extra_get (ri
))->label
, label
, BGP_LABEL_BYTES
) == 0)
2620 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2621 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2623 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2624 && peer
->sort
== BGP_PEER_EBGP
2625 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2627 if (bgp_debug_update(peer
, p
, NULL
, 1))
2628 zlog_debug ("%s rcvd %s %s", peer
->host
,
2629 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2630 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2632 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2634 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2635 bgp_process (bgp
, rn
, afi
, safi
);
2638 else /* Duplicate - odd */
2640 if (bgp_debug_update(peer
, p
, NULL
, 1))
2642 if (!peer
->rcvd_attr_printed
)
2644 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2645 peer
->rcvd_attr_printed
= 1;
2648 zlog_debug ("%s rcvd %s %s...duplicate ignored",
2650 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2651 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2654 /* graceful restart STALE flag unset. */
2655 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2657 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2658 bgp_process (bgp
, rn
, afi
, safi
);
2662 bgp_unlock_node (rn
);
2663 bgp_attr_unintern (&attr_new
);
2668 /* Withdraw/Announce before we fully processed the withdraw */
2669 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2671 if (bgp_debug_update(peer
, p
, NULL
, 1))
2672 zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
2674 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2675 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2676 bgp_info_restore (rn
, ri
);
2679 /* Received Logging. */
2680 if (bgp_debug_update(peer
, p
, NULL
, 1))
2681 zlog_debug ("%s rcvd %s %s", peer
->host
,
2682 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2683 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2685 /* graceful restart STALE flag unset. */
2686 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2687 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2689 /* The attribute is changed. */
2690 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2692 /* implicit withdraw, decrement aggregate and pcount here.
2693 * only if update is accepted, they'll increment below.
2695 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2697 /* Update bgp route dampening information. */
2698 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2699 && peer
->sort
== BGP_PEER_EBGP
)
2701 /* This is implicit withdraw so we should update dampening
2703 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2704 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2707 if (safi
== SAFI_MPLS_VPN
) {
2708 struct bgp_node
*prn
= NULL
;
2709 struct bgp_table
*table
= NULL
;
2711 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2713 table
= (struct bgp_table
*)(prn
->info
);
2715 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2722 bgp_unlock_node(prn
);
2724 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2725 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2727 * Implicit withdraw case.
2729 ++vnc_implicit_withdraw
;
2730 vnc_import_bgp_del_route(bgp
, p
, ri
);
2731 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2736 /* Update to new attribute. */
2737 bgp_attr_unintern (&ri
->attr
);
2738 ri
->attr
= attr_new
;
2740 /* Update MPLS label */
2741 if (has_valid_label
)
2743 memcpy (&(bgp_info_extra_get (ri
))->label
, label
, BGP_LABEL_BYTES
);
2744 bgp_set_valid_label(&(bgp_info_extra_get (ri
))->label
);
2748 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2750 if (vnc_implicit_withdraw
)
2753 * Add back the route with its new attributes (e.g., nexthop).
2754 * The route is still selected, until the route selection
2755 * queued by bgp_process actually runs. We have to make this
2756 * update to the VNC side immediately to avoid racing against
2757 * configuration changes (e.g., route-map changes) which
2758 * trigger re-importation of the entire RIB.
2760 vnc_import_bgp_add_route(bgp
, p
, ri
);
2761 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2765 /* Update Overlay Index */
2766 if(afi
== AFI_L2VPN
)
2768 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2769 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2772 /* Update bgp route dampening information. */
2773 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2774 && peer
->sort
== BGP_PEER_EBGP
)
2776 /* Now we do normal update dampening. */
2777 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2778 if (ret
== BGP_DAMP_SUPPRESSED
)
2780 bgp_unlock_node (rn
);
2785 /* Nexthop reachability check - for unicast and labeled-unicast.. */
2786 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2787 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2789 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2790 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2791 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2796 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2797 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2800 if (BGP_DEBUG(nht
, NHT
))
2802 char buf1
[INET6_ADDRSTRLEN
];
2803 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2804 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2806 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2810 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2813 if (safi
== SAFI_MPLS_VPN
)
2815 struct bgp_node
*prn
= NULL
;
2816 struct bgp_table
*table
= NULL
;
2818 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2821 table
= (struct bgp_table
*)(prn
->info
);
2823 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2830 bgp_unlock_node(prn
);
2834 /* Process change. */
2835 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2837 bgp_process (bgp
, rn
, afi
, safi
);
2838 bgp_unlock_node (rn
);
2841 if (SAFI_MPLS_VPN
== safi
)
2843 mpls_label_t label_decoded
= decode_label(label
);
2845 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2848 if (SAFI_ENCAP
== safi
)
2850 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2856 } // End of implicit withdraw
2858 /* Received Logging. */
2859 if (bgp_debug_update(peer
, p
, NULL
, 1))
2861 if (!peer
->rcvd_attr_printed
)
2863 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2864 peer
->rcvd_attr_printed
= 1;
2867 zlog_debug ("%s rcvd %s %s ", peer
->host
,
2868 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2869 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
);
2872 /* Make new BGP info. */
2873 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2875 /* Update MPLS label */
2876 if (has_valid_label
)
2878 memcpy (&(bgp_info_extra_get (new))->label
, label
, BGP_LABEL_BYTES
);
2879 bgp_set_valid_label(&(bgp_info_extra_get (new))->label
);
2882 /* Update Overlay Index */
2883 if(afi
== AFI_L2VPN
)
2885 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2886 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2888 /* Nexthop reachability check. */
2889 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2890 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2892 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2893 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2894 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2899 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2900 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2903 if (BGP_DEBUG(nht
, NHT
))
2905 char buf1
[INET6_ADDRSTRLEN
];
2906 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2907 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2909 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2913 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2916 new->addpath_rx_id
= addpath_id
;
2918 /* Increment prefix */
2919 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2921 /* Register new BGP information. */
2922 bgp_info_add (rn
, new);
2924 /* route_node_get lock */
2925 bgp_unlock_node (rn
);
2928 if (safi
== SAFI_MPLS_VPN
)
2930 struct bgp_node
*prn
= NULL
;
2931 struct bgp_table
*table
= NULL
;
2933 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2936 table
= (struct bgp_table
*)(prn
->info
);
2938 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2945 bgp_unlock_node(prn
);
2949 /* If maximum prefix count is configured and current prefix
2951 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2954 /* Process change. */
2955 bgp_process (bgp
, rn
, afi
, safi
);
2958 if (SAFI_MPLS_VPN
== safi
)
2960 mpls_label_t label_decoded
= decode_label(label
);
2962 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2965 if (SAFI_ENCAP
== safi
)
2967 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2974 /* This BGP update is filtered. Log the reason then update BGP
2977 if (bgp_debug_update(peer
, p
, NULL
, 1))
2979 if (!peer
->rcvd_attr_printed
)
2981 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2982 peer
->rcvd_attr_printed
= 1;
2985 zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
2987 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2988 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), label_buf
, reason
);
2992 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2994 bgp_unlock_node (rn
);
2998 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2999 * a few lines above)
3001 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
3003 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3011 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3012 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
3013 struct prefix_rd
*prd
, mpls_label_t
*label
, struct bgp_route_evpn
*evpn
)
3016 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3017 struct bgp_node
*rn
;
3018 struct bgp_info
*ri
;
3021 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
3023 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3030 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3032 /* If peer is soft reconfiguration enabled. Record input packet for
3033 * further calculation.
3035 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3036 * routes that are filtered. This tanks out Quagga RS pretty badly due to
3037 * the iteration over all RS clients.
3038 * Since we need to remove the entry from adj_in anyway, do that first and
3039 * if there was no entry, we don't need to do anything more.
3041 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3042 && peer
!= bgp
->peer_self
)
3043 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
3045 if (bgp_debug_update (peer
, p
, NULL
, 1))
3046 zlog_debug ("%s withdrawing route %s not in adj-in",
3048 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3049 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3050 bgp_unlock_node (rn
);
3054 /* Lookup withdrawn route. */
3055 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3056 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
3057 ri
->addpath_rx_id
== addpath_id
)
3061 if (bgp_debug_update(peer
, p
, NULL
, 1))
3063 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
3065 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3066 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3069 /* Withdraw specified route from routing table. */
3070 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
3071 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
3072 else if (bgp_debug_update(peer
, p
, NULL
, 1))
3073 zlog_debug ("%s Can't find the route %s",
3075 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
3076 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
3078 /* Unlock bgp_node_get() lock. */
3079 bgp_unlock_node (rn
);
3085 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
3087 struct update_subgroup
*subgrp
;
3088 subgrp
= peer_subgroup(peer
, afi
, safi
);
3089 subgroup_default_originate(subgrp
, withdraw
);
3094 * bgp_stop_announce_route_timer
3097 bgp_stop_announce_route_timer (struct peer_af
*paf
)
3099 if (!paf
->t_announce_route
)
3102 THREAD_TIMER_OFF (paf
->t_announce_route
);
3106 * bgp_announce_route_timer_expired
3108 * Callback that is invoked when the route announcement timer for a
3112 bgp_announce_route_timer_expired (struct thread
*t
)
3114 struct peer_af
*paf
;
3117 paf
= THREAD_ARG (t
);
3120 if (peer
->status
!= Established
)
3123 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3126 peer_af_announce_route (paf
, 1);
3131 * bgp_announce_route
3133 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3136 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3138 struct peer_af
*paf
;
3139 struct update_subgroup
*subgrp
;
3141 paf
= peer_af_find (peer
, afi
, safi
);
3144 subgrp
= PAF_SUBGRP(paf
);
3147 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3148 * or a refresh has already been triggered.
3150 if (!subgrp
|| paf
->t_announce_route
)
3154 * Start a timer to stagger/delay the announce. This serves
3155 * two purposes - announcement can potentially be combined for
3156 * multiple peers and the announcement doesn't happen in the
3159 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3160 (subgrp
->peer_count
== 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
: BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3161 &paf
->t_announce_route
);
3165 * Announce routes from all AF tables to a peer.
3167 * This should ONLY be called when there is a need to refresh the
3168 * routes to the peer based on a policy change for this peer alone
3169 * or a route refresh request received from the peer.
3170 * The operation will result in splitting the peer from its existing
3171 * subgroups and putting it in new subgroups.
3174 bgp_announce_route_all (struct peer
*peer
)
3179 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3180 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3181 bgp_announce_route (peer
, afi
, safi
);
3185 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3186 struct bgp_table
*table
, struct prefix_rd
*prd
)
3189 struct bgp_node
*rn
;
3190 struct bgp_adj_in
*ain
;
3193 table
= peer
->bgp
->rib
[afi
][safi
];
3195 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3196 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3198 if (ain
->peer
== peer
)
3200 struct bgp_info
*ri
= rn
->info
;
3201 mpls_label_t label
= (ri
&& ri
->extra
) ? ri
->extra
->label
: MPLS_INVALID_LABEL
;
3203 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3204 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3205 prd
, &label
, 1, NULL
);
3209 bgp_unlock_node (rn
);
3217 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3219 struct bgp_node
*rn
;
3220 struct bgp_table
*table
;
3222 if (peer
->status
!= Established
)
3225 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3226 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3228 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3229 rn
= bgp_route_next (rn
))
3230 if ((table
= rn
->info
) != NULL
)
3232 struct prefix_rd prd
;
3233 prd
.family
= AF_UNSPEC
;
3235 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3237 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3242 struct bgp_clear_node_queue
3244 struct bgp_node
*rn
;
3247 static wq_item_status
3248 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3250 struct bgp_clear_node_queue
*cnq
= data
;
3251 struct bgp_node
*rn
= cnq
->rn
;
3252 struct peer
*peer
= wq
->spec
.data
;
3253 struct bgp_info
*ri
;
3254 afi_t afi
= bgp_node_table (rn
)->afi
;
3255 safi_t safi
= bgp_node_table (rn
)->safi
;
3257 assert (rn
&& peer
);
3259 /* It is possible that we have multiple paths for a prefix from a peer
3260 * if that peer is using AddPath.
3262 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3263 if (ri
->peer
== peer
)
3265 /* graceful restart STALE flag set. */
3266 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3267 && peer
->nsf
[afi
][safi
]
3268 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3269 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3270 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3272 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3278 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3280 struct bgp_clear_node_queue
*cnq
= data
;
3281 struct bgp_node
*rn
= cnq
->rn
;
3282 struct bgp_table
*table
= bgp_node_table (rn
);
3284 bgp_unlock_node (rn
);
3285 bgp_table_unlock (table
);
3286 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3290 bgp_clear_node_complete (struct work_queue
*wq
)
3292 struct peer
*peer
= wq
->spec
.data
;
3294 /* Tickle FSM to start moving again */
3295 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3297 peer_unlock (peer
); /* bgp_clear_route */
3301 bgp_clear_node_queue_init (struct peer
*peer
)
3303 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3305 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3306 #undef CLEAR_QUEUE_NAME_LEN
3308 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3310 zlog_err ("%s: Failed to allocate work queue", __func__
);
3313 peer
->clear_node_queue
->spec
.hold
= 10;
3314 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3315 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3316 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3317 peer
->clear_node_queue
->spec
.max_retries
= 0;
3319 /* we only 'lock' this peer reference when the queue is actually active */
3320 peer
->clear_node_queue
->spec
.data
= peer
;
3324 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3325 struct bgp_table
*table
)
3327 struct bgp_node
*rn
;
3328 int force
= bm
->process_main_queue
? 0 : 1;
3331 table
= peer
->bgp
->rib
[afi
][safi
];
3333 /* If still no table => afi/safi isn't configured at all or smth. */
3337 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3339 struct bgp_info
*ri
, *next
;
3340 struct bgp_adj_in
*ain
;
3341 struct bgp_adj_in
*ain_next
;
3343 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3344 * queued for every clearing peer, regardless of whether it is
3345 * relevant to the peer at hand.
3347 * Overview: There are 3 different indices which need to be
3348 * scrubbed, potentially, when a peer is removed:
3350 * 1 peer's routes visible via the RIB (ie accepted routes)
3351 * 2 peer's routes visible by the (optional) peer's adj-in index
3352 * 3 other routes visible by the peer's adj-out index
3354 * 3 there is no hurry in scrubbing, once the struct peer is
3355 * removed from bgp->peer, we could just GC such deleted peer's
3356 * adj-outs at our leisure.
3358 * 1 and 2 must be 'scrubbed' in some way, at least made
3359 * invisible via RIB index before peer session is allowed to be
3360 * brought back up. So one needs to know when such a 'search' is
3365 * - there'd be a single global queue or a single RIB walker
3366 * - rather than tracking which route_nodes still need to be
3367 * examined on a peer basis, we'd track which peers still
3370 * Given that our per-peer prefix-counts now should be reliable,
3371 * this may actually be achievable. It doesn't seem to be a huge
3372 * problem at this time,
3374 * It is possible that we have multiple paths for a prefix from a peer
3375 * if that peer is using AddPath.
3380 ain_next
= ain
->next
;
3382 if (ain
->peer
== peer
)
3384 bgp_adj_in_remove (rn
, ain
);
3385 bgp_unlock_node (rn
);
3391 for (ri
= rn
->info
; ri
; ri
= next
)
3394 if (ri
->peer
!= peer
)
3398 bgp_info_reap (rn
, ri
);
3401 struct bgp_clear_node_queue
*cnq
;
3403 /* both unlocked in bgp_clear_node_queue_del */
3404 bgp_table_lock (bgp_node_table (rn
));
3406 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3407 sizeof (struct bgp_clear_node_queue
));
3409 work_queue_add (peer
->clear_node_queue
, cnq
);
3418 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3420 struct bgp_node
*rn
;
3421 struct bgp_table
*table
;
3423 if (peer
->clear_node_queue
== NULL
)
3424 bgp_clear_node_queue_init (peer
);
3426 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3427 * Idle until it receives a Clearing_Completed event. This protects
3428 * against peers which flap faster than we can we clear, which could
3431 * a) race with routes from the new session being installed before
3432 * clear_route_node visits the node (to delete the route of that
3434 * b) resource exhaustion, clear_route_node likely leads to an entry
3435 * on the process_main queue. Fast-flapping could cause that queue
3439 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3440 * the unlock will happen upon work-queue completion; other wise, the
3441 * unlock happens at the end of this function.
3443 if (!peer
->clear_node_queue
->thread
)
3446 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3447 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3449 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3450 rn
= bgp_route_next (rn
))
3451 if ((table
= rn
->info
) != NULL
)
3452 bgp_clear_route_table (peer
, afi
, safi
, table
);
3454 /* unlock if no nodes got added to the clear-node-queue. */
3455 if (!peer
->clear_node_queue
->thread
)
3461 bgp_clear_route_all (struct peer
*peer
)
3466 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3467 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3468 bgp_clear_route (peer
, afi
, safi
);
3471 rfapiProcessPeerDown(peer
);
3476 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3478 struct bgp_table
*table
;
3479 struct bgp_node
*rn
;
3480 struct bgp_adj_in
*ain
;
3481 struct bgp_adj_in
*ain_next
;
3483 table
= peer
->bgp
->rib
[afi
][safi
];
3485 /* It is possible that we have multiple paths for a prefix from a peer
3486 * if that peer is using AddPath.
3488 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3494 ain_next
= ain
->next
;
3496 if (ain
->peer
== peer
)
3498 bgp_adj_in_remove (rn
, ain
);
3499 bgp_unlock_node (rn
);
3508 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3510 struct bgp_node
*rn
;
3511 struct bgp_info
*ri
;
3512 struct bgp_table
*table
;
3514 if ( safi
== SAFI_MPLS_VPN
)
3516 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3518 struct bgp_node
*rm
;
3519 struct bgp_info
*ri
;
3521 /* look for neighbor in tables */
3522 if ((table
= rn
->info
) != NULL
)
3524 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3525 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3526 if (ri
->peer
== peer
)
3528 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3529 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3537 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3538 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3539 if (ri
->peer
== peer
)
3541 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3542 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3549 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3551 struct bgp_node
*rn
;
3552 struct bgp_info
*ri
;
3553 struct bgp_info
*next
;
3555 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3556 for (ri
= rn
->info
; ri
; ri
= next
)
3559 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3560 && ri
->type
== ZEBRA_ROUTE_BGP
3561 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3562 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3564 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3565 bgp_info_reap (rn
, ri
);
3570 /* Delete all kernel routes. */
3572 bgp_cleanup_routes (struct bgp
*bgp
)
3575 struct bgp_node
*rn
;
3577 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3579 if (afi
== AFI_L2VPN
)
3581 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3583 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3585 if (afi
!= AFI_L2VPN
)
3588 safi
= SAFI_MPLS_VPN
;
3589 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3590 rn
= bgp_route_next (rn
))
3594 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3595 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3597 bgp_unlock_node(rn
);
3601 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3602 rn
= bgp_route_next (rn
))
3606 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3607 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3609 bgp_unlock_node(rn
);
3614 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3615 rn
= bgp_route_next (rn
))
3619 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3620 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3622 bgp_unlock_node(rn
);
3631 bgp_zclient_reset ();
3632 access_list_reset ();
3633 prefix_list_reset ();
3637 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3639 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3640 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3643 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3646 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3647 struct bgp_nlri
*packet
)
3656 int addpath_encoded
;
3657 u_int32_t addpath_id
;
3659 /* Check peer status. */
3660 if (peer
->status
!= Established
)
3664 lim
= pnt
+ packet
->length
;
3666 safi
= packet
->safi
;
3668 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3670 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3671 syntactic validity. If the field is syntactically incorrect,
3672 then the Error Subcode is set to Invalid Network Field. */
3673 for (; pnt
< lim
; pnt
+= psize
)
3675 /* Clear prefix structure. */
3676 memset (&p
, 0, sizeof (struct prefix
));
3678 if (addpath_encoded
)
3681 /* When packet overflow occurs return immediately. */
3682 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3685 addpath_id
= ntohl(*((uint32_t*) pnt
));
3686 pnt
+= BGP_ADDPATH_ID_LEN
;
3689 /* Fetch prefix length. */
3690 p
.prefixlen
= *pnt
++;
3691 /* afi/safi validity already verified by caller, bgp_update_receive */
3692 p
.family
= afi2family (afi
);
3694 /* Prefix length check. */
3695 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3697 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3698 peer
->host
, p
.prefixlen
, packet
->afi
);
3702 /* Packet size overflow check. */
3703 psize
= PSIZE (p
.prefixlen
);
3705 /* When packet overflow occur return immediately. */
3706 if (pnt
+ psize
> lim
)
3708 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3709 peer
->host
, p
.prefixlen
);
3713 /* Defensive coding, double-check the psize fits in a struct prefix */
3714 if (psize
> (ssize_t
) sizeof(p
.u
))
3716 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3717 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3721 /* Fetch prefix from NLRI packet. */
3722 memcpy (&p
.u
.prefix
, pnt
, psize
);
3724 /* Check address. */
3725 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3727 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3729 /* From RFC4271 Section 6.3:
3731 * If a prefix in the NLRI field is semantically incorrect
3732 * (e.g., an unexpected multicast IP address), an error SHOULD
3733 * be logged locally, and the prefix SHOULD be ignored.
3735 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3736 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3741 /* Check address. */
3742 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3744 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3748 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3749 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3753 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3757 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3758 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3764 /* Normal process. */
3766 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3767 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3769 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3770 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3772 /* Address family configuration mismatch or maximum-prefix count
3778 /* Packet length consistency check. */
3781 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3789 static struct bgp_static
*
3790 bgp_static_new (void)
3792 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3796 bgp_static_free (struct bgp_static
*bgp_static
)
3798 if (bgp_static
->rmap
.name
)
3799 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3800 if(bgp_static
->eth_s_id
)
3801 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3802 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3806 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3807 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3809 struct bgp_node
*rn
;
3810 struct bgp_info
*ri
;
3811 struct bgp_info
*new;
3812 struct bgp_info info
;
3814 struct attr
*attr_new
;
3817 int vnc_implicit_withdraw
= 0;
3820 assert (bgp_static
);
3824 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3826 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3828 attr
.nexthop
= bgp_static
->igpnexthop
;
3829 attr
.med
= bgp_static
->igpmetric
;
3830 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3832 if (bgp_static
->atomic
)
3833 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3835 /* Store label index, if required. */
3836 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3838 (bgp_attr_extra_get (&attr
))->label_index
= bgp_static
->label_index
;
3839 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3842 /* Apply route-map. */
3843 if (bgp_static
->rmap
.name
)
3845 struct attr attr_tmp
= attr
;
3846 info
.peer
= bgp
->peer_self
;
3847 info
.attr
= &attr_tmp
;
3849 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3851 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3853 bgp
->peer_self
->rmap_type
= 0;
3855 if (ret
== RMAP_DENYMATCH
)
3857 /* Free uninterned attribute. */
3858 bgp_attr_flush (&attr_tmp
);
3860 /* Unintern original. */
3861 aspath_unintern (&attr
.aspath
);
3862 bgp_attr_extra_free (&attr
);
3863 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3866 attr_new
= bgp_attr_intern (&attr_tmp
);
3869 attr_new
= bgp_attr_intern (&attr
);
3871 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3872 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3873 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3878 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3879 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3880 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3882 bgp_unlock_node (rn
);
3883 bgp_attr_unintern (&attr_new
);
3884 aspath_unintern (&attr
.aspath
);
3885 bgp_attr_extra_free (&attr
);
3890 /* The attribute is changed. */
3891 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3893 /* Rewrite BGP route information. */
3894 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3895 bgp_info_restore(rn
, ri
);
3897 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3899 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3901 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3904 * Implicit withdraw case.
3905 * We have to do this before ri is changed
3907 ++vnc_implicit_withdraw
;
3908 vnc_import_bgp_del_route(bgp
, p
, ri
);
3909 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3913 bgp_attr_unintern (&ri
->attr
);
3914 ri
->attr
= attr_new
;
3915 ri
->uptime
= bgp_clock ();
3917 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3919 if (vnc_implicit_withdraw
)
3921 vnc_import_bgp_add_route(bgp
, p
, ri
);
3922 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3927 /* Nexthop reachability check. */
3928 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3929 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3931 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3932 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3935 if (BGP_DEBUG(nht
, NHT
))
3937 char buf1
[INET6_ADDRSTRLEN
];
3938 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3940 zlog_debug("%s(%s): Route not in table, not advertising",
3941 __FUNCTION__
, buf1
);
3943 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3948 /* Delete the NHT structure if any, if we're toggling between
3949 * enabling/disabling import check. We deregister the route
3950 * from NHT to avoid overloading NHT and the process interaction
3952 bgp_unlink_nexthop(ri
);
3953 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3955 /* Process change. */
3956 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3957 bgp_process (bgp
, rn
, afi
, safi
);
3958 bgp_unlock_node (rn
);
3959 aspath_unintern (&attr
.aspath
);
3960 bgp_attr_extra_free (&attr
);
3965 /* Make new BGP info. */
3966 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3968 /* Nexthop reachability check. */
3969 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
3970 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3972 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3973 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3976 if (BGP_DEBUG(nht
, NHT
))
3978 char buf1
[INET6_ADDRSTRLEN
];
3979 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3981 zlog_debug("%s(%s): Route not in table, not advertising",
3982 __FUNCTION__
, buf1
);
3984 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3989 /* Delete the NHT structure if any, if we're toggling between
3990 * enabling/disabling import check. We deregister the route
3991 * from NHT to avoid overloading NHT and the process interaction
3993 bgp_unlink_nexthop(new);
3995 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3998 /* Aggregate address increment. */
3999 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4001 /* Register new BGP information. */
4002 bgp_info_add (rn
, new);
4004 /* route_node_get lock */
4005 bgp_unlock_node (rn
);
4007 /* Process change. */
4008 bgp_process (bgp
, rn
, afi
, safi
);
4010 /* Unintern original. */
4011 aspath_unintern (&attr
.aspath
);
4012 bgp_attr_extra_free (&attr
);
4016 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4019 struct bgp_node
*rn
;
4020 struct bgp_info
*ri
;
4022 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4024 /* Check selected route and self inserted route. */
4025 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4026 if (ri
->peer
== bgp
->peer_self
4027 && ri
->type
== ZEBRA_ROUTE_BGP
4028 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4031 /* Withdraw static BGP route from routing table. */
4034 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4035 bgp_unlink_nexthop(ri
);
4036 bgp_info_delete (rn
, ri
);
4037 bgp_process (bgp
, rn
, afi
, safi
);
4040 /* Unlock bgp_node_lookup. */
4041 bgp_unlock_node (rn
);
4045 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4048 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4049 safi_t safi
, struct prefix_rd
*prd
)
4051 struct bgp_node
*rn
;
4052 struct bgp_info
*ri
;
4054 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4056 /* Check selected route and self inserted route. */
4057 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4058 if (ri
->peer
== bgp
->peer_self
4059 && ri
->type
== ZEBRA_ROUTE_BGP
4060 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4063 /* Withdraw static BGP route from routing table. */
4067 rfapiProcessWithdraw(
4076 1); /* Kill, since it is an administrative change */
4078 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4079 bgp_info_delete (rn
, ri
);
4080 bgp_process (bgp
, rn
, afi
, safi
);
4083 /* Unlock bgp_node_lookup. */
4084 bgp_unlock_node (rn
);
4088 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4089 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4091 struct bgp_node
*rn
;
4092 struct bgp_info
*new;
4093 struct attr
*attr_new
;
4094 struct attr attr
= { 0 };
4095 struct bgp_info
*ri
;
4097 mpls_label_t label
= 0;
4101 assert (bgp_static
);
4103 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4105 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4107 attr
.nexthop
= bgp_static
->igpnexthop
;
4108 attr
.med
= bgp_static
->igpmetric
;
4109 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4111 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4115 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4116 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4119 if(afi
== AFI_L2VPN
)
4121 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4122 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4123 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4124 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4125 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4126 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4128 struct bgp_encap_type_vxlan bet
;
4129 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4130 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4131 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4133 if (bgp_static
->router_mac
)
4135 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4138 /* Apply route-map. */
4139 if (bgp_static
->rmap
.name
)
4141 struct attr attr_tmp
= attr
;
4142 struct bgp_info info
;
4145 info
.peer
= bgp
->peer_self
;
4146 info
.attr
= &attr_tmp
;
4148 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4150 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4152 bgp
->peer_self
->rmap_type
= 0;
4154 if (ret
== RMAP_DENYMATCH
)
4156 /* Free uninterned attribute. */
4157 bgp_attr_flush (&attr_tmp
);
4159 /* Unintern original. */
4160 aspath_unintern (&attr
.aspath
);
4161 bgp_attr_extra_free (&attr
);
4162 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
);
4166 attr_new
= bgp_attr_intern (&attr_tmp
);
4170 attr_new
= bgp_attr_intern (&attr
);
4173 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4174 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4175 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4181 memset(&add
, 0, sizeof(union gw_addr
));
4182 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4183 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4184 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4186 bgp_unlock_node (rn
);
4187 bgp_attr_unintern (&attr_new
);
4188 aspath_unintern (&attr
.aspath
);
4189 bgp_attr_extra_free (&attr
);
4194 /* The attribute is changed. */
4195 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4197 /* Rewrite BGP route information. */
4198 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4199 bgp_info_restore(rn
, ri
);
4201 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4202 bgp_attr_unintern (&ri
->attr
);
4203 ri
->attr
= attr_new
;
4204 ri
->uptime
= bgp_clock ();
4207 label
= decode_label (&ri
->extra
->label
);
4210 /* Process change. */
4211 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4212 bgp_process (bgp
, rn
, afi
, safi
);
4214 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4215 ri
->attr
, afi
, safi
,
4216 ri
->type
, ri
->sub_type
, &label
);
4218 bgp_unlock_node (rn
);
4219 aspath_unintern (&attr
.aspath
);
4220 bgp_attr_extra_free (&attr
);
4226 /* Make new BGP info. */
4227 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4229 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4230 new->extra
= bgp_info_extra_new();
4231 new->extra
->label
= bgp_static
->label
;
4233 label
= decode_label (&bgp_static
->label
);
4236 /* Aggregate address increment. */
4237 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4239 /* Register new BGP information. */
4240 bgp_info_add (rn
, new);
4241 /* route_node_get lock */
4242 bgp_unlock_node (rn
);
4244 /* Process change. */
4245 bgp_process (bgp
, rn
, afi
, safi
);
4248 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4249 new->attr
, afi
, safi
,
4250 new->type
, new->sub_type
, &label
);
4253 /* Unintern original. */
4254 aspath_unintern (&attr
.aspath
);
4255 bgp_attr_extra_free (&attr
);
4258 /* Configure static BGP network. When user don't run zebra, static
4259 route should be installed as valid. */
4261 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4262 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4263 u_int32_t label_index
)
4265 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4268 struct bgp_static
*bgp_static
;
4269 struct bgp_node
*rn
;
4270 u_char need_update
= 0;
4272 /* Convert IP prefix string to struct prefix. */
4273 ret
= str2prefix (ip_str
, &p
);
4276 vty_outln (vty
, "%% Malformed prefix");
4279 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4281 vty_outln (vty
,"%% Malformed prefix (link-local address)");
4287 /* Set BGP static route configuration. */
4288 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4292 /* Configuration change. */
4293 bgp_static
= rn
->info
;
4295 /* Label index cannot be changed. */
4296 if (bgp_static
->label_index
!= label_index
)
4298 vty_outln (vty
, "%% Label index cannot be changed");
4302 /* Check previous routes are installed into BGP. */
4303 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4306 bgp_static
->backdoor
= backdoor
;
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
);
4317 if (bgp_static
->rmap
.name
)
4318 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4319 bgp_static
->rmap
.name
= NULL
;
4320 bgp_static
->rmap
.map
= NULL
;
4321 bgp_static
->valid
= 0;
4323 bgp_unlock_node (rn
);
4327 /* New configuration. */
4328 bgp_static
= bgp_static_new ();
4329 bgp_static
->backdoor
= backdoor
;
4330 bgp_static
->valid
= 0;
4331 bgp_static
->igpmetric
= 0;
4332 bgp_static
->igpnexthop
.s_addr
= 0;
4333 bgp_static
->label_index
= label_index
;
4337 if (bgp_static
->rmap
.name
)
4338 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4339 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4340 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4342 rn
->info
= bgp_static
;
4345 bgp_static
->valid
= 1;
4347 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4349 if (! bgp_static
->backdoor
)
4350 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4355 /* Configure static BGP network. */
4357 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4358 afi_t afi
, safi_t safi
)
4360 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4363 struct bgp_static
*bgp_static
;
4364 struct bgp_node
*rn
;
4366 /* Convert IP prefix string to struct prefix. */
4367 ret
= str2prefix (ip_str
, &p
);
4370 vty_outln (vty
, "%% Malformed prefix");
4373 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4375 vty_outln (vty
,"%% Malformed prefix (link-local address)");
4381 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4384 vty_outln (vty
,"%% Can't find specified static route configuration.");
4388 bgp_static
= rn
->info
;
4390 /* Update BGP RIB. */
4391 if (! bgp_static
->backdoor
)
4392 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4394 /* Clear configuration. */
4395 bgp_static_free (bgp_static
);
4397 bgp_unlock_node (rn
);
4398 bgp_unlock_node (rn
);
4404 bgp_static_add (struct bgp
*bgp
)
4408 struct bgp_node
*rn
;
4409 struct bgp_node
*rm
;
4410 struct bgp_table
*table
;
4411 struct bgp_static
*bgp_static
;
4413 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4414 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4415 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4416 if (rn
->info
!= NULL
)
4418 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4422 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4424 bgp_static
= rm
->info
;
4425 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4430 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4435 /* Called from bgp_delete(). Delete all static routes from the BGP
4438 bgp_static_delete (struct bgp
*bgp
)
4442 struct bgp_node
*rn
;
4443 struct bgp_node
*rm
;
4444 struct bgp_table
*table
;
4445 struct bgp_static
*bgp_static
;
4447 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4448 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4449 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4450 if (rn
->info
!= NULL
)
4452 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4456 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4458 bgp_static
= rm
->info
;
4459 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4461 (struct prefix_rd
*)&rn
->p
);
4462 bgp_static_free (bgp_static
);
4464 bgp_unlock_node (rn
);
4469 bgp_static
= rn
->info
;
4470 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4471 bgp_static_free (bgp_static
);
4473 bgp_unlock_node (rn
);
4479 bgp_static_redo_import_check (struct bgp
*bgp
)
4483 struct bgp_node
*rn
;
4484 struct bgp_node
*rm
;
4485 struct bgp_table
*table
;
4486 struct bgp_static
*bgp_static
;
4488 /* Use this flag to force reprocessing of the route */
4489 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4490 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4491 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4492 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4493 if (rn
->info
!= NULL
)
4495 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4499 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4501 bgp_static
= rm
->info
;
4502 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4507 bgp_static
= rn
->info
;
4508 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4511 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4515 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4517 struct bgp_table
*table
;
4518 struct bgp_node
*rn
;
4519 struct bgp_info
*ri
;
4521 table
= bgp
->rib
[afi
][safi
];
4522 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4524 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4526 if (ri
->peer
== bgp
->peer_self
&&
4527 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4528 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4529 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4530 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4532 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4533 bgp_unlink_nexthop(ri
);
4534 bgp_info_delete (rn
, ri
);
4535 bgp_process (bgp
, rn
, afi
, safi
);
4542 * Purge all networks and redistributed routes from routing table.
4543 * Invoked upon the instance going down.
4546 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4551 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4552 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4553 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4558 * Currently this is used to set static routes for VPN and ENCAP.
4559 * I think it can probably be factored with bgp_static_set.
4562 bgp_static_set_safi (afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4563 const char *rd_str
, const char *label_str
,
4564 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4565 const char *ethtag
, const char *routermac
)
4567 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4570 struct prefix_rd prd
;
4571 struct bgp_node
*prn
;
4572 struct bgp_node
*rn
;
4573 struct bgp_table
*table
;
4574 struct bgp_static
*bgp_static
;
4575 mpls_label_t label
= MPLS_INVALID_LABEL
;
4576 struct prefix gw_ip
;
4578 /* validate ip prefix */
4579 ret
= str2prefix (ip_str
, &p
);
4582 vty_outln (vty
, "%% Malformed prefix");
4586 if ( (afi
== AFI_L2VPN
) &&
4587 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4589 vty_outln (vty
, "%% L2VPN prefix could not be forged");
4593 ret
= str2prefix_rd (rd_str
, &prd
);
4596 vty_outln (vty
, "%% Malformed rd");
4602 unsigned long label_val
;
4603 label_val
= strtoul(label_str
, NULL
, 10);
4604 encode_label (label_val
, &label
);
4607 if (safi
== SAFI_EVPN
)
4609 if( esi
&& str2esi (esi
, NULL
) == 0)
4611 vty_outln (vty
, "%% Malformed ESI");
4614 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4616 vty_outln (vty
, "%% Malformed Router MAC");
4621 memset (&gw_ip
, 0, sizeof (struct prefix
));
4622 ret
= str2prefix (gwip
, &gw_ip
);
4625 vty_outln (vty
, "%% Malformed GatewayIp");
4628 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4629 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4631 vty_outln (vty
, "%% GatewayIp family differs with IP prefix");
4636 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4637 (struct prefix
*)&prd
);
4638 if (prn
->info
== NULL
)
4639 prn
->info
= bgp_table_init (afi
, safi
);
4641 bgp_unlock_node (prn
);
4644 rn
= bgp_node_get (table
, &p
);
4648 vty_outln (vty
, "%% Same network configuration exists");
4649 bgp_unlock_node (rn
);
4653 /* New configuration. */
4654 bgp_static
= bgp_static_new ();
4655 bgp_static
->backdoor
= 0;
4656 bgp_static
->valid
= 0;
4657 bgp_static
->igpmetric
= 0;
4658 bgp_static
->igpnexthop
.s_addr
= 0;
4659 bgp_static
->label
= label
;
4660 bgp_static
->prd
= prd
;
4664 if (bgp_static
->rmap
.name
)
4665 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4666 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4667 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4670 if (safi
== SAFI_EVPN
)
4674 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4675 str2esi (esi
, bgp_static
->eth_s_id
);
4679 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4680 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4683 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4685 rn
->info
= bgp_static
;
4687 bgp_static
->valid
= 1;
4688 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4694 /* Configure static BGP network. */
4696 bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4697 const char *rd_str
, const char *label_str
,
4698 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4700 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4703 struct prefix_rd prd
;
4704 struct bgp_node
*prn
;
4705 struct bgp_node
*rn
;
4706 struct bgp_table
*table
;
4707 struct bgp_static
*bgp_static
;
4708 mpls_label_t label
= MPLS_INVALID_LABEL
;
4710 /* Convert IP prefix string to struct prefix. */
4711 ret
= str2prefix (ip_str
, &p
);
4714 vty_outln (vty
, "%% Malformed prefix");
4718 if ( (afi
== AFI_L2VPN
) &&
4719 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4721 vty_outln (vty
, "%% L2VPN prefix could not be forged");
4724 ret
= str2prefix_rd (rd_str
, &prd
);
4727 vty_outln (vty
, "%% Malformed rd");
4733 unsigned long label_val
;
4734 label_val
= strtoul(label_str
, NULL
, 10);
4735 encode_label (label_val
, &label
);
4738 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4739 (struct prefix
*)&prd
);
4740 if (prn
->info
== NULL
)
4741 prn
->info
= bgp_table_init (afi
, safi
);
4743 bgp_unlock_node (prn
);
4746 rn
= bgp_node_lookup (table
, &p
);
4750 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
);
4752 bgp_static
= rn
->info
;
4753 bgp_static_free (bgp_static
);
4755 bgp_unlock_node (rn
);
4756 bgp_unlock_node (rn
);
4759 vty_outln (vty
, "%% Can't find the route");
4765 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4766 const char *rmap_name
)
4768 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4769 struct bgp_rmap
*rmap
;
4771 rmap
= &bgp
->table_map
[afi
][safi
];
4775 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4776 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4777 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4782 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4787 bgp_zebra_announce_table(bgp
, afi
, safi
);
4793 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4794 const char *rmap_name
)
4796 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4797 struct bgp_rmap
*rmap
;
4799 rmap
= &bgp
->table_map
[afi
][safi
];
4801 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4805 bgp_zebra_announce_table(bgp
, afi
, safi
);
4811 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4812 safi_t safi
, int *write
)
4814 if (bgp
->table_map
[afi
][safi
].name
)
4816 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4817 vty_outln (vty
, " table-map %s",
4818 bgp
->table_map
[afi
][safi
].name
);
4824 DEFUN (bgp_table_map
,
4827 "BGP table to RIB route download filter\n"
4828 "Name of the route map\n")
4831 return bgp_table_map_set (vty
,
4832 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4834 DEFUN (no_bgp_table_map
,
4835 no_bgp_table_map_cmd
,
4836 "no table-map WORD",
4838 "BGP table to RIB route download filter\n"
4839 "Name of the route map\n")
4842 return bgp_table_map_unset (vty
,
4843 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4848 "network A.B.C.D/M",
4849 "Specify a network to announce via BGP\n"
4852 int idx_ipv4_prefixlen
= 1;
4853 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4854 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4855 BGP_INVALID_LABEL_INDEX
);
4858 DEFUN (bgp_network_route_map
,
4859 bgp_network_route_map_cmd
,
4860 "network A.B.C.D/M route-map WORD",
4861 "Specify a network to announce via BGP\n"
4863 "Route-map to modify the attributes\n"
4864 "Name of the route map\n")
4866 int idx_ipv4_prefixlen
= 1;
4868 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4869 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
4870 BGP_INVALID_LABEL_INDEX
);
4873 DEFUN (bgp_network_backdoor
,
4874 bgp_network_backdoor_cmd
,
4875 "network A.B.C.D/M backdoor",
4876 "Specify a network to announce via BGP\n"
4878 "Specify a BGP backdoor route\n")
4880 int idx_ipv4_prefixlen
= 1;
4881 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4882 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
4885 DEFUN (bgp_network_mask
,
4886 bgp_network_mask_cmd
,
4887 "network A.B.C.D mask A.B.C.D",
4888 "Specify a network to announce via BGP\n"
4896 char prefix_str
[BUFSIZ
];
4898 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4901 vty_outln (vty
, "%% Inconsistent address and mask");
4905 return bgp_static_set (vty
, prefix_str
,
4906 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
4909 DEFUN (bgp_network_mask_route_map
,
4910 bgp_network_mask_route_map_cmd
,
4911 "network A.B.C.D mask A.B.C.D route-map WORD",
4912 "Specify a network to announce via BGP\n"
4916 "Route-map to modify the attributes\n"
4917 "Name of the route map\n")
4923 char prefix_str
[BUFSIZ
];
4925 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4928 vty_outln (vty
, "%% Inconsistent address and mask");
4932 return bgp_static_set (vty
, prefix_str
,
4933 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
4936 DEFUN (bgp_network_mask_backdoor
,
4937 bgp_network_mask_backdoor_cmd
,
4938 "network A.B.C.D mask A.B.C.D backdoor",
4939 "Specify a network to announce via BGP\n"
4943 "Specify a BGP backdoor route\n")
4948 char prefix_str
[BUFSIZ
];
4950 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4953 vty_outln (vty
, "%% Inconsistent address and mask");
4957 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4959 BGP_INVALID_LABEL_INDEX
);
4962 DEFUN (bgp_network_mask_natural
,
4963 bgp_network_mask_natural_cmd
,
4965 "Specify a network to announce via BGP\n"
4970 char prefix_str
[BUFSIZ
];
4972 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4975 vty_outln (vty
, "%% Inconsistent address and mask");
4979 return bgp_static_set (vty
, prefix_str
,
4980 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4981 BGP_INVALID_LABEL_INDEX
);
4984 DEFUN (bgp_network_mask_natural_route_map
,
4985 bgp_network_mask_natural_route_map_cmd
,
4986 "network A.B.C.D route-map WORD",
4987 "Specify a network to announce via BGP\n"
4989 "Route-map to modify the attributes\n"
4990 "Name of the route map\n")
4995 char prefix_str
[BUFSIZ
];
4997 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5000 vty_outln (vty
, "%% Inconsistent address and mask");
5004 return bgp_static_set (vty
, prefix_str
,
5005 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5006 BGP_INVALID_LABEL_INDEX
);
5009 DEFUN (bgp_network_mask_natural_backdoor
,
5010 bgp_network_mask_natural_backdoor_cmd
,
5011 "network A.B.C.D backdoor",
5012 "Specify a network to announce via BGP\n"
5014 "Specify a BGP backdoor route\n")
5018 char prefix_str
[BUFSIZ
];
5020 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5023 vty_outln (vty
, "%% Inconsistent address and mask");
5027 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5028 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5031 DEFUN (bgp_network_label_index
,
5032 bgp_network_label_index_cmd
,
5033 "network A.B.C.D/M label-index (0-1048560)",
5034 "Specify a network to announce via BGP\n"
5035 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5036 "Label index to associate with the prefix\n"
5037 "Label index value\n")
5039 u_int32_t label_index
;
5041 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5042 return bgp_static_set (vty
, argv
[1]->arg
,
5043 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5046 DEFUN (bgp_network_label_index_route_map
,
5047 bgp_network_label_index_route_map_cmd
,
5048 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5049 "Specify a network to announce via BGP\n"
5051 "Label index to associate with the prefix\n"
5052 "Label index value\n"
5053 "Route-map to modify the attributes\n"
5054 "Name of the route map\n")
5056 u_int32_t label_index
;
5058 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5059 return bgp_static_set (vty
, argv
[1]->arg
,
5060 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5063 DEFUN (no_bgp_network
,
5065 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5067 "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")
5073 int idx_ipv4_prefixlen
= 2;
5074 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5075 bgp_node_safi (vty
));
5078 DEFUN (no_bgp_network_mask
,
5079 no_bgp_network_mask_cmd
,
5080 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5082 "Specify a network to announce via BGP\n"
5086 "Specify a BGP backdoor route\n"
5087 "Route-map to modify the attributes\n"
5088 "Name of the route map\n")
5093 char prefix_str
[BUFSIZ
];
5095 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5098 vty_outln (vty
, "%% Inconsistent address and mask");
5102 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5103 bgp_node_safi (vty
));
5106 DEFUN (no_bgp_network_mask_natural
,
5107 no_bgp_network_mask_natural_cmd
,
5108 "no network A.B.C.D [<backdoor|route-map WORD>]",
5110 "Specify a network to announce via BGP\n"
5112 "Specify a BGP backdoor route\n"
5113 "Route-map to modify the attributes\n"
5114 "Name of the route map\n")
5118 char prefix_str
[BUFSIZ
];
5120 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5123 vty_outln (vty
, "%% Inconsistent address and mask");
5127 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5128 bgp_node_safi (vty
));
5131 ALIAS (no_bgp_network
,
5132 no_bgp_network_label_index_cmd
,
5133 "no network A.B.C.D/M label-index (0-1048560)",
5135 "Specify a network to announce via BGP\n"
5136 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5137 "Label index to associate with the prefix\n"
5138 "Label index value\n")
5140 ALIAS (no_bgp_network
,
5141 no_bgp_network_label_index_route_map_cmd
,
5142 "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
5144 "Specify a network to announce via BGP\n"
5146 "Label index to associate with the prefix\n"
5147 "Label index value\n"
5148 "Route-map to modify the attributes\n"
5149 "Name of the route map\n")
5151 DEFUN (ipv6_bgp_network
,
5152 ipv6_bgp_network_cmd
,
5153 "network X:X::X:X/M",
5154 "Specify a network to announce via BGP\n"
5157 int idx_ipv6_prefixlen
= 1;
5158 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5160 BGP_INVALID_LABEL_INDEX
);
5163 DEFUN (ipv6_bgp_network_route_map
,
5164 ipv6_bgp_network_route_map_cmd
,
5165 "network X:X::X:X/M route-map WORD",
5166 "Specify a network to announce via BGP\n"
5168 "Route-map to modify the attributes\n"
5169 "Name of the route map\n")
5171 int idx_ipv6_prefixlen
= 1;
5173 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5174 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5175 BGP_INVALID_LABEL_INDEX
);
5178 DEFUN (ipv6_bgp_network_label_index
,
5179 ipv6_bgp_network_label_index_cmd
,
5180 "network X:X::X:X/M label-index (0-1048560)",
5181 "Specify a network to announce via BGP\n"
5182 "IPv6 prefix <network>/<length>\n"
5183 "Label index to associate with the prefix\n"
5184 "Label index value\n")
5186 u_int32_t label_index
;
5188 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5189 return bgp_static_set (vty
, argv
[1]->arg
,
5190 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5193 DEFUN (ipv6_bgp_network_label_index_route_map
,
5194 ipv6_bgp_network_label_index_route_map_cmd
,
5195 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5196 "Specify a network to announce via BGP\n"
5198 "Label index to associate with the prefix\n"
5199 "Label index value\n"
5200 "Route-map to modify the attributes\n"
5201 "Name of the route map\n")
5203 u_int32_t label_index
;
5205 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5206 return bgp_static_set (vty
, argv
[1]->arg
,
5207 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5210 DEFUN (no_ipv6_bgp_network
,
5211 no_ipv6_bgp_network_cmd
,
5212 "no network X:X::X:X/M [route-map WORD]",
5214 "Specify a network to announce via BGP\n"
5216 "Route-map to modify the attributes\n"
5217 "Name of the route map\n")
5219 int idx_ipv6_prefixlen
= 2;
5220 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5223 ALIAS (no_ipv6_bgp_network
,
5224 no_ipv6_bgp_network_label_index_cmd
,
5225 "no network X:X::X:X/M label-index (0-1048560)",
5227 "Specify a network to announce via BGP\n"
5228 "IPv6 prefix <network>/<length>\n"
5229 "Label index to associate with the prefix\n"
5230 "Label index value\n")
5232 ALIAS (no_ipv6_bgp_network
,
5233 no_ipv6_bgp_network_label_index_route_map_cmd
,
5234 "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
5236 "Specify a network to announce via BGP\n"
5238 "Label index to associate with the prefix\n"
5239 "Label index value\n"
5240 "Route-map to modify the attributes\n"
5241 "Name of the route map\n")
5243 /* Aggreagete address:
5245 advertise-map Set condition to advertise attribute
5246 as-set Generate AS set path information
5247 attribute-map Set attributes of aggregate
5248 route-map Set parameters of aggregate
5249 summary-only Filter more specific routes from updates
5250 suppress-map Conditionally filter more specific routes from updates
5253 struct bgp_aggregate
5255 /* Summary-only flag. */
5256 u_char summary_only
;
5258 /* AS set generation. */
5261 /* Route-map for aggregated route. */
5262 struct route_map
*map
;
5264 /* Suppress-count. */
5265 unsigned long count
;
5267 /* SAFI configuration. */
5271 static struct bgp_aggregate
*
5272 bgp_aggregate_new (void)
5274 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5278 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5280 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5283 /* Update an aggregate as routes are added/removed from the BGP table */
5285 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5286 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5287 struct bgp_aggregate
*aggregate
)
5289 struct bgp_table
*table
;
5290 struct bgp_node
*top
;
5291 struct bgp_node
*rn
;
5293 struct aspath
*aspath
= NULL
;
5294 struct aspath
*asmerge
= NULL
;
5295 struct community
*community
= NULL
;
5296 struct community
*commerge
= NULL
;
5297 #if defined(AGGREGATE_NEXTHOP_CHECK)
5298 struct in_addr nexthop
;
5301 struct bgp_info
*ri
;
5302 struct bgp_info
*new;
5304 unsigned long match
= 0;
5305 u_char atomic_aggregate
= 0;
5307 /* Record adding route's nexthop and med. */
5310 #if defined(AGGREGATE_NEXTHOP_CHECK)
5311 nexthop
= rinew
->attr
->nexthop
;
5312 med
= rinew
->attr
->med
;
5316 /* ORIGIN attribute: If at least one route among routes that are
5317 aggregated has ORIGIN with the value INCOMPLETE, then the
5318 aggregated route must have the ORIGIN attribute with the value
5319 INCOMPLETE. Otherwise, if at least one route among routes that
5320 are aggregated has ORIGIN with the value EGP, then the aggregated
5321 route must have the origin attribute with the value EGP. In all
5322 other case the value of the ORIGIN attribute of the aggregated
5323 route is INTERNAL. */
5324 origin
= BGP_ORIGIN_IGP
;
5326 table
= bgp
->rib
[afi
][safi
];
5328 top
= bgp_node_get (table
, p
);
5329 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5330 if (rn
->p
.prefixlen
> p
->prefixlen
)
5334 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5336 if (BGP_INFO_HOLDDOWN (ri
))
5339 if (del
&& ri
== del
)
5342 if (! rinew
&& first
)
5344 #if defined(AGGREGATE_NEXTHOP_CHECK)
5345 nexthop
= ri
->attr
->nexthop
;
5346 med
= ri
->attr
->med
;
5351 #ifdef AGGREGATE_NEXTHOP_CHECK
5352 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5353 || ri
->attr
->med
!= med
)
5356 aspath_free (aspath
);
5358 community_free (community
);
5359 bgp_unlock_node (rn
);
5360 bgp_unlock_node (top
);
5363 #endif /* AGGREGATE_NEXTHOP_CHECK */
5365 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5366 atomic_aggregate
= 1;
5368 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5370 if (aggregate
->summary_only
)
5372 (bgp_info_extra_get (ri
))->suppress
++;
5373 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5379 if (origin
< ri
->attr
->origin
)
5380 origin
= ri
->attr
->origin
;
5382 if (aggregate
->as_set
)
5386 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5387 aspath_free (aspath
);
5391 aspath
= aspath_dup (ri
->attr
->aspath
);
5393 if (ri
->attr
->community
)
5397 commerge
= community_merge (community
,
5398 ri
->attr
->community
);
5399 community
= community_uniq_sort (commerge
);
5400 community_free (commerge
);
5403 community
= community_dup (ri
->attr
->community
);
5409 bgp_process (bgp
, rn
, afi
, safi
);
5411 bgp_unlock_node (top
);
5417 if (aggregate
->summary_only
)
5418 (bgp_info_extra_get (rinew
))->suppress
++;
5420 if (origin
< rinew
->attr
->origin
)
5421 origin
= rinew
->attr
->origin
;
5423 if (aggregate
->as_set
)
5427 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5428 aspath_free (aspath
);
5432 aspath
= aspath_dup (rinew
->attr
->aspath
);
5434 if (rinew
->attr
->community
)
5438 commerge
= community_merge (community
,
5439 rinew
->attr
->community
);
5440 community
= community_uniq_sort (commerge
);
5441 community_free (commerge
);
5444 community
= community_dup (rinew
->attr
->community
);
5449 if (aggregate
->count
> 0)
5451 rn
= bgp_node_get (table
, p
);
5452 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5453 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5455 atomic_aggregate
), rn
);
5456 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5458 bgp_info_add (rn
, new);
5459 bgp_unlock_node (rn
);
5460 bgp_process (bgp
, rn
, afi
, safi
);
5465 aspath_free (aspath
);
5467 community_free (community
);
5471 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5472 struct bgp_aggregate
*);
5475 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5476 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5478 struct bgp_node
*child
;
5479 struct bgp_node
*rn
;
5480 struct bgp_aggregate
*aggregate
;
5481 struct bgp_table
*table
;
5483 /* MPLS-VPN aggregation is not yet supported. */
5484 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5487 table
= bgp
->aggregate
[afi
][safi
];
5489 /* No aggregates configured. */
5490 if (bgp_table_top_nolock (table
) == NULL
)
5493 if (p
->prefixlen
== 0)
5496 if (BGP_INFO_HOLDDOWN (ri
))
5499 child
= bgp_node_get (table
, p
);
5501 /* Aggregate address configuration check. */
5502 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5503 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5505 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5506 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5508 bgp_unlock_node (child
);
5512 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5513 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5515 struct bgp_node
*child
;
5516 struct bgp_node
*rn
;
5517 struct bgp_aggregate
*aggregate
;
5518 struct bgp_table
*table
;
5520 /* MPLS-VPN aggregation is not yet supported. */
5521 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5524 table
= bgp
->aggregate
[afi
][safi
];
5526 /* No aggregates configured. */
5527 if (bgp_table_top_nolock (table
) == NULL
)
5530 if (p
->prefixlen
== 0)
5533 child
= bgp_node_get (table
, p
);
5535 /* Aggregate address configuration check. */
5536 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5537 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5539 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5540 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5542 bgp_unlock_node (child
);
5545 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5547 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5548 struct bgp_aggregate
*aggregate
)
5550 struct bgp_table
*table
;
5551 struct bgp_node
*top
;
5552 struct bgp_node
*rn
;
5553 struct bgp_info
*new;
5554 struct bgp_info
*ri
;
5555 unsigned long match
;
5556 u_char origin
= BGP_ORIGIN_IGP
;
5557 struct aspath
*aspath
= NULL
;
5558 struct aspath
*asmerge
= NULL
;
5559 struct community
*community
= NULL
;
5560 struct community
*commerge
= NULL
;
5561 u_char atomic_aggregate
= 0;
5563 table
= bgp
->rib
[afi
][safi
];
5566 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5568 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5571 /* If routes exists below this node, generate aggregate routes. */
5572 top
= bgp_node_get (table
, p
);
5573 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5574 if (rn
->p
.prefixlen
> p
->prefixlen
)
5578 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5580 if (BGP_INFO_HOLDDOWN (ri
))
5583 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5584 atomic_aggregate
= 1;
5586 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5588 /* summary-only aggregate route suppress aggregated
5589 route announcement. */
5590 if (aggregate
->summary_only
)
5592 (bgp_info_extra_get (ri
))->suppress
++;
5593 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5597 /* If at least one route among routes that are aggregated has
5598 * ORIGIN with the value INCOMPLETE, then the aggregated route
5599 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5600 * Otherwise, if at least one route among routes that are
5601 * aggregated has ORIGIN with the value EGP, then the aggregated
5602 * route MUST have the ORIGIN attribute with the value EGP.
5604 if (origin
< ri
->attr
->origin
)
5605 origin
= ri
->attr
->origin
;
5607 /* as-set aggregate route generate origin, as path,
5608 community aggregation. */
5609 if (aggregate
->as_set
)
5613 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5614 aspath_free (aspath
);
5618 aspath
= aspath_dup (ri
->attr
->aspath
);
5620 if (ri
->attr
->community
)
5624 commerge
= community_merge (community
,
5625 ri
->attr
->community
);
5626 community
= community_uniq_sort (commerge
);
5627 community_free (commerge
);
5630 community
= community_dup (ri
->attr
->community
);
5637 /* If this node is suppressed, process the change. */
5639 bgp_process (bgp
, rn
, afi
, safi
);
5641 bgp_unlock_node (top
);
5643 /* Add aggregate route to BGP table. */
5644 if (aggregate
->count
)
5646 rn
= bgp_node_get (table
, p
);
5647 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5648 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5650 atomic_aggregate
), rn
);
5651 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5653 bgp_info_add (rn
, new);
5654 bgp_unlock_node (rn
);
5656 /* Process change. */
5657 bgp_process (bgp
, rn
, afi
, safi
);
5662 aspath_free (aspath
);
5664 community_free (community
);
5669 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5670 safi_t safi
, struct bgp_aggregate
*aggregate
)
5672 struct bgp_table
*table
;
5673 struct bgp_node
*top
;
5674 struct bgp_node
*rn
;
5675 struct bgp_info
*ri
;
5676 unsigned long match
;
5678 table
= bgp
->rib
[afi
][safi
];
5680 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5682 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5685 /* If routes exists below this node, generate aggregate routes. */
5686 top
= bgp_node_get (table
, p
);
5687 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5688 if (rn
->p
.prefixlen
> p
->prefixlen
)
5692 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5694 if (BGP_INFO_HOLDDOWN (ri
))
5697 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5699 if (aggregate
->summary_only
&& ri
->extra
)
5701 ri
->extra
->suppress
--;
5703 if (ri
->extra
->suppress
== 0)
5705 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5713 /* If this node was suppressed, process the change. */
5715 bgp_process (bgp
, rn
, afi
, safi
);
5717 bgp_unlock_node (top
);
5719 /* Delete aggregate route from BGP table. */
5720 rn
= bgp_node_get (table
, p
);
5722 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5723 if (ri
->peer
== bgp
->peer_self
5724 && ri
->type
== ZEBRA_ROUTE_BGP
5725 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5728 /* Withdraw static BGP route from routing table. */
5731 bgp_info_delete (rn
, ri
);
5732 bgp_process (bgp
, rn
, afi
, safi
);
5735 /* Unlock bgp_node_lookup. */
5736 bgp_unlock_node (rn
);
5739 /* Aggregate route attribute. */
5740 #define AGGREGATE_SUMMARY_ONLY 1
5741 #define AGGREGATE_AS_SET 1
5744 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5745 afi_t afi
, safi_t safi
)
5747 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5750 struct bgp_node
*rn
;
5751 struct bgp_aggregate
*aggregate
;
5753 /* Convert string to prefix structure. */
5754 ret
= str2prefix (prefix_str
, &p
);
5757 vty_outln (vty
, "Malformed prefix");
5762 /* Old configuration check. */
5763 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5766 vty_outln (vty
,"%% There is no aggregate-address configuration.");
5770 aggregate
= rn
->info
;
5771 if (aggregate
->safi
== SAFI_UNICAST
)
5772 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5773 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5774 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5775 if (aggregate
->safi
== SAFI_MULTICAST
)
5776 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5778 /* Unlock aggregate address configuration. */
5780 bgp_aggregate_free (aggregate
);
5781 bgp_unlock_node (rn
);
5782 bgp_unlock_node (rn
);
5788 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5789 afi_t afi
, safi_t safi
,
5790 u_char summary_only
, u_char as_set
)
5792 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5795 struct bgp_node
*rn
;
5796 struct bgp_aggregate
*aggregate
;
5798 /* Convert string to prefix structure. */
5799 ret
= str2prefix (prefix_str
, &p
);
5802 vty_outln (vty
, "Malformed prefix");
5807 /* Old configuration check. */
5808 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5812 vty_outln (vty
, "There is already same aggregate network.");
5813 /* try to remove the old entry */
5814 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5817 vty_outln (vty
, "Error deleting aggregate.");
5818 bgp_unlock_node (rn
);
5823 /* Make aggregate address structure. */
5824 aggregate
= bgp_aggregate_new ();
5825 aggregate
->summary_only
= summary_only
;
5826 aggregate
->as_set
= as_set
;
5827 aggregate
->safi
= safi
;
5828 rn
->info
= aggregate
;
5830 /* Aggregate address insert into BGP routing table. */
5831 if (safi
== SAFI_UNICAST
)
5832 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5833 if (safi
== SAFI_LABELED_UNICAST
)
5834 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5835 if (safi
== SAFI_MULTICAST
)
5836 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5841 DEFUN (aggregate_address
,
5842 aggregate_address_cmd
,
5843 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5844 "Configure BGP aggregate entries\n"
5845 "Aggregate prefix\n"
5846 "Generate AS set path information\n"
5847 "Filter more specific routes from updates\n"
5848 "Filter more specific routes from updates\n"
5849 "Generate AS set path information\n")
5852 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5853 char *prefix
= argv
[idx
]->arg
;
5854 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5856 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5858 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5861 DEFUN (aggregate_address_mask
,
5862 aggregate_address_mask_cmd
,
5863 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5864 "Configure BGP aggregate entries\n"
5865 "Aggregate address\n"
5867 "Generate AS set path information\n"
5868 "Filter more specific routes from updates\n"
5869 "Filter more specific routes from updates\n"
5870 "Generate AS set path information\n")
5873 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5874 char *prefix
= argv
[idx
]->arg
;
5875 char *mask
= argv
[idx
+1]->arg
;
5876 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5878 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5880 char prefix_str
[BUFSIZ
];
5881 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5885 vty_outln (vty
, "%% Inconsistent address and mask");
5889 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5892 DEFUN (no_aggregate_address
,
5893 no_aggregate_address_cmd
,
5894 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5896 "Configure BGP aggregate entries\n"
5897 "Aggregate prefix\n"
5898 "Generate AS set path information\n"
5899 "Filter more specific routes from updates\n"
5900 "Filter more specific routes from updates\n"
5901 "Generate AS set path information\n")
5904 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5905 char *prefix
= argv
[idx
]->arg
;
5906 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5909 DEFUN (no_aggregate_address_mask
,
5910 no_aggregate_address_mask_cmd
,
5911 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5913 "Configure BGP aggregate entries\n"
5914 "Aggregate address\n"
5916 "Generate AS set path information\n"
5917 "Filter more specific routes from updates\n"
5918 "Filter more specific routes from updates\n"
5919 "Generate AS set path information\n")
5922 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5923 char *prefix
= argv
[idx
]->arg
;
5924 char *mask
= argv
[idx
+1]->arg
;
5926 char prefix_str
[BUFSIZ
];
5927 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5931 vty_outln (vty
, "%% Inconsistent address and mask");
5935 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5938 DEFUN (ipv6_aggregate_address
,
5939 ipv6_aggregate_address_cmd
,
5940 "aggregate-address X:X::X:X/M [summary-only]",
5941 "Configure BGP aggregate entries\n"
5942 "Aggregate prefix\n"
5943 "Filter more specific routes from updates\n")
5946 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5947 char *prefix
= argv
[idx
]->arg
;
5948 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5949 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5952 DEFUN (no_ipv6_aggregate_address
,
5953 no_ipv6_aggregate_address_cmd
,
5954 "no aggregate-address X:X::X:X/M [summary-only]",
5956 "Configure BGP aggregate entries\n"
5957 "Aggregate prefix\n"
5958 "Filter more specific routes from updates\n")
5961 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5962 char *prefix
= argv
[idx
]->arg
;
5963 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5966 /* Redistribute route treatment. */
5968 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5969 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5970 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5972 struct bgp_info
*new;
5973 struct bgp_info
*bi
;
5974 struct bgp_info info
;
5975 struct bgp_node
*bn
;
5977 struct attr
*new_attr
;
5980 struct bgp_redist
*red
;
5982 /* Make default attribute. */
5983 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5985 attr
.nexthop
= *nexthop
;
5986 attr
.nh_ifindex
= ifindex
;
5990 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5991 extra
->mp_nexthop_global
= *nexthop6
;
5992 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5996 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5997 attr
.extra
->tag
= tag
;
5999 afi
= family2afi (p
->family
);
6001 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6004 struct attr attr_new
;
6005 struct attr_extra extra_new
;
6007 /* Copy attribute for modification. */
6008 attr_new
.extra
= &extra_new
;
6009 bgp_attr_dup (&attr_new
, &attr
);
6011 if (red
->redist_metric_flag
)
6012 attr_new
.med
= red
->redist_metric
;
6014 /* Apply route-map. */
6017 info
.peer
= bgp
->peer_self
;
6018 info
.attr
= &attr_new
;
6020 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6022 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6024 bgp
->peer_self
->rmap_type
= 0;
6026 if (ret
== RMAP_DENYMATCH
)
6028 /* Free uninterned attribute. */
6029 bgp_attr_flush (&attr_new
);
6031 /* Unintern original. */
6032 aspath_unintern (&attr
.aspath
);
6033 bgp_attr_extra_free (&attr
);
6034 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6039 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6040 afi
, SAFI_UNICAST
, p
, NULL
);
6042 new_attr
= bgp_attr_intern (&attr_new
);
6044 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6045 if (bi
->peer
== bgp
->peer_self
6046 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6051 /* Ensure the (source route) type is updated. */
6053 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6054 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6056 bgp_attr_unintern (&new_attr
);
6057 aspath_unintern (&attr
.aspath
);
6058 bgp_attr_extra_free (&attr
);
6059 bgp_unlock_node (bn
);
6064 /* The attribute is changed. */
6065 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6067 /* Rewrite BGP route information. */
6068 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6069 bgp_info_restore(bn
, bi
);
6071 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6072 bgp_attr_unintern (&bi
->attr
);
6073 bi
->attr
= new_attr
;
6074 bi
->uptime
= bgp_clock ();
6076 /* Process change. */
6077 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6078 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6079 bgp_unlock_node (bn
);
6080 aspath_unintern (&attr
.aspath
);
6081 bgp_attr_extra_free (&attr
);
6086 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6088 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6090 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6091 bgp_info_add (bn
, new);
6092 bgp_unlock_node (bn
);
6093 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6096 /* Unintern original. */
6097 aspath_unintern (&attr
.aspath
);
6098 bgp_attr_extra_free (&attr
);
6102 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6105 struct bgp_node
*rn
;
6106 struct bgp_info
*ri
;
6107 struct bgp_redist
*red
;
6109 afi
= family2afi (p
->family
);
6111 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6114 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6116 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6117 if (ri
->peer
== bgp
->peer_self
6118 && ri
->type
== type
)
6123 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6124 bgp_info_delete (rn
, ri
);
6125 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6127 bgp_unlock_node (rn
);
6131 /* Withdraw specified route type's route. */
6133 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6135 struct bgp_node
*rn
;
6136 struct bgp_info
*ri
;
6137 struct bgp_table
*table
;
6139 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6141 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6143 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6144 if (ri
->peer
== bgp
->peer_self
6146 && ri
->instance
== instance
)
6151 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6152 bgp_info_delete (rn
, ri
);
6153 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6158 /* Static function to display route. */
6160 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6163 u_int32_t destination
;
6166 if (p
->family
== AF_INET
)
6168 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6169 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6171 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6172 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6173 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6174 || p
->u
.prefix4
.s_addr
== 0)
6176 /* When mask is natural, mask is not displayed. */
6179 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6181 else if (p
->family
== AF_ETHERNET
)
6183 prefix2str(p
, buf
, PREFIX_STRLEN
);
6184 len
= vty_out (vty
, "%s", buf
);
6187 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6192 vty_out (vty
, "%s%*s", VTYNL
, 20, " ");
6194 vty_out (vty
, "%*s", len
, " ");
6197 enum bgp_display_type
6202 /* Print the short form route status for a bgp_info */
6204 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6205 json_object
*json_path
)
6210 /* Route status display. */
6211 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6212 json_object_boolean_true_add(json_path
, "removed");
6214 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6215 json_object_boolean_true_add(json_path
, "stale");
6217 if (binfo
->extra
&& binfo
->extra
->suppress
)
6218 json_object_boolean_true_add(json_path
, "suppressed");
6220 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6221 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6222 json_object_boolean_true_add(json_path
, "valid");
6225 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6226 json_object_boolean_true_add(json_path
, "history");
6228 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6229 json_object_boolean_true_add(json_path
, "damped");
6231 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6232 json_object_boolean_true_add(json_path
, "bestpath");
6234 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6235 json_object_boolean_true_add(json_path
, "multipath");
6237 /* Internal route. */
6238 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6239 json_object_string_add(json_path
, "pathFrom", "internal");
6241 json_object_string_add(json_path
, "pathFrom", "external");
6246 /* Route status display. */
6247 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6249 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6251 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6253 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6254 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6260 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6262 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6264 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6266 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6271 /* Internal route. */
6273 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6279 /* called from terminal list command */
6281 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6282 struct bgp_info
*binfo
, int display
, safi_t safi
,
6283 json_object
*json_paths
)
6286 json_object
*json_path
= NULL
;
6287 json_object
*json_nexthops
= NULL
;
6288 json_object
*json_nexthop_global
= NULL
;
6289 json_object
*json_nexthop_ll
= NULL
;
6292 json_path
= json_object_new_object();
6294 /* short status lead text */
6295 route_vty_short_status_out (vty
, binfo
, json_path
);
6299 /* print prefix and mask */
6301 route_vty_out_route (p
, vty
);
6303 vty_out (vty
, "%*s", 17, " ");
6306 /* Print attribute */
6311 * For ENCAP routes, nexthop address family is not
6312 * neccessarily the same as the prefix address family.
6313 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6315 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6320 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6325 vty_out (vty
, "%s", inet_ntop(af
,
6326 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6329 vty_out (vty
, "%s", inet_ntop(af
,
6330 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6341 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6345 json_nexthop_global
= json_object_new_object();
6347 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6348 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6350 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6352 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6353 json_object_boolean_true_add(json_nexthop_global
, "used");
6357 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6358 vty_out (vty
, "%-16s",
6359 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6361 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6366 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6373 json_nexthop_global
= json_object_new_object();
6374 json_object_string_add(json_nexthop_global
, "ip",
6375 inet_ntop (AF_INET6
,
6376 &attr
->extra
->mp_nexthop_global
,
6378 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6379 json_object_string_add(json_nexthop_global
, "scope", "global");
6381 /* We display both LL & GL if both have been received */
6382 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6384 json_nexthop_ll
= json_object_new_object();
6385 json_object_string_add(json_nexthop_ll
, "ip",
6386 inet_ntop (AF_INET6
,
6387 &attr
->extra
->mp_nexthop_local
,
6389 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6390 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6392 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6393 &attr
->extra
->mp_nexthop_local
) != 0) &&
6394 !attr
->extra
->mp_nexthop_prefer_global
)
6395 json_object_boolean_true_add(json_nexthop_ll
, "used");
6397 json_object_boolean_true_add(json_nexthop_global
, "used");
6400 json_object_boolean_true_add(json_nexthop_global
, "used");
6404 /* Display LL if LL/Global both in table unless prefer-global is set */
6405 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6406 !attr
->extra
->mp_nexthop_prefer_global
) ||
6407 (binfo
->peer
->conf_if
))
6409 if (binfo
->peer
->conf_if
)
6411 len
= vty_out (vty
, "%s",
6412 binfo
->peer
->conf_if
);
6413 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6416 vty_out (vty
, "%s%*s", VTYNL
, 45, " ");
6418 vty_out (vty
, "%*s", len
, " ");
6422 len
= vty_out (vty
, "%s",
6423 inet_ntop (AF_INET6
,
6424 &attr
->extra
->mp_nexthop_local
,
6429 vty_out (vty
, "%s%*s", VTYNL
, 36, " ");
6431 vty_out (vty
, "%*s", len
, " ");
6436 len
= vty_out (vty
, "%s",
6437 inet_ntop (AF_INET6
,
6438 &attr
->extra
->mp_nexthop_global
,
6443 vty_out (vty
, "%s%*s", VTYNL
, 36, " ");
6445 vty_out (vty
, "%*s", len
, " ");
6451 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6453 json_object_int_add(json_path
, "med", attr
->med
);
6455 vty_out (vty
, "%10u", attr
->med
);
6461 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6463 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6465 vty_out (vty
, "%7u", attr
->local_pref
);
6473 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6475 json_object_int_add(json_path
, "weight", 0);
6478 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6482 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6489 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6491 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6496 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6498 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6503 json_object_string_add(json_path
, "alert", "No attributes");
6505 vty_outln (vty
, "No attributes to print");
6510 if (json_nexthop_global
|| json_nexthop_ll
)
6512 json_nexthops
= json_object_new_array();
6514 if (json_nexthop_global
)
6515 json_object_array_add(json_nexthops
, json_nexthop_global
);
6517 if (json_nexthop_ll
)
6518 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6520 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6523 json_object_array_add(json_paths
, json_path
);
6527 vty_out (vty
, VTYNL
);
6529 /* prints an additional line, indented, with VNC info, if present */
6530 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6531 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6536 /* called from terminal list command */
6538 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6539 u_char use_json
, json_object
*json_ar
)
6541 json_object
*json_status
= NULL
;
6542 json_object
*json_net
= NULL
;
6544 /* Route status display. */
6547 json_status
= json_object_new_object();
6548 json_net
= json_object_new_object();
6557 /* print prefix and mask */
6559 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6561 route_vty_out_route (p
, vty
);
6563 /* Print attribute */
6568 if (p
->family
== AF_INET
&&
6569 (safi
== SAFI_MPLS_VPN
||
6570 safi
== SAFI_ENCAP
||
6571 safi
== SAFI_EVPN
||
6572 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6574 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6575 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6577 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6579 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6583 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6587 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6588 json_object_int_add(json_net
, "metric", attr
->med
);
6590 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6591 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6594 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6596 json_object_int_add(json_net
, "weight", 0);
6600 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6603 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6607 if (p
->family
== AF_INET
&&
6608 (safi
== SAFI_MPLS_VPN
||
6609 safi
== SAFI_ENCAP
||
6610 safi
== SAFI_EVPN
||
6611 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6613 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6614 vty_out (vty
, "%-16s",
6615 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6617 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6619 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6624 assert (attr
->extra
);
6626 len
= vty_out (vty
, "%s",
6627 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6631 vty_out (vty
, "%s%*s", VTYNL
, 36, " ");
6633 vty_out (vty
, "%*s", len
, " ");
6635 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6636 vty_out (vty
, "%10u", attr
->med
);
6640 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6641 vty_out (vty
, "%7u", attr
->local_pref
);
6645 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6649 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6652 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6657 json_object_boolean_true_add(json_status
, "*");
6658 json_object_boolean_true_add(json_status
, ">");
6659 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6660 char buf_cut
[BUFSIZ
];
6661 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6664 vty_out (vty
, VTYNL
);
6668 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6669 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6671 json_object
*json_out
= NULL
;
6673 mpls_label_t label
= MPLS_INVALID_LABEL
;
6679 json_out
= json_object_new_object();
6681 /* short status lead text */
6682 route_vty_short_status_out (vty
, binfo
, json_out
);
6684 /* print prefix and mask */
6688 route_vty_out_route (p
, vty
);
6690 vty_out (vty
, "%*s", 17, " ");
6693 /* Print attribute */
6697 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6698 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6699 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6701 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6704 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6706 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6711 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6713 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6716 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6717 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6718 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6720 assert (attr
->extra
);
6724 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6727 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6728 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6731 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6734 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6738 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6740 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6742 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6743 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6746 vty_out (vty
, "%s(%s)",
6747 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6749 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6756 label
= decode_label (&binfo
->extra
->label
);
6758 if (bgp_is_valid_label(&label
))
6762 json_object_int_add(json_out
, "notag", label
);
6763 json_object_array_add(json
, json_out
);
6767 vty_out (vty
, "notag/%d", label
);
6768 vty_out (vty
, VTYNL
);
6774 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6775 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6779 json_object
*json_path
= NULL
;
6782 json_path
= json_object_new_object();
6787 /* short status lead text */
6788 route_vty_short_status_out (vty
, binfo
, json_path
);
6790 /* print prefix and mask */
6792 route_vty_out_route (p
, vty
);
6794 vty_out (vty
, "%*s", 17, " ");
6796 /* Print attribute */
6803 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6807 vty_out (vty
, "%-16s", inet_ntop(af
,
6808 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6811 vty_out (vty
, "%s(%s)",
6813 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6815 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6827 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6828 char *str
= esi2str(id
);
6829 vty_out (vty
, "%s", str
);
6830 XFREE (MTYPE_TMP
, str
);
6831 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6833 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6835 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6837 vty_out (vty
, "/%s",
6838 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6841 if(attr
->extra
->ecommunity
)
6844 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6845 ECOMMUNITY_ENCODE_EVPN
,
6846 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6848 mac
= ecom_mac2str((char *)routermac
->val
);
6851 vty_out (vty
, "/%s",(char *)mac
);
6852 XFREE(MTYPE_TMP
, mac
);
6856 vty_out (vty
, VTYNL
);
6859 /* dampening route */
6861 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6862 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6866 char timebuf
[BGP_UPTIME_LEN
];
6868 /* short status lead text */
6869 route_vty_short_status_out (vty
, binfo
, json
);
6871 /* print prefix and mask */
6875 route_vty_out_route (p
, vty
);
6877 vty_out (vty
, "%*s", 17, " ");
6880 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6885 vty_out (vty
, "%s%*s", VTYNL
, 34, " ");
6890 json_object_int_add(json
, "peerHost", len
);
6892 vty_out (vty
, "%*s", len
, " ");
6896 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6898 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6900 /* Print attribute */
6908 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6910 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6915 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6917 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6920 vty_out (vty
, VTYNL
);
6925 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6926 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6929 struct bgp_damp_info
*bdi
;
6930 char timebuf
[BGP_UPTIME_LEN
];
6936 bdi
= binfo
->extra
->damp_info
;
6938 /* short status lead text */
6939 route_vty_short_status_out (vty
, binfo
, json
);
6941 /* print prefix and mask */
6945 route_vty_out_route (p
, vty
);
6947 vty_out (vty
, "%*s", 17, " ");
6950 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6955 vty_out (vty
, "%s%*s", VTYNL
, 33, " ");
6960 json_object_int_add(json
, "peerHost", len
);
6962 vty_out (vty
, "%*s", len
, " ");
6965 len
= vty_out (vty
, "%d", bdi
->flap
);
6975 json_object_int_add(json
, "bdiFlap", len
);
6977 vty_out (vty
, "%*s", len
, " ");
6981 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6983 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6984 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6986 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6987 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6990 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6992 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6997 vty_out (vty
, "%*s ", 8, " ");
7000 /* Print attribute */
7008 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
7010 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7015 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7017 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7020 vty_out (vty
, VTYNL
);
7024 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7025 const char *header
, json_object
*json_adv_to
)
7027 char buf1
[INET6_ADDRSTRLEN
];
7028 json_object
*json_peer
= NULL
;
7032 /* 'advertised-to' is a dictionary of peers we have advertised this
7033 * prefix too. The key is the peer's IP or swpX, the value is the
7034 * hostname if we know it and "" if not.
7036 json_peer
= json_object_new_object();
7039 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7042 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7044 json_object_object_add(json_adv_to
,
7045 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7052 vty_out (vty
, "%s", header
);
7056 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7059 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7061 vty_out (vty
, " %s(%s)", peer
->hostname
,
7062 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7067 vty_out (vty
, " %s", peer
->conf_if
);
7069 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7075 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7076 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7077 json_object
*json_paths
)
7079 char buf
[INET6_ADDRSTRLEN
];
7082 int sockunion_vty_out (struct vty
*, union sockunion
*);
7084 json_object
*json_bestpath
= NULL
;
7085 json_object
*json_cluster_list
= NULL
;
7086 json_object
*json_cluster_list_list
= NULL
;
7087 json_object
*json_ext_community
= NULL
;
7088 json_object
*json_last_update
= NULL
;
7089 json_object
*json_nexthop_global
= NULL
;
7090 json_object
*json_nexthop_ll
= NULL
;
7091 json_object
*json_nexthops
= NULL
;
7092 json_object
*json_path
= NULL
;
7093 json_object
*json_peer
= NULL
;
7094 json_object
*json_string
= NULL
;
7095 json_object
*json_adv_to
= NULL
;
7097 struct listnode
*node
, *nnode
;
7099 int addpath_capable
;
7101 unsigned int first_as
;
7105 json_path
= json_object_new_object();
7106 json_peer
= json_object_new_object();
7107 json_nexthop_global
= json_object_new_object();
7114 /* Line1 display AS-path, Aggregator */
7119 json_object_lock(attr
->aspath
->json
);
7120 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7124 if (attr
->aspath
->segments
)
7125 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7127 vty_out (vty
, " Local");
7131 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7134 json_object_boolean_true_add(json_path
, "removed");
7136 vty_out (vty
, ", (removed)");
7139 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7142 json_object_boolean_true_add(json_path
, "stale");
7144 vty_out (vty
, ", (stale)");
7147 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7151 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
7152 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
7156 vty_out (vty
, ", (aggregated by %u %s)",
7157 attr
->extra
->aggregator_as
,
7158 inet_ntoa (attr
->extra
->aggregator_addr
));
7162 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7165 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7167 vty_out (vty
, ", (Received from a RR-client)");
7170 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7173 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7175 vty_out (vty
, ", (Received from a RS-client)");
7178 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7181 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7183 vty_out (vty
, ", (history entry)");
7185 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7188 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7190 vty_out (vty
, ", (suppressed due to dampening)");
7194 vty_out (vty
, VTYNL
);
7196 /* Line2 display Next-hop, Neighbor, Router-id */
7197 /* Display the nexthop */
7198 if (p
->family
== AF_INET
&&
7199 (safi
== SAFI_MPLS_VPN
||
7200 safi
== SAFI_ENCAP
||
7201 safi
== SAFI_EVPN
||
7202 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7204 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7207 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7209 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7214 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7216 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7220 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7224 assert (attr
->extra
);
7227 json_object_string_add(json_nexthop_global
, "ip",
7228 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7229 buf
, INET6_ADDRSTRLEN
));
7230 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7231 json_object_string_add(json_nexthop_global
, "scope", "global");
7235 vty_out (vty
, " %s",
7236 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7237 buf
, INET6_ADDRSTRLEN
));
7241 /* Display the IGP cost or 'inaccessible' */
7242 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7245 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7247 vty_out (vty
, " (inaccessible)");
7251 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7254 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7256 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7259 /* IGP cost is 0, display this only for json */
7263 json_object_int_add(json_nexthop_global
, "metric", 0);
7267 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7270 /* Display peer "from" output */
7271 /* This path was originated locally */
7272 if (binfo
->peer
== bgp
->peer_self
)
7275 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7278 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7280 vty_out (vty
, " from 0.0.0.0 ");
7285 json_object_string_add(json_peer
, "peerId", "::");
7287 vty_out (vty
, " from :: ");
7291 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7293 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7296 /* We RXed this path from one of our peers */
7302 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7303 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7305 if (binfo
->peer
->hostname
)
7306 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7308 if (binfo
->peer
->domainname
)
7309 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7311 if (binfo
->peer
->conf_if
)
7312 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7316 if (binfo
->peer
->conf_if
)
7318 if (binfo
->peer
->hostname
&&
7319 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7320 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7321 binfo
->peer
->conf_if
);
7323 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7327 if (binfo
->peer
->hostname
&&
7328 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7329 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7332 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7335 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7336 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7338 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7343 vty_out (vty
, VTYNL
);
7345 /* display the link-local nexthop */
7346 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7350 json_nexthop_ll
= json_object_new_object();
7351 json_object_string_add(json_nexthop_ll
, "ip",
7352 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7353 buf
, INET6_ADDRSTRLEN
));
7354 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7355 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7357 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7359 if (!attr
->extra
->mp_nexthop_prefer_global
)
7360 json_object_boolean_true_add(json_nexthop_ll
, "used");
7362 json_object_boolean_true_add(json_nexthop_global
, "used");
7366 vty_outln (vty
, " (%s) %s",
7367 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7368 buf
, INET6_ADDRSTRLEN
),
7369 attr
->extra
->mp_nexthop_prefer_global
? "(prefer-global)" : "(used)");
7372 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7376 json_object_boolean_true_add(json_nexthop_global
, "used");
7379 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7381 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7383 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7385 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7388 json_object_int_add(json_path
, "med", attr
->med
);
7390 vty_out (vty
, ", metric %u", attr
->med
);
7393 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7396 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7398 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7403 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7405 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7408 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7411 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7413 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7416 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7419 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7421 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7424 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7427 json_object_boolean_false_add(json_path
, "valid");
7429 vty_out (vty
, ", invalid");
7431 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7434 json_object_boolean_true_add(json_path
, "valid");
7436 vty_out (vty
, ", valid");
7439 if (binfo
->peer
!= bgp
->peer_self
)
7441 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7443 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7446 json_object_string_add(json_peer
, "type", "confed-internal");
7448 vty_out (vty
, ", confed-internal");
7453 json_object_string_add(json_peer
, "type", "internal");
7455 vty_out (vty
, ", internal");
7460 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7463 json_object_string_add(json_peer
, "type", "confed-external");
7465 vty_out (vty
, ", confed-external");
7470 json_object_string_add(json_peer
, "type", "external");
7472 vty_out (vty
, ", external");
7476 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7480 json_object_boolean_true_add(json_path
, "aggregated");
7481 json_object_boolean_true_add(json_path
, "local");
7485 vty_out (vty
, ", aggregated, local");
7488 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7491 json_object_boolean_true_add(json_path
, "sourced");
7493 vty_out (vty
, ", sourced");
7499 json_object_boolean_true_add(json_path
, "sourced");
7500 json_object_boolean_true_add(json_path
, "local");
7504 vty_out (vty
, ", sourced, local");
7508 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7511 json_object_boolean_true_add(json_path
, "atomicAggregate");
7513 vty_out (vty
, ", atomic-aggregate");
7516 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7517 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7518 bgp_info_mpath_count (binfo
)))
7521 json_object_boolean_true_add(json_path
, "multipath");
7523 vty_out (vty
, ", multipath");
7526 // Mark the bestpath(s)
7527 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7529 first_as
= aspath_get_first_as(attr
->aspath
);
7534 json_bestpath
= json_object_new_object();
7535 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7540 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7542 vty_out (vty
, ", bestpath-from-AS Local");
7546 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7551 json_bestpath
= json_object_new_object();
7552 json_object_boolean_true_add(json_bestpath
, "overall");
7555 vty_out (vty
, ", best");
7559 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7562 vty_out (vty
, VTYNL
);
7564 /* Line 4 display Community */
7565 if (attr
->community
)
7569 json_object_lock(attr
->community
->json
);
7570 json_object_object_add(json_path
, "community", attr
->community
->json
);
7574 vty_outln (vty
, " Community: %s",attr
->community
->str
);
7578 /* Line 5 display Extended-community */
7579 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7583 json_ext_community
= json_object_new_object();
7584 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7585 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7589 vty_outln (vty
, " Extended Community: %s",
7590 attr
->extra
->ecommunity
->str
);
7594 /* Line 6 display Large community */
7595 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7596 vty_outln (vty
, " Large Community: %s",
7597 attr
->extra
->lcommunity
->str
);
7599 /* Line 7 display Originator, Cluster-id */
7600 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7601 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7603 assert (attr
->extra
);
7604 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7607 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7609 vty_out (vty
, " Originator: %s",
7610 inet_ntoa (attr
->extra
->originator_id
));
7613 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7619 json_cluster_list
= json_object_new_object();
7620 json_cluster_list_list
= json_object_new_array();
7622 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7624 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7625 json_object_array_add(json_cluster_list_list
, json_string
);
7628 /* struct cluster_list does not have "str" variable like
7629 * aspath and community do. Add this someday if someone
7631 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7633 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7634 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7638 vty_out (vty
, ", Cluster list: ");
7640 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7642 vty_out (vty
, "%s ",
7643 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7649 vty_out (vty
, VTYNL
);
7652 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7653 bgp_damp_info_vty (vty
, binfo
, json_path
);
7656 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
))
7658 mpls_label_t label
= label_pton(&binfo
->extra
->label
);
7660 json_object_int_add(json_path
, "remoteLabel", label
);
7662 vty_outln (vty
, " Remote label: %d", label
);
7666 if (attr
->extra
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7669 json_object_int_add(json_path
, "labelIndex", attr
->extra
->label_index
);
7671 vty_outln (vty
, " Label Index: %d",
7672 attr
->extra
->label_index
);
7675 /* Line 8 display Addpath IDs */
7676 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7680 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7681 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7685 vty_outln (vty
, " AddPath ID: RX %u, TX %u",
7686 binfo
->addpath_rx_id
,binfo
->addpath_tx_id
);
7690 /* If we used addpath to TX a non-bestpath we need to display
7691 * "Advertised to" on a path-by-path basis */
7692 if (bgp
->addpath_tx_used
[afi
][safi
])
7696 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7698 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7699 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7701 if ((addpath_capable
&& has_adj
) ||
7702 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7704 if (json_path
&& !json_adv_to
)
7705 json_adv_to
= json_object_new_object();
7707 route_vty_out_advertised_to(vty
, peer
, &first
,
7717 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7724 vty_out (vty
, VTYNL
);
7729 /* Line 9 display Uptime */
7730 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7733 json_last_update
= json_object_new_object();
7734 json_object_int_add(json_last_update
, "epoch", tbuf
);
7735 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7736 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7739 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7742 /* We've constructed the json object for this path, add it to the json
7747 if (json_nexthop_global
|| json_nexthop_ll
)
7749 json_nexthops
= json_object_new_array();
7751 if (json_nexthop_global
)
7752 json_object_array_add(json_nexthops
, json_nexthop_global
);
7754 if (json_nexthop_ll
)
7755 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7757 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7760 json_object_object_add(json_path
, "peer", json_peer
);
7761 json_object_array_add(json_paths
, json_path
);
7764 vty_out (vty
, VTYNL
);
7767 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
7768 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path"
7769 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path"
7772 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7773 const char *prefix_list_str
, afi_t afi
,
7774 safi_t safi
, enum bgp_show_type type
);
7776 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7777 const char *filter
, afi_t afi
,
7778 safi_t safi
, enum bgp_show_type type
);
7780 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7781 const char *rmap_str
, afi_t afi
,
7782 safi_t safi
, enum bgp_show_type type
);
7784 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7785 const char *com
, int exact
,
7786 afi_t afi
, safi_t safi
);
7788 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7789 const char *prefix
, afi_t afi
,
7790 safi_t safi
, enum bgp_show_type type
);
7792 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7793 safi_t safi
, enum bgp_show_type type
);
7795 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7796 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7799 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7800 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7802 struct bgp_info
*ri
;
7803 struct bgp_node
*rn
;
7806 unsigned long output_count
;
7807 unsigned long total_count
;
7811 json_object
*json_paths
= NULL
;
7816 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7817 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7818 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7819 table
->version
, inet_ntoa (bgp
->router_id
));
7820 json_paths
= json_object_new_object();
7823 /* This is first entry point, so reset total line. */
7827 /* Start processing of routes. */
7828 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7829 if (rn
->info
!= NULL
)
7832 if (!first
&& use_json
)
7837 json_paths
= json_object_new_array();
7841 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7844 if (type
== bgp_show_type_flap_statistics
7845 || type
== bgp_show_type_flap_neighbor
7846 || type
== bgp_show_type_dampend_paths
7847 || type
== bgp_show_type_damp_neighbor
)
7849 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7852 if (type
== bgp_show_type_regexp
)
7854 regex_t
*regex
= output_arg
;
7856 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7859 if (type
== bgp_show_type_prefix_list
)
7861 struct prefix_list
*plist
= output_arg
;
7863 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7866 if (type
== bgp_show_type_filter_list
)
7868 struct as_list
*as_list
= output_arg
;
7870 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7873 if (type
== bgp_show_type_route_map
)
7875 struct route_map
*rmap
= output_arg
;
7876 struct bgp_info binfo
;
7877 struct attr dummy_attr
;
7878 struct attr_extra dummy_extra
;
7881 dummy_attr
.extra
= &dummy_extra
;
7882 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7884 binfo
.peer
= ri
->peer
;
7885 binfo
.attr
= &dummy_attr
;
7887 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7888 if (ret
== RMAP_DENYMATCH
)
7891 if (type
== bgp_show_type_neighbor
7892 || type
== bgp_show_type_flap_neighbor
7893 || type
== bgp_show_type_damp_neighbor
)
7895 union sockunion
*su
= output_arg
;
7897 if (ri
->peer
== NULL
||
7898 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7901 if (type
== bgp_show_type_cidr_only
)
7903 u_int32_t destination
;
7905 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7906 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7908 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7910 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7913 if (type
== bgp_show_type_prefix_longer
)
7915 struct prefix
*p
= output_arg
;
7917 if (! prefix_match (p
, &rn
->p
))
7920 if (type
== bgp_show_type_community_all
)
7922 if (! ri
->attr
->community
)
7925 if (type
== bgp_show_type_community
)
7927 struct community
*com
= output_arg
;
7929 if (! ri
->attr
->community
||
7930 ! community_match (ri
->attr
->community
, com
))
7933 if (type
== bgp_show_type_community_exact
)
7935 struct community
*com
= output_arg
;
7937 if (! ri
->attr
->community
||
7938 ! community_cmp (ri
->attr
->community
, com
))
7941 if (type
== bgp_show_type_community_list
)
7943 struct community_list
*list
= output_arg
;
7945 if (! community_list_match (ri
->attr
->community
, list
))
7948 if (type
== bgp_show_type_community_list_exact
)
7950 struct community_list
*list
= output_arg
;
7952 if (! community_list_exact_match (ri
->attr
->community
, list
))
7955 if (type
== bgp_show_type_lcommunity
)
7957 struct lcommunity
*lcom
= output_arg
;
7959 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7960 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7963 if (type
== bgp_show_type_lcommunity_list
)
7965 struct community_list
*list
= output_arg
;
7967 if (! ri
->attr
->extra
||
7968 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7971 if (type
== bgp_show_type_lcommunity_all
)
7973 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7976 if (type
== bgp_show_type_dampend_paths
7977 || type
== bgp_show_type_damp_neighbor
)
7979 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7980 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7984 if (!use_json
&& header
)
7986 vty_outln (vty
, "BGP table version is %" PRIu64
", local router ID is %s", table
->version
,
7987 inet_ntoa(bgp
->router_id
));
7988 vty_outln (vty
, BGP_SHOW_SCODE_HEADER
, VTYNL
);
7989 vty_outln (vty
, BGP_SHOW_OCODE_HEADER
, VTYNL
);
7990 if (type
== bgp_show_type_dampend_paths
7991 || type
== bgp_show_type_damp_neighbor
)
7992 vty_outln (vty
, BGP_SHOW_DAMP_HEADER
);
7993 else if (type
== bgp_show_type_flap_statistics
7994 || type
== bgp_show_type_flap_neighbor
)
7995 vty_outln (vty
, BGP_SHOW_FLAP_HEADER
);
7997 vty_outln (vty
, BGP_SHOW_HEADER
);
8001 if (type
== bgp_show_type_dampend_paths
8002 || type
== bgp_show_type_damp_neighbor
)
8003 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8004 else if (type
== bgp_show_type_flap_statistics
8005 || type
== bgp_show_type_flap_neighbor
)
8006 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8008 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8018 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8019 vty_out (vty
, "\"%s\": ", buf2
);
8020 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8021 json_object_free (json_paths
);
8030 json_object_free (json_paths
);
8031 vty_outln (vty
, " } }");
8035 /* No route is displayed */
8036 if (output_count
== 0)
8038 if (type
== bgp_show_type_normal
)
8039 vty_outln (vty
, "No BGP prefixes displayed, %ld exist",
8043 vty_outln (vty
, "%sDisplayed %ld routes and %ld total paths",
8044 VTYNL
, output_count
, total_count
);
8051 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8052 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8054 struct bgp_table
*table
;
8058 bgp
= bgp_get_default ();
8064 vty_outln (vty
, "No BGP process is configured");
8067 /* use MPLS and ENCAP specific shows until they are merged */
8068 if (safi
== SAFI_MPLS_VPN
)
8070 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8074 table
= bgp
->rib
[afi
][safi
];
8076 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8081 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8084 struct listnode
*node
, *nnode
;
8089 vty_outln (vty
, "{");
8091 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8096 vty_outln (vty
, ",");
8100 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8101 ? "Default" : bgp
->name
);
8105 vty_outln (vty
, "%sInstance %s:",
8107 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? "Default" : bgp
->name
);
8109 bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
, use_json
);
8114 vty_outln (vty
, "}");
8117 /* Header of detailed BGP route information */
8119 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8120 struct bgp_node
*rn
,
8121 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8124 struct bgp_info
*ri
;
8127 struct listnode
*node
, *nnode
;
8128 char buf1
[INET6_ADDRSTRLEN
];
8129 char buf2
[INET6_ADDRSTRLEN
];
8134 int no_advertise
= 0;
8137 int has_valid_label
= 0;
8139 json_object
*json_adv_to
= NULL
;
8142 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8144 if (has_valid_label
)
8145 label
= label_pton(&rn
->local_label
);
8149 if (has_valid_label
)
8150 json_object_int_add(json
, "localLabel", label
);
8152 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8153 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8157 if (p
->family
== AF_ETHERNET
)
8158 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8160 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8161 vty_outln (vty
, "BGP routing table entry for %s%s%s/%d",
8162 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8163 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8164 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8168 if (has_valid_label
)
8169 vty_outln (vty
, "Local label: %d", label
);
8170 else if (bgp_labeled_safi(safi
))
8171 vty_outln (vty
, "Local label: not allocated");
8174 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8177 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8180 if (ri
->extra
&& ri
->extra
->suppress
)
8182 if (ri
->attr
->community
!= NULL
)
8184 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8186 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8188 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8196 vty_out (vty
, "Paths: (%d available", count
);
8199 vty_out (vty
, ", best #%d", best
);
8200 if (safi
== SAFI_UNICAST
)
8201 vty_out (vty
, ", table %s",
8202 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8203 ? "Default-IP-Routing-Table" : bgp
->name
);
8206 vty_out (vty
, ", no best path");
8209 vty_out (vty
, ", not advertised to any peer");
8211 vty_out (vty
, ", not advertised to EBGP peer");
8213 vty_out (vty
, ", not advertised outside local AS");
8216 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8217 vty_outln (vty
, ")");
8220 /* If we are not using addpath then we can display Advertised to and that will
8221 * show what peers we advertised the bestpath to. If we are using addpath
8222 * though then we must display Advertised to on a path-by-path basis. */
8223 if (!bgp
->addpath_tx_used
[afi
][safi
])
8225 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8227 if (bgp_adj_out_lookup (peer
, rn
, 0))
8229 if (json
&& !json_adv_to
)
8230 json_adv_to
= json_object_new_object();
8232 route_vty_out_advertised_to(vty
, peer
, &first
,
8233 " Advertised to non peer-group peers:\n ",
8242 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8248 vty_out (vty
, " Not advertised to any peer");
8249 vty_out (vty
, VTYNL
);
8254 /* Display specified route of BGP table. */
8256 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8257 struct bgp_table
*rib
, const char *ip_str
,
8258 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8259 int prefix_check
, enum bgp_path_type pathtype
,
8265 struct prefix match
;
8266 struct bgp_node
*rn
;
8267 struct bgp_node
*rm
;
8268 struct bgp_info
*ri
;
8269 struct bgp_table
*table
;
8270 json_object
*json
= NULL
;
8271 json_object
*json_paths
= NULL
;
8273 /* Check IP address argument. */
8274 ret
= str2prefix (ip_str
, &match
);
8277 vty_outln (vty
, "address is malformed");
8281 match
.family
= afi2family (afi
);
8285 json
= json_object_new_object();
8286 json_paths
= json_object_new_array();
8289 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8291 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8293 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8296 if ((table
= rn
->info
) != NULL
)
8300 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8302 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8304 bgp_unlock_node (rm
);
8308 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8312 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8313 AFI_IP
, safi
, json
);
8318 if (pathtype
== BGP_PATH_ALL
||
8319 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8320 (pathtype
== BGP_PATH_MULTIPATH
&&
8321 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8322 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8325 bgp_unlock_node (rm
);
8334 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8336 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8338 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8342 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8347 if (pathtype
== BGP_PATH_ALL
||
8348 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8349 (pathtype
== BGP_PATH_MULTIPATH
&&
8350 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8351 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8355 bgp_unlock_node (rn
);
8362 json_object_object_add(json
, "paths", json_paths
);
8364 vty_outln (vty
, "%s",
8365 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8366 json_object_free(json
);
8372 vty_outln (vty
, "%% Network not in table");
8380 /* Display specified route of Main RIB */
8382 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8383 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8384 int prefix_check
, enum bgp_path_type pathtype
,
8388 bgp
= bgp_get_default ();
8390 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8391 afi
, safi
, prd
, prefix_check
, pathtype
,
8396 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8397 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8399 struct lcommunity
*lcom
;
8405 b
= buffer_new (1024);
8406 for (i
= 0; i
< argc
; i
++)
8409 buffer_putc (b
, ' ');
8412 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8415 buffer_putstr (b
, argv
[i
]->arg
);
8419 buffer_putc (b
, '\0');
8421 str
= buffer_getstr (b
);
8424 lcom
= lcommunity_str2com (str
);
8425 XFREE (MTYPE_TMP
, str
);
8428 vty_outln (vty
, "%% Large-community malformed");
8432 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8436 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8437 afi_t afi
, safi_t safi
, u_char uj
)
8439 struct community_list
*list
;
8441 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8444 vty_outln (vty
, "%% %s is not a valid large-community-list name",lcom
);
8448 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8451 DEFUN (show_ip_bgp_large_community_list
,
8452 show_ip_bgp_large_community_list_cmd
,
8453 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8457 BGP_INSTANCE_HELP_STR
8460 "Display routes matching the large-community-list\n"
8461 "large-community-list number\n"
8462 "large-community-list name\n"
8466 afi_t afi
= AFI_IP6
;
8467 safi_t safi
= SAFI_UNICAST
;
8470 if (argv_find (argv
, argc
, "ip", &idx
))
8472 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8473 vrf
= argv
[++idx
]->arg
;
8474 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8476 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8477 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8478 safi
= bgp_vty_safi_from_str (argv
[idx
]->text
);
8481 int uj
= use_json (argc
, argv
);
8483 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8486 vty_outln (vty
, "Can't find BGP instance %s", vrf
);
8490 argv_find (argv
, argc
, "large-community-list", &idx
);
8491 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8493 DEFUN (show_ip_bgp_large_community
,
8494 show_ip_bgp_large_community_cmd
,
8495 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8499 BGP_INSTANCE_HELP_STR
8502 "Display routes matching the large-communities\n"
8503 "List of large-community numbers\n"
8507 afi_t afi
= AFI_IP6
;
8508 safi_t safi
= SAFI_UNICAST
;
8511 if (argv_find (argv
, argc
, "ip", &idx
))
8513 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8514 vrf
= argv
[++idx
]->arg
;
8515 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8517 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8518 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8519 safi
= bgp_vty_safi_from_str (argv
[idx
]->text
);
8522 int uj
= use_json (argc
, argv
);
8524 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8527 vty_outln (vty
, "Can't find BGP instance %s", vrf
);
8531 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8532 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8534 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8537 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8539 /* BGP route print out function. */
8542 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8545 |dampening <flap-statistics|dampened-paths|parameters>\
8550 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8551 |community-list <(1-500)|WORD> [exact-match]\
8552 |A.B.C.D/M longer-prefixes\
8553 |X:X::X:X/M longer-prefixes>\
8558 BGP_INSTANCE_HELP_STR
8561 "Display only routes with non-natural netmasks\n"
8562 "Display detailed information about dampening\n"
8563 "Display flap statistics of routes\n"
8564 "Display paths suppressed due to dampening\n"
8565 "Display detail of configured dampening parameters\n"
8566 "Display routes matching the route-map\n"
8567 "A route-map to match on\n"
8568 "Display routes conforming to the prefix-list\n"
8569 "Prefix-list name\n"
8570 "Display routes conforming to the filter-list\n"
8571 "Regular expression access list name\n"
8572 "BGP RIB advertisement statistics\n"
8573 "Display routes matching the communities\n"
8575 "Do not send outside local AS (well-known community)\n"
8576 "Do not advertise to any peer (well-known community)\n"
8577 "Do not export to next AS (well-known community)\n"
8578 "Exact match of the communities\n"
8579 "Display routes matching the community-list\n"
8580 "community-list number\n"
8581 "community-list name\n"
8582 "Exact match of the communities\n"
8584 "Display route and more specific routes\n"
8586 "Display route and more specific routes\n"
8589 afi_t afi
= AFI_IP6
;
8590 safi_t safi
= SAFI_UNICAST
;
8591 int exact_match
= 0;
8592 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8593 struct bgp
*bgp
= NULL
;
8596 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8600 int uj
= use_json (argc
, argv
);
8603 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8604 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8606 if (argv_find(argv
, argc
, "dampening", &idx
))
8608 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8609 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8610 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8611 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8612 else if (argv_find (argv
, argc
, "parameters", &idx
))
8613 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8616 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8617 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8619 if (argv_find(argv
, argc
, "filter-list", &idx
))
8620 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8622 if (argv_find(argv
, argc
, "statistics", &idx
))
8623 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8625 if (argv_find(argv
, argc
, "route-map", &idx
))
8626 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8628 if (argv_find(argv
, argc
, "community", &idx
))
8630 /* show a specific community */
8631 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8632 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8633 argv_find (argv
, argc
, "no-export", &idx
))
8635 if (argv_find (argv
, argc
, "exact_match", &idx
))
8637 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8639 /* show all communities */
8641 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8644 if (argv_find(argv
, argc
, "community-list", &idx
))
8646 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8647 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8649 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8652 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8653 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8655 if (safi
== SAFI_MPLS_VPN
)
8656 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8658 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8661 DEFUN (show_ip_bgp_route
,
8662 show_ip_bgp_route_cmd
,
8663 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8664 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8668 BGP_INSTANCE_HELP_STR
8671 "Network in the BGP routing table to display\n"
8673 "Network in the BGP routing table to display\n"
8675 "Display only the bestpath\n"
8676 "Display only multipaths\n"
8679 int prefix_check
= 0;
8681 afi_t afi
= AFI_IP6
;
8682 safi_t safi
= SAFI_UNICAST
;
8683 char *prefix
= NULL
;
8684 struct bgp
*bgp
= NULL
;
8685 enum bgp_path_type path_type
;
8686 u_char uj
= use_json(argc
, argv
);
8690 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8697 "Specified 'all' vrf's but this command currently only works per view/vrf");
8701 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8702 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8704 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8707 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8710 "%% Cannot specify IPv6 address or prefix with IPv4 AFI");
8713 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8716 "%% Cannot specify IPv4 address or prefix with IPv6 AFI");
8720 prefix
= argv
[idx
]->arg
;
8722 /* [<bestpath|multipath>] */
8723 if (argv_find (argv
, argc
, "bestpath", &idx
))
8724 path_type
= BGP_PATH_BESTPATH
;
8725 else if (argv_find (argv
, argc
, "multipath", &idx
))
8726 path_type
= BGP_PATH_MULTIPATH
;
8728 path_type
= BGP_PATH_ALL
;
8730 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8733 DEFUN (show_ip_bgp_regexp
,
8734 show_ip_bgp_regexp_cmd
,
8735 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8739 BGP_INSTANCE_HELP_STR
8742 "Display routes matching the AS path regular expression\n"
8743 "A regular-expression to match the BGP AS paths\n")
8745 afi_t afi
= AFI_IP6
;
8746 safi_t safi
= SAFI_UNICAST
;
8747 struct bgp
*bgp
= NULL
;
8750 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8754 // get index of regex
8755 argv_find (argv
, argc
, "regexp", &idx
);
8758 char *regstr
= argv_concat (argv
, argc
, idx
);
8759 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8760 XFREE (MTYPE_TMP
, regstr
);
8764 DEFUN (show_ip_bgp_instance_all
,
8765 show_ip_bgp_instance_all_cmd
,
8766 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8770 BGP_INSTANCE_ALL_HELP_STR
8776 safi_t safi
= SAFI_UNICAST
;
8777 struct bgp
*bgp
= NULL
;
8780 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8784 int uj
= use_json (argc
, argv
);
8787 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8792 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8793 safi_t safi
, enum bgp_show_type type
)
8798 regex
= bgp_regcomp (regstr
);
8801 vty_outln (vty
, "Can't compile regexp %s", regstr
);
8805 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8806 bgp_regex_free (regex
);
8811 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8812 const char *prefix_list_str
, afi_t afi
,
8813 safi_t safi
, enum bgp_show_type type
)
8815 struct prefix_list
*plist
;
8817 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8820 vty_outln (vty
, "%% %s is not a valid prefix-list name",
8825 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8829 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8830 const char *filter
, afi_t afi
,
8831 safi_t safi
, enum bgp_show_type type
)
8833 struct as_list
*as_list
;
8835 as_list
= as_list_lookup (filter
);
8836 if (as_list
== NULL
)
8838 vty_outln (vty
, "%% %s is not a valid AS-path access-list name",
8843 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8847 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8848 const char *rmap_str
, afi_t afi
,
8849 safi_t safi
, enum bgp_show_type type
)
8851 struct route_map
*rmap
;
8853 rmap
= route_map_lookup_by_name (rmap_str
);
8856 vty_outln (vty
, "%% %s is not a valid route-map name",
8861 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8865 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8866 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8868 struct community
*com
;
8875 b
= buffer_new (1024);
8876 for (i
= 0; i
< argc
; i
++)
8879 buffer_putc (b
, ' ');
8882 if (strmatch(argv
[i
]->text
, "unicast") || strmatch(argv
[i
]->text
, "multicast"))
8887 buffer_putstr (b
, argv
[i
]->arg
);
8889 buffer_putc (b
, '\0');
8891 str
= buffer_getstr (b
);
8894 com
= community_str2com (str
);
8895 XFREE (MTYPE_TMP
, str
);
8898 vty_outln (vty
, "%% Community malformed: ");
8902 ret
= bgp_show (vty
, bgp
, afi
, safi
,
8903 (exact
? bgp_show_type_community_exact
:
8904 bgp_show_type_community
), com
, 0);
8905 community_free (com
);
8911 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8912 const char *com
, int exact
,
8913 afi_t afi
, safi_t safi
)
8915 struct community_list
*list
;
8917 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8920 vty_outln (vty
, "%% %s is not a valid community-list name",com
);
8924 return bgp_show (vty
, bgp
, afi
, safi
,
8925 (exact
? bgp_show_type_community_list_exact
:
8926 bgp_show_type_community_list
), list
, 0);
8930 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8931 const char *prefix
, afi_t afi
,
8932 safi_t safi
, enum bgp_show_type type
)
8939 ret
= str2prefix (prefix
, p
);
8942 vty_outln (vty
, "%% Malformed Prefix");
8946 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8951 static struct peer
*
8952 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8953 const char *ip_str
, u_char use_json
)
8959 /* Get peer sockunion. */
8960 ret
= str2sockunion (ip_str
, &su
);
8963 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8966 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8972 json_object
*json_no
= NULL
;
8973 json_no
= json_object_new_object();
8974 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8975 vty_outln (vty
, "%s", json_object_to_json_string(json_no
));
8976 json_object_free(json_no
);
8979 vty_outln (vty
, "%% Malformed address or name: %s", ip_str
);
8986 /* Peer structure lookup. */
8987 peer
= peer_lookup (bgp
, &su
);
8992 json_object
*json_no
= NULL
;
8993 json_no
= json_object_new_object();
8994 json_object_string_add(json_no
, "warning","No such neighbor");
8995 vty_outln (vty
, "%s", json_object_to_json_string(json_no
));
8996 json_object_free(json_no
);
8999 vty_outln (vty
, "No such neighbor");
9008 BGP_STATS_MAXBITLEN
= 0,
9012 BGP_STATS_UNAGGREGATEABLE
,
9013 BGP_STATS_MAX_AGGREGATEABLE
,
9014 BGP_STATS_AGGREGATES
,
9016 BGP_STATS_ASPATH_COUNT
,
9017 BGP_STATS_ASPATH_MAXHOPS
,
9018 BGP_STATS_ASPATH_TOTHOPS
,
9019 BGP_STATS_ASPATH_MAXSIZE
,
9020 BGP_STATS_ASPATH_TOTSIZE
,
9021 BGP_STATS_ASN_HIGHEST
,
9025 static const char *table_stats_strs
[] =
9027 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9028 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9029 [BGP_STATS_RIB
] = "Total Advertisements",
9030 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9031 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9032 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9033 [BGP_STATS_SPACE
] = "Address space advertised",
9034 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9035 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9036 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9037 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9038 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9039 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9040 [BGP_STATS_MAX
] = NULL
,
9043 struct bgp_table_stats
9045 struct bgp_table
*table
;
9046 unsigned long long counts
[BGP_STATS_MAX
];
9050 #define TALLY_SIGFIG 100000
9051 static unsigned long
9052 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9054 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9055 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9056 unsigned long ret
= newtot
/ count
;
9058 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9066 bgp_table_stats_walker (struct thread
*t
)
9068 struct bgp_node
*rn
;
9069 struct bgp_node
*top
;
9070 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9071 unsigned int space
= 0;
9073 if (!(top
= bgp_table_top (ts
->table
)))
9076 switch (top
->p
.family
)
9079 space
= IPV4_MAX_BITLEN
;
9082 space
= IPV6_MAX_BITLEN
;
9086 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9088 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9090 struct bgp_info
*ri
;
9091 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9092 unsigned int rinum
= 0;
9100 ts
->counts
[BGP_STATS_PREFIXES
]++;
9101 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9104 ts
->counts
[BGP_STATS_AVGPLEN
]
9105 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9106 ts
->counts
[BGP_STATS_AVGPLEN
],
9110 /* check if the prefix is included by any other announcements */
9111 while (prn
&& !prn
->info
)
9112 prn
= bgp_node_parent_nolock (prn
);
9114 if (prn
== NULL
|| prn
== top
)
9116 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9117 /* announced address space */
9119 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9122 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9124 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9127 ts
->counts
[BGP_STATS_RIB
]++;
9130 (CHECK_FLAG (ri
->attr
->flag
,
9131 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9132 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9135 if (ri
->attr
&& ri
->attr
->aspath
)
9137 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9138 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9139 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9141 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9143 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9144 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9146 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9147 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9149 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9150 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9152 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9153 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9154 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9156 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9157 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9158 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9161 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9162 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9170 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9172 struct bgp_table_stats ts
;
9175 if (!bgp
->rib
[afi
][safi
])
9177 vty_outln (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)",
9182 memset (&ts
, 0, sizeof (ts
));
9183 ts
.table
= bgp
->rib
[afi
][safi
];
9184 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9186 vty_outln (vty
, "BGP %s RIB statistics%s",
9187 afi_safi_print (afi
, safi
), VTYNL
);
9189 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9191 if (!table_stats_strs
[i
])
9197 case BGP_STATS_ASPATH_AVGHOPS
:
9198 case BGP_STATS_ASPATH_AVGSIZE
:
9199 case BGP_STATS_AVGPLEN
:
9200 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9201 vty_out (vty
, "%12.2f",
9202 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9205 case BGP_STATS_ASPATH_TOTHOPS
:
9206 case BGP_STATS_ASPATH_TOTSIZE
:
9207 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9208 vty_out (vty
, "%12.2f",
9210 (float)ts
.counts
[i
] /
9211 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9214 case BGP_STATS_TOTPLEN
:
9215 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9216 vty_out (vty
, "%12.2f",
9218 (float)ts
.counts
[i
] /
9219 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9222 case BGP_STATS_SPACE
:
9223 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9224 vty_outln (vty
, "%12llu", ts
.counts
[i
]);
9225 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9227 vty_out (vty
, "%30s: ", "%% announced ");
9228 vty_outln (vty
, "%12.2f",
9229 100 * (float)ts
.counts
[BGP_STATS_SPACE
] / (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]));
9230 vty_out (vty
, "%30s: ", "/8 equivalent ");
9231 vty_outln (vty
, "%12.2f",
9232 (float)ts
.counts
[BGP_STATS_SPACE
] / (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)));
9233 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9235 vty_out (vty
, "%30s: ", "/24 equivalent ");
9236 vty_out (vty
, "%12.2f",
9237 (float)ts
.counts
[BGP_STATS_SPACE
] /
9238 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9241 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9242 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9245 vty_out (vty
, VTYNL
);
9260 PCOUNT_PFCNT
, /* the figure we display to users */
9264 static const char *pcount_strs
[] =
9266 [PCOUNT_ADJ_IN
] = "Adj-in",
9267 [PCOUNT_DAMPED
] = "Damped",
9268 [PCOUNT_REMOVED
] = "Removed",
9269 [PCOUNT_HISTORY
] = "History",
9270 [PCOUNT_STALE
] = "Stale",
9271 [PCOUNT_VALID
] = "Valid",
9272 [PCOUNT_ALL
] = "All RIB",
9273 [PCOUNT_COUNTED
] = "PfxCt counted",
9274 [PCOUNT_PFCNT
] = "Useable",
9275 [PCOUNT_MAX
] = NULL
,
9280 unsigned int count
[PCOUNT_MAX
];
9281 const struct peer
*peer
;
9282 const struct bgp_table
*table
;
9286 bgp_peer_count_walker (struct thread
*t
)
9288 struct bgp_node
*rn
;
9289 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9290 const struct peer
*peer
= pc
->peer
;
9292 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9294 struct bgp_adj_in
*ain
;
9295 struct bgp_info
*ri
;
9297 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9298 if (ain
->peer
== peer
)
9299 pc
->count
[PCOUNT_ADJ_IN
]++;
9301 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9303 char buf
[SU_ADDRSTRLEN
];
9305 if (ri
->peer
!= peer
)
9308 pc
->count
[PCOUNT_ALL
]++;
9310 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9311 pc
->count
[PCOUNT_DAMPED
]++;
9312 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9313 pc
->count
[PCOUNT_HISTORY
]++;
9314 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9315 pc
->count
[PCOUNT_REMOVED
]++;
9316 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9317 pc
->count
[PCOUNT_STALE
]++;
9318 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9319 pc
->count
[PCOUNT_VALID
]++;
9320 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9321 pc
->count
[PCOUNT_PFCNT
]++;
9323 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9325 pc
->count
[PCOUNT_COUNTED
]++;
9326 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9327 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9329 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9330 buf
, SU_ADDRSTRLEN
),
9336 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9337 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9339 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9340 buf
, SU_ADDRSTRLEN
),
9350 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9352 struct peer_pcounts pcounts
= { .peer
= peer
};
9354 json_object
*json
= NULL
;
9355 json_object
*json_loop
= NULL
;
9359 json
= json_object_new_object();
9360 json_loop
= json_object_new_object();
9363 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9364 || !peer
->bgp
->rib
[afi
][safi
])
9368 json_object_string_add(json
, "warning", "No such neighbor or address family");
9369 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9370 json_object_free(json
);
9373 vty_outln (vty
, "%% No such neighbor or address family");
9378 memset (&pcounts
, 0, sizeof(pcounts
));
9379 pcounts
.peer
= peer
;
9380 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9382 /* in-place call via thread subsystem so as to record execution time
9383 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9384 * * on just vty_read()).
9386 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9390 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9391 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9392 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9394 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9395 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9397 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9399 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9401 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9402 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9404 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9405 json_object_free(json
);
9410 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9412 vty_outln (vty
, "Prefix counts for %s/%s, %s",
9413 peer
->hostname
, peer
->host
,afi_safi_print(afi
, safi
));
9417 vty_outln (vty
, "Prefix counts for %s, %s",
9418 peer
->host
, afi_safi_print(afi
, safi
));
9421 vty_outln (vty
, "PfxCt: %ld", peer
->pcount
[afi
][safi
]);
9422 vty_outln (vty
, "%sCounts from RIB table walk:%s",
9425 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9426 vty_outln (vty
, "%20s: %-10d", pcount_strs
[i
], pcounts
.count
[i
]);
9428 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9430 vty_outln (vty
, "%s [pcount] PfxCt drift!",
9433 "Please report this bug, with the above command output");
9440 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9441 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9442 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9443 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9447 BGP_INSTANCE_HELP_STR
9450 "Address Family modifier\n"
9451 "Detailed information on TCP and BGP neighbor connections\n"
9452 "Neighbor to display information about\n"
9453 "Neighbor to display information about\n"
9454 "Neighbor on BGP configured interface\n"
9455 "Display detailed prefix count information\n"
9458 afi_t afi
= AFI_IP6
;
9459 safi_t safi
= SAFI_UNICAST
;
9462 struct bgp
*bgp
= NULL
;
9464 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9468 int uj
= use_json (argc
, argv
);
9471 argv_find (argv
, argc
, "neighbors", &idx
);
9472 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9476 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9479 #ifdef KEEP_OLD_VPN_COMMANDS
9480 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9481 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9482 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9487 "Display information about all VPNv4 NLRIs\n"
9488 "Detailed information on TCP and BGP neighbor connections\n"
9489 "Neighbor to display information about\n"
9490 "Neighbor to display information about\n"
9491 "Neighbor on BGP configured interface\n"
9492 "Display detailed prefix count information\n"
9497 u_char uj
= use_json(argc
, argv
);
9499 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9503 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9506 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9507 show_ip_bgp_vpn_all_route_prefix_cmd
,
9508 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9513 "Display information about all VPNv4 NLRIs\n"
9514 "Network in the BGP routing table to display\n"
9515 "Network in the BGP routing table to display\n"
9519 char *network
= NULL
;
9520 struct bgp
*bgp
= bgp_get_default();
9523 vty_outln (vty
, "Can't find default instance");
9527 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9528 network
= argv
[idx
]->arg
;
9529 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9530 network
= argv
[idx
]->arg
;
9533 vty_outln (vty
, "Unable to figure out Network");
9537 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9539 #endif /* KEEP_OLD_VPN_COMMANDS */
9541 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9542 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9543 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9549 "Display information about all EVPN NLRIs\n"
9550 "Network in the BGP routing table to display\n"
9551 "Network in the BGP routing table to display\n"
9555 char *network
= NULL
;
9557 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9558 network
= argv
[idx
]->arg
;
9559 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9560 network
= argv
[idx
]->arg
;
9563 vty_outln (vty
, "Unable to figure out Network");
9566 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9570 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9571 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9573 struct bgp_table
*table
;
9574 struct bgp_adj_in
*ain
;
9575 struct bgp_adj_out
*adj
;
9576 unsigned long output_count
;
9577 unsigned long filtered_count
;
9578 struct bgp_node
*rn
;
9583 struct attr_extra extra
;
9585 struct update_subgroup
*subgrp
;
9586 json_object
*json_scode
= NULL
;
9587 json_object
*json_ocode
= NULL
;
9588 json_object
*json_ar
= NULL
;
9589 struct peer_af
*paf
;
9593 json_scode
= json_object_new_object();
9594 json_ocode
= json_object_new_object();
9595 json_ar
= json_object_new_object();
9597 json_object_string_add(json_scode
, "suppressed", "s");
9598 json_object_string_add(json_scode
, "damped", "d");
9599 json_object_string_add(json_scode
, "history", "h");
9600 json_object_string_add(json_scode
, "valid", "*");
9601 json_object_string_add(json_scode
, "best", ">");
9602 json_object_string_add(json_scode
, "multipath", "=");
9603 json_object_string_add(json_scode
, "internal", "i");
9604 json_object_string_add(json_scode
, "ribFailure", "r");
9605 json_object_string_add(json_scode
, "stale", "S");
9606 json_object_string_add(json_scode
, "removed", "R");
9608 json_object_string_add(json_ocode
, "igp", "i");
9609 json_object_string_add(json_ocode
, "egp", "e");
9610 json_object_string_add(json_ocode
, "incomplete", "?");
9619 json_object_string_add(json
, "alert", "no BGP");
9620 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9621 json_object_free(json
);
9624 vty_outln (vty
, "%% No bgp");
9628 table
= bgp
->rib
[afi
][safi
];
9630 output_count
= filtered_count
= 0;
9631 subgrp
= peer_subgroup(peer
, afi
, safi
);
9633 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9637 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9638 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9639 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9640 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9641 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9645 vty_outln (vty
, "BGP table version is %" PRIu64
", local router ID is %s", table
->version
,
9646 inet_ntoa(bgp
->router_id
));
9647 vty_outln (vty
, BGP_SHOW_SCODE_HEADER
, VTYNL
);
9648 vty_outln (vty
, BGP_SHOW_OCODE_HEADER
, VTYNL
);
9650 vty_outln (vty
, "Originating default network 0.0.0.0%s",
9656 attr
.extra
= &extra
;
9657 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9661 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9663 if (ain
->peer
== peer
)
9669 json_object_int_add(json
, "bgpTableVersion", 0);
9670 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9671 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9672 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9676 vty_outln (vty
, "BGP table version is 0, local router ID is %s",
9677 inet_ntoa(bgp
->router_id
));
9678 vty_outln (vty
, BGP_SHOW_SCODE_HEADER
, VTYNL
);
9679 vty_outln (vty
, BGP_SHOW_OCODE_HEADER
, VTYNL
);
9686 vty_outln (vty
, BGP_SHOW_HEADER
);
9691 bgp_attr_dup(&attr
, ain
->attr
);
9692 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9694 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9705 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9706 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9707 if (paf
->peer
== peer
)
9713 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9714 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9715 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9716 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9720 vty_outln (vty
, "BGP table version is %" PRIu64
", local router ID is %s", table
->version
,
9721 inet_ntoa(bgp
->router_id
));
9722 vty_outln (vty
, BGP_SHOW_SCODE_HEADER
, VTYNL
);
9723 vty_outln (vty
, BGP_SHOW_OCODE_HEADER
, VTYNL
);
9731 vty_outln (vty
, BGP_SHOW_HEADER
);
9737 bgp_attr_dup(&attr
, adj
->attr
);
9738 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9739 if (ret
!= RMAP_DENY
)
9741 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9751 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9753 if (output_count
!= 0)
9756 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9758 vty_outln (vty
, "%sTotal number of prefixes %ld",
9759 VTYNL
, output_count
);
9763 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9764 json_object_free(json
);
9770 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9771 int in
, const char *rmap_name
, u_char use_json
)
9773 json_object
*json
= NULL
;
9776 json
= json_object_new_object();
9778 if (!peer
|| !peer
->afc
[afi
][safi
])
9782 json_object_string_add(json
, "warning", "No such neighbor or address family");
9783 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9784 json_object_free(json
);
9787 vty_outln (vty
, "%% No such neighbor or address family");
9792 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9796 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9797 vty_outln (vty
, "%s", json_object_to_json_string(json
));
9798 json_object_free(json
);
9801 vty_outln (vty
, "%% Inbound soft reconfiguration not enabled");
9806 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9811 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9812 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9813 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9814 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9818 BGP_INSTANCE_HELP_STR
9821 "Detailed information on TCP and BGP neighbor connections\n"
9822 "Neighbor to display information about\n"
9823 "Neighbor to display information about\n"
9824 "Neighbor on BGP configured interface\n"
9825 "Display the received routes from neighbor\n"
9826 "Display the routes advertised to a BGP neighbor\n"
9827 "Route-map to modify the attributes\n"
9828 "Name of the route map\n"
9831 afi_t afi
= AFI_IP6
;
9832 safi_t safi
= SAFI_UNICAST
;
9833 char *rmap_name
= NULL
;
9834 char *peerstr
= NULL
;
9836 struct bgp
*bgp
= NULL
;
9841 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9845 int uj
= use_json (argc
, argv
);
9848 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9849 argv_find (argv
, argc
, "neighbors", &idx
);
9850 peerstr
= argv
[++idx
]->arg
;
9852 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9856 if (argv_find (argv
, argc
, "received-routes", &idx
))
9858 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9860 if (argv_find (argv
, argc
, "route-map", &idx
))
9861 rmap_name
= argv
[++idx
]->arg
;
9863 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9866 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9867 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9868 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9874 "Address Family modifier\n"
9875 "Detailed information on TCP and BGP neighbor connections\n"
9876 "Neighbor to display information about\n"
9877 "Neighbor to display information about\n"
9878 "Neighbor on BGP configured interface\n"
9879 "Display information received from a BGP neighbor\n"
9880 "Display the prefixlist filter\n"
9883 afi_t afi
= AFI_IP6
;
9884 safi_t safi
= SAFI_UNICAST
;
9885 char *peerstr
= NULL
;
9895 if (argv_find (argv
, argc
, "ip", &idx
))
9897 /* [<ipv4|ipv6> [unicast]] */
9898 if (argv_find (argv
, argc
, "ipv4", &idx
))
9900 if (argv_find (argv
, argc
, "ipv6", &idx
))
9902 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9903 argv_find (argv
, argc
, "neighbors", &idx
);
9904 peerstr
= argv
[++idx
]->arg
;
9906 u_char uj
= use_json(argc
, argv
);
9908 ret
= str2sockunion (peerstr
, &su
);
9911 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9915 vty_outln (vty
, "{}");
9917 vty_outln (vty
, "%% Malformed address or name: %s", peerstr
);
9923 peer
= peer_lookup (NULL
, &su
);
9927 vty_outln (vty
, "{}");
9929 vty_outln (vty
, "No peer");
9934 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9935 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9939 vty_outln (vty
, "Address Family: %s", afi_safi_print(afi
, safi
));
9940 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9945 vty_outln (vty
, "{}");
9947 vty_outln (vty
, "No functional output");
9954 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9955 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9957 if (! peer
|| ! peer
->afc
[afi
][safi
])
9961 json_object
*json_no
= NULL
;
9962 json_no
= json_object_new_object();
9963 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9964 vty_outln (vty
, "%s", json_object_to_json_string(json_no
));
9965 json_object_free(json_no
);
9968 vty_outln (vty
, "%% No such neighbor or address family");
9972 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9975 DEFUN (show_ip_bgp_neighbor_routes
,
9976 show_ip_bgp_neighbor_routes_cmd
,
9977 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9978 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9982 BGP_INSTANCE_HELP_STR
9985 "Detailed information on TCP and BGP neighbor connections\n"
9986 "Neighbor to display information about\n"
9987 "Neighbor to display information about\n"
9988 "Neighbor on BGP configured interface\n"
9989 "Display flap statistics of the routes learned from neighbor\n"
9990 "Display the dampened routes received from neighbor\n"
9991 "Display routes learned from neighbor\n"
9994 char *peerstr
= NULL
;
9995 struct bgp
*bgp
= NULL
;
9996 afi_t afi
= AFI_IP6
;
9997 safi_t safi
= SAFI_UNICAST
;
9999 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10003 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10005 return CMD_WARNING
;
10007 int uj
= use_json (argc
, argv
);
10010 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10011 argv_find (argv
, argc
, "neighbors", &idx
);
10012 peerstr
= argv
[++idx
]->arg
;
10014 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10017 vty_outln (vty
, "No such neighbor");
10018 return CMD_WARNING
;
10021 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10022 sh_type
= bgp_show_type_flap_neighbor
;
10023 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10024 sh_type
= bgp_show_type_damp_neighbor
;
10025 else if (argv_find (argv
, argc
, "routes", &idx
))
10026 sh_type
= bgp_show_type_neighbor
;
10028 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10031 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10033 struct bgp_distance
10035 /* Distance value for the IP source prefix. */
10038 /* Name of the access-list to be matched. */
10042 DEFUN (show_bgp_afi_vpn_rd_route
,
10043 show_bgp_afi_vpn_rd_route_cmd
,
10044 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
10048 "Address Family modifier\n"
10049 "Display information for a route distinguisher\n"
10050 "Route Distinguisher\n"
10051 "Network in the BGP routing table to display\n"
10052 "Network in the BGP routing table to display\n"
10056 struct prefix_rd prd
;
10057 afi_t afi
= AFI_MAX
;
10060 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10061 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10064 vty_outln (vty
, "%% Malformed Route Distinguisher");
10065 return CMD_WARNING
;
10067 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10070 static struct bgp_distance
*
10071 bgp_distance_new (void)
10073 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10077 bgp_distance_free (struct bgp_distance
*bdistance
)
10079 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10083 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10084 const char *ip_str
, const char *access_list_str
)
10091 struct bgp_node
*rn
;
10092 struct bgp_distance
*bdistance
;
10094 afi
= bgp_node_afi (vty
);
10095 safi
= bgp_node_safi (vty
);
10097 ret
= str2prefix (ip_str
, &p
);
10100 vty_outln (vty
, "Malformed prefix");
10101 return CMD_WARNING
;
10104 distance
= atoi (distance_str
);
10106 /* Get BGP distance node. */
10107 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10110 bdistance
= rn
->info
;
10111 bgp_unlock_node (rn
);
10115 bdistance
= bgp_distance_new ();
10116 rn
->info
= bdistance
;
10119 /* Set distance value. */
10120 bdistance
->distance
= distance
;
10122 /* Reset access-list configuration. */
10123 if (bdistance
->access_list
)
10125 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10126 bdistance
->access_list
= NULL
;
10128 if (access_list_str
)
10129 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10131 return CMD_SUCCESS
;
10135 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10136 const char *ip_str
, const char *access_list_str
)
10143 struct bgp_node
*rn
;
10144 struct bgp_distance
*bdistance
;
10146 afi
= bgp_node_afi (vty
);
10147 safi
= bgp_node_safi (vty
);
10149 ret
= str2prefix (ip_str
, &p
);
10152 vty_outln (vty
, "Malformed prefix");
10153 return CMD_WARNING
;
10156 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10159 vty_outln (vty
, "Can't find specified prefix");
10160 return CMD_WARNING
;
10163 bdistance
= rn
->info
;
10164 distance
= atoi(distance_str
);
10166 if (bdistance
->distance
!= distance
)
10168 vty_outln (vty
, "Distance does not match configured");
10169 return CMD_WARNING
;
10172 if (bdistance
->access_list
)
10173 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10174 bgp_distance_free (bdistance
);
10177 bgp_unlock_node (rn
);
10178 bgp_unlock_node (rn
);
10180 return CMD_SUCCESS
;
10183 /* Apply BGP information to distance method. */
10185 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10186 safi_t safi
, struct bgp
*bgp
)
10188 struct bgp_node
*rn
;
10191 struct bgp_distance
*bdistance
;
10192 struct access_list
*alist
;
10193 struct bgp_static
*bgp_static
;
10198 peer
= rinfo
->peer
;
10200 /* Check source address. */
10201 sockunion2hostprefix (&peer
->su
, &q
);
10202 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10205 bdistance
= rn
->info
;
10206 bgp_unlock_node (rn
);
10208 if (bdistance
->access_list
)
10210 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10211 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10212 return bdistance
->distance
;
10215 return bdistance
->distance
;
10218 /* Backdoor check. */
10219 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10222 bgp_static
= rn
->info
;
10223 bgp_unlock_node (rn
);
10225 if (bgp_static
->backdoor
)
10227 if (bgp
->distance_local
[afi
][safi
])
10228 return bgp
->distance_local
[afi
][safi
];
10230 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10234 if (peer
->sort
== BGP_PEER_EBGP
)
10236 if (bgp
->distance_ebgp
[afi
][safi
])
10237 return bgp
->distance_ebgp
[afi
][safi
];
10238 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10242 if (bgp
->distance_ibgp
[afi
][safi
])
10243 return bgp
->distance_ibgp
[afi
][safi
];
10244 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10248 DEFUN (bgp_distance
,
10250 "distance bgp (1-255) (1-255) (1-255)",
10251 "Define an administrative distance\n"
10253 "Distance for routes external to the AS\n"
10254 "Distance for routes internal to the AS\n"
10255 "Distance for local routes\n")
10257 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10258 int idx_number
= 2;
10259 int idx_number_2
= 3;
10260 int idx_number_3
= 4;
10264 afi
= bgp_node_afi (vty
);
10265 safi
= bgp_node_safi (vty
);
10267 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10268 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10269 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10270 return CMD_SUCCESS
;
10273 DEFUN (no_bgp_distance
,
10274 no_bgp_distance_cmd
,
10275 "no distance bgp [(1-255) (1-255) (1-255)]",
10277 "Define an administrative distance\n"
10279 "Distance for routes external to the AS\n"
10280 "Distance for routes internal to the AS\n"
10281 "Distance for local routes\n")
10283 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10287 afi
= bgp_node_afi (vty
);
10288 safi
= bgp_node_safi (vty
);
10290 bgp
->distance_ebgp
[afi
][safi
] = 0;
10291 bgp
->distance_ibgp
[afi
][safi
] = 0;
10292 bgp
->distance_local
[afi
][safi
] = 0;
10293 return CMD_SUCCESS
;
10297 DEFUN (bgp_distance_source
,
10298 bgp_distance_source_cmd
,
10299 "distance (1-255) A.B.C.D/M",
10300 "Define an administrative distance\n"
10301 "Administrative distance\n"
10302 "IP source prefix\n")
10304 int idx_number
= 1;
10305 int idx_ipv4_prefixlen
= 2;
10306 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10307 return CMD_SUCCESS
;
10310 DEFUN (no_bgp_distance_source
,
10311 no_bgp_distance_source_cmd
,
10312 "no distance (1-255) A.B.C.D/M",
10314 "Define an administrative distance\n"
10315 "Administrative distance\n"
10316 "IP source prefix\n")
10318 int idx_number
= 2;
10319 int idx_ipv4_prefixlen
= 3;
10320 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10321 return CMD_SUCCESS
;
10324 DEFUN (bgp_distance_source_access_list
,
10325 bgp_distance_source_access_list_cmd
,
10326 "distance (1-255) A.B.C.D/M WORD",
10327 "Define an administrative distance\n"
10328 "Administrative distance\n"
10329 "IP source prefix\n"
10330 "Access list name\n")
10332 int idx_number
= 1;
10333 int idx_ipv4_prefixlen
= 2;
10335 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10336 return CMD_SUCCESS
;
10339 DEFUN (no_bgp_distance_source_access_list
,
10340 no_bgp_distance_source_access_list_cmd
,
10341 "no distance (1-255) A.B.C.D/M WORD",
10343 "Define an administrative distance\n"
10344 "Administrative distance\n"
10345 "IP source prefix\n"
10346 "Access list name\n")
10348 int idx_number
= 2;
10349 int idx_ipv4_prefixlen
= 3;
10351 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10352 return CMD_SUCCESS
;
10355 DEFUN (ipv6_bgp_distance_source
,
10356 ipv6_bgp_distance_source_cmd
,
10357 "distance (1-255) X:X::X:X/M",
10358 "Define an administrative distance\n"
10359 "Administrative distance\n"
10360 "IP source prefix\n")
10362 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10363 return CMD_SUCCESS
;
10366 DEFUN (no_ipv6_bgp_distance_source
,
10367 no_ipv6_bgp_distance_source_cmd
,
10368 "no distance (1-255) X:X::X:X/M",
10370 "Define an administrative distance\n"
10371 "Administrative distance\n"
10372 "IP source prefix\n")
10374 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10375 return CMD_SUCCESS
;
10378 DEFUN (ipv6_bgp_distance_source_access_list
,
10379 ipv6_bgp_distance_source_access_list_cmd
,
10380 "distance (1-255) X:X::X:X/M WORD",
10381 "Define an administrative distance\n"
10382 "Administrative distance\n"
10383 "IP source prefix\n"
10384 "Access list name\n")
10386 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10387 return CMD_SUCCESS
;
10390 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10391 no_ipv6_bgp_distance_source_access_list_cmd
,
10392 "no distance (1-255) X:X::X:X/M WORD",
10394 "Define an administrative distance\n"
10395 "Administrative distance\n"
10396 "IP source prefix\n"
10397 "Access list name\n")
10399 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10400 return CMD_SUCCESS
;
10403 DEFUN (bgp_damp_set
,
10405 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10406 "BGP Specific commands\n"
10407 "Enable route-flap dampening\n"
10408 "Half-life time for the penalty\n"
10409 "Value to start reusing a route\n"
10410 "Value to start suppressing a route\n"
10411 "Maximum duration to suppress a stable route\n")
10413 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10414 int idx_half_life
= 2;
10416 int idx_suppress
= 4;
10417 int idx_max_suppress
= 5;
10418 int half
= DEFAULT_HALF_LIFE
* 60;
10419 int reuse
= DEFAULT_REUSE
;
10420 int suppress
= DEFAULT_SUPPRESS
;
10421 int max
= 4 * half
;
10425 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10426 reuse
= atoi (argv
[idx_reuse
]->arg
);
10427 suppress
= atoi (argv
[idx_suppress
]->arg
);
10428 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10430 else if (argc
== 3)
10432 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10436 if (suppress
< reuse
)
10438 vty_outln (vty
,"Suppress value cannot be less than reuse value ");
10442 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10443 half
, reuse
, suppress
, max
);
10446 DEFUN (bgp_damp_unset
,
10447 bgp_damp_unset_cmd
,
10448 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10450 "BGP Specific commands\n"
10451 "Enable route-flap dampening\n"
10452 "Half-life time for the penalty\n"
10453 "Value to start reusing a route\n"
10454 "Value to start suppressing a route\n"
10455 "Maximum duration to suppress a stable route\n")
10457 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10458 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10461 /* Display specified route of BGP table. */
10463 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10464 const char *ip_str
, afi_t afi
, safi_t safi
,
10465 struct prefix_rd
*prd
, int prefix_check
)
10468 struct prefix match
;
10469 struct bgp_node
*rn
;
10470 struct bgp_node
*rm
;
10471 struct bgp_info
*ri
;
10472 struct bgp_info
*ri_temp
;
10474 struct bgp_table
*table
;
10476 /* BGP structure lookup. */
10479 bgp
= bgp_lookup_by_name (view_name
);
10482 vty_outln (vty
, "%% Can't find BGP instance %s", view_name
);
10483 return CMD_WARNING
;
10488 bgp
= bgp_get_default ();
10491 vty_outln (vty
, "%% No BGP process is configured");
10492 return CMD_WARNING
;
10496 /* Check IP address argument. */
10497 ret
= str2prefix (ip_str
, &match
);
10500 vty_outln (vty
, "%% address is malformed");
10501 return CMD_WARNING
;
10504 match
.family
= afi2family (afi
);
10506 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10508 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10510 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10513 if ((table
= rn
->info
) != NULL
)
10514 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10516 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10521 if (ri
->extra
&& ri
->extra
->damp_info
)
10523 ri_temp
= ri
->next
;
10524 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10532 bgp_unlock_node (rm
);
10538 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10540 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10545 if (ri
->extra
&& ri
->extra
->damp_info
)
10547 ri_temp
= ri
->next
;
10548 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10556 bgp_unlock_node (rn
);
10560 return CMD_SUCCESS
;
10563 DEFUN (clear_ip_bgp_dampening
,
10564 clear_ip_bgp_dampening_cmd
,
10565 "clear ip bgp dampening",
10569 "Clear route flap dampening information\n")
10571 bgp_damp_info_clean ();
10572 return CMD_SUCCESS
;
10575 DEFUN (clear_ip_bgp_dampening_prefix
,
10576 clear_ip_bgp_dampening_prefix_cmd
,
10577 "clear ip bgp dampening A.B.C.D/M",
10581 "Clear route flap dampening information\n"
10584 int idx_ipv4_prefixlen
= 4;
10585 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10586 SAFI_UNICAST
, NULL
, 1);
10589 DEFUN (clear_ip_bgp_dampening_address
,
10590 clear_ip_bgp_dampening_address_cmd
,
10591 "clear ip bgp dampening A.B.C.D",
10595 "Clear route flap dampening information\n"
10596 "Network to clear damping information\n")
10599 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10600 SAFI_UNICAST
, NULL
, 0);
10603 DEFUN (clear_ip_bgp_dampening_address_mask
,
10604 clear_ip_bgp_dampening_address_mask_cmd
,
10605 "clear ip bgp dampening A.B.C.D A.B.C.D",
10609 "Clear route flap dampening information\n"
10610 "Network to clear damping information\n"
10614 int idx_ipv4_2
= 5;
10616 char prefix_str
[BUFSIZ
];
10618 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10621 vty_outln (vty
, "%% Inconsistent address and mask");
10622 return CMD_WARNING
;
10625 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10626 SAFI_UNICAST
, NULL
, 0);
10629 /* also used for encap safi */
10631 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10632 afi_t afi
, safi_t safi
, int *write
)
10634 struct bgp_node
*prn
;
10635 struct bgp_node
*rn
;
10636 struct bgp_table
*table
;
10638 struct prefix_rd
*prd
;
10639 struct bgp_static
*bgp_static
;
10640 mpls_label_t label
;
10641 char buf
[SU_ADDRSTRLEN
];
10642 char rdbuf
[RD_ADDRSTRLEN
];
10644 /* Network configuration. */
10645 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10646 if ((table
= prn
->info
) != NULL
)
10647 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10648 if ((bgp_static
= rn
->info
) != NULL
)
10651 prd
= (struct prefix_rd
*) &prn
->p
;
10653 /* "address-family" display. */
10654 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10656 /* "network" configuration display. */
10657 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10658 label
= decode_label (&bgp_static
->label
);
10660 vty_out (vty
, " network %s/%d rd %s",
10661 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10662 p
->prefixlen
, rdbuf
);
10663 if (safi
== SAFI_MPLS_VPN
)
10664 vty_out (vty
, " label %u", label
);
10666 if (bgp_static
->rmap
.name
)
10667 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10670 if (bgp_static
->backdoor
)
10671 vty_out (vty
, " backdoor");
10673 vty_out (vty
, VTYNL
);
10679 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10680 afi_t afi
, safi_t safi
, int *write
)
10682 struct bgp_node
*prn
;
10683 struct bgp_node
*rn
;
10684 struct bgp_table
*table
;
10686 struct prefix_rd
*prd
;
10687 struct bgp_static
*bgp_static
;
10688 char buf
[PREFIX_STRLEN
];
10689 char buf2
[SU_ADDRSTRLEN
];
10690 char rdbuf
[RD_ADDRSTRLEN
];
10692 /* Network configuration. */
10693 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10694 if ((table
= prn
->info
) != NULL
)
10695 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10696 if ((bgp_static
= rn
->info
) != NULL
)
10698 char *macrouter
= NULL
;
10701 if(bgp_static
->router_mac
)
10702 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10703 if(bgp_static
->eth_s_id
)
10704 esi
= esi2str(bgp_static
->eth_s_id
);
10706 prd
= (struct prefix_rd
*) &prn
->p
;
10708 /* "address-family" display. */
10709 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10711 /* "network" configuration display. */
10712 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10714 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10716 prefix2str (p
, buf
, sizeof (buf
)),
10717 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10718 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10719 decode_label (&bgp_static
->label
), esi
, buf2
, macrouter
);
10720 vty_out (vty
, VTYNL
);
10722 XFREE (MTYPE_TMP
, macrouter
);
10724 XFREE (MTYPE_TMP
, esi
);
10729 /* Configuration of static route announcement and aggregate
10732 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10733 afi_t afi
, safi_t safi
, int *write
)
10735 struct bgp_node
*rn
;
10737 struct bgp_static
*bgp_static
;
10738 struct bgp_aggregate
*bgp_aggregate
;
10739 char buf
[SU_ADDRSTRLEN
];
10741 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10742 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10744 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10745 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10747 /* Network configuration. */
10748 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10749 if ((bgp_static
= rn
->info
) != NULL
)
10753 /* "address-family" display. */
10754 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10756 /* "network" configuration display. */
10757 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10759 u_int32_t destination
;
10760 struct in_addr netmask
;
10762 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10763 masklen2ip (p
->prefixlen
, &netmask
);
10764 vty_out (vty
, " network %s",
10765 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10767 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10768 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10769 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10770 || p
->u
.prefix4
.s_addr
== 0)
10772 /* Natural mask is not display. */
10775 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10779 vty_out (vty
, " network %s/%d",
10780 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10784 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10785 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10787 if (bgp_static
->rmap
.name
)
10788 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10791 if (bgp_static
->backdoor
)
10792 vty_out (vty
, " backdoor");
10795 vty_out (vty
, VTYNL
);
10798 /* Aggregate-address configuration. */
10799 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10800 if ((bgp_aggregate
= rn
->info
) != NULL
)
10804 /* "address-family" display. */
10805 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10807 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10809 struct in_addr netmask
;
10811 masklen2ip (p
->prefixlen
, &netmask
);
10812 vty_out (vty
, " aggregate-address %s %s",
10813 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10814 inet_ntoa (netmask
));
10818 vty_out (vty
, " aggregate-address %s/%d",
10819 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10823 if (bgp_aggregate
->as_set
)
10824 vty_out (vty
, " as-set");
10826 if (bgp_aggregate
->summary_only
)
10827 vty_out (vty
, " summary-only");
10829 vty_out (vty
, VTYNL
);
10836 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10837 safi_t safi
, int *write
)
10839 struct bgp_node
*rn
;
10840 struct bgp_distance
*bdistance
;
10842 /* Distance configuration. */
10843 if (bgp
->distance_ebgp
[afi
][safi
]
10844 && bgp
->distance_ibgp
[afi
][safi
]
10845 && bgp
->distance_local
[afi
][safi
]
10846 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10847 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10848 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10850 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10851 vty_outln (vty
, " distance bgp %d %d %d",
10852 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10853 bgp
->distance_local
[afi
][safi
]);
10856 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10857 rn
= bgp_route_next (rn
))
10858 if ((bdistance
= rn
->info
) != NULL
)
10860 char buf
[PREFIX_STRLEN
];
10862 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10863 vty_outln (vty
, " distance %d %s %s", bdistance
->distance
,
10864 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10865 bdistance
->access_list
? bdistance
->access_list
: "");
10871 /* Allocate routing table structure and install commands. */
10873 bgp_route_init (void)
10878 /* Init BGP distance table. */
10879 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10880 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10881 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10883 /* IPv4 BGP commands. */
10884 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10885 install_element (BGP_NODE
, &bgp_network_cmd
);
10886 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10887 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10888 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10889 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10890 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10891 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10892 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10893 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10894 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10895 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10896 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10897 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10899 install_element (BGP_NODE
, &aggregate_address_cmd
);
10900 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10901 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10902 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10904 /* IPv4 unicast configuration. */
10905 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10906 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10907 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10908 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10909 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10910 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10911 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10912 install_element (BGP_IPV4_NODE
, &bgp_network_label_index_cmd
);
10913 install_element (BGP_IPV4_NODE
, &bgp_network_label_index_route_map_cmd
);
10914 install_element (BGP_IPV4_NODE
, &no_bgp_network_label_index_cmd
);
10915 install_element (BGP_IPV4_NODE
, &no_bgp_network_label_index_route_map_cmd
);
10916 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10917 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10918 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10919 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10921 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10922 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10923 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10924 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10926 /* IPv4 multicast configuration. */
10927 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10928 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10929 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10930 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10931 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10932 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10933 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10934 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10935 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10936 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10937 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10938 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10939 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10940 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10941 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10943 /* IPv4 labeled-unicast configuration. */
10944 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10945 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10946 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10947 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10949 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10950 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10951 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10952 #ifdef KEEP_OLD_VPN_COMMANDS
10953 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10954 #endif /* KEEP_OLD_VPN_COMMANDS */
10955 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10956 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10958 /* BGP dampening clear commands */
10959 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10960 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10962 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10963 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10966 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10967 #ifdef KEEP_OLD_VPN_COMMANDS
10968 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10969 #endif /* KEEP_OLD_VPN_COMMANDS */
10971 /* New config IPv6 BGP commands. */
10972 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10973 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10974 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10975 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10976 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10977 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
10978 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
10979 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
10980 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
10982 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10983 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10985 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10986 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10988 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
10989 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
10990 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
10991 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
10992 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
10994 install_element (BGP_NODE
, &bgp_distance_cmd
);
10995 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10996 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10997 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10998 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10999 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11000 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11001 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11002 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11003 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11004 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11005 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11006 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11007 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11008 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11009 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11010 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11011 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11012 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11013 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11014 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11015 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11016 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11017 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11018 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11019 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11020 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11021 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11022 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11023 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11025 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11026 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11027 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11028 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11030 /* IPv4 Multicast Mode */
11031 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11032 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11034 /* Large Communities */
11035 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11036 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11040 bgp_route_finish (void)
11045 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11046 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11048 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11049 bgp_distance_table
[afi
][safi
] = NULL
;