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
) ||
114 bgp_afi_node_lookup (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
115 struct prefix_rd
*prd
)
118 struct bgp_node
*prn
= NULL
;
123 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
125 prn
= bgp_node_lookup (table
, (struct prefix
*) prd
);
129 if (prn
->info
== NULL
)
131 bgp_unlock_node (prn
);
138 rn
= bgp_node_lookup (table
, p
);
143 /* Allocate bgp_info_extra */
144 static struct bgp_info_extra
*
145 bgp_info_extra_new (void)
147 struct bgp_info_extra
*new;
148 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
149 new->label
= MPLS_INVALID_LABEL
;
154 bgp_info_extra_free (struct bgp_info_extra
**extra
)
158 if ((*extra
)->damp_info
)
159 bgp_damp_info_free ((*extra
)->damp_info
, 0);
161 (*extra
)->damp_info
= NULL
;
163 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
169 /* Get bgp_info extra information for the given bgp_info, lazy allocated
172 struct bgp_info_extra
*
173 bgp_info_extra_get (struct bgp_info
*ri
)
176 ri
->extra
= bgp_info_extra_new();
180 /* Allocate new bgp info structure. */
184 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
187 /* Free bgp route information. */
189 bgp_info_free (struct bgp_info
*binfo
)
192 bgp_attr_unintern (&binfo
->attr
);
194 bgp_unlink_nexthop(binfo
);
195 bgp_info_extra_free (&binfo
->extra
);
196 bgp_info_mpath_free (&binfo
->mpath
);
198 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
200 XFREE (MTYPE_BGP_ROUTE
, binfo
);
204 bgp_info_lock (struct bgp_info
*binfo
)
211 bgp_info_unlock (struct bgp_info
*binfo
)
213 assert (binfo
&& binfo
->lock
> 0);
216 if (binfo
->lock
== 0)
219 zlog_debug ("%s: unlocked and freeing", __func__
);
220 zlog_backtrace (LOG_DEBUG
);
222 bgp_info_free (binfo
);
227 if (binfo
->lock
== 1)
229 zlog_debug ("%s: unlocked to 1", __func__
);
230 zlog_backtrace (LOG_DEBUG
);
238 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
240 struct bgp_info
*top
;
252 peer_lock (ri
->peer
); /* bgp_info peer reference */
255 /* Do the actual removal of info from RIB, for use by bgp_process
256 completion callback *only* */
258 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
261 ri
->next
->prev
= ri
->prev
;
263 ri
->prev
->next
= ri
->next
;
267 bgp_info_mpath_dequeue (ri
);
268 bgp_info_unlock (ri
);
269 bgp_unlock_node (rn
);
273 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
275 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
276 /* set of previous already took care of pcount */
277 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
280 /* undo the effects of a previous call to bgp_info_delete; typically
281 called when a route is deleted and then quickly re-added before the
282 deletion has been processed */
284 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
286 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
287 /* unset of previous already took care of pcount */
288 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
291 /* Adjust pcount as required */
293 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
295 struct bgp_table
*table
;
297 assert (rn
&& bgp_node_table (rn
));
298 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
300 table
= bgp_node_table (rn
);
302 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
305 if (!BGP_INFO_COUNTABLE (ri
)
306 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
309 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
311 /* slight hack, but more robust against errors. */
312 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
313 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
316 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
317 __func__
, ri
->peer
->host
);
318 zlog_backtrace (LOG_WARNING
);
319 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
322 else if (BGP_INFO_COUNTABLE (ri
)
323 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
325 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
326 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
331 bgp_label_index_differs (struct bgp_info
*ri1
, struct bgp_info
*ri2
)
333 return (!(ri1
->attr
->label_index
== ri2
->attr
->label_index
));
336 /* Set/unset bgp_info flags, adjusting any other state as needed.
337 * This is here primarily to keep prefix-count in check.
340 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
342 SET_FLAG (ri
->flags
, flag
);
344 /* early bath if we know it's not a flag that changes countability state */
345 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
348 bgp_pcount_adjust (rn
, ri
);
352 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
354 UNSET_FLAG (ri
->flags
, flag
);
356 /* early bath if we know it's not a flag that changes countability state */
357 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
360 bgp_pcount_adjust (rn
, ri
);
363 /* Get MED value. If MED value is missing and "bgp bestpath
364 missing-as-worst" is specified, treat it as the worst value. */
366 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
368 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
372 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
380 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
382 if (ri
->addpath_rx_id
)
383 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
385 sprintf(buf
, "path %s", ri
->peer
->host
);
388 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
390 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
391 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
392 char *pfx_buf
, afi_t afi
, safi_t safi
)
394 struct attr
*newattr
, *existattr
;
395 bgp_peer_sort_t new_sort
;
396 bgp_peer_sort_t exist_sort
;
398 u_int32_t exist_pref
;
401 u_int32_t new_weight
;
402 u_int32_t exist_weight
;
403 uint32_t newm
, existm
;
404 struct in_addr new_id
;
405 struct in_addr exist_id
;
408 int internal_as_route
;
411 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
412 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
413 u_int32_t new_mm_seq
;
414 u_int32_t exist_mm_seq
;
422 zlog_debug("%s: new is NULL", pfx_buf
);
427 bgp_info_path_with_addpath_rx_str (new, new_buf
);
432 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
438 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
439 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
440 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
444 existattr
= exist
->attr
;
446 /* For EVPN routes, we cannot just go by local vs remote, we have to
447 * look at the MAC mobility sequence number, if present.
449 if (safi
== SAFI_EVPN
)
451 /* This is an error condition described in RFC 7432 Section 15.2. The RFC
452 * states that in this scenario "the PE MUST alert the operator" but it
453 * does not state what other action to take. In order to provide some
454 * consistency in this scenario we are going to prefer the path with the
457 if (newattr
->sticky
!= existattr
->sticky
)
461 prefix2str (&new->net
->p
, pfx_buf
, sizeof (*pfx_buf
) * PREFIX2STR_BUFFER
);
462 bgp_info_path_with_addpath_rx_str (new, new_buf
);
463 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
466 if (newattr
->sticky
&& !existattr
->sticky
)
468 zlog_warn("%s: %s wins over %s due to sticky MAC flag",
469 pfx_buf
, new_buf
, exist_buf
);
473 if (!newattr
->sticky
&& existattr
->sticky
)
475 zlog_warn("%s: %s loses to %s due to sticky MAC flag",
476 pfx_buf
, new_buf
, exist_buf
);
481 new_mm_seq
= mac_mobility_seqnum (newattr
);
482 exist_mm_seq
= mac_mobility_seqnum (existattr
);
484 if (new_mm_seq
> exist_mm_seq
)
487 zlog_debug("%s: %s wins over %s due to MM seq %u > %u",
488 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
, exist_mm_seq
);
492 if (new_mm_seq
< exist_mm_seq
)
495 zlog_debug("%s: %s loses to %s due to MM seq %u < %u",
496 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
, exist_mm_seq
);
501 /* 1. Weight check. */
502 new_weight
= exist_weight
= 0;
504 new_weight
= newattr
->weight
;
505 exist_weight
= existattr
->weight
;
507 if (new_weight
> exist_weight
)
510 zlog_debug("%s: %s wins over %s due to weight %d > %d",
511 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
515 if (new_weight
< exist_weight
)
518 zlog_debug("%s: %s loses to %s due to weight %d < %d",
519 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
523 /* 2. Local preference check. */
524 new_pref
= exist_pref
= bgp
->default_local_pref
;
526 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
527 new_pref
= newattr
->local_pref
;
528 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
529 exist_pref
= existattr
->local_pref
;
531 if (new_pref
> exist_pref
)
534 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
535 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
539 if (new_pref
< exist_pref
)
542 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
543 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
547 /* 3. Local route check. We prefer:
549 * - BGP_ROUTE_AGGREGATE
550 * - BGP_ROUTE_REDISTRIBUTE
552 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
555 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
556 pfx_buf
, new_buf
, exist_buf
);
560 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
563 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
564 pfx_buf
, new_buf
, exist_buf
);
568 /* 4. AS path length check. */
569 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
571 int exist_hops
= aspath_count_hops (existattr
->aspath
);
572 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
574 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
578 aspath_hops
= aspath_count_hops (newattr
->aspath
);
579 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
581 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
584 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
585 pfx_buf
, new_buf
, exist_buf
,
586 aspath_hops
, (exist_hops
+ exist_confeds
));
590 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
593 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
594 pfx_buf
, new_buf
, exist_buf
,
595 aspath_hops
, (exist_hops
+ exist_confeds
));
601 int newhops
= aspath_count_hops (newattr
->aspath
);
603 if (newhops
< exist_hops
)
606 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
607 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
611 if (newhops
> exist_hops
)
614 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
615 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
621 /* 5. Origin check. */
622 if (newattr
->origin
< existattr
->origin
)
625 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
626 pfx_buf
, new_buf
, exist_buf
,
627 bgp_origin_long_str
[newattr
->origin
],
628 bgp_origin_long_str
[existattr
->origin
]);
632 if (newattr
->origin
> existattr
->origin
)
635 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
636 pfx_buf
, new_buf
, exist_buf
,
637 bgp_origin_long_str
[newattr
->origin
],
638 bgp_origin_long_str
[existattr
->origin
]);
643 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
644 && aspath_count_hops (existattr
->aspath
) == 0);
645 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
646 && aspath_count_confeds (existattr
->aspath
) > 0
647 && aspath_count_hops (newattr
->aspath
) == 0
648 && aspath_count_hops (existattr
->aspath
) == 0);
650 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
651 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
653 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
654 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
655 || internal_as_route
)
657 new_med
= bgp_med_value (new->attr
, bgp
);
658 exist_med
= bgp_med_value (exist
->attr
, bgp
);
660 if (new_med
< exist_med
)
663 zlog_debug("%s: %s wins over %s due to MED %d < %d",
664 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
668 if (new_med
> exist_med
)
671 zlog_debug("%s: %s loses to %s due to MED %d > %d",
672 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
677 /* 7. Peer type check. */
678 new_sort
= new->peer
->sort
;
679 exist_sort
= exist
->peer
->sort
;
681 if (new_sort
== BGP_PEER_EBGP
682 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
685 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
686 pfx_buf
, new_buf
, exist_buf
);
690 if (exist_sort
== BGP_PEER_EBGP
691 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
694 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
695 pfx_buf
, new_buf
, exist_buf
);
699 /* 8. IGP metric check. */
703 newm
= new->extra
->igpmetric
;
705 existm
= exist
->extra
->igpmetric
;
710 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
711 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
718 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
719 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
723 /* 9. Same IGP metric. Compare the cluster list length as
724 representative of IGP hops metric. Rewrite the metric value
725 pair (newm, existm) with the cluster list length. Prefer the
726 path with smaller cluster list length. */
729 if (peer_sort (new->peer
) == BGP_PEER_IBGP
730 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
731 && (mpath_cfg
== NULL
||
732 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
733 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
735 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
736 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
741 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
742 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
749 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
750 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
756 /* 10. confed-external vs. confed-internal */
757 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
759 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
762 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
763 pfx_buf
, new_buf
, exist_buf
);
767 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
770 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
771 pfx_buf
, new_buf
, exist_buf
);
776 /* 11. Maximum path check. */
779 /* If one path has a label but the other does not, do not treat
780 * them as equals for multipath
782 if ((new->extra
&& bgp_is_valid_label(&new->extra
->label
)) !=
783 (exist
->extra
&& bgp_is_valid_label(&exist
->extra
->label
)))
786 zlog_debug("%s: %s and %s cannot be multipath, one has a label while the other does not",
787 pfx_buf
, new_buf
, exist_buf
);
789 else if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
793 * For the two paths, all comparison steps till IGP metric
794 * have succeeded - including AS_PATH hop count. Since 'bgp
795 * bestpath as-path multipath-relax' knob is on, we don't need
796 * an exact match of AS_PATH. Thus, mark the paths are equal.
797 * That will trigger both these paths to get into the multipath
803 zlog_debug("%s: %s and %s are equal via multipath-relax",
804 pfx_buf
, new_buf
, exist_buf
);
806 else if (new->peer
->sort
== BGP_PEER_IBGP
)
808 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
813 zlog_debug("%s: %s and %s are equal via matching aspaths",
814 pfx_buf
, new_buf
, exist_buf
);
817 else if (new->peer
->as
== exist
->peer
->as
)
822 zlog_debug("%s: %s and %s are equal via same remote-as",
823 pfx_buf
, new_buf
, exist_buf
);
829 * TODO: If unequal cost ibgp multipath is enabled we can
830 * mark the paths as equal here instead of returning
835 zlog_debug("%s: %s wins over %s after IGP metric comparison",
836 pfx_buf
, new_buf
, exist_buf
);
838 zlog_debug("%s: %s loses to %s after IGP metric comparison",
839 pfx_buf
, new_buf
, exist_buf
);
844 /* 12. If both paths are external, prefer the path that was received
845 first (the oldest one). This step minimizes route-flap, since a
846 newer path won't displace an older one, even if it was the
847 preferred route based on the additional decision criteria below. */
848 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
849 && new_sort
== BGP_PEER_EBGP
850 && exist_sort
== BGP_PEER_EBGP
)
852 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
855 zlog_debug("%s: %s wins over %s due to oldest external",
856 pfx_buf
, new_buf
, exist_buf
);
860 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
863 zlog_debug("%s: %s loses to %s due to oldest external",
864 pfx_buf
, new_buf
, exist_buf
);
869 /* 13. Router-ID comparision. */
870 /* If one of the paths is "stale", the corresponding peer router-id will
871 * be 0 and would always win over the other path. If originator id is
872 * used for the comparision, it will decide which path is better.
874 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
875 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
877 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
878 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
879 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
881 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
883 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
886 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
887 pfx_buf
, new_buf
, exist_buf
);
891 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
894 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
895 pfx_buf
, new_buf
, exist_buf
);
899 /* 14. Cluster length comparision. */
900 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
901 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
903 if (new_cluster
< exist_cluster
)
906 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
907 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
911 if (new_cluster
> exist_cluster
)
914 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
915 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
919 /* 15. Neighbor address comparision. */
920 /* Do this only if neither path is "stale" as stale paths do not have
921 * valid peer information (as the connection may or may not be up).
923 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
926 zlog_debug("%s: %s wins over %s due to latter path being STALE",
927 pfx_buf
, new_buf
, exist_buf
);
931 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
934 zlog_debug("%s: %s loses to %s due to former path being STALE",
935 pfx_buf
, new_buf
, exist_buf
);
939 /* locally configured routes to advertise do not have su_remote */
940 if (new->peer
->su_remote
== NULL
)
942 if (exist
->peer
->su_remote
== NULL
)
945 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
950 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
951 pfx_buf
, new_buf
, exist_buf
);
958 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
959 pfx_buf
, new_buf
, exist_buf
);
964 zlog_debug("%s: %s wins over %s due to nothing left to compare",
965 pfx_buf
, new_buf
, exist_buf
);
970 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
971 * is preferred, or 0 if they are the same (usually will only occur if
972 * multipath is enabled
973 * This version is compatible with */
975 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
976 char *pfx_buf
, afi_t afi
, safi_t safi
)
980 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0,
995 static enum filter_type
996 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
997 afi_t afi
, safi_t safi
)
999 struct bgp_filter
*filter
;
1001 filter
= &peer
->filter
[afi
][safi
];
1003 #define FILTER_EXIST_WARN(F,f,filter) \
1004 if (BGP_DEBUG (update, UPDATE_IN) \
1005 && !(F ## _IN (filter))) \
1006 zlog_warn ("%s: Could not find configured input %s-list %s!", \
1007 peer->host, #f, F ## _IN_NAME(filter));
1009 if (DISTRIBUTE_IN_NAME (filter
)) {
1010 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1012 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
1016 if (PREFIX_LIST_IN_NAME (filter
)) {
1017 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1019 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
1023 if (FILTER_LIST_IN_NAME (filter
)) {
1024 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1026 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
1030 return FILTER_PERMIT
;
1031 #undef FILTER_EXIST_WARN
1034 static enum filter_type
1035 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1036 afi_t afi
, safi_t safi
)
1038 struct bgp_filter
*filter
;
1040 filter
= &peer
->filter
[afi
][safi
];
1042 #define FILTER_EXIST_WARN(F,f,filter) \
1043 if (BGP_DEBUG (update, UPDATE_OUT) \
1044 && !(F ## _OUT (filter))) \
1045 zlog_warn ("%s: Could not find configured output %s-list %s!", \
1046 peer->host, #f, F ## _OUT_NAME(filter));
1048 if (DISTRIBUTE_OUT_NAME (filter
)) {
1049 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1051 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
1055 if (PREFIX_LIST_OUT_NAME (filter
)) {
1056 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1058 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
1062 if (FILTER_LIST_OUT_NAME (filter
)) {
1063 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1065 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
1069 return FILTER_PERMIT
;
1070 #undef FILTER_EXIST_WARN
1073 /* If community attribute includes no_export then return 1. */
1075 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
1077 if (attr
->community
)
1079 /* NO_ADVERTISE check. */
1080 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
1083 /* NO_EXPORT check. */
1084 if (peer
->sort
== BGP_PEER_EBGP
&&
1085 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
1088 /* NO_EXPORT_SUBCONFED check. */
1089 if (peer
->sort
== BGP_PEER_EBGP
1090 || peer
->sort
== BGP_PEER_CONFED
)
1091 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
1097 /* Route reflection loop check. */
1099 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1101 struct in_addr cluster_id
;
1105 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1106 cluster_id
= peer
->bgp
->cluster_id
;
1108 cluster_id
= peer
->bgp
->router_id
;
1110 if (cluster_loop_check (attr
->cluster
, cluster_id
))
1117 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1118 afi_t afi
, safi_t safi
, const char *rmap_name
)
1120 struct bgp_filter
*filter
;
1121 struct bgp_info info
;
1122 route_map_result_t ret
;
1123 struct route_map
*rmap
= NULL
;
1125 filter
= &peer
->filter
[afi
][safi
];
1127 /* Apply default weight value. */
1128 if (peer
->weight
[afi
][safi
])
1129 attr
->weight
= peer
->weight
[afi
][safi
];
1133 rmap
= route_map_lookup_by_name(rmap_name
);
1140 if (ROUTE_MAP_IN_NAME(filter
))
1142 rmap
= ROUTE_MAP_IN (filter
);
1149 /* Route map apply. */
1152 /* Duplicate current value to new strucutre for modification. */
1156 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1158 /* Apply BGP route map to the attribute. */
1159 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1161 peer
->rmap_type
= 0;
1163 if (ret
== RMAP_DENYMATCH
)
1165 /* Free newly generated AS path and community by route-map. */
1166 bgp_attr_flush (attr
);
1174 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1175 afi_t afi
, safi_t safi
, const char *rmap_name
)
1177 struct bgp_filter
*filter
;
1178 struct bgp_info info
;
1179 route_map_result_t ret
;
1180 struct route_map
*rmap
= NULL
;
1182 filter
= &peer
->filter
[afi
][safi
];
1184 /* Apply default weight value. */
1185 if (peer
->weight
[afi
][safi
])
1186 attr
->weight
= peer
->weight
[afi
][safi
];
1190 rmap
= route_map_lookup_by_name(rmap_name
);
1197 if (ROUTE_MAP_OUT_NAME(filter
))
1199 rmap
= ROUTE_MAP_OUT (filter
);
1206 /* Route map apply. */
1209 /* Duplicate current value to new strucutre for modification. */
1213 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1215 /* Apply BGP route map to the attribute. */
1216 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1218 peer
->rmap_type
= 0;
1220 if (ret
== RMAP_DENYMATCH
)
1221 /* caller has multiple error paths with bgp_attr_flush() */
1227 /* If this is an EBGP peer with remove-private-AS */
1229 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1230 struct peer
*peer
, struct attr
*attr
)
1232 if (peer
->sort
== BGP_PEER_EBGP
&&
1233 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1234 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1235 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1236 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1238 // Take action on the entire aspath
1239 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1240 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1242 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1243 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1245 // The entire aspath consists of private ASNs so create an empty aspath
1246 else if (aspath_private_as_check (attr
->aspath
))
1247 attr
->aspath
= aspath_empty_get ();
1249 // There are some public and some private ASNs, remove the private ASNs
1251 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1254 // 'all' was not specified so the entire aspath must be private ASNs
1255 // for us to do anything
1256 else if (aspath_private_as_check (attr
->aspath
))
1258 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1259 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1261 attr
->aspath
= aspath_empty_get ();
1266 /* If this is an EBGP peer with as-override */
1268 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1269 struct peer
*peer
, struct attr
*attr
)
1271 if (peer
->sort
== BGP_PEER_EBGP
&&
1272 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1274 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1275 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1280 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1282 if (family
== AF_INET
)
1283 attr
->nexthop
.s_addr
= 0;
1284 if (family
== AF_INET6
)
1285 memset (&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1289 subgroup_announce_check (struct bgp_node
*rn
, struct bgp_info
*ri
,
1290 struct update_subgroup
*subgrp
,
1291 struct prefix
*p
, struct attr
*attr
)
1293 struct bgp_filter
*filter
;
1296 struct peer
*onlypeer
;
1298 struct attr
*riattr
;
1299 struct peer_af
*paf
;
1300 char buf
[PREFIX_STRLEN
];
1306 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1308 if (DISABLE_BGP_ANNOUNCE
)
1311 afi
= SUBGRP_AFI(subgrp
);
1312 safi
= SUBGRP_SAFI(subgrp
);
1313 peer
= SUBGRP_PEER(subgrp
);
1315 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1316 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1319 filter
= &peer
->filter
[afi
][safi
];
1320 bgp
= SUBGRP_INST(subgrp
);
1321 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1324 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1325 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1326 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1329 * direct and direct_ext type routes originate internally even
1330 * though they can have peer pointers that reference other systems
1332 prefix2str(p
, buf
, PREFIX_STRLEN
);
1333 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1338 /* With addpath we may be asked to TX all kinds of paths so make sure
1340 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1341 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1342 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1347 /* If this is not the bestpath then check to see if there is an enabled addpath
1348 * feature that requires us to advertise it */
1349 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1351 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1357 /* Aggregate-address suppress check. */
1358 if (ri
->extra
&& ri
->extra
->suppress
)
1359 if (! UNSUPPRESS_MAP_NAME (filter
))
1364 /* If it's labeled safi, make sure the route has a valid label. */
1365 if (safi
== SAFI_LABELED_UNICAST
)
1367 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1368 if (!bgp_is_valid_label(&label
))
1370 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1371 zlog_debug ("u%" PRIu64
":s%" PRIu64
" %s/%d is filtered - no label (%p)",
1372 subgrp
->update_group
->id
, subgrp
->id
,
1373 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1374 p
->prefixlen
, &label
);
1379 /* Do not send back route to sender. */
1380 if (onlypeer
&& from
== onlypeer
)
1385 /* Do not send the default route in the BGP table if the neighbor is
1386 * configured for default-originate */
1387 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1389 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1391 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1395 /* Transparency check. */
1396 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1397 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1402 /* If community is not disabled check the no-export and local. */
1403 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1405 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1406 zlog_debug ("subgrpannouncecheck: community filter check fail");
1410 /* If the attribute has originator-id and it is same as remote
1413 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1414 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->originator_id
)))
1416 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1417 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1419 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1423 /* ORF prefix-list filter check */
1424 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1425 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1426 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1427 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1428 if (peer
->orf_plist
[afi
][safi
])
1430 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1432 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1433 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1434 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1439 /* Output filter check. */
1440 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1442 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1443 zlog_debug ("%s [Update:SEND] %s is filtered",
1444 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1448 #ifdef BGP_SEND_ASPATH_CHECK
1449 /* AS path loop check. */
1450 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1452 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1453 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1454 "that is part of AS path.",
1455 onlypeer
->host
, onlypeer
->as
);
1458 #endif /* BGP_SEND_ASPATH_CHECK */
1460 /* If we're a CONFED we need to loop check the CONFED ID too */
1461 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1463 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1465 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1466 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1474 /* Route-Reflect check. */
1475 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1480 /* IBGP reflection check. */
1481 if (reflect
&& !samepeer_safe
)
1483 /* A route from a Client peer. */
1484 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1486 /* Reflect to all the Non-Client peers and also to the
1487 Client peers other than the originator. Originator check
1488 is already done. So there is noting to do. */
1489 /* no bgp client-to-client reflection check. */
1490 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1491 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1492 PEER_FLAG_REFLECTOR_CLIENT
))
1497 /* A route from a Non-client peer. Reflect to all other
1499 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1500 PEER_FLAG_REFLECTOR_CLIENT
))
1505 /* For modify attribute, copy it to temporary structure. */
1506 bgp_attr_dup (attr
, riattr
);
1508 /* If local-preference is not set. */
1509 if ((peer
->sort
== BGP_PEER_IBGP
1510 || peer
->sort
== BGP_PEER_CONFED
)
1511 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1513 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1514 attr
->local_pref
= bgp
->default_local_pref
;
1517 /* If originator-id is not set and the route is to be reflected,
1518 set the originator id */
1519 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1521 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1522 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1525 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1526 if (peer
->sort
== BGP_PEER_EBGP
1527 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1529 if (from
!= bgp
->peer_self
&& ! transparent
1530 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1531 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1534 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1535 * in announce check, only certain flags and length (or number of nexthops
1536 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1537 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1538 * Typically, the source nexthop in the attribute is preserved but in the
1539 * scenarios where we know it will always be overwritten, we reset the
1540 * nexthop to "0" in an attempt to achieve better Update packing. An
1541 * example of this is when a prefix from each of 2 IBGP peers needs to be
1542 * announced to an EBGP peer (and they have the same attributes barring
1546 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1548 #define NEXTHOP_IS_V6 (\
1549 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1550 (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) || \
1551 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1552 attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1554 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1555 * the peer (group) is configured to receive link-local nexthop unchanged
1556 * and it is available in the prefix OR we're not reflecting the route and
1557 * the peer (group) to whom we're going to announce is on a shared network
1558 * and this is either a self-originated route or the peer is EBGP.
1562 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1563 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1564 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1565 IN6_IS_ADDR_LINKLOCAL (&attr
->mp_nexthop_local
)) ||
1566 (!reflect
&& peer
->shared_network
&&
1567 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1569 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1572 /* Clear off link-local nexthop in source, whenever it is not needed to
1573 * ensure more prefixes share the same attribute for announcement.
1575 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1576 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1577 memset (&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1580 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1581 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1583 /* Route map & unsuppress-map apply. */
1584 if (ROUTE_MAP_OUT_NAME (filter
)
1585 || (ri
->extra
&& ri
->extra
->suppress
) )
1587 struct bgp_info info
;
1588 struct attr dummy_attr
;
1592 /* don't confuse inbound and outbound setting */
1593 RESET_FLAG(attr
->rmap_change_flags
);
1596 * The route reflector is not allowed to modify the attributes
1597 * of the reflected IBGP routes unless explicitly allowed.
1599 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1600 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1602 bgp_attr_dup (&dummy_attr
, attr
);
1603 info
.attr
= &dummy_attr
;
1606 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1608 if (ri
->extra
&& ri
->extra
->suppress
)
1609 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1611 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1613 peer
->rmap_type
= 0;
1615 if (ret
== RMAP_DENYMATCH
)
1617 bgp_attr_flush (attr
);
1622 /* After route-map has been applied, we check to see if the nexthop to
1623 * be carried in the attribute (that is used for the announcement) can
1624 * be cleared off or not. We do this in all cases where we would be
1625 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1626 * the global nexthop here; the link-local nexthop would have been cleared
1627 * already, and if not, it is required by the update formation code.
1628 * Also see earlier comments in this function.
1631 * If route-map has performed some operation on the nexthop or the peer
1632 * configuration says to pass it unchanged, we cannot reset the nexthop
1633 * here, so only attempt to do it if these aren't true. Note that the
1634 * route-map handler itself might have cleared the nexthop, if for example,
1635 * it is configured as 'peer-address'.
1637 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1638 riattr
->rmap_change_flags
) &&
1640 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1642 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1643 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1644 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1647 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1648 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1649 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ?
1650 AF_INET6
: p
->family
), attr
);
1652 else if (peer
->sort
== BGP_PEER_EBGP
)
1654 /* Can also reset the nexthop if announcing to EBGP, but only if
1655 * no peer in the subgroup is on a shared subnet.
1656 * Note: 3rd party nexthop currently implemented for IPv4 only.
1658 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1660 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1664 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
, afi
, safi
) ? AF_INET6
: p
->family
), attr
);
1666 /* If IPv6/MP and nexthop does not have any override and happens to
1667 * be a link-local address, reset it so that we don't pass along the
1668 * source's link-local IPv6 address to recipients who may not be on
1669 * the same interface.
1671 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
))
1673 if (IN6_IS_ADDR_LINKLOCAL (&attr
->mp_nexthop_global
))
1674 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1682 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1683 struct bgp_maxpaths_cfg
*mpath_cfg
,
1684 struct bgp_info_pair
*result
,
1685 afi_t afi
, safi_t safi
)
1687 struct bgp_info
*new_select
;
1688 struct bgp_info
*old_select
;
1689 struct bgp_info
*ri
;
1690 struct bgp_info
*ri1
;
1691 struct bgp_info
*ri2
;
1692 struct bgp_info
*nextri
= NULL
;
1693 int paths_eq
, do_mpath
, debug
;
1694 struct list mp_list
;
1695 char pfx_buf
[PREFIX2STR_BUFFER
];
1696 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1698 bgp_mp_list_init (&mp_list
);
1699 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1701 debug
= bgp_debug_bestpath(&rn
->p
);
1704 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1706 /* bgp deterministic-med */
1708 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1711 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1712 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1713 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1715 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1717 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1719 if (BGP_INFO_HOLDDOWN (ri1
))
1721 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1722 if (ri1
->peer
->status
!= Established
)
1728 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1730 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1732 if (BGP_INFO_HOLDDOWN (ri2
))
1735 ri2
->peer
!= bgp
->peer_self
&&
1736 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1737 if (ri2
->peer
->status
!= Established
)
1740 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1741 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1744 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1745 mpath_cfg
, debug
, pfx_buf
, afi
, safi
))
1747 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1751 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1755 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1756 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1760 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1761 zlog_debug("%s: %s is the bestpath from AS %d",
1762 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1767 /* Check old selected route and new selected route. */
1770 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1772 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1775 if (BGP_INFO_HOLDDOWN (ri
))
1777 /* reap REMOVED routes, if needs be
1778 * selected route must stay for a while longer though
1780 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1781 && (ri
!= old_select
))
1782 bgp_info_reap (rn
, ri
);
1788 ri
->peer
!= bgp
->peer_self
&&
1789 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1790 if (ri
->peer
->status
!= Established
)
1793 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1794 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1796 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1800 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1802 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1803 debug
, pfx_buf
, afi
, safi
))
1809 /* Now that we know which path is the bestpath see if any of the other paths
1810 * qualify as multipaths
1815 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1817 sprintf (path_buf
, "NONE");
1818 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1820 old_select
? old_select
->peer
->host
: "NONE");
1823 if (do_mpath
&& new_select
)
1825 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1829 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1831 if (ri
== new_select
)
1834 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1836 bgp_mp_list_add (&mp_list
, ri
);
1840 if (BGP_INFO_HOLDDOWN (ri
))
1844 ri
->peer
!= bgp
->peer_self
&&
1845 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1846 if (ri
->peer
->status
!= Established
)
1849 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1852 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1857 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1858 debug
, pfx_buf
, afi
, safi
);
1863 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1865 bgp_mp_list_add (&mp_list
, ri
);
1870 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1871 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1872 bgp_mp_list_clear (&mp_list
);
1874 result
->old
= old_select
;
1875 result
->new = new_select
;
1881 * A new route/change in bestpath of an existing route. Evaluate the path
1882 * for advertisement to the subgroup.
1885 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1886 struct bgp_info
*selected
,
1887 struct bgp_node
*rn
,
1888 u_int32_t addpath_tx_id
)
1891 struct peer
*onlypeer
;
1897 afi
= SUBGRP_AFI(subgrp
);
1898 safi
= SUBGRP_SAFI(subgrp
);
1899 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1900 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1902 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1903 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1904 PEER_STATUS_ORF_WAIT_REFRESH
))
1907 memset(&attr
, 0, sizeof(struct attr
));
1908 /* It's initialized in bgp_announce_check() */
1910 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1913 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1914 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1916 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1919 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1922 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1929 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1930 * This is called at the end of route processing.
1933 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1935 struct bgp_info
*ri
;
1937 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1939 if (BGP_INFO_HOLDDOWN (ri
))
1941 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1942 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1947 * Has the route changed from the RIB's perspective? This is invoked only
1948 * if the route selection returns the same best route as earlier - to
1949 * determine if we need to update zebra or not.
1952 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1954 struct bgp_info
*mpinfo
;
1956 /* If this is multipath, check all selected paths for any nexthop change or
1957 * attribute change. Some attribute changes (e.g., community) aren't of
1958 * relevance to the RIB, but we'll update zebra to ensure we handle the
1959 * case of BGP nexthop change. This is the behavior when the best path has
1960 * an attribute change anyway.
1962 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1963 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1966 /* If this is multipath, check all selected paths for any nexthop change */
1967 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1968 mpinfo
= bgp_info_mpath_next (mpinfo
))
1970 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1971 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1975 /* Nothing has changed from the RIB's perspective. */
1979 struct bgp_process_queue
1982 struct bgp_node
*rn
;
1987 static wq_item_status
1988 bgp_process_main (struct work_queue
*wq
, void *data
)
1990 struct bgp_process_queue
*pq
= data
;
1991 struct bgp
*bgp
= pq
->bgp
;
1992 struct bgp_node
*rn
= pq
->rn
;
1993 afi_t afi
= pq
->afi
;
1994 safi_t safi
= pq
->safi
;
1995 struct prefix
*p
= &rn
->p
;
1996 struct bgp_info
*new_select
;
1997 struct bgp_info
*old_select
;
1998 struct bgp_info_pair old_and_new
;
2000 /* Is it end of initial update? (after startup) */
2003 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2004 sizeof(bgp
->update_delay_zebra_resume_time
));
2006 bgp
->main_zebra_update_hold
= 0;
2007 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2008 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2010 if (bgp_fibupd_safi(safi
))
2011 bgp_zebra_announce_table(bgp
, afi
, safi
);
2013 bgp
->main_peers_update_hold
= 0;
2015 bgp_start_routeadv(bgp
);
2019 /* Best path selection. */
2020 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
],
2021 &old_and_new
, afi
, safi
);
2022 old_select
= old_and_new
.old
;
2023 new_select
= old_and_new
.new;
2025 /* Do we need to allocate or free labels?
2026 * Right now, since we only deal with per-prefix labels, it is not necessary
2027 * to do this upon changes to best path except of the label index changes.
2029 if (safi
== SAFI_UNICAST
)
2034 bgp_label_index_differs (new_select
, old_select
) ||
2035 new_select
->sub_type
!= old_select
->sub_type
)
2037 if (new_select
->sub_type
== BGP_ROUTE_STATIC
&&
2038 new_select
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
) &&
2039 new_select
->attr
->label_index
!= BGP_INVALID_LABEL_INDEX
)
2041 if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
2042 bgp_unregister_for_label (rn
);
2043 label_ntop (MPLS_IMP_NULL_LABEL
, 1, &rn
->local_label
);
2044 bgp_set_valid_label(&rn
->local_label
);
2047 bgp_register_for_label (rn
, new_select
);
2050 else if (CHECK_FLAG (rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
))
2051 bgp_unregister_for_label (rn
);
2054 /* If best route remains the same and this is not due to user-initiated
2055 * clear, see exactly what needs to be done.
2058 if (old_select
&& old_select
== new_select
&&
2059 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
2060 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
2061 !bgp
->addpath_tx_used
[afi
][safi
])
2063 if (bgp_zebra_has_route_changed (rn
, old_select
))
2066 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2067 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2069 if (bgp_fibupd_safi(safi
) &&
2071 !bgp_option_check (BGP_OPT_NO_FIB
) &&
2072 new_select
->type
== ZEBRA_ROUTE_BGP
&&
2073 new_select
->sub_type
== BGP_ROUTE_NORMAL
)
2074 bgp_zebra_announce (rn
, p
, old_select
, bgp
, afi
, safi
);
2076 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2077 bgp_zebra_clear_route_change_flags (rn
);
2079 /* If there is a change of interest to peers, reannounce the route. */
2080 if (CHECK_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
) ||
2081 CHECK_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
))
2083 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2085 /* unicast routes must also be annouced to labeled-unicast update-groups */
2086 if (safi
== SAFI_UNICAST
)
2087 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
, new_select
);
2089 UNSET_FLAG (old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2090 UNSET_FLAG (rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2093 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2097 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
2098 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2100 /* bestpath has changed; bump version */
2101 if (old_select
|| new_select
)
2103 bgp_bump_version(rn
);
2105 if (!bgp
->t_rmap_def_originate_eval
)
2108 thread_add_timer(bm
->master
,
2109 update_group_refresh_default_originate_route_map
,
2110 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2111 &bgp
->t_rmap_def_originate_eval
);
2116 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
2119 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
2120 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2121 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2125 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2126 if (old_select
!= new_select
) {
2128 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
2129 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2132 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
2133 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2139 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2141 /* unicast routes must also be annouced to labeled-unicast update-groups */
2142 if (safi
== SAFI_UNICAST
)
2143 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
, new_select
);
2146 if (bgp_fibupd_safi(safi
) &&
2147 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
2148 !bgp_option_check (BGP_OPT_NO_FIB
))
2151 && new_select
->type
== ZEBRA_ROUTE_BGP
2152 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
2153 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2154 bgp_zebra_announce (rn
, p
, new_select
, bgp
, afi
, safi
);
2157 /* Withdraw the route from the kernel. */
2159 && old_select
->type
== ZEBRA_ROUTE_BGP
2160 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
2161 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2162 bgp_zebra_withdraw (p
, old_select
, safi
);
2166 /* Clear any route change flags. */
2167 bgp_zebra_clear_route_change_flags (rn
);
2169 /* Reap old select bgp_info, if it has been removed */
2170 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2171 bgp_info_reap (rn
, old_select
);
2173 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2178 bgp_processq_del (struct work_queue
*wq
, void *data
)
2180 struct bgp_process_queue
*pq
= data
;
2181 struct bgp_table
*table
;
2183 bgp_unlock (pq
->bgp
);
2186 table
= bgp_node_table (pq
->rn
);
2187 bgp_unlock_node (pq
->rn
);
2188 bgp_table_unlock (table
);
2190 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2194 bgp_process_queue_init (void)
2196 if (!bm
->process_main_queue
)
2198 bm
->process_main_queue
2199 = work_queue_new (bm
->master
, "process_main_queue");
2201 if ( !bm
->process_main_queue
)
2203 zlog_err ("%s: Failed to allocate work queue", __func__
);
2208 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2209 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2210 bm
->process_main_queue
->spec
.max_retries
= 0;
2211 bm
->process_main_queue
->spec
.hold
= 50;
2212 /* Use a higher yield value of 50ms for main queue processing */
2213 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2217 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2219 struct bgp_process_queue
*pqnode
;
2221 /* already scheduled for processing? */
2222 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2225 if (bm
->process_main_queue
== NULL
)
2228 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2229 sizeof (struct bgp_process_queue
));
2233 /* all unlocked in bgp_processq_del */
2234 bgp_table_lock (bgp_node_table (rn
));
2235 pqnode
->rn
= bgp_lock_node (rn
);
2239 pqnode
->safi
= safi
;
2240 work_queue_add (bm
->process_main_queue
, pqnode
);
2241 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2246 bgp_add_eoiu_mark (struct bgp
*bgp
)
2248 struct bgp_process_queue
*pqnode
;
2250 if (bm
->process_main_queue
== NULL
)
2253 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2254 sizeof (struct bgp_process_queue
));
2261 work_queue_add (bm
->process_main_queue
, pqnode
);
2265 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2269 peer
= THREAD_ARG (thread
);
2270 peer
->t_pmax_restart
= NULL
;
2272 if (bgp_debug_neighbor_events(peer
))
2273 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2276 peer_clear (peer
, NULL
);
2282 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2283 safi_t safi
, int always
)
2288 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2291 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2293 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2297 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2298 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2299 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2300 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2302 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2305 /* Convert AFI, SAFI to values for packet. */
2306 pkt_afi
= afi_int2iana (afi
);
2307 pkt_safi
= safi_int2iana (safi
);
2311 ndata
[0] = (pkt_afi
>> 8);
2313 ndata
[2] = pkt_safi
;
2314 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2315 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2316 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2317 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2319 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2320 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2321 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2324 /* Dynamic peers will just close their connection. */
2325 if (peer_dynamic_neighbor (peer
))
2328 /* restart timer start */
2329 if (peer
->pmax_restart
[afi
][safi
])
2331 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2333 if (bgp_debug_neighbor_events(peer
))
2334 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2335 peer
->host
, peer
->v_pmax_restart
);
2337 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2338 peer
->v_pmax_restart
);
2344 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2346 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2348 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2352 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2353 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2354 peer
->pmax
[afi
][safi
]);
2355 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2358 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2362 /* Unconditionally remove the route from the RIB, without taking
2363 * damping into consideration (eg, because the session went down)
2366 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2367 afi_t afi
, safi_t safi
)
2369 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2371 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2372 bgp_info_delete (rn
, ri
); /* keep historical info */
2374 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2378 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2379 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2381 int status
= BGP_DAMP_NONE
;
2383 /* apply dampening, if result is suppressed, we'll be retaining
2384 * the bgp_info in the RIB for historical reference.
2386 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2387 && peer
->sort
== BGP_PEER_EBGP
)
2388 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2389 == BGP_DAMP_SUPPRESSED
)
2391 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2396 if (safi
== SAFI_MPLS_VPN
) {
2397 struct bgp_node
*prn
= NULL
;
2398 struct bgp_table
*table
= NULL
;
2400 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2402 table
= (struct bgp_table
*)(prn
->info
);
2404 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2411 bgp_unlock_node(prn
);
2413 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2414 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2416 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2417 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2422 /* If this is an EVPN route, process for un-import. */
2423 if (safi
== SAFI_EVPN
)
2424 bgp_evpn_unimport_route (peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2426 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2430 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
,
2431 struct attr
*attr
, struct bgp_node
*rn
)
2433 struct bgp_info
*new;
2435 /* Make new BGP info. */
2436 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2438 new->instance
= instance
;
2439 new->sub_type
= sub_type
;
2442 new->uptime
= bgp_clock ();
2444 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2449 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2454 if(eth_s_id
== NULL
)
2456 memset(&(attr
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2460 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2464 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2468 memcpy(&(attr
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2473 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2475 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2476 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2479 if(afi
!= AFI_L2VPN
)
2483 memset(&temp
, 0, 16);
2484 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2485 info_gw_ip
= (union gw_addr
*)&temp
;
2486 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2491 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2492 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2495 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2497 info_gw_ip_remote
= gw_ip
;
2498 if(eth_s_id
== NULL
)
2499 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2501 info_eth_s_id_remote
= eth_s_id
;
2502 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2504 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2507 /* Check if received nexthop is valid or not. */
2509 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2513 /* Only validated for unicast and multicast currently. */
2514 /* Also valid for EVPN where the nexthop is an IP address. */
2515 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2518 /* If NEXT_HOP is present, validate it. */
2519 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2521 if (attr
->nexthop
.s_addr
== 0 ||
2522 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2523 bgp_nexthop_self (bgp
, attr
->nexthop
))
2527 /* If MP_NEXTHOP is present, validate it. */
2528 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2529 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2530 * it is not an IPv6 link-local address.
2532 if (attr
->mp_nexthop_len
)
2534 switch (attr
->mp_nexthop_len
)
2536 case BGP_ATTR_NHLEN_IPV4
:
2537 case BGP_ATTR_NHLEN_VPNV4
:
2538 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0 ||
2539 IPV4_CLASS_DE (ntohl (attr
->mp_nexthop_global_in
.s_addr
)) ||
2540 bgp_nexthop_self (bgp
, attr
->mp_nexthop_global_in
));
2543 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2544 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2545 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2546 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
) ||
2547 IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
) ||
2548 IN6_IS_ADDR_MULTICAST(&attr
->mp_nexthop_global
));
2561 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2562 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2563 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2564 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2567 int aspath_loop_count
= 0;
2568 struct bgp_node
*rn
;
2570 struct attr new_attr
;
2571 struct attr
*attr_new
;
2572 struct bgp_info
*ri
;
2573 struct bgp_info
*new;
2575 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2578 int do_loop_check
= 1;
2579 int has_valid_label
= 0;
2581 int vnc_implicit_withdraw
= 0;
2585 memset (&new_attr
, 0, sizeof(struct attr
));
2586 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2587 new_attr
.label
= MPLS_INVALID_LABEL
;
2590 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2591 has_valid_label
= bgp_is_valid_label(label
);
2593 if (has_valid_label
)
2594 sprintf (label_buf
, "label %u", label_pton(label
));
2596 /* When peer's soft reconfiguration enabled. Record input packet in
2598 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2599 && peer
!= bgp
->peer_self
)
2600 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2602 /* Check previously received route. */
2603 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2604 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2605 ri
->addpath_rx_id
== addpath_id
)
2608 /* AS path local-as loop check. */
2609 if (peer
->change_local_as
)
2611 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2612 aspath_loop_count
= 1;
2614 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2616 reason
= "as-path contains our own AS;";
2621 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2622 * as-path is our ASN then we do not need to call aspath_loop_check
2624 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2625 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2628 /* AS path loop check. */
2631 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2632 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2633 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2635 reason
= "as-path contains our own AS;";
2640 /* Route reflector originator ID check. */
2641 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2642 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->originator_id
))
2644 reason
= "originator is us;";
2648 /* Route reflector cluster ID check. */
2649 if (bgp_cluster_filter (peer
, attr
))
2651 reason
= "reflected from the same cluster;";
2655 /* Apply incoming filter. */
2656 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2662 bgp_attr_dup (&new_attr
, attr
);
2664 /* Apply incoming route-map.
2665 * NB: new_attr may now contain newly allocated values from route-map "set"
2666 * commands, so we need bgp_attr_flush in the error paths, until we intern
2667 * the attr (which takes over the memory references) */
2668 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2670 reason
= "route-map;";
2671 bgp_attr_flush (&new_attr
);
2675 /* next hop check. */
2676 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2678 reason
= "martian or self next-hop;";
2679 bgp_attr_flush (&new_attr
);
2683 attr_new
= bgp_attr_intern (&new_attr
);
2685 /* If the update is implicit withdraw. */
2688 ri
->uptime
= bgp_clock ();
2689 same_attr
= attrhash_cmp (ri
->attr
, attr_new
);
2691 /* Same attribute comes in. */
2692 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2693 && attrhash_cmp (ri
->attr
, attr_new
)
2694 && (!has_valid_label
||
2695 memcmp (&(bgp_info_extra_get (ri
))->label
, label
, BGP_LABEL_BYTES
) == 0)
2696 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2697 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2699 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2700 && peer
->sort
== BGP_PEER_EBGP
2701 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2703 if (bgp_debug_update(peer
, p
, NULL
, 1))
2705 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
2706 addpath_id
? 1 : 0, addpath_id
,
2707 pfx_buf
, sizeof (pfx_buf
));
2708 zlog_debug ("%s rcvd %s", peer
->host
, pfx_buf
);
2711 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2713 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2714 bgp_process (bgp
, rn
, afi
, safi
);
2717 else /* Duplicate - odd */
2719 if (bgp_debug_update(peer
, p
, NULL
, 1))
2721 if (!peer
->rcvd_attr_printed
)
2723 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2724 peer
->rcvd_attr_printed
= 1;
2727 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
2728 addpath_id
? 1 : 0, addpath_id
,
2729 pfx_buf
, sizeof (pfx_buf
));
2730 zlog_debug ("%s rcvd %s...duplicate ignored",
2731 peer
->host
, pfx_buf
);
2734 /* graceful restart STALE flag unset. */
2735 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2737 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2738 bgp_process (bgp
, rn
, afi
, safi
);
2742 bgp_unlock_node (rn
);
2743 bgp_attr_unintern (&attr_new
);
2748 /* Withdraw/Announce before we fully processed the withdraw */
2749 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2751 if (bgp_debug_update(peer
, p
, NULL
, 1))
2753 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
2754 addpath_id
? 1 : 0, addpath_id
,
2755 pfx_buf
, sizeof (pfx_buf
));
2756 zlog_debug ("%s rcvd %s, flapped quicker than processing",
2757 peer
->host
, pfx_buf
);
2760 bgp_info_restore (rn
, ri
);
2763 /* Received Logging. */
2764 if (bgp_debug_update(peer
, p
, NULL
, 1))
2766 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
2767 addpath_id
? 1 : 0, addpath_id
,
2768 pfx_buf
, sizeof (pfx_buf
));
2769 zlog_debug ("%s rcvd %s", peer
->host
, pfx_buf
);
2772 /* graceful restart STALE flag unset. */
2773 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2774 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2776 /* The attribute is changed. */
2777 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2779 /* implicit withdraw, decrement aggregate and pcount here.
2780 * only if update is accepted, they'll increment below.
2782 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2784 /* Update bgp route dampening information. */
2785 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2786 && peer
->sort
== BGP_PEER_EBGP
)
2788 /* This is implicit withdraw so we should update dampening
2790 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2791 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2794 if (safi
== SAFI_MPLS_VPN
) {
2795 struct bgp_node
*prn
= NULL
;
2796 struct bgp_table
*table
= NULL
;
2798 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2800 table
= (struct bgp_table
*)(prn
->info
);
2802 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2809 bgp_unlock_node(prn
);
2811 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2812 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2814 * Implicit withdraw case.
2816 ++vnc_implicit_withdraw
;
2817 vnc_import_bgp_del_route(bgp
, p
, ri
);
2818 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2823 /* Special handling for EVPN update of an existing route. If the
2824 * extended community attribute has changed, we need to un-import
2825 * the route using its existing extended community. It will be
2826 * subsequently processed for import with the new extended community.
2828 if (safi
== SAFI_EVPN
&& !same_attr
)
2830 if ((ri
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
)) &&
2831 (attr_new
->flag
& ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
)))
2835 cmp
= ecommunity_cmp (ri
->attr
->ecommunity
,
2836 attr_new
->ecommunity
);
2839 if (bgp_debug_update(peer
, p
, NULL
, 1))
2840 zlog_debug ("Change in EXT-COMM, existing %s new %s",
2841 ecommunity_str (ri
->attr
->ecommunity
),
2842 ecommunity_str (attr_new
->ecommunity
));
2843 bgp_evpn_unimport_route (bgp
, afi
, safi
, p
, ri
);
2848 /* Update to new attribute. */
2849 bgp_attr_unintern (&ri
->attr
);
2850 ri
->attr
= attr_new
;
2852 /* Update MPLS label */
2853 if (has_valid_label
)
2855 memcpy (&(bgp_info_extra_get (ri
))->label
, label
, BGP_LABEL_BYTES
);
2856 bgp_set_valid_label(&(bgp_info_extra_get (ri
))->label
);
2860 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2862 if (vnc_implicit_withdraw
)
2865 * Add back the route with its new attributes (e.g., nexthop).
2866 * The route is still selected, until the route selection
2867 * queued by bgp_process actually runs. We have to make this
2868 * update to the VNC side immediately to avoid racing against
2869 * configuration changes (e.g., route-map changes) which
2870 * trigger re-importation of the entire RIB.
2872 vnc_import_bgp_add_route(bgp
, p
, ri
);
2873 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2877 /* Update Overlay Index */
2878 if(afi
== AFI_L2VPN
)
2880 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2881 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2884 /* Update bgp route dampening information. */
2885 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2886 && peer
->sort
== BGP_PEER_EBGP
)
2888 /* Now we do normal update dampening. */
2889 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2890 if (ret
== BGP_DAMP_SUPPRESSED
)
2892 bgp_unlock_node (rn
);
2897 /* Nexthop reachability check - for unicast and labeled-unicast.. */
2898 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
2899 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
2901 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2902 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2903 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2908 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2909 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2912 if (BGP_DEBUG(nht
, NHT
))
2914 char buf1
[INET6_ADDRSTRLEN
];
2915 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2916 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2918 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2922 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2925 if (safi
== SAFI_MPLS_VPN
)
2927 struct bgp_node
*prn
= NULL
;
2928 struct bgp_table
*table
= NULL
;
2930 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2933 table
= (struct bgp_table
*)(prn
->info
);
2935 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2942 bgp_unlock_node(prn
);
2946 /* If this is an EVPN route and some attribute has changed, process
2947 * route for import. If the extended community has changed, we would
2948 * have done the un-import earlier and the import would result in the
2949 * route getting injected into appropriate L2 VNIs. If it is just
2950 * some other attribute change, the import will result in updating
2951 * the attributes for the route in the VNI(s).
2953 if (safi
== SAFI_EVPN
&& !same_attr
)
2954 bgp_evpn_import_route (bgp
, afi
, safi
, p
, ri
);
2956 /* Process change. */
2957 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2959 bgp_process (bgp
, rn
, afi
, safi
);
2960 bgp_unlock_node (rn
);
2963 if (SAFI_MPLS_VPN
== safi
)
2965 mpls_label_t label_decoded
= decode_label(label
);
2967 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2970 if (SAFI_ENCAP
== safi
)
2972 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2978 } // End of implicit withdraw
2980 /* Received Logging. */
2981 if (bgp_debug_update(peer
, p
, NULL
, 1))
2983 if (!peer
->rcvd_attr_printed
)
2985 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2986 peer
->rcvd_attr_printed
= 1;
2989 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
2990 addpath_id
? 1 : 0, addpath_id
,
2991 pfx_buf
, sizeof (pfx_buf
));
2992 zlog_debug ("%s rcvd %s", peer
->host
, pfx_buf
);
2995 /* Make new BGP info. */
2996 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2998 /* Update MPLS label */
2999 if (has_valid_label
)
3001 memcpy (&(bgp_info_extra_get (new))->label
, label
, BGP_LABEL_BYTES
);
3002 bgp_set_valid_label(&(bgp_info_extra_get (new))->label
);
3005 /* Update Overlay Index */
3006 if(afi
== AFI_L2VPN
)
3008 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
3009 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
3011 /* Nexthop reachability check. */
3012 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) &&
3013 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
3015 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
3016 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3017 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3022 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
3023 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3026 if (BGP_DEBUG(nht
, NHT
))
3028 char buf1
[INET6_ADDRSTRLEN
];
3029 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
3030 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
3032 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3036 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3039 new->addpath_rx_id
= addpath_id
;
3041 /* Increment prefix */
3042 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3044 /* Register new BGP information. */
3045 bgp_info_add (rn
, new);
3047 /* route_node_get lock */
3048 bgp_unlock_node (rn
);
3051 if (safi
== SAFI_MPLS_VPN
)
3053 struct bgp_node
*prn
= NULL
;
3054 struct bgp_table
*table
= NULL
;
3056 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
3059 table
= (struct bgp_table
*)(prn
->info
);
3061 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3068 bgp_unlock_node(prn
);
3072 /* If maximum prefix count is configured and current prefix
3074 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
3077 /* If this is an EVPN route, process for import. */
3078 if (safi
== SAFI_EVPN
)
3079 bgp_evpn_import_route (bgp
, afi
, safi
, p
, new);
3081 /* Process change. */
3082 bgp_process (bgp
, rn
, afi
, safi
);
3085 if (SAFI_MPLS_VPN
== safi
)
3087 mpls_label_t label_decoded
= decode_label(label
);
3089 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
3092 if (SAFI_ENCAP
== safi
)
3094 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
3101 /* This BGP update is filtered. Log the reason then update BGP
3104 if (bgp_debug_update(peer
, p
, NULL
, 1))
3106 if (!peer
->rcvd_attr_printed
)
3108 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
3109 peer
->rcvd_attr_printed
= 1;
3112 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
3113 addpath_id
? 1 : 0, addpath_id
,
3114 pfx_buf
, sizeof (pfx_buf
));
3115 zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
3116 peer
->host
, pfx_buf
, reason
);
3121 /* If this is an EVPN route, un-import it as it is now filtered. */
3122 if (safi
== SAFI_EVPN
)
3123 bgp_evpn_unimport_route (bgp
, afi
, safi
, p
, ri
);
3125 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3128 bgp_unlock_node (rn
);
3132 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
3133 * a few lines above)
3135 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
3137 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3145 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3146 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
3147 struct prefix_rd
*prd
, mpls_label_t
*label
, struct bgp_route_evpn
*evpn
)
3150 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3151 struct bgp_node
*rn
;
3152 struct bgp_info
*ri
;
3155 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
3157 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
3164 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3166 /* If peer is soft reconfiguration enabled. Record input packet for
3167 * further calculation.
3169 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3170 * routes that are filtered. This tanks out Quagga RS pretty badly due to
3171 * the iteration over all RS clients.
3172 * Since we need to remove the entry from adj_in anyway, do that first and
3173 * if there was no entry, we don't need to do anything more.
3175 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3176 && peer
!= bgp
->peer_self
)
3177 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
3179 if (bgp_debug_update (peer
, p
, NULL
, 1))
3181 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
3182 addpath_id
? 1 : 0, addpath_id
,
3183 pfx_buf
, sizeof (pfx_buf
));
3184 zlog_debug ("%s withdrawing route %s not in adj-in",
3185 peer
->host
, pfx_buf
);
3187 bgp_unlock_node (rn
);
3191 /* Lookup withdrawn route. */
3192 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3193 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
3194 ri
->addpath_rx_id
== addpath_id
)
3198 if (bgp_debug_update(peer
, p
, NULL
, 1))
3200 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
3201 addpath_id
? 1 : 0, addpath_id
,
3202 pfx_buf
, sizeof (pfx_buf
));
3203 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
3204 peer
->host
, pfx_buf
);
3207 /* Withdraw specified route from routing table. */
3208 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
3209 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
3210 else if (bgp_debug_update(peer
, p
, NULL
, 1))
3212 bgp_debug_rdpfxpath2str (afi
, safi
, prd
, p
, label
,
3213 addpath_id
? 1 : 0, addpath_id
,
3214 pfx_buf
, sizeof (pfx_buf
));
3215 zlog_debug ("%s Can't find the route %s",
3216 peer
->host
, pfx_buf
);
3219 /* Unlock bgp_node_get() lock. */
3220 bgp_unlock_node (rn
);
3226 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
3228 struct update_subgroup
*subgrp
;
3229 subgrp
= peer_subgroup(peer
, afi
, safi
);
3230 subgroup_default_originate(subgrp
, withdraw
);
3235 * bgp_stop_announce_route_timer
3238 bgp_stop_announce_route_timer (struct peer_af
*paf
)
3240 if (!paf
->t_announce_route
)
3243 THREAD_TIMER_OFF (paf
->t_announce_route
);
3247 * bgp_announce_route_timer_expired
3249 * Callback that is invoked when the route announcement timer for a
3253 bgp_announce_route_timer_expired (struct thread
*t
)
3255 struct peer_af
*paf
;
3258 paf
= THREAD_ARG (t
);
3261 if (peer
->status
!= Established
)
3264 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3267 peer_af_announce_route (paf
, 1);
3272 * bgp_announce_route
3274 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3277 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3279 struct peer_af
*paf
;
3280 struct update_subgroup
*subgrp
;
3282 paf
= peer_af_find (peer
, afi
, safi
);
3285 subgrp
= PAF_SUBGRP(paf
);
3288 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3289 * or a refresh has already been triggered.
3291 if (!subgrp
|| paf
->t_announce_route
)
3295 * Start a timer to stagger/delay the announce. This serves
3296 * two purposes - announcement can potentially be combined for
3297 * multiple peers and the announcement doesn't happen in the
3300 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3301 (subgrp
->peer_count
== 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
: BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3302 &paf
->t_announce_route
);
3306 * Announce routes from all AF tables to a peer.
3308 * This should ONLY be called when there is a need to refresh the
3309 * routes to the peer based on a policy change for this peer alone
3310 * or a route refresh request received from the peer.
3311 * The operation will result in splitting the peer from its existing
3312 * subgroups and putting it in new subgroups.
3315 bgp_announce_route_all (struct peer
*peer
)
3320 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3321 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3322 bgp_announce_route (peer
, afi
, safi
);
3326 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3327 struct bgp_table
*table
, struct prefix_rd
*prd
)
3330 struct bgp_node
*rn
;
3331 struct bgp_adj_in
*ain
;
3334 table
= peer
->bgp
->rib
[afi
][safi
];
3336 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3337 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3339 if (ain
->peer
== peer
)
3341 struct bgp_info
*ri
= rn
->info
;
3342 mpls_label_t label
= (ri
&& ri
->extra
) ? ri
->extra
->label
: MPLS_INVALID_LABEL
;
3344 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3345 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3346 prd
, &label
, 1, NULL
);
3350 bgp_unlock_node (rn
);
3358 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3360 struct bgp_node
*rn
;
3361 struct bgp_table
*table
;
3363 if (peer
->status
!= Established
)
3366 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3367 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3369 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3370 rn
= bgp_route_next (rn
))
3371 if ((table
= rn
->info
) != NULL
)
3373 struct prefix_rd prd
;
3374 prd
.family
= AF_UNSPEC
;
3376 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3378 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3383 struct bgp_clear_node_queue
3385 struct bgp_node
*rn
;
3388 static wq_item_status
3389 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3391 struct bgp_clear_node_queue
*cnq
= data
;
3392 struct bgp_node
*rn
= cnq
->rn
;
3393 struct peer
*peer
= wq
->spec
.data
;
3394 struct bgp_info
*ri
;
3395 afi_t afi
= bgp_node_table (rn
)->afi
;
3396 safi_t safi
= bgp_node_table (rn
)->safi
;
3398 assert (rn
&& peer
);
3400 /* It is possible that we have multiple paths for a prefix from a peer
3401 * if that peer is using AddPath.
3403 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3404 if (ri
->peer
== peer
)
3406 /* graceful restart STALE flag set. */
3407 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3408 && peer
->nsf
[afi
][safi
]
3409 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3410 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3411 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3414 /* If this is an EVPN route, process for un-import. */
3415 if (safi
== SAFI_EVPN
)
3416 bgp_evpn_unimport_route (peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
3417 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3424 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3426 struct bgp_clear_node_queue
*cnq
= data
;
3427 struct bgp_node
*rn
= cnq
->rn
;
3428 struct bgp_table
*table
= bgp_node_table (rn
);
3430 bgp_unlock_node (rn
);
3431 bgp_table_unlock (table
);
3432 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3436 bgp_clear_node_complete (struct work_queue
*wq
)
3438 struct peer
*peer
= wq
->spec
.data
;
3440 /* Tickle FSM to start moving again */
3441 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3443 peer_unlock (peer
); /* bgp_clear_route */
3447 bgp_clear_node_queue_init (struct peer
*peer
)
3449 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3451 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3452 #undef CLEAR_QUEUE_NAME_LEN
3454 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3456 zlog_err ("%s: Failed to allocate work queue", __func__
);
3459 peer
->clear_node_queue
->spec
.hold
= 10;
3460 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3461 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3462 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3463 peer
->clear_node_queue
->spec
.max_retries
= 0;
3465 /* we only 'lock' this peer reference when the queue is actually active */
3466 peer
->clear_node_queue
->spec
.data
= peer
;
3470 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3471 struct bgp_table
*table
)
3473 struct bgp_node
*rn
;
3474 int force
= bm
->process_main_queue
? 0 : 1;
3477 table
= peer
->bgp
->rib
[afi
][safi
];
3479 /* If still no table => afi/safi isn't configured at all or smth. */
3483 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3485 struct bgp_info
*ri
, *next
;
3486 struct bgp_adj_in
*ain
;
3487 struct bgp_adj_in
*ain_next
;
3489 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3490 * queued for every clearing peer, regardless of whether it is
3491 * relevant to the peer at hand.
3493 * Overview: There are 3 different indices which need to be
3494 * scrubbed, potentially, when a peer is removed:
3496 * 1 peer's routes visible via the RIB (ie accepted routes)
3497 * 2 peer's routes visible by the (optional) peer's adj-in index
3498 * 3 other routes visible by the peer's adj-out index
3500 * 3 there is no hurry in scrubbing, once the struct peer is
3501 * removed from bgp->peer, we could just GC such deleted peer's
3502 * adj-outs at our leisure.
3504 * 1 and 2 must be 'scrubbed' in some way, at least made
3505 * invisible via RIB index before peer session is allowed to be
3506 * brought back up. So one needs to know when such a 'search' is
3511 * - there'd be a single global queue or a single RIB walker
3512 * - rather than tracking which route_nodes still need to be
3513 * examined on a peer basis, we'd track which peers still
3516 * Given that our per-peer prefix-counts now should be reliable,
3517 * this may actually be achievable. It doesn't seem to be a huge
3518 * problem at this time,
3520 * It is possible that we have multiple paths for a prefix from a peer
3521 * if that peer is using AddPath.
3526 ain_next
= ain
->next
;
3528 if (ain
->peer
== peer
)
3530 bgp_adj_in_remove (rn
, ain
);
3531 bgp_unlock_node (rn
);
3537 for (ri
= rn
->info
; ri
; ri
= next
)
3540 if (ri
->peer
!= peer
)
3544 bgp_info_reap (rn
, ri
);
3547 struct bgp_clear_node_queue
*cnq
;
3549 /* both unlocked in bgp_clear_node_queue_del */
3550 bgp_table_lock (bgp_node_table (rn
));
3552 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3553 sizeof (struct bgp_clear_node_queue
));
3555 work_queue_add (peer
->clear_node_queue
, cnq
);
3564 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3566 struct bgp_node
*rn
;
3567 struct bgp_table
*table
;
3569 if (peer
->clear_node_queue
== NULL
)
3570 bgp_clear_node_queue_init (peer
);
3572 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3573 * Idle until it receives a Clearing_Completed event. This protects
3574 * against peers which flap faster than we can we clear, which could
3577 * a) race with routes from the new session being installed before
3578 * clear_route_node visits the node (to delete the route of that
3580 * b) resource exhaustion, clear_route_node likely leads to an entry
3581 * on the process_main queue. Fast-flapping could cause that queue
3585 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3586 * the unlock will happen upon work-queue completion; other wise, the
3587 * unlock happens at the end of this function.
3589 if (!peer
->clear_node_queue
->thread
)
3592 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3593 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3595 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3596 rn
= bgp_route_next (rn
))
3597 if ((table
= rn
->info
) != NULL
)
3598 bgp_clear_route_table (peer
, afi
, safi
, table
);
3600 /* unlock if no nodes got added to the clear-node-queue. */
3601 if (!peer
->clear_node_queue
->thread
)
3607 bgp_clear_route_all (struct peer
*peer
)
3612 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3613 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3614 bgp_clear_route (peer
, afi
, safi
);
3617 rfapiProcessPeerDown(peer
);
3622 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3624 struct bgp_table
*table
;
3625 struct bgp_node
*rn
;
3626 struct bgp_adj_in
*ain
;
3627 struct bgp_adj_in
*ain_next
;
3629 table
= peer
->bgp
->rib
[afi
][safi
];
3631 /* It is possible that we have multiple paths for a prefix from a peer
3632 * if that peer is using AddPath.
3634 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3640 ain_next
= ain
->next
;
3642 if (ain
->peer
== peer
)
3644 bgp_adj_in_remove (rn
, ain
);
3645 bgp_unlock_node (rn
);
3654 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3656 struct bgp_node
*rn
;
3657 struct bgp_info
*ri
;
3658 struct bgp_table
*table
;
3660 if ( safi
== SAFI_MPLS_VPN
)
3662 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3664 struct bgp_node
*rm
;
3665 struct bgp_info
*ri
;
3667 /* look for neighbor in tables */
3668 if ((table
= rn
->info
) != NULL
)
3670 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3671 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3672 if (ri
->peer
== peer
)
3674 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3675 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3683 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3684 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3685 if (ri
->peer
== peer
)
3687 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3688 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3695 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3697 struct bgp_node
*rn
;
3698 struct bgp_info
*ri
;
3699 struct bgp_info
*next
;
3701 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3702 for (ri
= rn
->info
; ri
; ri
= next
)
3705 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3706 && ri
->type
== ZEBRA_ROUTE_BGP
3707 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3708 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3710 if (bgp_fibupd_safi(safi
))
3711 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3712 bgp_info_reap (rn
, ri
);
3717 /* Delete all kernel routes. */
3719 bgp_cleanup_routes (struct bgp
*bgp
)
3722 struct bgp_node
*rn
;
3724 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3726 if (afi
== AFI_L2VPN
)
3728 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3730 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3732 if (afi
!= AFI_L2VPN
)
3735 safi
= SAFI_MPLS_VPN
;
3736 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3737 rn
= bgp_route_next (rn
))
3741 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3742 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3744 bgp_unlock_node(rn
);
3748 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3749 rn
= bgp_route_next (rn
))
3753 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3754 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3756 bgp_unlock_node(rn
);
3761 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3762 rn
= bgp_route_next (rn
))
3766 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3767 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3769 bgp_unlock_node(rn
);
3778 bgp_zclient_reset ();
3779 access_list_reset ();
3780 prefix_list_reset ();
3784 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3786 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3787 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3790 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3793 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3794 struct bgp_nlri
*packet
)
3803 int addpath_encoded
;
3804 u_int32_t addpath_id
;
3806 /* Check peer status. */
3807 if (peer
->status
!= Established
)
3811 lim
= pnt
+ packet
->length
;
3813 safi
= packet
->safi
;
3815 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3817 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3818 syntactic validity. If the field is syntactically incorrect,
3819 then the Error Subcode is set to Invalid Network Field. */
3820 for (; pnt
< lim
; pnt
+= psize
)
3822 /* Clear prefix structure. */
3823 memset (&p
, 0, sizeof (struct prefix
));
3825 if (addpath_encoded
)
3828 /* When packet overflow occurs return immediately. */
3829 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3832 addpath_id
= ntohl(*((uint32_t*) pnt
));
3833 pnt
+= BGP_ADDPATH_ID_LEN
;
3836 /* Fetch prefix length. */
3837 p
.prefixlen
= *pnt
++;
3838 /* afi/safi validity already verified by caller, bgp_update_receive */
3839 p
.family
= afi2family (afi
);
3841 /* Prefix length check. */
3842 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3844 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3845 peer
->host
, p
.prefixlen
, packet
->afi
);
3849 /* Packet size overflow check. */
3850 psize
= PSIZE (p
.prefixlen
);
3852 /* When packet overflow occur return immediately. */
3853 if (pnt
+ psize
> lim
)
3855 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3856 peer
->host
, p
.prefixlen
);
3860 /* Defensive coding, double-check the psize fits in a struct prefix */
3861 if (psize
> (ssize_t
) sizeof(p
.u
))
3863 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3864 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3868 /* Fetch prefix from NLRI packet. */
3869 memcpy (&p
.u
.prefix
, pnt
, psize
);
3871 /* Check address. */
3872 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3874 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3876 /* From RFC4271 Section 6.3:
3878 * If a prefix in the NLRI field is semantically incorrect
3879 * (e.g., an unexpected multicast IP address), an error SHOULD
3880 * be logged locally, and the prefix SHOULD be ignored.
3882 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3883 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3888 /* Check address. */
3889 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3891 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3895 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3896 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3900 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3904 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3905 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3911 /* Normal process. */
3913 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3914 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3916 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3917 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3919 /* Address family configuration mismatch or maximum-prefix count
3925 /* Packet length consistency check. */
3928 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3936 static struct bgp_static
*
3937 bgp_static_new (void)
3939 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3943 bgp_static_free (struct bgp_static
*bgp_static
)
3945 if (bgp_static
->rmap
.name
)
3946 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3947 if(bgp_static
->eth_s_id
)
3948 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3949 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3953 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3954 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3956 struct bgp_node
*rn
;
3957 struct bgp_info
*ri
;
3958 struct bgp_info
*new;
3959 struct bgp_info info
;
3961 struct attr
*attr_new
;
3964 int vnc_implicit_withdraw
= 0;
3967 assert (bgp_static
);
3971 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3973 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3975 attr
.nexthop
= bgp_static
->igpnexthop
;
3976 attr
.med
= bgp_static
->igpmetric
;
3977 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3979 if (bgp_static
->atomic
)
3980 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3982 /* Store label index, if required. */
3983 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
3985 attr
.label_index
= bgp_static
->label_index
;
3986 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
3989 /* Apply route-map. */
3990 if (bgp_static
->rmap
.name
)
3992 struct attr attr_tmp
= attr
;
3993 info
.peer
= bgp
->peer_self
;
3994 info
.attr
= &attr_tmp
;
3996 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3998 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4000 bgp
->peer_self
->rmap_type
= 0;
4002 if (ret
== RMAP_DENYMATCH
)
4004 /* Free uninterned attribute. */
4005 bgp_attr_flush (&attr_tmp
);
4007 /* Unintern original. */
4008 aspath_unintern (&attr
.aspath
);
4009 bgp_static_withdraw (bgp
, p
, afi
, safi
);
4012 attr_new
= bgp_attr_intern (&attr_tmp
);
4015 attr_new
= bgp_attr_intern (&attr
);
4017 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4018 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4019 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4024 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4025 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
4026 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
4028 bgp_unlock_node (rn
);
4029 bgp_attr_unintern (&attr_new
);
4030 aspath_unintern (&attr
.aspath
);
4035 /* The attribute is changed. */
4036 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4038 /* Rewrite BGP route information. */
4039 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4040 bgp_info_restore(rn
, ri
);
4042 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4044 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
4046 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
4049 * Implicit withdraw case.
4050 * We have to do this before ri is changed
4052 ++vnc_implicit_withdraw
;
4053 vnc_import_bgp_del_route(bgp
, p
, ri
);
4054 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
4058 bgp_attr_unintern (&ri
->attr
);
4059 ri
->attr
= attr_new
;
4060 ri
->uptime
= bgp_clock ();
4062 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
4064 if (vnc_implicit_withdraw
)
4066 vnc_import_bgp_add_route(bgp
, p
, ri
);
4067 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
4072 /* Nexthop reachability check. */
4073 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
4074 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
4076 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
4077 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
4080 if (BGP_DEBUG(nht
, NHT
))
4082 char buf1
[INET6_ADDRSTRLEN
];
4083 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4085 zlog_debug("%s(%s): Route not in table, not advertising",
4086 __FUNCTION__
, buf1
);
4088 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
4093 /* Delete the NHT structure if any, if we're toggling between
4094 * enabling/disabling import check. We deregister the route
4095 * from NHT to avoid overloading NHT and the process interaction
4097 bgp_unlink_nexthop(ri
);
4098 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
4100 /* Process change. */
4101 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4102 bgp_process (bgp
, rn
, afi
, safi
);
4103 bgp_unlock_node (rn
);
4104 aspath_unintern (&attr
.aspath
);
4109 /* Make new BGP info. */
4110 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4112 /* Nexthop reachability check. */
4113 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
) &&
4114 (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
))
4116 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
4117 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
4120 if (BGP_DEBUG(nht
, NHT
))
4122 char buf1
[INET6_ADDRSTRLEN
];
4123 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4125 zlog_debug("%s(%s): Route not in table, not advertising",
4126 __FUNCTION__
, buf1
);
4128 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
4133 /* Delete the NHT structure if any, if we're toggling between
4134 * enabling/disabling import check. We deregister the route
4135 * from NHT to avoid overloading NHT and the process interaction
4137 bgp_unlink_nexthop(new);
4139 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
4142 /* Aggregate address increment. */
4143 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4145 /* Register new BGP information. */
4146 bgp_info_add (rn
, new);
4148 /* route_node_get lock */
4149 bgp_unlock_node (rn
);
4151 /* Process change. */
4152 bgp_process (bgp
, rn
, afi
, safi
);
4154 /* Unintern original. */
4155 aspath_unintern (&attr
.aspath
);
4159 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4162 struct bgp_node
*rn
;
4163 struct bgp_info
*ri
;
4165 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4167 /* Check selected route and self inserted route. */
4168 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4169 if (ri
->peer
== bgp
->peer_self
4170 && ri
->type
== ZEBRA_ROUTE_BGP
4171 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4174 /* Withdraw static BGP route from routing table. */
4177 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4178 bgp_unlink_nexthop(ri
);
4179 bgp_info_delete (rn
, ri
);
4180 bgp_process (bgp
, rn
, afi
, safi
);
4183 /* Unlock bgp_node_lookup. */
4184 bgp_unlock_node (rn
);
4188 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4191 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4192 safi_t safi
, struct prefix_rd
*prd
)
4194 struct bgp_node
*rn
;
4195 struct bgp_info
*ri
;
4197 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4199 /* Check selected route and self inserted route. */
4200 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4201 if (ri
->peer
== bgp
->peer_self
4202 && ri
->type
== ZEBRA_ROUTE_BGP
4203 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4206 /* Withdraw static BGP route from routing table. */
4210 rfapiProcessWithdraw(
4219 1); /* Kill, since it is an administrative change */
4221 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4222 bgp_info_delete (rn
, ri
);
4223 bgp_process (bgp
, rn
, afi
, safi
);
4226 /* Unlock bgp_node_lookup. */
4227 bgp_unlock_node (rn
);
4231 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
4232 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4234 struct bgp_node
*rn
;
4235 struct bgp_info
*new;
4236 struct attr
*attr_new
;
4237 struct attr attr
= { 0 };
4238 struct bgp_info
*ri
;
4240 mpls_label_t label
= 0;
4244 assert (bgp_static
);
4246 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4248 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4250 attr
.nexthop
= bgp_static
->igpnexthop
;
4251 attr
.med
= bgp_static
->igpmetric
;
4252 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4254 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4258 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4259 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4262 if(afi
== AFI_L2VPN
)
4264 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4265 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4266 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4267 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4268 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4269 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4271 struct bgp_encap_type_vxlan bet
;
4272 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4273 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4274 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4276 if (bgp_static
->router_mac
)
4278 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4281 /* Apply route-map. */
4282 if (bgp_static
->rmap
.name
)
4284 struct attr attr_tmp
= attr
;
4285 struct bgp_info info
;
4288 info
.peer
= bgp
->peer_self
;
4289 info
.attr
= &attr_tmp
;
4291 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4293 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4295 bgp
->peer_self
->rmap_type
= 0;
4297 if (ret
== RMAP_DENYMATCH
)
4299 /* Free uninterned attribute. */
4300 bgp_attr_flush (&attr_tmp
);
4302 /* Unintern original. */
4303 aspath_unintern (&attr
.aspath
);
4304 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
);
4308 attr_new
= bgp_attr_intern (&attr_tmp
);
4312 attr_new
= bgp_attr_intern (&attr
);
4315 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4316 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4317 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4323 memset(&add
, 0, sizeof(union gw_addr
));
4324 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4325 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4326 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4328 bgp_unlock_node (rn
);
4329 bgp_attr_unintern (&attr_new
);
4330 aspath_unintern (&attr
.aspath
);
4335 /* The attribute is changed. */
4336 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4338 /* Rewrite BGP route information. */
4339 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4340 bgp_info_restore(rn
, ri
);
4342 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4343 bgp_attr_unintern (&ri
->attr
);
4344 ri
->attr
= attr_new
;
4345 ri
->uptime
= bgp_clock ();
4348 label
= decode_label (&ri
->extra
->label
);
4351 /* Process change. */
4352 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4353 bgp_process (bgp
, rn
, afi
, safi
);
4355 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4356 ri
->attr
, afi
, safi
,
4357 ri
->type
, ri
->sub_type
, &label
);
4359 bgp_unlock_node (rn
);
4360 aspath_unintern (&attr
.aspath
);
4366 /* Make new BGP info. */
4367 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4369 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4370 new->extra
= bgp_info_extra_new();
4371 new->extra
->label
= bgp_static
->label
;
4373 label
= decode_label (&bgp_static
->label
);
4376 /* Aggregate address increment. */
4377 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4379 /* Register new BGP information. */
4380 bgp_info_add (rn
, new);
4381 /* route_node_get lock */
4382 bgp_unlock_node (rn
);
4384 /* Process change. */
4385 bgp_process (bgp
, rn
, afi
, safi
);
4388 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4389 new->attr
, afi
, safi
,
4390 new->type
, new->sub_type
, &label
);
4393 /* Unintern original. */
4394 aspath_unintern (&attr
.aspath
);
4397 /* Configure static BGP network. When user don't run zebra, static
4398 route should be installed as valid. */
4400 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4401 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
,
4402 u_int32_t label_index
)
4404 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4407 struct bgp_static
*bgp_static
;
4408 struct bgp_node
*rn
;
4409 u_char need_update
= 0;
4411 /* Convert IP prefix string to struct prefix. */
4412 ret
= str2prefix (ip_str
, &p
);
4415 vty_out (vty
, "%% Malformed prefix\n");
4416 return CMD_WARNING_CONFIG_FAILED
;
4418 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4420 vty_out (vty
,"%% Malformed prefix (link-local address)\n");
4421 return CMD_WARNING_CONFIG_FAILED
;
4426 /* Set BGP static route configuration. */
4427 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4431 /* Configuration change. */
4432 bgp_static
= rn
->info
;
4434 /* Label index cannot be changed. */
4435 if (bgp_static
->label_index
!= label_index
)
4437 vty_out (vty
, "%% Label index cannot be changed\n");
4438 return CMD_WARNING_CONFIG_FAILED
;
4441 /* Check previous routes are installed into BGP. */
4442 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4445 bgp_static
->backdoor
= backdoor
;
4449 if (bgp_static
->rmap
.name
)
4450 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4451 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4452 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4456 if (bgp_static
->rmap
.name
)
4457 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4458 bgp_static
->rmap
.name
= NULL
;
4459 bgp_static
->rmap
.map
= NULL
;
4460 bgp_static
->valid
= 0;
4462 bgp_unlock_node (rn
);
4466 /* New configuration. */
4467 bgp_static
= bgp_static_new ();
4468 bgp_static
->backdoor
= backdoor
;
4469 bgp_static
->valid
= 0;
4470 bgp_static
->igpmetric
= 0;
4471 bgp_static
->igpnexthop
.s_addr
= 0;
4472 bgp_static
->label_index
= label_index
;
4476 if (bgp_static
->rmap
.name
)
4477 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4478 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4479 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4481 rn
->info
= bgp_static
;
4484 bgp_static
->valid
= 1;
4486 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4488 if (! bgp_static
->backdoor
)
4489 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4494 /* Configure static BGP network. */
4496 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4497 afi_t afi
, safi_t safi
)
4499 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4502 struct bgp_static
*bgp_static
;
4503 struct bgp_node
*rn
;
4505 /* Convert IP prefix string to struct prefix. */
4506 ret
= str2prefix (ip_str
, &p
);
4509 vty_out (vty
, "%% Malformed prefix\n");
4510 return CMD_WARNING_CONFIG_FAILED
;
4512 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4514 vty_out (vty
,"%% Malformed prefix (link-local address)\n");
4515 return CMD_WARNING_CONFIG_FAILED
;
4520 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4523 vty_out (vty
,"%% Can't find specified static route configuration.\n");
4524 return CMD_WARNING_CONFIG_FAILED
;
4527 bgp_static
= rn
->info
;
4529 /* Update BGP RIB. */
4530 if (! bgp_static
->backdoor
)
4531 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4533 /* Clear configuration. */
4534 bgp_static_free (bgp_static
);
4536 bgp_unlock_node (rn
);
4537 bgp_unlock_node (rn
);
4543 bgp_static_add (struct bgp
*bgp
)
4547 struct bgp_node
*rn
;
4548 struct bgp_node
*rm
;
4549 struct bgp_table
*table
;
4550 struct bgp_static
*bgp_static
;
4552 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4553 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4554 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4555 if (rn
->info
!= NULL
)
4557 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4561 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4563 bgp_static
= rm
->info
;
4564 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4569 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4574 /* Called from bgp_delete(). Delete all static routes from the BGP
4577 bgp_static_delete (struct bgp
*bgp
)
4581 struct bgp_node
*rn
;
4582 struct bgp_node
*rm
;
4583 struct bgp_table
*table
;
4584 struct bgp_static
*bgp_static
;
4586 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4587 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4588 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4589 if (rn
->info
!= NULL
)
4591 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4595 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4597 bgp_static
= rm
->info
;
4598 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4600 (struct prefix_rd
*)&rn
->p
);
4601 bgp_static_free (bgp_static
);
4603 bgp_unlock_node (rn
);
4608 bgp_static
= rn
->info
;
4609 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4610 bgp_static_free (bgp_static
);
4612 bgp_unlock_node (rn
);
4618 bgp_static_redo_import_check (struct bgp
*bgp
)
4622 struct bgp_node
*rn
;
4623 struct bgp_node
*rm
;
4624 struct bgp_table
*table
;
4625 struct bgp_static
*bgp_static
;
4627 /* Use this flag to force reprocessing of the route */
4628 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4629 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4630 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4631 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4632 if (rn
->info
!= NULL
)
4634 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4638 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4640 bgp_static
= rm
->info
;
4641 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4646 bgp_static
= rn
->info
;
4647 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4650 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4654 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4656 struct bgp_table
*table
;
4657 struct bgp_node
*rn
;
4658 struct bgp_info
*ri
;
4660 table
= bgp
->rib
[afi
][safi
];
4661 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4663 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4665 if (ri
->peer
== bgp
->peer_self
&&
4666 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4667 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4668 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4669 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4671 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4672 bgp_unlink_nexthop(ri
);
4673 bgp_info_delete (rn
, ri
);
4674 bgp_process (bgp
, rn
, afi
, safi
);
4681 * Purge all networks and redistributed routes from routing table.
4682 * Invoked upon the instance going down.
4685 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4690 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4691 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4692 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4697 * Currently this is used to set static routes for VPN and ENCAP.
4698 * I think it can probably be factored with bgp_static_set.
4701 bgp_static_set_safi (afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4702 const char *rd_str
, const char *label_str
,
4703 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4704 const char *ethtag
, const char *routermac
)
4706 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4709 struct prefix_rd prd
;
4710 struct bgp_node
*prn
;
4711 struct bgp_node
*rn
;
4712 struct bgp_table
*table
;
4713 struct bgp_static
*bgp_static
;
4714 mpls_label_t label
= MPLS_INVALID_LABEL
;
4715 struct prefix gw_ip
;
4717 /* validate ip prefix */
4718 ret
= str2prefix (ip_str
, &p
);
4721 vty_out (vty
, "%% Malformed prefix\n");
4722 return CMD_WARNING_CONFIG_FAILED
;
4725 if ( (afi
== AFI_L2VPN
) &&
4726 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4728 vty_out (vty
, "%% L2VPN prefix could not be forged\n");
4729 return CMD_WARNING_CONFIG_FAILED
;
4732 ret
= str2prefix_rd (rd_str
, &prd
);
4735 vty_out (vty
, "%% Malformed rd\n");
4736 return CMD_WARNING_CONFIG_FAILED
;
4741 unsigned long label_val
;
4742 label_val
= strtoul(label_str
, NULL
, 10);
4743 encode_label (label_val
, &label
);
4746 if (safi
== SAFI_EVPN
)
4748 if( esi
&& str2esi (esi
, NULL
) == 0)
4750 vty_out (vty
, "%% Malformed ESI\n");
4751 return CMD_WARNING_CONFIG_FAILED
;
4753 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4755 vty_out (vty
, "%% Malformed Router MAC\n");
4756 return CMD_WARNING_CONFIG_FAILED
;
4760 memset (&gw_ip
, 0, sizeof (struct prefix
));
4761 ret
= str2prefix (gwip
, &gw_ip
);
4764 vty_out (vty
, "%% Malformed GatewayIp\n");
4765 return CMD_WARNING_CONFIG_FAILED
;
4767 if((gw_ip
.family
== AF_INET
&&
4768 IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)&p
)) ||
4769 (gw_ip
.family
== AF_INET6
&&
4770 IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)&p
)))
4772 vty_out (vty
, "%% GatewayIp family differs with IP prefix\n");
4773 return CMD_WARNING_CONFIG_FAILED
;
4777 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4778 (struct prefix
*)&prd
);
4779 if (prn
->info
== NULL
)
4780 prn
->info
= bgp_table_init (afi
, safi
);
4782 bgp_unlock_node (prn
);
4785 rn
= bgp_node_get (table
, &p
);
4789 vty_out (vty
, "%% Same network configuration exists\n");
4790 bgp_unlock_node (rn
);
4794 /* New configuration. */
4795 bgp_static
= bgp_static_new ();
4796 bgp_static
->backdoor
= 0;
4797 bgp_static
->valid
= 0;
4798 bgp_static
->igpmetric
= 0;
4799 bgp_static
->igpnexthop
.s_addr
= 0;
4800 bgp_static
->label
= label
;
4801 bgp_static
->prd
= prd
;
4805 if (bgp_static
->rmap
.name
)
4806 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4807 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4808 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4811 if (safi
== SAFI_EVPN
)
4815 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4816 str2esi (esi
, bgp_static
->eth_s_id
);
4820 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4821 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4824 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4826 rn
->info
= bgp_static
;
4828 bgp_static
->valid
= 1;
4829 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4835 /* Configure static BGP network. */
4837 bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4838 const char *rd_str
, const char *label_str
,
4839 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4841 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4844 struct prefix_rd prd
;
4845 struct bgp_node
*prn
;
4846 struct bgp_node
*rn
;
4847 struct bgp_table
*table
;
4848 struct bgp_static
*bgp_static
;
4849 mpls_label_t label
= MPLS_INVALID_LABEL
;
4851 /* Convert IP prefix string to struct prefix. */
4852 ret
= str2prefix (ip_str
, &p
);
4855 vty_out (vty
, "%% Malformed prefix\n");
4856 return CMD_WARNING_CONFIG_FAILED
;
4859 if ( (afi
== AFI_L2VPN
) &&
4860 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4862 vty_out (vty
, "%% L2VPN prefix could not be forged\n");
4863 return CMD_WARNING_CONFIG_FAILED
;
4865 ret
= str2prefix_rd (rd_str
, &prd
);
4868 vty_out (vty
, "%% Malformed rd\n");
4869 return CMD_WARNING_CONFIG_FAILED
;
4874 unsigned long label_val
;
4875 label_val
= strtoul(label_str
, NULL
, 10);
4876 encode_label (label_val
, &label
);
4879 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4880 (struct prefix
*)&prd
);
4881 if (prn
->info
== NULL
)
4882 prn
->info
= bgp_table_init (afi
, safi
);
4884 bgp_unlock_node (prn
);
4887 rn
= bgp_node_lookup (table
, &p
);
4891 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
);
4893 bgp_static
= rn
->info
;
4894 bgp_static_free (bgp_static
);
4896 bgp_unlock_node (rn
);
4897 bgp_unlock_node (rn
);
4900 vty_out (vty
, "%% Can't find the route\n");
4906 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4907 const char *rmap_name
)
4909 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4910 struct bgp_rmap
*rmap
;
4912 rmap
= &bgp
->table_map
[afi
][safi
];
4916 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4917 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4918 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4923 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4928 if (bgp_fibupd_safi(safi
))
4929 bgp_zebra_announce_table(bgp
, afi
, safi
);
4935 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4936 const char *rmap_name
)
4938 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4939 struct bgp_rmap
*rmap
;
4941 rmap
= &bgp
->table_map
[afi
][safi
];
4943 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4947 if (bgp_fibupd_safi(safi
))
4948 bgp_zebra_announce_table(bgp
, afi
, safi
);
4954 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4955 safi_t safi
, int *write
)
4957 if (bgp
->table_map
[afi
][safi
].name
)
4959 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4960 vty_out (vty
, " table-map %s\n",
4961 bgp
->table_map
[afi
][safi
].name
);
4967 DEFUN (bgp_table_map
,
4970 "BGP table to RIB route download filter\n"
4971 "Name of the route map\n")
4974 return bgp_table_map_set (vty
,
4975 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4977 DEFUN (no_bgp_table_map
,
4978 no_bgp_table_map_cmd
,
4979 "no table-map WORD",
4981 "BGP table to RIB route download filter\n"
4982 "Name of the route map\n")
4985 return bgp_table_map_unset (vty
,
4986 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4991 "network A.B.C.D/M",
4992 "Specify a network to announce via BGP\n"
4995 int idx_ipv4_prefixlen
= 1;
4996 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4997 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
4998 BGP_INVALID_LABEL_INDEX
);
5001 DEFUN (bgp_network_route_map
,
5002 bgp_network_route_map_cmd
,
5003 "network A.B.C.D/M route-map WORD",
5004 "Specify a network to announce via BGP\n"
5006 "Route-map to modify the attributes\n"
5007 "Name of the route map\n")
5009 int idx_ipv4_prefixlen
= 1;
5011 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
5012 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5013 BGP_INVALID_LABEL_INDEX
);
5016 DEFUN (bgp_network_backdoor
,
5017 bgp_network_backdoor_cmd
,
5018 "network A.B.C.D/M backdoor",
5019 "Specify a network to announce via BGP\n"
5021 "Specify a BGP backdoor route\n")
5023 int idx_ipv4_prefixlen
= 1;
5024 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
5025 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5028 DEFUN (bgp_network_mask
,
5029 bgp_network_mask_cmd
,
5030 "network A.B.C.D mask A.B.C.D",
5031 "Specify a network to announce via BGP\n"
5039 char prefix_str
[BUFSIZ
];
5041 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5044 vty_out (vty
, "%% Inconsistent address and mask\n");
5045 return CMD_WARNING_CONFIG_FAILED
;
5048 return bgp_static_set (vty
, prefix_str
,
5049 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, BGP_INVALID_LABEL_INDEX
);
5052 DEFUN (bgp_network_mask_route_map
,
5053 bgp_network_mask_route_map_cmd
,
5054 "network A.B.C.D mask A.B.C.D route-map WORD",
5055 "Specify a network to announce via BGP\n"
5059 "Route-map to modify the attributes\n"
5060 "Name of the route map\n")
5066 char prefix_str
[BUFSIZ
];
5068 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5071 vty_out (vty
, "%% Inconsistent address and mask\n");
5072 return CMD_WARNING_CONFIG_FAILED
;
5075 return bgp_static_set (vty
, prefix_str
,
5076 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
5079 DEFUN (bgp_network_mask_backdoor
,
5080 bgp_network_mask_backdoor_cmd
,
5081 "network A.B.C.D mask A.B.C.D backdoor",
5082 "Specify a network to announce via BGP\n"
5086 "Specify a BGP backdoor route\n")
5091 char prefix_str
[BUFSIZ
];
5093 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5096 vty_out (vty
, "%% Inconsistent address and mask\n");
5097 return CMD_WARNING_CONFIG_FAILED
;
5100 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5102 BGP_INVALID_LABEL_INDEX
);
5105 DEFUN (bgp_network_mask_natural
,
5106 bgp_network_mask_natural_cmd
,
5108 "Specify a network to announce via BGP\n"
5113 char prefix_str
[BUFSIZ
];
5115 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5118 vty_out (vty
, "%% Inconsistent address and mask\n");
5119 return CMD_WARNING_CONFIG_FAILED
;
5122 return bgp_static_set (vty
, prefix_str
,
5123 AFI_IP
, bgp_node_safi (vty
), NULL
, 0,
5124 BGP_INVALID_LABEL_INDEX
);
5127 DEFUN (bgp_network_mask_natural_route_map
,
5128 bgp_network_mask_natural_route_map_cmd
,
5129 "network A.B.C.D route-map WORD",
5130 "Specify a network to announce via BGP\n"
5132 "Route-map to modify the attributes\n"
5133 "Name of the route map\n")
5138 char prefix_str
[BUFSIZ
];
5140 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5143 vty_out (vty
, "%% Inconsistent address and mask\n");
5144 return CMD_WARNING_CONFIG_FAILED
;
5147 return bgp_static_set (vty
, prefix_str
,
5148 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5149 BGP_INVALID_LABEL_INDEX
);
5152 DEFUN (bgp_network_mask_natural_backdoor
,
5153 bgp_network_mask_natural_backdoor_cmd
,
5154 "network A.B.C.D backdoor",
5155 "Specify a network to announce via BGP\n"
5157 "Specify a BGP backdoor route\n")
5161 char prefix_str
[BUFSIZ
];
5163 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5166 vty_out (vty
, "%% Inconsistent address and mask\n");
5167 return CMD_WARNING_CONFIG_FAILED
;
5170 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
5171 NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5174 DEFUN (bgp_network_label_index
,
5175 bgp_network_label_index_cmd
,
5176 "network A.B.C.D/M label-index (0-1048560)",
5177 "Specify a network to announce via BGP\n"
5178 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5179 "Label index to associate with the prefix\n"
5180 "Label index value\n")
5182 u_int32_t label_index
;
5184 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5185 return bgp_static_set (vty
, argv
[1]->arg
,
5186 AFI_IP
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5189 DEFUN (bgp_network_label_index_route_map
,
5190 bgp_network_label_index_route_map_cmd
,
5191 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5192 "Specify a network to announce via BGP\n"
5194 "Label index to associate with the prefix\n"
5195 "Label index value\n"
5196 "Route-map to modify the attributes\n"
5197 "Name of the route map\n")
5199 u_int32_t label_index
;
5201 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5202 return bgp_static_set (vty
, argv
[1]->arg
,
5203 AFI_IP
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5206 DEFUN (no_bgp_network
,
5208 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5210 "Specify a network to announce via BGP\n"
5212 "Specify a BGP backdoor route\n"
5213 "Route-map to modify the attributes\n"
5214 "Name of the route map\n")
5216 int idx_ipv4_prefixlen
= 2;
5217 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5218 bgp_node_safi (vty
));
5221 DEFUN (no_bgp_network_mask
,
5222 no_bgp_network_mask_cmd
,
5223 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5225 "Specify a network to announce via BGP\n"
5229 "Specify a BGP backdoor route\n"
5230 "Route-map to modify the attributes\n"
5231 "Name of the route map\n")
5236 char prefix_str
[BUFSIZ
];
5238 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
5241 vty_out (vty
, "%% Inconsistent address and mask\n");
5242 return CMD_WARNING_CONFIG_FAILED
;
5245 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5246 bgp_node_safi (vty
));
5249 DEFUN (no_bgp_network_mask_natural
,
5250 no_bgp_network_mask_natural_cmd
,
5251 "no network A.B.C.D [<backdoor|route-map WORD>]",
5253 "Specify a network to announce via BGP\n"
5255 "Specify a BGP backdoor route\n"
5256 "Route-map to modify the attributes\n"
5257 "Name of the route map\n")
5261 char prefix_str
[BUFSIZ
];
5263 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5266 vty_out (vty
, "%% Inconsistent address and mask\n");
5267 return CMD_WARNING_CONFIG_FAILED
;
5270 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
5271 bgp_node_safi (vty
));
5274 ALIAS (no_bgp_network
,
5275 no_bgp_network_label_index_cmd
,
5276 "no network A.B.C.D/M label-index (0-1048560)",
5278 "Specify a network to announce via BGP\n"
5279 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5280 "Label index to associate with the prefix\n"
5281 "Label index value\n")
5283 ALIAS (no_bgp_network
,
5284 no_bgp_network_label_index_route_map_cmd
,
5285 "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
5287 "Specify a network to announce via BGP\n"
5289 "Label index to associate with the prefix\n"
5290 "Label index value\n"
5291 "Route-map to modify the attributes\n"
5292 "Name of the route map\n")
5294 DEFUN (ipv6_bgp_network
,
5295 ipv6_bgp_network_cmd
,
5296 "network X:X::X:X/M",
5297 "Specify a network to announce via BGP\n"
5300 int idx_ipv6_prefixlen
= 1;
5301 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5303 BGP_INVALID_LABEL_INDEX
);
5306 DEFUN (ipv6_bgp_network_route_map
,
5307 ipv6_bgp_network_route_map_cmd
,
5308 "network X:X::X:X/M route-map WORD",
5309 "Specify a network to announce via BGP\n"
5311 "Route-map to modify the attributes\n"
5312 "Name of the route map\n")
5314 int idx_ipv6_prefixlen
= 1;
5316 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5317 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0,
5318 BGP_INVALID_LABEL_INDEX
);
5321 DEFUN (ipv6_bgp_network_label_index
,
5322 ipv6_bgp_network_label_index_cmd
,
5323 "network X:X::X:X/M label-index (0-1048560)",
5324 "Specify a network to announce via BGP\n"
5325 "IPv6 prefix <network>/<length>\n"
5326 "Label index to associate with the prefix\n"
5327 "Label index value\n")
5329 u_int32_t label_index
;
5331 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5332 return bgp_static_set (vty
, argv
[1]->arg
,
5333 AFI_IP6
, bgp_node_safi (vty
), NULL
, 0, label_index
);
5336 DEFUN (ipv6_bgp_network_label_index_route_map
,
5337 ipv6_bgp_network_label_index_route_map_cmd
,
5338 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5339 "Specify a network to announce via BGP\n"
5341 "Label index to associate with the prefix\n"
5342 "Label index value\n"
5343 "Route-map to modify the attributes\n"
5344 "Name of the route map\n")
5346 u_int32_t label_index
;
5348 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5349 return bgp_static_set (vty
, argv
[1]->arg
,
5350 AFI_IP6
, bgp_node_safi (vty
), argv
[5]->arg
, 0, label_index
);
5353 DEFUN (no_ipv6_bgp_network
,
5354 no_ipv6_bgp_network_cmd
,
5355 "no network X:X::X:X/M [route-map WORD]",
5357 "Specify a network to announce via BGP\n"
5359 "Route-map to modify the attributes\n"
5360 "Name of the route map\n")
5362 int idx_ipv6_prefixlen
= 2;
5363 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5366 ALIAS (no_ipv6_bgp_network
,
5367 no_ipv6_bgp_network_label_index_cmd
,
5368 "no network X:X::X:X/M label-index (0-1048560)",
5370 "Specify a network to announce via BGP\n"
5371 "IPv6 prefix <network>/<length>\n"
5372 "Label index to associate with the prefix\n"
5373 "Label index value\n")
5375 ALIAS (no_ipv6_bgp_network
,
5376 no_ipv6_bgp_network_label_index_route_map_cmd
,
5377 "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
5379 "Specify a network to announce via BGP\n"
5381 "Label index to associate with the prefix\n"
5382 "Label index value\n"
5383 "Route-map to modify the attributes\n"
5384 "Name of the route map\n")
5386 /* Aggreagete address:
5388 advertise-map Set condition to advertise attribute
5389 as-set Generate AS set path information
5390 attribute-map Set attributes of aggregate
5391 route-map Set parameters of aggregate
5392 summary-only Filter more specific routes from updates
5393 suppress-map Conditionally filter more specific routes from updates
5396 struct bgp_aggregate
5398 /* Summary-only flag. */
5399 u_char summary_only
;
5401 /* AS set generation. */
5404 /* Route-map for aggregated route. */
5405 struct route_map
*map
;
5407 /* Suppress-count. */
5408 unsigned long count
;
5410 /* SAFI configuration. */
5414 static struct bgp_aggregate
*
5415 bgp_aggregate_new (void)
5417 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5421 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5423 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5426 /* Update an aggregate as routes are added/removed from the BGP table */
5428 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5429 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5430 struct bgp_aggregate
*aggregate
)
5432 struct bgp_table
*table
;
5433 struct bgp_node
*top
;
5434 struct bgp_node
*rn
;
5436 struct aspath
*aspath
= NULL
;
5437 struct aspath
*asmerge
= NULL
;
5438 struct community
*community
= NULL
;
5439 struct community
*commerge
= NULL
;
5440 #if defined(AGGREGATE_NEXTHOP_CHECK)
5441 struct in_addr nexthop
;
5444 struct bgp_info
*ri
;
5445 struct bgp_info
*new;
5447 unsigned long match
= 0;
5448 u_char atomic_aggregate
= 0;
5450 /* Record adding route's nexthop and med. */
5453 #if defined(AGGREGATE_NEXTHOP_CHECK)
5454 nexthop
= rinew
->attr
->nexthop
;
5455 med
= rinew
->attr
->med
;
5459 /* ORIGIN attribute: If at least one route among routes that are
5460 aggregated has ORIGIN with the value INCOMPLETE, then the
5461 aggregated route must have the ORIGIN attribute with the value
5462 INCOMPLETE. Otherwise, if at least one route among routes that
5463 are aggregated has ORIGIN with the value EGP, then the aggregated
5464 route must have the origin attribute with the value EGP. In all
5465 other case the value of the ORIGIN attribute of the aggregated
5466 route is INTERNAL. */
5467 origin
= BGP_ORIGIN_IGP
;
5469 table
= bgp
->rib
[afi
][safi
];
5471 top
= bgp_node_get (table
, p
);
5472 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5473 if (rn
->p
.prefixlen
> p
->prefixlen
)
5477 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5479 if (BGP_INFO_HOLDDOWN (ri
))
5482 if (del
&& ri
== del
)
5485 if (! rinew
&& first
)
5487 #if defined(AGGREGATE_NEXTHOP_CHECK)
5488 nexthop
= ri
->attr
->nexthop
;
5489 med
= ri
->attr
->med
;
5494 #ifdef AGGREGATE_NEXTHOP_CHECK
5495 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5496 || ri
->attr
->med
!= med
)
5499 aspath_free (aspath
);
5501 community_free (community
);
5502 bgp_unlock_node (rn
);
5503 bgp_unlock_node (top
);
5506 #endif /* AGGREGATE_NEXTHOP_CHECK */
5508 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5509 atomic_aggregate
= 1;
5511 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5513 if (aggregate
->summary_only
)
5515 (bgp_info_extra_get (ri
))->suppress
++;
5516 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5522 if (origin
< ri
->attr
->origin
)
5523 origin
= ri
->attr
->origin
;
5525 if (aggregate
->as_set
)
5529 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5530 aspath_free (aspath
);
5534 aspath
= aspath_dup (ri
->attr
->aspath
);
5536 if (ri
->attr
->community
)
5540 commerge
= community_merge (community
,
5541 ri
->attr
->community
);
5542 community
= community_uniq_sort (commerge
);
5543 community_free (commerge
);
5546 community
= community_dup (ri
->attr
->community
);
5552 bgp_process (bgp
, rn
, afi
, safi
);
5554 bgp_unlock_node (top
);
5560 if (aggregate
->summary_only
)
5561 (bgp_info_extra_get (rinew
))->suppress
++;
5563 if (origin
< rinew
->attr
->origin
)
5564 origin
= rinew
->attr
->origin
;
5566 if (aggregate
->as_set
)
5570 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5571 aspath_free (aspath
);
5575 aspath
= aspath_dup (rinew
->attr
->aspath
);
5577 if (rinew
->attr
->community
)
5581 commerge
= community_merge (community
,
5582 rinew
->attr
->community
);
5583 community
= community_uniq_sort (commerge
);
5584 community_free (commerge
);
5587 community
= community_dup (rinew
->attr
->community
);
5592 if (aggregate
->count
> 0)
5594 rn
= bgp_node_get (table
, p
);
5595 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5596 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5598 atomic_aggregate
), rn
);
5599 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5601 bgp_info_add (rn
, new);
5602 bgp_unlock_node (rn
);
5603 bgp_process (bgp
, rn
, afi
, safi
);
5608 aspath_free (aspath
);
5610 community_free (community
);
5614 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5615 struct bgp_aggregate
*);
5618 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5619 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5621 struct bgp_node
*child
;
5622 struct bgp_node
*rn
;
5623 struct bgp_aggregate
*aggregate
;
5624 struct bgp_table
*table
;
5626 /* MPLS-VPN aggregation is not yet supported. */
5627 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5630 table
= bgp
->aggregate
[afi
][safi
];
5632 /* No aggregates configured. */
5633 if (bgp_table_top_nolock (table
) == NULL
)
5636 if (p
->prefixlen
== 0)
5639 if (BGP_INFO_HOLDDOWN (ri
))
5642 child
= bgp_node_get (table
, p
);
5644 /* Aggregate address configuration check. */
5645 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5646 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5648 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5649 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5651 bgp_unlock_node (child
);
5655 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5656 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5658 struct bgp_node
*child
;
5659 struct bgp_node
*rn
;
5660 struct bgp_aggregate
*aggregate
;
5661 struct bgp_table
*table
;
5663 /* MPLS-VPN aggregation is not yet supported. */
5664 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5667 table
= bgp
->aggregate
[afi
][safi
];
5669 /* No aggregates configured. */
5670 if (bgp_table_top_nolock (table
) == NULL
)
5673 if (p
->prefixlen
== 0)
5676 child
= bgp_node_get (table
, p
);
5678 /* Aggregate address configuration check. */
5679 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5680 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5682 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5683 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5685 bgp_unlock_node (child
);
5688 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5690 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5691 struct bgp_aggregate
*aggregate
)
5693 struct bgp_table
*table
;
5694 struct bgp_node
*top
;
5695 struct bgp_node
*rn
;
5696 struct bgp_info
*new;
5697 struct bgp_info
*ri
;
5698 unsigned long match
;
5699 u_char origin
= BGP_ORIGIN_IGP
;
5700 struct aspath
*aspath
= NULL
;
5701 struct aspath
*asmerge
= NULL
;
5702 struct community
*community
= NULL
;
5703 struct community
*commerge
= NULL
;
5704 u_char atomic_aggregate
= 0;
5706 table
= bgp
->rib
[afi
][safi
];
5709 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5711 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5714 /* If routes exists below this node, generate aggregate routes. */
5715 top
= bgp_node_get (table
, p
);
5716 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5717 if (rn
->p
.prefixlen
> p
->prefixlen
)
5721 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5723 if (BGP_INFO_HOLDDOWN (ri
))
5726 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5727 atomic_aggregate
= 1;
5729 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5731 /* summary-only aggregate route suppress aggregated
5732 route announcement. */
5733 if (aggregate
->summary_only
)
5735 (bgp_info_extra_get (ri
))->suppress
++;
5736 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5740 /* If at least one route among routes that are aggregated has
5741 * ORIGIN with the value INCOMPLETE, then the aggregated route
5742 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5743 * Otherwise, if at least one route among routes that are
5744 * aggregated has ORIGIN with the value EGP, then the aggregated
5745 * route MUST have the ORIGIN attribute with the value EGP.
5747 if (origin
< ri
->attr
->origin
)
5748 origin
= ri
->attr
->origin
;
5750 /* as-set aggregate route generate origin, as path,
5751 community aggregation. */
5752 if (aggregate
->as_set
)
5756 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5757 aspath_free (aspath
);
5761 aspath
= aspath_dup (ri
->attr
->aspath
);
5763 if (ri
->attr
->community
)
5767 commerge
= community_merge (community
,
5768 ri
->attr
->community
);
5769 community
= community_uniq_sort (commerge
);
5770 community_free (commerge
);
5773 community
= community_dup (ri
->attr
->community
);
5780 /* If this node is suppressed, process the change. */
5782 bgp_process (bgp
, rn
, afi
, safi
);
5784 bgp_unlock_node (top
);
5786 /* Add aggregate route to BGP table. */
5787 if (aggregate
->count
)
5789 rn
= bgp_node_get (table
, p
);
5790 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5791 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5793 atomic_aggregate
), rn
);
5794 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5796 bgp_info_add (rn
, new);
5797 bgp_unlock_node (rn
);
5799 /* Process change. */
5800 bgp_process (bgp
, rn
, afi
, safi
);
5805 aspath_free (aspath
);
5807 community_free (community
);
5812 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5813 safi_t safi
, struct bgp_aggregate
*aggregate
)
5815 struct bgp_table
*table
;
5816 struct bgp_node
*top
;
5817 struct bgp_node
*rn
;
5818 struct bgp_info
*ri
;
5819 unsigned long match
;
5821 table
= bgp
->rib
[afi
][safi
];
5823 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5825 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5828 /* If routes exists below this node, generate aggregate routes. */
5829 top
= bgp_node_get (table
, p
);
5830 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5831 if (rn
->p
.prefixlen
> p
->prefixlen
)
5835 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5837 if (BGP_INFO_HOLDDOWN (ri
))
5840 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5842 if (aggregate
->summary_only
&& ri
->extra
)
5844 ri
->extra
->suppress
--;
5846 if (ri
->extra
->suppress
== 0)
5848 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5856 /* If this node was suppressed, process the change. */
5858 bgp_process (bgp
, rn
, afi
, safi
);
5860 bgp_unlock_node (top
);
5862 /* Delete aggregate route from BGP table. */
5863 rn
= bgp_node_get (table
, p
);
5865 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5866 if (ri
->peer
== bgp
->peer_self
5867 && ri
->type
== ZEBRA_ROUTE_BGP
5868 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5871 /* Withdraw static BGP route from routing table. */
5874 bgp_info_delete (rn
, ri
);
5875 bgp_process (bgp
, rn
, afi
, safi
);
5878 /* Unlock bgp_node_lookup. */
5879 bgp_unlock_node (rn
);
5882 /* Aggregate route attribute. */
5883 #define AGGREGATE_SUMMARY_ONLY 1
5884 #define AGGREGATE_AS_SET 1
5887 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5888 afi_t afi
, safi_t safi
)
5890 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5893 struct bgp_node
*rn
;
5894 struct bgp_aggregate
*aggregate
;
5896 /* Convert string to prefix structure. */
5897 ret
= str2prefix (prefix_str
, &p
);
5900 vty_out (vty
, "Malformed prefix\n");
5901 return CMD_WARNING_CONFIG_FAILED
;
5905 /* Old configuration check. */
5906 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5909 vty_out (vty
,"%% There is no aggregate-address configuration.\n");
5910 return CMD_WARNING_CONFIG_FAILED
;
5913 aggregate
= rn
->info
;
5914 if (aggregate
->safi
== SAFI_UNICAST
)
5915 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5916 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5917 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5918 if (aggregate
->safi
== SAFI_MULTICAST
)
5919 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5921 /* Unlock aggregate address configuration. */
5923 bgp_aggregate_free (aggregate
);
5924 bgp_unlock_node (rn
);
5925 bgp_unlock_node (rn
);
5931 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5932 afi_t afi
, safi_t safi
,
5933 u_char summary_only
, u_char as_set
)
5935 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5938 struct bgp_node
*rn
;
5939 struct bgp_aggregate
*aggregate
;
5941 /* Convert string to prefix structure. */
5942 ret
= str2prefix (prefix_str
, &p
);
5945 vty_out (vty
, "Malformed prefix\n");
5946 return CMD_WARNING_CONFIG_FAILED
;
5950 /* Old configuration check. */
5951 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5955 vty_out (vty
, "There is already same aggregate network.\n");
5956 /* try to remove the old entry */
5957 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5960 vty_out (vty
, "Error deleting aggregate.\n");
5961 bgp_unlock_node (rn
);
5962 return CMD_WARNING_CONFIG_FAILED
;
5966 /* Make aggregate address structure. */
5967 aggregate
= bgp_aggregate_new ();
5968 aggregate
->summary_only
= summary_only
;
5969 aggregate
->as_set
= as_set
;
5970 aggregate
->safi
= safi
;
5971 rn
->info
= aggregate
;
5973 /* Aggregate address insert into BGP routing table. */
5974 if (safi
== SAFI_UNICAST
)
5975 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5976 if (safi
== SAFI_LABELED_UNICAST
)
5977 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_LABELED_UNICAST
, aggregate
);
5978 if (safi
== SAFI_MULTICAST
)
5979 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5984 DEFUN (aggregate_address
,
5985 aggregate_address_cmd
,
5986 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5987 "Configure BGP aggregate entries\n"
5988 "Aggregate prefix\n"
5989 "Generate AS set path information\n"
5990 "Filter more specific routes from updates\n"
5991 "Filter more specific routes from updates\n"
5992 "Generate AS set path information\n")
5995 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5996 char *prefix
= argv
[idx
]->arg
;
5997 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5999 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
6001 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
6004 DEFUN (aggregate_address_mask
,
6005 aggregate_address_mask_cmd
,
6006 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6007 "Configure BGP aggregate entries\n"
6008 "Aggregate address\n"
6010 "Generate AS set path information\n"
6011 "Filter more specific routes from updates\n"
6012 "Filter more specific routes from updates\n"
6013 "Generate AS set path information\n")
6016 argv_find (argv
, argc
, "A.B.C.D", &idx
);
6017 char *prefix
= argv
[idx
]->arg
;
6018 char *mask
= argv
[idx
+1]->arg
;
6019 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6021 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
6023 char prefix_str
[BUFSIZ
];
6024 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
6028 vty_out (vty
, "%% Inconsistent address and mask\n");
6029 return CMD_WARNING_CONFIG_FAILED
;
6032 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
6035 DEFUN (no_aggregate_address
,
6036 no_aggregate_address_cmd
,
6037 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6039 "Configure BGP aggregate entries\n"
6040 "Aggregate prefix\n"
6041 "Generate AS set path information\n"
6042 "Filter more specific routes from updates\n"
6043 "Filter more specific routes from updates\n"
6044 "Generate AS set path information\n")
6047 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
6048 char *prefix
= argv
[idx
]->arg
;
6049 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
6052 DEFUN (no_aggregate_address_mask
,
6053 no_aggregate_address_mask_cmd
,
6054 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6056 "Configure BGP aggregate entries\n"
6057 "Aggregate address\n"
6059 "Generate AS set path information\n"
6060 "Filter more specific routes from updates\n"
6061 "Filter more specific routes from updates\n"
6062 "Generate AS set path information\n")
6065 argv_find (argv
, argc
, "A.B.C.D", &idx
);
6066 char *prefix
= argv
[idx
]->arg
;
6067 char *mask
= argv
[idx
+1]->arg
;
6069 char prefix_str
[BUFSIZ
];
6070 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
6074 vty_out (vty
, "%% Inconsistent address and mask\n");
6075 return CMD_WARNING_CONFIG_FAILED
;
6078 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
6081 DEFUN (ipv6_aggregate_address
,
6082 ipv6_aggregate_address_cmd
,
6083 "aggregate-address X:X::X:X/M [summary-only]",
6084 "Configure BGP aggregate entries\n"
6085 "Aggregate prefix\n"
6086 "Filter more specific routes from updates\n")
6089 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
6090 char *prefix
= argv
[idx
]->arg
;
6091 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
6092 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
6095 DEFUN (no_ipv6_aggregate_address
,
6096 no_ipv6_aggregate_address_cmd
,
6097 "no aggregate-address X:X::X:X/M [summary-only]",
6099 "Configure BGP aggregate entries\n"
6100 "Aggregate prefix\n"
6101 "Filter more specific routes from updates\n")
6104 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
6105 char *prefix
= argv
[idx
]->arg
;
6106 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6109 /* Redistribute route treatment. */
6111 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
6112 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
6113 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
6115 struct bgp_info
*new;
6116 struct bgp_info
*bi
;
6117 struct bgp_info info
;
6118 struct bgp_node
*bn
;
6120 struct attr
*new_attr
;
6123 struct bgp_redist
*red
;
6125 /* Make default attribute. */
6126 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
6128 attr
.nexthop
= *nexthop
;
6129 attr
.nh_ifindex
= ifindex
;
6133 attr
.mp_nexthop_global
= *nexthop6
;
6134 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6138 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
6141 afi
= family2afi (p
->family
);
6143 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6146 struct attr attr_new
;
6148 /* Copy attribute for modification. */
6149 bgp_attr_dup (&attr_new
, &attr
);
6151 if (red
->redist_metric_flag
)
6152 attr_new
.med
= red
->redist_metric
;
6154 /* Apply route-map. */
6157 info
.peer
= bgp
->peer_self
;
6158 info
.attr
= &attr_new
;
6160 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
6162 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
6164 bgp
->peer_self
->rmap_type
= 0;
6166 if (ret
== RMAP_DENYMATCH
)
6168 /* Free uninterned attribute. */
6169 bgp_attr_flush (&attr_new
);
6171 /* Unintern original. */
6172 aspath_unintern (&attr
.aspath
);
6173 bgp_redistribute_delete (bgp
, p
, type
, instance
);
6178 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
6179 afi
, SAFI_UNICAST
, p
, NULL
);
6181 new_attr
= bgp_attr_intern (&attr_new
);
6183 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6184 if (bi
->peer
== bgp
->peer_self
6185 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6190 /* Ensure the (source route) type is updated. */
6192 if (attrhash_cmp (bi
->attr
, new_attr
) &&
6193 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6195 bgp_attr_unintern (&new_attr
);
6196 aspath_unintern (&attr
.aspath
);
6197 bgp_unlock_node (bn
);
6202 /* The attribute is changed. */
6203 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
6205 /* Rewrite BGP route information. */
6206 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6207 bgp_info_restore(bn
, bi
);
6209 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6210 bgp_attr_unintern (&bi
->attr
);
6211 bi
->attr
= new_attr
;
6212 bi
->uptime
= bgp_clock ();
6214 /* Process change. */
6215 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
6216 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6217 bgp_unlock_node (bn
);
6218 aspath_unintern (&attr
.aspath
);
6223 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
6225 SET_FLAG (new->flags
, BGP_INFO_VALID
);
6227 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
6228 bgp_info_add (bn
, new);
6229 bgp_unlock_node (bn
);
6230 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
6233 /* Unintern original. */
6234 aspath_unintern (&attr
.aspath
);
6238 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
6241 struct bgp_node
*rn
;
6242 struct bgp_info
*ri
;
6243 struct bgp_redist
*red
;
6245 afi
= family2afi (p
->family
);
6247 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6250 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
6252 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6253 if (ri
->peer
== bgp
->peer_self
6254 && ri
->type
== type
)
6259 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6260 bgp_info_delete (rn
, ri
);
6261 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6263 bgp_unlock_node (rn
);
6267 /* Withdraw specified route type's route. */
6269 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
6271 struct bgp_node
*rn
;
6272 struct bgp_info
*ri
;
6273 struct bgp_table
*table
;
6275 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6277 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
6279 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6280 if (ri
->peer
== bgp
->peer_self
6282 && ri
->instance
== instance
)
6287 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
6288 bgp_info_delete (rn
, ri
);
6289 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
6294 /* Static function to display route. */
6296 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
6299 u_int32_t destination
;
6302 if (p
->family
== AF_INET
)
6304 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6305 destination
= ntohl (p
->u
.prefix4
.s_addr
);
6307 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
6308 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
6309 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
6310 || p
->u
.prefix4
.s_addr
== 0)
6312 /* When mask is natural, mask is not displayed. */
6315 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
6317 else if (p
->family
== AF_ETHERNET
)
6319 #if defined (HAVE_CUMULUS)
6320 len
= vty_out (vty
, "%s",
6321 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
, BUFSIZ
));
6323 prefix2str(p
, buf
, PREFIX_STRLEN
);
6324 len
= vty_out (vty
, "%s", buf
);
6328 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6333 vty_out (vty
, "\n%*s", 20, " ");
6335 vty_out (vty
, "%*s", len
, " ");
6338 enum bgp_display_type
6343 /* Print the short form route status for a bgp_info */
6345 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
6346 json_object
*json_path
)
6351 /* Route status display. */
6352 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6353 json_object_boolean_true_add(json_path
, "removed");
6355 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6356 json_object_boolean_true_add(json_path
, "stale");
6358 if (binfo
->extra
&& binfo
->extra
->suppress
)
6359 json_object_boolean_true_add(json_path
, "suppressed");
6361 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6362 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6363 json_object_boolean_true_add(json_path
, "valid");
6366 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6367 json_object_boolean_true_add(json_path
, "history");
6369 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6370 json_object_boolean_true_add(json_path
, "damped");
6372 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6373 json_object_boolean_true_add(json_path
, "bestpath");
6375 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6376 json_object_boolean_true_add(json_path
, "multipath");
6378 /* Internal route. */
6379 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6380 json_object_string_add(json_path
, "pathFrom", "internal");
6382 json_object_string_add(json_path
, "pathFrom", "external");
6387 /* Route status display. */
6388 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6390 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6392 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6394 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6395 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6401 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6403 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6405 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6407 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6412 /* Internal route. */
6414 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6420 /* called from terminal list command */
6422 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6423 struct bgp_info
*binfo
, int display
, safi_t safi
,
6424 json_object
*json_paths
)
6427 json_object
*json_path
= NULL
;
6428 json_object
*json_nexthops
= NULL
;
6429 json_object
*json_nexthop_global
= NULL
;
6430 json_object
*json_nexthop_ll
= NULL
;
6433 json_path
= json_object_new_object();
6435 /* short status lead text */
6436 route_vty_short_status_out (vty
, binfo
, json_path
);
6440 /* print prefix and mask */
6442 route_vty_out_route (p
, vty
);
6444 vty_out (vty
, "%*s", 17, " ");
6447 /* Print attribute */
6452 * For ENCAP and EVPN routes, nexthop address family is not
6453 * neccessarily the same as the prefix address family.
6454 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6455 * EVPN routes are also exchanged with a MP nexthop. Currently, this
6456 * is only IPv4, the value will be present in either attr->nexthop or
6457 * attr->mp_nexthop_global_in
6459 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
))
6462 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6467 vty_out (vty
, "%s", inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6470 vty_out (vty
, "%s", inet_ntop(af
, &attr
->mp_nexthop_global
, buf
, BUFSIZ
));
6477 else if (safi
== SAFI_EVPN
)
6481 json_nexthop_global
= json_object_new_object();
6483 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6484 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6485 json_object_boolean_true_add(json_nexthop_global
, "used");
6488 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6491 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6495 json_nexthop_global
= json_object_new_object();
6497 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6498 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->mp_nexthop_global_in
));
6500 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6502 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6503 json_object_boolean_true_add(json_nexthop_global
, "used");
6507 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6508 vty_out (vty
, "%-16s",
6509 inet_ntoa (attr
->mp_nexthop_global_in
));
6511 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6516 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6523 json_nexthop_global
= json_object_new_object();
6524 json_object_string_add(json_nexthop_global
, "ip",
6525 inet_ntop (AF_INET6
,
6526 &attr
->mp_nexthop_global
,
6528 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6529 json_object_string_add(json_nexthop_global
, "scope", "global");
6531 /* We display both LL & GL if both have been received */
6532 if ((attr
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6534 json_nexthop_ll
= json_object_new_object();
6535 json_object_string_add(json_nexthop_ll
, "ip",
6536 inet_ntop (AF_INET6
,
6537 &attr
->mp_nexthop_local
,
6539 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6540 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6542 if ((IPV6_ADDR_CMP (&attr
->mp_nexthop_global
,
6543 &attr
->mp_nexthop_local
) != 0) &&
6544 !attr
->mp_nexthop_prefer_global
)
6545 json_object_boolean_true_add(json_nexthop_ll
, "used");
6547 json_object_boolean_true_add(json_nexthop_global
, "used");
6550 json_object_boolean_true_add(json_nexthop_global
, "used");
6554 /* Display LL if LL/Global both in table unless prefer-global is set */
6555 if (((attr
->mp_nexthop_len
== 32) &&
6556 !attr
->mp_nexthop_prefer_global
) ||
6557 (binfo
->peer
->conf_if
))
6559 if (binfo
->peer
->conf_if
)
6561 len
= vty_out (vty
, "%s",
6562 binfo
->peer
->conf_if
);
6563 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6566 vty_out (vty
, "\n%*s", 45, " ");
6568 vty_out (vty
, "%*s", len
, " ");
6572 len
= vty_out (vty
, "%s",
6573 inet_ntop (AF_INET6
,
6574 &attr
->mp_nexthop_local
,
6579 vty_out (vty
, "\n%*s", 36, " ");
6581 vty_out (vty
, "%*s", len
, " ");
6586 len
= vty_out (vty
, "%s",
6587 inet_ntop (AF_INET6
,
6588 &attr
->mp_nexthop_global
,
6593 vty_out (vty
, "\n%*s", 36, " ");
6595 vty_out (vty
, "%*s", len
, " ");
6601 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6603 json_object_int_add(json_path
, "med", attr
->med
);
6605 vty_out (vty
, "%10u", attr
->med
);
6611 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6613 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6615 vty_out (vty
, "%7u", attr
->local_pref
);
6621 json_object_int_add(json_path
, "weight", attr
->weight
);
6623 vty_out (vty
, "%7u ", attr
->weight
);
6627 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6634 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6636 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6641 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6643 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6648 json_object_string_add(json_path
, "alert", "No attributes");
6650 vty_out (vty
, "No attributes to print\n");
6655 if (json_nexthop_global
|| json_nexthop_ll
)
6657 json_nexthops
= json_object_new_array();
6659 if (json_nexthop_global
)
6660 json_object_array_add(json_nexthops
, json_nexthop_global
);
6662 if (json_nexthop_ll
)
6663 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6665 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6668 json_object_array_add(json_paths
, json_path
);
6672 vty_out (vty
, "\n");
6674 /* prints an additional line, indented, with VNC info, if present */
6675 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6676 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6681 /* called from terminal list command */
6683 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6684 u_char use_json
, json_object
*json_ar
)
6686 json_object
*json_status
= NULL
;
6687 json_object
*json_net
= NULL
;
6689 /* Route status display. */
6692 json_status
= json_object_new_object();
6693 json_net
= json_object_new_object();
6702 /* print prefix and mask */
6704 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6706 route_vty_out_route (p
, vty
);
6708 /* Print attribute */
6713 if (p
->family
== AF_INET
&&
6714 (safi
== SAFI_MPLS_VPN
||
6715 safi
== SAFI_ENCAP
||
6716 safi
== SAFI_EVPN
||
6717 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6719 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6720 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->mp_nexthop_global_in
));
6722 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6724 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6728 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
6732 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6733 json_object_int_add(json_net
, "metric", attr
->med
);
6735 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6736 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6738 json_object_int_add(json_net
, "weight", attr
->weight
);
6742 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6745 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6749 if (p
->family
== AF_INET
&&
6750 (safi
== SAFI_MPLS_VPN
||
6751 safi
== SAFI_ENCAP
||
6752 safi
== SAFI_EVPN
||
6753 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6755 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6756 vty_out (vty
, "%-16s",
6757 inet_ntoa (attr
->mp_nexthop_global_in
));
6759 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6761 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6766 len
= vty_out (vty
, "%s",
6767 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
6771 vty_out (vty
, "\n%*s", 36, " ");
6773 vty_out (vty
, "%*s", len
, " ");
6775 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6776 vty_out (vty
, "%10u", attr
->med
);
6780 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6781 vty_out (vty
, "%7u", attr
->local_pref
);
6785 vty_out (vty
, "%7u ", attr
->weight
);
6789 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6792 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6797 json_object_boolean_true_add(json_status
, "*");
6798 json_object_boolean_true_add(json_status
, ">");
6799 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6800 char buf_cut
[BUFSIZ
];
6801 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6804 vty_out (vty
, "\n");
6808 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6809 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6811 json_object
*json_out
= NULL
;
6813 mpls_label_t label
= MPLS_INVALID_LABEL
;
6819 json_out
= json_object_new_object();
6821 /* short status lead text */
6822 route_vty_short_status_out (vty
, binfo
, json_out
);
6824 /* print prefix and mask */
6828 route_vty_out_route (p
, vty
);
6830 vty_out (vty
, "%*s", 17, " ");
6833 /* Print attribute */
6837 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6838 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6839 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6841 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6844 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->mp_nexthop_global_in
));
6846 vty_out (vty
, "%-16s", inet_ntoa (attr
->mp_nexthop_global_in
));
6851 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6853 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6856 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6857 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6858 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6863 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6866 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6867 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6870 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
6873 else if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6877 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
6879 inet_ntop (AF_INET6
, &attr
->mp_nexthop_local
,
6881 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6882 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6885 vty_out (vty
, "%s(%s)",
6886 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
6888 inet_ntop (AF_INET6
, &attr
->mp_nexthop_local
,
6895 label
= decode_label (&binfo
->extra
->label
);
6897 if (bgp_is_valid_label(&label
))
6901 json_object_int_add(json_out
, "notag", label
);
6902 json_object_array_add(json
, json_out
);
6906 vty_out (vty
, "notag/%d", label
);
6907 vty_out (vty
, "\n");
6913 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6914 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6918 json_object
*json_path
= NULL
;
6921 json_path
= json_object_new_object();
6926 /* short status lead text */
6927 route_vty_short_status_out (vty
, binfo
, json_path
);
6929 /* print prefix and mask */
6931 route_vty_out_route (p
, vty
);
6933 vty_out (vty
, "%*s", 17, " ");
6935 /* Print attribute */
6940 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6944 vty_out (vty
, "%-16s", inet_ntop(af
,
6945 &attr
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6948 vty_out (vty
, "%s(%s)",
6950 &attr
->mp_nexthop_global
, buf
, BUFSIZ
),
6952 &attr
->mp_nexthop_local
, buf1
, BUFSIZ
));
6959 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
6960 char *str
= esi2str(id
);
6961 vty_out (vty
, "%s", str
);
6962 XFREE (MTYPE_TMP
, str
);
6963 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
))
6965 vty_out (vty
, "/%s", inet_ntoa (attr
->evpn_overlay
.gw_ip
.ipv4
));
6967 else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
))
6969 vty_out (vty
, "/%s",
6970 inet_ntop (AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
6973 if(attr
->ecommunity
)
6976 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->ecommunity
,
6977 ECOMMUNITY_ENCODE_EVPN
,
6978 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6980 mac
= ecom_mac2str((char *)routermac
->val
);
6983 vty_out (vty
, "/%s",(char *)mac
);
6984 XFREE(MTYPE_TMP
, mac
);
6987 vty_out (vty
, "\n");
6990 /* dampening route */
6992 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6993 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6997 char timebuf
[BGP_UPTIME_LEN
];
6999 /* short status lead text */
7000 route_vty_short_status_out (vty
, binfo
, json
);
7002 /* print prefix and mask */
7006 route_vty_out_route (p
, vty
);
7008 vty_out (vty
, "%*s", 17, " ");
7011 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
7016 vty_out (vty
, "\n%*s", 34, " ");
7021 json_object_int_add(json
, "peerHost", len
);
7023 vty_out (vty
, "%*s", len
, " ");
7027 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
7029 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
7031 /* Print attribute */
7039 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
7041 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7046 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7048 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7051 vty_out (vty
, "\n");
7056 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
7057 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
7060 struct bgp_damp_info
*bdi
;
7061 char timebuf
[BGP_UPTIME_LEN
];
7067 bdi
= binfo
->extra
->damp_info
;
7069 /* short status lead text */
7070 route_vty_short_status_out (vty
, binfo
, json
);
7072 /* print prefix and mask */
7076 route_vty_out_route (p
, vty
);
7078 vty_out (vty
, "%*s", 17, " ");
7081 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
7086 vty_out (vty
, "\n%*s", 33, " ");
7091 json_object_int_add(json
, "peerHost", len
);
7093 vty_out (vty
, "%*s", len
, " ");
7096 len
= vty_out (vty
, "%d", bdi
->flap
);
7106 json_object_int_add(json
, "bdiFlap", len
);
7108 vty_out (vty
, "%*s", len
, " ");
7112 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
7114 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
7115 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
7117 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
7118 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7121 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
7123 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
7128 vty_out (vty
, "%*s ", 8, " ");
7131 /* Print attribute */
7139 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
7141 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
7146 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
7148 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
7151 vty_out (vty
, "\n");
7155 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
7156 const char *header
, json_object
*json_adv_to
)
7158 char buf1
[INET6_ADDRSTRLEN
];
7159 json_object
*json_peer
= NULL
;
7163 /* 'advertised-to' is a dictionary of peers we have advertised this
7164 * prefix too. The key is the peer's IP or swpX, the value is the
7165 * hostname if we know it and "" if not.
7167 json_peer
= json_object_new_object();
7170 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
7173 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
7175 json_object_object_add(json_adv_to
,
7176 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7183 vty_out (vty
, "%s", header
);
7187 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7190 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
7192 vty_out (vty
, " %s(%s)", peer
->hostname
,
7193 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7198 vty_out (vty
, " %s", peer
->conf_if
);
7200 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
7206 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7207 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7208 json_object
*json_paths
)
7210 char buf
[INET6_ADDRSTRLEN
];
7212 #if defined(HAVE_CUMULUS)
7213 char buf2
[EVPN_ROUTE_STRLEN
];
7216 int sockunion_vty_out (struct vty
*, union sockunion
*);
7218 json_object
*json_bestpath
= NULL
;
7219 json_object
*json_cluster_list
= NULL
;
7220 json_object
*json_cluster_list_list
= NULL
;
7221 json_object
*json_ext_community
= NULL
;
7222 json_object
*json_last_update
= NULL
;
7223 json_object
*json_nexthop_global
= NULL
;
7224 json_object
*json_nexthop_ll
= NULL
;
7225 json_object
*json_nexthops
= NULL
;
7226 json_object
*json_path
= NULL
;
7227 json_object
*json_peer
= NULL
;
7228 json_object
*json_string
= NULL
;
7229 json_object
*json_adv_to
= NULL
;
7231 struct listnode
*node
, *nnode
;
7233 int addpath_capable
;
7235 unsigned int first_as
;
7239 json_path
= json_object_new_object();
7240 json_peer
= json_object_new_object();
7241 json_nexthop_global
= json_object_new_object();
7244 #if defined (HAVE_CUMULUS)
7245 if (!json_paths
&& safi
== SAFI_EVPN
)
7249 bgp_evpn_route2str ((struct prefix_evpn
*)p
, buf2
, sizeof (buf2
));
7250 vty_out (vty
, " Route %s", buf2
);
7254 bgp_evpn_label2str (&binfo
->extra
->label
, tag_buf
, sizeof (tag_buf
));
7255 vty_out (vty
, " VNI %s", tag_buf
);
7257 vty_out (vty
, "\n");
7258 if (binfo
->extra
&& binfo
->extra
->parent
)
7260 struct bgp_info
*parent_ri
;
7261 struct bgp_node
*rn
, *prn
;
7263 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7264 rn
= parent_ri
->net
;
7268 vty_out (vty
, " Imported from %s:%s\n",
7269 prefix_rd2str ((struct prefix_rd
*)&prn
->p
,
7270 buf1
, RD_ADDRSTRLEN
),
7281 /* Line1 display AS-path, Aggregator */
7286 json_object_lock(attr
->aspath
->json
);
7287 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
7291 if (attr
->aspath
->segments
)
7292 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
7294 vty_out (vty
, " Local");
7298 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
7301 json_object_boolean_true_add(json_path
, "removed");
7303 vty_out (vty
, ", (removed)");
7306 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
7309 json_object_boolean_true_add(json_path
, "stale");
7311 vty_out (vty
, ", (stale)");
7314 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
7318 json_object_int_add(json_path
, "aggregatorAs", attr
->aggregator_as
);
7319 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->aggregator_addr
));
7323 vty_out (vty
, ", (aggregated by %u %s)",
7324 attr
->aggregator_as
,
7325 inet_ntoa (attr
->aggregator_addr
));
7329 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
7332 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
7334 vty_out (vty
, ", (Received from a RR-client)");
7337 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
7340 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
7342 vty_out (vty
, ", (Received from a RS-client)");
7345 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7348 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
7350 vty_out (vty
, ", (history entry)");
7352 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
7355 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
7357 vty_out (vty
, ", (suppressed due to dampening)");
7361 vty_out (vty
, "\n");
7363 /* Line2 display Next-hop, Neighbor, Router-id */
7364 /* Display the nexthop */
7365 if ((p
->family
== AF_INET
||
7366 p
->family
== AF_ETHERNET
) &&
7367 (safi
== SAFI_MPLS_VPN
||
7368 safi
== SAFI_ENCAP
||
7369 safi
== SAFI_EVPN
||
7370 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7372 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7375 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->mp_nexthop_global_in
));
7377 vty_out (vty
, " %s", inet_ntoa (attr
->mp_nexthop_global_in
));
7382 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7384 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7388 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7394 json_object_string_add(json_nexthop_global
, "ip",
7395 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
7396 buf
, INET6_ADDRSTRLEN
));
7397 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7398 json_object_string_add(json_nexthop_global
, "scope", "global");
7402 vty_out (vty
, " %s",
7403 inet_ntop (AF_INET6
, &attr
->mp_nexthop_global
,
7404 buf
, INET6_ADDRSTRLEN
));
7408 /* Display the IGP cost or 'inaccessible' */
7409 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7412 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7414 vty_out (vty
, " (inaccessible)");
7418 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7421 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7423 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7426 /* IGP cost is 0, display this only for json */
7430 json_object_int_add(json_nexthop_global
, "metric", 0);
7434 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7437 /* Display peer "from" output */
7438 /* This path was originated locally */
7439 if (binfo
->peer
== bgp
->peer_self
)
7442 if (safi
== SAFI_EVPN
||
7443 (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
7446 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7448 vty_out (vty
, " from 0.0.0.0 ");
7453 json_object_string_add(json_peer
, "peerId", "::");
7455 vty_out (vty
, " from :: ");
7459 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7461 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7464 /* We RXed this path from one of our peers */
7470 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7471 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7473 if (binfo
->peer
->hostname
)
7474 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7476 if (binfo
->peer
->domainname
)
7477 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7479 if (binfo
->peer
->conf_if
)
7480 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7484 if (binfo
->peer
->conf_if
)
7486 if (binfo
->peer
->hostname
&&
7487 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7488 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7489 binfo
->peer
->conf_if
);
7491 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7495 if (binfo
->peer
->hostname
&&
7496 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7497 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7500 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7503 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7504 vty_out (vty
, " (%s)", inet_ntoa (attr
->originator_id
));
7506 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7511 vty_out (vty
, "\n");
7513 /* display the link-local nexthop */
7514 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7518 json_nexthop_ll
= json_object_new_object();
7519 json_object_string_add(json_nexthop_ll
, "ip",
7520 inet_ntop (AF_INET6
, &attr
->mp_nexthop_local
,
7521 buf
, INET6_ADDRSTRLEN
));
7522 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7523 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7525 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7527 if (!attr
->mp_nexthop_prefer_global
)
7528 json_object_boolean_true_add(json_nexthop_ll
, "used");
7530 json_object_boolean_true_add(json_nexthop_global
, "used");
7534 vty_out (vty
, " (%s) %s\n",
7535 inet_ntop (AF_INET6
, &attr
->mp_nexthop_local
,
7536 buf
, INET6_ADDRSTRLEN
),
7537 attr
->mp_nexthop_prefer_global
? "(prefer-global)" : "(used)");
7540 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7544 json_object_boolean_true_add(json_nexthop_global
, "used");
7547 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7549 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7551 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7553 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7556 json_object_int_add(json_path
, "med", attr
->med
);
7558 vty_out (vty
, ", metric %u", attr
->med
);
7561 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7564 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7566 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7571 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7573 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7576 if (attr
->weight
!= 0)
7579 json_object_int_add(json_path
, "weight", attr
->weight
);
7581 vty_out (vty
, ", weight %u", attr
->weight
);
7587 json_object_int_add(json_path
, "tag", attr
->tag
);
7589 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->tag
);
7592 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7595 json_object_boolean_false_add(json_path
, "valid");
7597 vty_out (vty
, ", invalid");
7599 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7602 json_object_boolean_true_add(json_path
, "valid");
7604 vty_out (vty
, ", valid");
7607 if (binfo
->peer
!= bgp
->peer_self
)
7609 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7611 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7614 json_object_string_add(json_peer
, "type", "confed-internal");
7616 vty_out (vty
, ", confed-internal");
7621 json_object_string_add(json_peer
, "type", "internal");
7623 vty_out (vty
, ", internal");
7628 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7631 json_object_string_add(json_peer
, "type", "confed-external");
7633 vty_out (vty
, ", confed-external");
7638 json_object_string_add(json_peer
, "type", "external");
7640 vty_out (vty
, ", external");
7644 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7648 json_object_boolean_true_add(json_path
, "aggregated");
7649 json_object_boolean_true_add(json_path
, "local");
7653 vty_out (vty
, ", aggregated, local");
7656 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7659 json_object_boolean_true_add(json_path
, "sourced");
7661 vty_out (vty
, ", sourced");
7667 json_object_boolean_true_add(json_path
, "sourced");
7668 json_object_boolean_true_add(json_path
, "local");
7672 vty_out (vty
, ", sourced, local");
7676 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7679 json_object_boolean_true_add(json_path
, "atomicAggregate");
7681 vty_out (vty
, ", atomic-aggregate");
7684 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7685 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7686 bgp_info_mpath_count (binfo
)))
7689 json_object_boolean_true_add(json_path
, "multipath");
7691 vty_out (vty
, ", multipath");
7694 // Mark the bestpath(s)
7695 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7697 first_as
= aspath_get_first_as(attr
->aspath
);
7702 json_bestpath
= json_object_new_object();
7703 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7708 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7710 vty_out (vty
, ", bestpath-from-AS Local");
7714 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7719 json_bestpath
= json_object_new_object();
7720 json_object_boolean_true_add(json_bestpath
, "overall");
7723 vty_out (vty
, ", best");
7727 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7730 vty_out (vty
, "\n");
7732 /* Line 4 display Community */
7733 if (attr
->community
)
7737 json_object_lock(attr
->community
->json
);
7738 json_object_object_add(json_path
, "community", attr
->community
->json
);
7742 vty_out (vty
, " Community: %s\n",attr
->community
->str
);
7746 /* Line 5 display Extended-community */
7747 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7751 json_ext_community
= json_object_new_object();
7752 json_object_string_add(json_ext_community
, "string", attr
->ecommunity
->str
);
7753 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7757 vty_out (vty
, " Extended Community: %s\n",
7758 attr
->ecommunity
->str
);
7762 /* Line 6 display Large community */
7763 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7764 vty_out (vty
, " Large Community: %s\n",
7765 attr
->lcommunity
->str
);
7767 /* Line 7 display Originator, Cluster-id */
7768 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7769 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7771 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7774 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->originator_id
));
7776 vty_out (vty
, " Originator: %s",
7777 inet_ntoa (attr
->originator_id
));
7780 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7786 json_cluster_list
= json_object_new_object();
7787 json_cluster_list_list
= json_object_new_array();
7789 for (i
= 0; i
< attr
->cluster
->length
/ 4; i
++)
7791 json_string
= json_object_new_string(inet_ntoa (attr
->cluster
->list
[i
]));
7792 json_object_array_add(json_cluster_list_list
, json_string
);
7795 /* struct cluster_list does not have "str" variable like
7796 * aspath and community do. Add this someday if someone
7798 json_object_string_add(json_cluster_list, "string", attr->cluster->str);
7800 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7801 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7805 vty_out (vty
, ", Cluster list: ");
7807 for (i
= 0; i
< attr
->cluster
->length
/ 4; i
++)
7809 vty_out (vty
, "%s ",
7810 inet_ntoa (attr
->cluster
->list
[i
]));
7816 vty_out (vty
, "\n");
7819 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7820 bgp_damp_info_vty (vty
, binfo
, json_path
);
7823 #if defined (HAVE_CUMULUS)
7824 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
) && safi
!= SAFI_EVPN
)
7826 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
))
7829 mpls_label_t label
= label_pton(&binfo
->extra
->label
);
7831 json_object_int_add(json_path
, "remoteLabel", label
);
7833 vty_out (vty
, " Remote label: %d\n", label
);
7837 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
)
7840 json_object_int_add(json_path
, "labelIndex", attr
->label_index
);
7842 vty_out (vty
, " Label Index: %d\n",
7846 /* Line 8 display Addpath IDs */
7847 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7851 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7852 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7856 vty_out (vty
, " AddPath ID: RX %u, TX %u\n",
7857 binfo
->addpath_rx_id
,binfo
->addpath_tx_id
);
7861 /* If we used addpath to TX a non-bestpath we need to display
7862 * "Advertised to" on a path-by-path basis */
7863 if (bgp
->addpath_tx_used
[afi
][safi
])
7867 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7869 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7870 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7872 if ((addpath_capable
&& has_adj
) ||
7873 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7875 if (json_path
&& !json_adv_to
)
7876 json_adv_to
= json_object_new_object();
7878 route_vty_out_advertised_to(vty
, peer
, &first
,
7888 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7895 vty_out (vty
, "\n");
7900 /* Line 9 display Uptime */
7901 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7904 json_last_update
= json_object_new_object();
7905 json_object_int_add(json_last_update
, "epoch", tbuf
);
7906 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7907 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7910 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7913 /* We've constructed the json object for this path, add it to the json
7918 if (json_nexthop_global
|| json_nexthop_ll
)
7920 json_nexthops
= json_object_new_array();
7922 if (json_nexthop_global
)
7923 json_object_array_add(json_nexthops
, json_nexthop_global
);
7925 if (json_nexthop_ll
)
7926 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7928 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7931 json_object_object_add(json_path
, "peer", json_peer
);
7932 json_object_array_add(json_paths
, json_path
);
7935 vty_out (vty
, "\n");
7938 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
7939 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
7940 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
7943 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7944 const char *prefix_list_str
, afi_t afi
,
7945 safi_t safi
, enum bgp_show_type type
);
7947 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7948 const char *filter
, afi_t afi
,
7949 safi_t safi
, enum bgp_show_type type
);
7951 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7952 const char *rmap_str
, afi_t afi
,
7953 safi_t safi
, enum bgp_show_type type
);
7955 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7956 const char *com
, int exact
,
7957 afi_t afi
, safi_t safi
);
7959 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7960 const char *prefix
, afi_t afi
,
7961 safi_t safi
, enum bgp_show_type type
);
7963 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7964 safi_t safi
, enum bgp_show_type type
);
7966 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7967 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7970 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7971 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7973 struct bgp_info
*ri
;
7974 struct bgp_node
*rn
;
7977 unsigned long output_count
;
7978 unsigned long total_count
;
7982 json_object
*json_paths
= NULL
;
7987 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7988 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7989 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7990 table
->version
, inet_ntoa (bgp
->router_id
));
7991 json_paths
= json_object_new_object();
7994 /* This is first entry point, so reset total line. */
7998 /* Start processing of routes. */
7999 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
8000 if (rn
->info
!= NULL
)
8003 if (!first
&& use_json
)
8008 json_paths
= json_object_new_array();
8012 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8015 if (type
== bgp_show_type_flap_statistics
8016 || type
== bgp_show_type_flap_neighbor
8017 || type
== bgp_show_type_dampend_paths
8018 || type
== bgp_show_type_damp_neighbor
)
8020 if (!(ri
->extra
&& ri
->extra
->damp_info
))
8023 if (type
== bgp_show_type_regexp
)
8025 regex_t
*regex
= output_arg
;
8027 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
8030 if (type
== bgp_show_type_prefix_list
)
8032 struct prefix_list
*plist
= output_arg
;
8034 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
8037 if (type
== bgp_show_type_filter_list
)
8039 struct as_list
*as_list
= output_arg
;
8041 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
8044 if (type
== bgp_show_type_route_map
)
8046 struct route_map
*rmap
= output_arg
;
8047 struct bgp_info binfo
;
8048 struct attr dummy_attr
;
8051 bgp_attr_dup (&dummy_attr
, ri
->attr
);
8053 binfo
.peer
= ri
->peer
;
8054 binfo
.attr
= &dummy_attr
;
8056 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
8057 if (ret
== RMAP_DENYMATCH
)
8060 if (type
== bgp_show_type_neighbor
8061 || type
== bgp_show_type_flap_neighbor
8062 || type
== bgp_show_type_damp_neighbor
)
8064 union sockunion
*su
= output_arg
;
8066 if (ri
->peer
== NULL
||
8067 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
8070 if (type
== bgp_show_type_cidr_only
)
8072 u_int32_t destination
;
8074 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
8075 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
8077 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
8079 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
8082 if (type
== bgp_show_type_prefix_longer
)
8084 struct prefix
*p
= output_arg
;
8086 if (! prefix_match (p
, &rn
->p
))
8089 if (type
== bgp_show_type_community_all
)
8091 if (! ri
->attr
->community
)
8094 if (type
== bgp_show_type_community
)
8096 struct community
*com
= output_arg
;
8098 if (! ri
->attr
->community
||
8099 ! community_match (ri
->attr
->community
, com
))
8102 if (type
== bgp_show_type_community_exact
)
8104 struct community
*com
= output_arg
;
8106 if (! ri
->attr
->community
||
8107 ! community_cmp (ri
->attr
->community
, com
))
8110 if (type
== bgp_show_type_community_list
)
8112 struct community_list
*list
= output_arg
;
8114 if (! community_list_match (ri
->attr
->community
, list
))
8117 if (type
== bgp_show_type_community_list_exact
)
8119 struct community_list
*list
= output_arg
;
8121 if (! community_list_exact_match (ri
->attr
->community
, list
))
8124 if (type
== bgp_show_type_lcommunity
)
8126 struct lcommunity
*lcom
= output_arg
;
8128 if (! ri
->attr
->lcommunity
||
8129 ! lcommunity_match (ri
->attr
->lcommunity
, lcom
))
8132 if (type
== bgp_show_type_lcommunity_list
)
8134 struct community_list
*list
= output_arg
;
8136 if (! lcommunity_list_match (ri
->attr
->lcommunity
, list
))
8139 if (type
== bgp_show_type_lcommunity_all
)
8141 if (! ri
->attr
->lcommunity
)
8144 if (type
== bgp_show_type_dampend_paths
8145 || type
== bgp_show_type_damp_neighbor
)
8147 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
8148 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
8152 if (!use_json
&& header
)
8154 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s\n", table
->version
,
8155 inet_ntoa(bgp
->router_id
));
8156 vty_out (vty
, BGP_SHOW_SCODE_HEADER
);
8157 vty_out (vty
, BGP_SHOW_OCODE_HEADER
);
8158 if (type
== bgp_show_type_dampend_paths
8159 || type
== bgp_show_type_damp_neighbor
)
8160 vty_out (vty
, BGP_SHOW_DAMP_HEADER
);
8161 else if (type
== bgp_show_type_flap_statistics
8162 || type
== bgp_show_type_flap_neighbor
)
8163 vty_out (vty
, BGP_SHOW_FLAP_HEADER
);
8165 vty_out (vty
, BGP_SHOW_HEADER
);
8169 if (type
== bgp_show_type_dampend_paths
8170 || type
== bgp_show_type_damp_neighbor
)
8171 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8172 else if (type
== bgp_show_type_flap_statistics
8173 || type
== bgp_show_type_flap_neighbor
)
8174 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
8176 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
8186 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
8187 vty_out (vty
, "\"%s\": ", buf2
);
8188 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
8189 json_object_free (json_paths
);
8198 json_object_free (json_paths
);
8199 vty_out (vty
, " } }\n");
8203 /* No route is displayed */
8204 if (output_count
== 0)
8206 if (type
== bgp_show_type_normal
)
8207 vty_out (vty
, "No BGP prefixes displayed, %ld exist\n",
8211 vty_out (vty
, "\nDisplayed %ld routes and %ld total paths\n", output_count
, total_count
);
8218 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8219 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8221 struct bgp_table
*table
;
8225 bgp
= bgp_get_default ();
8231 vty_out (vty
, "No BGP process is configured\n");
8235 /* use MPLS and ENCAP specific shows until they are merged */
8236 if (safi
== SAFI_MPLS_VPN
)
8238 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
8241 /* labeled-unicast routes live in the unicast table */
8242 else if (safi
== SAFI_LABELED_UNICAST
)
8243 safi
= SAFI_UNICAST
;
8245 table
= bgp
->rib
[afi
][safi
];
8247 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
8252 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
8255 struct listnode
*node
, *nnode
;
8260 vty_out (vty
, "{\n");
8262 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
8267 vty_out (vty
, ",\n");
8271 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8272 ? "Default" : bgp
->name
);
8276 vty_out (vty
, "\nInstance %s:\n",
8277 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? "Default" : bgp
->name
);
8279 bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
, use_json
);
8284 vty_out (vty
, "}\n");
8287 /* Header of detailed BGP route information */
8289 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
8290 struct bgp_node
*rn
,
8291 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
8294 struct bgp_info
*ri
;
8297 struct listnode
*node
, *nnode
;
8298 char buf1
[INET6_ADDRSTRLEN
];
8299 char buf2
[INET6_ADDRSTRLEN
];
8300 #if defined(HAVE_CUMULUS)
8301 char buf3
[EVPN_ROUTE_STRLEN
];
8307 int no_advertise
= 0;
8310 int has_valid_label
= 0;
8312 json_object
*json_adv_to
= NULL
;
8315 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8317 if (has_valid_label
)
8318 label
= label_pton(&rn
->local_label
);
8322 if (has_valid_label
)
8323 json_object_int_add(json
, "localLabel", label
);
8325 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
8326 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8330 #if defined (HAVE_CUMULUS)
8331 if (safi
== SAFI_EVPN
)
8332 vty_out (vty
, "BGP routing table entry for %s%s%s\n",
8333 prd
? prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : "",
8335 bgp_evpn_route2str ((struct prefix_evpn
*)p
,
8336 buf3
, sizeof (buf3
)));
8338 vty_out (vty
, "BGP routing table entry for %s%s%s/%d\n",
8339 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
) ?
8340 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8341 safi
== SAFI_MPLS_VPN
? ":" : "",
8342 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
8345 if (p
->family
== AF_ETHERNET
)
8346 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
8348 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
8349 vty_out (vty
, "BGP routing table entry for %s%s%s/%d\n",
8350 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
8351 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
8352 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
8357 if (has_valid_label
)
8358 vty_out (vty
, "Local label: %d\n", label
);
8359 #if defined (HAVE_CUMULUS)
8360 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8362 if (bgp_labeled_safi(safi
))
8364 vty_out(vty
, "not allocated\n");
8367 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8370 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
8373 if (ri
->extra
&& ri
->extra
->suppress
)
8375 if (ri
->attr
->community
!= NULL
)
8377 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
8379 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
8381 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
8389 vty_out (vty
, "Paths: (%d available", count
);
8392 vty_out (vty
, ", best #%d", best
);
8393 if (safi
== SAFI_UNICAST
)
8394 vty_out (vty
, ", table %s",
8395 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8396 ? "Default-IP-Routing-Table" : bgp
->name
);
8399 vty_out (vty
, ", no best path");
8402 vty_out (vty
, ", not advertised to any peer");
8404 vty_out (vty
, ", not advertised to EBGP peer");
8406 vty_out (vty
, ", not advertised outside local AS");
8409 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
8410 vty_out (vty
, ")\n");
8413 /* If we are not using addpath then we can display Advertised to and that will
8414 * show what peers we advertised the bestpath to. If we are using addpath
8415 * though then we must display Advertised to on a path-by-path basis. */
8416 if (!bgp
->addpath_tx_used
[afi
][safi
])
8418 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
8420 if (bgp_adj_out_lookup (peer
, rn
, 0))
8422 if (json
&& !json_adv_to
)
8423 json_adv_to
= json_object_new_object();
8425 route_vty_out_advertised_to(vty
, peer
, &first
,
8426 " Advertised to non peer-group peers:\n ",
8435 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8441 vty_out (vty
, " Not advertised to any peer");
8442 vty_out (vty
, "\n");
8447 /* Display specified route of BGP table. */
8449 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8450 struct bgp_table
*rib
, const char *ip_str
,
8451 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8452 int prefix_check
, enum bgp_path_type pathtype
,
8458 struct prefix match
;
8459 struct bgp_node
*rn
;
8460 struct bgp_node
*rm
;
8461 struct bgp_info
*ri
;
8462 struct bgp_table
*table
;
8463 json_object
*json
= NULL
;
8464 json_object
*json_paths
= NULL
;
8466 /* Check IP address argument. */
8467 ret
= str2prefix (ip_str
, &match
);
8470 vty_out (vty
, "address is malformed\n");
8474 match
.family
= afi2family (afi
);
8478 json
= json_object_new_object();
8479 json_paths
= json_object_new_array();
8482 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8484 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8486 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8489 if ((table
= rn
->info
) != NULL
)
8493 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8495 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8497 bgp_unlock_node (rm
);
8501 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8505 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8506 AFI_IP
, safi
, json
);
8511 if (pathtype
== BGP_PATH_ALL
||
8512 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8513 (pathtype
== BGP_PATH_MULTIPATH
&&
8514 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8515 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8518 bgp_unlock_node (rm
);
8527 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8529 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8531 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8535 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8540 if (pathtype
== BGP_PATH_ALL
||
8541 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8542 (pathtype
== BGP_PATH_MULTIPATH
&&
8543 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8544 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8548 bgp_unlock_node (rn
);
8555 json_object_object_add(json
, "paths", json_paths
);
8557 vty_out (vty
, "%s\n",
8558 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8559 json_object_free(json
);
8565 vty_out (vty
, "%% Network not in table\n");
8573 /* Display specified route of Main RIB */
8575 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8576 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8577 int prefix_check
, enum bgp_path_type pathtype
,
8581 bgp
= bgp_get_default ();
8583 /* labeled-unicast routes live in the unicast table */
8584 if (safi
== SAFI_LABELED_UNICAST
)
8585 safi
= SAFI_UNICAST
;
8587 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8588 afi
, safi
, prd
, prefix_check
, pathtype
,
8593 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8594 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8596 struct lcommunity
*lcom
;
8602 b
= buffer_new (1024);
8603 for (i
= 0; i
< argc
; i
++)
8606 buffer_putc (b
, ' ');
8609 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8612 buffer_putstr (b
, argv
[i
]->arg
);
8616 buffer_putc (b
, '\0');
8618 str
= buffer_getstr (b
);
8621 lcom
= lcommunity_str2com (str
);
8622 XFREE (MTYPE_TMP
, str
);
8625 vty_out (vty
, "%% Large-community malformed\n");
8629 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8633 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8634 afi_t afi
, safi_t safi
, u_char uj
)
8636 struct community_list
*list
;
8638 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8641 vty_out (vty
, "%% %s is not a valid large-community-list name\n",lcom
);
8645 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8648 DEFUN (show_ip_bgp_large_community_list
,
8649 show_ip_bgp_large_community_list_cmd
,
8650 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8654 BGP_INSTANCE_HELP_STR
8656 BGP_SAFI_WITH_LABEL_HELP_STR
8657 "Display routes matching the large-community-list\n"
8658 "large-community-list number\n"
8659 "large-community-list name\n"
8663 afi_t afi
= AFI_IP6
;
8664 safi_t safi
= SAFI_UNICAST
;
8667 if (argv_find (argv
, argc
, "ip", &idx
))
8669 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8670 vrf
= argv
[++idx
]->arg
;
8671 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8673 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8674 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8675 safi
= bgp_vty_safi_from_str (argv
[idx
]->text
);
8678 int uj
= use_json (argc
, argv
);
8680 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8683 vty_out (vty
, "Can't find BGP instance %s\n", vrf
);
8687 argv_find (argv
, argc
, "large-community-list", &idx
);
8688 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8690 DEFUN (show_ip_bgp_large_community
,
8691 show_ip_bgp_large_community_cmd
,
8692 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8696 BGP_INSTANCE_HELP_STR
8698 BGP_SAFI_WITH_LABEL_HELP_STR
8699 "Display routes matching the large-communities\n"
8700 "List of large-community numbers\n"
8704 afi_t afi
= AFI_IP6
;
8705 safi_t safi
= SAFI_UNICAST
;
8708 if (argv_find (argv
, argc
, "ip", &idx
))
8710 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8711 vrf
= argv
[++idx
]->arg
;
8712 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8714 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8715 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8716 safi
= bgp_vty_safi_from_str (argv
[idx
]->text
);
8719 int uj
= use_json (argc
, argv
);
8721 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8724 vty_out (vty
, "Can't find BGP instance %s\n", vrf
);
8728 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8729 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8731 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8734 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8736 /* BGP route print out function. */
8739 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8742 |dampening <flap-statistics|dampened-paths|parameters>\
8747 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8748 |community-list <(1-500)|WORD> [exact-match]\
8749 |A.B.C.D/M longer-prefixes\
8750 |X:X::X:X/M longer-prefixes>\
8755 BGP_INSTANCE_HELP_STR
8757 BGP_SAFI_WITH_LABEL_HELP_STR
8758 "Display only routes with non-natural netmasks\n"
8759 "Display detailed information about dampening\n"
8760 "Display flap statistics of routes\n"
8761 "Display paths suppressed due to dampening\n"
8762 "Display detail of configured dampening parameters\n"
8763 "Display routes matching the route-map\n"
8764 "A route-map to match on\n"
8765 "Display routes conforming to the prefix-list\n"
8766 "Prefix-list name\n"
8767 "Display routes conforming to the filter-list\n"
8768 "Regular expression access list name\n"
8769 "BGP RIB advertisement statistics\n"
8770 "Display routes matching the communities\n"
8772 "Do not send outside local AS (well-known community)\n"
8773 "Do not advertise to any peer (well-known community)\n"
8774 "Do not export to next AS (well-known community)\n"
8775 "Exact match of the communities\n"
8776 "Display routes matching the community-list\n"
8777 "community-list number\n"
8778 "community-list name\n"
8779 "Exact match of the communities\n"
8781 "Display route and more specific routes\n"
8783 "Display route and more specific routes\n"
8786 afi_t afi
= AFI_IP6
;
8787 safi_t safi
= SAFI_UNICAST
;
8788 int exact_match
= 0;
8789 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8790 struct bgp
*bgp
= NULL
;
8793 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8797 int uj
= use_json (argc
, argv
);
8800 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8801 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8803 if (argv_find(argv
, argc
, "dampening", &idx
))
8805 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8806 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8807 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8808 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8809 else if (argv_find (argv
, argc
, "parameters", &idx
))
8810 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8813 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8814 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8816 if (argv_find(argv
, argc
, "filter-list", &idx
))
8817 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8819 if (argv_find(argv
, argc
, "statistics", &idx
))
8820 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8822 if (argv_find(argv
, argc
, "route-map", &idx
))
8823 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8825 if (argv_find(argv
, argc
, "community", &idx
))
8827 /* show a specific community */
8828 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8829 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8830 argv_find (argv
, argc
, "no-export", &idx
))
8832 if (argv_find (argv
, argc
, "exact_match", &idx
))
8834 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8836 /* show all communities */
8838 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8841 if (argv_find(argv
, argc
, "community-list", &idx
))
8843 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8844 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8846 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8849 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8850 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8852 if (safi
== SAFI_MPLS_VPN
)
8853 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8855 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8858 DEFUN (show_ip_bgp_route
,
8859 show_ip_bgp_route_cmd
,
8860 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
8861 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8865 BGP_INSTANCE_HELP_STR
8867 BGP_SAFI_WITH_LABEL_HELP_STR
8868 "Network in the BGP routing table to display\n"
8870 "Network in the BGP routing table to display\n"
8872 "Display only the bestpath\n"
8873 "Display only multipaths\n"
8876 int prefix_check
= 0;
8878 afi_t afi
= AFI_IP6
;
8879 safi_t safi
= SAFI_UNICAST
;
8880 char *prefix
= NULL
;
8881 struct bgp
*bgp
= NULL
;
8882 enum bgp_path_type path_type
;
8883 u_char uj
= use_json(argc
, argv
);
8887 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8894 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
8898 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8899 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8901 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8904 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8907 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
8910 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8913 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
8917 prefix
= argv
[idx
]->arg
;
8919 /* [<bestpath|multipath>] */
8920 if (argv_find (argv
, argc
, "bestpath", &idx
))
8921 path_type
= BGP_PATH_BESTPATH
;
8922 else if (argv_find (argv
, argc
, "multipath", &idx
))
8923 path_type
= BGP_PATH_MULTIPATH
;
8925 path_type
= BGP_PATH_ALL
;
8927 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8930 DEFUN (show_ip_bgp_regexp
,
8931 show_ip_bgp_regexp_cmd
,
8932 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
8936 BGP_INSTANCE_HELP_STR
8938 BGP_SAFI_WITH_LABEL_HELP_STR
8939 "Display routes matching the AS path regular expression\n"
8940 "A regular-expression to match the BGP AS paths\n")
8942 afi_t afi
= AFI_IP6
;
8943 safi_t safi
= SAFI_UNICAST
;
8944 struct bgp
*bgp
= NULL
;
8947 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8951 // get index of regex
8952 argv_find (argv
, argc
, "regexp", &idx
);
8955 char *regstr
= argv_concat (argv
, argc
, idx
);
8956 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8957 XFREE (MTYPE_TMP
, regstr
);
8961 DEFUN (show_ip_bgp_instance_all
,
8962 show_ip_bgp_instance_all_cmd
,
8963 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
8967 BGP_INSTANCE_ALL_HELP_STR
8969 BGP_SAFI_WITH_LABEL_HELP_STR
8973 safi_t safi
= SAFI_UNICAST
;
8974 struct bgp
*bgp
= NULL
;
8977 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8981 int uj
= use_json (argc
, argv
);
8984 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8989 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8990 safi_t safi
, enum bgp_show_type type
)
8995 regex
= bgp_regcomp (regstr
);
8998 vty_out (vty
, "Can't compile regexp %s\n", regstr
);
9002 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
9003 bgp_regex_free (regex
);
9008 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
9009 const char *prefix_list_str
, afi_t afi
,
9010 safi_t safi
, enum bgp_show_type type
)
9012 struct prefix_list
*plist
;
9014 plist
= prefix_list_lookup (afi
, prefix_list_str
);
9017 vty_out (vty
, "%% %s is not a valid prefix-list name\n",
9022 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
9026 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
9027 const char *filter
, afi_t afi
,
9028 safi_t safi
, enum bgp_show_type type
)
9030 struct as_list
*as_list
;
9032 as_list
= as_list_lookup (filter
);
9033 if (as_list
== NULL
)
9035 vty_out (vty
, "%% %s is not a valid AS-path access-list name\n",
9040 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9044 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
9045 const char *rmap_str
, afi_t afi
,
9046 safi_t safi
, enum bgp_show_type type
)
9048 struct route_map
*rmap
;
9050 rmap
= route_map_lookup_by_name (rmap_str
);
9053 vty_out (vty
, "%% %s is not a valid route-map name\n",
9058 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9062 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
9063 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
9065 struct community
*com
;
9072 b
= buffer_new (1024);
9073 for (i
= 0; i
< argc
; i
++)
9076 buffer_putc (b
, ' ');
9079 if (strmatch(argv
[i
]->text
, "unicast") || strmatch(argv
[i
]->text
, "multicast"))
9084 buffer_putstr (b
, argv
[i
]->arg
);
9086 buffer_putc (b
, '\0');
9088 str
= buffer_getstr (b
);
9091 com
= community_str2com (str
);
9092 XFREE (MTYPE_TMP
, str
);
9095 vty_out (vty
, "%% Community malformed: \n");
9099 ret
= bgp_show (vty
, bgp
, afi
, safi
,
9100 (exact
? bgp_show_type_community_exact
:
9101 bgp_show_type_community
), com
, 0);
9102 community_free (com
);
9108 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
9109 const char *com
, int exact
,
9110 afi_t afi
, safi_t safi
)
9112 struct community_list
*list
;
9114 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9117 vty_out (vty
, "%% %s is not a valid community-list name\n",com
);
9121 return bgp_show (vty
, bgp
, afi
, safi
,
9122 (exact
? bgp_show_type_community_list_exact
:
9123 bgp_show_type_community_list
), list
, 0);
9127 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
9128 const char *prefix
, afi_t afi
,
9129 safi_t safi
, enum bgp_show_type type
)
9136 ret
= str2prefix (prefix
, p
);
9139 vty_out (vty
, "%% Malformed Prefix\n");
9143 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
9148 static struct peer
*
9149 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
9150 const char *ip_str
, u_char use_json
)
9156 /* Get peer sockunion. */
9157 ret
= str2sockunion (ip_str
, &su
);
9160 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
9163 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9169 json_object
*json_no
= NULL
;
9170 json_no
= json_object_new_object();
9171 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
9172 vty_out (vty
, "%s\n", json_object_to_json_string(json_no
));
9173 json_object_free(json_no
);
9176 vty_out (vty
, "%% Malformed address or name: %s\n", ip_str
);
9183 /* Peer structure lookup. */
9184 peer
= peer_lookup (bgp
, &su
);
9189 json_object
*json_no
= NULL
;
9190 json_no
= json_object_new_object();
9191 json_object_string_add(json_no
, "warning","No such neighbor");
9192 vty_out (vty
, "%s\n", json_object_to_json_string(json_no
));
9193 json_object_free(json_no
);
9196 vty_out (vty
, "No such neighbor\n");
9205 BGP_STATS_MAXBITLEN
= 0,
9209 BGP_STATS_UNAGGREGATEABLE
,
9210 BGP_STATS_MAX_AGGREGATEABLE
,
9211 BGP_STATS_AGGREGATES
,
9213 BGP_STATS_ASPATH_COUNT
,
9214 BGP_STATS_ASPATH_MAXHOPS
,
9215 BGP_STATS_ASPATH_TOTHOPS
,
9216 BGP_STATS_ASPATH_MAXSIZE
,
9217 BGP_STATS_ASPATH_TOTSIZE
,
9218 BGP_STATS_ASN_HIGHEST
,
9222 static const char *table_stats_strs
[] =
9224 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9225 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9226 [BGP_STATS_RIB
] = "Total Advertisements",
9227 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9228 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
9229 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9230 [BGP_STATS_SPACE
] = "Address space advertised",
9231 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9232 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9233 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9234 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9235 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9236 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9237 [BGP_STATS_MAX
] = NULL
,
9240 struct bgp_table_stats
9242 struct bgp_table
*table
;
9243 unsigned long long counts
[BGP_STATS_MAX
];
9247 #define TALLY_SIGFIG 100000
9248 static unsigned long
9249 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9251 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9252 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9253 unsigned long ret
= newtot
/ count
;
9255 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9263 bgp_table_stats_walker (struct thread
*t
)
9265 struct bgp_node
*rn
;
9266 struct bgp_node
*top
;
9267 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
9268 unsigned int space
= 0;
9270 if (!(top
= bgp_table_top (ts
->table
)))
9273 switch (top
->p
.family
)
9276 space
= IPV4_MAX_BITLEN
;
9279 space
= IPV6_MAX_BITLEN
;
9283 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9285 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
9287 struct bgp_info
*ri
;
9288 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
9289 unsigned int rinum
= 0;
9297 ts
->counts
[BGP_STATS_PREFIXES
]++;
9298 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9301 ts
->counts
[BGP_STATS_AVGPLEN
]
9302 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9303 ts
->counts
[BGP_STATS_AVGPLEN
],
9307 /* check if the prefix is included by any other announcements */
9308 while (prn
&& !prn
->info
)
9309 prn
= bgp_node_parent_nolock (prn
);
9311 if (prn
== NULL
|| prn
== top
)
9313 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9314 /* announced address space */
9316 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
9319 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9321 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9324 ts
->counts
[BGP_STATS_RIB
]++;
9327 (CHECK_FLAG (ri
->attr
->flag
,
9328 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
9329 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9332 if (ri
->attr
&& ri
->attr
->aspath
)
9334 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
9335 unsigned int size
= aspath_size (ri
->attr
->aspath
);
9336 as_t highest
= aspath_highest (ri
->attr
->aspath
);
9338 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9340 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9341 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
9343 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9344 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
9346 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9347 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9349 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9350 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9351 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9353 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9354 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9355 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9358 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9359 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
9367 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
9369 struct bgp_table_stats ts
;
9372 if (!bgp
->rib
[afi
][safi
])
9374 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9379 vty_out (vty
, "BGP %s RIB statistics\n",
9380 afi_safi_print (afi
, safi
));
9382 /* labeled-unicast routes live in the unicast table */
9383 if (safi
== SAFI_LABELED_UNICAST
)
9384 safi
= SAFI_UNICAST
;
9386 memset (&ts
, 0, sizeof (ts
));
9387 ts
.table
= bgp
->rib
[afi
][safi
];
9388 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9390 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
9392 if (!table_stats_strs
[i
])
9398 case BGP_STATS_ASPATH_AVGHOPS
:
9399 case BGP_STATS_ASPATH_AVGSIZE
:
9400 case BGP_STATS_AVGPLEN
:
9401 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9402 vty_out (vty
, "%12.2f",
9403 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9406 case BGP_STATS_ASPATH_TOTHOPS
:
9407 case BGP_STATS_ASPATH_TOTSIZE
:
9408 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9409 vty_out (vty
, "%12.2f",
9411 (float)ts
.counts
[i
] /
9412 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
9415 case BGP_STATS_TOTPLEN
:
9416 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9417 vty_out (vty
, "%12.2f",
9419 (float)ts
.counts
[i
] /
9420 (float)ts
.counts
[BGP_STATS_PREFIXES
]
9423 case BGP_STATS_SPACE
:
9424 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9425 vty_out (vty
, "%12llu\n", ts
.counts
[i
]);
9426 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
9428 vty_out (vty
, "%30s: ", "%% announced ");
9429 vty_out (vty
, "%12.2f\n",
9430 100 * (float)ts
.counts
[BGP_STATS_SPACE
] / (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]));
9431 vty_out (vty
, "%30s: ", "/8 equivalent ");
9432 vty_out (vty
, "%12.2f\n",
9433 (float)ts
.counts
[BGP_STATS_SPACE
] / (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)));
9434 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9436 vty_out (vty
, "%30s: ", "/24 equivalent ");
9437 vty_out (vty
, "%12.2f",
9438 (float)ts
.counts
[BGP_STATS_SPACE
] /
9439 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9442 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9443 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9446 vty_out (vty
, "\n");
9461 PCOUNT_PFCNT
, /* the figure we display to users */
9465 static const char *pcount_strs
[] =
9467 [PCOUNT_ADJ_IN
] = "Adj-in",
9468 [PCOUNT_DAMPED
] = "Damped",
9469 [PCOUNT_REMOVED
] = "Removed",
9470 [PCOUNT_HISTORY
] = "History",
9471 [PCOUNT_STALE
] = "Stale",
9472 [PCOUNT_VALID
] = "Valid",
9473 [PCOUNT_ALL
] = "All RIB",
9474 [PCOUNT_COUNTED
] = "PfxCt counted",
9475 [PCOUNT_PFCNT
] = "Useable",
9476 [PCOUNT_MAX
] = NULL
,
9481 unsigned int count
[PCOUNT_MAX
];
9482 const struct peer
*peer
;
9483 const struct bgp_table
*table
;
9487 bgp_peer_count_walker (struct thread
*t
)
9489 struct bgp_node
*rn
;
9490 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9491 const struct peer
*peer
= pc
->peer
;
9493 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9495 struct bgp_adj_in
*ain
;
9496 struct bgp_info
*ri
;
9498 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9499 if (ain
->peer
== peer
)
9500 pc
->count
[PCOUNT_ADJ_IN
]++;
9502 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9504 char buf
[SU_ADDRSTRLEN
];
9506 if (ri
->peer
!= peer
)
9509 pc
->count
[PCOUNT_ALL
]++;
9511 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9512 pc
->count
[PCOUNT_DAMPED
]++;
9513 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9514 pc
->count
[PCOUNT_HISTORY
]++;
9515 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9516 pc
->count
[PCOUNT_REMOVED
]++;
9517 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9518 pc
->count
[PCOUNT_STALE
]++;
9519 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9520 pc
->count
[PCOUNT_VALID
]++;
9521 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9522 pc
->count
[PCOUNT_PFCNT
]++;
9524 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9526 pc
->count
[PCOUNT_COUNTED
]++;
9527 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9528 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9530 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9531 buf
, SU_ADDRSTRLEN
),
9537 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9538 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9540 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9541 buf
, SU_ADDRSTRLEN
),
9551 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9553 struct peer_pcounts pcounts
= { .peer
= peer
};
9555 json_object
*json
= NULL
;
9556 json_object
*json_loop
= NULL
;
9560 json
= json_object_new_object();
9561 json_loop
= json_object_new_object();
9564 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9565 || !peer
->bgp
->rib
[afi
][safi
])
9569 json_object_string_add(json
, "warning", "No such neighbor or address family");
9570 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9571 json_object_free(json
);
9574 vty_out (vty
, "%% No such neighbor or address family\n");
9579 memset (&pcounts
, 0, sizeof(pcounts
));
9580 pcounts
.peer
= peer
;
9581 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9583 /* in-place call via thread subsystem so as to record execution time
9584 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9585 * * on just vty_read()).
9587 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9591 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9592 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9593 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9595 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9596 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9598 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9600 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9602 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9603 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9605 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9606 json_object_free(json
);
9611 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9613 vty_out (vty
, "Prefix counts for %s/%s, %s\n",
9614 peer
->hostname
, peer
->host
,afi_safi_print(afi
, safi
));
9618 vty_out (vty
, "Prefix counts for %s, %s\n",
9619 peer
->host
, afi_safi_print(afi
, safi
));
9622 vty_out (vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9623 vty_out (vty
, "\nCounts from RIB table walk:\n\n");
9625 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9626 vty_out (vty
, "%20s: %-10d\n", pcount_strs
[i
], pcounts
.count
[i
]);
9628 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9630 vty_out (vty
, "%s [pcount] PfxCt drift!\n",
9633 "Please report this bug, with the above command output\n");
9640 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9641 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9642 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9643 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9647 BGP_INSTANCE_HELP_STR
9650 "Detailed information on TCP and BGP neighbor connections\n"
9651 "Neighbor to display information about\n"
9652 "Neighbor to display information about\n"
9653 "Neighbor on BGP configured interface\n"
9654 "Display detailed prefix count information\n"
9657 afi_t afi
= AFI_IP6
;
9658 safi_t safi
= SAFI_UNICAST
;
9661 struct bgp
*bgp
= NULL
;
9663 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9667 int uj
= use_json (argc
, argv
);
9670 argv_find (argv
, argc
, "neighbors", &idx
);
9671 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9675 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9678 #ifdef KEEP_OLD_VPN_COMMANDS
9679 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9680 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9681 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9686 "Display information about all VPNv4 NLRIs\n"
9687 "Detailed information on TCP and BGP neighbor connections\n"
9688 "Neighbor to display information about\n"
9689 "Neighbor to display information about\n"
9690 "Neighbor on BGP configured interface\n"
9691 "Display detailed prefix count information\n"
9696 u_char uj
= use_json(argc
, argv
);
9698 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9702 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9705 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9706 show_ip_bgp_vpn_all_route_prefix_cmd
,
9707 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9712 "Display information about all VPNv4 NLRIs\n"
9713 "Network in the BGP routing table to display\n"
9714 "Network in the BGP routing table to display\n"
9718 char *network
= NULL
;
9719 struct bgp
*bgp
= bgp_get_default();
9722 vty_out (vty
, "Can't find default instance\n");
9726 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9727 network
= argv
[idx
]->arg
;
9728 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9729 network
= argv
[idx
]->arg
;
9732 vty_out (vty
, "Unable to figure out Network\n");
9736 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9738 #endif /* KEEP_OLD_VPN_COMMANDS */
9740 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9741 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9742 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9748 "Display information about all EVPN NLRIs\n"
9749 "Network in the BGP routing table to display\n"
9750 "Network in the BGP routing table to display\n"
9754 char *network
= NULL
;
9756 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9757 network
= argv
[idx
]->arg
;
9758 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9759 network
= argv
[idx
]->arg
;
9762 vty_out (vty
, "Unable to figure out Network\n");
9765 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9769 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9770 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9772 struct bgp_table
*table
;
9773 struct bgp_adj_in
*ain
;
9774 struct bgp_adj_out
*adj
;
9775 unsigned long output_count
;
9776 unsigned long filtered_count
;
9777 struct bgp_node
*rn
;
9783 struct update_subgroup
*subgrp
;
9784 json_object
*json_scode
= NULL
;
9785 json_object
*json_ocode
= NULL
;
9786 json_object
*json_ar
= NULL
;
9787 struct peer_af
*paf
;
9791 json_scode
= json_object_new_object();
9792 json_ocode
= json_object_new_object();
9793 json_ar
= json_object_new_object();
9795 json_object_string_add(json_scode
, "suppressed", "s");
9796 json_object_string_add(json_scode
, "damped", "d");
9797 json_object_string_add(json_scode
, "history", "h");
9798 json_object_string_add(json_scode
, "valid", "*");
9799 json_object_string_add(json_scode
, "best", ">");
9800 json_object_string_add(json_scode
, "multipath", "=");
9801 json_object_string_add(json_scode
, "internal", "i");
9802 json_object_string_add(json_scode
, "ribFailure", "r");
9803 json_object_string_add(json_scode
, "stale", "S");
9804 json_object_string_add(json_scode
, "removed", "R");
9806 json_object_string_add(json_ocode
, "igp", "i");
9807 json_object_string_add(json_ocode
, "egp", "e");
9808 json_object_string_add(json_ocode
, "incomplete", "?");
9817 json_object_string_add(json
, "alert", "no BGP");
9818 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9819 json_object_free(json
);
9822 vty_out (vty
, "%% No bgp\n");
9826 table
= bgp
->rib
[afi
][safi
];
9828 output_count
= filtered_count
= 0;
9829 subgrp
= peer_subgroup(peer
, afi
, safi
);
9831 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9835 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9836 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9837 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9838 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9839 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9843 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s\n", table
->version
,
9844 inet_ntoa(bgp
->router_id
));
9845 vty_out (vty
, BGP_SHOW_SCODE_HEADER
);
9846 vty_out (vty
, BGP_SHOW_OCODE_HEADER
);
9848 vty_out (vty
, "Originating default network 0.0.0.0\n\n");
9853 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9857 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9859 if (ain
->peer
== peer
)
9865 json_object_int_add(json
, "bgpTableVersion", 0);
9866 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9867 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9868 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9872 vty_out (vty
, "BGP table version is 0, local router ID is %s\n",
9873 inet_ntoa(bgp
->router_id
));
9874 vty_out (vty
, BGP_SHOW_SCODE_HEADER
);
9875 vty_out (vty
, BGP_SHOW_OCODE_HEADER
);
9882 vty_out (vty
, BGP_SHOW_HEADER
);
9887 bgp_attr_dup(&attr
, ain
->attr
);
9888 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9890 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9901 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9902 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9903 if (paf
->peer
== peer
)
9909 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9910 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9911 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9912 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9916 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s\n", table
->version
,
9917 inet_ntoa(bgp
->router_id
));
9918 vty_out (vty
, BGP_SHOW_SCODE_HEADER
);
9919 vty_out (vty
, BGP_SHOW_OCODE_HEADER
);
9927 vty_out (vty
, BGP_SHOW_HEADER
);
9933 bgp_attr_dup(&attr
, adj
->attr
);
9934 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9935 if (ret
!= RMAP_DENY
)
9937 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9947 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9949 if (output_count
!= 0)
9952 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9954 vty_out (vty
, "\nTotal number of prefixes %ld\n", output_count
);
9958 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9959 json_object_free(json
);
9965 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9966 int in
, const char *rmap_name
, u_char use_json
)
9968 json_object
*json
= NULL
;
9971 json
= json_object_new_object();
9973 /* labeled-unicast routes live in the unicast table */
9974 if (safi
== SAFI_LABELED_UNICAST
)
9975 safi
= SAFI_UNICAST
;
9977 if (!peer
|| !peer
->afc
[afi
][safi
])
9981 json_object_string_add(json
, "warning", "No such neighbor or address family");
9982 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9983 json_object_free(json
);
9986 vty_out (vty
, "%% No such neighbor or address family\n");
9991 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9995 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9996 vty_out (vty
, "%s\n", json_object_to_json_string(json
));
9997 json_object_free(json
);
10000 vty_out (vty
, "%% Inbound soft reconfiguration not enabled\n");
10002 return CMD_WARNING
;
10005 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10007 return CMD_SUCCESS
;
10010 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10011 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10012 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10013 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10017 BGP_INSTANCE_HELP_STR
10019 BGP_SAFI_WITH_LABEL_HELP_STR
10020 "Detailed information on TCP and BGP neighbor connections\n"
10021 "Neighbor to display information about\n"
10022 "Neighbor to display information about\n"
10023 "Neighbor on BGP configured interface\n"
10024 "Display the received routes from neighbor\n"
10025 "Display the routes advertised to a BGP neighbor\n"
10026 "Route-map to modify the attributes\n"
10027 "Name of the route map\n"
10030 afi_t afi
= AFI_IP6
;
10031 safi_t safi
= SAFI_UNICAST
;
10032 char *rmap_name
= NULL
;
10033 char *peerstr
= NULL
;
10035 struct bgp
*bgp
= NULL
;
10040 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10042 return CMD_WARNING
;
10044 int uj
= use_json (argc
, argv
);
10047 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10048 argv_find (argv
, argc
, "neighbors", &idx
);
10049 peerstr
= argv
[++idx
]->arg
;
10051 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10053 return CMD_WARNING
;
10055 if (argv_find (argv
, argc
, "received-routes", &idx
))
10057 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
10059 if (argv_find (argv
, argc
, "route-map", &idx
))
10060 rmap_name
= argv
[++idx
]->arg
;
10062 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10065 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10066 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10067 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10073 "Address Family modifier\n"
10074 "Detailed information on TCP and BGP neighbor connections\n"
10075 "Neighbor to display information about\n"
10076 "Neighbor to display information about\n"
10077 "Neighbor on BGP configured interface\n"
10078 "Display information received from a BGP neighbor\n"
10079 "Display the prefixlist filter\n"
10082 afi_t afi
= AFI_IP6
;
10083 safi_t safi
= SAFI_UNICAST
;
10084 char *peerstr
= NULL
;
10087 union sockunion su
;
10093 /* show [ip] bgp */
10094 if (argv_find (argv
, argc
, "ip", &idx
))
10096 /* [<ipv4|ipv6> [unicast]] */
10097 if (argv_find (argv
, argc
, "ipv4", &idx
))
10099 if (argv_find (argv
, argc
, "ipv6", &idx
))
10101 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10102 argv_find (argv
, argc
, "neighbors", &idx
);
10103 peerstr
= argv
[++idx
]->arg
;
10105 u_char uj
= use_json(argc
, argv
);
10107 ret
= str2sockunion (peerstr
, &su
);
10110 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
10114 vty_out (vty
, "{}\n");
10116 vty_out (vty
, "%% Malformed address or name: %s\n", peerstr
);
10117 return CMD_WARNING
;
10122 peer
= peer_lookup (NULL
, &su
);
10126 vty_out (vty
, "{}\n");
10128 vty_out (vty
, "No peer\n");
10129 return CMD_WARNING
;
10133 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10134 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
10138 vty_out (vty
, "Address Family: %s\n", afi_safi_print(afi
, safi
));
10139 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
10144 vty_out (vty
, "{}\n");
10146 vty_out (vty
, "No functional output\n");
10149 return CMD_SUCCESS
;
10153 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10154 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
10156 if (! peer
|| ! peer
->afc
[afi
][safi
])
10160 json_object
*json_no
= NULL
;
10161 json_no
= json_object_new_object();
10162 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
10163 vty_out (vty
, "%s\n", json_object_to_json_string(json_no
));
10164 json_object_free(json_no
);
10167 vty_out (vty
, "%% No such neighbor or address family\n");
10168 return CMD_WARNING
;
10171 /* labeled-unicast routes live in the unicast table */
10172 if (safi
== SAFI_LABELED_UNICAST
)
10173 safi
= SAFI_UNICAST
;
10175 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10178 DEFUN (show_ip_bgp_neighbor_routes
,
10179 show_ip_bgp_neighbor_routes_cmd
,
10180 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10181 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10185 BGP_INSTANCE_HELP_STR
10187 BGP_SAFI_WITH_LABEL_HELP_STR
10188 "Detailed information on TCP and BGP neighbor connections\n"
10189 "Neighbor to display information about\n"
10190 "Neighbor to display information about\n"
10191 "Neighbor on BGP configured interface\n"
10192 "Display flap statistics of the routes learned from neighbor\n"
10193 "Display the dampened routes received from neighbor\n"
10194 "Display routes learned from neighbor\n"
10197 char *peerstr
= NULL
;
10198 struct bgp
*bgp
= NULL
;
10199 afi_t afi
= AFI_IP6
;
10200 safi_t safi
= SAFI_UNICAST
;
10202 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10206 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
10208 return CMD_WARNING
;
10210 int uj
= use_json (argc
, argv
);
10213 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10214 argv_find (argv
, argc
, "neighbors", &idx
);
10215 peerstr
= argv
[++idx
]->arg
;
10217 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
10220 vty_out (vty
, "No such neighbor\n");
10221 return CMD_WARNING
;
10224 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
10225 sh_type
= bgp_show_type_flap_neighbor
;
10226 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
10227 sh_type
= bgp_show_type_damp_neighbor
;
10228 else if (argv_find (argv
, argc
, "routes", &idx
))
10229 sh_type
= bgp_show_type_neighbor
;
10231 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
10234 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10236 struct bgp_distance
10238 /* Distance value for the IP source prefix. */
10241 /* Name of the access-list to be matched. */
10245 DEFUN (show_bgp_afi_vpn_rd_route
,
10246 show_bgp_afi_vpn_rd_route_cmd
,
10247 "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]",
10251 "Address Family modifier\n"
10252 "Display information for a route distinguisher\n"
10253 "Route Distinguisher\n"
10254 "Network in the BGP routing table to display\n"
10255 "Network in the BGP routing table to display\n"
10259 struct prefix_rd prd
;
10260 afi_t afi
= AFI_MAX
;
10263 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
10264 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
10267 vty_out (vty
, "%% Malformed Route Distinguisher\n");
10268 return CMD_WARNING
;
10270 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
10273 static struct bgp_distance
*
10274 bgp_distance_new (void)
10276 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
10280 bgp_distance_free (struct bgp_distance
*bdistance
)
10282 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
10286 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
10287 const char *ip_str
, const char *access_list_str
)
10294 struct bgp_node
*rn
;
10295 struct bgp_distance
*bdistance
;
10297 afi
= bgp_node_afi (vty
);
10298 safi
= bgp_node_safi (vty
);
10300 ret
= str2prefix (ip_str
, &p
);
10303 vty_out (vty
, "Malformed prefix\n");
10304 return CMD_WARNING_CONFIG_FAILED
;
10307 distance
= atoi (distance_str
);
10309 /* Get BGP distance node. */
10310 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
10313 bdistance
= rn
->info
;
10314 bgp_unlock_node (rn
);
10318 bdistance
= bgp_distance_new ();
10319 rn
->info
= bdistance
;
10322 /* Set distance value. */
10323 bdistance
->distance
= distance
;
10325 /* Reset access-list configuration. */
10326 if (bdistance
->access_list
)
10328 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10329 bdistance
->access_list
= NULL
;
10331 if (access_list_str
)
10332 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10334 return CMD_SUCCESS
;
10338 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
10339 const char *ip_str
, const char *access_list_str
)
10346 struct bgp_node
*rn
;
10347 struct bgp_distance
*bdistance
;
10349 afi
= bgp_node_afi (vty
);
10350 safi
= bgp_node_safi (vty
);
10352 ret
= str2prefix (ip_str
, &p
);
10355 vty_out (vty
, "Malformed prefix\n");
10356 return CMD_WARNING_CONFIG_FAILED
;
10359 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10362 vty_out (vty
, "Can't find specified prefix\n");
10363 return CMD_WARNING_CONFIG_FAILED
;
10366 bdistance
= rn
->info
;
10367 distance
= atoi(distance_str
);
10369 if (bdistance
->distance
!= distance
)
10371 vty_out (vty
, "Distance does not match configured\n");
10372 return CMD_WARNING_CONFIG_FAILED
;
10375 if (bdistance
->access_list
)
10376 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10377 bgp_distance_free (bdistance
);
10380 bgp_unlock_node (rn
);
10381 bgp_unlock_node (rn
);
10383 return CMD_SUCCESS
;
10386 /* Apply BGP information to distance method. */
10388 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10389 safi_t safi
, struct bgp
*bgp
)
10391 struct bgp_node
*rn
;
10394 struct bgp_distance
*bdistance
;
10395 struct access_list
*alist
;
10396 struct bgp_static
*bgp_static
;
10401 peer
= rinfo
->peer
;
10403 /* Check source address. */
10404 sockunion2hostprefix (&peer
->su
, &q
);
10405 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
10408 bdistance
= rn
->info
;
10409 bgp_unlock_node (rn
);
10411 if (bdistance
->access_list
)
10413 alist
= access_list_lookup (afi
, bdistance
->access_list
);
10414 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
10415 return bdistance
->distance
;
10418 return bdistance
->distance
;
10421 /* Backdoor check. */
10422 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
10425 bgp_static
= rn
->info
;
10426 bgp_unlock_node (rn
);
10428 if (bgp_static
->backdoor
)
10430 if (bgp
->distance_local
[afi
][safi
])
10431 return bgp
->distance_local
[afi
][safi
];
10433 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10437 if (peer
->sort
== BGP_PEER_EBGP
)
10439 if (bgp
->distance_ebgp
[afi
][safi
])
10440 return bgp
->distance_ebgp
[afi
][safi
];
10441 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10445 if (bgp
->distance_ibgp
[afi
][safi
])
10446 return bgp
->distance_ibgp
[afi
][safi
];
10447 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10451 DEFUN (bgp_distance
,
10453 "distance bgp (1-255) (1-255) (1-255)",
10454 "Define an administrative distance\n"
10456 "Distance for routes external to the AS\n"
10457 "Distance for routes internal to the AS\n"
10458 "Distance for local routes\n")
10460 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10461 int idx_number
= 2;
10462 int idx_number_2
= 3;
10463 int idx_number_3
= 4;
10467 afi
= bgp_node_afi (vty
);
10468 safi
= bgp_node_safi (vty
);
10470 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10471 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10472 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10473 return CMD_SUCCESS
;
10476 DEFUN (no_bgp_distance
,
10477 no_bgp_distance_cmd
,
10478 "no distance bgp [(1-255) (1-255) (1-255)]",
10480 "Define an administrative distance\n"
10482 "Distance for routes external to the AS\n"
10483 "Distance for routes internal to the AS\n"
10484 "Distance for local routes\n")
10486 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10490 afi
= bgp_node_afi (vty
);
10491 safi
= bgp_node_safi (vty
);
10493 bgp
->distance_ebgp
[afi
][safi
] = 0;
10494 bgp
->distance_ibgp
[afi
][safi
] = 0;
10495 bgp
->distance_local
[afi
][safi
] = 0;
10496 return CMD_SUCCESS
;
10500 DEFUN (bgp_distance_source
,
10501 bgp_distance_source_cmd
,
10502 "distance (1-255) A.B.C.D/M",
10503 "Define an administrative distance\n"
10504 "Administrative distance\n"
10505 "IP source prefix\n")
10507 int idx_number
= 1;
10508 int idx_ipv4_prefixlen
= 2;
10509 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10510 return CMD_SUCCESS
;
10513 DEFUN (no_bgp_distance_source
,
10514 no_bgp_distance_source_cmd
,
10515 "no distance (1-255) A.B.C.D/M",
10517 "Define an administrative distance\n"
10518 "Administrative distance\n"
10519 "IP source prefix\n")
10521 int idx_number
= 2;
10522 int idx_ipv4_prefixlen
= 3;
10523 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10524 return CMD_SUCCESS
;
10527 DEFUN (bgp_distance_source_access_list
,
10528 bgp_distance_source_access_list_cmd
,
10529 "distance (1-255) A.B.C.D/M WORD",
10530 "Define an administrative distance\n"
10531 "Administrative distance\n"
10532 "IP source prefix\n"
10533 "Access list name\n")
10535 int idx_number
= 1;
10536 int idx_ipv4_prefixlen
= 2;
10538 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10539 return CMD_SUCCESS
;
10542 DEFUN (no_bgp_distance_source_access_list
,
10543 no_bgp_distance_source_access_list_cmd
,
10544 "no distance (1-255) A.B.C.D/M WORD",
10546 "Define an administrative distance\n"
10547 "Administrative distance\n"
10548 "IP source prefix\n"
10549 "Access list name\n")
10551 int idx_number
= 2;
10552 int idx_ipv4_prefixlen
= 3;
10554 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10555 return CMD_SUCCESS
;
10558 DEFUN (ipv6_bgp_distance_source
,
10559 ipv6_bgp_distance_source_cmd
,
10560 "distance (1-255) X:X::X:X/M",
10561 "Define an administrative distance\n"
10562 "Administrative distance\n"
10563 "IP source prefix\n")
10565 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10566 return CMD_SUCCESS
;
10569 DEFUN (no_ipv6_bgp_distance_source
,
10570 no_ipv6_bgp_distance_source_cmd
,
10571 "no distance (1-255) X:X::X:X/M",
10573 "Define an administrative distance\n"
10574 "Administrative distance\n"
10575 "IP source prefix\n")
10577 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10578 return CMD_SUCCESS
;
10581 DEFUN (ipv6_bgp_distance_source_access_list
,
10582 ipv6_bgp_distance_source_access_list_cmd
,
10583 "distance (1-255) X:X::X:X/M WORD",
10584 "Define an administrative distance\n"
10585 "Administrative distance\n"
10586 "IP source prefix\n"
10587 "Access list name\n")
10589 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10590 return CMD_SUCCESS
;
10593 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10594 no_ipv6_bgp_distance_source_access_list_cmd
,
10595 "no distance (1-255) X:X::X:X/M WORD",
10597 "Define an administrative distance\n"
10598 "Administrative distance\n"
10599 "IP source prefix\n"
10600 "Access list name\n")
10602 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10603 return CMD_SUCCESS
;
10606 DEFUN (bgp_damp_set
,
10608 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10609 "BGP Specific commands\n"
10610 "Enable route-flap dampening\n"
10611 "Half-life time for the penalty\n"
10612 "Value to start reusing a route\n"
10613 "Value to start suppressing a route\n"
10614 "Maximum duration to suppress a stable route\n")
10616 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10617 int idx_half_life
= 2;
10619 int idx_suppress
= 4;
10620 int idx_max_suppress
= 5;
10621 int half
= DEFAULT_HALF_LIFE
* 60;
10622 int reuse
= DEFAULT_REUSE
;
10623 int suppress
= DEFAULT_SUPPRESS
;
10624 int max
= 4 * half
;
10628 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10629 reuse
= atoi (argv
[idx_reuse
]->arg
);
10630 suppress
= atoi (argv
[idx_suppress
]->arg
);
10631 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10633 else if (argc
== 3)
10635 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10639 if (suppress
< reuse
)
10641 vty_out (vty
,"Suppress value cannot be less than reuse value \n");
10645 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10646 half
, reuse
, suppress
, max
);
10649 DEFUN (bgp_damp_unset
,
10650 bgp_damp_unset_cmd
,
10651 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10653 "BGP Specific commands\n"
10654 "Enable route-flap dampening\n"
10655 "Half-life time for the penalty\n"
10656 "Value to start reusing a route\n"
10657 "Value to start suppressing a route\n"
10658 "Maximum duration to suppress a stable route\n")
10660 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10661 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10664 /* Display specified route of BGP table. */
10666 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10667 const char *ip_str
, afi_t afi
, safi_t safi
,
10668 struct prefix_rd
*prd
, int prefix_check
)
10671 struct prefix match
;
10672 struct bgp_node
*rn
;
10673 struct bgp_node
*rm
;
10674 struct bgp_info
*ri
;
10675 struct bgp_info
*ri_temp
;
10677 struct bgp_table
*table
;
10679 /* BGP structure lookup. */
10682 bgp
= bgp_lookup_by_name (view_name
);
10685 vty_out (vty
, "%% Can't find BGP instance %s\n", view_name
);
10686 return CMD_WARNING
;
10691 bgp
= bgp_get_default ();
10694 vty_out (vty
, "%% No BGP process is configured\n");
10695 return CMD_WARNING
;
10699 /* Check IP address argument. */
10700 ret
= str2prefix (ip_str
, &match
);
10703 vty_out (vty
, "%% address is malformed\n");
10704 return CMD_WARNING
;
10707 match
.family
= afi2family (afi
);
10709 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10711 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10713 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10716 if ((table
= rn
->info
) != NULL
)
10717 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10719 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10724 if (ri
->extra
&& ri
->extra
->damp_info
)
10726 ri_temp
= ri
->next
;
10727 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10735 bgp_unlock_node (rm
);
10741 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10743 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10748 if (ri
->extra
&& ri
->extra
->damp_info
)
10750 ri_temp
= ri
->next
;
10751 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10759 bgp_unlock_node (rn
);
10763 return CMD_SUCCESS
;
10766 DEFUN (clear_ip_bgp_dampening
,
10767 clear_ip_bgp_dampening_cmd
,
10768 "clear ip bgp dampening",
10772 "Clear route flap dampening information\n")
10774 bgp_damp_info_clean ();
10775 return CMD_SUCCESS
;
10778 DEFUN (clear_ip_bgp_dampening_prefix
,
10779 clear_ip_bgp_dampening_prefix_cmd
,
10780 "clear ip bgp dampening A.B.C.D/M",
10784 "Clear route flap dampening information\n"
10787 int idx_ipv4_prefixlen
= 4;
10788 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10789 SAFI_UNICAST
, NULL
, 1);
10792 DEFUN (clear_ip_bgp_dampening_address
,
10793 clear_ip_bgp_dampening_address_cmd
,
10794 "clear ip bgp dampening A.B.C.D",
10798 "Clear route flap dampening information\n"
10799 "Network to clear damping information\n")
10802 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10803 SAFI_UNICAST
, NULL
, 0);
10806 DEFUN (clear_ip_bgp_dampening_address_mask
,
10807 clear_ip_bgp_dampening_address_mask_cmd
,
10808 "clear ip bgp dampening A.B.C.D A.B.C.D",
10812 "Clear route flap dampening information\n"
10813 "Network to clear damping information\n"
10817 int idx_ipv4_2
= 5;
10819 char prefix_str
[BUFSIZ
];
10821 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10824 vty_out (vty
, "%% Inconsistent address and mask\n");
10825 return CMD_WARNING
;
10828 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10829 SAFI_UNICAST
, NULL
, 0);
10832 /* also used for encap safi */
10834 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10835 afi_t afi
, safi_t safi
, int *write
)
10837 struct bgp_node
*prn
;
10838 struct bgp_node
*rn
;
10839 struct bgp_table
*table
;
10841 struct prefix_rd
*prd
;
10842 struct bgp_static
*bgp_static
;
10843 mpls_label_t label
;
10844 char buf
[SU_ADDRSTRLEN
];
10845 char rdbuf
[RD_ADDRSTRLEN
];
10847 /* Network configuration. */
10848 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10849 if ((table
= prn
->info
) != NULL
)
10850 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10851 if ((bgp_static
= rn
->info
) != NULL
)
10854 prd
= (struct prefix_rd
*) &prn
->p
;
10856 /* "address-family" display. */
10857 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10859 /* "network" configuration display. */
10860 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10861 label
= decode_label (&bgp_static
->label
);
10863 vty_out (vty
, " network %s/%d rd %s",
10864 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10865 p
->prefixlen
, rdbuf
);
10866 if (safi
== SAFI_MPLS_VPN
)
10867 vty_out (vty
, " label %u", label
);
10869 if (bgp_static
->rmap
.name
)
10870 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10873 if (bgp_static
->backdoor
)
10874 vty_out (vty
, " backdoor");
10876 vty_out (vty
, "\n");
10882 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10883 afi_t afi
, safi_t safi
, int *write
)
10885 struct bgp_node
*prn
;
10886 struct bgp_node
*rn
;
10887 struct bgp_table
*table
;
10889 struct prefix_rd
*prd
;
10890 struct bgp_static
*bgp_static
;
10891 char buf
[PREFIX_STRLEN
];
10892 char buf2
[SU_ADDRSTRLEN
];
10893 char rdbuf
[RD_ADDRSTRLEN
];
10895 /* Network configuration. */
10896 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10897 if ((table
= prn
->info
) != NULL
)
10898 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10899 if ((bgp_static
= rn
->info
) != NULL
)
10901 char *macrouter
= NULL
;
10904 if(bgp_static
->router_mac
)
10905 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10906 if(bgp_static
->eth_s_id
)
10907 esi
= esi2str(bgp_static
->eth_s_id
);
10909 prd
= (struct prefix_rd
*) &prn
->p
;
10911 /* "address-family" display. */
10912 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10914 /* "network" configuration display. */
10915 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10917 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10919 prefix2str (p
, buf
, sizeof (buf
)),
10920 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10921 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10922 decode_label (&bgp_static
->label
), esi
, buf2
, macrouter
);
10923 vty_out (vty
, "\n");
10925 XFREE (MTYPE_TMP
, macrouter
);
10927 XFREE (MTYPE_TMP
, esi
);
10932 /* Configuration of static route announcement and aggregate
10935 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10936 afi_t afi
, safi_t safi
, int *write
)
10938 struct bgp_node
*rn
;
10940 struct bgp_static
*bgp_static
;
10941 struct bgp_aggregate
*bgp_aggregate
;
10942 char buf
[SU_ADDRSTRLEN
];
10944 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10945 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10947 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10948 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10950 /* Network configuration. */
10951 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10952 if ((bgp_static
= rn
->info
) != NULL
)
10956 /* "address-family" display. */
10957 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10959 /* "network" configuration display. */
10960 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10962 u_int32_t destination
;
10963 struct in_addr netmask
;
10965 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10966 masklen2ip (p
->prefixlen
, &netmask
);
10967 vty_out (vty
, " network %s",
10968 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10970 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10971 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10972 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10973 || p
->u
.prefix4
.s_addr
== 0)
10975 /* Natural mask is not display. */
10978 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10982 vty_out (vty
, " network %s/%d",
10983 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10987 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
10988 vty_out (vty
, " label-index %u", bgp_static
->label_index
);
10990 if (bgp_static
->rmap
.name
)
10991 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10994 if (bgp_static
->backdoor
)
10995 vty_out (vty
, " backdoor");
10998 vty_out (vty
, "\n");
11001 /* Aggregate-address configuration. */
11002 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
11003 if ((bgp_aggregate
= rn
->info
) != NULL
)
11007 /* "address-family" display. */
11008 bgp_config_write_family_header (vty
, afi
, safi
, write
);
11010 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
11012 struct in_addr netmask
;
11014 masklen2ip (p
->prefixlen
, &netmask
);
11015 vty_out (vty
, " aggregate-address %s %s",
11016 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
11017 inet_ntoa (netmask
));
11021 vty_out (vty
, " aggregate-address %s/%d",
11022 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
11026 if (bgp_aggregate
->as_set
)
11027 vty_out (vty
, " as-set");
11029 if (bgp_aggregate
->summary_only
)
11030 vty_out (vty
, " summary-only");
11032 vty_out (vty
, "\n");
11039 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11040 safi_t safi
, int *write
)
11042 struct bgp_node
*rn
;
11043 struct bgp_distance
*bdistance
;
11045 /* Distance configuration. */
11046 if (bgp
->distance_ebgp
[afi
][safi
]
11047 && bgp
->distance_ibgp
[afi
][safi
]
11048 && bgp
->distance_local
[afi
][safi
]
11049 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11050 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11051 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
11053 bgp_config_write_family_header (vty
, afi
, safi
, write
);
11054 vty_out (vty
, " distance bgp %d %d %d\n",
11055 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
11056 bgp
->distance_local
[afi
][safi
]);
11059 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
11060 rn
= bgp_route_next (rn
))
11061 if ((bdistance
= rn
->info
) != NULL
)
11063 char buf
[PREFIX_STRLEN
];
11065 bgp_config_write_family_header (vty
, afi
, safi
, write
);
11066 vty_out (vty
, " distance %d %s %s\n", bdistance
->distance
,
11067 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
11068 bdistance
->access_list
? bdistance
->access_list
: "");
11074 /* Allocate routing table structure and install commands. */
11076 bgp_route_init (void)
11081 /* Init BGP distance table. */
11082 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11083 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11084 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
11086 /* IPv4 BGP commands. */
11087 install_element (BGP_NODE
, &bgp_table_map_cmd
);
11088 install_element (BGP_NODE
, &bgp_network_cmd
);
11089 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
11090 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
11091 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
11092 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
11093 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11094 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
11095 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
11096 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
11097 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
11098 install_element (BGP_NODE
, &no_bgp_network_cmd
);
11099 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
11100 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
11102 install_element (BGP_NODE
, &aggregate_address_cmd
);
11103 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
11104 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
11105 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
11107 /* IPv4 unicast configuration. */
11108 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11109 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
11110 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
11111 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
11112 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
11113 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
11114 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11115 install_element (BGP_IPV4_NODE
, &bgp_network_label_index_cmd
);
11116 install_element (BGP_IPV4_NODE
, &bgp_network_label_index_route_map_cmd
);
11117 install_element (BGP_IPV4_NODE
, &no_bgp_network_label_index_cmd
);
11118 install_element (BGP_IPV4_NODE
, &no_bgp_network_label_index_route_map_cmd
);
11119 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11120 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
11121 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
11122 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
11124 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
11125 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11126 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11127 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11129 /* IPv4 multicast configuration. */
11130 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11131 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
11132 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
11133 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
11134 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
11135 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
11136 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11137 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11138 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
11139 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
11140 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
11141 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11142 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11143 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11144 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11146 /* IPv4 labeled-unicast configuration. */
11147 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11148 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
11149 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
11150 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11152 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11153 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11154 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11155 #ifdef KEEP_OLD_VPN_COMMANDS
11156 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11157 #endif /* KEEP_OLD_VPN_COMMANDS */
11158 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11159 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11161 /* BGP dampening clear commands */
11162 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11163 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11165 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11166 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11169 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11170 #ifdef KEEP_OLD_VPN_COMMANDS
11171 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11172 #endif /* KEEP_OLD_VPN_COMMANDS */
11174 /* New config IPv6 BGP commands. */
11175 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11176 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11177 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
11178 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11179 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
11180 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
11181 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
11182 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_route_map_cmd
);
11183 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_route_map_cmd
);
11185 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11186 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11188 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11189 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11191 install_element (BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11192 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11193 install_element (BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11194 install_element (BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11195 install_element (BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11197 install_element (BGP_NODE
, &bgp_distance_cmd
);
11198 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
11199 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
11200 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
11201 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11202 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11203 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
11204 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11205 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11206 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11207 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11208 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11209 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11210 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11211 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11212 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11213 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11214 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
11215 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
11216 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11217 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11218 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11219 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11220 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11221 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11222 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11223 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11224 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11225 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
11226 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
11228 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
11229 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
11230 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11231 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11233 /* IPv4 Multicast Mode */
11234 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11235 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11237 /* Large Communities */
11238 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11239 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11243 bgp_route_finish (void)
11248 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11249 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11251 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
11252 bgp_distance_table
[afi
][safi
] = NULL
;