1 /* BGP routing information
2 Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 Copyright (C) 2016 Job Snijders <job@instituut.net>
5 This file is part of GNU Zebra.
7 GNU Zebra is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 GNU Zebra is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Zebra; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "sockunion.h"
36 #include "workqueue.h"
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"
66 #include "bgpd/rfapi/rfapi_backend.h"
67 #include "bgpd/rfapi/vnc_import_bgp.h"
68 #include "bgpd/rfapi/vnc_export_bgp.h"
71 /* Extern from bgp_dump.c */
72 extern const char *bgp_origin_str
[];
73 extern const char *bgp_origin_long_str
[];
76 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
77 struct prefix_rd
*prd
)
80 struct bgp_node
*prn
= NULL
;
86 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
88 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
90 if (prn
->info
== NULL
)
91 prn
->info
= bgp_table_init (afi
, safi
);
93 bgp_unlock_node (prn
);
97 rn
= bgp_node_get (table
, p
);
99 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
105 /* Allocate bgp_info_extra */
106 static struct bgp_info_extra
*
107 bgp_info_extra_new (void)
109 struct bgp_info_extra
*new;
110 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
115 bgp_info_extra_free (struct bgp_info_extra
**extra
)
119 if ((*extra
)->damp_info
)
120 bgp_damp_info_free ((*extra
)->damp_info
, 0);
122 (*extra
)->damp_info
= NULL
;
124 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
130 /* Get bgp_info extra information for the given bgp_info, lazy allocated
133 struct bgp_info_extra
*
134 bgp_info_extra_get (struct bgp_info
*ri
)
137 ri
->extra
= bgp_info_extra_new();
141 /* Allocate new bgp info structure. */
145 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
148 /* Free bgp route information. */
150 bgp_info_free (struct bgp_info
*binfo
)
153 bgp_attr_unintern (&binfo
->attr
);
155 bgp_unlink_nexthop(binfo
);
156 bgp_info_extra_free (&binfo
->extra
);
157 bgp_info_mpath_free (&binfo
->mpath
);
159 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
161 XFREE (MTYPE_BGP_ROUTE
, binfo
);
165 bgp_info_lock (struct bgp_info
*binfo
)
172 bgp_info_unlock (struct bgp_info
*binfo
)
174 assert (binfo
&& binfo
->lock
> 0);
177 if (binfo
->lock
== 0)
180 zlog_debug ("%s: unlocked and freeing", __func__
);
181 zlog_backtrace (LOG_DEBUG
);
183 bgp_info_free (binfo
);
188 if (binfo
->lock
== 1)
190 zlog_debug ("%s: unlocked to 1", __func__
);
191 zlog_backtrace (LOG_DEBUG
);
199 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
201 struct bgp_info
*top
;
213 peer_lock (ri
->peer
); /* bgp_info peer reference */
216 /* Do the actual removal of info from RIB, for use by bgp_process
217 completion callback *only* */
219 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
222 ri
->next
->prev
= ri
->prev
;
224 ri
->prev
->next
= ri
->next
;
228 bgp_info_mpath_dequeue (ri
);
229 bgp_info_unlock (ri
);
230 bgp_unlock_node (rn
);
234 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
236 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
237 /* set of previous already took care of pcount */
238 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
241 /* undo the effects of a previous call to bgp_info_delete; typically
242 called when a route is deleted and then quickly re-added before the
243 deletion has been processed */
245 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
247 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
248 /* unset of previous already took care of pcount */
249 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
252 /* Adjust pcount as required */
254 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
256 struct bgp_table
*table
;
258 assert (rn
&& bgp_node_table (rn
));
259 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
261 table
= bgp_node_table (rn
);
263 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
266 if (!BGP_INFO_COUNTABLE (ri
)
267 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
270 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
272 /* slight hack, but more robust against errors. */
273 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
274 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
277 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
278 __func__
, ri
->peer
->host
);
279 zlog_backtrace (LOG_WARNING
);
280 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
283 else if (BGP_INFO_COUNTABLE (ri
)
284 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
286 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
287 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
292 /* Set/unset bgp_info flags, adjusting any other state as needed.
293 * This is here primarily to keep prefix-count in check.
296 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
298 SET_FLAG (ri
->flags
, flag
);
300 /* early bath if we know it's not a flag that changes countability state */
301 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
304 bgp_pcount_adjust (rn
, ri
);
308 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
310 UNSET_FLAG (ri
->flags
, flag
);
312 /* early bath if we know it's not a flag that changes countability state */
313 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
316 bgp_pcount_adjust (rn
, ri
);
319 /* Get MED value. If MED value is missing and "bgp bestpath
320 missing-as-worst" is specified, treat it as the worst value. */
322 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
324 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
328 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
336 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
338 if (ri
->addpath_rx_id
)
339 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
341 sprintf(buf
, "path %s", ri
->peer
->host
);
344 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
346 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
347 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
350 struct attr
*newattr
, *existattr
;
351 struct attr_extra
*newattre
, *existattre
;
352 bgp_peer_sort_t new_sort
;
353 bgp_peer_sort_t exist_sort
;
355 u_int32_t exist_pref
;
358 u_int32_t new_weight
;
359 u_int32_t exist_weight
;
360 uint32_t newm
, existm
;
361 struct in_addr new_id
;
362 struct in_addr exist_id
;
365 int internal_as_route
;
368 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
369 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
377 zlog_debug("%s: new is NULL", pfx_buf
);
382 bgp_info_path_with_addpath_rx_str (new, new_buf
);
387 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
393 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
394 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
395 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
399 existattr
= exist
->attr
;
400 newattre
= newattr
->extra
;
401 existattre
= existattr
->extra
;
403 /* 1. Weight check. */
404 new_weight
= exist_weight
= 0;
407 new_weight
= newattre
->weight
;
409 exist_weight
= existattre
->weight
;
411 if (new_weight
> exist_weight
)
414 zlog_debug("%s: %s wins over %s due to weight %d > %d",
415 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
419 if (new_weight
< exist_weight
)
422 zlog_debug("%s: %s loses to %s due to weight %d < %d",
423 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
427 /* 2. Local preference check. */
428 new_pref
= exist_pref
= bgp
->default_local_pref
;
430 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
431 new_pref
= newattr
->local_pref
;
432 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
433 exist_pref
= existattr
->local_pref
;
435 if (new_pref
> exist_pref
)
438 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
439 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
443 if (new_pref
< exist_pref
)
446 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
447 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
451 /* 3. Local route check. We prefer:
453 * - BGP_ROUTE_AGGREGATE
454 * - BGP_ROUTE_REDISTRIBUTE
456 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
459 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
460 pfx_buf
, new_buf
, exist_buf
);
464 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
467 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
468 pfx_buf
, new_buf
, exist_buf
);
472 /* 4. AS path length check. */
473 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
475 int exist_hops
= aspath_count_hops (existattr
->aspath
);
476 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
478 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
482 aspath_hops
= aspath_count_hops (newattr
->aspath
);
483 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
485 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
488 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
489 pfx_buf
, new_buf
, exist_buf
,
490 aspath_hops
, (exist_hops
+ exist_confeds
));
494 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
497 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
498 pfx_buf
, new_buf
, exist_buf
,
499 aspath_hops
, (exist_hops
+ exist_confeds
));
505 int newhops
= aspath_count_hops (newattr
->aspath
);
507 if (newhops
< exist_hops
)
510 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
511 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
515 if (newhops
> exist_hops
)
518 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
519 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
525 /* 5. Origin check. */
526 if (newattr
->origin
< existattr
->origin
)
529 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
530 pfx_buf
, new_buf
, exist_buf
,
531 bgp_origin_long_str
[newattr
->origin
],
532 bgp_origin_long_str
[existattr
->origin
]);
536 if (newattr
->origin
> existattr
->origin
)
539 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
540 pfx_buf
, new_buf
, exist_buf
,
541 bgp_origin_long_str
[newattr
->origin
],
542 bgp_origin_long_str
[existattr
->origin
]);
547 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
548 && aspath_count_hops (existattr
->aspath
) == 0);
549 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
550 && aspath_count_confeds (existattr
->aspath
) > 0
551 && aspath_count_hops (newattr
->aspath
) == 0
552 && aspath_count_hops (existattr
->aspath
) == 0);
554 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
555 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
557 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
558 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
559 || internal_as_route
)
561 new_med
= bgp_med_value (new->attr
, bgp
);
562 exist_med
= bgp_med_value (exist
->attr
, bgp
);
564 if (new_med
< exist_med
)
567 zlog_debug("%s: %s wins over %s due to MED %d < %d",
568 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
572 if (new_med
> exist_med
)
575 zlog_debug("%s: %s loses to %s due to MED %d > %d",
576 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
581 /* 7. Peer type check. */
582 new_sort
= new->peer
->sort
;
583 exist_sort
= exist
->peer
->sort
;
585 if (new_sort
== BGP_PEER_EBGP
586 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
589 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
590 pfx_buf
, new_buf
, exist_buf
);
594 if (exist_sort
== BGP_PEER_EBGP
595 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
598 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
599 pfx_buf
, new_buf
, exist_buf
);
603 /* 8. IGP metric check. */
607 newm
= new->extra
->igpmetric
;
609 existm
= exist
->extra
->igpmetric
;
614 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
615 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
622 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
623 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
627 /* 9. Same IGP metric. Compare the cluster list length as
628 representative of IGP hops metric. Rewrite the metric value
629 pair (newm, existm) with the cluster list length. Prefer the
630 path with smaller cluster list length. */
633 if (peer_sort (new->peer
) == BGP_PEER_IBGP
634 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
635 && (mpath_cfg
== NULL
||
636 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
637 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
639 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
640 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
645 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
646 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
653 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
654 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
660 /* 10. confed-external vs. confed-internal */
661 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
663 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
666 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
667 pfx_buf
, new_buf
, exist_buf
);
671 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
674 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
675 pfx_buf
, new_buf
, exist_buf
);
680 /* 11. Maximum path check. */
683 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
687 * For the two paths, all comparison steps till IGP metric
688 * have succeeded - including AS_PATH hop count. Since 'bgp
689 * bestpath as-path multipath-relax' knob is on, we don't need
690 * an exact match of AS_PATH. Thus, mark the paths are equal.
691 * That will trigger both these paths to get into the multipath
697 zlog_debug("%s: %s and %s are equal via multipath-relax",
698 pfx_buf
, new_buf
, exist_buf
);
700 else if (new->peer
->sort
== BGP_PEER_IBGP
)
702 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
707 zlog_debug("%s: %s and %s are equal via matching aspaths",
708 pfx_buf
, new_buf
, exist_buf
);
711 else if (new->peer
->as
== exist
->peer
->as
)
716 zlog_debug("%s: %s and %s are equal via same remote-as",
717 pfx_buf
, new_buf
, exist_buf
);
723 * TODO: If unequal cost ibgp multipath is enabled we can
724 * mark the paths as equal here instead of returning
729 zlog_debug("%s: %s wins over %s after IGP metric comparison",
730 pfx_buf
, new_buf
, exist_buf
);
732 zlog_debug("%s: %s loses to %s after IGP metric comparison",
733 pfx_buf
, new_buf
, exist_buf
);
738 /* 12. If both paths are external, prefer the path that was received
739 first (the oldest one). This step minimizes route-flap, since a
740 newer path won't displace an older one, even if it was the
741 preferred route based on the additional decision criteria below. */
742 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
743 && new_sort
== BGP_PEER_EBGP
744 && exist_sort
== BGP_PEER_EBGP
)
746 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
749 zlog_debug("%s: %s wins over %s due to oldest external",
750 pfx_buf
, new_buf
, exist_buf
);
754 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
757 zlog_debug("%s: %s loses to %s due to oldest external",
758 pfx_buf
, new_buf
, exist_buf
);
763 /* 13. Router-ID comparision. */
764 /* If one of the paths is "stale", the corresponding peer router-id will
765 * be 0 and would always win over the other path. If originator id is
766 * used for the comparision, it will decide which path is better.
768 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
769 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
771 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
772 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
773 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
775 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
777 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
780 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
781 pfx_buf
, new_buf
, exist_buf
);
785 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
788 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
789 pfx_buf
, new_buf
, exist_buf
);
793 /* 14. Cluster length comparision. */
794 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
795 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
797 if (new_cluster
< exist_cluster
)
800 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
801 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
805 if (new_cluster
> exist_cluster
)
808 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
809 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
813 /* 15. Neighbor address comparision. */
814 /* Do this only if neither path is "stale" as stale paths do not have
815 * valid peer information (as the connection may or may not be up).
817 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
820 zlog_debug("%s: %s wins over %s due to latter path being STALE",
821 pfx_buf
, new_buf
, exist_buf
);
825 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
828 zlog_debug("%s: %s loses to %s due to former path being STALE",
829 pfx_buf
, new_buf
, exist_buf
);
833 /* locally configured routes to advertise do not have su_remote */
834 if (new->peer
->su_remote
== NULL
)
836 if (exist
->peer
->su_remote
== NULL
)
839 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
844 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
845 pfx_buf
, new_buf
, exist_buf
);
852 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
853 pfx_buf
, new_buf
, exist_buf
);
858 zlog_debug("%s: %s wins over %s due to nothing left to compare",
859 pfx_buf
, new_buf
, exist_buf
);
864 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
865 * is preferred, or 0 if they are the same (usually will only occur if
866 * multipath is enabled
867 * This version is compatible with */
869 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
870 afi_t afi
, safi_t safi
)
874 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
888 static enum filter_type
889 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
890 afi_t afi
, safi_t safi
)
892 struct bgp_filter
*filter
;
894 filter
= &peer
->filter
[afi
][safi
];
896 #define FILTER_EXIST_WARN(F,f,filter) \
897 if (BGP_DEBUG (update, UPDATE_IN) \
898 && !(F ## _IN (filter))) \
899 zlog_warn ("%s: Could not find configured input %s-list %s!", \
900 peer->host, #f, F ## _IN_NAME(filter));
902 if (DISTRIBUTE_IN_NAME (filter
)) {
903 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
905 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
909 if (PREFIX_LIST_IN_NAME (filter
)) {
910 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
912 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
916 if (FILTER_LIST_IN_NAME (filter
)) {
917 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
919 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
923 return FILTER_PERMIT
;
924 #undef FILTER_EXIST_WARN
927 static enum filter_type
928 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
929 afi_t afi
, safi_t safi
)
931 struct bgp_filter
*filter
;
933 filter
= &peer
->filter
[afi
][safi
];
935 #define FILTER_EXIST_WARN(F,f,filter) \
936 if (BGP_DEBUG (update, UPDATE_OUT) \
937 && !(F ## _OUT (filter))) \
938 zlog_warn ("%s: Could not find configured output %s-list %s!", \
939 peer->host, #f, F ## _OUT_NAME(filter));
941 if (DISTRIBUTE_OUT_NAME (filter
)) {
942 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
944 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
948 if (PREFIX_LIST_OUT_NAME (filter
)) {
949 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
951 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
955 if (FILTER_LIST_OUT_NAME (filter
)) {
956 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
958 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
962 return FILTER_PERMIT
;
963 #undef FILTER_EXIST_WARN
966 /* If community attribute includes no_export then return 1. */
968 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
972 /* NO_ADVERTISE check. */
973 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
976 /* NO_EXPORT check. */
977 if (peer
->sort
== BGP_PEER_EBGP
&&
978 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
981 /* NO_EXPORT_SUBCONFED check. */
982 if (peer
->sort
== BGP_PEER_EBGP
983 || peer
->sort
== BGP_PEER_CONFED
)
984 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
990 /* Route reflection loop check. */
992 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
994 struct in_addr cluster_id
;
996 if (attr
->extra
&& attr
->extra
->cluster
)
998 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
999 cluster_id
= peer
->bgp
->cluster_id
;
1001 cluster_id
= peer
->bgp
->router_id
;
1003 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1010 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1011 afi_t afi
, safi_t safi
, const char *rmap_name
)
1013 struct bgp_filter
*filter
;
1014 struct bgp_info info
;
1015 route_map_result_t ret
;
1016 struct route_map
*rmap
= NULL
;
1018 filter
= &peer
->filter
[afi
][safi
];
1020 /* Apply default weight value. */
1021 if (peer
->weight
[afi
][safi
])
1022 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1026 rmap
= route_map_lookup_by_name(rmap_name
);
1033 if (ROUTE_MAP_IN_NAME(filter
))
1035 rmap
= ROUTE_MAP_IN (filter
);
1042 /* Route map apply. */
1045 /* Duplicate current value to new strucutre for modification. */
1049 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1051 /* Apply BGP route map to the attribute. */
1052 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1054 peer
->rmap_type
= 0;
1056 if (ret
== RMAP_DENYMATCH
)
1058 /* Free newly generated AS path and community by route-map. */
1059 bgp_attr_flush (attr
);
1067 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1068 afi_t afi
, safi_t safi
, const char *rmap_name
)
1070 struct bgp_filter
*filter
;
1071 struct bgp_info info
;
1072 route_map_result_t ret
;
1073 struct route_map
*rmap
= NULL
;
1075 filter
= &peer
->filter
[afi
][safi
];
1077 /* Apply default weight value. */
1078 if (peer
->weight
[afi
][safi
])
1079 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1083 rmap
= route_map_lookup_by_name(rmap_name
);
1090 if (ROUTE_MAP_OUT_NAME(filter
))
1092 rmap
= ROUTE_MAP_OUT (filter
);
1099 /* Route map apply. */
1102 /* Duplicate current value to new strucutre for modification. */
1106 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1108 /* Apply BGP route map to the attribute. */
1109 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1111 peer
->rmap_type
= 0;
1113 if (ret
== RMAP_DENYMATCH
)
1114 /* caller has multiple error paths with bgp_attr_flush() */
1120 /* If this is an EBGP peer with remove-private-AS */
1122 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1123 struct peer
*peer
, struct attr
*attr
)
1125 if (peer
->sort
== BGP_PEER_EBGP
&&
1126 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1127 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1128 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1129 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1131 // Take action on the entire aspath
1132 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1133 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1135 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1136 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1138 // The entire aspath consists of private ASNs so create an empty aspath
1139 else if (aspath_private_as_check (attr
->aspath
))
1140 attr
->aspath
= aspath_empty_get ();
1142 // There are some public and some private ASNs, remove the private ASNs
1144 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1147 // 'all' was not specified so the entire aspath must be private ASNs
1148 // for us to do anything
1149 else if (aspath_private_as_check (attr
->aspath
))
1151 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1152 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1154 attr
->aspath
= aspath_empty_get ();
1159 /* If this is an EBGP peer with as-override */
1161 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1162 struct peer
*peer
, struct attr
*attr
)
1164 if (peer
->sort
== BGP_PEER_EBGP
&&
1165 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1167 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1168 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1173 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1175 if (family
== AF_INET
)
1176 attr
->nexthop
.s_addr
= 0;
1177 if (family
== AF_INET6
)
1178 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1182 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1183 struct prefix
*p
, struct attr
*attr
)
1185 struct bgp_filter
*filter
;
1188 struct peer
*onlypeer
;
1190 struct attr
*riattr
;
1191 struct peer_af
*paf
;
1192 char buf
[SU_ADDRSTRLEN
];
1198 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1200 if (DISABLE_BGP_ANNOUNCE
)
1203 afi
= SUBGRP_AFI(subgrp
);
1204 safi
= SUBGRP_SAFI(subgrp
);
1205 peer
= SUBGRP_PEER(subgrp
);
1207 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1208 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1211 filter
= &peer
->filter
[afi
][safi
];
1212 bgp
= SUBGRP_INST(subgrp
);
1213 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1216 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1217 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1218 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1221 * direct and direct_ext type routes originate internally even
1222 * though they can have peer pointers that reference other systems
1225 prefix2str(p
, buf
, BUFSIZ
);
1226 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1231 /* With addpath we may be asked to TX all kinds of paths so make sure
1233 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1234 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1235 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1240 /* If this is not the bestpath then check to see if there is an enabled addpath
1241 * feature that requires us to advertise it */
1242 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1244 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1250 /* Aggregate-address suppress check. */
1251 if (ri
->extra
&& ri
->extra
->suppress
)
1252 if (! UNSUPPRESS_MAP_NAME (filter
))
1257 /* Do not send back route to sender. */
1258 if (onlypeer
&& from
== onlypeer
)
1263 /* Do not send the default route in the BGP table if the neighbor is
1264 * configured for default-originate */
1265 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1267 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1269 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1273 /* Transparency check. */
1274 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1275 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1280 /* If community is not disabled check the no-export and local. */
1281 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1283 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1284 zlog_debug ("subgrpannouncecheck: community filter check fail");
1288 /* If the attribute has originator-id and it is same as remote
1291 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1292 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1294 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1295 zlog_debug ("%s [Update:SEND] %s/%d originator-id is same as "
1298 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1303 /* ORF prefix-list filter check */
1304 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1305 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1306 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1307 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1308 if (peer
->orf_plist
[afi
][safi
])
1310 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1312 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1313 zlog_debug ("%s [Update:SEND] %s/%d is filtered via ORF",
1315 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1321 /* Output filter check. */
1322 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1324 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1325 zlog_debug ("%s [Update:SEND] %s/%d is filtered",
1327 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1332 #ifdef BGP_SEND_ASPATH_CHECK
1333 /* AS path loop check. */
1334 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1336 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1337 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1338 "that is part of AS path.",
1339 onlypeer
->host
, onlypeer
->as
);
1342 #endif /* BGP_SEND_ASPATH_CHECK */
1344 /* If we're a CONFED we need to loop check the CONFED ID too */
1345 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1347 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1349 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1350 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1358 /* Route-Reflect check. */
1359 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1364 /* IBGP reflection check. */
1365 if (reflect
&& !samepeer_safe
)
1367 /* A route from a Client peer. */
1368 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1370 /* Reflect to all the Non-Client peers and also to the
1371 Client peers other than the originator. Originator check
1372 is already done. So there is noting to do. */
1373 /* no bgp client-to-client reflection check. */
1374 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1375 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1376 PEER_FLAG_REFLECTOR_CLIENT
))
1381 /* A route from a Non-client peer. Reflect to all other
1383 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1384 PEER_FLAG_REFLECTOR_CLIENT
))
1389 /* For modify attribute, copy it to temporary structure. */
1390 bgp_attr_dup (attr
, riattr
);
1392 /* If local-preference is not set. */
1393 if ((peer
->sort
== BGP_PEER_IBGP
1394 || peer
->sort
== BGP_PEER_CONFED
)
1395 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1397 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1398 attr
->local_pref
= bgp
->default_local_pref
;
1401 /* If originator-id is not set and the route is to be reflected,
1402 set the originator id */
1403 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1405 attr
->extra
= bgp_attr_extra_get(attr
);
1406 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1407 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1410 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1411 if (peer
->sort
== BGP_PEER_EBGP
1412 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1414 if (from
!= bgp
->peer_self
&& ! transparent
1415 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1416 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1419 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1420 * in announce check, only certain flags and length (or number of nexthops
1421 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1422 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1423 * Typically, the source nexthop in the attribute is preserved but in the
1424 * scenarios where we know it will always be overwritten, we reset the
1425 * nexthop to "0" in an attempt to achieve better Update packing. An
1426 * example of this is when a prefix from each of 2 IBGP peers needs to be
1427 * announced to an EBGP peer (and they have the same attributes barring
1431 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1433 #define NEXTHOP_IS_V6 (\
1434 (safi != SAFI_ENCAP && \
1435 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1436 (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
1438 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1439 * the peer (group) is configured to receive link-local nexthop unchanged
1440 * and it is available in the prefix OR we're not reflecting the route and
1441 * the peer (group) to whom we're going to announce is on a shared network
1442 * and this is either a self-originated route or the peer is EBGP.
1446 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1447 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1448 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1449 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1450 (!reflect
&& peer
->shared_network
&&
1451 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1453 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1456 /* Clear off link-local nexthop in source, whenever it is not needed to
1457 * ensure more prefixes share the same attribute for announcement.
1459 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1460 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1461 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1464 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1465 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1467 /* Route map & unsuppress-map apply. */
1468 if (ROUTE_MAP_OUT_NAME (filter
)
1469 || (ri
->extra
&& ri
->extra
->suppress
) )
1471 struct bgp_info info
;
1472 struct attr dummy_attr
;
1473 struct attr_extra dummy_extra
;
1475 dummy_attr
.extra
= &dummy_extra
;
1479 /* don't confuse inbound and outbound setting */
1480 RESET_FLAG(attr
->rmap_change_flags
);
1483 * The route reflector is not allowed to modify the attributes
1484 * of the reflected IBGP routes unless explicitly allowed.
1486 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1487 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1489 bgp_attr_dup (&dummy_attr
, attr
);
1490 info
.attr
= &dummy_attr
;
1493 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1495 if (ri
->extra
&& ri
->extra
->suppress
)
1496 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1498 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1500 peer
->rmap_type
= 0;
1502 if (ret
== RMAP_DENYMATCH
)
1504 bgp_attr_flush (attr
);
1509 /* After route-map has been applied, we check to see if the nexthop to
1510 * be carried in the attribute (that is used for the announcement) can
1511 * be cleared off or not. We do this in all cases where we would be
1512 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1513 * the global nexthop here; the link-local nexthop would have been cleared
1514 * already, and if not, it is required by the update formation code.
1515 * Also see earlier comments in this function.
1518 * If route-map has performed some operation on the nexthop or the peer
1519 * configuration says to pass it unchanged, we cannot reset the nexthop
1520 * here, so only attempt to do it if these aren't true. Note that the
1521 * route-map handler itself might have cleared the nexthop, if for example,
1522 * it is configured as 'peer-address'.
1524 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1525 riattr
->rmap_change_flags
) &&
1527 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1529 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1530 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1531 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1534 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1535 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1536 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ?
1537 AF_INET6
: p
->family
), attr
);
1539 else if (peer
->sort
== BGP_PEER_EBGP
)
1541 /* Can also reset the nexthop if announcing to EBGP, but only if
1542 * no peer in the subgroup is on a shared subnet.
1543 * Note: 3rd party nexthop currently implemented for IPv4 only.
1545 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1547 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1551 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ? AF_INET6
: p
->family
), attr
);
1553 /* If IPv6/MP and nexthop does not have any override and happens to
1554 * be a link-local address, reset it so that we don't pass along the
1555 * source's link-local IPv6 address to recipients who may not be on
1556 * the same interface.
1558 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
))
1560 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1561 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1568 struct bgp_info_pair
1570 struct bgp_info
*old
;
1571 struct bgp_info
*new;
1575 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1576 struct bgp_maxpaths_cfg
*mpath_cfg
,
1577 struct bgp_info_pair
*result
)
1579 struct bgp_info
*new_select
;
1580 struct bgp_info
*old_select
;
1581 struct bgp_info
*ri
;
1582 struct bgp_info
*ri1
;
1583 struct bgp_info
*ri2
;
1584 struct bgp_info
*nextri
= NULL
;
1585 int paths_eq
, do_mpath
, debug
;
1586 struct list mp_list
;
1587 char pfx_buf
[PREFIX2STR_BUFFER
];
1588 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1590 bgp_mp_list_init (&mp_list
);
1591 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1593 debug
= bgp_debug_bestpath(&rn
->p
);
1596 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1598 /* bgp deterministic-med */
1600 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1603 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1604 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1605 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1607 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1609 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1611 if (BGP_INFO_HOLDDOWN (ri1
))
1613 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1614 if (ri1
->peer
->status
!= Established
)
1620 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1622 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1624 if (BGP_INFO_HOLDDOWN (ri2
))
1627 ri2
->peer
!= bgp
->peer_self
&&
1628 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1629 if (ri2
->peer
->status
!= Established
)
1632 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1633 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1636 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1637 mpath_cfg
, debug
, pfx_buf
))
1639 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1643 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1647 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1648 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1652 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1653 zlog_debug("%s: %s is the bestpath from AS %d",
1654 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1659 /* Check old selected route and new selected route. */
1662 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1664 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1667 if (BGP_INFO_HOLDDOWN (ri
))
1669 /* reap REMOVED routes, if needs be
1670 * selected route must stay for a while longer though
1672 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1673 && (ri
!= old_select
))
1674 bgp_info_reap (rn
, ri
);
1680 ri
->peer
!= bgp
->peer_self
&&
1681 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1682 if (ri
->peer
->status
!= Established
)
1685 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1686 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1688 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1692 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1694 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1700 /* Now that we know which path is the bestpath see if any of the other paths
1701 * qualify as multipaths
1706 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1708 sprintf (path_buf
, "NONE");
1709 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1711 old_select
? old_select
->peer
->host
: "NONE");
1714 if (do_mpath
&& new_select
)
1716 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1720 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1722 if (ri
== new_select
)
1725 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1727 bgp_mp_list_add (&mp_list
, ri
);
1731 if (BGP_INFO_HOLDDOWN (ri
))
1735 ri
->peer
!= bgp
->peer_self
&&
1736 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1737 if (ri
->peer
->status
!= Established
)
1740 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1743 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1748 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1753 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1755 bgp_mp_list_add (&mp_list
, ri
);
1760 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1761 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1762 bgp_mp_list_clear (&mp_list
);
1764 result
->old
= old_select
;
1765 result
->new = new_select
;
1771 * A new route/change in bestpath of an existing route. Evaluate the path
1772 * for advertisement to the subgroup.
1775 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1776 struct bgp_info
*selected
,
1777 struct bgp_node
*rn
,
1778 u_int32_t addpath_tx_id
)
1781 struct peer
*onlypeer
;
1783 struct attr_extra extra
;
1788 afi
= SUBGRP_AFI(subgrp
);
1789 safi
= SUBGRP_SAFI(subgrp
);
1790 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1791 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1793 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1794 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1795 PEER_STATUS_ORF_WAIT_REFRESH
))
1798 memset(&extra
, 0, sizeof(struct attr_extra
));
1799 /* It's initialized in bgp_announce_check() */
1800 attr
.extra
= &extra
;
1802 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1805 if (subgroup_announce_check(selected
, subgrp
, p
, &attr
))
1806 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1808 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1811 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1814 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1821 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1822 * This is called at the end of route processing.
1825 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1827 struct bgp_info
*ri
;
1829 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1831 if (BGP_INFO_HOLDDOWN (ri
))
1833 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1834 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1839 * Has the route changed from the RIB's perspective? This is invoked only
1840 * if the route selection returns the same best route as earlier - to
1841 * determine if we need to update zebra or not.
1844 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1846 struct bgp_info
*mpinfo
;
1848 /* If this is multipath, check all selected paths for any nexthop change or
1849 * attribute change. Some attribute changes (e.g., community) aren't of
1850 * relevance to the RIB, but we'll update zebra to ensure we handle the
1851 * case of BGP nexthop change. This is the behavior when the best path has
1852 * an attribute change anyway.
1854 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1855 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1858 /* If this is multipath, check all selected paths for any nexthop change */
1859 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1860 mpinfo
= bgp_info_mpath_next (mpinfo
))
1862 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1863 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1867 /* Nothing has changed from the RIB's perspective. */
1871 struct bgp_process_queue
1874 struct bgp_node
*rn
;
1879 static wq_item_status
1880 bgp_process_main (struct work_queue
*wq
, void *data
)
1882 struct bgp_process_queue
*pq
= data
;
1883 struct bgp
*bgp
= pq
->bgp
;
1884 struct bgp_node
*rn
= pq
->rn
;
1885 afi_t afi
= pq
->afi
;
1886 safi_t safi
= pq
->safi
;
1887 struct prefix
*p
= &rn
->p
;
1888 struct bgp_info
*new_select
;
1889 struct bgp_info
*old_select
;
1890 struct bgp_info_pair old_and_new
;
1892 /* Is it end of initial update? (after startup) */
1895 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1896 sizeof(bgp
->update_delay_zebra_resume_time
));
1898 bgp
->main_zebra_update_hold
= 0;
1899 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1900 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1902 bgp_zebra_announce_table(bgp
, afi
, safi
);
1904 bgp
->main_peers_update_hold
= 0;
1906 bgp_start_routeadv(bgp
);
1910 /* Best path selection. */
1911 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1912 old_select
= old_and_new
.old
;
1913 new_select
= old_and_new
.new;
1915 /* Nothing to do. */
1916 if (old_select
&& old_select
== new_select
&&
1917 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1918 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1919 !bgp
->addpath_tx_used
[afi
][safi
])
1921 if (bgp_zebra_has_route_changed (rn
, old_select
))
1924 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1925 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1927 bgp_zebra_announce (p
, old_select
, bgp
, afi
, safi
);
1929 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1930 bgp_zebra_clear_route_change_flags (rn
);
1931 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
1935 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
1936 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1938 /* bestpath has changed; bump version */
1939 if (old_select
|| new_select
)
1941 bgp_bump_version(rn
);
1943 if (!bgp
->t_rmap_def_originate_eval
)
1946 THREAD_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
1947 update_group_refresh_default_originate_route_map
,
1948 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
1953 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
1956 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
1957 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
1958 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1962 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
1963 if (old_select
!= new_select
) {
1965 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
1966 vnc_import_bgp_del_route(bgp
, p
, old_select
);
1969 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
1970 vnc_import_bgp_add_route(bgp
, p
, new_select
);
1976 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
1979 if ((safi
== SAFI_UNICAST
|| safi
== SAFI_MULTICAST
) &&
1980 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
1981 !bgp_option_check (BGP_OPT_NO_FIB
))
1984 && new_select
->type
== ZEBRA_ROUTE_BGP
1985 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
1986 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1987 bgp_zebra_announce (p
, new_select
, bgp
, afi
, safi
);
1990 /* Withdraw the route from the kernel. */
1992 && old_select
->type
== ZEBRA_ROUTE_BGP
1993 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
1994 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1995 bgp_zebra_withdraw (p
, old_select
, safi
);
1999 /* Clear any route change flags. */
2000 bgp_zebra_clear_route_change_flags (rn
);
2002 /* Reap old select bgp_info, if it has been removed */
2003 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2004 bgp_info_reap (rn
, old_select
);
2006 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2011 bgp_processq_del (struct work_queue
*wq
, void *data
)
2013 struct bgp_process_queue
*pq
= data
;
2014 struct bgp_table
*table
;
2016 bgp_unlock (pq
->bgp
);
2019 table
= bgp_node_table (pq
->rn
);
2020 bgp_unlock_node (pq
->rn
);
2021 bgp_table_unlock (table
);
2023 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2027 bgp_process_queue_init (void)
2029 if (!bm
->process_main_queue
)
2031 bm
->process_main_queue
2032 = work_queue_new (bm
->master
, "process_main_queue");
2034 if ( !bm
->process_main_queue
)
2036 zlog_err ("%s: Failed to allocate work queue", __func__
);
2041 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2042 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2043 bm
->process_main_queue
->spec
.max_retries
= 0;
2044 bm
->process_main_queue
->spec
.hold
= 50;
2045 /* Use a higher yield value of 50ms for main queue processing */
2046 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2050 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2052 struct bgp_process_queue
*pqnode
;
2054 /* already scheduled for processing? */
2055 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2058 if (bm
->process_main_queue
== NULL
)
2059 bgp_process_queue_init ();
2061 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2062 sizeof (struct bgp_process_queue
));
2066 /* all unlocked in bgp_processq_del */
2067 bgp_table_lock (bgp_node_table (rn
));
2068 pqnode
->rn
= bgp_lock_node (rn
);
2072 pqnode
->safi
= safi
;
2073 work_queue_add (bm
->process_main_queue
, pqnode
);
2074 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2079 bgp_add_eoiu_mark (struct bgp
*bgp
)
2081 struct bgp_process_queue
*pqnode
;
2083 if (bm
->process_main_queue
== NULL
)
2084 bgp_process_queue_init ();
2086 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2087 sizeof (struct bgp_process_queue
));
2094 work_queue_add (bm
->process_main_queue
, pqnode
);
2098 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2102 peer
= THREAD_ARG (thread
);
2103 peer
->t_pmax_restart
= NULL
;
2105 if (bgp_debug_neighbor_events(peer
))
2106 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2109 peer_clear (peer
, NULL
);
2115 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2116 safi_t safi
, int always
)
2121 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2124 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2126 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2130 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2131 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2132 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2133 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2135 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2138 /* Convert AFI, SAFI to values for packet. */
2139 pkt_afi
= afi_int2iana (afi
);
2140 pkt_safi
= safi_int2iana (safi
);
2144 ndata
[0] = (pkt_afi
>> 8);
2146 ndata
[2] = pkt_safi
;
2147 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2148 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2149 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2150 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2152 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2153 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2154 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2157 /* Dynamic peers will just close their connection. */
2158 if (peer_dynamic_neighbor (peer
))
2161 /* restart timer start */
2162 if (peer
->pmax_restart
[afi
][safi
])
2164 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2166 if (bgp_debug_neighbor_events(peer
))
2167 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2168 peer
->host
, peer
->v_pmax_restart
);
2170 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2171 peer
->v_pmax_restart
);
2177 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2179 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2181 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2185 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2186 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2187 peer
->pmax
[afi
][safi
]);
2188 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2191 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2195 /* Unconditionally remove the route from the RIB, without taking
2196 * damping into consideration (eg, because the session went down)
2199 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2200 afi_t afi
, safi_t safi
)
2202 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2204 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2205 bgp_info_delete (rn
, ri
); /* keep historical info */
2207 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2211 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2212 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2214 int status
= BGP_DAMP_NONE
;
2216 /* apply dampening, if result is suppressed, we'll be retaining
2217 * the bgp_info in the RIB for historical reference.
2219 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2220 && peer
->sort
== BGP_PEER_EBGP
)
2221 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2222 == BGP_DAMP_SUPPRESSED
)
2224 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2229 if (safi
== SAFI_MPLS_VPN
) {
2230 struct bgp_node
*prn
= NULL
;
2231 struct bgp_table
*table
= NULL
;
2233 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2235 table
= (struct bgp_table
*)(prn
->info
);
2237 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2244 bgp_unlock_node(prn
);
2246 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2247 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2249 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2250 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2254 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2257 static struct bgp_info
*
2258 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2259 struct bgp_node
*rn
)
2261 struct bgp_info
*new;
2263 /* Make new BGP info. */
2264 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2266 new->instance
= instance
;
2267 new->sub_type
= sub_type
;
2270 new->uptime
= bgp_clock ();
2272 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2277 bgp_info_addpath_rx_str(u_int32_t addpath_id
, char *buf
)
2280 sprintf(buf
, " with addpath ID %d", addpath_id
);
2284 /* Check if received nexthop is valid or not. */
2286 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2288 struct attr_extra
*attre
= attr
->extra
;
2291 /* Only validated for unicast and multicast currently. */
2292 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2295 /* If NEXT_HOP is present, validate it. */
2296 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2298 if (attr
->nexthop
.s_addr
== 0 ||
2299 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2300 bgp_nexthop_self (bgp
, attr
))
2304 /* If MP_NEXTHOP is present, validate it. */
2305 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2306 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2307 * it is not an IPv6 link-local address.
2309 if (attre
&& attre
->mp_nexthop_len
)
2311 switch (attre
->mp_nexthop_len
)
2313 case BGP_ATTR_NHLEN_IPV4
:
2314 case BGP_ATTR_NHLEN_VPNV4
:
2315 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2316 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2319 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2320 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2321 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2322 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2323 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2324 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2337 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2338 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2339 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2343 int aspath_loop_count
= 0;
2344 struct bgp_node
*rn
;
2346 struct attr new_attr
;
2347 struct attr_extra new_extra
;
2348 struct attr
*attr_new
;
2349 struct bgp_info
*ri
;
2350 struct bgp_info
*new;
2352 char buf
[SU_ADDRSTRLEN
];
2355 int do_loop_check
= 1;
2357 int vnc_implicit_withdraw
= 0;
2360 memset (&new_attr
, 0, sizeof(struct attr
));
2361 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2364 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2366 /* When peer's soft reconfiguration enabled. Record input packet in
2368 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2369 && peer
!= bgp
->peer_self
)
2370 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2372 /* Check previously received route. */
2373 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2374 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2375 ri
->addpath_rx_id
== addpath_id
)
2378 /* AS path local-as loop check. */
2379 if (peer
->change_local_as
)
2381 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2382 aspath_loop_count
= 1;
2384 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2386 reason
= "as-path contains our own AS;";
2391 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2392 * as-path is our ASN then we do not need to call aspath_loop_check
2394 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2395 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2398 /* AS path loop check. */
2401 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2402 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2403 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2405 reason
= "as-path contains our own AS;";
2410 /* Route reflector originator ID check. */
2411 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2412 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2414 reason
= "originator is us;";
2418 /* Route reflector cluster ID check. */
2419 if (bgp_cluster_filter (peer
, attr
))
2421 reason
= "reflected from the same cluster;";
2425 /* Apply incoming filter. */
2426 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2432 new_attr
.extra
= &new_extra
;
2433 bgp_attr_dup (&new_attr
, attr
);
2435 /* Apply incoming route-map.
2436 * NB: new_attr may now contain newly allocated values from route-map "set"
2437 * commands, so we need bgp_attr_flush in the error paths, until we intern
2438 * the attr (which takes over the memory references) */
2439 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2441 reason
= "route-map;";
2442 bgp_attr_flush (&new_attr
);
2446 /* next hop check. */
2447 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2449 reason
= "martian or self next-hop;";
2450 bgp_attr_flush (&new_attr
);
2454 attr_new
= bgp_attr_intern (&new_attr
);
2456 /* If the update is implicit withdraw. */
2459 ri
->uptime
= bgp_clock ();
2461 /* Same attribute comes in. */
2462 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2463 && attrhash_cmp (ri
->attr
, attr_new
))
2465 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2466 && peer
->sort
== BGP_PEER_EBGP
2467 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2469 if (bgp_debug_update(peer
, p
, NULL
, 1))
2471 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2472 zlog_debug ("%s rcvd %s/%d%s",
2474 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2475 p
->prefixlen
, buf2
);
2478 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2480 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2481 bgp_process (bgp
, rn
, afi
, safi
);
2484 else /* Duplicate - odd */
2486 if (bgp_debug_update(peer
, p
, NULL
, 1))
2488 if (!peer
->rcvd_attr_printed
)
2490 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2491 peer
->rcvd_attr_printed
= 1;
2494 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2495 zlog_debug ("%s rcvd %s/%d%s...duplicate ignored",
2497 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2498 p
->prefixlen
, buf2
);
2501 /* graceful restart STALE flag unset. */
2502 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2504 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2505 bgp_process (bgp
, rn
, afi
, safi
);
2509 bgp_unlock_node (rn
);
2510 bgp_attr_unintern (&attr_new
);
2515 /* Withdraw/Announce before we fully processed the withdraw */
2516 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2518 if (bgp_debug_update(peer
, p
, NULL
, 1))
2520 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2521 zlog_debug ("%s rcvd %s/%d%s, flapped quicker than processing",
2523 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2524 p
->prefixlen
, buf2
);
2526 bgp_info_restore (rn
, ri
);
2529 /* Received Logging. */
2530 if (bgp_debug_update(peer
, p
, NULL
, 1))
2532 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2533 zlog_debug ("%s rcvd %s/%d%s",
2535 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2536 p
->prefixlen
, buf2
);
2539 /* graceful restart STALE flag unset. */
2540 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2541 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2543 /* The attribute is changed. */
2544 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2546 /* implicit withdraw, decrement aggregate and pcount here.
2547 * only if update is accepted, they'll increment below.
2549 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2551 /* Update bgp route dampening information. */
2552 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2553 && peer
->sort
== BGP_PEER_EBGP
)
2555 /* This is implicit withdraw so we should update dampening
2557 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2558 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2561 if (safi
== SAFI_MPLS_VPN
) {
2562 struct bgp_node
*prn
= NULL
;
2563 struct bgp_table
*table
= NULL
;
2565 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2567 table
= (struct bgp_table
*)(prn
->info
);
2569 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2576 bgp_unlock_node(prn
);
2578 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2579 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2581 * Implicit withdraw case.
2583 ++vnc_implicit_withdraw
;
2584 vnc_import_bgp_del_route(bgp
, p
, ri
);
2585 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2590 /* Update to new attribute. */
2591 bgp_attr_unintern (&ri
->attr
);
2592 ri
->attr
= attr_new
;
2594 /* Update MPLS tag. */
2595 if (safi
== SAFI_MPLS_VPN
)
2596 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2599 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2601 if (vnc_implicit_withdraw
)
2604 * Add back the route with its new attributes (e.g., nexthop).
2605 * The route is still selected, until the route selection
2606 * queued by bgp_process actually runs. We have to make this
2607 * update to the VNC side immediately to avoid racing against
2608 * configuration changes (e.g., route-map changes) which
2609 * trigger re-importation of the entire RIB.
2611 vnc_import_bgp_add_route(bgp
, p
, ri
);
2612 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2617 /* Update bgp route dampening information. */
2618 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2619 && peer
->sort
== BGP_PEER_EBGP
)
2621 /* Now we do normal update dampening. */
2622 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2623 if (ret
== BGP_DAMP_SUPPRESSED
)
2625 bgp_unlock_node (rn
);
2630 /* Nexthop reachability check. */
2631 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2633 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2634 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2635 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2640 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2641 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2644 if (BGP_DEBUG(nht
, NHT
))
2646 char buf1
[INET6_ADDRSTRLEN
];
2647 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2648 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2650 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2654 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2657 if (safi
== SAFI_MPLS_VPN
)
2659 struct bgp_node
*prn
= NULL
;
2660 struct bgp_table
*table
= NULL
;
2662 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2665 table
= (struct bgp_table
*)(prn
->info
);
2667 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2674 bgp_unlock_node(prn
);
2678 /* Process change. */
2679 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2681 bgp_process (bgp
, rn
, afi
, safi
);
2682 bgp_unlock_node (rn
);
2685 } // End of implicit withdraw
2687 /* Received Logging. */
2688 if (bgp_debug_update(peer
, p
, NULL
, 1))
2690 if (!peer
->rcvd_attr_printed
)
2692 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2693 peer
->rcvd_attr_printed
= 1;
2696 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2697 zlog_debug ("%s rcvd %s/%d%s",
2699 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2700 p
->prefixlen
, buf2
);
2703 /* Make new BGP info. */
2704 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2706 /* Update MPLS tag. */
2707 if (safi
== SAFI_MPLS_VPN
)
2708 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2710 /* Nexthop reachability check. */
2711 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2713 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2714 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2715 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2720 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2721 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2724 if (BGP_DEBUG(nht
, NHT
))
2726 char buf1
[INET6_ADDRSTRLEN
];
2727 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2728 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2730 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2734 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2737 new->addpath_rx_id
= addpath_id
;
2739 /* Increment prefix */
2740 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2742 /* Register new BGP information. */
2743 bgp_info_add (rn
, new);
2745 /* route_node_get lock */
2746 bgp_unlock_node (rn
);
2749 if (safi
== SAFI_MPLS_VPN
)
2751 struct bgp_node
*prn
= NULL
;
2752 struct bgp_table
*table
= NULL
;
2754 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2757 table
= (struct bgp_table
*)(prn
->info
);
2759 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2766 bgp_unlock_node(prn
);
2770 /* If maximum prefix count is configured and current prefix
2772 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2775 /* Process change. */
2776 bgp_process (bgp
, rn
, afi
, safi
);
2780 /* This BGP update is filtered. Log the reason then update BGP
2783 if (bgp_debug_update(peer
, p
, NULL
, 1))
2785 if (!peer
->rcvd_attr_printed
)
2787 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2788 peer
->rcvd_attr_printed
= 1;
2791 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2792 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- DENIED due to: %s",
2794 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2795 p
->prefixlen
, buf2
, reason
);
2799 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2801 bgp_unlock_node (rn
);
2807 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2808 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2809 struct prefix_rd
*prd
, u_char
*tag
)
2812 char buf
[SU_ADDRSTRLEN
];
2814 struct bgp_node
*rn
;
2815 struct bgp_info
*ri
;
2820 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2822 /* If peer is soft reconfiguration enabled. Record input packet for
2823 * further calculation.
2825 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2826 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2827 * the iteration over all RS clients.
2828 * Since we need to remove the entry from adj_in anyway, do that first and
2829 * if there was no entry, we don't need to do anything more.
2831 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2832 && peer
!= bgp
->peer_self
)
2833 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2835 if (bgp_debug_update (peer
, p
, NULL
, 1))
2836 zlog_debug ("%s withdrawing route %s/%d "
2837 "not in adj-in", peer
->host
,
2838 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2840 bgp_unlock_node (rn
);
2844 /* Lookup withdrawn route. */
2845 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2846 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2847 ri
->addpath_rx_id
== addpath_id
)
2851 if (bgp_debug_update(peer
, p
, NULL
, 1))
2853 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2854 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- withdrawn",
2856 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2857 p
->prefixlen
, buf2
);
2860 /* Withdraw specified route from routing table. */
2861 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2862 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2863 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2864 zlog_debug ("%s Can't find the route %s/%d", peer
->host
,
2865 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2868 /* Unlock bgp_node_get() lock. */
2869 bgp_unlock_node (rn
);
2875 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2877 struct update_subgroup
*subgrp
;
2878 subgrp
= peer_subgroup(peer
, afi
, safi
);
2879 subgroup_default_originate(subgrp
, withdraw
);
2884 * bgp_stop_announce_route_timer
2887 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2889 if (!paf
->t_announce_route
)
2892 THREAD_TIMER_OFF (paf
->t_announce_route
);
2896 * bgp_announce_route_timer_expired
2898 * Callback that is invoked when the route announcement timer for a
2902 bgp_announce_route_timer_expired (struct thread
*t
)
2904 struct peer_af
*paf
;
2907 paf
= THREAD_ARG (t
);
2910 assert (paf
->t_announce_route
);
2911 paf
->t_announce_route
= NULL
;
2913 if (peer
->status
!= Established
)
2916 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
2919 peer_af_announce_route (paf
, 1);
2924 * bgp_announce_route
2926 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
2929 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
2931 struct peer_af
*paf
;
2932 struct update_subgroup
*subgrp
;
2934 paf
= peer_af_find (peer
, afi
, safi
);
2937 subgrp
= PAF_SUBGRP(paf
);
2940 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
2941 * or a refresh has already been triggered.
2943 if (!subgrp
|| paf
->t_announce_route
)
2947 * Start a timer to stagger/delay the announce. This serves
2948 * two purposes - announcement can potentially be combined for
2949 * multiple peers and the announcement doesn't happen in the
2952 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
2953 bgp_announce_route_timer_expired
, paf
,
2954 (subgrp
->peer_count
== 1) ?
2955 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
2956 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
2960 * Announce routes from all AF tables to a peer.
2962 * This should ONLY be called when there is a need to refresh the
2963 * routes to the peer based on a policy change for this peer alone
2964 * or a route refresh request received from the peer.
2965 * The operation will result in splitting the peer from its existing
2966 * subgroups and putting it in new subgroups.
2969 bgp_announce_route_all (struct peer
*peer
)
2974 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2975 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2976 bgp_announce_route (peer
, afi
, safi
);
2980 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
2981 struct bgp_table
*table
, struct prefix_rd
*prd
)
2984 struct bgp_node
*rn
;
2985 struct bgp_adj_in
*ain
;
2988 table
= peer
->bgp
->rib
[afi
][safi
];
2990 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
2991 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
2993 if (ain
->peer
== peer
)
2995 struct bgp_info
*ri
= rn
->info
;
2996 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
2998 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
2999 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3004 bgp_unlock_node (rn
);
3012 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3014 struct bgp_node
*rn
;
3015 struct bgp_table
*table
;
3017 if (peer
->status
!= Established
)
3020 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
))
3021 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3023 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3024 rn
= bgp_route_next (rn
))
3025 if ((table
= rn
->info
) != NULL
)
3027 struct prefix_rd prd
;
3028 prd
.family
= AF_UNSPEC
;
3030 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3032 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3037 struct bgp_clear_node_queue
3039 struct bgp_node
*rn
;
3042 static wq_item_status
3043 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3045 struct bgp_clear_node_queue
*cnq
= data
;
3046 struct bgp_node
*rn
= cnq
->rn
;
3047 struct peer
*peer
= wq
->spec
.data
;
3048 struct bgp_info
*ri
;
3049 afi_t afi
= bgp_node_table (rn
)->afi
;
3050 safi_t safi
= bgp_node_table (rn
)->safi
;
3052 assert (rn
&& peer
);
3054 /* It is possible that we have multiple paths for a prefix from a peer
3055 * if that peer is using AddPath.
3057 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3058 if (ri
->peer
== peer
)
3060 /* graceful restart STALE flag set. */
3061 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3062 && peer
->nsf
[afi
][safi
]
3063 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3064 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3065 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3067 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3073 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3075 struct bgp_clear_node_queue
*cnq
= data
;
3076 struct bgp_node
*rn
= cnq
->rn
;
3077 struct bgp_table
*table
= bgp_node_table (rn
);
3079 bgp_unlock_node (rn
);
3080 bgp_table_unlock (table
);
3081 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3085 bgp_clear_node_complete (struct work_queue
*wq
)
3087 struct peer
*peer
= wq
->spec
.data
;
3089 /* Tickle FSM to start moving again */
3090 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3092 peer_unlock (peer
); /* bgp_clear_route */
3096 bgp_clear_node_queue_init (struct peer
*peer
)
3098 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3100 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3101 #undef CLEAR_QUEUE_NAME_LEN
3103 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3105 zlog_err ("%s: Failed to allocate work queue", __func__
);
3108 peer
->clear_node_queue
->spec
.hold
= 10;
3109 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3110 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3111 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3112 peer
->clear_node_queue
->spec
.max_retries
= 0;
3114 /* we only 'lock' this peer reference when the queue is actually active */
3115 peer
->clear_node_queue
->spec
.data
= peer
;
3119 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3120 struct bgp_table
*table
)
3122 struct bgp_node
*rn
;
3123 int force
= bm
->process_main_queue
? 0 : 1;
3126 table
= peer
->bgp
->rib
[afi
][safi
];
3128 /* If still no table => afi/safi isn't configured at all or smth. */
3132 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3134 struct bgp_info
*ri
, *next
;
3135 struct bgp_adj_in
*ain
;
3136 struct bgp_adj_in
*ain_next
;
3138 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3139 * queued for every clearing peer, regardless of whether it is
3140 * relevant to the peer at hand.
3142 * Overview: There are 3 different indices which need to be
3143 * scrubbed, potentially, when a peer is removed:
3145 * 1 peer's routes visible via the RIB (ie accepted routes)
3146 * 2 peer's routes visible by the (optional) peer's adj-in index
3147 * 3 other routes visible by the peer's adj-out index
3149 * 3 there is no hurry in scrubbing, once the struct peer is
3150 * removed from bgp->peer, we could just GC such deleted peer's
3151 * adj-outs at our leisure.
3153 * 1 and 2 must be 'scrubbed' in some way, at least made
3154 * invisible via RIB index before peer session is allowed to be
3155 * brought back up. So one needs to know when such a 'search' is
3160 * - there'd be a single global queue or a single RIB walker
3161 * - rather than tracking which route_nodes still need to be
3162 * examined on a peer basis, we'd track which peers still
3165 * Given that our per-peer prefix-counts now should be reliable,
3166 * this may actually be achievable. It doesn't seem to be a huge
3167 * problem at this time,
3169 * It is possible that we have multiple paths for a prefix from a peer
3170 * if that peer is using AddPath.
3175 ain_next
= ain
->next
;
3177 if (ain
->peer
== peer
)
3179 bgp_adj_in_remove (rn
, ain
);
3180 bgp_unlock_node (rn
);
3186 for (ri
= rn
->info
; ri
; ri
= next
)
3189 if (ri
->peer
!= peer
)
3193 bgp_info_reap (rn
, ri
);
3196 struct bgp_clear_node_queue
*cnq
;
3198 /* both unlocked in bgp_clear_node_queue_del */
3199 bgp_table_lock (bgp_node_table (rn
));
3201 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3202 sizeof (struct bgp_clear_node_queue
));
3204 work_queue_add (peer
->clear_node_queue
, cnq
);
3213 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3215 struct bgp_node
*rn
;
3216 struct bgp_table
*table
;
3218 if (peer
->clear_node_queue
== NULL
)
3219 bgp_clear_node_queue_init (peer
);
3221 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3222 * Idle until it receives a Clearing_Completed event. This protects
3223 * against peers which flap faster than we can we clear, which could
3226 * a) race with routes from the new session being installed before
3227 * clear_route_node visits the node (to delete the route of that
3229 * b) resource exhaustion, clear_route_node likely leads to an entry
3230 * on the process_main queue. Fast-flapping could cause that queue
3234 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3235 * the unlock will happen upon work-queue completion; other wise, the
3236 * unlock happens at the end of this function.
3238 if (!peer
->clear_node_queue
->thread
)
3241 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
)
3242 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3244 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3245 rn
= bgp_route_next (rn
))
3246 if ((table
= rn
->info
) != NULL
)
3247 bgp_clear_route_table (peer
, afi
, safi
, table
);
3249 /* unlock if no nodes got added to the clear-node-queue. */
3250 if (!peer
->clear_node_queue
->thread
)
3256 bgp_clear_route_all (struct peer
*peer
)
3261 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3262 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3263 bgp_clear_route (peer
, afi
, safi
);
3266 rfapiProcessPeerDown(peer
);
3271 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3273 struct bgp_table
*table
;
3274 struct bgp_node
*rn
;
3275 struct bgp_adj_in
*ain
;
3276 struct bgp_adj_in
*ain_next
;
3278 table
= peer
->bgp
->rib
[afi
][safi
];
3280 /* It is possible that we have multiple paths for a prefix from a peer
3281 * if that peer is using AddPath.
3283 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3289 ain_next
= ain
->next
;
3291 if (ain
->peer
== peer
)
3293 bgp_adj_in_remove (rn
, ain
);
3294 bgp_unlock_node (rn
);
3303 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3305 struct bgp_node
*rn
;
3306 struct bgp_info
*ri
;
3307 struct bgp_table
*table
;
3309 if ( safi
== SAFI_MPLS_VPN
)
3311 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3313 struct bgp_node
*rm
;
3314 struct bgp_info
*ri
;
3316 /* look for neighbor in tables */
3317 if ((table
= rn
->info
) != NULL
)
3319 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3320 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3321 if (ri
->peer
== peer
)
3323 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3324 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3332 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3333 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3334 if (ri
->peer
== peer
)
3336 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3337 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3344 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3346 struct bgp_node
*rn
;
3347 struct bgp_info
*ri
;
3348 struct bgp_info
*next
;
3350 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3351 for (ri
= rn
->info
; ri
; ri
= next
)
3354 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3355 && ri
->type
== ZEBRA_ROUTE_BGP
3356 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3357 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3360 if (table
->owner
&& table
->owner
->bgp
)
3361 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3363 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3364 bgp_info_reap (rn
, ri
);
3369 /* Delete all kernel routes. */
3371 bgp_cleanup_routes (struct bgp
*bgp
)
3375 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3377 struct bgp_node
*rn
;
3379 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3382 * VPN and ENCAP tables are two-level (RD is top level)
3384 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
3385 rn
= bgp_route_next (rn
))
3389 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_MPLS_VPN
);
3390 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3392 bgp_unlock_node(rn
);
3396 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_ENCAP
]); rn
;
3397 rn
= bgp_route_next (rn
))
3401 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_ENCAP
);
3402 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3404 bgp_unlock_node(rn
);
3414 bgp_zclient_reset ();
3415 access_list_reset ();
3416 prefix_list_reset ();
3420 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3422 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3423 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3426 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3429 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3430 struct bgp_nlri
*packet
)
3439 int addpath_encoded
;
3440 u_int32_t addpath_id
;
3442 /* Check peer status. */
3443 if (peer
->status
!= Established
)
3447 lim
= pnt
+ packet
->length
;
3449 safi
= packet
->safi
;
3451 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3453 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3454 syntactic validity. If the field is syntactically incorrect,
3455 then the Error Subcode is set to Invalid Network Field. */
3456 for (; pnt
< lim
; pnt
+= psize
)
3458 /* Clear prefix structure. */
3459 memset (&p
, 0, sizeof (struct prefix
));
3461 if (addpath_encoded
)
3464 /* When packet overflow occurs return immediately. */
3465 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3468 addpath_id
= ntohl(*((uint32_t*) pnt
));
3469 pnt
+= BGP_ADDPATH_ID_LEN
;
3472 /* Fetch prefix length. */
3473 p
.prefixlen
= *pnt
++;
3474 /* afi/safi validity already verified by caller, bgp_update_receive */
3475 p
.family
= afi2family (afi
);
3477 /* Prefix length check. */
3478 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3480 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3481 peer
->host
, p
.prefixlen
, packet
->afi
);
3485 /* Packet size overflow check. */
3486 psize
= PSIZE (p
.prefixlen
);
3488 /* When packet overflow occur return immediately. */
3489 if (pnt
+ psize
> lim
)
3491 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3492 peer
->host
, p
.prefixlen
);
3496 /* Defensive coding, double-check the psize fits in a struct prefix */
3497 if (psize
> (ssize_t
) sizeof(p
.u
))
3499 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3500 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3504 /* Fetch prefix from NLRI packet. */
3505 memcpy (&p
.u
.prefix
, pnt
, psize
);
3507 /* Check address. */
3508 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3510 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3512 /* From RFC4271 Section 6.3:
3514 * If a prefix in the NLRI field is semantically incorrect
3515 * (e.g., an unexpected multicast IP address), an error SHOULD
3516 * be logged locally, and the prefix SHOULD be ignored.
3518 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3519 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3524 /* Check address. */
3525 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3527 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3531 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3532 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3536 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3540 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3541 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3547 /* Normal process. */
3549 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3550 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0);
3552 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3553 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
);
3555 /* Address family configuration mismatch or maximum-prefix count
3561 /* Packet length consistency check. */
3564 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3572 static struct bgp_static
*
3573 bgp_static_new (void)
3575 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3579 bgp_static_free (struct bgp_static
*bgp_static
)
3581 if (bgp_static
->rmap
.name
)
3582 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3583 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3587 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3588 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3590 struct bgp_node
*rn
;
3591 struct bgp_info
*ri
;
3592 struct bgp_info
*new;
3593 struct bgp_info info
;
3595 struct attr
*attr_new
;
3598 int vnc_implicit_withdraw
= 0;
3601 assert (bgp_static
);
3605 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3607 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3609 attr
.nexthop
= bgp_static
->igpnexthop
;
3610 attr
.med
= bgp_static
->igpmetric
;
3611 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3613 if (bgp_static
->atomic
)
3614 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3616 /* Apply route-map. */
3617 if (bgp_static
->rmap
.name
)
3619 struct attr attr_tmp
= attr
;
3620 info
.peer
= bgp
->peer_self
;
3621 info
.attr
= &attr_tmp
;
3623 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3625 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3627 bgp
->peer_self
->rmap_type
= 0;
3629 if (ret
== RMAP_DENYMATCH
)
3631 /* Free uninterned attribute. */
3632 bgp_attr_flush (&attr_tmp
);
3634 /* Unintern original. */
3635 aspath_unintern (&attr
.aspath
);
3636 bgp_attr_extra_free (&attr
);
3637 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3640 attr_new
= bgp_attr_intern (&attr_tmp
);
3643 attr_new
= bgp_attr_intern (&attr
);
3645 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3646 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3647 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3652 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3653 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3654 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3656 bgp_unlock_node (rn
);
3657 bgp_attr_unintern (&attr_new
);
3658 aspath_unintern (&attr
.aspath
);
3659 bgp_attr_extra_free (&attr
);
3664 /* The attribute is changed. */
3665 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3667 /* Rewrite BGP route information. */
3668 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3669 bgp_info_restore(rn
, ri
);
3671 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3673 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3675 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3678 * Implicit withdraw case.
3679 * We have to do this before ri is changed
3681 ++vnc_implicit_withdraw
;
3682 vnc_import_bgp_del_route(bgp
, p
, ri
);
3683 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3687 bgp_attr_unintern (&ri
->attr
);
3688 ri
->attr
= attr_new
;
3689 ri
->uptime
= bgp_clock ();
3691 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3693 if (vnc_implicit_withdraw
)
3695 vnc_import_bgp_add_route(bgp
, p
, ri
);
3696 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3701 /* Nexthop reachability check. */
3702 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3704 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3705 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3708 if (BGP_DEBUG(nht
, NHT
))
3710 char buf1
[INET6_ADDRSTRLEN
];
3711 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3713 zlog_debug("%s(%s): Route not in table, not advertising",
3714 __FUNCTION__
, buf1
);
3716 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3721 /* Delete the NHT structure if any, if we're toggling between
3722 * enabling/disabling import check. We deregister the route
3723 * from NHT to avoid overloading NHT and the process interaction
3725 bgp_unlink_nexthop(ri
);
3726 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3728 /* Process change. */
3729 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3730 bgp_process (bgp
, rn
, afi
, safi
);
3731 bgp_unlock_node (rn
);
3732 aspath_unintern (&attr
.aspath
);
3733 bgp_attr_extra_free (&attr
);
3738 /* Make new BGP info. */
3739 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3741 /* Nexthop reachability check. */
3742 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3744 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3745 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3748 if (BGP_DEBUG(nht
, NHT
))
3750 char buf1
[INET6_ADDRSTRLEN
];
3751 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3753 zlog_debug("%s(%s): Route not in table, not advertising",
3754 __FUNCTION__
, buf1
);
3756 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3761 /* Delete the NHT structure if any, if we're toggling between
3762 * enabling/disabling import check. We deregister the route
3763 * from NHT to avoid overloading NHT and the process interaction
3765 bgp_unlink_nexthop(new);
3767 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3770 /* Aggregate address increment. */
3771 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3773 /* Register new BGP information. */
3774 bgp_info_add (rn
, new);
3776 /* route_node_get lock */
3777 bgp_unlock_node (rn
);
3779 /* Process change. */
3780 bgp_process (bgp
, rn
, afi
, safi
);
3782 /* Unintern original. */
3783 aspath_unintern (&attr
.aspath
);
3784 bgp_attr_extra_free (&attr
);
3788 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3789 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3791 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3795 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3798 struct bgp_node
*rn
;
3799 struct bgp_info
*ri
;
3801 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3803 /* Check selected route and self inserted route. */
3804 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3805 if (ri
->peer
== bgp
->peer_self
3806 && ri
->type
== ZEBRA_ROUTE_BGP
3807 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3810 /* Withdraw static BGP route from routing table. */
3813 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3814 bgp_unlink_nexthop(ri
);
3815 bgp_info_delete (rn
, ri
);
3816 bgp_process (bgp
, rn
, afi
, safi
);
3819 /* Unlock bgp_node_lookup. */
3820 bgp_unlock_node (rn
);
3824 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3827 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3828 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3830 struct bgp_node
*rn
;
3831 struct bgp_info
*ri
;
3833 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3835 /* Check selected route and self inserted route. */
3836 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3837 if (ri
->peer
== bgp
->peer_self
3838 && ri
->type
== ZEBRA_ROUTE_BGP
3839 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3842 /* Withdraw static BGP route from routing table. */
3846 rfapiProcessWithdraw(
3855 1); /* Kill, since it is an administrative change */
3857 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3858 bgp_info_delete (rn
, ri
);
3859 bgp_process (bgp
, rn
, afi
, safi
);
3862 /* Unlock bgp_node_lookup. */
3863 bgp_unlock_node (rn
);
3867 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3868 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3870 struct bgp_node
*rn
;
3871 struct bgp_info
*new;
3872 struct attr
*attr_new
;
3873 struct attr attr
= { 0 };
3874 struct bgp_info
*ri
;
3876 u_int32_t label
= 0;
3879 assert (bgp_static
);
3881 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
3883 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3885 attr
.nexthop
= bgp_static
->igpnexthop
;
3886 attr
.med
= bgp_static
->igpmetric
;
3887 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3889 /* Apply route-map. */
3890 if (bgp_static
->rmap
.name
)
3892 struct attr attr_tmp
= attr
;
3893 struct bgp_info info
;
3896 info
.peer
= bgp
->peer_self
;
3897 info
.attr
= &attr_tmp
;
3899 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3901 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3903 bgp
->peer_self
->rmap_type
= 0;
3905 if (ret
== RMAP_DENYMATCH
)
3907 /* Free uninterned attribute. */
3908 bgp_attr_flush (&attr_tmp
);
3910 /* Unintern original. */
3911 aspath_unintern (&attr
.aspath
);
3912 bgp_attr_extra_free (&attr
);
3913 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
3918 attr_new
= bgp_attr_intern (&attr_tmp
);
3922 attr_new
= bgp_attr_intern (&attr
);
3925 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3926 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3927 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3932 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3933 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3935 bgp_unlock_node (rn
);
3936 bgp_attr_unintern (&attr_new
);
3937 aspath_unintern (&attr
.aspath
);
3938 bgp_attr_extra_free (&attr
);
3943 /* The attribute is changed. */
3944 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3946 /* Rewrite BGP route information. */
3947 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3948 bgp_info_restore(rn
, ri
);
3950 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3951 bgp_attr_unintern (&ri
->attr
);
3952 ri
->attr
= attr_new
;
3953 ri
->uptime
= bgp_clock ();
3956 label
= decode_label (ri
->extra
->tag
);
3959 /* Process change. */
3960 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3961 bgp_process (bgp
, rn
, afi
, safi
);
3963 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
3964 ri
->attr
, afi
, safi
,
3965 ri
->type
, ri
->sub_type
, &label
);
3967 bgp_unlock_node (rn
);
3968 aspath_unintern (&attr
.aspath
);
3969 bgp_attr_extra_free (&attr
);
3975 /* Make new BGP info. */
3976 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3978 SET_FLAG (new->flags
, BGP_INFO_VALID
);
3979 new->extra
= bgp_info_extra_new();
3980 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
3982 label
= decode_label (bgp_static
->tag
);
3985 /* Aggregate address increment. */
3986 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3988 /* Register new BGP information. */
3989 bgp_info_add (rn
, new);
3991 /* route_node_get lock */
3992 bgp_unlock_node (rn
);
3994 /* Process change. */
3995 bgp_process (bgp
, rn
, afi
, safi
);
3998 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
3999 new->attr
, afi
, safi
,
4000 new->type
, new->sub_type
, &label
);
4003 /* Unintern original. */
4004 aspath_unintern (&attr
.aspath
);
4005 bgp_attr_extra_free (&attr
);
4008 /* Configure static BGP network. When user don't run zebra, static
4009 route should be installed as valid. */
4011 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4012 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4014 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4017 struct bgp_static
*bgp_static
;
4018 struct bgp_node
*rn
;
4019 u_char need_update
= 0;
4021 /* Convert IP prefix string to struct prefix. */
4022 ret
= str2prefix (ip_str
, &p
);
4025 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4028 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4030 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4037 /* Set BGP static route configuration. */
4038 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4042 /* Configuration change. */
4043 bgp_static
= rn
->info
;
4045 /* Check previous routes are installed into BGP. */
4046 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4049 bgp_static
->backdoor
= backdoor
;
4053 if (bgp_static
->rmap
.name
)
4054 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4055 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4056 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4060 if (bgp_static
->rmap
.name
)
4061 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4062 bgp_static
->rmap
.name
= NULL
;
4063 bgp_static
->rmap
.map
= NULL
;
4064 bgp_static
->valid
= 0;
4066 bgp_unlock_node (rn
);
4070 /* New configuration. */
4071 bgp_static
= bgp_static_new ();
4072 bgp_static
->backdoor
= backdoor
;
4073 bgp_static
->valid
= 0;
4074 bgp_static
->igpmetric
= 0;
4075 bgp_static
->igpnexthop
.s_addr
= 0;
4079 if (bgp_static
->rmap
.name
)
4080 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4081 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4082 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4084 rn
->info
= bgp_static
;
4087 bgp_static
->valid
= 1;
4089 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4091 if (! bgp_static
->backdoor
)
4092 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4097 /* Configure static BGP network. */
4099 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4100 afi_t afi
, safi_t safi
)
4102 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4105 struct bgp_static
*bgp_static
;
4106 struct bgp_node
*rn
;
4108 /* Convert IP prefix string to struct prefix. */
4109 ret
= str2prefix (ip_str
, &p
);
4112 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4115 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4117 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4124 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4127 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4132 bgp_static
= rn
->info
;
4134 /* Update BGP RIB. */
4135 if (! bgp_static
->backdoor
)
4136 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4138 /* Clear configuration. */
4139 bgp_static_free (bgp_static
);
4141 bgp_unlock_node (rn
);
4142 bgp_unlock_node (rn
);
4148 bgp_static_add (struct bgp
*bgp
)
4152 struct bgp_node
*rn
;
4153 struct bgp_node
*rm
;
4154 struct bgp_table
*table
;
4155 struct bgp_static
*bgp_static
;
4157 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4158 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4159 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4160 if (rn
->info
!= NULL
)
4162 if (safi
== SAFI_MPLS_VPN
)
4166 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4168 bgp_static
= rn
->info
;
4169 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4174 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4179 /* Called from bgp_delete(). Delete all static routes from the BGP
4182 bgp_static_delete (struct bgp
*bgp
)
4186 struct bgp_node
*rn
;
4187 struct bgp_node
*rm
;
4188 struct bgp_table
*table
;
4189 struct bgp_static
*bgp_static
;
4191 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4192 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4193 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4194 if (rn
->info
!= NULL
)
4196 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4200 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4202 bgp_static
= rn
->info
;
4203 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4205 (struct prefix_rd
*)&rn
->p
,
4207 bgp_static_free (bgp_static
);
4209 bgp_unlock_node (rn
);
4214 bgp_static
= rn
->info
;
4215 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4216 bgp_static_free (bgp_static
);
4218 bgp_unlock_node (rn
);
4224 bgp_static_redo_import_check (struct bgp
*bgp
)
4228 struct bgp_node
*rn
;
4229 struct bgp_static
*bgp_static
;
4231 /* Use this flag to force reprocessing of the route */
4232 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4233 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4234 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4235 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4236 if (rn
->info
!= NULL
)
4238 bgp_static
= rn
->info
;
4239 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4241 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4245 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4247 struct bgp_table
*table
;
4248 struct bgp_node
*rn
;
4249 struct bgp_info
*ri
;
4251 table
= bgp
->rib
[afi
][safi
];
4252 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4254 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4256 if (ri
->peer
== bgp
->peer_self
&&
4257 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4258 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4259 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4260 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4262 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4263 bgp_unlink_nexthop(ri
);
4264 bgp_info_delete (rn
, ri
);
4265 bgp_process (bgp
, rn
, afi
, safi
);
4272 * Purge all networks and redistributed routes from routing table.
4273 * Invoked upon the instance going down.
4276 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4281 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4282 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4283 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4288 * Currently this is used to set static routes for VPN and ENCAP.
4289 * I think it can probably be factored with bgp_static_set.
4292 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4293 const char *rd_str
, const char *tag_str
,
4294 const char *rmap_str
)
4296 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4299 struct prefix_rd prd
;
4300 struct bgp_node
*prn
;
4301 struct bgp_node
*rn
;
4302 struct bgp_table
*table
;
4303 struct bgp_static
*bgp_static
;
4307 ret
= str2prefix (ip_str
, &p
);
4310 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4315 ret
= str2prefix_rd (rd_str
, &prd
);
4318 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4322 ret
= str2tag (tag_str
, tag
);
4325 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4328 if (p
.family
== AF_INET
)
4330 else if (p
.family
== AF_INET6
)
4334 vty_out (vty
, "%% Non Supported prefix%s", VTY_NEWLINE
);
4337 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4338 (struct prefix
*)&prd
);
4339 if (prn
->info
== NULL
)
4340 prn
->info
= bgp_table_init (afi
, safi
);
4342 bgp_unlock_node (prn
);
4345 rn
= bgp_node_get (table
, &p
);
4349 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4350 bgp_unlock_node (rn
);
4354 /* New configuration. */
4355 bgp_static
= bgp_static_new ();
4356 bgp_static
->backdoor
= 0;
4357 bgp_static
->valid
= 0;
4358 bgp_static
->igpmetric
= 0;
4359 bgp_static
->igpnexthop
.s_addr
= 0;
4360 memcpy(bgp_static
->tag
, tag
, 3);
4361 bgp_static
->prd
= prd
;
4365 if (bgp_static
->rmap
.name
)
4366 free (bgp_static
->rmap
.name
);
4367 bgp_static
->rmap
.name
= strdup (rmap_str
);
4368 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4370 rn
->info
= bgp_static
;
4372 bgp_static
->valid
= 1;
4373 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4379 /* Configure static BGP network. */
4381 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4382 const char *rd_str
, const char *tag_str
)
4384 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4387 struct prefix_rd prd
;
4388 struct bgp_node
*prn
;
4389 struct bgp_node
*rn
;
4390 struct bgp_table
*table
;
4391 struct bgp_static
*bgp_static
;
4394 /* Convert IP prefix string to struct prefix. */
4395 ret
= str2prefix (ip_str
, &p
);
4398 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4403 ret
= str2prefix_rd (rd_str
, &prd
);
4406 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4410 ret
= str2tag (tag_str
, tag
);
4413 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4417 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4418 (struct prefix
*)&prd
);
4419 if (prn
->info
== NULL
)
4420 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4422 bgp_unlock_node (prn
);
4425 rn
= bgp_node_lookup (table
, &p
);
4429 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4431 bgp_static
= rn
->info
;
4432 bgp_static_free (bgp_static
);
4434 bgp_unlock_node (rn
);
4435 bgp_unlock_node (rn
);
4438 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4444 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4445 const char *rmap_name
)
4447 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4448 struct bgp_rmap
*rmap
;
4450 rmap
= &bgp
->table_map
[afi
][safi
];
4454 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4455 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4456 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4461 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4466 bgp_zebra_announce_table(bgp
, afi
, safi
);
4472 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4473 const char *rmap_name
)
4475 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4476 struct bgp_rmap
*rmap
;
4478 rmap
= &bgp
->table_map
[afi
][safi
];
4480 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4484 bgp_zebra_announce_table(bgp
, afi
, safi
);
4490 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4491 safi_t safi
, int *write
)
4493 if (bgp
->table_map
[afi
][safi
].name
)
4495 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4496 vty_out (vty
, " table-map %s%s",
4497 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4503 DEFUN (bgp_table_map
,
4506 "BGP table to RIB route download filter\n"
4507 "Name of the route map\n")
4510 return bgp_table_map_set (vty
,
4511 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4513 DEFUN (no_bgp_table_map
,
4514 no_bgp_table_map_cmd
,
4515 "no table-map WORD",
4517 "BGP table to RIB route download filter\n"
4518 "Name of the route map\n")
4521 return bgp_table_map_unset (vty
,
4522 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4527 "network A.B.C.D/M",
4528 "Specify a network to announce via BGP\n"
4531 int idx_ipv4_prefixlen
= 1;
4532 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4533 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4536 DEFUN (bgp_network_route_map
,
4537 bgp_network_route_map_cmd
,
4538 "network A.B.C.D/M route-map WORD",
4539 "Specify a network to announce via BGP\n"
4541 "Route-map to modify the attributes\n"
4542 "Name of the route map\n")
4544 int idx_ipv4_prefixlen
= 1;
4546 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4547 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4550 DEFUN (bgp_network_backdoor
,
4551 bgp_network_backdoor_cmd
,
4552 "network A.B.C.D/M backdoor",
4553 "Specify a network to announce via BGP\n"
4555 "Specify a BGP backdoor route\n")
4557 int idx_ipv4_prefixlen
= 1;
4558 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4562 DEFUN (bgp_network_mask
,
4563 bgp_network_mask_cmd
,
4564 "network A.B.C.D mask A.B.C.D",
4565 "Specify a network to announce via BGP\n"
4573 char prefix_str
[BUFSIZ
];
4575 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4578 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4582 return bgp_static_set (vty
, prefix_str
,
4583 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4586 DEFUN (bgp_network_mask_route_map
,
4587 bgp_network_mask_route_map_cmd
,
4588 "network A.B.C.D mask A.B.C.D route-map WORD",
4589 "Specify a network to announce via BGP\n"
4593 "Route-map to modify the attributes\n"
4594 "Name of the route map\n")
4600 char prefix_str
[BUFSIZ
];
4602 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4605 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4609 return bgp_static_set (vty
, prefix_str
,
4610 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4613 DEFUN (bgp_network_mask_backdoor
,
4614 bgp_network_mask_backdoor_cmd
,
4615 "network A.B.C.D mask A.B.C.D backdoor",
4616 "Specify a network to announce via BGP\n"
4620 "Specify a BGP backdoor route\n")
4625 char prefix_str
[BUFSIZ
];
4627 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4630 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4634 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4638 DEFUN (bgp_network_mask_natural
,
4639 bgp_network_mask_natural_cmd
,
4641 "Specify a network to announce via BGP\n"
4646 char prefix_str
[BUFSIZ
];
4648 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4651 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4655 return bgp_static_set (vty
, prefix_str
,
4656 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4659 DEFUN (bgp_network_mask_natural_route_map
,
4660 bgp_network_mask_natural_route_map_cmd
,
4661 "network A.B.C.D route-map WORD",
4662 "Specify a network to announce via BGP\n"
4664 "Route-map to modify the attributes\n"
4665 "Name of the route map\n")
4670 char prefix_str
[BUFSIZ
];
4672 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4675 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4679 return bgp_static_set (vty
, prefix_str
,
4680 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4683 DEFUN (bgp_network_mask_natural_backdoor
,
4684 bgp_network_mask_natural_backdoor_cmd
,
4685 "network A.B.C.D backdoor",
4686 "Specify a network to announce via BGP\n"
4688 "Specify a BGP backdoor route\n")
4692 char prefix_str
[BUFSIZ
];
4694 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4697 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4701 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4705 DEFUN (no_bgp_network
,
4707 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4709 "Specify a network to announce via BGP\n"
4711 "Specify a BGP backdoor route\n"
4712 "Route-map to modify the attributes\n"
4713 "Name of the route map\n")
4715 int idx_ipv4_prefixlen
= 2;
4716 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4717 bgp_node_safi (vty
));
4720 DEFUN (no_bgp_network_mask
,
4721 no_bgp_network_mask_cmd
,
4722 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4724 "Specify a network to announce via BGP\n"
4728 "Specify a BGP backdoor route\n"
4729 "Route-map to modify the attributes\n"
4730 "Name of the route map\n")
4735 char prefix_str
[BUFSIZ
];
4737 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4740 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4744 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4745 bgp_node_safi (vty
));
4748 DEFUN (no_bgp_network_mask_natural
,
4749 no_bgp_network_mask_natural_cmd
,
4750 "no network A.B.C.D [<backdoor|route-map WORD>]",
4752 "Specify a network to announce via BGP\n"
4754 "Specify a BGP backdoor route\n"
4755 "Route-map to modify the attributes\n"
4756 "Name of the route map\n")
4760 char prefix_str
[BUFSIZ
];
4762 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4765 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4769 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4770 bgp_node_safi (vty
));
4773 DEFUN (ipv6_bgp_network
,
4774 ipv6_bgp_network_cmd
,
4775 "network X:X::X:X/M",
4776 "Specify a network to announce via BGP\n"
4779 int idx_ipv6_prefixlen
= 1;
4780 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4784 DEFUN (ipv6_bgp_network_route_map
,
4785 ipv6_bgp_network_route_map_cmd
,
4786 "network X:X::X:X/M route-map WORD",
4787 "Specify a network to announce via BGP\n"
4789 "Route-map to modify the attributes\n"
4790 "Name of the route map\n")
4792 int idx_ipv6_prefixlen
= 1;
4794 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4795 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4798 DEFUN (no_ipv6_bgp_network
,
4799 no_ipv6_bgp_network_cmd
,
4800 "no network X:X::X:X/M [route-map WORD]",
4802 "Specify a network to announce via BGP\n"
4804 "Route-map to modify the attributes\n"
4805 "Name of the route map\n")
4807 int idx_ipv6_prefixlen
= 2;
4808 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4811 /* Aggreagete address:
4813 advertise-map Set condition to advertise attribute
4814 as-set Generate AS set path information
4815 attribute-map Set attributes of aggregate
4816 route-map Set parameters of aggregate
4817 summary-only Filter more specific routes from updates
4818 suppress-map Conditionally filter more specific routes from updates
4821 struct bgp_aggregate
4823 /* Summary-only flag. */
4824 u_char summary_only
;
4826 /* AS set generation. */
4829 /* Route-map for aggregated route. */
4830 struct route_map
*map
;
4832 /* Suppress-count. */
4833 unsigned long count
;
4835 /* SAFI configuration. */
4839 static struct bgp_aggregate
*
4840 bgp_aggregate_new (void)
4842 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4846 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4848 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4851 /* Update an aggregate as routes are added/removed from the BGP table */
4853 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4854 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4855 struct bgp_aggregate
*aggregate
)
4857 struct bgp_table
*table
;
4858 struct bgp_node
*top
;
4859 struct bgp_node
*rn
;
4861 struct aspath
*aspath
= NULL
;
4862 struct aspath
*asmerge
= NULL
;
4863 struct community
*community
= NULL
;
4864 struct community
*commerge
= NULL
;
4865 #if defined(AGGREGATE_NEXTHOP_CHECK)
4866 struct in_addr nexthop
;
4869 struct bgp_info
*ri
;
4870 struct bgp_info
*new;
4872 unsigned long match
= 0;
4873 u_char atomic_aggregate
= 0;
4875 /* Record adding route's nexthop and med. */
4878 #if defined(AGGREGATE_NEXTHOP_CHECK)
4879 nexthop
= rinew
->attr
->nexthop
;
4880 med
= rinew
->attr
->med
;
4884 /* ORIGIN attribute: If at least one route among routes that are
4885 aggregated has ORIGIN with the value INCOMPLETE, then the
4886 aggregated route must have the ORIGIN attribute with the value
4887 INCOMPLETE. Otherwise, if at least one route among routes that
4888 are aggregated has ORIGIN with the value EGP, then the aggregated
4889 route must have the origin attribute with the value EGP. In all
4890 other case the value of the ORIGIN attribute of the aggregated
4891 route is INTERNAL. */
4892 origin
= BGP_ORIGIN_IGP
;
4894 table
= bgp
->rib
[afi
][safi
];
4896 top
= bgp_node_get (table
, p
);
4897 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
4898 if (rn
->p
.prefixlen
> p
->prefixlen
)
4902 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4904 if (BGP_INFO_HOLDDOWN (ri
))
4907 if (del
&& ri
== del
)
4910 if (! rinew
&& first
)
4912 #if defined(AGGREGATE_NEXTHOP_CHECK)
4913 nexthop
= ri
->attr
->nexthop
;
4914 med
= ri
->attr
->med
;
4919 #ifdef AGGREGATE_NEXTHOP_CHECK
4920 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
4921 || ri
->attr
->med
!= med
)
4924 aspath_free (aspath
);
4926 community_free (community
);
4927 bgp_unlock_node (rn
);
4928 bgp_unlock_node (top
);
4931 #endif /* AGGREGATE_NEXTHOP_CHECK */
4933 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
4934 atomic_aggregate
= 1;
4936 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
4938 if (aggregate
->summary_only
)
4940 (bgp_info_extra_get (ri
))->suppress
++;
4941 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4947 if (origin
< ri
->attr
->origin
)
4948 origin
= ri
->attr
->origin
;
4950 if (aggregate
->as_set
)
4954 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
4955 aspath_free (aspath
);
4959 aspath
= aspath_dup (ri
->attr
->aspath
);
4961 if (ri
->attr
->community
)
4965 commerge
= community_merge (community
,
4966 ri
->attr
->community
);
4967 community
= community_uniq_sort (commerge
);
4968 community_free (commerge
);
4971 community
= community_dup (ri
->attr
->community
);
4977 bgp_process (bgp
, rn
, afi
, safi
);
4979 bgp_unlock_node (top
);
4985 if (aggregate
->summary_only
)
4986 (bgp_info_extra_get (rinew
))->suppress
++;
4988 if (origin
< rinew
->attr
->origin
)
4989 origin
= rinew
->attr
->origin
;
4991 if (aggregate
->as_set
)
4995 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
4996 aspath_free (aspath
);
5000 aspath
= aspath_dup (rinew
->attr
->aspath
);
5002 if (rinew
->attr
->community
)
5006 commerge
= community_merge (community
,
5007 rinew
->attr
->community
);
5008 community
= community_uniq_sort (commerge
);
5009 community_free (commerge
);
5012 community
= community_dup (rinew
->attr
->community
);
5017 if (aggregate
->count
> 0)
5019 rn
= bgp_node_get (table
, p
);
5020 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5021 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5023 atomic_aggregate
), rn
);
5024 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5026 bgp_info_add (rn
, new);
5027 bgp_unlock_node (rn
);
5028 bgp_process (bgp
, rn
, afi
, safi
);
5033 aspath_free (aspath
);
5035 community_free (community
);
5039 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5040 struct bgp_aggregate
*);
5043 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5044 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5046 struct bgp_node
*child
;
5047 struct bgp_node
*rn
;
5048 struct bgp_aggregate
*aggregate
;
5049 struct bgp_table
*table
;
5051 /* MPLS-VPN aggregation is not yet supported. */
5052 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5055 table
= bgp
->aggregate
[afi
][safi
];
5057 /* No aggregates configured. */
5058 if (bgp_table_top_nolock (table
) == NULL
)
5061 if (p
->prefixlen
== 0)
5064 if (BGP_INFO_HOLDDOWN (ri
))
5067 child
= bgp_node_get (table
, p
);
5069 /* Aggregate address configuration check. */
5070 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5071 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5073 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5074 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5076 bgp_unlock_node (child
);
5080 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5081 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5083 struct bgp_node
*child
;
5084 struct bgp_node
*rn
;
5085 struct bgp_aggregate
*aggregate
;
5086 struct bgp_table
*table
;
5088 /* MPLS-VPN aggregation is not yet supported. */
5089 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5092 table
= bgp
->aggregate
[afi
][safi
];
5094 /* No aggregates configured. */
5095 if (bgp_table_top_nolock (table
) == NULL
)
5098 if (p
->prefixlen
== 0)
5101 child
= bgp_node_get (table
, p
);
5103 /* Aggregate address configuration check. */
5104 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5105 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5107 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5108 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5110 bgp_unlock_node (child
);
5113 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5115 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5116 struct bgp_aggregate
*aggregate
)
5118 struct bgp_table
*table
;
5119 struct bgp_node
*top
;
5120 struct bgp_node
*rn
;
5121 struct bgp_info
*new;
5122 struct bgp_info
*ri
;
5123 unsigned long match
;
5124 u_char origin
= BGP_ORIGIN_IGP
;
5125 struct aspath
*aspath
= NULL
;
5126 struct aspath
*asmerge
= NULL
;
5127 struct community
*community
= NULL
;
5128 struct community
*commerge
= NULL
;
5129 u_char atomic_aggregate
= 0;
5131 table
= bgp
->rib
[afi
][safi
];
5134 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5136 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5139 /* If routes exists below this node, generate aggregate routes. */
5140 top
= bgp_node_get (table
, p
);
5141 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5142 if (rn
->p
.prefixlen
> p
->prefixlen
)
5146 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5148 if (BGP_INFO_HOLDDOWN (ri
))
5151 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5152 atomic_aggregate
= 1;
5154 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5156 /* summary-only aggregate route suppress aggregated
5157 route announcement. */
5158 if (aggregate
->summary_only
)
5160 (bgp_info_extra_get (ri
))->suppress
++;
5161 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5165 /* If at least one route among routes that are aggregated has
5166 * ORIGIN with the value INCOMPLETE, then the aggregated route
5167 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5168 * Otherwise, if at least one route among routes that are
5169 * aggregated has ORIGIN with the value EGP, then the aggregated
5170 * route MUST have the ORIGIN attribute with the value EGP.
5172 if (origin
< ri
->attr
->origin
)
5173 origin
= ri
->attr
->origin
;
5175 /* as-set aggregate route generate origin, as path,
5176 community aggregation. */
5177 if (aggregate
->as_set
)
5181 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5182 aspath_free (aspath
);
5186 aspath
= aspath_dup (ri
->attr
->aspath
);
5188 if (ri
->attr
->community
)
5192 commerge
= community_merge (community
,
5193 ri
->attr
->community
);
5194 community
= community_uniq_sort (commerge
);
5195 community_free (commerge
);
5198 community
= community_dup (ri
->attr
->community
);
5205 /* If this node is suppressed, process the change. */
5207 bgp_process (bgp
, rn
, afi
, safi
);
5209 bgp_unlock_node (top
);
5211 /* Add aggregate route to BGP table. */
5212 if (aggregate
->count
)
5214 rn
= bgp_node_get (table
, p
);
5215 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5216 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5218 atomic_aggregate
), rn
);
5219 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5221 bgp_info_add (rn
, new);
5222 bgp_unlock_node (rn
);
5224 /* Process change. */
5225 bgp_process (bgp
, rn
, afi
, safi
);
5230 aspath_free (aspath
);
5232 community_free (community
);
5237 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5238 safi_t safi
, struct bgp_aggregate
*aggregate
)
5240 struct bgp_table
*table
;
5241 struct bgp_node
*top
;
5242 struct bgp_node
*rn
;
5243 struct bgp_info
*ri
;
5244 unsigned long match
;
5246 table
= bgp
->rib
[afi
][safi
];
5248 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5250 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5253 /* If routes exists below this node, generate aggregate routes. */
5254 top
= bgp_node_get (table
, p
);
5255 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5256 if (rn
->p
.prefixlen
> p
->prefixlen
)
5260 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5262 if (BGP_INFO_HOLDDOWN (ri
))
5265 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5267 if (aggregate
->summary_only
&& ri
->extra
)
5269 ri
->extra
->suppress
--;
5271 if (ri
->extra
->suppress
== 0)
5273 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5281 /* If this node was suppressed, process the change. */
5283 bgp_process (bgp
, rn
, afi
, safi
);
5285 bgp_unlock_node (top
);
5287 /* Delete aggregate route from BGP table. */
5288 rn
= bgp_node_get (table
, p
);
5290 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5291 if (ri
->peer
== bgp
->peer_self
5292 && ri
->type
== ZEBRA_ROUTE_BGP
5293 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5296 /* Withdraw static BGP route from routing table. */
5299 bgp_info_delete (rn
, ri
);
5300 bgp_process (bgp
, rn
, afi
, safi
);
5303 /* Unlock bgp_node_lookup. */
5304 bgp_unlock_node (rn
);
5307 /* Aggregate route attribute. */
5308 #define AGGREGATE_SUMMARY_ONLY 1
5309 #define AGGREGATE_AS_SET 1
5312 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5313 afi_t afi
, safi_t safi
)
5315 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5318 struct bgp_node
*rn
;
5319 struct bgp_aggregate
*aggregate
;
5321 /* Convert string to prefix structure. */
5322 ret
= str2prefix (prefix_str
, &p
);
5325 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5330 /* Old configuration check. */
5331 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5334 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5339 aggregate
= rn
->info
;
5340 if (aggregate
->safi
& SAFI_UNICAST
)
5341 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5342 if (aggregate
->safi
& SAFI_MULTICAST
)
5343 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5345 /* Unlock aggregate address configuration. */
5347 bgp_aggregate_free (aggregate
);
5348 bgp_unlock_node (rn
);
5349 bgp_unlock_node (rn
);
5355 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5356 afi_t afi
, safi_t safi
,
5357 u_char summary_only
, u_char as_set
)
5359 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5362 struct bgp_node
*rn
;
5363 struct bgp_aggregate
*aggregate
;
5365 /* Convert string to prefix structure. */
5366 ret
= str2prefix (prefix_str
, &p
);
5369 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5374 /* Old configuration check. */
5375 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5379 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5380 /* try to remove the old entry */
5381 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5384 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5385 bgp_unlock_node (rn
);
5390 /* Make aggregate address structure. */
5391 aggregate
= bgp_aggregate_new ();
5392 aggregate
->summary_only
= summary_only
;
5393 aggregate
->as_set
= as_set
;
5394 aggregate
->safi
= safi
;
5395 rn
->info
= aggregate
;
5397 /* Aggregate address insert into BGP routing table. */
5398 if (safi
& SAFI_UNICAST
)
5399 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5400 if (safi
& SAFI_MULTICAST
)
5401 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5406 DEFUN (aggregate_address
,
5407 aggregate_address_cmd
,
5408 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5409 "Configure BGP aggregate entries\n"
5410 "Aggregate prefix\n"
5411 "Generate AS set path information\n"
5412 "Filter more specific routes from updates\n"
5413 "Filter more specific routes from updates\n"
5414 "Generate AS set path information\n")
5417 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5418 char *prefix
= argv
[idx
]->arg
;
5419 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5421 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5423 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5426 DEFUN (aggregate_address_mask
,
5427 aggregate_address_mask_cmd
,
5428 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5429 "Configure BGP aggregate entries\n"
5430 "Aggregate address\n"
5432 "Generate AS set path information\n"
5433 "Filter more specific routes from updates\n"
5434 "Filter more specific routes from updates\n"
5435 "Generate AS set path information\n")
5438 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5439 char *prefix
= argv
[idx
++]->arg
;
5440 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5441 char *mask
= argv
[idx
]->arg
;
5442 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5444 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5446 char prefix_str
[BUFSIZ
];
5447 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5451 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5455 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5458 DEFUN (no_aggregate_address
,
5459 no_aggregate_address_cmd
,
5460 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5462 "Configure BGP aggregate entries\n"
5463 "Aggregate prefix\n"
5464 "Generate AS set path information\n"
5465 "Filter more specific routes from updates\n"
5466 "Filter more specific routes from updates\n"
5467 "Generate AS set path information\n")
5470 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5471 char *prefix
= argv
[idx
]->arg
;
5472 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5475 DEFUN (no_aggregate_address_mask
,
5476 no_aggregate_address_mask_cmd
,
5477 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5479 "Configure BGP aggregate entries\n"
5480 "Aggregate address\n"
5482 "Generate AS set path information\n"
5483 "Filter more specific routes from updates\n"
5484 "Filter more specific routes from updates\n"
5485 "Generate AS set path information\n")
5488 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5489 char *prefix
= argv
[idx
++]->arg
;
5490 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5491 char *mask
= argv
[idx
]->arg
;
5493 char prefix_str
[BUFSIZ
];
5494 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5498 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5502 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5505 DEFUN (ipv6_aggregate_address
,
5506 ipv6_aggregate_address_cmd
,
5507 "aggregate-address X:X::X:X/M [summary-only]",
5508 "Configure BGP aggregate entries\n"
5509 "Aggregate prefix\n"
5510 "Filter more specific routes from updates\n")
5513 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5514 char *prefix
= argv
[idx
]->arg
;
5515 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5516 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5519 DEFUN (no_ipv6_aggregate_address
,
5520 no_ipv6_aggregate_address_cmd
,
5521 "no aggregate-address X:X::X:X/M [summary-only]",
5523 "Configure BGP aggregate entries\n"
5524 "Aggregate prefix\n"
5525 "Filter more specific routes from updates\n")
5528 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5529 char *prefix
= argv
[idx
]->arg
;
5530 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5533 /* Redistribute route treatment. */
5535 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5536 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5537 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5539 struct bgp_info
*new;
5540 struct bgp_info
*bi
;
5541 struct bgp_info info
;
5542 struct bgp_node
*bn
;
5544 struct attr
*new_attr
;
5547 struct bgp_redist
*red
;
5549 /* Make default attribute. */
5550 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5552 attr
.nexthop
= *nexthop
;
5553 attr
.nh_ifindex
= ifindex
;
5557 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5558 extra
->mp_nexthop_global
= *nexthop6
;
5559 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5563 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5564 attr
.extra
->tag
= tag
;
5566 afi
= family2afi (p
->family
);
5568 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5571 struct attr attr_new
;
5572 struct attr_extra extra_new
;
5574 /* Copy attribute for modification. */
5575 attr_new
.extra
= &extra_new
;
5576 bgp_attr_dup (&attr_new
, &attr
);
5578 if (red
->redist_metric_flag
)
5579 attr_new
.med
= red
->redist_metric
;
5581 /* Apply route-map. */
5584 info
.peer
= bgp
->peer_self
;
5585 info
.attr
= &attr_new
;
5587 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5589 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5591 bgp
->peer_self
->rmap_type
= 0;
5593 if (ret
== RMAP_DENYMATCH
)
5595 /* Free uninterned attribute. */
5596 bgp_attr_flush (&attr_new
);
5598 /* Unintern original. */
5599 aspath_unintern (&attr
.aspath
);
5600 bgp_attr_extra_free (&attr
);
5601 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5606 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5607 afi
, SAFI_UNICAST
, p
, NULL
);
5609 new_attr
= bgp_attr_intern (&attr_new
);
5611 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5612 if (bi
->peer
== bgp
->peer_self
5613 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5618 /* Ensure the (source route) type is updated. */
5620 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5621 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5623 bgp_attr_unintern (&new_attr
);
5624 aspath_unintern (&attr
.aspath
);
5625 bgp_attr_extra_free (&attr
);
5626 bgp_unlock_node (bn
);
5631 /* The attribute is changed. */
5632 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5634 /* Rewrite BGP route information. */
5635 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5636 bgp_info_restore(bn
, bi
);
5638 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5639 bgp_attr_unintern (&bi
->attr
);
5640 bi
->attr
= new_attr
;
5641 bi
->uptime
= bgp_clock ();
5643 /* Process change. */
5644 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5645 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5646 bgp_unlock_node (bn
);
5647 aspath_unintern (&attr
.aspath
);
5648 bgp_attr_extra_free (&attr
);
5653 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5655 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5657 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5658 bgp_info_add (bn
, new);
5659 bgp_unlock_node (bn
);
5660 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5663 /* Unintern original. */
5664 aspath_unintern (&attr
.aspath
);
5665 bgp_attr_extra_free (&attr
);
5669 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5672 struct bgp_node
*rn
;
5673 struct bgp_info
*ri
;
5674 struct bgp_redist
*red
;
5676 afi
= family2afi (p
->family
);
5678 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5681 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5683 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5684 if (ri
->peer
== bgp
->peer_self
5685 && ri
->type
== type
)
5690 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5691 bgp_info_delete (rn
, ri
);
5692 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5694 bgp_unlock_node (rn
);
5698 /* Withdraw specified route type's route. */
5700 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5702 struct bgp_node
*rn
;
5703 struct bgp_info
*ri
;
5704 struct bgp_table
*table
;
5706 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5708 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5710 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5711 if (ri
->peer
== bgp
->peer_self
5713 && ri
->instance
== instance
)
5718 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5719 bgp_info_delete (rn
, ri
);
5720 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5725 /* Static function to display route. */
5727 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5730 u_int32_t destination
;
5733 if (p
->family
== AF_INET
)
5735 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5736 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5738 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5739 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5740 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5741 || p
->u
.prefix4
.s_addr
== 0)
5743 /* When mask is natural, mask is not displayed. */
5746 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5749 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5754 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5756 vty_out (vty
, "%*s", len
, " ");
5759 enum bgp_display_type
5764 /* Print the short form route status for a bgp_info */
5766 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5767 json_object
*json_path
)
5772 /* Route status display. */
5773 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5774 json_object_boolean_true_add(json_path
, "removed");
5776 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5777 json_object_boolean_true_add(json_path
, "stale");
5779 if (binfo
->extra
&& binfo
->extra
->suppress
)
5780 json_object_boolean_true_add(json_path
, "suppressed");
5782 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5783 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5784 json_object_boolean_true_add(json_path
, "valid");
5787 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5788 json_object_boolean_true_add(json_path
, "history");
5790 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5791 json_object_boolean_true_add(json_path
, "damped");
5793 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5794 json_object_boolean_true_add(json_path
, "bestpath");
5796 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5797 json_object_boolean_true_add(json_path
, "multipath");
5799 /* Internal route. */
5800 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5801 json_object_string_add(json_path
, "pathFrom", "internal");
5803 json_object_string_add(json_path
, "pathFrom", "external");
5808 /* Route status display. */
5809 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5811 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5813 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5815 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5816 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5822 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5824 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5826 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5828 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5833 /* Internal route. */
5834 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5840 /* called from terminal list command */
5842 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5843 struct bgp_info
*binfo
, int display
, safi_t safi
,
5844 json_object
*json_paths
)
5847 json_object
*json_path
= NULL
;
5848 json_object
*json_nexthops
= NULL
;
5849 json_object
*json_nexthop_global
= NULL
;
5850 json_object
*json_nexthop_ll
= NULL
;
5853 json_path
= json_object_new_object();
5855 /* short status lead text */
5856 route_vty_short_status_out (vty
, binfo
, json_path
);
5860 /* print prefix and mask */
5862 route_vty_out_route (p
, vty
);
5864 vty_out (vty
, "%*s", 17, " ");
5867 /* Print attribute */
5872 * For ENCAP routes, nexthop address family is not
5873 * neccessarily the same as the prefix address family.
5874 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
5876 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
))
5881 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
5886 vty_out (vty
, "%s", inet_ntop(af
,
5887 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
5890 vty_out (vty
, "%s", inet_ntop(af
,
5891 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
5902 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5906 json_nexthop_global
= json_object_new_object();
5908 if (safi
== SAFI_MPLS_VPN
)
5909 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5911 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
5913 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
5914 json_object_boolean_true_add(json_nexthop_global
, "used");
5918 if (safi
== SAFI_MPLS_VPN
)
5919 vty_out (vty
, "%-16s",
5920 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5922 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
5927 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5934 json_nexthop_global
= json_object_new_object();
5935 json_object_string_add(json_nexthop_global
, "ip",
5936 inet_ntop (AF_INET6
,
5937 &attr
->extra
->mp_nexthop_global
,
5939 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
5940 json_object_string_add(json_nexthop_global
, "scope", "global");
5942 /* We display both LL & GL if both have been received */
5943 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
5945 json_nexthop_ll
= json_object_new_object();
5946 json_object_string_add(json_nexthop_ll
, "ip",
5947 inet_ntop (AF_INET6
,
5948 &attr
->extra
->mp_nexthop_local
,
5950 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
5951 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
5953 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
5954 &attr
->extra
->mp_nexthop_local
) != 0) &&
5955 !attr
->extra
->mp_nexthop_prefer_global
)
5956 json_object_boolean_true_add(json_nexthop_ll
, "used");
5958 json_object_boolean_true_add(json_nexthop_global
, "used");
5961 json_object_boolean_true_add(json_nexthop_global
, "used");
5965 /* Display LL if LL/Global both in table unless prefer-global is set */
5966 if (((attr
->extra
->mp_nexthop_len
== 32) &&
5967 !attr
->extra
->mp_nexthop_prefer_global
) ||
5968 (binfo
->peer
->conf_if
))
5970 if (binfo
->peer
->conf_if
)
5972 len
= vty_out (vty
, "%s",
5973 binfo
->peer
->conf_if
);
5974 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
5977 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
5979 vty_out (vty
, "%*s", len
, " ");
5983 len
= vty_out (vty
, "%s",
5984 inet_ntop (AF_INET6
,
5985 &attr
->extra
->mp_nexthop_local
,
5990 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
5992 vty_out (vty
, "%*s", len
, " ");
5997 len
= vty_out (vty
, "%s",
5998 inet_ntop (AF_INET6
,
5999 &attr
->extra
->mp_nexthop_global
,
6004 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6006 vty_out (vty
, "%*s", len
, " ");
6012 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6014 json_object_int_add(json_path
, "med", attr
->med
);
6016 vty_out (vty
, "%10u", attr
->med
);
6022 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6024 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6026 vty_out (vty
, "%7u", attr
->local_pref
);
6034 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6036 json_object_int_add(json_path
, "weight", 0);
6039 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6043 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6050 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6052 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6057 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6059 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6064 json_object_string_add(json_path
, "alert", "No attributes");
6066 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6071 if (json_nexthop_global
|| json_nexthop_ll
)
6073 json_nexthops
= json_object_new_array();
6075 if (json_nexthop_global
)
6076 json_object_array_add(json_nexthops
, json_nexthop_global
);
6078 if (json_nexthop_ll
)
6079 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6081 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6084 json_object_array_add(json_paths
, json_path
);
6088 vty_out (vty
, "%s", VTY_NEWLINE
);
6090 /* prints an additional line, indented, with VNC info, if present */
6091 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6092 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6097 /* called from terminal list command */
6099 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6100 u_char use_json
, json_object
*json_ar
)
6102 json_object
*json_status
= NULL
;
6103 json_object
*json_net
= NULL
;
6105 /* Route status display. */
6108 json_status
= json_object_new_object();
6109 json_net
= json_object_new_object();
6118 /* print prefix and mask */
6120 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6122 route_vty_out_route (p
, vty
);
6124 /* Print attribute */
6129 if (p
->family
== AF_INET
&&
6130 (safi
== SAFI_MPLS_VPN
||
6131 safi
== SAFI_ENCAP
||
6132 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6134 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6135 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6137 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6139 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6143 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6147 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6148 json_object_int_add(json_net
, "metric", attr
->med
);
6150 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6151 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6154 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6156 json_object_int_add(json_net
, "weight", 0);
6160 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6163 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6167 if (p
->family
== AF_INET
&&
6168 (safi
== SAFI_MPLS_VPN
||
6169 safi
== SAFI_ENCAP
||
6170 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6172 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6173 vty_out (vty
, "%-16s",
6174 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6176 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6178 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6183 assert (attr
->extra
);
6185 len
= vty_out (vty
, "%s",
6186 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6190 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6192 vty_out (vty
, "%*s", len
, " ");
6194 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6195 vty_out (vty
, "%10u", attr
->med
);
6199 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6200 vty_out (vty
, "%7u", attr
->local_pref
);
6204 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6208 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6211 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6216 json_object_boolean_true_add(json_status
, "*");
6217 json_object_boolean_true_add(json_status
, ">");
6218 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6219 char buf_cut
[BUFSIZ
];
6220 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6223 vty_out (vty
, "%s", VTY_NEWLINE
);
6227 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6228 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6230 json_object
*json_out
= NULL
;
6232 u_int32_t label
= 0;
6238 json_out
= json_object_new_object();
6240 /* short status lead text */
6241 route_vty_short_status_out (vty
, binfo
, json_out
);
6243 /* print prefix and mask */
6247 route_vty_out_route (p
, vty
);
6249 vty_out (vty
, "%*s", 17, " ");
6252 /* Print attribute */
6256 if (p
->family
== AF_INET
6257 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6259 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6262 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6264 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6269 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6271 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6274 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6276 assert (attr
->extra
);
6280 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6283 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6284 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6287 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6290 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6294 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6296 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6298 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6299 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6302 vty_out (vty
, "%s(%s)",
6303 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6305 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6312 label
= decode_label (binfo
->extra
->tag
);
6317 json_object_int_add(json_out
, "notag", label
);
6318 json_object_array_add(json
, json_out
);
6322 vty_out (vty
, "notag/%d", label
);
6323 vty_out (vty
, "%s", VTY_NEWLINE
);
6327 /* dampening route */
6329 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6330 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6334 char timebuf
[BGP_UPTIME_LEN
];
6336 /* short status lead text */
6337 route_vty_short_status_out (vty
, binfo
, json
);
6339 /* print prefix and mask */
6343 route_vty_out_route (p
, vty
);
6345 vty_out (vty
, "%*s", 17, " ");
6348 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6353 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6358 json_object_int_add(json
, "peerHost", len
);
6360 vty_out (vty
, "%*s", len
, " ");
6364 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6366 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6368 /* Print attribute */
6376 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6378 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6383 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6385 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6388 vty_out (vty
, "%s", VTY_NEWLINE
);
6393 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6394 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6397 struct bgp_damp_info
*bdi
;
6398 char timebuf
[BGP_UPTIME_LEN
];
6404 bdi
= binfo
->extra
->damp_info
;
6406 /* short status lead text */
6407 route_vty_short_status_out (vty
, binfo
, json
);
6409 /* print prefix and mask */
6413 route_vty_out_route (p
, vty
);
6415 vty_out (vty
, "%*s", 17, " ");
6418 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6423 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6428 json_object_int_add(json
, "peerHost", len
);
6430 vty_out (vty
, "%*s", len
, " ");
6433 len
= vty_out (vty
, "%d", bdi
->flap
);
6443 json_object_int_add(json
, "bdiFlap", len
);
6445 vty_out (vty
, "%*s", len
, " ");
6449 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6451 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6452 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6454 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6455 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6458 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6460 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6465 vty_out (vty
, "%*s ", 8, " ");
6468 /* Print attribute */
6476 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6478 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6483 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6485 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6488 vty_out (vty
, "%s", VTY_NEWLINE
);
6492 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6493 const char *header
, json_object
*json_adv_to
)
6495 char buf1
[INET6_ADDRSTRLEN
];
6496 json_object
*json_peer
= NULL
;
6500 /* 'advertised-to' is a dictionary of peers we have advertised this
6501 * prefix too. The key is the peer's IP or swpX, the value is the
6502 * hostname if we know it and "" if not.
6504 json_peer
= json_object_new_object();
6507 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6510 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6512 json_object_object_add(json_adv_to
,
6513 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6520 vty_out (vty
, "%s", header
);
6524 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6527 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6529 vty_out (vty
, " %s(%s)", peer
->hostname
,
6530 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6535 vty_out (vty
, " %s", peer
->conf_if
);
6537 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6543 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6544 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6545 json_object
*json_paths
)
6547 char buf
[INET6_ADDRSTRLEN
];
6550 int sockunion_vty_out (struct vty
*, union sockunion
*);
6552 json_object
*json_bestpath
= NULL
;
6553 json_object
*json_cluster_list
= NULL
;
6554 json_object
*json_cluster_list_list
= NULL
;
6555 json_object
*json_ext_community
= NULL
;
6556 json_object
*json_last_update
= NULL
;
6557 json_object
*json_nexthop_global
= NULL
;
6558 json_object
*json_nexthop_ll
= NULL
;
6559 json_object
*json_nexthops
= NULL
;
6560 json_object
*json_path
= NULL
;
6561 json_object
*json_peer
= NULL
;
6562 json_object
*json_string
= NULL
;
6563 json_object
*json_adv_to
= NULL
;
6565 struct listnode
*node
, *nnode
;
6567 int addpath_capable
;
6569 unsigned int first_as
;
6573 json_path
= json_object_new_object();
6574 json_peer
= json_object_new_object();
6575 json_nexthop_global
= json_object_new_object();
6582 /* Line1 display AS-path, Aggregator */
6587 json_object_lock(attr
->aspath
->json
);
6588 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6592 if (attr
->aspath
->segments
)
6593 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6595 vty_out (vty
, " Local");
6599 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6602 json_object_boolean_true_add(json_path
, "removed");
6604 vty_out (vty
, ", (removed)");
6607 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6610 json_object_boolean_true_add(json_path
, "stale");
6612 vty_out (vty
, ", (stale)");
6615 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6619 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6620 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6624 vty_out (vty
, ", (aggregated by %u %s)",
6625 attr
->extra
->aggregator_as
,
6626 inet_ntoa (attr
->extra
->aggregator_addr
));
6630 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6633 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6635 vty_out (vty
, ", (Received from a RR-client)");
6638 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6641 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6643 vty_out (vty
, ", (Received from a RS-client)");
6646 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6649 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6651 vty_out (vty
, ", (history entry)");
6653 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6656 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6658 vty_out (vty
, ", (suppressed due to dampening)");
6662 vty_out (vty
, "%s", VTY_NEWLINE
);
6664 /* Line2 display Next-hop, Neighbor, Router-id */
6665 /* Display the nexthop */
6666 if (p
->family
== AF_INET
&&
6667 (safi
== SAFI_MPLS_VPN
||
6668 safi
== SAFI_ENCAP
||
6669 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6671 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6674 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6676 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6681 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6683 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6687 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6691 assert (attr
->extra
);
6694 json_object_string_add(json_nexthop_global
, "ip",
6695 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6696 buf
, INET6_ADDRSTRLEN
));
6697 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6698 json_object_string_add(json_nexthop_global
, "scope", "global");
6702 vty_out (vty
, " %s",
6703 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6704 buf
, INET6_ADDRSTRLEN
));
6708 /* Display the IGP cost or 'inaccessible' */
6709 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6712 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6714 vty_out (vty
, " (inaccessible)");
6718 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6721 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6723 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6726 /* IGP cost is 0, display this only for json */
6730 json_object_int_add(json_nexthop_global
, "metric", 0);
6734 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6737 /* Display peer "from" output */
6738 /* This path was originated locally */
6739 if (binfo
->peer
== bgp
->peer_self
)
6742 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6745 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6747 vty_out (vty
, " from 0.0.0.0 ");
6752 json_object_string_add(json_peer
, "peerId", "::");
6754 vty_out (vty
, " from :: ");
6758 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6760 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
6763 /* We RXed this path from one of our peers */
6769 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6770 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6772 if (binfo
->peer
->hostname
)
6773 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
6775 if (binfo
->peer
->domainname
)
6776 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
6778 if (binfo
->peer
->conf_if
)
6779 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
6783 if (binfo
->peer
->conf_if
)
6785 if (binfo
->peer
->hostname
&&
6786 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6787 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6788 binfo
->peer
->conf_if
);
6790 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
6794 if (binfo
->peer
->hostname
&&
6795 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6796 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6799 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6802 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
6803 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
6805 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6810 vty_out (vty
, "%s", VTY_NEWLINE
);
6812 /* display the link-local nexthop */
6813 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6817 json_nexthop_ll
= json_object_new_object();
6818 json_object_string_add(json_nexthop_ll
, "ip",
6819 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6820 buf
, INET6_ADDRSTRLEN
));
6821 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6822 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6824 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
6826 if (!attr
->extra
->mp_nexthop_prefer_global
)
6827 json_object_boolean_true_add(json_nexthop_ll
, "used");
6829 json_object_boolean_true_add(json_nexthop_global
, "used");
6833 vty_out (vty
, " (%s) %s%s",
6834 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6835 buf
, INET6_ADDRSTRLEN
),
6836 attr
->extra
->mp_nexthop_prefer_global
?
6837 "(prefer-global)" : "(used)",
6841 /* If we do not have a link-local nexthop then we must flag the global as "used" */
6845 json_object_boolean_true_add(json_nexthop_global
, "used");
6848 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
6850 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6852 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
6854 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6857 json_object_int_add(json_path
, "med", attr
->med
);
6859 vty_out (vty
, ", metric %u", attr
->med
);
6862 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6865 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6867 vty_out (vty
, ", localpref %u", attr
->local_pref
);
6872 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
6874 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
6877 if (attr
->extra
&& attr
->extra
->weight
!= 0)
6880 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6882 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
6885 if (attr
->extra
&& attr
->extra
->tag
!= 0)
6888 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
6890 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
6893 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6896 json_object_boolean_false_add(json_path
, "valid");
6898 vty_out (vty
, ", invalid");
6900 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6903 json_object_boolean_true_add(json_path
, "valid");
6905 vty_out (vty
, ", valid");
6908 if (binfo
->peer
!= bgp
->peer_self
)
6910 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
6912 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
6915 json_object_string_add(json_peer
, "type", "confed-internal");
6917 vty_out (vty
, ", confed-internal");
6922 json_object_string_add(json_peer
, "type", "internal");
6924 vty_out (vty
, ", internal");
6929 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
6932 json_object_string_add(json_peer
, "type", "confed-external");
6934 vty_out (vty
, ", confed-external");
6939 json_object_string_add(json_peer
, "type", "external");
6941 vty_out (vty
, ", external");
6945 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
6949 json_object_boolean_true_add(json_path
, "aggregated");
6950 json_object_boolean_true_add(json_path
, "local");
6954 vty_out (vty
, ", aggregated, local");
6957 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
6960 json_object_boolean_true_add(json_path
, "sourced");
6962 vty_out (vty
, ", sourced");
6968 json_object_boolean_true_add(json_path
, "sourced");
6969 json_object_boolean_true_add(json_path
, "local");
6973 vty_out (vty
, ", sourced, local");
6977 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
6980 json_object_boolean_true_add(json_path
, "atomicAggregate");
6982 vty_out (vty
, ", atomic-aggregate");
6985 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
6986 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
6987 bgp_info_mpath_count (binfo
)))
6990 json_object_boolean_true_add(json_path
, "multipath");
6992 vty_out (vty
, ", multipath");
6995 // Mark the bestpath(s)
6996 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
6998 first_as
= aspath_get_first_as(attr
->aspath
);
7003 json_bestpath
= json_object_new_object();
7004 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7009 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7011 vty_out (vty
, ", bestpath-from-AS Local");
7015 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7020 json_bestpath
= json_object_new_object();
7021 json_object_boolean_true_add(json_bestpath
, "overall");
7024 vty_out (vty
, ", best");
7028 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7031 vty_out (vty
, "%s", VTY_NEWLINE
);
7033 /* Line 4 display Community */
7034 if (attr
->community
)
7038 json_object_lock(attr
->community
->json
);
7039 json_object_object_add(json_path
, "community", attr
->community
->json
);
7043 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7048 /* Line 5 display Extended-community */
7049 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7053 json_ext_community
= json_object_new_object();
7054 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7055 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7059 vty_out (vty
, " Extended Community: %s%s",
7060 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7064 /* Line 6 display Large community */
7065 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7066 vty_out (vty
, " Large Community: %s%s",
7067 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7069 /* Line 7 display Originator, Cluster-id */
7070 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7071 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7073 assert (attr
->extra
);
7074 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7077 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7079 vty_out (vty
, " Originator: %s",
7080 inet_ntoa (attr
->extra
->originator_id
));
7083 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7089 json_cluster_list
= json_object_new_object();
7090 json_cluster_list_list
= json_object_new_array();
7092 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7094 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7095 json_object_array_add(json_cluster_list_list
, json_string
);
7098 /* struct cluster_list does not have "str" variable like
7099 * aspath and community do. Add this someday if someone
7101 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7103 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7104 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7108 vty_out (vty
, ", Cluster list: ");
7110 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7112 vty_out (vty
, "%s ",
7113 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7119 vty_out (vty
, "%s", VTY_NEWLINE
);
7122 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7123 bgp_damp_info_vty (vty
, binfo
, json_path
);
7125 /* Line 8 display Addpath IDs */
7126 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7130 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7131 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7135 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7136 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7141 /* If we used addpath to TX a non-bestpath we need to display
7142 * "Advertised to" on a path-by-path basis */
7143 if (bgp
->addpath_tx_used
[afi
][safi
])
7147 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7149 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7150 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7152 if ((addpath_capable
&& has_adj
) ||
7153 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7155 if (json_path
&& !json_adv_to
)
7156 json_adv_to
= json_object_new_object();
7158 route_vty_out_advertised_to(vty
, peer
, &first
,
7168 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7175 vty_out (vty
, "%s", VTY_NEWLINE
);
7180 /* Line 9 display Uptime */
7181 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7184 json_last_update
= json_object_new_object();
7185 json_object_int_add(json_last_update
, "epoch", tbuf
);
7186 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7187 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7190 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7193 /* We've constructed the json object for this path, add it to the json
7198 if (json_nexthop_global
|| json_nexthop_ll
)
7200 json_nexthops
= json_object_new_array();
7202 if (json_nexthop_global
)
7203 json_object_array_add(json_nexthops
, json_nexthop_global
);
7205 if (json_nexthop_ll
)
7206 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7208 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7211 json_object_object_add(json_path
, "peer", json_peer
);
7212 json_object_array_add(json_paths
, json_path
);
7215 vty_out (vty
, "%s", VTY_NEWLINE
);
7218 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7219 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7220 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7224 bgp_show_type_normal
,
7225 bgp_show_type_regexp
,
7226 bgp_show_type_prefix_list
,
7227 bgp_show_type_filter_list
,
7228 bgp_show_type_route_map
,
7229 bgp_show_type_neighbor
,
7230 bgp_show_type_cidr_only
,
7231 bgp_show_type_prefix_longer
,
7232 bgp_show_type_community_all
,
7233 bgp_show_type_community
,
7234 bgp_show_type_community_exact
,
7235 bgp_show_type_community_list
,
7236 bgp_show_type_community_list_exact
,
7237 bgp_show_type_lcommunity_all
,
7238 bgp_show_type_lcommunity
,
7239 bgp_show_type_lcommunity_list
,
7240 bgp_show_type_flap_statistics
,
7241 bgp_show_type_flap_neighbor
,
7242 bgp_show_type_dampend_paths
,
7243 bgp_show_type_damp_neighbor
7247 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
7248 const char *prefix_list_str
, afi_t afi
,
7249 safi_t safi
, enum bgp_show_type type
);
7251 bgp_show_filter_list (struct vty
*vty
, const char *name
,
7252 const char *filter
, afi_t afi
,
7253 safi_t safi
, enum bgp_show_type type
);
7255 bgp_show_route_map (struct vty
*vty
, const char *name
,
7256 const char *rmap_str
, afi_t afi
,
7257 safi_t safi
, enum bgp_show_type type
);
7259 bgp_show_community_list (struct vty
*vty
, const char *name
,
7260 const char *com
, int exact
,
7261 afi_t afi
, safi_t safi
);
7263 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
7264 const char *prefix
, afi_t afi
,
7265 safi_t safi
, enum bgp_show_type type
);
7267 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7268 safi_t safi
, enum bgp_show_type type
);
7270 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
7271 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7274 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7275 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7277 struct bgp_info
*ri
;
7278 struct bgp_node
*rn
;
7281 unsigned long output_count
;
7282 unsigned long total_count
;
7286 json_object
*json_paths
= NULL
;
7291 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7292 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7293 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7294 table
->version
, inet_ntoa (bgp
->router_id
));
7295 json_paths
= json_object_new_object();
7298 /* This is first entry point, so reset total line. */
7302 /* Start processing of routes. */
7303 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7304 if (rn
->info
!= NULL
)
7307 if (!first
&& use_json
)
7312 json_paths
= json_object_new_array();
7316 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7319 if (type
== bgp_show_type_flap_statistics
7320 || type
== bgp_show_type_flap_neighbor
7321 || type
== bgp_show_type_dampend_paths
7322 || type
== bgp_show_type_damp_neighbor
)
7324 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7327 if (type
== bgp_show_type_regexp
)
7329 regex_t
*regex
= output_arg
;
7331 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7334 if (type
== bgp_show_type_prefix_list
)
7336 struct prefix_list
*plist
= output_arg
;
7338 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7341 if (type
== bgp_show_type_filter_list
)
7343 struct as_list
*as_list
= output_arg
;
7345 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7348 if (type
== bgp_show_type_route_map
)
7350 struct route_map
*rmap
= output_arg
;
7351 struct bgp_info binfo
;
7352 struct attr dummy_attr
;
7353 struct attr_extra dummy_extra
;
7356 dummy_attr
.extra
= &dummy_extra
;
7357 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7359 binfo
.peer
= ri
->peer
;
7360 binfo
.attr
= &dummy_attr
;
7362 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7363 if (ret
== RMAP_DENYMATCH
)
7366 if (type
== bgp_show_type_neighbor
7367 || type
== bgp_show_type_flap_neighbor
7368 || type
== bgp_show_type_damp_neighbor
)
7370 union sockunion
*su
= output_arg
;
7372 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7375 if (type
== bgp_show_type_cidr_only
)
7377 u_int32_t destination
;
7379 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7380 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7382 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7384 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7387 if (type
== bgp_show_type_prefix_longer
)
7389 struct prefix
*p
= output_arg
;
7391 if (! prefix_match (p
, &rn
->p
))
7394 if (type
== bgp_show_type_community_all
)
7396 if (! ri
->attr
->community
)
7399 if (type
== bgp_show_type_community
)
7401 struct community
*com
= output_arg
;
7403 if (! ri
->attr
->community
||
7404 ! community_match (ri
->attr
->community
, com
))
7407 if (type
== bgp_show_type_community_exact
)
7409 struct community
*com
= output_arg
;
7411 if (! ri
->attr
->community
||
7412 ! community_cmp (ri
->attr
->community
, com
))
7415 if (type
== bgp_show_type_community_list
)
7417 struct community_list
*list
= output_arg
;
7419 if (! community_list_match (ri
->attr
->community
, list
))
7422 if (type
== bgp_show_type_community_list_exact
)
7424 struct community_list
*list
= output_arg
;
7426 if (! community_list_exact_match (ri
->attr
->community
, list
))
7429 if (type
== bgp_show_type_community_all
)
7431 if (! ri
->attr
->community
)
7434 if (type
== bgp_show_type_lcommunity
)
7436 struct lcommunity
*lcom
= output_arg
;
7438 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7439 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7442 if (type
== bgp_show_type_lcommunity_list
)
7444 struct community_list
*list
= output_arg
;
7446 if (! ri
->attr
->extra
||
7447 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7450 if (type
== bgp_show_type_lcommunity_all
)
7452 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7455 if (type
== bgp_show_type_dampend_paths
7456 || type
== bgp_show_type_damp_neighbor
)
7458 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7459 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7463 if (!use_json
&& header
)
7465 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7466 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7467 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7468 if (type
== bgp_show_type_dampend_paths
7469 || type
== bgp_show_type_damp_neighbor
)
7470 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7471 else if (type
== bgp_show_type_flap_statistics
7472 || type
== bgp_show_type_flap_neighbor
)
7473 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7475 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7479 if (type
== bgp_show_type_dampend_paths
7480 || type
== bgp_show_type_damp_neighbor
)
7481 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7482 else if (type
== bgp_show_type_flap_statistics
7483 || type
== bgp_show_type_flap_neighbor
)
7484 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7486 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7496 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7497 vty_out (vty
, "\"%s\": ", buf2
);
7498 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7499 json_object_free (json_paths
);
7508 json_object_free (json_paths
);
7509 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7513 /* No route is displayed */
7514 if (output_count
== 0)
7516 if (type
== bgp_show_type_normal
)
7517 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7520 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7521 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7528 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7529 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7531 struct bgp_table
*table
;
7535 bgp
= bgp_get_default ();
7541 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7545 table
= bgp
->rib
[afi
][safi
];
7547 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7552 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7555 struct listnode
*node
, *nnode
;
7557 struct bgp_table
*table
;
7561 vty_out (vty
, "{%s", VTY_NEWLINE
);
7563 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7568 vty_out (vty
, ",%s", VTY_NEWLINE
);
7572 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7573 ? "Default" : bgp
->name
);
7577 vty_out (vty
, "%sInstance %s:%s",
7579 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7580 ? "Default" : bgp
->name
,
7583 table
= bgp
->rib
[afi
][safi
];
7584 bgp_show_table (vty
, bgp
, table
,
7585 bgp_show_type_normal
, NULL
, use_json
);
7590 vty_out (vty
, "}%s", VTY_NEWLINE
);
7593 /* Header of detailed BGP route information */
7595 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7596 struct bgp_node
*rn
,
7597 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7600 struct bgp_info
*ri
;
7603 struct listnode
*node
, *nnode
;
7604 char buf1
[INET6_ADDRSTRLEN
];
7605 char buf2
[INET6_ADDRSTRLEN
];
7610 int no_advertise
= 0;
7613 json_object
*json_adv_to
= NULL
;
7619 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7620 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7624 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7625 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
) ?
7626 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7627 safi
== SAFI_MPLS_VPN
? ":" : "",
7628 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
7629 p
->prefixlen
, VTY_NEWLINE
);
7632 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7635 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7638 if (ri
->extra
&& ri
->extra
->suppress
)
7640 if (ri
->attr
->community
!= NULL
)
7642 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7644 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7646 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7654 vty_out (vty
, "Paths: (%d available", count
);
7657 vty_out (vty
, ", best #%d", best
);
7658 if (safi
== SAFI_UNICAST
)
7659 vty_out (vty
, ", table %s",
7660 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7661 ? "Default-IP-Routing-Table" : bgp
->name
);
7664 vty_out (vty
, ", no best path");
7667 vty_out (vty
, ", not advertised to any peer");
7669 vty_out (vty
, ", not advertised to EBGP peer");
7671 vty_out (vty
, ", not advertised outside local AS");
7674 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7675 vty_out (vty
, ")%s", VTY_NEWLINE
);
7678 /* If we are not using addpath then we can display Advertised to and that will
7679 * show what peers we advertised the bestpath to. If we are using addpath
7680 * though then we must display Advertised to on a path-by-path basis. */
7681 if (!bgp
->addpath_tx_used
[afi
][safi
])
7683 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7685 if (bgp_adj_out_lookup (peer
, rn
, 0))
7687 if (json
&& !json_adv_to
)
7688 json_adv_to
= json_object_new_object();
7690 route_vty_out_advertised_to(vty
, peer
, &first
,
7691 " Advertised to non peer-group peers:\n ",
7700 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7706 vty_out (vty
, " Not advertised to any peer");
7707 vty_out (vty
, "%s", VTY_NEWLINE
);
7712 /* Display specified route of BGP table. */
7714 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7715 struct bgp_table
*rib
, const char *ip_str
,
7716 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7717 int prefix_check
, enum bgp_path_type pathtype
,
7723 struct prefix match
;
7724 struct bgp_node
*rn
;
7725 struct bgp_node
*rm
;
7726 struct bgp_info
*ri
;
7727 struct bgp_table
*table
;
7728 json_object
*json
= NULL
;
7729 json_object
*json_paths
= NULL
;
7731 /* Check IP address argument. */
7732 ret
= str2prefix (ip_str
, &match
);
7735 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7739 match
.family
= afi2family (afi
);
7743 json
= json_object_new_object();
7744 json_paths
= json_object_new_array();
7747 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
7749 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7751 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7754 if ((table
= rn
->info
) != NULL
)
7758 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7760 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7762 bgp_unlock_node (rm
);
7766 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7770 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7771 AFI_IP
, safi
, json
);
7776 if (pathtype
== BGP_PATH_ALL
||
7777 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7778 (pathtype
== BGP_PATH_MULTIPATH
&&
7779 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7780 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
7783 bgp_unlock_node (rm
);
7792 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
7794 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
7796 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7800 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
7805 if (pathtype
== BGP_PATH_ALL
||
7806 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7807 (pathtype
== BGP_PATH_MULTIPATH
&&
7808 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7809 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
7813 bgp_unlock_node (rn
);
7820 json_object_object_add(json
, "paths", json_paths
);
7822 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
7823 json_object_free(json
);
7829 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
7837 /* Display specified route of Main RIB */
7839 bgp_show_route (struct vty
*vty
, const char *view_name
, const char *ip_str
,
7840 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7841 int prefix_check
, enum bgp_path_type pathtype
,
7846 /* BGP structure lookup. */
7849 bgp
= bgp_lookup_by_name (view_name
);
7852 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
7858 bgp
= bgp_get_default ();
7861 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7866 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
7867 afi
, safi
, prd
, prefix_check
, pathtype
,
7872 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7873 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
7875 struct lcommunity
*lcom
;
7881 b
= buffer_new (1024);
7882 for (i
= 0; i
< argc
; i
++)
7885 buffer_putc (b
, ' ');
7888 if (strmatch (argv
[i
]->text
, "<AA:BB:CC>"))
7891 buffer_putstr (b
, argv
[i
]->arg
);
7895 buffer_putc (b
, '\0');
7897 str
= buffer_getstr (b
);
7900 lcom
= lcommunity_str2com (str
);
7901 XFREE (MTYPE_TMP
, str
);
7904 vty_out (vty
, "%% Large-community malformed: %s", VTY_NEWLINE
);
7908 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
7912 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
7913 afi_t afi
, safi_t safi
, u_char uj
)
7915 struct community_list
*list
;
7917 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
7920 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
7925 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
7928 /* BGP route print out function. */
7929 DEFUN (show_ip_bgp_ipv4
,
7930 show_ip_bgp_ipv4_cmd
,
7931 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]]\
7934 |dampening <flap-statistics|dampened-paths|parameters>\
7938 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
7939 |community-list <(1-500)|WORD> [exact-match]\
7940 |large-community [<AA:BB:CC>...]\
7941 |large-community-list <(1-500)|WORD>\
7942 |A.B.C.D/M longer-prefixes\
7943 |X:X::X:X/M longer-prefixes>\
7948 BGP_INSTANCE_HELP_STR
7951 "Address Family modifier\n"
7952 "Address Family modifier\n"
7953 "Address Family modifier\n"
7954 "Address Family modifier\n"
7955 "Display only routes with non-natural netmasks\n"
7956 "Display detailed information about dampening\n"
7957 "Display flap statistics of routes\n"
7958 "Display paths suppressed due to dampening\n"
7959 "Display dampening parameters\n"
7960 "Display routes matching the route-map\n"
7961 "A route-map to match on\n"
7962 "Display routes conforming to the prefix-list\n"
7963 "Prefix-list name\n"
7964 "Display routes conforming to the filter-list\n"
7965 "Regular expression access list name\n"
7966 "Display routes matching the communities\n"
7968 "Do not send outside local AS (well-known community)\n"
7969 "Do not advertise to any peer (well-known community)\n"
7970 "Do not export to next AS (well-known community)\n"
7971 "Exact match of the communities\n"
7972 "Display routes matching the community-list\n"
7973 "community-list number\n"
7974 "community-list name\n"
7975 "Exact match of the communities\n"
7976 "Display routes matching the large-communities\n"
7977 "large-community number\n"
7978 "large-community number\n"
7979 "large-community number\n"
7980 "large-community number\n"
7981 "Display routes matching the large-community-list\n"
7982 "large-community-list number\n"
7983 "large-community-list name\n"
7985 "Display route and more specific routes\n"
7987 "Display route and more specific routes\n"
7991 afi_t afi
= AFI_IP6
;
7992 safi_t safi
= SAFI_UNICAST
;
7993 int exact_match
= 0;
7994 enum bgp_show_type sh_type
= bgp_show_type_normal
;
7998 if (argv_find (argv
, argc
, "ip", &idx
))
8000 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8001 vrf
= argv
[++idx
]->arg
;
8002 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8004 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8005 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8006 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8008 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8011 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8012 // advance idx if necessary
8013 argv_find (argv
, argc
, "unicast", &idx
);
8016 int uj
= use_json (argc
, argv
);
8019 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8022 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8028 if (strmatch(argv
[idx
]->text
, "cidr-only"))
8029 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8031 else if (strmatch(argv
[idx
]->text
, "dampening"))
8033 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8034 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8035 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8036 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8037 else if (argv_find (argv
, argc
, "parameters", &idx
))
8038 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8041 else if (strmatch(argv
[idx
]->text
, "prefix-list"))
8042 return bgp_show_prefix_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8044 else if (strmatch(argv
[idx
]->text
, "filter-list"))
8045 return bgp_show_filter_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8047 else if (strmatch(argv
[idx
]->text
, "route-map"))
8048 return bgp_show_route_map (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8050 else if (strmatch(argv
[idx
]->text
, "community"))
8052 /* show a specific community */
8053 if (argv
[idx
+ 1]->type
== VARIABLE_TKN
||
8054 strmatch(argv
[idx
+ 1]->text
, "local-AS") ||
8055 strmatch(argv
[idx
+ 1]->text
, "no-advertise") ||
8056 strmatch(argv
[idx
+ 1]->text
, "no-export"))
8058 if (strmatch(argv
[idx
+ 2]->text
, "exact_match"))
8060 return bgp_show_community (vty
, vrf
, argc
, argv
, exact_match
, afi
, safi
);
8062 /* show all communities */
8064 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8066 else if (strmatch(argv
[idx
]->text
, "community-list"))
8068 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8069 if (++idx
< argc
&& strmatch (argv
[idx
]->arg
, "exact-match"))
8071 return bgp_show_community_list (vty
, vrf
, clist_number_or_name
, exact_match
, afi
, safi
);
8073 else if (strmatch(argv
[idx
]->text
, "large-community"))
8075 if (strmatch(argv
[idx
+1]->text
, "<AA:BB:CC>"))
8076 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8078 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8080 else if (strmatch(argv
[idx
]->text
, "large-community-list"))
8082 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8085 else if (argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV6_TKN
)
8086 return bgp_show_prefix_longer (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8089 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8092 DEFUN (show_ip_bgp_route
,
8093 show_ip_bgp_route_cmd
,
8094 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]]"
8095 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8099 BGP_INSTANCE_HELP_STR
8102 "Address Family modifier\n"
8103 "Address Family modifier\n"
8104 "Address Family modifier\n"
8105 "Address Family modifier\n"
8106 "Network in the BGP routing table to display\n"
8108 "Network in the BGP routing table to display\n"
8110 "Display only the bestpath\n"
8111 "Display only multipaths\n"
8114 int prefix_check
= 0;
8116 afi_t afi
= AFI_IP6
;
8117 safi_t safi
= SAFI_UNICAST
;
8119 char *prefix
= NULL
;
8121 enum bgp_path_type path_type
;
8122 u_char uj
= use_json(argc
, argv
);
8127 if (argv_find (argv
, argc
, "ip", &idx
))
8129 /* [<view|vrf> WORD] */
8130 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8131 vrf
= argv
[++idx
]->arg
;
8132 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8133 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8135 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8136 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8137 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8139 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8142 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8143 // advance idx if necessary
8144 argv_find (argv
, argc
, "unicast", &idx
);
8147 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8148 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8150 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8153 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8155 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8158 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8160 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8164 prefix
= argv
[idx
]->arg
;
8166 /* [<bestpath|multipath>] */
8167 if (argv_find (argv
, argc
, "bestpath", &idx
))
8168 path_type
= BGP_PATH_BESTPATH
;
8169 else if (argv_find (argv
, argc
, "multipath", &idx
))
8170 path_type
= BGP_PATH_MULTIPATH
;
8172 path_type
= BGP_PATH_ALL
;
8174 return bgp_show_route (vty
, vrf
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8177 DEFUN (show_ip_bgp_regexp
,
8178 show_ip_bgp_regexp_cmd
,
8179 "show [ip] bgp [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]|encap [unicast]|vpnv4 [unicast]>] regexp REGEX...",
8184 "Address Family modifier\n"
8185 "Address Family modifier\n"
8186 "Address Family modifier\n"
8187 "Address Family modifier\n"
8189 "Address Family modifier\n"
8190 "Address Family modifier\n"
8191 "Address Family modifier\n"
8192 "Address Family modifier\n"
8194 "Address Family modifier\n"
8196 "Address Family modifier\n"
8197 "Display routes matching the AS path regular expression\n"
8198 "A regular-expression to match the BGP AS paths\n")
8200 afi_t afi
= AFI_IP6
;
8201 safi_t safi
= SAFI_UNICAST
;
8205 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8206 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8208 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8209 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8210 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8212 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8215 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8216 // advance idx if necessary
8217 argv_find (argv
, argc
, "unicast", &idx
);
8220 // get index of regex
8221 argv_find (argv
, argc
, "regexp", &idx
);
8224 char *regstr
= argv_concat (argv
, argc
, idx
);
8225 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8226 XFREE (MTYPE_TMP
, regstr
);
8230 DEFUN (show_ip_bgp_instance_all
,
8231 show_ip_bgp_instance_all_cmd
,
8232 "show [ip] bgp <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [json]",
8236 BGP_INSTANCE_ALL_HELP_STR
8238 "Address Family modifier\n"
8239 "Address Family modifier\n"
8241 "Address Family modifier\n"
8242 "Address Family modifier\n"
8244 "Address Family modifier\n"
8246 "Address Family modifier\n"
8250 safi_t safi
= SAFI_UNICAST
;
8255 if (argv_find (argv
, argc
, "ip", &idx
))
8257 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8258 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8260 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8261 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8262 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8264 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8267 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8268 // advance idx if necessary
8269 argv_find (argv
, argc
, "unicast", &idx
);
8272 u_char uj
= use_json(argc
, argv
);
8274 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8280 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8281 safi_t safi
, enum bgp_show_type type
)
8288 regex
= bgp_regcomp (regstr
);
8291 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8295 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8296 bgp_regex_free (regex
);
8301 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
8302 const char *prefix_list_str
, afi_t afi
,
8303 safi_t safi
, enum bgp_show_type type
)
8305 struct prefix_list
*plist
;
8306 struct bgp
*bgp
= NULL
;
8308 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8310 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8314 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8317 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8318 prefix_list_str
, VTY_NEWLINE
);
8322 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8326 bgp_show_filter_list (struct vty
*vty
, const char *name
,
8327 const char *filter
, afi_t afi
,
8328 safi_t safi
, enum bgp_show_type type
)
8330 struct as_list
*as_list
;
8331 struct bgp
*bgp
= NULL
;
8333 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8335 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8339 as_list
= as_list_lookup (filter
);
8340 if (as_list
== NULL
)
8342 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8346 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8349 DEFUN (show_ip_bgp_dampening_info
,
8350 show_ip_bgp_dampening_params_cmd
,
8351 "show [ip] bgp dampening parameters",
8355 "Display detailed information about dampening\n"
8356 "Display detail of configured dampening parameters\n")
8358 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8362 DEFUN (show_ip_bgp_ipv4_dampening_parameters
,
8363 show_ip_bgp_ipv4_dampening_parameters_cmd
,
8364 "show [ip] bgp ipv4 <unicast|multicast> dampening parameters",
8369 "Address Family modifier\n"
8370 "Address Family modifier\n"
8371 "Display detailed information about dampening\n"
8372 "Display detail of configured dampening parameters\n")
8375 if (strncmp(argv
[idx_safi
]->arg
, "m", 1) == 0)
8376 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_MULTICAST
);
8378 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8382 bgp_show_route_map (struct vty
*vty
, const char *name
,
8383 const char *rmap_str
, afi_t afi
,
8384 safi_t safi
, enum bgp_show_type type
)
8386 struct route_map
*rmap
;
8387 struct bgp
*bgp
= NULL
;
8389 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8393 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8397 rmap
= route_map_lookup_by_name (rmap_str
);
8400 vty_out (vty
, "%% %s is not a valid route-map name%s",
8401 rmap_str
, VTY_NEWLINE
);
8405 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8409 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
8410 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8412 struct community
*com
;
8419 /* BGP structure lookup */
8422 bgp
= bgp_lookup_by_name (view_name
);
8425 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8431 bgp
= bgp_get_default ();
8434 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8439 b
= buffer_new (1024);
8440 for (i
= 0; i
< argc
; i
++)
8443 buffer_putc (b
, ' ');
8446 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8451 buffer_putstr (b
, argv
[i
]->arg
);
8453 buffer_putc (b
, '\0');
8455 str
= buffer_getstr (b
);
8458 com
= community_str2com (str
);
8459 XFREE (MTYPE_TMP
, str
);
8462 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8466 return bgp_show (vty
, bgp
, afi
, safi
,
8467 (exact
? bgp_show_type_community_exact
:
8468 bgp_show_type_community
), com
, 0);
8472 bgp_show_community_list (struct vty
*vty
, const char *name
,
8473 const char *com
, int exact
,
8474 afi_t afi
, safi_t safi
)
8476 struct community_list
*list
;
8477 struct bgp
*bgp
= NULL
;
8479 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8481 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8485 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8488 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8493 return bgp_show (vty
, bgp
, afi
, safi
,
8494 (exact
? bgp_show_type_community_list_exact
:
8495 bgp_show_type_community_list
), list
, 0);
8499 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
8500 const char *prefix
, afi_t afi
,
8501 safi_t safi
, enum bgp_show_type type
)
8505 struct bgp
*bgp
= NULL
;
8507 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8509 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8515 ret
= str2prefix (prefix
, p
);
8518 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8522 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8527 static struct peer
*
8528 peer_lookup_in_view (struct vty
*vty
, const char *view_name
,
8529 const char *ip_str
, u_char use_json
)
8536 /* BGP structure lookup. */
8539 bgp
= bgp_lookup_by_name (view_name
);
8544 json_object
*json_no
= NULL
;
8545 json_no
= json_object_new_object();
8546 json_object_string_add(json_no
, "warning", "Can't find BGP view");
8547 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8548 json_object_free(json_no
);
8551 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8557 bgp
= bgp_get_default ();
8562 json_object
*json_no
= NULL
;
8563 json_no
= json_object_new_object();
8564 json_object_string_add(json_no
, "warning", "No BGP process configured");
8565 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8566 json_object_free(json_no
);
8569 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8574 /* Get peer sockunion. */
8575 ret
= str2sockunion (ip_str
, &su
);
8578 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8581 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8587 json_object
*json_no
= NULL
;
8588 json_no
= json_object_new_object();
8589 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8590 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8591 json_object_free(json_no
);
8594 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8601 /* Peer structure lookup. */
8602 peer
= peer_lookup (bgp
, &su
);
8607 json_object
*json_no
= NULL
;
8608 json_no
= json_object_new_object();
8609 json_object_string_add(json_no
, "warning","No such neighbor");
8610 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8611 json_object_free(json_no
);
8614 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8623 BGP_STATS_MAXBITLEN
= 0,
8627 BGP_STATS_UNAGGREGATEABLE
,
8628 BGP_STATS_MAX_AGGREGATEABLE
,
8629 BGP_STATS_AGGREGATES
,
8631 BGP_STATS_ASPATH_COUNT
,
8632 BGP_STATS_ASPATH_MAXHOPS
,
8633 BGP_STATS_ASPATH_TOTHOPS
,
8634 BGP_STATS_ASPATH_MAXSIZE
,
8635 BGP_STATS_ASPATH_TOTSIZE
,
8636 BGP_STATS_ASN_HIGHEST
,
8640 static const char *table_stats_strs
[] =
8642 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8643 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8644 [BGP_STATS_RIB
] = "Total Advertisements",
8645 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8646 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8647 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8648 [BGP_STATS_SPACE
] = "Address space advertised",
8649 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8650 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8651 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8652 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8653 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8654 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8655 [BGP_STATS_MAX
] = NULL
,
8658 struct bgp_table_stats
8660 struct bgp_table
*table
;
8661 unsigned long long counts
[BGP_STATS_MAX
];
8665 #define TALLY_SIGFIG 100000
8666 static unsigned long
8667 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8669 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8670 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8671 unsigned long ret
= newtot
/ count
;
8673 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8681 bgp_table_stats_walker (struct thread
*t
)
8683 struct bgp_node
*rn
;
8684 struct bgp_node
*top
;
8685 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8686 unsigned int space
= 0;
8688 if (!(top
= bgp_table_top (ts
->table
)))
8691 switch (top
->p
.family
)
8694 space
= IPV4_MAX_BITLEN
;
8697 space
= IPV6_MAX_BITLEN
;
8701 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8703 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8705 struct bgp_info
*ri
;
8706 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8707 unsigned int rinum
= 0;
8715 ts
->counts
[BGP_STATS_PREFIXES
]++;
8716 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8719 ts
->counts
[BGP_STATS_AVGPLEN
]
8720 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8721 ts
->counts
[BGP_STATS_AVGPLEN
],
8725 /* check if the prefix is included by any other announcements */
8726 while (prn
&& !prn
->info
)
8727 prn
= bgp_node_parent_nolock (prn
);
8729 if (prn
== NULL
|| prn
== top
)
8731 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8732 /* announced address space */
8734 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8737 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8739 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8742 ts
->counts
[BGP_STATS_RIB
]++;
8745 (CHECK_FLAG (ri
->attr
->flag
,
8746 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8747 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8750 if (ri
->attr
&& ri
->attr
->aspath
)
8752 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8753 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8754 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8756 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8758 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8759 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8761 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8762 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8764 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8765 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8767 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8768 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8769 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8771 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8772 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8773 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8776 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8777 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8785 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8787 struct bgp_table_stats ts
;
8790 if (!bgp
->rib
[afi
][safi
])
8792 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8793 afi
, safi
, VTY_NEWLINE
);
8797 memset (&ts
, 0, sizeof (ts
));
8798 ts
.table
= bgp
->rib
[afi
][safi
];
8799 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8801 vty_out (vty
, "BGP %s RIB statistics%s%s",
8802 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8804 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8806 if (!table_stats_strs
[i
])
8812 case BGP_STATS_ASPATH_AVGHOPS
:
8813 case BGP_STATS_ASPATH_AVGSIZE
:
8814 case BGP_STATS_AVGPLEN
:
8815 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8816 vty_out (vty
, "%12.2f",
8817 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8820 case BGP_STATS_ASPATH_TOTHOPS
:
8821 case BGP_STATS_ASPATH_TOTSIZE
:
8822 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8823 vty_out (vty
, "%12.2f",
8825 (float)ts
.counts
[i
] /
8826 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8829 case BGP_STATS_TOTPLEN
:
8830 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8831 vty_out (vty
, "%12.2f",
8833 (float)ts
.counts
[i
] /
8834 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8837 case BGP_STATS_SPACE
:
8838 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8839 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8840 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8842 vty_out (vty
, "%30s: ", "%% announced ");
8843 vty_out (vty
, "%12.2f%s",
8844 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8845 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8847 vty_out (vty
, "%30s: ", "/8 equivalent ");
8848 vty_out (vty
, "%12.2f%s",
8849 (float)ts
.counts
[BGP_STATS_SPACE
] /
8850 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8852 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8854 vty_out (vty
, "%30s: ", "/24 equivalent ");
8855 vty_out (vty
, "%12.2f",
8856 (float)ts
.counts
[BGP_STATS_SPACE
] /
8857 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8860 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8861 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8864 vty_out (vty
, "%s", VTY_NEWLINE
);
8870 bgp_table_stats_vty (struct vty
*vty
, const char *name
,
8871 const char *afi_str
, const char *safi_str
)
8878 bgp
= bgp_lookup_by_name (name
);
8880 bgp
= bgp_get_default ();
8884 vty_out (vty
, "%% No such BGP instance exist%s", VTY_NEWLINE
);
8887 afi
= bgp_vty_afi_from_arg(afi_str
);
8890 vty_out (vty
, "%% Invalid address family \"%s\"%s",
8891 afi_str
, VTY_NEWLINE
);
8894 safi
= bgp_vty_safi_from_arg(safi_str
);
8895 if (safi
== SAFI_MAX
)
8897 vty_out (vty
, "%% Invalid subsequent address family %s%s",
8898 safi_str
, VTY_NEWLINE
);
8902 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8905 DEFUN (show_bgp_statistics
,
8906 show_bgp_statistics_cmd
,
8907 "show [ip] bgp <ipv4|ipv6> <encap|multicast|unicast|vpn> statistics",
8913 "Address Family modifier\n"
8914 "Address Family modifier\n"
8915 "Address Family modifier\n"
8916 "Address Family modifier\n"
8917 "BGP RIB advertisement statistics\n")
8921 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_afi
]->arg
, argv
[idx_safi
]->arg
);
8924 DEFUN (show_bgp_statistics_view
,
8925 show_bgp_statistics_view_cmd
,
8926 "show [ip] bgp <view|vrf> WORD <ipv4|ipv6> <unicast|multicast|vpn|encap> statistics",
8930 BGP_INSTANCE_HELP_STR
8933 "Address Family modifier\n"
8934 "Address Family modifier\n"
8935 "Address Family modifier\n"
8936 "Address Family modifier\n"
8937 "BGP RIB advertisement statistics\n")
8941 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_word
]->arg
, argv
[idx_afi
]->arg
);
8954 PCOUNT_PFCNT
, /* the figure we display to users */
8958 static const char *pcount_strs
[] =
8960 [PCOUNT_ADJ_IN
] = "Adj-in",
8961 [PCOUNT_DAMPED
] = "Damped",
8962 [PCOUNT_REMOVED
] = "Removed",
8963 [PCOUNT_HISTORY
] = "History",
8964 [PCOUNT_STALE
] = "Stale",
8965 [PCOUNT_VALID
] = "Valid",
8966 [PCOUNT_ALL
] = "All RIB",
8967 [PCOUNT_COUNTED
] = "PfxCt counted",
8968 [PCOUNT_PFCNT
] = "Useable",
8969 [PCOUNT_MAX
] = NULL
,
8974 unsigned int count
[PCOUNT_MAX
];
8975 const struct peer
*peer
;
8976 const struct bgp_table
*table
;
8980 bgp_peer_count_walker (struct thread
*t
)
8982 struct bgp_node
*rn
;
8983 struct peer_pcounts
*pc
= THREAD_ARG (t
);
8984 const struct peer
*peer
= pc
->peer
;
8986 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
8988 struct bgp_adj_in
*ain
;
8989 struct bgp_info
*ri
;
8991 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
8992 if (ain
->peer
== peer
)
8993 pc
->count
[PCOUNT_ADJ_IN
]++;
8995 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8997 char buf
[SU_ADDRSTRLEN
];
8999 if (ri
->peer
!= peer
)
9002 pc
->count
[PCOUNT_ALL
]++;
9004 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9005 pc
->count
[PCOUNT_DAMPED
]++;
9006 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9007 pc
->count
[PCOUNT_HISTORY
]++;
9008 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9009 pc
->count
[PCOUNT_REMOVED
]++;
9010 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9011 pc
->count
[PCOUNT_STALE
]++;
9012 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9013 pc
->count
[PCOUNT_VALID
]++;
9014 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9015 pc
->count
[PCOUNT_PFCNT
]++;
9017 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9019 pc
->count
[PCOUNT_COUNTED
]++;
9020 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9021 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9023 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9024 buf
, SU_ADDRSTRLEN
),
9030 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9031 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9033 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9034 buf
, SU_ADDRSTRLEN
),
9044 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9046 struct peer_pcounts pcounts
= { .peer
= peer
};
9048 json_object
*json
= NULL
;
9049 json_object
*json_loop
= NULL
;
9053 json
= json_object_new_object();
9054 json_loop
= json_object_new_object();
9057 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9058 || !peer
->bgp
->rib
[afi
][safi
])
9062 json_object_string_add(json
, "warning", "No such neighbor or address family");
9063 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9064 json_object_free(json
);
9067 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9072 memset (&pcounts
, 0, sizeof(pcounts
));
9073 pcounts
.peer
= peer
;
9074 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9076 /* in-place call via thread subsystem so as to record execution time
9077 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9078 * * on just vty_read()).
9080 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9084 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9085 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9086 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9088 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9089 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9091 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9093 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9095 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9096 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9098 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9099 json_object_free(json
);
9104 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9106 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9107 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9112 vty_out (vty
, "Prefix counts for %s, %s%s",
9113 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9116 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9117 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9118 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9120 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9121 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9123 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9125 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9126 peer
->host
, VTY_NEWLINE
);
9127 vty_out (vty
, "Please report this bug, with the above command output%s",
9135 DEFUN (show_ip_bgp_neighbor_prefix_counts
,
9136 show_ip_bgp_neighbor_prefix_counts_cmd
,
9137 "show [ip] bgp neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9141 "Detailed information on TCP and BGP neighbor connections\n"
9142 "Neighbor to display information about\n"
9143 "Neighbor to display information about\n"
9144 "Neighbor on BGP configured interface\n"
9145 "Display detailed prefix count information\n"
9150 u_char uj
= use_json(argc
, argv
);
9152 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9156 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9159 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9160 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9161 "show [ip] bgp <view|vrf> WORD neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9165 BGP_INSTANCE_HELP_STR
9166 "Detailed information on TCP and BGP neighbor connections\n"
9167 "Neighbor to display information about\n"
9168 "Neighbor to display information about\n"
9169 "Neighbor on BGP configured interface\n"
9170 "Display detailed prefix count information\n"
9176 u_char uj
= use_json(argc
, argv
);
9178 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9182 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9185 DEFUN (show_bgp_ipv6_neighbor_prefix_counts
,
9186 show_bgp_ipv6_neighbor_prefix_counts_cmd
,
9187 "show [ip] bgp ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9192 "Detailed information on TCP and BGP neighbor connections\n"
9193 "Neighbor to display information about\n"
9194 "Neighbor to display information about\n"
9195 "Neighbor on BGP configured interface\n"
9196 "Display detailed prefix count information\n"
9201 u_char uj
= use_json(argc
, argv
);
9203 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9207 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9210 DEFUN (show_bgp_instance_ipv6_neighbor_prefix_counts
,
9211 show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
,
9212 "show [ip] bgp <view|vrf> WORD ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9216 BGP_INSTANCE_HELP_STR
9218 "Detailed information on TCP and BGP neighbor connections\n"
9219 "Neighbor to display information about\n"
9220 "Neighbor to display information about\n"
9221 "Neighbor on BGP configured interface\n"
9222 "Display detailed prefix count information\n"
9228 u_char uj
= use_json(argc
, argv
);
9230 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9234 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9237 DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts
,
9238 show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
,
9239 "show [ip] bgp ipv4 <unicast|multicast> neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9244 "Address Family modifier\n"
9245 "Address Family modifier\n"
9246 "Detailed information on TCP and BGP neighbor connections\n"
9247 "Neighbor to display information about\n"
9248 "Neighbor to display information about\n"
9249 "Neighbor on BGP configured interface\n"
9250 "Display detailed prefix count information\n"
9256 u_char uj
= use_json(argc
, argv
);
9258 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9262 if (strncmp (argv
[idx_safi
]->arg
, "m", 1) == 0)
9263 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MULTICAST
, uj
);
9265 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9268 DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts
,
9269 show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
,
9270 "show [ip] bgp vpnv4 all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9275 "Display information about all VPNv4 NLRIs\n"
9276 "Detailed information on TCP and BGP neighbor connections\n"
9277 "Neighbor to display information about\n"
9278 "Neighbor to display information about\n"
9279 "Neighbor on BGP configured interface\n"
9280 "Display detailed prefix count information\n"
9285 u_char uj
= use_json(argc
, argv
);
9287 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9291 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9294 DEFUN (show_ip_bgp_vpnv4_all_route_prefix
,
9295 show_ip_bgp_vpnv4_all_route_prefix_cmd
,
9296 "show [ip] bgp vpnv4 all <A.B.C.D|A.B.C.D/M> [json]",
9301 "Display information about all VPNv4 NLRIs\n"
9302 "Network in the BGP routing table to display\n"
9303 "Network in the BGP routing table to display\n"
9307 char *network
= NULL
;
9308 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9309 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9310 return bgp_show_route (vty
, NULL
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9314 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9315 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9317 struct bgp_table
*table
;
9318 struct bgp_adj_in
*ain
;
9319 struct bgp_adj_out
*adj
;
9320 unsigned long output_count
;
9321 unsigned long filtered_count
;
9322 struct bgp_node
*rn
;
9327 struct attr_extra extra
;
9329 struct update_subgroup
*subgrp
;
9330 json_object
*json_scode
= NULL
;
9331 json_object
*json_ocode
= NULL
;
9332 json_object
*json_ar
= NULL
;
9333 struct peer_af
*paf
;
9337 json_scode
= json_object_new_object();
9338 json_ocode
= json_object_new_object();
9339 json_ar
= json_object_new_object();
9341 json_object_string_add(json_scode
, "suppressed", "s");
9342 json_object_string_add(json_scode
, "damped", "d");
9343 json_object_string_add(json_scode
, "history", "h");
9344 json_object_string_add(json_scode
, "valid", "*");
9345 json_object_string_add(json_scode
, "best", ">");
9346 json_object_string_add(json_scode
, "multipath", "=");
9347 json_object_string_add(json_scode
, "internal", "i");
9348 json_object_string_add(json_scode
, "ribFailure", "r");
9349 json_object_string_add(json_scode
, "stale", "S");
9350 json_object_string_add(json_scode
, "removed", "R");
9352 json_object_string_add(json_ocode
, "igp", "i");
9353 json_object_string_add(json_ocode
, "egp", "e");
9354 json_object_string_add(json_ocode
, "incomplete", "?");
9363 json_object_string_add(json
, "alert", "no BGP");
9364 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9365 json_object_free(json
);
9368 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9372 table
= bgp
->rib
[afi
][safi
];
9374 output_count
= filtered_count
= 0;
9375 subgrp
= peer_subgroup(peer
, afi
, safi
);
9377 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9381 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9382 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9383 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9384 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9385 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9389 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9390 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9391 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9393 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9394 VTY_NEWLINE
, VTY_NEWLINE
);
9399 attr
.extra
= &extra
;
9400 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9404 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9406 if (ain
->peer
== peer
)
9412 json_object_int_add(json
, "bgpTableVersion", 0);
9413 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9414 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9415 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9419 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9420 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9421 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9428 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9433 bgp_attr_dup(&attr
, ain
->attr
);
9434 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9436 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9447 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9448 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9449 if (paf
->peer
== peer
)
9455 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9456 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9457 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9458 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9462 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9463 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9464 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9465 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9473 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9479 bgp_attr_dup(&attr
, adj
->attr
);
9480 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9481 if (ret
!= RMAP_DENY
)
9483 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9493 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9495 if (output_count
!= 0)
9498 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9500 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9501 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9505 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9506 json_object_free(json
);
9512 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9513 int in
, const char *rmap_name
, u_char use_json
)
9515 json_object
*json
= NULL
;
9518 json
= json_object_new_object();
9520 if (!peer
|| !peer
->afc
[afi
][safi
])
9524 json_object_string_add(json
, "warning", "No such neighbor or address family");
9525 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9526 json_object_free(json
);
9529 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9534 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9538 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9539 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9540 json_object_free(json
);
9543 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9548 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9553 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9554 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9555 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] neighbors <A.B.C.D|X:X::X:X|WORD> [<received-routes|advertised-routes> [route-map WORD]] [json]",
9559 BGP_INSTANCE_HELP_STR
9561 "Address Family modifier\n"
9562 "Address Family modifier\n"
9564 "Address Family modifier\n"
9565 "Address Family modifier\n"
9567 "Address Family modifier\n"
9569 "Address Family modifier\n"
9570 "Detailed information on TCP and BGP neighbor connections\n"
9571 "Neighbor to display information about\n"
9572 "Neighbor to display information about\n"
9573 "Neighbor on BGP configured interface\n"
9574 "Display the received routes from neighbor\n"
9575 "Display the routes advertised to a BGP neighbor\n"
9576 "Route-map to modify the attributes\n"
9577 "Name of the route map\n"
9580 afi_t afi
= AFI_IP6
;
9581 safi_t safi
= SAFI_UNICAST
;
9583 char *rmap_name
= NULL
;
9584 char *peerstr
= NULL
;
9592 if (argv_find (argv
, argc
, "ip", &idx
))
9594 /* [<view|vrf> WORD] */
9595 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9596 vrf
= argv
[++idx
]->arg
;
9597 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9598 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9600 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9601 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9602 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9604 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9607 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9608 // advance idx if necessary
9609 argv_find (argv
, argc
, "unicast", &idx
);
9612 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9613 argv_find (argv
, argc
, "neighbors", &idx
);
9614 peerstr
= argv
[++idx
]->arg
;
9616 u_char uj
= use_json(argc
, argv
);
9618 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9622 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9626 if (argv_find (argv
, argc
, "received-routes", &idx
))
9628 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9630 if (argv_find (argv
, argc
, "route-map", &idx
))
9631 rmap_name
= argv
[++idx
]->arg
;
9633 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9636 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9637 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9638 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9644 "Address Family modifier\n"
9645 "Detailed information on TCP and BGP neighbor connections\n"
9646 "Neighbor to display information about\n"
9647 "Neighbor to display information about\n"
9648 "Neighbor on BGP configured interface\n"
9649 "Display information received from a BGP neighbor\n"
9650 "Display the prefixlist filter\n"
9653 afi_t afi
= AFI_IP6
;
9654 safi_t safi
= SAFI_UNICAST
;
9655 char *peerstr
= NULL
;
9665 if (argv_find (argv
, argc
, "ip", &idx
))
9667 /* [<ipv4|ipv6> [unicast]] */
9668 if (argv_find (argv
, argc
, "ipv4", &idx
))
9670 if (argv_find (argv
, argc
, "ipv6", &idx
))
9672 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9673 argv_find (argv
, argc
, "neighbors", &idx
);
9674 peerstr
= argv
[++idx
]->arg
;
9676 u_char uj
= use_json(argc
, argv
);
9678 ret
= str2sockunion (peerstr
, &su
);
9681 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9685 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9687 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9693 peer
= peer_lookup (NULL
, &su
);
9697 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9699 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9704 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9705 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9709 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9710 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9715 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9717 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9724 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9725 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9727 if (! peer
|| ! peer
->afc
[afi
][safi
])
9731 json_object
*json_no
= NULL
;
9732 json_no
= json_object_new_object();
9733 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9734 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9735 json_object_free(json_no
);
9738 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9742 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9745 DEFUN (show_ip_bgp_neighbor_routes
,
9746 show_ip_bgp_neighbor_routes_cmd
,
9747 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9751 BGP_INSTANCE_HELP_STR
9753 "Address Family modifier\n"
9754 "Address Family modifier\n"
9756 "Address Family modifier\n"
9757 "Address Family modifier\n"
9759 "Address Family modifier\n"
9761 "Address Family modifier\n"
9762 "Detailed information on TCP and BGP neighbor connections\n"
9763 "Neighbor to display information about\n"
9764 "Neighbor to display information about\n"
9765 "Neighbor on BGP configured interface\n"
9766 "Display flap statistics of the routes learned from neighbor\n"
9767 "Display the dampened routes received from neighbor\n"
9768 "Display routes learned from neighbor\n"
9772 char *peerstr
= NULL
;
9774 afi_t afi
= AFI_IP6
;
9775 safi_t safi
= SAFI_UNICAST
;
9777 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9782 if (argv_find (argv
, argc
, "ip", &idx
))
9784 /* [<view|vrf> WORD] */
9785 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9786 vrf
= argv
[++idx
]->arg
;
9787 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9788 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9790 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9791 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9792 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9794 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9797 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9798 // advance idx if necessary
9799 argv_find (argv
, argc
, "unicast", &idx
);
9801 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9802 argv_find (argv
, argc
, "neighbors", &idx
);
9803 peerstr
= argv
[++idx
]->arg
;
9805 u_char uj
= use_json(argc
, argv
);
9807 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9810 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9814 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9815 sh_type
= bgp_show_type_flap_neighbor
;
9816 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9817 sh_type
= bgp_show_type_damp_neighbor
;
9818 else if (argv_find (argv
, argc
, "routes", &idx
))
9819 sh_type
= bgp_show_type_neighbor
;
9821 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9824 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9828 /* Distance value for the IP source prefix. */
9831 /* Name of the access-list to be matched. */
9835 static struct bgp_distance
*
9836 bgp_distance_new (void)
9838 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9842 bgp_distance_free (struct bgp_distance
*bdistance
)
9844 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9848 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9849 const char *ip_str
, const char *access_list_str
)
9856 struct bgp_node
*rn
;
9857 struct bgp_distance
*bdistance
;
9859 afi
= bgp_node_afi (vty
);
9860 safi
= bgp_node_safi (vty
);
9862 ret
= str2prefix (ip_str
, &p
);
9865 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9869 distance
= atoi (distance_str
);
9871 /* Get BGP distance node. */
9872 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9875 bdistance
= rn
->info
;
9876 bgp_unlock_node (rn
);
9880 bdistance
= bgp_distance_new ();
9881 rn
->info
= bdistance
;
9884 /* Set distance value. */
9885 bdistance
->distance
= distance
;
9887 /* Reset access-list configuration. */
9888 if (bdistance
->access_list
)
9890 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9891 bdistance
->access_list
= NULL
;
9893 if (access_list_str
)
9894 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9900 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9901 const char *ip_str
, const char *access_list_str
)
9908 struct bgp_node
*rn
;
9909 struct bgp_distance
*bdistance
;
9911 afi
= bgp_node_afi (vty
);
9912 safi
= bgp_node_safi (vty
);
9914 ret
= str2prefix (ip_str
, &p
);
9917 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9921 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9924 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9928 bdistance
= rn
->info
;
9929 distance
= atoi(distance_str
);
9931 if (bdistance
->distance
!= distance
)
9933 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9937 if (bdistance
->access_list
)
9938 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9939 bgp_distance_free (bdistance
);
9942 bgp_unlock_node (rn
);
9943 bgp_unlock_node (rn
);
9948 /* Apply BGP information to distance method. */
9950 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9951 safi_t safi
, struct bgp
*bgp
)
9953 struct bgp_node
*rn
;
9956 struct bgp_distance
*bdistance
;
9957 struct access_list
*alist
;
9958 struct bgp_static
*bgp_static
;
9965 /* Check source address. */
9966 sockunion2hostprefix (&peer
->su
, &q
);
9967 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9970 bdistance
= rn
->info
;
9971 bgp_unlock_node (rn
);
9973 if (bdistance
->access_list
)
9975 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9976 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9977 return bdistance
->distance
;
9980 return bdistance
->distance
;
9983 /* Backdoor check. */
9984 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9987 bgp_static
= rn
->info
;
9988 bgp_unlock_node (rn
);
9990 if (bgp_static
->backdoor
)
9992 if (bgp
->distance_local
[afi
][safi
])
9993 return bgp
->distance_local
[afi
][safi
];
9995 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9999 if (peer
->sort
== BGP_PEER_EBGP
)
10001 if (bgp
->distance_ebgp
[afi
][safi
])
10002 return bgp
->distance_ebgp
[afi
][safi
];
10003 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10007 if (bgp
->distance_ibgp
[afi
][safi
])
10008 return bgp
->distance_ibgp
[afi
][safi
];
10009 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10013 DEFUN (bgp_distance
,
10015 "distance bgp (1-255) (1-255) (1-255)",
10016 "Define an administrative distance\n"
10018 "Distance for routes external to the AS\n"
10019 "Distance for routes internal to the AS\n"
10020 "Distance for local routes\n")
10022 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10023 int idx_number
= 2;
10024 int idx_number_2
= 3;
10025 int idx_number_3
= 4;
10029 afi
= bgp_node_afi (vty
);
10030 safi
= bgp_node_safi (vty
);
10032 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10033 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10034 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10035 return CMD_SUCCESS
;
10038 DEFUN (no_bgp_distance
,
10039 no_bgp_distance_cmd
,
10040 "no distance bgp [(1-255) (1-255) (1-255)]",
10042 "Define an administrative distance\n"
10044 "Distance for routes external to the AS\n"
10045 "Distance for routes internal to the AS\n"
10046 "Distance for local routes\n")
10048 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10052 afi
= bgp_node_afi (vty
);
10053 safi
= bgp_node_safi (vty
);
10055 bgp
->distance_ebgp
[afi
][safi
] = 0;
10056 bgp
->distance_ibgp
[afi
][safi
] = 0;
10057 bgp
->distance_local
[afi
][safi
] = 0;
10058 return CMD_SUCCESS
;
10062 DEFUN (bgp_distance_source
,
10063 bgp_distance_source_cmd
,
10064 "distance (1-255) A.B.C.D/M",
10065 "Define an administrative distance\n"
10066 "Administrative distance\n"
10067 "IP source prefix\n")
10069 int idx_number
= 1;
10070 int idx_ipv4_prefixlen
= 2;
10071 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10072 return CMD_SUCCESS
;
10075 DEFUN (no_bgp_distance_source
,
10076 no_bgp_distance_source_cmd
,
10077 "no distance (1-255) A.B.C.D/M",
10079 "Define an administrative distance\n"
10080 "Administrative distance\n"
10081 "IP source prefix\n")
10083 int idx_number
= 2;
10084 int idx_ipv4_prefixlen
= 3;
10085 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10086 return CMD_SUCCESS
;
10089 DEFUN (bgp_distance_source_access_list
,
10090 bgp_distance_source_access_list_cmd
,
10091 "distance (1-255) A.B.C.D/M WORD",
10092 "Define an administrative distance\n"
10093 "Administrative distance\n"
10094 "IP source prefix\n"
10095 "Access list name\n")
10097 int idx_number
= 1;
10098 int idx_ipv4_prefixlen
= 2;
10100 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10101 return CMD_SUCCESS
;
10104 DEFUN (no_bgp_distance_source_access_list
,
10105 no_bgp_distance_source_access_list_cmd
,
10106 "no distance (1-255) A.B.C.D/M WORD",
10108 "Define an administrative distance\n"
10109 "Administrative distance\n"
10110 "IP source prefix\n"
10111 "Access list name\n")
10113 int idx_number
= 2;
10114 int idx_ipv4_prefixlen
= 3;
10116 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10117 return CMD_SUCCESS
;
10120 DEFUN (ipv6_bgp_distance_source
,
10121 ipv6_bgp_distance_source_cmd
,
10122 "distance (1-255) X:X::X:X/M",
10123 "Define an administrative distance\n"
10124 "Administrative distance\n"
10125 "IP source prefix\n")
10127 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10128 return CMD_SUCCESS
;
10131 DEFUN (no_ipv6_bgp_distance_source
,
10132 no_ipv6_bgp_distance_source_cmd
,
10133 "no distance (1-255) X:X::X:X/M",
10135 "Define an administrative distance\n"
10136 "Administrative distance\n"
10137 "IP source prefix\n")
10139 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10140 return CMD_SUCCESS
;
10143 DEFUN (ipv6_bgp_distance_source_access_list
,
10144 ipv6_bgp_distance_source_access_list_cmd
,
10145 "distance (1-255) X:X::X:X/M WORD",
10146 "Define an administrative distance\n"
10147 "Administrative distance\n"
10148 "IP source prefix\n"
10149 "Access list name\n")
10151 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10152 return CMD_SUCCESS
;
10155 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10156 no_ipv6_bgp_distance_source_access_list_cmd
,
10157 "no distance (1-255) X:X::X:X/M WORD",
10159 "Define an administrative distance\n"
10160 "Administrative distance\n"
10161 "IP source prefix\n"
10162 "Access list name\n")
10164 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10165 return CMD_SUCCESS
;
10168 DEFUN (bgp_damp_set
,
10170 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10171 "BGP Specific commands\n"
10172 "Enable route-flap dampening\n"
10173 "Half-life time for the penalty\n"
10174 "Value to start reusing a route\n"
10175 "Value to start suppressing a route\n"
10176 "Maximum duration to suppress a stable route\n")
10178 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10179 int idx_half_life
= 2;
10181 int idx_suppress
= 4;
10182 int idx_max_suppress
= 5;
10183 int half
= DEFAULT_HALF_LIFE
* 60;
10184 int reuse
= DEFAULT_REUSE
;
10185 int suppress
= DEFAULT_SUPPRESS
;
10186 int max
= 4 * half
;
10190 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10191 reuse
= atoi (argv
[idx_reuse
]->arg
);
10192 suppress
= atoi (argv
[idx_suppress
]->arg
);
10193 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10195 else if (argc
== 3)
10197 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10201 if (suppress
< reuse
)
10203 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10208 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10209 half
, reuse
, suppress
, max
);
10212 DEFUN (bgp_damp_unset
,
10213 bgp_damp_unset_cmd
,
10214 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10216 "BGP Specific commands\n"
10217 "Enable route-flap dampening\n"
10218 "Half-life time for the penalty\n"
10219 "Value to start reusing a route\n"
10220 "Value to start suppressing a route\n"
10221 "Maximum duration to suppress a stable route\n")
10223 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10224 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10227 /* Display specified route of BGP table. */
10229 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10230 const char *ip_str
, afi_t afi
, safi_t safi
,
10231 struct prefix_rd
*prd
, int prefix_check
)
10234 struct prefix match
;
10235 struct bgp_node
*rn
;
10236 struct bgp_node
*rm
;
10237 struct bgp_info
*ri
;
10238 struct bgp_info
*ri_temp
;
10240 struct bgp_table
*table
;
10242 /* BGP structure lookup. */
10245 bgp
= bgp_lookup_by_name (view_name
);
10248 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10249 return CMD_WARNING
;
10254 bgp
= bgp_get_default ();
10257 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10258 return CMD_WARNING
;
10262 /* Check IP address argument. */
10263 ret
= str2prefix (ip_str
, &match
);
10266 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10267 return CMD_WARNING
;
10270 match
.family
= afi2family (afi
);
10272 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10274 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10276 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10279 if ((table
= rn
->info
) != NULL
)
10280 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10282 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10287 if (ri
->extra
&& ri
->extra
->damp_info
)
10289 ri_temp
= ri
->next
;
10290 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10298 bgp_unlock_node (rm
);
10304 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10306 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10311 if (ri
->extra
&& ri
->extra
->damp_info
)
10313 ri_temp
= ri
->next
;
10314 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10322 bgp_unlock_node (rn
);
10326 return CMD_SUCCESS
;
10329 DEFUN (clear_ip_bgp_dampening
,
10330 clear_ip_bgp_dampening_cmd
,
10331 "clear ip bgp dampening",
10335 "Clear route flap dampening information\n")
10337 bgp_damp_info_clean ();
10338 return CMD_SUCCESS
;
10341 DEFUN (clear_ip_bgp_dampening_prefix
,
10342 clear_ip_bgp_dampening_prefix_cmd
,
10343 "clear ip bgp dampening A.B.C.D/M",
10347 "Clear route flap dampening information\n"
10350 int idx_ipv4_prefixlen
= 4;
10351 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10352 SAFI_UNICAST
, NULL
, 1);
10355 DEFUN (clear_ip_bgp_dampening_address
,
10356 clear_ip_bgp_dampening_address_cmd
,
10357 "clear ip bgp dampening A.B.C.D",
10361 "Clear route flap dampening information\n"
10362 "Network to clear damping information\n")
10365 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10366 SAFI_UNICAST
, NULL
, 0);
10369 DEFUN (clear_ip_bgp_dampening_address_mask
,
10370 clear_ip_bgp_dampening_address_mask_cmd
,
10371 "clear ip bgp dampening A.B.C.D A.B.C.D",
10375 "Clear route flap dampening information\n"
10376 "Network to clear damping information\n"
10380 int idx_ipv4_2
= 5;
10382 char prefix_str
[BUFSIZ
];
10384 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10387 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10388 return CMD_WARNING
;
10391 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10392 SAFI_UNICAST
, NULL
, 0);
10395 /* also used for encap safi */
10397 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10398 afi_t afi
, safi_t safi
, int *write
)
10400 struct bgp_node
*prn
;
10401 struct bgp_node
*rn
;
10402 struct bgp_table
*table
;
10404 struct prefix_rd
*prd
;
10405 struct bgp_static
*bgp_static
;
10407 char buf
[SU_ADDRSTRLEN
];
10408 char rdbuf
[RD_ADDRSTRLEN
];
10410 /* Network configuration. */
10411 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10412 if ((table
= prn
->info
) != NULL
)
10413 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10414 if ((bgp_static
= rn
->info
) != NULL
)
10417 prd
= (struct prefix_rd
*) &prn
->p
;
10419 /* "address-family" display. */
10420 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10422 /* "network" configuration display. */
10423 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10424 label
= decode_label (bgp_static
->tag
);
10426 vty_out (vty
, " network %s/%d rd %s tag %d",
10427 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10430 vty_out (vty
, "%s", VTY_NEWLINE
);
10435 /* Configuration of static route announcement and aggregate
10438 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10439 afi_t afi
, safi_t safi
, int *write
)
10441 struct bgp_node
*rn
;
10443 struct bgp_static
*bgp_static
;
10444 struct bgp_aggregate
*bgp_aggregate
;
10445 char buf
[SU_ADDRSTRLEN
];
10447 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10448 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10450 /* Network configuration. */
10451 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10452 if ((bgp_static
= rn
->info
) != NULL
)
10456 /* "address-family" display. */
10457 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10459 /* "network" configuration display. */
10460 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10462 u_int32_t destination
;
10463 struct in_addr netmask
;
10465 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10466 masklen2ip (p
->prefixlen
, &netmask
);
10467 vty_out (vty
, " network %s",
10468 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10470 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10471 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10472 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10473 || p
->u
.prefix4
.s_addr
== 0)
10475 /* Natural mask is not display. */
10478 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10482 vty_out (vty
, " network %s/%d",
10483 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10487 if (bgp_static
->rmap
.name
)
10488 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10491 if (bgp_static
->backdoor
)
10492 vty_out (vty
, " backdoor");
10495 vty_out (vty
, "%s", VTY_NEWLINE
);
10498 /* Aggregate-address configuration. */
10499 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10500 if ((bgp_aggregate
= rn
->info
) != NULL
)
10504 /* "address-family" display. */
10505 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10507 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10509 struct in_addr netmask
;
10511 masklen2ip (p
->prefixlen
, &netmask
);
10512 vty_out (vty
, " aggregate-address %s %s",
10513 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10514 inet_ntoa (netmask
));
10518 vty_out (vty
, " aggregate-address %s/%d",
10519 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10523 if (bgp_aggregate
->as_set
)
10524 vty_out (vty
, " as-set");
10526 if (bgp_aggregate
->summary_only
)
10527 vty_out (vty
, " summary-only");
10529 vty_out (vty
, "%s", VTY_NEWLINE
);
10536 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10537 safi_t safi
, int *write
)
10539 struct bgp_node
*rn
;
10540 struct bgp_distance
*bdistance
;
10542 /* Distance configuration. */
10543 if (bgp
->distance_ebgp
[afi
][safi
]
10544 && bgp
->distance_ibgp
[afi
][safi
]
10545 && bgp
->distance_local
[afi
][safi
]
10546 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10547 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10548 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10550 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10551 vty_out (vty
, " distance bgp %d %d %d%s",
10552 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10553 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10556 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10557 rn
= bgp_route_next (rn
))
10558 if ((bdistance
= rn
->info
) != NULL
)
10560 char buf
[PREFIX_STRLEN
];
10562 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10563 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10564 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10565 bdistance
->access_list
? bdistance
->access_list
: "",
10572 /* Allocate routing table structure and install commands. */
10574 bgp_route_init (void)
10579 /* Init BGP distance table. */
10580 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10581 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10582 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10584 /* IPv4 BGP commands. */
10585 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10586 install_element (BGP_NODE
, &bgp_network_cmd
);
10587 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10588 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10589 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10590 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10591 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10592 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10593 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10594 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10595 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10596 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10597 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10598 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10600 install_element (BGP_NODE
, &aggregate_address_cmd
);
10601 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10602 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10603 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10605 /* IPv4 unicast configuration. */
10606 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10607 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10608 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10609 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10610 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10611 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10612 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10613 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10614 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10615 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10616 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10618 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10619 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10620 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10621 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10623 /* IPv4 multicast configuration. */
10624 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10625 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10626 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10627 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10628 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10629 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10630 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10631 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10632 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10633 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10634 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10635 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10636 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10637 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10638 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10640 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10641 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_cmd
);
10642 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10643 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10645 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10646 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10647 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10648 install_element (VIEW_NODE
, &show_ip_bgp_dampening_params_cmd
);
10649 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_dampening_parameters_cmd
);
10650 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_route_prefix_cmd
);
10652 /* BGP dampening clear commands */
10653 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10654 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10656 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10657 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10660 install_element (ENABLE_NODE
, &show_ip_bgp_neighbor_prefix_counts_cmd
);
10661 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10662 install_element (ENABLE_NODE
, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
);
10663 install_element (ENABLE_NODE
, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
);
10664 install_element (ENABLE_NODE
, &show_bgp_ipv6_neighbor_prefix_counts_cmd
);
10665 install_element (ENABLE_NODE
, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
);
10667 /* New config IPv6 BGP commands. */
10668 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10669 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10670 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10671 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10672 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10674 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10675 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10677 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10678 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10681 install_element (ENABLE_NODE
, &show_bgp_statistics_cmd
);
10682 install_element (ENABLE_NODE
, &show_bgp_statistics_view_cmd
);
10684 install_element (BGP_NODE
, &bgp_distance_cmd
);
10685 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10686 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10687 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10688 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10689 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10690 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10691 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10692 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10693 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10694 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10695 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10696 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10697 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10698 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10699 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10700 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10701 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10702 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10703 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10704 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10705 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10706 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10707 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10708 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10709 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10710 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10711 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10712 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10713 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10715 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10716 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10717 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10718 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10720 /* IPv4 Multicast Mode */
10721 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10722 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10726 bgp_route_finish (void)
10731 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10732 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10734 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10735 bgp_distance_table
[afi
][safi
] = NULL
;