1 /* BGP routing information
2 Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #include "sockunion.h"
35 #include "workqueue.h"
40 #include "bgpd/bgpd.h"
41 #include "bgpd/bgp_table.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_attr.h"
44 #include "bgpd/bgp_debug.h"
45 #include "bgpd/bgp_aspath.h"
46 #include "bgpd/bgp_regex.h"
47 #include "bgpd/bgp_community.h"
48 #include "bgpd/bgp_ecommunity.h"
49 #include "bgpd/bgp_clist.h"
50 #include "bgpd/bgp_packet.h"
51 #include "bgpd/bgp_filter.h"
52 #include "bgpd/bgp_fsm.h"
53 #include "bgpd/bgp_mplsvpn.h"
54 #include "bgpd/bgp_nexthop.h"
55 #include "bgpd/bgp_damp.h"
56 #include "bgpd/bgp_advertise.h"
57 #include "bgpd/bgp_zebra.h"
58 #include "bgpd/bgp_vty.h"
59 #include "bgpd/bgp_mpath.h"
60 #include "bgpd/bgp_nht.h"
61 #include "bgpd/bgp_updgrp.h"
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
69 /* Extern from bgp_dump.c */
70 extern const char *bgp_origin_str
[];
71 extern const char *bgp_origin_long_str
[];
74 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
75 struct prefix_rd
*prd
)
78 struct bgp_node
*prn
= NULL
;
84 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
86 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
88 if (prn
->info
== NULL
)
89 prn
->info
= bgp_table_init (afi
, safi
);
91 bgp_unlock_node (prn
);
95 rn
= bgp_node_get (table
, p
);
97 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
103 /* Allocate bgp_info_extra */
104 static struct bgp_info_extra
*
105 bgp_info_extra_new (void)
107 struct bgp_info_extra
*new;
108 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
113 bgp_info_extra_free (struct bgp_info_extra
**extra
)
117 if ((*extra
)->damp_info
)
118 bgp_damp_info_free ((*extra
)->damp_info
, 0);
120 (*extra
)->damp_info
= NULL
;
122 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
128 /* Get bgp_info extra information for the given bgp_info, lazy allocated
131 struct bgp_info_extra
*
132 bgp_info_extra_get (struct bgp_info
*ri
)
135 ri
->extra
= bgp_info_extra_new();
139 /* Allocate new bgp info structure. */
143 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
146 /* Free bgp route information. */
148 bgp_info_free (struct bgp_info
*binfo
)
151 bgp_attr_unintern (&binfo
->attr
);
153 bgp_unlink_nexthop(binfo
);
154 bgp_info_extra_free (&binfo
->extra
);
155 bgp_info_mpath_free (&binfo
->mpath
);
157 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
159 XFREE (MTYPE_BGP_ROUTE
, binfo
);
163 bgp_info_lock (struct bgp_info
*binfo
)
170 bgp_info_unlock (struct bgp_info
*binfo
)
172 assert (binfo
&& binfo
->lock
> 0);
175 if (binfo
->lock
== 0)
178 zlog_debug ("%s: unlocked and freeing", __func__
);
179 zlog_backtrace (LOG_DEBUG
);
181 bgp_info_free (binfo
);
186 if (binfo
->lock
== 1)
188 zlog_debug ("%s: unlocked to 1", __func__
);
189 zlog_backtrace (LOG_DEBUG
);
197 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
199 struct bgp_info
*top
;
211 peer_lock (ri
->peer
); /* bgp_info peer reference */
214 /* Do the actual removal of info from RIB, for use by bgp_process
215 completion callback *only* */
217 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
220 ri
->next
->prev
= ri
->prev
;
222 ri
->prev
->next
= ri
->next
;
226 bgp_info_mpath_dequeue (ri
);
227 bgp_info_unlock (ri
);
228 bgp_unlock_node (rn
);
232 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
234 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
235 /* set of previous already took care of pcount */
236 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
239 /* undo the effects of a previous call to bgp_info_delete; typically
240 called when a route is deleted and then quickly re-added before the
241 deletion has been processed */
243 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
245 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
246 /* unset of previous already took care of pcount */
247 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
250 /* Adjust pcount as required */
252 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
254 struct bgp_table
*table
;
256 assert (rn
&& bgp_node_table (rn
));
257 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
259 table
= bgp_node_table (rn
);
261 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
264 if (!BGP_INFO_COUNTABLE (ri
)
265 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
268 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
270 /* slight hack, but more robust against errors. */
271 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
272 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
275 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
276 __func__
, ri
->peer
->host
);
277 zlog_backtrace (LOG_WARNING
);
278 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
281 else if (BGP_INFO_COUNTABLE (ri
)
282 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
284 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
285 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
290 /* Set/unset bgp_info flags, adjusting any other state as needed.
291 * This is here primarily to keep prefix-count in check.
294 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
296 SET_FLAG (ri
->flags
, flag
);
298 /* early bath if we know it's not a flag that changes countability state */
299 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
302 bgp_pcount_adjust (rn
, ri
);
306 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
308 UNSET_FLAG (ri
->flags
, flag
);
310 /* early bath if we know it's not a flag that changes countability state */
311 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
314 bgp_pcount_adjust (rn
, ri
);
317 /* Get MED value. If MED value is missing and "bgp bestpath
318 missing-as-worst" is specified, treat it as the worst value. */
320 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
322 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
326 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
334 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
336 if (ri
->addpath_rx_id
)
337 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
339 sprintf(buf
, "path %s", ri
->peer
->host
);
342 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
344 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
345 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
348 struct attr
*newattr
, *existattr
;
349 struct attr_extra
*newattre
, *existattre
;
350 bgp_peer_sort_t new_sort
;
351 bgp_peer_sort_t exist_sort
;
353 u_int32_t exist_pref
;
356 u_int32_t new_weight
;
357 u_int32_t exist_weight
;
358 uint32_t newm
, existm
;
359 struct in_addr new_id
;
360 struct in_addr exist_id
;
363 int internal_as_route
;
366 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
367 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
375 zlog_debug("%s: new is NULL", pfx_buf
);
380 bgp_info_path_with_addpath_rx_str (new, new_buf
);
385 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
391 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
392 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
393 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
397 existattr
= exist
->attr
;
398 newattre
= newattr
->extra
;
399 existattre
= existattr
->extra
;
401 /* 1. Weight check. */
402 new_weight
= exist_weight
= 0;
405 new_weight
= newattre
->weight
;
407 exist_weight
= existattre
->weight
;
409 if (new_weight
> exist_weight
)
412 zlog_debug("%s: %s wins over %s due to weight %d > %d",
413 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
417 if (new_weight
< exist_weight
)
420 zlog_debug("%s: %s loses to %s due to weight %d < %d",
421 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
425 /* 2. Local preference check. */
426 new_pref
= exist_pref
= bgp
->default_local_pref
;
428 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
429 new_pref
= newattr
->local_pref
;
430 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
431 exist_pref
= existattr
->local_pref
;
433 if (new_pref
> exist_pref
)
436 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
437 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
441 if (new_pref
< exist_pref
)
444 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
445 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
449 /* 3. Local route check. We prefer:
451 * - BGP_ROUTE_AGGREGATE
452 * - BGP_ROUTE_REDISTRIBUTE
454 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
457 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
458 pfx_buf
, new_buf
, exist_buf
);
462 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
465 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
466 pfx_buf
, new_buf
, exist_buf
);
470 /* 4. AS path length check. */
471 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
473 int exist_hops
= aspath_count_hops (existattr
->aspath
);
474 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
476 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
480 aspath_hops
= aspath_count_hops (newattr
->aspath
);
481 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
483 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
486 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
487 pfx_buf
, new_buf
, exist_buf
,
488 aspath_hops
, (exist_hops
+ exist_confeds
));
492 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
495 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
496 pfx_buf
, new_buf
, exist_buf
,
497 aspath_hops
, (exist_hops
+ exist_confeds
));
503 int newhops
= aspath_count_hops (newattr
->aspath
);
505 if (newhops
< exist_hops
)
508 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
509 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
513 if (newhops
> exist_hops
)
516 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
517 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
523 /* 5. Origin check. */
524 if (newattr
->origin
< existattr
->origin
)
527 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
528 pfx_buf
, new_buf
, exist_buf
,
529 bgp_origin_long_str
[newattr
->origin
],
530 bgp_origin_long_str
[existattr
->origin
]);
534 if (newattr
->origin
> existattr
->origin
)
537 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
538 pfx_buf
, new_buf
, exist_buf
,
539 bgp_origin_long_str
[newattr
->origin
],
540 bgp_origin_long_str
[existattr
->origin
]);
545 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
546 && aspath_count_hops (existattr
->aspath
) == 0);
547 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
548 && aspath_count_confeds (existattr
->aspath
) > 0
549 && aspath_count_hops (newattr
->aspath
) == 0
550 && aspath_count_hops (existattr
->aspath
) == 0);
552 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
553 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
555 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
556 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
557 || internal_as_route
)
559 new_med
= bgp_med_value (new->attr
, bgp
);
560 exist_med
= bgp_med_value (exist
->attr
, bgp
);
562 if (new_med
< exist_med
)
565 zlog_debug("%s: %s wins over %s due to MED %d < %d",
566 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
570 if (new_med
> exist_med
)
573 zlog_debug("%s: %s loses to %s due to MED %d > %d",
574 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
579 /* 7. Peer type check. */
580 new_sort
= new->peer
->sort
;
581 exist_sort
= exist
->peer
->sort
;
583 if (new_sort
== BGP_PEER_EBGP
584 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
587 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
588 pfx_buf
, new_buf
, exist_buf
);
592 if (exist_sort
== BGP_PEER_EBGP
593 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
596 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
597 pfx_buf
, new_buf
, exist_buf
);
601 /* 8. IGP metric check. */
605 newm
= new->extra
->igpmetric
;
607 existm
= exist
->extra
->igpmetric
;
612 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
613 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
620 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
621 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
625 /* 9. Same IGP metric. Compare the cluster list length as
626 representative of IGP hops metric. Rewrite the metric value
627 pair (newm, existm) with the cluster list length. Prefer the
628 path with smaller cluster list length. */
631 if (peer_sort (new->peer
) == BGP_PEER_IBGP
632 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
633 && (mpath_cfg
== NULL
||
634 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
635 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
637 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
638 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
643 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
644 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
651 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
652 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
658 /* 10. confed-external vs. confed-internal */
659 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
661 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
664 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
665 pfx_buf
, new_buf
, exist_buf
);
669 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
672 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
673 pfx_buf
, new_buf
, exist_buf
);
678 /* 11. Maximum path check. */
681 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
685 * For the two paths, all comparison steps till IGP metric
686 * have succeeded - including AS_PATH hop count. Since 'bgp
687 * bestpath as-path multipath-relax' knob is on, we don't need
688 * an exact match of AS_PATH. Thus, mark the paths are equal.
689 * That will trigger both these paths to get into the multipath
695 zlog_debug("%s: %s and %s are equal via multipath-relax",
696 pfx_buf
, new_buf
, exist_buf
);
698 else if (new->peer
->sort
== BGP_PEER_IBGP
)
700 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
705 zlog_debug("%s: %s and %s are equal via matching aspaths",
706 pfx_buf
, new_buf
, exist_buf
);
709 else if (new->peer
->as
== exist
->peer
->as
)
714 zlog_debug("%s: %s and %s are equal via same remote-as",
715 pfx_buf
, new_buf
, exist_buf
);
721 * TODO: If unequal cost ibgp multipath is enabled we can
722 * mark the paths as equal here instead of returning
727 zlog_debug("%s: %s wins over %s after IGP metric comparison",
728 pfx_buf
, new_buf
, exist_buf
);
730 zlog_debug("%s: %s loses to %s after IGP metric comparison",
731 pfx_buf
, new_buf
, exist_buf
);
736 /* 12. If both paths are external, prefer the path that was received
737 first (the oldest one). This step minimizes route-flap, since a
738 newer path won't displace an older one, even if it was the
739 preferred route based on the additional decision criteria below. */
740 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
741 && new_sort
== BGP_PEER_EBGP
742 && exist_sort
== BGP_PEER_EBGP
)
744 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
747 zlog_debug("%s: %s wins over %s due to oldest external",
748 pfx_buf
, new_buf
, exist_buf
);
752 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
755 zlog_debug("%s: %s loses to %s due to oldest external",
756 pfx_buf
, new_buf
, exist_buf
);
761 /* 13. Router-ID comparision. */
762 /* If one of the paths is "stale", the corresponding peer router-id will
763 * be 0 and would always win over the other path. If originator id is
764 * used for the comparision, it will decide which path is better.
766 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
767 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
769 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
770 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
771 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
773 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
775 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
778 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
779 pfx_buf
, new_buf
, exist_buf
);
783 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
786 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
787 pfx_buf
, new_buf
, exist_buf
);
791 /* 14. Cluster length comparision. */
792 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
793 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
795 if (new_cluster
< exist_cluster
)
798 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
799 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
803 if (new_cluster
> exist_cluster
)
806 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
807 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
811 /* 15. Neighbor address comparision. */
812 /* Do this only if neither path is "stale" as stale paths do not have
813 * valid peer information (as the connection may or may not be up).
815 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
818 zlog_debug("%s: %s wins over %s due to latter path being STALE",
819 pfx_buf
, new_buf
, exist_buf
);
823 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
826 zlog_debug("%s: %s loses to %s due to former path being STALE",
827 pfx_buf
, new_buf
, exist_buf
);
831 /* locally configured routes to advertise do not have su_remote */
832 if (new->peer
->su_remote
== NULL
)
834 if (exist
->peer
->su_remote
== NULL
)
837 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
842 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
843 pfx_buf
, new_buf
, exist_buf
);
850 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
851 pfx_buf
, new_buf
, exist_buf
);
856 zlog_debug("%s: %s wins over %s due to nothing left to compare",
857 pfx_buf
, new_buf
, exist_buf
);
862 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
863 * is preferred, or 0 if they are the same (usually will only occur if
864 * multipath is enabled
865 * This version is compatible with */
867 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
868 afi_t afi
, safi_t safi
)
872 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
886 static enum filter_type
887 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
888 afi_t afi
, safi_t safi
)
890 struct bgp_filter
*filter
;
892 filter
= &peer
->filter
[afi
][safi
];
894 #define FILTER_EXIST_WARN(F,f,filter) \
895 if (BGP_DEBUG (update, UPDATE_IN) \
896 && !(F ## _IN (filter))) \
897 zlog_warn ("%s: Could not find configured input %s-list %s!", \
898 peer->host, #f, F ## _IN_NAME(filter));
900 if (DISTRIBUTE_IN_NAME (filter
)) {
901 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
903 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
907 if (PREFIX_LIST_IN_NAME (filter
)) {
908 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
910 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
914 if (FILTER_LIST_IN_NAME (filter
)) {
915 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
917 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
921 return FILTER_PERMIT
;
922 #undef FILTER_EXIST_WARN
925 static enum filter_type
926 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
927 afi_t afi
, safi_t safi
)
929 struct bgp_filter
*filter
;
931 filter
= &peer
->filter
[afi
][safi
];
933 #define FILTER_EXIST_WARN(F,f,filter) \
934 if (BGP_DEBUG (update, UPDATE_OUT) \
935 && !(F ## _OUT (filter))) \
936 zlog_warn ("%s: Could not find configured output %s-list %s!", \
937 peer->host, #f, F ## _OUT_NAME(filter));
939 if (DISTRIBUTE_OUT_NAME (filter
)) {
940 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
942 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
946 if (PREFIX_LIST_OUT_NAME (filter
)) {
947 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
949 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
953 if (FILTER_LIST_OUT_NAME (filter
)) {
954 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
956 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
960 return FILTER_PERMIT
;
961 #undef FILTER_EXIST_WARN
964 /* If community attribute includes no_export then return 1. */
966 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
970 /* NO_ADVERTISE check. */
971 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
974 /* NO_EXPORT check. */
975 if (peer
->sort
== BGP_PEER_EBGP
&&
976 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
979 /* NO_EXPORT_SUBCONFED check. */
980 if (peer
->sort
== BGP_PEER_EBGP
981 || peer
->sort
== BGP_PEER_CONFED
)
982 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
988 /* Route reflection loop check. */
990 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
992 struct in_addr cluster_id
;
994 if (attr
->extra
&& attr
->extra
->cluster
)
996 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
997 cluster_id
= peer
->bgp
->cluster_id
;
999 cluster_id
= peer
->bgp
->router_id
;
1001 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1008 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1009 afi_t afi
, safi_t safi
, const char *rmap_name
)
1011 struct bgp_filter
*filter
;
1012 struct bgp_info info
;
1013 route_map_result_t ret
;
1014 struct route_map
*rmap
= NULL
;
1016 filter
= &peer
->filter
[afi
][safi
];
1018 /* Apply default weight value. */
1019 if (peer
->weight
[afi
][safi
])
1020 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1024 rmap
= route_map_lookup_by_name(rmap_name
);
1031 if (ROUTE_MAP_IN_NAME(filter
))
1033 rmap
= ROUTE_MAP_IN (filter
);
1040 /* Route map apply. */
1043 /* Duplicate current value to new strucutre for modification. */
1047 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1049 /* Apply BGP route map to the attribute. */
1050 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1052 peer
->rmap_type
= 0;
1054 if (ret
== RMAP_DENYMATCH
)
1056 /* Free newly generated AS path and community by route-map. */
1057 bgp_attr_flush (attr
);
1065 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1066 afi_t afi
, safi_t safi
, const char *rmap_name
)
1068 struct bgp_filter
*filter
;
1069 struct bgp_info info
;
1070 route_map_result_t ret
;
1071 struct route_map
*rmap
= NULL
;
1073 filter
= &peer
->filter
[afi
][safi
];
1075 /* Apply default weight value. */
1076 if (peer
->weight
[afi
][safi
])
1077 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1081 rmap
= route_map_lookup_by_name(rmap_name
);
1088 if (ROUTE_MAP_OUT_NAME(filter
))
1090 rmap
= ROUTE_MAP_OUT (filter
);
1097 /* Route map apply. */
1100 /* Duplicate current value to new strucutre for modification. */
1104 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1106 /* Apply BGP route map to the attribute. */
1107 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1109 peer
->rmap_type
= 0;
1111 if (ret
== RMAP_DENYMATCH
)
1112 /* caller has multiple error paths with bgp_attr_flush() */
1118 /* If this is an EBGP peer with remove-private-AS */
1120 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1121 struct peer
*peer
, struct attr
*attr
)
1123 if (peer
->sort
== BGP_PEER_EBGP
&&
1124 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1125 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1126 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1127 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1129 // Take action on the entire aspath
1130 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1131 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1133 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1134 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1136 // The entire aspath consists of private ASNs so create an empty aspath
1137 else if (aspath_private_as_check (attr
->aspath
))
1138 attr
->aspath
= aspath_empty_get ();
1140 // There are some public and some private ASNs, remove the private ASNs
1142 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1145 // 'all' was not specified so the entire aspath must be private ASNs
1146 // for us to do anything
1147 else if (aspath_private_as_check (attr
->aspath
))
1149 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1150 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1152 attr
->aspath
= aspath_empty_get ();
1157 /* If this is an EBGP peer with as-override */
1159 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1160 struct peer
*peer
, struct attr
*attr
)
1162 if (peer
->sort
== BGP_PEER_EBGP
&&
1163 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1165 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1166 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1171 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1173 if (family
== AF_INET
)
1174 attr
->nexthop
.s_addr
= 0;
1175 if (family
== AF_INET6
)
1176 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1180 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1181 struct prefix
*p
, struct attr
*attr
)
1183 struct bgp_filter
*filter
;
1186 struct peer
*onlypeer
;
1188 struct attr
*riattr
;
1189 struct peer_af
*paf
;
1190 char buf
[SU_ADDRSTRLEN
];
1196 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1198 if (DISABLE_BGP_ANNOUNCE
)
1201 afi
= SUBGRP_AFI(subgrp
);
1202 safi
= SUBGRP_SAFI(subgrp
);
1203 peer
= SUBGRP_PEER(subgrp
);
1205 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1206 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1209 filter
= &peer
->filter
[afi
][safi
];
1210 bgp
= SUBGRP_INST(subgrp
);
1211 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1214 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1215 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1216 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1219 * direct and direct_ext type routes originate internally even
1220 * though they can have peer pointers that reference other systems
1223 prefix2str(p
, buf
, BUFSIZ
);
1224 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1229 /* With addpath we may be asked to TX all kinds of paths so make sure
1231 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1232 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1233 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1238 /* If this is not the bestpath then check to see if there is an enabled addpath
1239 * feature that requires us to advertise it */
1240 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1242 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1248 /* Aggregate-address suppress check. */
1249 if (ri
->extra
&& ri
->extra
->suppress
)
1250 if (! UNSUPPRESS_MAP_NAME (filter
))
1255 /* Do not send back route to sender. */
1256 if (onlypeer
&& from
== onlypeer
)
1261 /* Do not send the default route in the BGP table if the neighbor is
1262 * configured for default-originate */
1263 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1265 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1267 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1271 /* Transparency check. */
1272 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1273 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1278 /* If community is not disabled check the no-export and local. */
1279 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1281 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1282 zlog_debug ("subgrpannouncecheck: community filter check fail");
1286 /* If the attribute has originator-id and it is same as remote
1289 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1290 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1292 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1293 zlog_debug ("%s [Update:SEND] %s/%d originator-id is same as "
1296 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1301 /* ORF prefix-list filter check */
1302 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1303 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1304 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1305 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1306 if (peer
->orf_plist
[afi
][safi
])
1308 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1310 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1311 zlog_debug ("%s [Update:SEND] %s/%d is filtered via ORF",
1313 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1319 /* Output filter check. */
1320 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1322 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1323 zlog_debug ("%s [Update:SEND] %s/%d is filtered",
1325 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1330 #ifdef BGP_SEND_ASPATH_CHECK
1331 /* AS path loop check. */
1332 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1334 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1335 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1336 "that is part of AS path.",
1337 onlypeer
->host
, onlypeer
->as
);
1340 #endif /* BGP_SEND_ASPATH_CHECK */
1342 /* If we're a CONFED we need to loop check the CONFED ID too */
1343 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1345 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1347 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1348 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1356 /* Route-Reflect check. */
1357 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1362 /* IBGP reflection check. */
1363 if (reflect
&& !samepeer_safe
)
1365 /* A route from a Client peer. */
1366 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1368 /* Reflect to all the Non-Client peers and also to the
1369 Client peers other than the originator. Originator check
1370 is already done. So there is noting to do. */
1371 /* no bgp client-to-client reflection check. */
1372 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1373 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1374 PEER_FLAG_REFLECTOR_CLIENT
))
1379 /* A route from a Non-client peer. Reflect to all other
1381 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1382 PEER_FLAG_REFLECTOR_CLIENT
))
1387 /* For modify attribute, copy it to temporary structure. */
1388 bgp_attr_dup (attr
, riattr
);
1390 /* If local-preference is not set. */
1391 if ((peer
->sort
== BGP_PEER_IBGP
1392 || peer
->sort
== BGP_PEER_CONFED
)
1393 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1395 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1396 attr
->local_pref
= bgp
->default_local_pref
;
1399 /* If originator-id is not set and the route is to be reflected,
1400 set the originator id */
1401 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1403 attr
->extra
= bgp_attr_extra_get(attr
);
1404 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1405 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1408 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1409 if (peer
->sort
== BGP_PEER_EBGP
1410 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1412 if (from
!= bgp
->peer_self
&& ! transparent
1413 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1414 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1417 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1418 * in announce check, only certain flags and length (or number of nexthops
1419 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1420 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1421 * Typically, the source nexthop in the attribute is preserved but in the
1422 * scenarios where we know it will always be overwritten, we reset the
1423 * nexthop to "0" in an attempt to achieve better Update packing. An
1424 * example of this is when a prefix from each of 2 IBGP peers needs to be
1425 * announced to an EBGP peer (and they have the same attributes barring
1429 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1431 #define NEXTHOP_IS_V6 (\
1432 (safi != SAFI_ENCAP && \
1433 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1434 (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
1436 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1437 * the peer (group) is configured to receive link-local nexthop unchanged
1438 * and it is available in the prefix OR we're not reflecting the route and
1439 * the peer (group) to whom we're going to announce is on a shared network
1440 * and this is either a self-originated route or the peer is EBGP.
1444 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1445 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1446 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1447 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1448 (!reflect
&& peer
->shared_network
&&
1449 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1451 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1454 /* Clear off link-local nexthop in source, whenever it is not needed to
1455 * ensure more prefixes share the same attribute for announcement.
1457 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1458 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1459 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1462 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1463 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1465 /* Route map & unsuppress-map apply. */
1466 if (ROUTE_MAP_OUT_NAME (filter
)
1467 || (ri
->extra
&& ri
->extra
->suppress
) )
1469 struct bgp_info info
;
1470 struct attr dummy_attr
;
1471 struct attr_extra dummy_extra
;
1473 dummy_attr
.extra
= &dummy_extra
;
1477 /* don't confuse inbound and outbound setting */
1478 RESET_FLAG(attr
->rmap_change_flags
);
1481 * The route reflector is not allowed to modify the attributes
1482 * of the reflected IBGP routes unless explicitly allowed.
1484 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1485 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1487 bgp_attr_dup (&dummy_attr
, attr
);
1488 info
.attr
= &dummy_attr
;
1491 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1493 if (ri
->extra
&& ri
->extra
->suppress
)
1494 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1496 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1498 peer
->rmap_type
= 0;
1500 if (ret
== RMAP_DENYMATCH
)
1502 bgp_attr_flush (attr
);
1507 /* After route-map has been applied, we check to see if the nexthop to
1508 * be carried in the attribute (that is used for the announcement) can
1509 * be cleared off or not. We do this in all cases where we would be
1510 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1511 * the global nexthop here; the link-local nexthop would have been cleared
1512 * already, and if not, it is required by the update formation code.
1513 * Also see earlier comments in this function.
1516 * If route-map has performed some operation on the nexthop or the peer
1517 * configuration says to pass it unchanged, we cannot reset the nexthop
1518 * here, so only attempt to do it if these aren't true. Note that the
1519 * route-map handler itself might have cleared the nexthop, if for example,
1520 * it is configured as 'peer-address'.
1522 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1523 riattr
->rmap_change_flags
) &&
1525 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1527 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1528 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1529 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1532 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1533 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1534 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ?
1535 AF_INET6
: p
->family
), attr
);
1537 else if (peer
->sort
== BGP_PEER_EBGP
)
1539 /* Can also reset the nexthop if announcing to EBGP, but only if
1540 * no peer in the subgroup is on a shared subnet.
1541 * Note: 3rd party nexthop currently implemented for IPv4 only.
1543 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1545 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1549 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ? AF_INET6
: p
->family
), attr
);
1551 /* If IPv6/MP and nexthop does not have any override and happens to
1552 * be a link-local address, reset it so that we don't pass along the
1553 * source's link-local IPv6 address to recipients who may not be on
1554 * the same interface.
1556 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
))
1558 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1559 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1566 struct bgp_info_pair
1568 struct bgp_info
*old
;
1569 struct bgp_info
*new;
1573 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1574 struct bgp_maxpaths_cfg
*mpath_cfg
,
1575 struct bgp_info_pair
*result
)
1577 struct bgp_info
*new_select
;
1578 struct bgp_info
*old_select
;
1579 struct bgp_info
*ri
;
1580 struct bgp_info
*ri1
;
1581 struct bgp_info
*ri2
;
1582 struct bgp_info
*nextri
= NULL
;
1583 int paths_eq
, do_mpath
, debug
;
1584 struct list mp_list
;
1585 char pfx_buf
[PREFIX2STR_BUFFER
];
1586 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1588 bgp_mp_list_init (&mp_list
);
1589 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1591 debug
= bgp_debug_bestpath(&rn
->p
);
1594 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1596 /* bgp deterministic-med */
1598 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1601 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1602 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1603 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1605 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1607 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1609 if (BGP_INFO_HOLDDOWN (ri1
))
1611 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1612 if (ri1
->peer
->status
!= Established
)
1618 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1620 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1622 if (BGP_INFO_HOLDDOWN (ri2
))
1625 ri2
->peer
!= bgp
->peer_self
&&
1626 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1627 if (ri2
->peer
->status
!= Established
)
1630 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1631 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1634 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1635 mpath_cfg
, debug
, pfx_buf
))
1637 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1641 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1645 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1646 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1650 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1651 zlog_debug("%s: %s is the bestpath from AS %d",
1652 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1657 /* Check old selected route and new selected route. */
1660 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1662 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1665 if (BGP_INFO_HOLDDOWN (ri
))
1667 /* reap REMOVED routes, if needs be
1668 * selected route must stay for a while longer though
1670 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1671 && (ri
!= old_select
))
1672 bgp_info_reap (rn
, ri
);
1678 ri
->peer
!= bgp
->peer_self
&&
1679 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1680 if (ri
->peer
->status
!= Established
)
1683 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1684 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1686 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1690 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1692 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1698 /* Now that we know which path is the bestpath see if any of the other paths
1699 * qualify as multipaths
1704 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1706 sprintf (path_buf
, "NONE");
1707 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1709 old_select
? old_select
->peer
->host
: "NONE");
1712 if (do_mpath
&& new_select
)
1714 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1718 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1720 if (ri
== new_select
)
1723 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1725 bgp_mp_list_add (&mp_list
, ri
);
1729 if (BGP_INFO_HOLDDOWN (ri
))
1733 ri
->peer
!= bgp
->peer_self
&&
1734 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1735 if (ri
->peer
->status
!= Established
)
1738 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1741 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1746 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1751 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1753 bgp_mp_list_add (&mp_list
, ri
);
1758 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1759 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1760 bgp_mp_list_clear (&mp_list
);
1762 result
->old
= old_select
;
1763 result
->new = new_select
;
1769 * A new route/change in bestpath of an existing route. Evaluate the path
1770 * for advertisement to the subgroup.
1773 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1774 struct bgp_info
*selected
,
1775 struct bgp_node
*rn
,
1776 u_int32_t addpath_tx_id
)
1779 struct peer
*onlypeer
;
1781 struct attr_extra extra
;
1786 afi
= SUBGRP_AFI(subgrp
);
1787 safi
= SUBGRP_SAFI(subgrp
);
1788 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1789 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1791 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1792 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1793 PEER_STATUS_ORF_WAIT_REFRESH
))
1796 memset(&extra
, 0, sizeof(struct attr_extra
));
1797 /* It's initialized in bgp_announce_check() */
1798 attr
.extra
= &extra
;
1800 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1803 if (subgroup_announce_check(selected
, subgrp
, p
, &attr
))
1804 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1806 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1809 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1812 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1819 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1820 * This is called at the end of route processing.
1823 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1825 struct bgp_info
*ri
;
1827 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1829 if (BGP_INFO_HOLDDOWN (ri
))
1831 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1832 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1837 * Has the route changed from the RIB's perspective? This is invoked only
1838 * if the route selection returns the same best route as earlier - to
1839 * determine if we need to update zebra or not.
1842 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1844 struct bgp_info
*mpinfo
;
1846 /* If this is multipath, check all selected paths for any nexthop change or
1847 * attribute change. Some attribute changes (e.g., community) aren't of
1848 * relevance to the RIB, but we'll update zebra to ensure we handle the
1849 * case of BGP nexthop change. This is the behavior when the best path has
1850 * an attribute change anyway.
1852 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1853 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1856 /* If this is multipath, check all selected paths for any nexthop change */
1857 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1858 mpinfo
= bgp_info_mpath_next (mpinfo
))
1860 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1861 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1865 /* Nothing has changed from the RIB's perspective. */
1869 struct bgp_process_queue
1872 struct bgp_node
*rn
;
1877 static wq_item_status
1878 bgp_process_main (struct work_queue
*wq
, void *data
)
1880 struct bgp_process_queue
*pq
= data
;
1881 struct bgp
*bgp
= pq
->bgp
;
1882 struct bgp_node
*rn
= pq
->rn
;
1883 afi_t afi
= pq
->afi
;
1884 safi_t safi
= pq
->safi
;
1885 struct prefix
*p
= &rn
->p
;
1886 struct bgp_info
*new_select
;
1887 struct bgp_info
*old_select
;
1888 struct bgp_info_pair old_and_new
;
1890 /* Is it end of initial update? (after startup) */
1893 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1894 sizeof(bgp
->update_delay_zebra_resume_time
));
1896 bgp
->main_zebra_update_hold
= 0;
1897 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1898 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1900 bgp_zebra_announce_table(bgp
, afi
, safi
);
1902 bgp
->main_peers_update_hold
= 0;
1904 bgp_start_routeadv(bgp
);
1908 /* Best path selection. */
1909 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1910 old_select
= old_and_new
.old
;
1911 new_select
= old_and_new
.new;
1913 /* Nothing to do. */
1914 if (old_select
&& old_select
== new_select
&&
1915 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1916 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1917 !bgp
->addpath_tx_used
[afi
][safi
])
1919 if (bgp_zebra_has_route_changed (rn
, old_select
))
1922 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1923 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1925 bgp_zebra_announce (p
, old_select
, bgp
, afi
, safi
);
1927 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1928 bgp_zebra_clear_route_change_flags (rn
);
1929 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
1933 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
1934 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1936 /* bestpath has changed; bump version */
1937 if (old_select
|| new_select
)
1939 bgp_bump_version(rn
);
1941 if (!bgp
->t_rmap_def_originate_eval
)
1944 THREAD_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
1945 update_group_refresh_default_originate_route_map
,
1946 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
1951 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
1954 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
1955 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
1956 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1960 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
1961 if (old_select
!= new_select
) {
1963 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
1964 vnc_import_bgp_del_route(bgp
, p
, old_select
);
1967 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
1968 vnc_import_bgp_add_route(bgp
, p
, new_select
);
1974 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
1977 if ((safi
== SAFI_UNICAST
|| safi
== SAFI_MULTICAST
) &&
1978 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
1979 !bgp_option_check (BGP_OPT_NO_FIB
))
1982 && new_select
->type
== ZEBRA_ROUTE_BGP
1983 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
1984 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1985 bgp_zebra_announce (p
, new_select
, bgp
, afi
, safi
);
1988 /* Withdraw the route from the kernel. */
1990 && old_select
->type
== ZEBRA_ROUTE_BGP
1991 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
1992 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1993 bgp_zebra_withdraw (p
, old_select
, safi
);
1997 /* Clear any route change flags. */
1998 bgp_zebra_clear_route_change_flags (rn
);
2000 /* Reap old select bgp_info, if it has been removed */
2001 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2002 bgp_info_reap (rn
, old_select
);
2004 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2009 bgp_processq_del (struct work_queue
*wq
, void *data
)
2011 struct bgp_process_queue
*pq
= data
;
2012 struct bgp_table
*table
;
2014 bgp_unlock (pq
->bgp
);
2017 table
= bgp_node_table (pq
->rn
);
2018 bgp_unlock_node (pq
->rn
);
2019 bgp_table_unlock (table
);
2021 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2025 bgp_process_queue_init (void)
2027 if (!bm
->process_main_queue
)
2029 bm
->process_main_queue
2030 = work_queue_new (bm
->master
, "process_main_queue");
2032 if ( !bm
->process_main_queue
)
2034 zlog_err ("%s: Failed to allocate work queue", __func__
);
2039 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2040 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2041 bm
->process_main_queue
->spec
.max_retries
= 0;
2042 bm
->process_main_queue
->spec
.hold
= 50;
2043 /* Use a higher yield value of 50ms for main queue processing */
2044 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2048 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2050 struct bgp_process_queue
*pqnode
;
2052 /* already scheduled for processing? */
2053 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2056 if (bm
->process_main_queue
== NULL
)
2057 bgp_process_queue_init ();
2059 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2060 sizeof (struct bgp_process_queue
));
2064 /* all unlocked in bgp_processq_del */
2065 bgp_table_lock (bgp_node_table (rn
));
2066 pqnode
->rn
= bgp_lock_node (rn
);
2070 pqnode
->safi
= safi
;
2071 work_queue_add (bm
->process_main_queue
, pqnode
);
2072 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2077 bgp_add_eoiu_mark (struct bgp
*bgp
)
2079 struct bgp_process_queue
*pqnode
;
2081 if (bm
->process_main_queue
== NULL
)
2082 bgp_process_queue_init ();
2084 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2085 sizeof (struct bgp_process_queue
));
2092 work_queue_add (bm
->process_main_queue
, pqnode
);
2096 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2100 peer
= THREAD_ARG (thread
);
2101 peer
->t_pmax_restart
= NULL
;
2103 if (bgp_debug_neighbor_events(peer
))
2104 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2107 peer_clear (peer
, NULL
);
2113 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2114 safi_t safi
, int always
)
2116 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2119 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2121 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2125 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2126 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2127 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2128 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2130 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2136 if (safi
== SAFI_MPLS_VPN
)
2137 safi
= SAFI_MPLS_LABELED_VPN
;
2139 ndata
[0] = (afi
>> 8);
2142 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2143 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2144 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2145 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2147 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2148 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2149 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2152 /* Dynamic peers will just close their connection. */
2153 if (peer_dynamic_neighbor (peer
))
2156 /* restart timer start */
2157 if (peer
->pmax_restart
[afi
][safi
])
2159 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2161 if (bgp_debug_neighbor_events(peer
))
2162 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2163 peer
->host
, peer
->v_pmax_restart
);
2165 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2166 peer
->v_pmax_restart
);
2172 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2174 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2176 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2180 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2181 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2182 peer
->pmax
[afi
][safi
]);
2183 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2186 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2190 /* Unconditionally remove the route from the RIB, without taking
2191 * damping into consideration (eg, because the session went down)
2194 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2195 afi_t afi
, safi_t safi
)
2197 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2199 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2200 bgp_info_delete (rn
, ri
); /* keep historical info */
2202 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2206 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2207 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2209 int status
= BGP_DAMP_NONE
;
2211 /* apply dampening, if result is suppressed, we'll be retaining
2212 * the bgp_info in the RIB for historical reference.
2214 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2215 && peer
->sort
== BGP_PEER_EBGP
)
2216 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2217 == BGP_DAMP_SUPPRESSED
)
2219 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2224 if (safi
== SAFI_MPLS_VPN
) {
2225 struct bgp_node
*prn
= NULL
;
2226 struct bgp_table
*table
= NULL
;
2228 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2230 table
= (struct bgp_table
*)(prn
->info
);
2232 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2239 bgp_unlock_node(prn
);
2241 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2242 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2244 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2245 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2249 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2252 static struct bgp_info
*
2253 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2254 struct bgp_node
*rn
)
2256 struct bgp_info
*new;
2258 /* Make new BGP info. */
2259 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2261 new->instance
= instance
;
2262 new->sub_type
= sub_type
;
2265 new->uptime
= bgp_clock ();
2267 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2272 bgp_info_addpath_rx_str(u_int32_t addpath_id
, char *buf
)
2275 sprintf(buf
, " with addpath ID %d", addpath_id
);
2279 /* Check if received nexthop is valid or not. */
2281 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2283 struct attr_extra
*attre
= attr
->extra
;
2286 /* Only validated for unicast and multicast currently. */
2287 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2290 /* If NEXT_HOP is present, validate it. */
2291 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2293 if (attr
->nexthop
.s_addr
== 0 ||
2294 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2295 bgp_nexthop_self (bgp
, attr
))
2299 /* If MP_NEXTHOP is present, validate it. */
2300 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2301 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2302 * it is not an IPv6 link-local address.
2304 if (attre
&& attre
->mp_nexthop_len
)
2306 switch (attre
->mp_nexthop_len
)
2308 case BGP_ATTR_NHLEN_IPV4
:
2309 case BGP_ATTR_NHLEN_VPNV4
:
2310 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2311 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2314 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2315 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2316 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2317 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2318 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2331 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2332 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2333 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2337 int aspath_loop_count
= 0;
2338 struct bgp_node
*rn
;
2340 struct attr new_attr
;
2341 struct attr_extra new_extra
;
2342 struct attr
*attr_new
;
2343 struct bgp_info
*ri
;
2344 struct bgp_info
*new;
2346 char buf
[SU_ADDRSTRLEN
];
2349 int do_loop_check
= 1;
2351 int vnc_implicit_withdraw
= 0;
2354 memset (&new_attr
, 0, sizeof(struct attr
));
2355 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2358 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2360 /* When peer's soft reconfiguration enabled. Record input packet in
2362 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2363 && peer
!= bgp
->peer_self
)
2364 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2366 /* Check previously received route. */
2367 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2368 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2369 ri
->addpath_rx_id
== addpath_id
)
2372 /* AS path local-as loop check. */
2373 if (peer
->change_local_as
)
2375 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2376 aspath_loop_count
= 1;
2378 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2380 reason
= "as-path contains our own AS;";
2385 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2386 * as-path is our ASN then we do not need to call aspath_loop_check
2388 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2389 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2392 /* AS path loop check. */
2395 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2396 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2397 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2399 reason
= "as-path contains our own AS;";
2404 /* Route reflector originator ID check. */
2405 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2406 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2408 reason
= "originator is us;";
2412 /* Route reflector cluster ID check. */
2413 if (bgp_cluster_filter (peer
, attr
))
2415 reason
= "reflected from the same cluster;";
2419 /* Apply incoming filter. */
2420 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2426 new_attr
.extra
= &new_extra
;
2427 bgp_attr_dup (&new_attr
, attr
);
2429 /* Apply incoming route-map.
2430 * NB: new_attr may now contain newly allocated values from route-map "set"
2431 * commands, so we need bgp_attr_flush in the error paths, until we intern
2432 * the attr (which takes over the memory references) */
2433 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2435 reason
= "route-map;";
2436 bgp_attr_flush (&new_attr
);
2440 /* next hop check. */
2441 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2443 reason
= "martian or self next-hop;";
2444 bgp_attr_flush (&new_attr
);
2448 attr_new
= bgp_attr_intern (&new_attr
);
2450 /* If the update is implicit withdraw. */
2453 ri
->uptime
= bgp_clock ();
2455 /* Same attribute comes in. */
2456 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2457 && attrhash_cmp (ri
->attr
, attr_new
))
2459 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2460 && peer
->sort
== BGP_PEER_EBGP
2461 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2463 if (bgp_debug_update(peer
, p
, NULL
, 1))
2465 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2466 zlog_debug ("%s rcvd %s/%d%s",
2468 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2469 p
->prefixlen
, buf2
);
2472 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2474 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2475 bgp_process (bgp
, rn
, afi
, safi
);
2478 else /* Duplicate - odd */
2480 if (bgp_debug_update(peer
, p
, NULL
, 1))
2482 if (!peer
->rcvd_attr_printed
)
2484 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2485 peer
->rcvd_attr_printed
= 1;
2488 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2489 zlog_debug ("%s rcvd %s/%d%s...duplicate ignored",
2491 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2492 p
->prefixlen
, buf2
);
2495 /* graceful restart STALE flag unset. */
2496 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2498 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2499 bgp_process (bgp
, rn
, afi
, safi
);
2503 bgp_unlock_node (rn
);
2504 bgp_attr_unintern (&attr_new
);
2509 /* Withdraw/Announce before we fully processed the withdraw */
2510 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2512 if (bgp_debug_update(peer
, p
, NULL
, 1))
2514 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2515 zlog_debug ("%s rcvd %s/%d%s, flapped quicker than processing",
2517 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2518 p
->prefixlen
, buf2
);
2520 bgp_info_restore (rn
, ri
);
2523 /* Received Logging. */
2524 if (bgp_debug_update(peer
, p
, NULL
, 1))
2526 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2527 zlog_debug ("%s rcvd %s/%d%s",
2529 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2530 p
->prefixlen
, buf2
);
2533 /* graceful restart STALE flag unset. */
2534 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2535 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2537 /* The attribute is changed. */
2538 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2540 /* implicit withdraw, decrement aggregate and pcount here.
2541 * only if update is accepted, they'll increment below.
2543 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2545 /* Update bgp route dampening information. */
2546 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2547 && peer
->sort
== BGP_PEER_EBGP
)
2549 /* This is implicit withdraw so we should update dampening
2551 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2552 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2555 if (safi
== SAFI_MPLS_VPN
) {
2556 struct bgp_node
*prn
= NULL
;
2557 struct bgp_table
*table
= NULL
;
2559 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2561 table
= (struct bgp_table
*)(prn
->info
);
2563 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2570 bgp_unlock_node(prn
);
2572 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2573 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2575 * Implicit withdraw case.
2577 ++vnc_implicit_withdraw
;
2578 vnc_import_bgp_del_route(bgp
, p
, ri
);
2579 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2584 /* Update to new attribute. */
2585 bgp_attr_unintern (&ri
->attr
);
2586 ri
->attr
= attr_new
;
2588 /* Update MPLS tag. */
2589 if (safi
== SAFI_MPLS_VPN
)
2590 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2593 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2595 if (vnc_implicit_withdraw
)
2598 * Add back the route with its new attributes (e.g., nexthop).
2599 * The route is still selected, until the route selection
2600 * queued by bgp_process actually runs. We have to make this
2601 * update to the VNC side immediately to avoid racing against
2602 * configuration changes (e.g., route-map changes) which
2603 * trigger re-importation of the entire RIB.
2605 vnc_import_bgp_add_route(bgp
, p
, ri
);
2606 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2611 /* Update bgp route dampening information. */
2612 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2613 && peer
->sort
== BGP_PEER_EBGP
)
2615 /* Now we do normal update dampening. */
2616 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2617 if (ret
== BGP_DAMP_SUPPRESSED
)
2619 bgp_unlock_node (rn
);
2624 /* Nexthop reachability check. */
2625 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2627 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2628 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2629 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2634 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2635 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2638 if (BGP_DEBUG(nht
, NHT
))
2640 char buf1
[INET6_ADDRSTRLEN
];
2641 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2642 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2644 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2648 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2651 if (safi
== SAFI_MPLS_VPN
)
2653 struct bgp_node
*prn
= NULL
;
2654 struct bgp_table
*table
= NULL
;
2656 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2659 table
= (struct bgp_table
*)(prn
->info
);
2661 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2668 bgp_unlock_node(prn
);
2672 /* Process change. */
2673 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2675 bgp_process (bgp
, rn
, afi
, safi
);
2676 bgp_unlock_node (rn
);
2679 } // End of implicit withdraw
2681 /* Received Logging. */
2682 if (bgp_debug_update(peer
, p
, NULL
, 1))
2684 if (!peer
->rcvd_attr_printed
)
2686 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2687 peer
->rcvd_attr_printed
= 1;
2690 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2691 zlog_debug ("%s rcvd %s/%d%s",
2693 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2694 p
->prefixlen
, buf2
);
2697 /* Make new BGP info. */
2698 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2700 /* Update MPLS tag. */
2701 if (safi
== SAFI_MPLS_VPN
)
2702 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2704 /* Nexthop reachability check. */
2705 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2707 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2708 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2709 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2714 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2715 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2718 if (BGP_DEBUG(nht
, NHT
))
2720 char buf1
[INET6_ADDRSTRLEN
];
2721 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2722 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2724 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2728 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2731 new->addpath_rx_id
= addpath_id
;
2733 /* Increment prefix */
2734 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2736 /* Register new BGP information. */
2737 bgp_info_add (rn
, new);
2739 /* route_node_get lock */
2740 bgp_unlock_node (rn
);
2743 if (safi
== SAFI_MPLS_VPN
)
2745 struct bgp_node
*prn
= NULL
;
2746 struct bgp_table
*table
= NULL
;
2748 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2751 table
= (struct bgp_table
*)(prn
->info
);
2753 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2760 bgp_unlock_node(prn
);
2764 /* If maximum prefix count is configured and current prefix
2766 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2769 /* Process change. */
2770 bgp_process (bgp
, rn
, afi
, safi
);
2774 /* This BGP update is filtered. Log the reason then update BGP
2777 if (bgp_debug_update(peer
, p
, NULL
, 1))
2779 if (!peer
->rcvd_attr_printed
)
2781 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2782 peer
->rcvd_attr_printed
= 1;
2785 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2786 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- DENIED due to: %s",
2788 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2789 p
->prefixlen
, buf2
, reason
);
2793 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2795 bgp_unlock_node (rn
);
2801 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2802 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2803 struct prefix_rd
*prd
, u_char
*tag
)
2806 char buf
[SU_ADDRSTRLEN
];
2808 struct bgp_node
*rn
;
2809 struct bgp_info
*ri
;
2814 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2816 /* If peer is soft reconfiguration enabled. Record input packet for
2817 * further calculation.
2819 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2820 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2821 * the iteration over all RS clients.
2822 * Since we need to remove the entry from adj_in anyway, do that first and
2823 * if there was no entry, we don't need to do anything more.
2825 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2826 && peer
!= bgp
->peer_self
)
2827 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2829 if (bgp_debug_update (peer
, p
, NULL
, 1))
2830 zlog_debug ("%s withdrawing route %s/%d "
2831 "not in adj-in", peer
->host
,
2832 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2834 bgp_unlock_node (rn
);
2838 /* Lookup withdrawn route. */
2839 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2840 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2841 ri
->addpath_rx_id
== addpath_id
)
2845 if (bgp_debug_update(peer
, p
, NULL
, 1))
2847 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2848 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- withdrawn",
2850 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2851 p
->prefixlen
, buf2
);
2854 /* Withdraw specified route from routing table. */
2855 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2856 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2857 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2858 zlog_debug ("%s Can't find the route %s/%d", peer
->host
,
2859 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2862 /* Unlock bgp_node_get() lock. */
2863 bgp_unlock_node (rn
);
2869 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2871 struct update_subgroup
*subgrp
;
2872 subgrp
= peer_subgroup(peer
, afi
, safi
);
2873 subgroup_default_originate(subgrp
, withdraw
);
2878 * bgp_stop_announce_route_timer
2881 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2883 if (!paf
->t_announce_route
)
2886 THREAD_TIMER_OFF (paf
->t_announce_route
);
2890 * bgp_announce_route_timer_expired
2892 * Callback that is invoked when the route announcement timer for a
2896 bgp_announce_route_timer_expired (struct thread
*t
)
2898 struct peer_af
*paf
;
2901 paf
= THREAD_ARG (t
);
2904 assert (paf
->t_announce_route
);
2905 paf
->t_announce_route
= NULL
;
2907 if (peer
->status
!= Established
)
2910 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
2913 peer_af_announce_route (paf
, 1);
2918 * bgp_announce_route
2920 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
2923 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
2925 struct peer_af
*paf
;
2926 struct update_subgroup
*subgrp
;
2928 paf
= peer_af_find (peer
, afi
, safi
);
2931 subgrp
= PAF_SUBGRP(paf
);
2934 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
2935 * or a refresh has already been triggered.
2937 if (!subgrp
|| paf
->t_announce_route
)
2941 * Start a timer to stagger/delay the announce. This serves
2942 * two purposes - announcement can potentially be combined for
2943 * multiple peers and the announcement doesn't happen in the
2946 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
2947 bgp_announce_route_timer_expired
, paf
,
2948 (subgrp
->peer_count
== 1) ?
2949 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
2950 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
2954 * Announce routes from all AF tables to a peer.
2956 * This should ONLY be called when there is a need to refresh the
2957 * routes to the peer based on a policy change for this peer alone
2958 * or a route refresh request received from the peer.
2959 * The operation will result in splitting the peer from its existing
2960 * subgroups and putting it in new subgroups.
2963 bgp_announce_route_all (struct peer
*peer
)
2968 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2969 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2970 bgp_announce_route (peer
, afi
, safi
);
2974 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
2975 struct bgp_table
*table
, struct prefix_rd
*prd
)
2978 struct bgp_node
*rn
;
2979 struct bgp_adj_in
*ain
;
2982 table
= peer
->bgp
->rib
[afi
][safi
];
2984 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
2985 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
2987 if (ain
->peer
== peer
)
2989 struct bgp_info
*ri
= rn
->info
;
2990 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
2992 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
2993 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2998 bgp_unlock_node (rn
);
3006 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3008 struct bgp_node
*rn
;
3009 struct bgp_table
*table
;
3011 if (peer
->status
!= Established
)
3014 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
))
3015 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3017 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3018 rn
= bgp_route_next (rn
))
3019 if ((table
= rn
->info
) != NULL
)
3021 struct prefix_rd prd
;
3022 prd
.family
= AF_UNSPEC
;
3024 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3026 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3031 struct bgp_clear_node_queue
3033 struct bgp_node
*rn
;
3036 static wq_item_status
3037 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3039 struct bgp_clear_node_queue
*cnq
= data
;
3040 struct bgp_node
*rn
= cnq
->rn
;
3041 struct peer
*peer
= wq
->spec
.data
;
3042 struct bgp_info
*ri
;
3043 afi_t afi
= bgp_node_table (rn
)->afi
;
3044 safi_t safi
= bgp_node_table (rn
)->safi
;
3046 assert (rn
&& peer
);
3048 /* It is possible that we have multiple paths for a prefix from a peer
3049 * if that peer is using AddPath.
3051 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3052 if (ri
->peer
== peer
)
3054 /* graceful restart STALE flag set. */
3055 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3056 && peer
->nsf
[afi
][safi
]
3057 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3058 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3059 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3061 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3067 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3069 struct bgp_clear_node_queue
*cnq
= data
;
3070 struct bgp_node
*rn
= cnq
->rn
;
3071 struct bgp_table
*table
= bgp_node_table (rn
);
3073 bgp_unlock_node (rn
);
3074 bgp_table_unlock (table
);
3075 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3079 bgp_clear_node_complete (struct work_queue
*wq
)
3081 struct peer
*peer
= wq
->spec
.data
;
3083 /* Tickle FSM to start moving again */
3084 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3086 peer_unlock (peer
); /* bgp_clear_route */
3090 bgp_clear_node_queue_init (struct peer
*peer
)
3092 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3094 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3095 #undef CLEAR_QUEUE_NAME_LEN
3097 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3099 zlog_err ("%s: Failed to allocate work queue", __func__
);
3102 peer
->clear_node_queue
->spec
.hold
= 10;
3103 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3104 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3105 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3106 peer
->clear_node_queue
->spec
.max_retries
= 0;
3108 /* we only 'lock' this peer reference when the queue is actually active */
3109 peer
->clear_node_queue
->spec
.data
= peer
;
3113 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3114 struct bgp_table
*table
)
3116 struct bgp_node
*rn
;
3117 int force
= bm
->process_main_queue
? 0 : 1;
3120 table
= peer
->bgp
->rib
[afi
][safi
];
3122 /* If still no table => afi/safi isn't configured at all or smth. */
3126 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3128 struct bgp_info
*ri
, *next
;
3129 struct bgp_adj_in
*ain
;
3130 struct bgp_adj_in
*ain_next
;
3132 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3133 * queued for every clearing peer, regardless of whether it is
3134 * relevant to the peer at hand.
3136 * Overview: There are 3 different indices which need to be
3137 * scrubbed, potentially, when a peer is removed:
3139 * 1 peer's routes visible via the RIB (ie accepted routes)
3140 * 2 peer's routes visible by the (optional) peer's adj-in index
3141 * 3 other routes visible by the peer's adj-out index
3143 * 3 there is no hurry in scrubbing, once the struct peer is
3144 * removed from bgp->peer, we could just GC such deleted peer's
3145 * adj-outs at our leisure.
3147 * 1 and 2 must be 'scrubbed' in some way, at least made
3148 * invisible via RIB index before peer session is allowed to be
3149 * brought back up. So one needs to know when such a 'search' is
3154 * - there'd be a single global queue or a single RIB walker
3155 * - rather than tracking which route_nodes still need to be
3156 * examined on a peer basis, we'd track which peers still
3159 * Given that our per-peer prefix-counts now should be reliable,
3160 * this may actually be achievable. It doesn't seem to be a huge
3161 * problem at this time,
3163 * It is possible that we have multiple paths for a prefix from a peer
3164 * if that peer is using AddPath.
3169 ain_next
= ain
->next
;
3171 if (ain
->peer
== peer
)
3173 bgp_adj_in_remove (rn
, ain
);
3174 bgp_unlock_node (rn
);
3180 for (ri
= rn
->info
; ri
; ri
= next
)
3183 if (ri
->peer
!= peer
)
3187 bgp_info_reap (rn
, ri
);
3190 struct bgp_clear_node_queue
*cnq
;
3192 /* both unlocked in bgp_clear_node_queue_del */
3193 bgp_table_lock (bgp_node_table (rn
));
3195 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3196 sizeof (struct bgp_clear_node_queue
));
3198 work_queue_add (peer
->clear_node_queue
, cnq
);
3207 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3209 struct bgp_node
*rn
;
3210 struct bgp_table
*table
;
3212 if (peer
->clear_node_queue
== NULL
)
3213 bgp_clear_node_queue_init (peer
);
3215 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3216 * Idle until it receives a Clearing_Completed event. This protects
3217 * against peers which flap faster than we can we clear, which could
3220 * a) race with routes from the new session being installed before
3221 * clear_route_node visits the node (to delete the route of that
3223 * b) resource exhaustion, clear_route_node likely leads to an entry
3224 * on the process_main queue. Fast-flapping could cause that queue
3228 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3229 * the unlock will happen upon work-queue completion; other wise, the
3230 * unlock happens at the end of this function.
3232 if (!peer
->clear_node_queue
->thread
)
3235 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
)
3236 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3238 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3239 rn
= bgp_route_next (rn
))
3240 if ((table
= rn
->info
) != NULL
)
3241 bgp_clear_route_table (peer
, afi
, safi
, table
);
3243 /* unlock if no nodes got added to the clear-node-queue. */
3244 if (!peer
->clear_node_queue
->thread
)
3250 bgp_clear_route_all (struct peer
*peer
)
3255 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3256 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3257 bgp_clear_route (peer
, afi
, safi
);
3260 rfapiProcessPeerDown(peer
);
3265 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3267 struct bgp_table
*table
;
3268 struct bgp_node
*rn
;
3269 struct bgp_adj_in
*ain
;
3270 struct bgp_adj_in
*ain_next
;
3272 table
= peer
->bgp
->rib
[afi
][safi
];
3274 /* It is possible that we have multiple paths for a prefix from a peer
3275 * if that peer is using AddPath.
3277 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3283 ain_next
= ain
->next
;
3285 if (ain
->peer
== peer
)
3287 bgp_adj_in_remove (rn
, ain
);
3288 bgp_unlock_node (rn
);
3297 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3299 struct bgp_node
*rn
;
3300 struct bgp_info
*ri
;
3301 struct bgp_table
*table
;
3303 if ( safi
== SAFI_MPLS_VPN
)
3305 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3307 struct bgp_node
*rm
;
3308 struct bgp_info
*ri
;
3310 /* look for neighbor in tables */
3311 if ((table
= rn
->info
) != NULL
)
3313 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3314 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3315 if (ri
->peer
== peer
)
3317 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3318 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3326 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3327 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3328 if (ri
->peer
== peer
)
3330 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3331 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3338 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3340 struct bgp_node
*rn
;
3341 struct bgp_info
*ri
;
3342 struct bgp_info
*next
;
3344 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3345 for (ri
= rn
->info
; ri
; ri
= next
)
3348 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3349 && ri
->type
== ZEBRA_ROUTE_BGP
3350 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3351 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3354 if (table
->owner
&& table
->owner
->bgp
)
3355 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3357 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3358 bgp_info_reap (rn
, ri
);
3363 /* Delete all kernel routes. */
3365 bgp_cleanup_routes (struct bgp
*bgp
)
3369 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3371 struct bgp_node
*rn
;
3373 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3376 * VPN and ENCAP tables are two-level (RD is top level)
3378 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
3379 rn
= bgp_route_next (rn
))
3383 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_MPLS_VPN
);
3384 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3386 bgp_unlock_node(rn
);
3390 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_ENCAP
]); rn
;
3391 rn
= bgp_route_next (rn
))
3395 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_ENCAP
);
3396 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3398 bgp_unlock_node(rn
);
3408 bgp_zclient_reset ();
3409 access_list_reset ();
3410 prefix_list_reset ();
3414 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3416 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3417 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3420 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3423 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3424 struct bgp_nlri
*packet
)
3433 int addpath_encoded
;
3434 u_int32_t addpath_id
;
3436 /* Check peer status. */
3437 if (peer
->status
!= Established
)
3441 lim
= pnt
+ packet
->length
;
3443 safi
= packet
->safi
;
3445 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3447 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3448 syntactic validity. If the field is syntactically incorrect,
3449 then the Error Subcode is set to Invalid Network Field. */
3450 for (; pnt
< lim
; pnt
+= psize
)
3452 /* Clear prefix structure. */
3453 memset (&p
, 0, sizeof (struct prefix
));
3455 if (addpath_encoded
)
3458 /* When packet overflow occurs return immediately. */
3459 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3462 addpath_id
= ntohl(*((uint32_t*) pnt
));
3463 pnt
+= BGP_ADDPATH_ID_LEN
;
3466 /* Fetch prefix length. */
3467 p
.prefixlen
= *pnt
++;
3468 /* afi/safi validity already verified by caller, bgp_update_receive */
3469 p
.family
= afi2family (afi
);
3471 /* Prefix length check. */
3472 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3474 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3475 peer
->host
, p
.prefixlen
, packet
->afi
);
3479 /* Packet size overflow check. */
3480 psize
= PSIZE (p
.prefixlen
);
3482 /* When packet overflow occur return immediately. */
3483 if (pnt
+ psize
> lim
)
3485 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3486 peer
->host
, p
.prefixlen
);
3490 /* Defensive coding, double-check the psize fits in a struct prefix */
3491 if (psize
> (ssize_t
) sizeof(p
.u
))
3493 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3494 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3498 /* Fetch prefix from NLRI packet. */
3499 memcpy (&p
.u
.prefix
, pnt
, psize
);
3501 /* Check address. */
3502 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3504 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3506 /* From RFC4271 Section 6.3:
3508 * If a prefix in the NLRI field is semantically incorrect
3509 * (e.g., an unexpected multicast IP address), an error SHOULD
3510 * be logged locally, and the prefix SHOULD be ignored.
3512 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3513 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3518 /* Check address. */
3519 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3521 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3525 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3526 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3530 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3534 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3535 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3541 /* Normal process. */
3543 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3544 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0);
3546 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3547 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
);
3549 /* Address family configuration mismatch or maximum-prefix count
3555 /* Packet length consistency check. */
3558 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3566 static struct bgp_static
*
3567 bgp_static_new (void)
3569 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3573 bgp_static_free (struct bgp_static
*bgp_static
)
3575 if (bgp_static
->rmap
.name
)
3576 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3577 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3581 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3582 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3584 struct bgp_node
*rn
;
3585 struct bgp_info
*ri
;
3586 struct bgp_info
*new;
3587 struct bgp_info info
;
3589 struct attr
*attr_new
;
3592 int vnc_implicit_withdraw
= 0;
3595 assert (bgp_static
);
3599 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3601 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3603 attr
.nexthop
= bgp_static
->igpnexthop
;
3604 attr
.med
= bgp_static
->igpmetric
;
3605 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3607 if (bgp_static
->atomic
)
3608 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3610 /* Apply route-map. */
3611 if (bgp_static
->rmap
.name
)
3613 struct attr attr_tmp
= attr
;
3614 info
.peer
= bgp
->peer_self
;
3615 info
.attr
= &attr_tmp
;
3617 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3619 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3621 bgp
->peer_self
->rmap_type
= 0;
3623 if (ret
== RMAP_DENYMATCH
)
3625 /* Free uninterned attribute. */
3626 bgp_attr_flush (&attr_tmp
);
3628 /* Unintern original. */
3629 aspath_unintern (&attr
.aspath
);
3630 bgp_attr_extra_free (&attr
);
3631 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3634 attr_new
= bgp_attr_intern (&attr_tmp
);
3637 attr_new
= bgp_attr_intern (&attr
);
3639 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3640 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3641 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3646 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3647 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3648 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3650 bgp_unlock_node (rn
);
3651 bgp_attr_unintern (&attr_new
);
3652 aspath_unintern (&attr
.aspath
);
3653 bgp_attr_extra_free (&attr
);
3658 /* The attribute is changed. */
3659 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3661 /* Rewrite BGP route information. */
3662 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3663 bgp_info_restore(rn
, ri
);
3665 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3667 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3669 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3672 * Implicit withdraw case.
3673 * We have to do this before ri is changed
3675 ++vnc_implicit_withdraw
;
3676 vnc_import_bgp_del_route(bgp
, p
, ri
);
3677 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3681 bgp_attr_unintern (&ri
->attr
);
3682 ri
->attr
= attr_new
;
3683 ri
->uptime
= bgp_clock ();
3685 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3687 if (vnc_implicit_withdraw
)
3689 vnc_import_bgp_add_route(bgp
, p
, ri
);
3690 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3695 /* Nexthop reachability check. */
3696 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3698 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3699 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3702 if (BGP_DEBUG(nht
, NHT
))
3704 char buf1
[INET6_ADDRSTRLEN
];
3705 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3707 zlog_debug("%s(%s): Route not in table, not advertising",
3708 __FUNCTION__
, buf1
);
3710 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3715 /* Delete the NHT structure if any, if we're toggling between
3716 * enabling/disabling import check. We deregister the route
3717 * from NHT to avoid overloading NHT and the process interaction
3719 bgp_unlink_nexthop(ri
);
3720 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3722 /* Process change. */
3723 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3724 bgp_process (bgp
, rn
, afi
, safi
);
3725 bgp_unlock_node (rn
);
3726 aspath_unintern (&attr
.aspath
);
3727 bgp_attr_extra_free (&attr
);
3732 /* Make new BGP info. */
3733 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3735 /* Nexthop reachability check. */
3736 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3738 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3739 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3742 if (BGP_DEBUG(nht
, NHT
))
3744 char buf1
[INET6_ADDRSTRLEN
];
3745 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3747 zlog_debug("%s(%s): Route not in table, not advertising",
3748 __FUNCTION__
, buf1
);
3750 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3755 /* Delete the NHT structure if any, if we're toggling between
3756 * enabling/disabling import check. We deregister the route
3757 * from NHT to avoid overloading NHT and the process interaction
3759 bgp_unlink_nexthop(new);
3761 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3764 /* Aggregate address increment. */
3765 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3767 /* Register new BGP information. */
3768 bgp_info_add (rn
, new);
3770 /* route_node_get lock */
3771 bgp_unlock_node (rn
);
3773 /* Process change. */
3774 bgp_process (bgp
, rn
, afi
, safi
);
3776 /* Unintern original. */
3777 aspath_unintern (&attr
.aspath
);
3778 bgp_attr_extra_free (&attr
);
3782 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3783 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3785 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3789 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3792 struct bgp_node
*rn
;
3793 struct bgp_info
*ri
;
3795 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3797 /* Check selected route and self inserted route. */
3798 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3799 if (ri
->peer
== bgp
->peer_self
3800 && ri
->type
== ZEBRA_ROUTE_BGP
3801 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3804 /* Withdraw static BGP route from routing table. */
3807 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3808 bgp_unlink_nexthop(ri
);
3809 bgp_info_delete (rn
, ri
);
3810 bgp_process (bgp
, rn
, afi
, safi
);
3813 /* Unlock bgp_node_lookup. */
3814 bgp_unlock_node (rn
);
3818 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3821 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3822 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3824 struct bgp_node
*rn
;
3825 struct bgp_info
*ri
;
3827 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3829 /* Check selected route and self inserted route. */
3830 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3831 if (ri
->peer
== bgp
->peer_self
3832 && ri
->type
== ZEBRA_ROUTE_BGP
3833 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3836 /* Withdraw static BGP route from routing table. */
3840 rfapiProcessWithdraw(
3849 1); /* Kill, since it is an administrative change */
3851 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3852 bgp_info_delete (rn
, ri
);
3853 bgp_process (bgp
, rn
, afi
, safi
);
3856 /* Unlock bgp_node_lookup. */
3857 bgp_unlock_node (rn
);
3861 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3862 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3864 struct bgp_node
*rn
;
3865 struct bgp_info
*new;
3866 struct attr
*attr_new
;
3867 struct attr attr
= { 0 };
3868 struct bgp_info
*ri
;
3870 u_int32_t label
= 0;
3873 assert (bgp_static
);
3875 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
3877 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3879 attr
.nexthop
= bgp_static
->igpnexthop
;
3880 attr
.med
= bgp_static
->igpmetric
;
3881 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3883 /* Apply route-map. */
3884 if (bgp_static
->rmap
.name
)
3886 struct attr attr_tmp
= attr
;
3887 struct bgp_info info
;
3890 info
.peer
= bgp
->peer_self
;
3891 info
.attr
= &attr_tmp
;
3893 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3895 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3897 bgp
->peer_self
->rmap_type
= 0;
3899 if (ret
== RMAP_DENYMATCH
)
3901 /* Free uninterned attribute. */
3902 bgp_attr_flush (&attr_tmp
);
3904 /* Unintern original. */
3905 aspath_unintern (&attr
.aspath
);
3906 bgp_attr_extra_free (&attr
);
3907 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
3912 attr_new
= bgp_attr_intern (&attr_tmp
);
3916 attr_new
= bgp_attr_intern (&attr
);
3919 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3920 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3921 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3926 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3927 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3929 bgp_unlock_node (rn
);
3930 bgp_attr_unintern (&attr_new
);
3931 aspath_unintern (&attr
.aspath
);
3932 bgp_attr_extra_free (&attr
);
3937 /* The attribute is changed. */
3938 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3940 /* Rewrite BGP route information. */
3941 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3942 bgp_info_restore(rn
, ri
);
3944 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3945 bgp_attr_unintern (&ri
->attr
);
3946 ri
->attr
= attr_new
;
3947 ri
->uptime
= bgp_clock ();
3950 label
= decode_label (ri
->extra
->tag
);
3953 /* Process change. */
3954 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3955 bgp_process (bgp
, rn
, afi
, safi
);
3957 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
3958 ri
->attr
, afi
, safi
,
3959 ri
->type
, ri
->sub_type
, &label
);
3961 bgp_unlock_node (rn
);
3962 aspath_unintern (&attr
.aspath
);
3963 bgp_attr_extra_free (&attr
);
3969 /* Make new BGP info. */
3970 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3972 SET_FLAG (new->flags
, BGP_INFO_VALID
);
3973 new->extra
= bgp_info_extra_new();
3974 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
3976 label
= decode_label (bgp_static
->tag
);
3979 /* Aggregate address increment. */
3980 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3982 /* Register new BGP information. */
3983 bgp_info_add (rn
, new);
3985 /* route_node_get lock */
3986 bgp_unlock_node (rn
);
3988 /* Process change. */
3989 bgp_process (bgp
, rn
, afi
, safi
);
3992 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
3993 new->attr
, afi
, safi
,
3994 new->type
, new->sub_type
, &label
);
3997 /* Unintern original. */
3998 aspath_unintern (&attr
.aspath
);
3999 bgp_attr_extra_free (&attr
);
4002 /* Configure static BGP network. When user don't run zebra, static
4003 route should be installed as valid. */
4005 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4006 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4008 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4011 struct bgp_static
*bgp_static
;
4012 struct bgp_node
*rn
;
4013 u_char need_update
= 0;
4015 /* Convert IP prefix string to struct prefix. */
4016 ret
= str2prefix (ip_str
, &p
);
4019 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4022 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4024 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4031 /* Set BGP static route configuration. */
4032 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4036 /* Configuration change. */
4037 bgp_static
= rn
->info
;
4039 /* Check previous routes are installed into BGP. */
4040 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4043 bgp_static
->backdoor
= backdoor
;
4047 if (bgp_static
->rmap
.name
)
4048 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4049 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4050 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4054 if (bgp_static
->rmap
.name
)
4055 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4056 bgp_static
->rmap
.name
= NULL
;
4057 bgp_static
->rmap
.map
= NULL
;
4058 bgp_static
->valid
= 0;
4060 bgp_unlock_node (rn
);
4064 /* New configuration. */
4065 bgp_static
= bgp_static_new ();
4066 bgp_static
->backdoor
= backdoor
;
4067 bgp_static
->valid
= 0;
4068 bgp_static
->igpmetric
= 0;
4069 bgp_static
->igpnexthop
.s_addr
= 0;
4073 if (bgp_static
->rmap
.name
)
4074 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4075 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4076 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4078 rn
->info
= bgp_static
;
4081 bgp_static
->valid
= 1;
4083 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4085 if (! bgp_static
->backdoor
)
4086 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4091 /* Configure static BGP network. */
4093 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4094 afi_t afi
, safi_t safi
)
4096 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4099 struct bgp_static
*bgp_static
;
4100 struct bgp_node
*rn
;
4102 /* Convert IP prefix string to struct prefix. */
4103 ret
= str2prefix (ip_str
, &p
);
4106 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4109 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4111 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4118 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4121 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4126 bgp_static
= rn
->info
;
4128 /* Update BGP RIB. */
4129 if (! bgp_static
->backdoor
)
4130 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4132 /* Clear configuration. */
4133 bgp_static_free (bgp_static
);
4135 bgp_unlock_node (rn
);
4136 bgp_unlock_node (rn
);
4142 bgp_static_add (struct bgp
*bgp
)
4146 struct bgp_node
*rn
;
4147 struct bgp_node
*rm
;
4148 struct bgp_table
*table
;
4149 struct bgp_static
*bgp_static
;
4151 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4152 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4153 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4154 if (rn
->info
!= NULL
)
4156 if (safi
== SAFI_MPLS_VPN
)
4160 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4162 bgp_static
= rn
->info
;
4163 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4168 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4173 /* Called from bgp_delete(). Delete all static routes from the BGP
4176 bgp_static_delete (struct bgp
*bgp
)
4180 struct bgp_node
*rn
;
4181 struct bgp_node
*rm
;
4182 struct bgp_table
*table
;
4183 struct bgp_static
*bgp_static
;
4185 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4186 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4187 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4188 if (rn
->info
!= NULL
)
4190 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4194 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4196 bgp_static
= rn
->info
;
4197 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4199 (struct prefix_rd
*)&rn
->p
,
4201 bgp_static_free (bgp_static
);
4203 bgp_unlock_node (rn
);
4208 bgp_static
= rn
->info
;
4209 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4210 bgp_static_free (bgp_static
);
4212 bgp_unlock_node (rn
);
4218 bgp_static_redo_import_check (struct bgp
*bgp
)
4222 struct bgp_node
*rn
;
4223 struct bgp_static
*bgp_static
;
4225 /* Use this flag to force reprocessing of the route */
4226 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4227 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4228 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4229 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4230 if (rn
->info
!= NULL
)
4232 bgp_static
= rn
->info
;
4233 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4235 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4239 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4241 struct bgp_table
*table
;
4242 struct bgp_node
*rn
;
4243 struct bgp_info
*ri
;
4245 table
= bgp
->rib
[afi
][safi
];
4246 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4248 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4250 if (ri
->peer
== bgp
->peer_self
&&
4251 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4252 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4253 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4254 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4256 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4257 bgp_unlink_nexthop(ri
);
4258 bgp_info_delete (rn
, ri
);
4259 bgp_process (bgp
, rn
, afi
, safi
);
4266 * Purge all networks and redistributed routes from routing table.
4267 * Invoked upon the instance going down.
4270 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4275 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4276 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4277 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4282 * Currently this is used to set static routes for VPN and ENCAP.
4283 * I think it can probably be factored with bgp_static_set.
4286 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4287 const char *rd_str
, const char *tag_str
,
4288 const char *rmap_str
)
4290 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4293 struct prefix_rd prd
;
4294 struct bgp_node
*prn
;
4295 struct bgp_node
*rn
;
4296 struct bgp_table
*table
;
4297 struct bgp_static
*bgp_static
;
4300 ret
= str2prefix (ip_str
, &p
);
4303 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4308 ret
= str2prefix_rd (rd_str
, &prd
);
4311 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4315 ret
= str2tag (tag_str
, tag
);
4318 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4322 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4323 (struct prefix
*)&prd
);
4324 if (prn
->info
== NULL
)
4325 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4327 bgp_unlock_node (prn
);
4330 rn
= bgp_node_get (table
, &p
);
4334 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4335 bgp_unlock_node (rn
);
4339 /* New configuration. */
4340 bgp_static
= bgp_static_new ();
4341 bgp_static
->backdoor
= 0;
4342 bgp_static
->valid
= 0;
4343 bgp_static
->igpmetric
= 0;
4344 bgp_static
->igpnexthop
.s_addr
= 0;
4345 memcpy(bgp_static
->tag
, tag
, 3);
4346 bgp_static
->prd
= prd
;
4350 if (bgp_static
->rmap
.name
)
4351 free (bgp_static
->rmap
.name
);
4352 bgp_static
->rmap
.name
= strdup (rmap_str
);
4353 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4355 rn
->info
= bgp_static
;
4357 bgp_static
->valid
= 1;
4358 bgp_static_update_safi (bgp
, &p
, bgp_static
, AFI_IP
, safi
);
4364 /* Configure static BGP network. */
4366 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4367 const char *rd_str
, const char *tag_str
)
4369 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4372 struct prefix_rd prd
;
4373 struct bgp_node
*prn
;
4374 struct bgp_node
*rn
;
4375 struct bgp_table
*table
;
4376 struct bgp_static
*bgp_static
;
4379 /* Convert IP prefix string to struct prefix. */
4380 ret
= str2prefix (ip_str
, &p
);
4383 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4388 ret
= str2prefix_rd (rd_str
, &prd
);
4391 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4395 ret
= str2tag (tag_str
, tag
);
4398 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4402 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4403 (struct prefix
*)&prd
);
4404 if (prn
->info
== NULL
)
4405 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4407 bgp_unlock_node (prn
);
4410 rn
= bgp_node_lookup (table
, &p
);
4414 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4416 bgp_static
= rn
->info
;
4417 bgp_static_free (bgp_static
);
4419 bgp_unlock_node (rn
);
4420 bgp_unlock_node (rn
);
4423 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4429 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4430 const char *rmap_name
)
4432 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4433 struct bgp_rmap
*rmap
;
4435 rmap
= &bgp
->table_map
[afi
][safi
];
4439 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4440 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4441 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4446 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4451 bgp_zebra_announce_table(bgp
, afi
, safi
);
4457 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4458 const char *rmap_name
)
4460 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4461 struct bgp_rmap
*rmap
;
4463 rmap
= &bgp
->table_map
[afi
][safi
];
4465 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4469 bgp_zebra_announce_table(bgp
, afi
, safi
);
4475 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4476 safi_t safi
, int *write
)
4478 if (bgp
->table_map
[afi
][safi
].name
)
4480 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4481 vty_out (vty
, " table-map %s%s",
4482 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4488 DEFUN (bgp_table_map
,
4491 "BGP table to RIB route download filter\n"
4492 "Name of the route map\n")
4495 return bgp_table_map_set (vty
,
4496 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4498 DEFUN (no_bgp_table_map
,
4499 no_bgp_table_map_cmd
,
4500 "no table-map WORD",
4502 "BGP table to RIB route download filter\n"
4503 "Name of the route map\n")
4506 return bgp_table_map_unset (vty
,
4507 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4512 "network A.B.C.D/M",
4513 "Specify a network to announce via BGP\n"
4516 int idx_ipv4_prefixlen
= 1;
4517 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4518 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4521 DEFUN (bgp_network_route_map
,
4522 bgp_network_route_map_cmd
,
4523 "network A.B.C.D/M route-map WORD",
4524 "Specify a network to announce via BGP\n"
4526 "Route-map to modify the attributes\n"
4527 "Name of the route map\n")
4529 int idx_ipv4_prefixlen
= 1;
4531 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4532 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4535 DEFUN (bgp_network_backdoor
,
4536 bgp_network_backdoor_cmd
,
4537 "network A.B.C.D/M backdoor",
4538 "Specify a network to announce via BGP\n"
4540 "Specify a BGP backdoor route\n")
4542 int idx_ipv4_prefixlen
= 1;
4543 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4547 DEFUN (bgp_network_mask
,
4548 bgp_network_mask_cmd
,
4549 "network A.B.C.D mask A.B.C.D",
4550 "Specify a network to announce via BGP\n"
4558 char prefix_str
[BUFSIZ
];
4560 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4563 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4567 return bgp_static_set (vty
, prefix_str
,
4568 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4571 DEFUN (bgp_network_mask_route_map
,
4572 bgp_network_mask_route_map_cmd
,
4573 "network A.B.C.D mask A.B.C.D route-map WORD",
4574 "Specify a network to announce via BGP\n"
4578 "Route-map to modify the attributes\n"
4579 "Name of the route map\n")
4585 char prefix_str
[BUFSIZ
];
4587 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4590 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4594 return bgp_static_set (vty
, prefix_str
,
4595 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4598 DEFUN (bgp_network_mask_backdoor
,
4599 bgp_network_mask_backdoor_cmd
,
4600 "network A.B.C.D mask A.B.C.D backdoor",
4601 "Specify a network to announce via BGP\n"
4605 "Specify a BGP backdoor route\n")
4610 char prefix_str
[BUFSIZ
];
4612 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4615 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4619 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4623 DEFUN (bgp_network_mask_natural
,
4624 bgp_network_mask_natural_cmd
,
4626 "Specify a network to announce via BGP\n"
4631 char prefix_str
[BUFSIZ
];
4633 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4636 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4640 return bgp_static_set (vty
, prefix_str
,
4641 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4644 DEFUN (bgp_network_mask_natural_route_map
,
4645 bgp_network_mask_natural_route_map_cmd
,
4646 "network A.B.C.D route-map WORD",
4647 "Specify a network to announce via BGP\n"
4649 "Route-map to modify the attributes\n"
4650 "Name of the route map\n")
4655 char prefix_str
[BUFSIZ
];
4657 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4660 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4664 return bgp_static_set (vty
, prefix_str
,
4665 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4668 DEFUN (bgp_network_mask_natural_backdoor
,
4669 bgp_network_mask_natural_backdoor_cmd
,
4670 "network A.B.C.D backdoor",
4671 "Specify a network to announce via BGP\n"
4673 "Specify a BGP backdoor route\n")
4677 char prefix_str
[BUFSIZ
];
4679 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4682 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4686 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4690 DEFUN (no_bgp_network
,
4692 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4694 "Specify a network to announce via BGP\n"
4696 "Specify a BGP backdoor route\n"
4697 "Route-map to modify the attributes\n"
4698 "Name of the route map\n")
4700 int idx_ipv4_prefixlen
= 2;
4701 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4702 bgp_node_safi (vty
));
4705 DEFUN (no_bgp_network_mask
,
4706 no_bgp_network_mask_cmd
,
4707 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4709 "Specify a network to announce via BGP\n"
4713 "Specify a BGP backdoor route\n"
4714 "Route-map to modify the attributes\n"
4715 "Name of the route map\n")
4720 char prefix_str
[BUFSIZ
];
4722 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4725 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4729 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4730 bgp_node_safi (vty
));
4733 DEFUN (no_bgp_network_mask_natural
,
4734 no_bgp_network_mask_natural_cmd
,
4735 "no network A.B.C.D [<backdoor|route-map WORD>]",
4737 "Specify a network to announce via BGP\n"
4739 "Specify a BGP backdoor route\n"
4740 "Route-map to modify the attributes\n"
4741 "Name of the route map\n")
4745 char prefix_str
[BUFSIZ
];
4747 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4750 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4754 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4755 bgp_node_safi (vty
));
4758 DEFUN (ipv6_bgp_network
,
4759 ipv6_bgp_network_cmd
,
4760 "network X:X::X:X/M",
4761 "Specify a network to announce via BGP\n"
4764 int idx_ipv6_prefixlen
= 1;
4765 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4769 DEFUN (ipv6_bgp_network_route_map
,
4770 ipv6_bgp_network_route_map_cmd
,
4771 "network X:X::X:X/M route-map WORD",
4772 "Specify a network to announce via BGP\n"
4774 "Route-map to modify the attributes\n"
4775 "Name of the route map\n")
4777 int idx_ipv6_prefixlen
= 1;
4779 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4780 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4783 DEFUN (no_ipv6_bgp_network
,
4784 no_ipv6_bgp_network_cmd
,
4785 "no 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
= 2;
4793 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4796 /* Aggreagete address:
4798 advertise-map Set condition to advertise attribute
4799 as-set Generate AS set path information
4800 attribute-map Set attributes of aggregate
4801 route-map Set parameters of aggregate
4802 summary-only Filter more specific routes from updates
4803 suppress-map Conditionally filter more specific routes from updates
4806 struct bgp_aggregate
4808 /* Summary-only flag. */
4809 u_char summary_only
;
4811 /* AS set generation. */
4814 /* Route-map for aggregated route. */
4815 struct route_map
*map
;
4817 /* Suppress-count. */
4818 unsigned long count
;
4820 /* SAFI configuration. */
4824 static struct bgp_aggregate
*
4825 bgp_aggregate_new (void)
4827 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4831 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4833 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4836 /* Update an aggregate as routes are added/removed from the BGP table */
4838 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4839 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4840 struct bgp_aggregate
*aggregate
)
4842 struct bgp_table
*table
;
4843 struct bgp_node
*top
;
4844 struct bgp_node
*rn
;
4846 struct aspath
*aspath
= NULL
;
4847 struct aspath
*asmerge
= NULL
;
4848 struct community
*community
= NULL
;
4849 struct community
*commerge
= NULL
;
4850 #if defined(AGGREGATE_NEXTHOP_CHECK)
4851 struct in_addr nexthop
;
4854 struct bgp_info
*ri
;
4855 struct bgp_info
*new;
4857 unsigned long match
= 0;
4858 u_char atomic_aggregate
= 0;
4860 /* Record adding route's nexthop and med. */
4863 #if defined(AGGREGATE_NEXTHOP_CHECK)
4864 nexthop
= rinew
->attr
->nexthop
;
4865 med
= rinew
->attr
->med
;
4869 /* ORIGIN attribute: If at least one route among routes that are
4870 aggregated has ORIGIN with the value INCOMPLETE, then the
4871 aggregated route must have the ORIGIN attribute with the value
4872 INCOMPLETE. Otherwise, if at least one route among routes that
4873 are aggregated has ORIGIN with the value EGP, then the aggregated
4874 route must have the origin attribute with the value EGP. In all
4875 other case the value of the ORIGIN attribute of the aggregated
4876 route is INTERNAL. */
4877 origin
= BGP_ORIGIN_IGP
;
4879 table
= bgp
->rib
[afi
][safi
];
4881 top
= bgp_node_get (table
, p
);
4882 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
4883 if (rn
->p
.prefixlen
> p
->prefixlen
)
4887 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4889 if (BGP_INFO_HOLDDOWN (ri
))
4892 if (del
&& ri
== del
)
4895 if (! rinew
&& first
)
4897 #if defined(AGGREGATE_NEXTHOP_CHECK)
4898 nexthop
= ri
->attr
->nexthop
;
4899 med
= ri
->attr
->med
;
4904 #ifdef AGGREGATE_NEXTHOP_CHECK
4905 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
4906 || ri
->attr
->med
!= med
)
4909 aspath_free (aspath
);
4911 community_free (community
);
4912 bgp_unlock_node (rn
);
4913 bgp_unlock_node (top
);
4916 #endif /* AGGREGATE_NEXTHOP_CHECK */
4918 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
4919 atomic_aggregate
= 1;
4921 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
4923 if (aggregate
->summary_only
)
4925 (bgp_info_extra_get (ri
))->suppress
++;
4926 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4932 if (origin
< ri
->attr
->origin
)
4933 origin
= ri
->attr
->origin
;
4935 if (aggregate
->as_set
)
4939 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
4940 aspath_free (aspath
);
4944 aspath
= aspath_dup (ri
->attr
->aspath
);
4946 if (ri
->attr
->community
)
4950 commerge
= community_merge (community
,
4951 ri
->attr
->community
);
4952 community
= community_uniq_sort (commerge
);
4953 community_free (commerge
);
4956 community
= community_dup (ri
->attr
->community
);
4962 bgp_process (bgp
, rn
, afi
, safi
);
4964 bgp_unlock_node (top
);
4970 if (aggregate
->summary_only
)
4971 (bgp_info_extra_get (rinew
))->suppress
++;
4973 if (origin
< rinew
->attr
->origin
)
4974 origin
= rinew
->attr
->origin
;
4976 if (aggregate
->as_set
)
4980 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
4981 aspath_free (aspath
);
4985 aspath
= aspath_dup (rinew
->attr
->aspath
);
4987 if (rinew
->attr
->community
)
4991 commerge
= community_merge (community
,
4992 rinew
->attr
->community
);
4993 community
= community_uniq_sort (commerge
);
4994 community_free (commerge
);
4997 community
= community_dup (rinew
->attr
->community
);
5002 if (aggregate
->count
> 0)
5004 rn
= bgp_node_get (table
, p
);
5005 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5006 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5008 atomic_aggregate
), rn
);
5009 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5011 bgp_info_add (rn
, new);
5012 bgp_unlock_node (rn
);
5013 bgp_process (bgp
, rn
, afi
, safi
);
5018 aspath_free (aspath
);
5020 community_free (community
);
5024 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5025 struct bgp_aggregate
*);
5028 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5029 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5031 struct bgp_node
*child
;
5032 struct bgp_node
*rn
;
5033 struct bgp_aggregate
*aggregate
;
5034 struct bgp_table
*table
;
5036 /* MPLS-VPN aggregation is not yet supported. */
5037 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5040 table
= bgp
->aggregate
[afi
][safi
];
5042 /* No aggregates configured. */
5043 if (bgp_table_top_nolock (table
) == NULL
)
5046 if (p
->prefixlen
== 0)
5049 if (BGP_INFO_HOLDDOWN (ri
))
5052 child
= bgp_node_get (table
, p
);
5054 /* Aggregate address configuration check. */
5055 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5056 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5058 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5059 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5061 bgp_unlock_node (child
);
5065 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5066 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5068 struct bgp_node
*child
;
5069 struct bgp_node
*rn
;
5070 struct bgp_aggregate
*aggregate
;
5071 struct bgp_table
*table
;
5073 /* MPLS-VPN aggregation is not yet supported. */
5074 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5077 table
= bgp
->aggregate
[afi
][safi
];
5079 /* No aggregates configured. */
5080 if (bgp_table_top_nolock (table
) == NULL
)
5083 if (p
->prefixlen
== 0)
5086 child
= bgp_node_get (table
, p
);
5088 /* Aggregate address configuration check. */
5089 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5090 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5092 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5093 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5095 bgp_unlock_node (child
);
5098 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5100 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5101 struct bgp_aggregate
*aggregate
)
5103 struct bgp_table
*table
;
5104 struct bgp_node
*top
;
5105 struct bgp_node
*rn
;
5106 struct bgp_info
*new;
5107 struct bgp_info
*ri
;
5108 unsigned long match
;
5109 u_char origin
= BGP_ORIGIN_IGP
;
5110 struct aspath
*aspath
= NULL
;
5111 struct aspath
*asmerge
= NULL
;
5112 struct community
*community
= NULL
;
5113 struct community
*commerge
= NULL
;
5114 u_char atomic_aggregate
= 0;
5116 table
= bgp
->rib
[afi
][safi
];
5119 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5121 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5124 /* If routes exists below this node, generate aggregate routes. */
5125 top
= bgp_node_get (table
, p
);
5126 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5127 if (rn
->p
.prefixlen
> p
->prefixlen
)
5131 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5133 if (BGP_INFO_HOLDDOWN (ri
))
5136 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5137 atomic_aggregate
= 1;
5139 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5141 /* summary-only aggregate route suppress aggregated
5142 route announcement. */
5143 if (aggregate
->summary_only
)
5145 (bgp_info_extra_get (ri
))->suppress
++;
5146 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5150 /* If at least one route among routes that are aggregated has
5151 * ORIGIN with the value INCOMPLETE, then the aggregated route
5152 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5153 * Otherwise, if at least one route among routes that are
5154 * aggregated has ORIGIN with the value EGP, then the aggregated
5155 * route MUST have the ORIGIN attribute with the value EGP.
5157 if (origin
< ri
->attr
->origin
)
5158 origin
= ri
->attr
->origin
;
5160 /* as-set aggregate route generate origin, as path,
5161 community aggregation. */
5162 if (aggregate
->as_set
)
5166 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5167 aspath_free (aspath
);
5171 aspath
= aspath_dup (ri
->attr
->aspath
);
5173 if (ri
->attr
->community
)
5177 commerge
= community_merge (community
,
5178 ri
->attr
->community
);
5179 community
= community_uniq_sort (commerge
);
5180 community_free (commerge
);
5183 community
= community_dup (ri
->attr
->community
);
5190 /* If this node is suppressed, process the change. */
5192 bgp_process (bgp
, rn
, afi
, safi
);
5194 bgp_unlock_node (top
);
5196 /* Add aggregate route to BGP table. */
5197 if (aggregate
->count
)
5199 rn
= bgp_node_get (table
, p
);
5200 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5201 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5203 atomic_aggregate
), rn
);
5204 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5206 bgp_info_add (rn
, new);
5207 bgp_unlock_node (rn
);
5209 /* Process change. */
5210 bgp_process (bgp
, rn
, afi
, safi
);
5215 aspath_free (aspath
);
5217 community_free (community
);
5222 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5223 safi_t safi
, struct bgp_aggregate
*aggregate
)
5225 struct bgp_table
*table
;
5226 struct bgp_node
*top
;
5227 struct bgp_node
*rn
;
5228 struct bgp_info
*ri
;
5229 unsigned long match
;
5231 table
= bgp
->rib
[afi
][safi
];
5233 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5235 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5238 /* If routes exists below this node, generate aggregate routes. */
5239 top
= bgp_node_get (table
, p
);
5240 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5241 if (rn
->p
.prefixlen
> p
->prefixlen
)
5245 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5247 if (BGP_INFO_HOLDDOWN (ri
))
5250 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5252 if (aggregate
->summary_only
&& ri
->extra
)
5254 ri
->extra
->suppress
--;
5256 if (ri
->extra
->suppress
== 0)
5258 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5266 /* If this node was suppressed, process the change. */
5268 bgp_process (bgp
, rn
, afi
, safi
);
5270 bgp_unlock_node (top
);
5272 /* Delete aggregate route from BGP table. */
5273 rn
= bgp_node_get (table
, p
);
5275 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5276 if (ri
->peer
== bgp
->peer_self
5277 && ri
->type
== ZEBRA_ROUTE_BGP
5278 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5281 /* Withdraw static BGP route from routing table. */
5284 bgp_info_delete (rn
, ri
);
5285 bgp_process (bgp
, rn
, afi
, safi
);
5288 /* Unlock bgp_node_lookup. */
5289 bgp_unlock_node (rn
);
5292 /* Aggregate route attribute. */
5293 #define AGGREGATE_SUMMARY_ONLY 1
5294 #define AGGREGATE_AS_SET 1
5297 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5298 afi_t afi
, safi_t safi
)
5300 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5303 struct bgp_node
*rn
;
5304 struct bgp_aggregate
*aggregate
;
5306 /* Convert string to prefix structure. */
5307 ret
= str2prefix (prefix_str
, &p
);
5310 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5315 /* Old configuration check. */
5316 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5319 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5324 aggregate
= rn
->info
;
5325 if (aggregate
->safi
& SAFI_UNICAST
)
5326 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5327 if (aggregate
->safi
& SAFI_MULTICAST
)
5328 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5330 /* Unlock aggregate address configuration. */
5332 bgp_aggregate_free (aggregate
);
5333 bgp_unlock_node (rn
);
5334 bgp_unlock_node (rn
);
5340 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5341 afi_t afi
, safi_t safi
,
5342 u_char summary_only
, u_char as_set
)
5344 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5347 struct bgp_node
*rn
;
5348 struct bgp_aggregate
*aggregate
;
5350 /* Convert string to prefix structure. */
5351 ret
= str2prefix (prefix_str
, &p
);
5354 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5359 /* Old configuration check. */
5360 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5364 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5365 /* try to remove the old entry */
5366 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5369 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5370 bgp_unlock_node (rn
);
5375 /* Make aggregate address structure. */
5376 aggregate
= bgp_aggregate_new ();
5377 aggregate
->summary_only
= summary_only
;
5378 aggregate
->as_set
= as_set
;
5379 aggregate
->safi
= safi
;
5380 rn
->info
= aggregate
;
5382 /* Aggregate address insert into BGP routing table. */
5383 if (safi
& SAFI_UNICAST
)
5384 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5385 if (safi
& SAFI_MULTICAST
)
5386 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5391 DEFUN (aggregate_address
,
5392 aggregate_address_cmd
,
5393 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5394 "Configure BGP aggregate entries\n"
5395 "Aggregate prefix\n"
5396 "Generate AS set path information\n"
5397 "Filter more specific routes from updates\n"
5398 "Filter more specific routes from updates\n"
5399 "Generate AS set path information\n")
5402 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5403 char *prefix
= argv
[idx
]->arg
;
5404 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5406 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5408 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5411 DEFUN (aggregate_address_mask
,
5412 aggregate_address_mask_cmd
,
5413 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5414 "Configure BGP aggregate entries\n"
5415 "Aggregate address\n"
5417 "Generate AS set path information\n"
5418 "Filter more specific routes from updates\n"
5419 "Filter more specific routes from updates\n"
5420 "Generate AS set path information\n")
5423 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5424 char *prefix
= argv
[idx
++]->arg
;
5425 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5426 char *mask
= argv
[idx
]->arg
;
5427 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5429 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5431 char prefix_str
[BUFSIZ
];
5432 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5436 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5440 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5443 DEFUN (no_aggregate_address
,
5444 no_aggregate_address_cmd
,
5445 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5447 "Configure BGP aggregate entries\n"
5448 "Aggregate prefix\n"
5449 "Generate AS set path information\n"
5450 "Filter more specific routes from updates\n"
5451 "Filter more specific routes from updates\n"
5452 "Generate AS set path information\n")
5455 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5456 char *prefix
= argv
[idx
]->arg
;
5457 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5460 DEFUN (no_aggregate_address_mask
,
5461 no_aggregate_address_mask_cmd
,
5462 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5464 "Configure BGP aggregate entries\n"
5465 "Aggregate address\n"
5467 "Generate AS set path information\n"
5468 "Filter more specific routes from updates\n"
5469 "Filter more specific routes from updates\n"
5470 "Generate AS set path information\n")
5473 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5474 char *prefix
= argv
[idx
++]->arg
;
5475 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5476 char *mask
= argv
[idx
]->arg
;
5478 char prefix_str
[BUFSIZ
];
5479 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5483 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5487 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5490 DEFUN (ipv6_aggregate_address
,
5491 ipv6_aggregate_address_cmd
,
5492 "aggregate-address X:X::X:X/M [summary-only]",
5493 "Configure BGP aggregate entries\n"
5494 "Aggregate prefix\n"
5495 "Filter more specific routes from updates\n")
5498 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5499 char *prefix
= argv
[idx
]->arg
;
5500 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5501 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5504 DEFUN (no_ipv6_aggregate_address
,
5505 no_ipv6_aggregate_address_cmd
,
5506 "no 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 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5518 /* Redistribute route treatment. */
5520 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5521 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5522 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5524 struct bgp_info
*new;
5525 struct bgp_info
*bi
;
5526 struct bgp_info info
;
5527 struct bgp_node
*bn
;
5529 struct attr
*new_attr
;
5532 struct bgp_redist
*red
;
5534 /* Make default attribute. */
5535 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5537 attr
.nexthop
= *nexthop
;
5538 attr
.nh_ifindex
= ifindex
;
5542 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5543 extra
->mp_nexthop_global
= *nexthop6
;
5544 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5548 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5549 attr
.extra
->tag
= tag
;
5551 afi
= family2afi (p
->family
);
5553 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5556 struct attr attr_new
;
5557 struct attr_extra extra_new
;
5559 /* Copy attribute for modification. */
5560 attr_new
.extra
= &extra_new
;
5561 bgp_attr_dup (&attr_new
, &attr
);
5563 if (red
->redist_metric_flag
)
5564 attr_new
.med
= red
->redist_metric
;
5566 /* Apply route-map. */
5569 info
.peer
= bgp
->peer_self
;
5570 info
.attr
= &attr_new
;
5572 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5574 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5576 bgp
->peer_self
->rmap_type
= 0;
5578 if (ret
== RMAP_DENYMATCH
)
5580 /* Free uninterned attribute. */
5581 bgp_attr_flush (&attr_new
);
5583 /* Unintern original. */
5584 aspath_unintern (&attr
.aspath
);
5585 bgp_attr_extra_free (&attr
);
5586 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5591 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5592 afi
, SAFI_UNICAST
, p
, NULL
);
5594 new_attr
= bgp_attr_intern (&attr_new
);
5596 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5597 if (bi
->peer
== bgp
->peer_self
5598 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5603 /* Ensure the (source route) type is updated. */
5605 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5606 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5608 bgp_attr_unintern (&new_attr
);
5609 aspath_unintern (&attr
.aspath
);
5610 bgp_attr_extra_free (&attr
);
5611 bgp_unlock_node (bn
);
5616 /* The attribute is changed. */
5617 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5619 /* Rewrite BGP route information. */
5620 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5621 bgp_info_restore(bn
, bi
);
5623 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5624 bgp_attr_unintern (&bi
->attr
);
5625 bi
->attr
= new_attr
;
5626 bi
->uptime
= bgp_clock ();
5628 /* Process change. */
5629 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5630 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5631 bgp_unlock_node (bn
);
5632 aspath_unintern (&attr
.aspath
);
5633 bgp_attr_extra_free (&attr
);
5638 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5640 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5642 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5643 bgp_info_add (bn
, new);
5644 bgp_unlock_node (bn
);
5645 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5648 /* Unintern original. */
5649 aspath_unintern (&attr
.aspath
);
5650 bgp_attr_extra_free (&attr
);
5654 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5657 struct bgp_node
*rn
;
5658 struct bgp_info
*ri
;
5659 struct bgp_redist
*red
;
5661 afi
= family2afi (p
->family
);
5663 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5666 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5668 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5669 if (ri
->peer
== bgp
->peer_self
5670 && ri
->type
== type
)
5675 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5676 bgp_info_delete (rn
, ri
);
5677 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5679 bgp_unlock_node (rn
);
5683 /* Withdraw specified route type's route. */
5685 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5687 struct bgp_node
*rn
;
5688 struct bgp_info
*ri
;
5689 struct bgp_table
*table
;
5691 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5693 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5695 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5696 if (ri
->peer
== bgp
->peer_self
5698 && ri
->instance
== instance
)
5703 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5704 bgp_info_delete (rn
, ri
);
5705 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5710 /* Static function to display route. */
5712 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5715 u_int32_t destination
;
5718 if (p
->family
== AF_INET
)
5720 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5721 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5723 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5724 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5725 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5726 || p
->u
.prefix4
.s_addr
== 0)
5728 /* When mask is natural, mask is not displayed. */
5731 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5734 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5739 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5741 vty_out (vty
, "%*s", len
, " ");
5744 enum bgp_display_type
5749 /* Print the short form route status for a bgp_info */
5751 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5752 json_object
*json_path
)
5757 /* Route status display. */
5758 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5759 json_object_boolean_true_add(json_path
, "removed");
5761 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5762 json_object_boolean_true_add(json_path
, "stale");
5764 if (binfo
->extra
&& binfo
->extra
->suppress
)
5765 json_object_boolean_true_add(json_path
, "suppressed");
5767 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5768 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5769 json_object_boolean_true_add(json_path
, "valid");
5772 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5773 json_object_boolean_true_add(json_path
, "history");
5775 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5776 json_object_boolean_true_add(json_path
, "damped");
5778 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5779 json_object_boolean_true_add(json_path
, "bestpath");
5781 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5782 json_object_boolean_true_add(json_path
, "multipath");
5784 /* Internal route. */
5785 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5786 json_object_string_add(json_path
, "pathFrom", "internal");
5788 json_object_string_add(json_path
, "pathFrom", "external");
5793 /* Route status display. */
5794 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5796 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5798 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5800 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5801 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5807 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5809 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5811 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5813 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5818 /* Internal route. */
5819 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5825 /* called from terminal list command */
5827 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5828 struct bgp_info
*binfo
, int display
, safi_t safi
,
5829 json_object
*json_paths
)
5832 json_object
*json_path
= NULL
;
5833 json_object
*json_nexthops
= NULL
;
5834 json_object
*json_nexthop_global
= NULL
;
5835 json_object
*json_nexthop_ll
= NULL
;
5838 json_path
= json_object_new_object();
5840 /* short status lead text */
5841 route_vty_short_status_out (vty
, binfo
, json_path
);
5845 /* print prefix and mask */
5847 route_vty_out_route (p
, vty
);
5849 vty_out (vty
, "%*s", 17, " ");
5852 /* Print attribute */
5857 * For ENCAP routes, nexthop address family is not
5858 * neccessarily the same as the prefix address family.
5859 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
5861 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
))
5866 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
5871 vty_out (vty
, "%s", inet_ntop(af
,
5872 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
5875 vty_out (vty
, "%s", inet_ntop(af
,
5876 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
5887 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5891 json_nexthop_global
= json_object_new_object();
5893 if (safi
== SAFI_MPLS_VPN
)
5894 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5896 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
5898 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
5899 json_object_boolean_true_add(json_nexthop_global
, "used");
5903 if (safi
== SAFI_MPLS_VPN
)
5904 vty_out (vty
, "%-16s",
5905 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5907 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
5912 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5919 json_nexthop_global
= json_object_new_object();
5920 json_object_string_add(json_nexthop_global
, "ip",
5921 inet_ntop (AF_INET6
,
5922 &attr
->extra
->mp_nexthop_global
,
5924 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
5925 json_object_string_add(json_nexthop_global
, "scope", "global");
5927 /* We display both LL & GL if both have been received */
5928 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
5930 json_nexthop_ll
= json_object_new_object();
5931 json_object_string_add(json_nexthop_ll
, "ip",
5932 inet_ntop (AF_INET6
,
5933 &attr
->extra
->mp_nexthop_local
,
5935 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
5936 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
5938 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
5939 &attr
->extra
->mp_nexthop_local
) != 0) &&
5940 !attr
->extra
->mp_nexthop_prefer_global
)
5941 json_object_boolean_true_add(json_nexthop_ll
, "used");
5943 json_object_boolean_true_add(json_nexthop_global
, "used");
5946 json_object_boolean_true_add(json_nexthop_global
, "used");
5950 /* Display LL if LL/Global both in table unless prefer-global is set */
5951 if (((attr
->extra
->mp_nexthop_len
== 32) &&
5952 !attr
->extra
->mp_nexthop_prefer_global
) ||
5953 (binfo
->peer
->conf_if
))
5955 if (binfo
->peer
->conf_if
)
5957 len
= vty_out (vty
, "%s",
5958 binfo
->peer
->conf_if
);
5959 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
5962 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
5964 vty_out (vty
, "%*s", len
, " ");
5968 len
= vty_out (vty
, "%s",
5969 inet_ntop (AF_INET6
,
5970 &attr
->extra
->mp_nexthop_local
,
5975 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
5977 vty_out (vty
, "%*s", len
, " ");
5982 len
= vty_out (vty
, "%s",
5983 inet_ntop (AF_INET6
,
5984 &attr
->extra
->mp_nexthop_global
,
5989 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
5991 vty_out (vty
, "%*s", len
, " ");
5997 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
5999 json_object_int_add(json_path
, "med", attr
->med
);
6001 vty_out (vty
, "%10u", attr
->med
);
6007 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6009 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6011 vty_out (vty
, "%7u", attr
->local_pref
);
6019 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6021 json_object_int_add(json_path
, "weight", 0);
6024 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6028 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6035 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6037 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6042 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6044 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6049 json_object_string_add(json_path
, "alert", "No attributes");
6051 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6056 if (json_nexthop_global
|| json_nexthop_ll
)
6058 json_nexthops
= json_object_new_array();
6060 if (json_nexthop_global
)
6061 json_object_array_add(json_nexthops
, json_nexthop_global
);
6063 if (json_nexthop_ll
)
6064 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6066 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6069 json_object_array_add(json_paths
, json_path
);
6073 vty_out (vty
, "%s", VTY_NEWLINE
);
6075 /* prints an additional line, indented, with VNC info, if present */
6076 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6077 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6082 /* called from terminal list command */
6084 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6085 u_char use_json
, json_object
*json_ar
)
6087 json_object
*json_status
= NULL
;
6088 json_object
*json_net
= NULL
;
6090 /* Route status display. */
6093 json_status
= json_object_new_object();
6094 json_net
= json_object_new_object();
6103 /* print prefix and mask */
6105 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6107 route_vty_out_route (p
, vty
);
6109 /* Print attribute */
6114 if (p
->family
== AF_INET
&&
6115 (safi
== SAFI_MPLS_VPN
||
6116 safi
== SAFI_ENCAP
||
6117 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6119 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6120 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6122 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6124 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6128 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6132 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6133 json_object_int_add(json_net
, "metric", attr
->med
);
6135 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6136 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6139 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6141 json_object_int_add(json_net
, "weight", 0);
6145 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6148 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6152 if (p
->family
== AF_INET
&&
6153 (safi
== SAFI_MPLS_VPN
||
6154 safi
== SAFI_ENCAP
||
6155 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6157 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6158 vty_out (vty
, "%-16s",
6159 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6161 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6163 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6168 assert (attr
->extra
);
6170 len
= vty_out (vty
, "%s",
6171 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6175 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6177 vty_out (vty
, "%*s", len
, " ");
6179 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6180 vty_out (vty
, "%10u", attr
->med
);
6184 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6185 vty_out (vty
, "%7u", attr
->local_pref
);
6189 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6193 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6196 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6201 json_object_boolean_true_add(json_status
, "*");
6202 json_object_boolean_true_add(json_status
, ">");
6203 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6204 char buf_cut
[BUFSIZ
];
6205 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6208 vty_out (vty
, "%s", VTY_NEWLINE
);
6212 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6213 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6215 json_object
*json_out
= NULL
;
6217 u_int32_t label
= 0;
6223 json_out
= json_object_new_object();
6225 /* short status lead text */
6226 route_vty_short_status_out (vty
, binfo
, json_out
);
6228 /* print prefix and mask */
6232 route_vty_out_route (p
, vty
);
6234 vty_out (vty
, "%*s", 17, " ");
6237 /* Print attribute */
6241 if (p
->family
== AF_INET
6242 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6244 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6247 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6249 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6254 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6256 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6259 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6261 assert (attr
->extra
);
6265 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6268 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6269 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6272 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6275 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6279 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6281 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6283 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6284 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6287 vty_out (vty
, "%s(%s)",
6288 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6290 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6297 label
= decode_label (binfo
->extra
->tag
);
6302 json_object_int_add(json_out
, "notag", label
);
6303 json_object_array_add(json
, json_out
);
6307 vty_out (vty
, "notag/%d", label
);
6308 vty_out (vty
, "%s", VTY_NEWLINE
);
6312 /* dampening route */
6314 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6315 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6319 char timebuf
[BGP_UPTIME_LEN
];
6321 /* short status lead text */
6322 route_vty_short_status_out (vty
, binfo
, json
);
6324 /* print prefix and mask */
6328 route_vty_out_route (p
, vty
);
6330 vty_out (vty
, "%*s", 17, " ");
6333 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6338 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6343 json_object_int_add(json
, "peerHost", len
);
6345 vty_out (vty
, "%*s", len
, " ");
6349 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6351 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6353 /* Print attribute */
6361 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6363 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6368 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6370 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6373 vty_out (vty
, "%s", VTY_NEWLINE
);
6378 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6379 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6382 struct bgp_damp_info
*bdi
;
6383 char timebuf
[BGP_UPTIME_LEN
];
6389 bdi
= binfo
->extra
->damp_info
;
6391 /* short status lead text */
6392 route_vty_short_status_out (vty
, binfo
, json
);
6394 /* print prefix and mask */
6398 route_vty_out_route (p
, vty
);
6400 vty_out (vty
, "%*s", 17, " ");
6403 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6408 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6413 json_object_int_add(json
, "peerHost", len
);
6415 vty_out (vty
, "%*s", len
, " ");
6418 len
= vty_out (vty
, "%d", bdi
->flap
);
6428 json_object_int_add(json
, "bdiFlap", len
);
6430 vty_out (vty
, "%*s", len
, " ");
6434 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6436 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6437 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6439 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6440 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6443 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6445 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6450 vty_out (vty
, "%*s ", 8, " ");
6453 /* Print attribute */
6461 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6463 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6468 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6470 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6473 vty_out (vty
, "%s", VTY_NEWLINE
);
6477 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6478 const char *header
, json_object
*json_adv_to
)
6480 char buf1
[INET6_ADDRSTRLEN
];
6481 json_object
*json_peer
= NULL
;
6485 /* 'advertised-to' is a dictionary of peers we have advertised this
6486 * prefix too. The key is the peer's IP or swpX, the value is the
6487 * hostname if we know it and "" if not.
6489 json_peer
= json_object_new_object();
6492 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6495 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6497 json_object_object_add(json_adv_to
,
6498 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6505 vty_out (vty
, "%s", header
);
6509 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6512 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6514 vty_out (vty
, " %s(%s)", peer
->hostname
,
6515 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6520 vty_out (vty
, " %s", peer
->conf_if
);
6522 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6528 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6529 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6530 json_object
*json_paths
)
6532 char buf
[INET6_ADDRSTRLEN
];
6535 int sockunion_vty_out (struct vty
*, union sockunion
*);
6537 json_object
*json_bestpath
= NULL
;
6538 json_object
*json_cluster_list
= NULL
;
6539 json_object
*json_cluster_list_list
= NULL
;
6540 json_object
*json_ext_community
= NULL
;
6541 json_object
*json_last_update
= NULL
;
6542 json_object
*json_nexthop_global
= NULL
;
6543 json_object
*json_nexthop_ll
= NULL
;
6544 json_object
*json_nexthops
= NULL
;
6545 json_object
*json_path
= NULL
;
6546 json_object
*json_peer
= NULL
;
6547 json_object
*json_string
= NULL
;
6548 json_object
*json_adv_to
= NULL
;
6550 struct listnode
*node
, *nnode
;
6552 int addpath_capable
;
6554 unsigned int first_as
;
6558 json_path
= json_object_new_object();
6559 json_peer
= json_object_new_object();
6560 json_nexthop_global
= json_object_new_object();
6567 /* Line1 display AS-path, Aggregator */
6572 json_object_lock(attr
->aspath
->json
);
6573 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6577 if (attr
->aspath
->segments
)
6578 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6580 vty_out (vty
, " Local");
6584 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6587 json_object_boolean_true_add(json_path
, "removed");
6589 vty_out (vty
, ", (removed)");
6592 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6595 json_object_boolean_true_add(json_path
, "stale");
6597 vty_out (vty
, ", (stale)");
6600 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6604 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6605 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6609 vty_out (vty
, ", (aggregated by %u %s)",
6610 attr
->extra
->aggregator_as
,
6611 inet_ntoa (attr
->extra
->aggregator_addr
));
6615 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6618 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6620 vty_out (vty
, ", (Received from a RR-client)");
6623 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6626 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6628 vty_out (vty
, ", (Received from a RS-client)");
6631 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6634 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6636 vty_out (vty
, ", (history entry)");
6638 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6641 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6643 vty_out (vty
, ", (suppressed due to dampening)");
6647 vty_out (vty
, "%s", VTY_NEWLINE
);
6649 /* Line2 display Next-hop, Neighbor, Router-id */
6650 /* Display the nexthop */
6651 if (p
->family
== AF_INET
&&
6652 (safi
== SAFI_MPLS_VPN
||
6653 safi
== SAFI_ENCAP
||
6654 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6656 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6659 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6661 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6666 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6668 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6672 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6676 assert (attr
->extra
);
6679 json_object_string_add(json_nexthop_global
, "ip",
6680 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6681 buf
, INET6_ADDRSTRLEN
));
6682 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6683 json_object_string_add(json_nexthop_global
, "scope", "global");
6687 vty_out (vty
, " %s",
6688 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6689 buf
, INET6_ADDRSTRLEN
));
6693 /* Display the IGP cost or 'inaccessible' */
6694 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6697 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6699 vty_out (vty
, " (inaccessible)");
6703 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6706 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6708 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6711 /* IGP cost is 0, display this only for json */
6715 json_object_int_add(json_nexthop_global
, "metric", 0);
6719 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6722 /* Display peer "from" output */
6723 /* This path was originated locally */
6724 if (binfo
->peer
== bgp
->peer_self
)
6727 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6730 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6732 vty_out (vty
, " from 0.0.0.0 ");
6737 json_object_string_add(json_peer
, "peerId", "::");
6739 vty_out (vty
, " from :: ");
6743 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6745 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
6748 /* We RXed this path from one of our peers */
6754 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6755 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6757 if (binfo
->peer
->hostname
)
6758 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
6760 if (binfo
->peer
->domainname
)
6761 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
6763 if (binfo
->peer
->conf_if
)
6764 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
6768 if (binfo
->peer
->conf_if
)
6770 if (binfo
->peer
->hostname
&&
6771 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6772 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6773 binfo
->peer
->conf_if
);
6775 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
6779 if (binfo
->peer
->hostname
&&
6780 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6781 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6784 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6787 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
6788 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
6790 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6795 vty_out (vty
, "%s", VTY_NEWLINE
);
6797 /* display the link-local nexthop */
6798 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6802 json_nexthop_ll
= json_object_new_object();
6803 json_object_string_add(json_nexthop_ll
, "ip",
6804 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6805 buf
, INET6_ADDRSTRLEN
));
6806 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6807 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6809 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
6811 if (!attr
->extra
->mp_nexthop_prefer_global
)
6812 json_object_boolean_true_add(json_nexthop_ll
, "used");
6814 json_object_boolean_true_add(json_nexthop_global
, "used");
6818 vty_out (vty
, " (%s) %s%s",
6819 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6820 buf
, INET6_ADDRSTRLEN
),
6821 attr
->extra
->mp_nexthop_prefer_global
?
6822 "(prefer-global)" : "(used)",
6826 /* If we do not have a link-local nexthop then we must flag the global as "used" */
6830 json_object_boolean_true_add(json_nexthop_global
, "used");
6833 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
6835 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6837 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
6839 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6842 json_object_int_add(json_path
, "med", attr
->med
);
6844 vty_out (vty
, ", metric %u", attr
->med
);
6847 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6850 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6852 vty_out (vty
, ", localpref %u", attr
->local_pref
);
6857 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
6859 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
6862 if (attr
->extra
&& attr
->extra
->weight
!= 0)
6865 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6867 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
6870 if (attr
->extra
&& attr
->extra
->tag
!= 0)
6873 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
6875 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
6878 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6881 json_object_boolean_false_add(json_path
, "valid");
6883 vty_out (vty
, ", invalid");
6885 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6888 json_object_boolean_true_add(json_path
, "valid");
6890 vty_out (vty
, ", valid");
6893 if (binfo
->peer
!= bgp
->peer_self
)
6895 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
6897 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
6900 json_object_string_add(json_peer
, "type", "confed-internal");
6902 vty_out (vty
, ", confed-internal");
6907 json_object_string_add(json_peer
, "type", "internal");
6909 vty_out (vty
, ", internal");
6914 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
6917 json_object_string_add(json_peer
, "type", "confed-external");
6919 vty_out (vty
, ", confed-external");
6924 json_object_string_add(json_peer
, "type", "external");
6926 vty_out (vty
, ", external");
6930 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
6934 json_object_boolean_true_add(json_path
, "aggregated");
6935 json_object_boolean_true_add(json_path
, "local");
6939 vty_out (vty
, ", aggregated, local");
6942 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
6945 json_object_boolean_true_add(json_path
, "sourced");
6947 vty_out (vty
, ", sourced");
6953 json_object_boolean_true_add(json_path
, "sourced");
6954 json_object_boolean_true_add(json_path
, "local");
6958 vty_out (vty
, ", sourced, local");
6962 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
6965 json_object_boolean_true_add(json_path
, "atomicAggregate");
6967 vty_out (vty
, ", atomic-aggregate");
6970 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
6971 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
6972 bgp_info_mpath_count (binfo
)))
6975 json_object_boolean_true_add(json_path
, "multipath");
6977 vty_out (vty
, ", multipath");
6980 // Mark the bestpath(s)
6981 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
6983 first_as
= aspath_get_first_as(attr
->aspath
);
6988 json_bestpath
= json_object_new_object();
6989 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
6994 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
6996 vty_out (vty
, ", bestpath-from-AS Local");
7000 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7005 json_bestpath
= json_object_new_object();
7006 json_object_boolean_true_add(json_bestpath
, "overall");
7009 vty_out (vty
, ", best");
7013 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7016 vty_out (vty
, "%s", VTY_NEWLINE
);
7018 /* Line 4 display Community */
7019 if (attr
->community
)
7023 json_object_lock(attr
->community
->json
);
7024 json_object_object_add(json_path
, "community", attr
->community
->json
);
7028 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7033 /* Line 5 display Extended-community */
7034 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7038 json_ext_community
= json_object_new_object();
7039 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7040 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7044 vty_out (vty
, " Extended Community: %s%s",
7045 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7049 /* Line 6 display Originator, Cluster-id */
7050 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7051 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7053 assert (attr
->extra
);
7054 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7057 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7059 vty_out (vty
, " Originator: %s",
7060 inet_ntoa (attr
->extra
->originator_id
));
7063 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7069 json_cluster_list
= json_object_new_object();
7070 json_cluster_list_list
= json_object_new_array();
7072 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7074 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7075 json_object_array_add(json_cluster_list_list
, json_string
);
7078 /* struct cluster_list does not have "str" variable like
7079 * aspath and community do. Add this someday if someone
7081 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7083 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7084 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7088 vty_out (vty
, ", Cluster list: ");
7090 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7092 vty_out (vty
, "%s ",
7093 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7099 vty_out (vty
, "%s", VTY_NEWLINE
);
7102 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7103 bgp_damp_info_vty (vty
, binfo
, json_path
);
7105 /* Line 7 display Addpath IDs */
7106 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7110 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7111 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7115 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7116 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7121 /* If we used addpath to TX a non-bestpath we need to display
7122 * "Advertised to" on a path-by-path basis */
7123 if (bgp
->addpath_tx_used
[afi
][safi
])
7127 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7129 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7130 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7132 if ((addpath_capable
&& has_adj
) ||
7133 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7135 if (json_path
&& !json_adv_to
)
7136 json_adv_to
= json_object_new_object();
7138 route_vty_out_advertised_to(vty
, peer
, &first
,
7148 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7155 vty_out (vty
, "%s", VTY_NEWLINE
);
7160 /* Line 8 display Uptime */
7161 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7164 json_last_update
= json_object_new_object();
7165 json_object_int_add(json_last_update
, "epoch", tbuf
);
7166 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7167 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7170 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7173 /* We've constructed the json object for this path, add it to the json
7178 if (json_nexthop_global
|| json_nexthop_ll
)
7180 json_nexthops
= json_object_new_array();
7182 if (json_nexthop_global
)
7183 json_object_array_add(json_nexthops
, json_nexthop_global
);
7185 if (json_nexthop_ll
)
7186 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7188 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7191 json_object_object_add(json_path
, "peer", json_peer
);
7192 json_object_array_add(json_paths
, json_path
);
7195 vty_out (vty
, "%s", VTY_NEWLINE
);
7198 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7199 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7200 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7204 bgp_show_type_normal
,
7205 bgp_show_type_regexp
,
7206 bgp_show_type_prefix_list
,
7207 bgp_show_type_filter_list
,
7208 bgp_show_type_route_map
,
7209 bgp_show_type_neighbor
,
7210 bgp_show_type_cidr_only
,
7211 bgp_show_type_prefix_longer
,
7212 bgp_show_type_community_all
,
7213 bgp_show_type_community
,
7214 bgp_show_type_community_exact
,
7215 bgp_show_type_community_list
,
7216 bgp_show_type_community_list_exact
,
7217 bgp_show_type_flap_statistics
,
7218 bgp_show_type_flap_neighbor
,
7219 bgp_show_type_dampend_paths
,
7220 bgp_show_type_damp_neighbor
7224 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
7225 const char *prefix_list_str
, afi_t afi
,
7226 safi_t safi
, enum bgp_show_type type
);
7228 bgp_show_filter_list (struct vty
*vty
, const char *name
,
7229 const char *filter
, afi_t afi
,
7230 safi_t safi
, enum bgp_show_type type
);
7232 bgp_show_route_map (struct vty
*vty
, const char *name
,
7233 const char *rmap_str
, afi_t afi
,
7234 safi_t safi
, enum bgp_show_type type
);
7236 bgp_show_community_list (struct vty
*vty
, const char *name
,
7237 const char *com
, int exact
,
7238 afi_t afi
, safi_t safi
);
7240 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
7241 const char *prefix
, afi_t afi
,
7242 safi_t safi
, enum bgp_show_type type
);
7244 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7245 safi_t safi
, enum bgp_show_type type
);
7247 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
7248 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7251 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7252 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7254 struct bgp_info
*ri
;
7255 struct bgp_node
*rn
;
7258 unsigned long output_count
;
7259 unsigned long total_count
;
7263 json_object
*json_paths
= NULL
;
7268 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7269 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7270 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7271 table
->version
, inet_ntoa (bgp
->router_id
));
7272 json_paths
= json_object_new_object();
7275 /* This is first entry point, so reset total line. */
7279 /* Start processing of routes. */
7280 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7281 if (rn
->info
!= NULL
)
7284 if (!first
&& use_json
)
7289 json_paths
= json_object_new_array();
7293 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7296 if (type
== bgp_show_type_flap_statistics
7297 || type
== bgp_show_type_flap_neighbor
7298 || type
== bgp_show_type_dampend_paths
7299 || type
== bgp_show_type_damp_neighbor
)
7301 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7304 if (type
== bgp_show_type_regexp
)
7306 regex_t
*regex
= output_arg
;
7308 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7311 if (type
== bgp_show_type_prefix_list
)
7313 struct prefix_list
*plist
= output_arg
;
7315 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7318 if (type
== bgp_show_type_filter_list
)
7320 struct as_list
*as_list
= output_arg
;
7322 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7325 if (type
== bgp_show_type_route_map
)
7327 struct route_map
*rmap
= output_arg
;
7328 struct bgp_info binfo
;
7329 struct attr dummy_attr
;
7330 struct attr_extra dummy_extra
;
7333 dummy_attr
.extra
= &dummy_extra
;
7334 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7336 binfo
.peer
= ri
->peer
;
7337 binfo
.attr
= &dummy_attr
;
7339 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7340 if (ret
== RMAP_DENYMATCH
)
7343 if (type
== bgp_show_type_neighbor
7344 || type
== bgp_show_type_flap_neighbor
7345 || type
== bgp_show_type_damp_neighbor
)
7347 union sockunion
*su
= output_arg
;
7349 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7352 if (type
== bgp_show_type_cidr_only
)
7354 u_int32_t destination
;
7356 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7357 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7359 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7361 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7364 if (type
== bgp_show_type_prefix_longer
)
7366 struct prefix
*p
= output_arg
;
7368 if (! prefix_match (p
, &rn
->p
))
7371 if (type
== bgp_show_type_community_all
)
7373 if (! ri
->attr
->community
)
7376 if (type
== bgp_show_type_community
)
7378 struct community
*com
= output_arg
;
7380 if (! ri
->attr
->community
||
7381 ! community_match (ri
->attr
->community
, com
))
7384 if (type
== bgp_show_type_community_exact
)
7386 struct community
*com
= output_arg
;
7388 if (! ri
->attr
->community
||
7389 ! community_cmp (ri
->attr
->community
, com
))
7392 if (type
== bgp_show_type_community_list
)
7394 struct community_list
*list
= output_arg
;
7396 if (! community_list_match (ri
->attr
->community
, list
))
7399 if (type
== bgp_show_type_community_list_exact
)
7401 struct community_list
*list
= output_arg
;
7403 if (! community_list_exact_match (ri
->attr
->community
, list
))
7406 if (type
== bgp_show_type_dampend_paths
7407 || type
== bgp_show_type_damp_neighbor
)
7409 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7410 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7414 if (!use_json
&& header
)
7416 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7417 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7418 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7419 if (type
== bgp_show_type_dampend_paths
7420 || type
== bgp_show_type_damp_neighbor
)
7421 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7422 else if (type
== bgp_show_type_flap_statistics
7423 || type
== bgp_show_type_flap_neighbor
)
7424 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7426 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7430 if (type
== bgp_show_type_dampend_paths
7431 || type
== bgp_show_type_damp_neighbor
)
7432 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7433 else if (type
== bgp_show_type_flap_statistics
7434 || type
== bgp_show_type_flap_neighbor
)
7435 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7437 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7447 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7448 vty_out (vty
, "\"%s\": ", buf2
);
7449 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7450 json_object_free (json_paths
);
7459 json_object_free (json_paths
);
7460 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7464 /* No route is displayed */
7465 if (output_count
== 0)
7467 if (type
== bgp_show_type_normal
)
7468 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7471 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7472 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7479 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7480 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7482 struct bgp_table
*table
;
7486 bgp
= bgp_get_default ();
7492 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7496 table
= bgp
->rib
[afi
][safi
];
7498 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7503 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7506 struct listnode
*node
, *nnode
;
7508 struct bgp_table
*table
;
7512 vty_out (vty
, "{%s", VTY_NEWLINE
);
7514 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7519 vty_out (vty
, ",%s", VTY_NEWLINE
);
7523 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7524 ? "Default" : bgp
->name
);
7528 vty_out (vty
, "%sInstance %s:%s",
7530 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7531 ? "Default" : bgp
->name
,
7534 table
= bgp
->rib
[afi
][safi
];
7535 bgp_show_table (vty
, bgp
, table
,
7536 bgp_show_type_normal
, NULL
, use_json
);
7541 vty_out (vty
, "}%s", VTY_NEWLINE
);
7544 /* Header of detailed BGP route information */
7546 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7547 struct bgp_node
*rn
,
7548 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7551 struct bgp_info
*ri
;
7554 struct listnode
*node
, *nnode
;
7555 char buf1
[INET6_ADDRSTRLEN
];
7556 char buf2
[INET6_ADDRSTRLEN
];
7561 int no_advertise
= 0;
7564 json_object
*json_adv_to
= NULL
;
7570 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7571 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7575 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7576 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
) ?
7577 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7578 safi
== SAFI_MPLS_VPN
? ":" : "",
7579 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
7580 p
->prefixlen
, VTY_NEWLINE
);
7583 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7586 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7589 if (ri
->extra
&& ri
->extra
->suppress
)
7591 if (ri
->attr
->community
!= NULL
)
7593 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7595 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7597 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7605 vty_out (vty
, "Paths: (%d available", count
);
7608 vty_out (vty
, ", best #%d", best
);
7609 if (safi
== SAFI_UNICAST
)
7610 vty_out (vty
, ", table %s",
7611 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7612 ? "Default-IP-Routing-Table" : bgp
->name
);
7615 vty_out (vty
, ", no best path");
7618 vty_out (vty
, ", not advertised to any peer");
7620 vty_out (vty
, ", not advertised to EBGP peer");
7622 vty_out (vty
, ", not advertised outside local AS");
7625 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7626 vty_out (vty
, ")%s", VTY_NEWLINE
);
7629 /* If we are not using addpath then we can display Advertised to and that will
7630 * show what peers we advertised the bestpath to. If we are using addpath
7631 * though then we must display Advertised to on a path-by-path basis. */
7632 if (!bgp
->addpath_tx_used
[afi
][safi
])
7634 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7636 if (bgp_adj_out_lookup (peer
, rn
, 0))
7638 if (json
&& !json_adv_to
)
7639 json_adv_to
= json_object_new_object();
7641 route_vty_out_advertised_to(vty
, peer
, &first
,
7642 " Advertised to non peer-group peers:\n ",
7651 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7657 vty_out (vty
, " Not advertised to any peer");
7658 vty_out (vty
, "%s", VTY_NEWLINE
);
7663 /* Display specified route of BGP table. */
7665 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7666 struct bgp_table
*rib
, const char *ip_str
,
7667 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7668 int prefix_check
, enum bgp_path_type pathtype
,
7674 struct prefix match
;
7675 struct bgp_node
*rn
;
7676 struct bgp_node
*rm
;
7677 struct bgp_info
*ri
;
7678 struct bgp_table
*table
;
7679 json_object
*json
= NULL
;
7680 json_object
*json_paths
= NULL
;
7682 /* Check IP address argument. */
7683 ret
= str2prefix (ip_str
, &match
);
7686 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7690 match
.family
= afi2family (afi
);
7694 json
= json_object_new_object();
7695 json_paths
= json_object_new_array();
7698 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
7700 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7702 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7705 if ((table
= rn
->info
) != NULL
)
7709 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7711 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7713 bgp_unlock_node (rm
);
7717 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7721 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7722 AFI_IP
, safi
, json
);
7727 if (pathtype
== BGP_PATH_ALL
||
7728 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7729 (pathtype
== BGP_PATH_MULTIPATH
&&
7730 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7731 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
7734 bgp_unlock_node (rm
);
7743 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
7745 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
7747 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7751 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
7756 if (pathtype
== BGP_PATH_ALL
||
7757 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7758 (pathtype
== BGP_PATH_MULTIPATH
&&
7759 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7760 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
7764 bgp_unlock_node (rn
);
7771 json_object_object_add(json
, "paths", json_paths
);
7773 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
7774 json_object_free(json
);
7780 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
7788 /* Display specified route of Main RIB */
7790 bgp_show_route (struct vty
*vty
, const char *view_name
, const char *ip_str
,
7791 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7792 int prefix_check
, enum bgp_path_type pathtype
,
7797 /* BGP structure lookup. */
7800 bgp
= bgp_lookup_by_name (view_name
);
7803 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
7809 bgp
= bgp_get_default ();
7812 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7817 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
7818 afi
, safi
, prd
, prefix_check
, pathtype
,
7822 /* BGP route print out function. */
7823 DEFUN (show_ip_bgp_ipv4
,
7824 show_ip_bgp_ipv4_cmd
,
7825 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]]\
7828 |dampening <flap-statistics|dampened-paths|parameters>\
7832 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
7833 |community-list <(1-500)|WORD> [exact-match]\
7834 |A.B.C.D/M longer-prefixes\
7835 |X:X::X:X/M longer-prefixes\
7841 BGP_INSTANCE_HELP_STR
7843 "Address Family modifier\n"
7844 "Address Family modifier\n"
7845 "Address Family modifier\n"
7846 "Address Family modifier\n"
7848 "Address Family modifier\n"
7849 "Address Family modifier\n"
7850 "Address Family modifier\n"
7851 "Address Family modifier\n"
7852 "Display only routes with non-natural netmasks\n"
7853 "Display detailed information about dampening\n"
7854 "Display flap statistics of routes\n"
7855 "Display paths suppressed due to dampening\n"
7856 "Display dampening parameters\n"
7857 "Display routes matching the route-map\n"
7858 "A route-map to match on\n"
7859 "Display routes conforming to the prefix-list\n"
7860 "Prefix-list name\n"
7861 "Display routes conforming to the filter-list\n"
7862 "Regular expression access list name\n"
7863 "Display routes matching the communities\n"
7865 "Do not send outside local AS (well-known community)\n"
7866 "Do not advertise to any peer (well-known community)\n"
7867 "Do not export to next AS (well-known community)\n"
7868 "Exact match of the communities\n"
7869 "Display routes matching the community-list\n"
7870 "community-list number\n"
7871 "community-list name\n"
7872 "Exact match of the communities\n"
7874 "Display route and more specific routes\n"
7876 "Display route and more specific routes\n"
7880 afi_t afi
= AFI_IP6
;
7881 safi_t safi
= SAFI_UNICAST
;
7882 int exact_match
= 0;
7883 enum bgp_show_type sh_type
= bgp_show_type_normal
;
7887 if (argv_find (argv
, argc
, "ip", &idx
))
7889 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
7890 vrf
= argv
[++idx
]->arg
;
7891 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
7893 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
7894 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
7895 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
7897 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
7900 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
7901 // advance idx if necessary
7902 argv_find (argv
, argc
, "unicast", &idx
);
7905 int uj
= use_json (argc
, argv
);
7908 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
7911 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
7917 if (strmatch(argv
[idx
]->text
, "cidr-only"))
7918 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
7920 else if (strmatch(argv
[idx
]->text
, "dampening"))
7922 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
7923 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
7924 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
7925 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
7926 else if (argv_find (argv
, argc
, "parameters", &idx
))
7927 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
7930 else if (strmatch(argv
[idx
]->text
, "prefix-list"))
7931 return bgp_show_prefix_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
7933 else if (strmatch(argv
[idx
]->text
, "filter-list"))
7934 return bgp_show_filter_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
7936 else if (strmatch(argv
[idx
]->text
, "route-map"))
7937 return bgp_show_route_map (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
7939 else if (strmatch(argv
[idx
]->text
, "community"))
7941 /* show a specific community */
7942 if (argv
[idx
+ 1]->type
== VARIABLE_TKN
||
7943 strmatch(argv
[idx
+ 1]->text
, "local-AS") ||
7944 strmatch(argv
[idx
+ 1]->text
, "no-advertise") ||
7945 strmatch(argv
[idx
+ 1]->text
, "no-export"))
7947 if (strmatch(argv
[idx
+ 2]->text
, "exact_match"))
7949 return bgp_show_community (vty
, vrf
, argc
, argv
, exact_match
, afi
, safi
);
7951 /* show all communities */
7953 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
7955 else if (strmatch(argv
[idx
]->text
, "community-list"))
7957 const char *clist_number_or_name
= argv
[++idx
]->arg
;
7958 if (++idx
< argc
&& strmatch (argv
[idx
]->arg
, "exact-match"))
7960 return bgp_show_community_list (vty
, vrf
, clist_number_or_name
, exact_match
, afi
, safi
);
7963 else if (argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV6_TKN
)
7964 return bgp_show_prefix_longer (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
7967 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
7970 DEFUN (show_ip_bgp_route
,
7971 show_ip_bgp_route_cmd
,
7972 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]]"
7973 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
7977 BGP_INSTANCE_HELP_STR
7979 "Address Family modifier\n"
7980 "Address Family modifier\n"
7981 "Address Family modifier\n"
7982 "Address Family modifier\n"
7984 "Address Family modifier\n"
7985 "Address Family modifier\n"
7986 "Address Family modifier\n"
7987 "Address Family modifier\n"
7988 "Network in the BGP routing table to display\n"
7990 "Network in the BGP routing table to display\n"
7992 "Display only the bestpath\n"
7993 "Display only multipaths\n"
7996 int prefix_check
= 0;
7998 afi_t afi
= AFI_IP6
;
7999 safi_t safi
= SAFI_UNICAST
;
8001 char *prefix
= NULL
;
8003 enum bgp_path_type path_type
;
8004 u_char uj
= use_json(argc
, argv
);
8009 if (argv_find (argv
, argc
, "ip", &idx
))
8011 /* [<view|vrf> WORD] */
8012 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8013 vrf
= argv
[++idx
]->arg
;
8014 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8015 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8017 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8018 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8019 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8021 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8024 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8025 // advance idx if necessary
8026 argv_find (argv
, argc
, "unicast", &idx
);
8029 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8030 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8032 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8035 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8037 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8040 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8042 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8046 prefix
= argv
[idx
]->arg
;
8048 /* [<bestpath|multipath>] */
8049 if (argv_find (argv
, argc
, "bestpath", &idx
))
8050 path_type
= BGP_PATH_BESTPATH
;
8051 else if (argv_find (argv
, argc
, "multipath", &idx
))
8052 path_type
= BGP_PATH_MULTIPATH
;
8054 path_type
= BGP_PATH_ALL
;
8056 return bgp_show_route (vty
, vrf
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8059 DEFUN (show_ip_bgp_regexp
,
8060 show_ip_bgp_regexp_cmd
,
8061 "show [ip] bgp [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]|encap [unicast]|vpnv4 [unicast]>] regexp REGEX...",
8066 "Address Family modifier\n"
8067 "Address Family modifier\n"
8068 "Address Family modifier\n"
8069 "Address Family modifier\n"
8071 "Address Family modifier\n"
8072 "Address Family modifier\n"
8073 "Address Family modifier\n"
8074 "Address Family modifier\n"
8076 "Address Family modifier\n"
8078 "Address Family modifier\n"
8079 "Display routes matching the AS path regular expression\n"
8080 "A regular-expression to match the BGP AS paths\n")
8082 afi_t afi
= AFI_IP6
;
8083 safi_t safi
= SAFI_UNICAST
;
8087 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8088 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8090 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8091 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8092 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8094 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8097 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8098 // advance idx if necessary
8099 argv_find (argv
, argc
, "unicast", &idx
);
8102 // get index of regex
8103 argv_find (argv
, argc
, "regexp", &idx
);
8106 char *regstr
= argv_concat (argv
, argc
, idx
);
8107 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8108 XFREE (MTYPE_TMP
, regstr
);
8112 DEFUN (show_ip_bgp_instance_all
,
8113 show_ip_bgp_instance_all_cmd
,
8114 "show [ip] bgp <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [json]",
8118 BGP_INSTANCE_ALL_HELP_STR
8120 "Address Family modifier\n"
8121 "Address Family modifier\n"
8123 "Address Family modifier\n"
8124 "Address Family modifier\n"
8126 "Address Family modifier\n"
8128 "Address Family modifier\n"
8132 safi_t safi
= SAFI_UNICAST
;
8137 if (argv_find (argv
, argc
, "ip", &idx
))
8139 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8140 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8142 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8143 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8144 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8146 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8149 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8150 // advance idx if necessary
8151 argv_find (argv
, argc
, "unicast", &idx
);
8154 u_char uj
= use_json(argc
, argv
);
8156 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8162 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8163 safi_t safi
, enum bgp_show_type type
)
8170 regex
= bgp_regcomp (regstr
);
8173 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8177 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8178 bgp_regex_free (regex
);
8183 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
8184 const char *prefix_list_str
, afi_t afi
,
8185 safi_t safi
, enum bgp_show_type type
)
8187 struct prefix_list
*plist
;
8188 struct bgp
*bgp
= NULL
;
8190 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8192 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8196 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8199 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8200 prefix_list_str
, VTY_NEWLINE
);
8204 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8208 bgp_show_filter_list (struct vty
*vty
, const char *name
,
8209 const char *filter
, afi_t afi
,
8210 safi_t safi
, enum bgp_show_type type
)
8212 struct as_list
*as_list
;
8213 struct bgp
*bgp
= NULL
;
8215 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8217 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8221 as_list
= as_list_lookup (filter
);
8222 if (as_list
== NULL
)
8224 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8228 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8231 DEFUN (show_ip_bgp_dampening_info
,
8232 show_ip_bgp_dampening_params_cmd
,
8233 "show [ip] bgp dampening parameters",
8237 "Display detailed information about dampening\n"
8238 "Display detail of configured dampening parameters\n")
8240 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8244 DEFUN (show_ip_bgp_ipv4_dampening_parameters
,
8245 show_ip_bgp_ipv4_dampening_parameters_cmd
,
8246 "show [ip] bgp ipv4 <unicast|multicast> dampening parameters",
8251 "Address Family modifier\n"
8252 "Address Family modifier\n"
8253 "Display detailed information about dampening\n"
8254 "Display detail of configured dampening parameters\n")
8257 if (strncmp(argv
[idx_safi
]->arg
, "m", 1) == 0)
8258 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_MULTICAST
);
8260 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8264 bgp_show_route_map (struct vty
*vty
, const char *name
,
8265 const char *rmap_str
, afi_t afi
,
8266 safi_t safi
, enum bgp_show_type type
)
8268 struct route_map
*rmap
;
8269 struct bgp
*bgp
= NULL
;
8271 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8275 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8279 rmap
= route_map_lookup_by_name (rmap_str
);
8282 vty_out (vty
, "%% %s is not a valid route-map name%s",
8283 rmap_str
, VTY_NEWLINE
);
8287 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8291 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
8292 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8294 struct community
*com
;
8301 /* BGP structure lookup */
8304 bgp
= bgp_lookup_by_name (view_name
);
8307 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8313 bgp
= bgp_get_default ();
8316 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8321 b
= buffer_new (1024);
8322 for (i
= 0; i
< argc
; i
++)
8325 buffer_putc (b
, ' ');
8328 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8333 buffer_putstr (b
, argv
[i
]->arg
);
8335 buffer_putc (b
, '\0');
8337 str
= buffer_getstr (b
);
8340 com
= community_str2com (str
);
8341 XFREE (MTYPE_TMP
, str
);
8344 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8348 return bgp_show (vty
, bgp
, afi
, safi
,
8349 (exact
? bgp_show_type_community_exact
:
8350 bgp_show_type_community
), com
, 0);
8354 bgp_show_community_list (struct vty
*vty
, const char *name
,
8355 const char *com
, int exact
,
8356 afi_t afi
, safi_t safi
)
8358 struct community_list
*list
;
8359 struct bgp
*bgp
= NULL
;
8361 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8363 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8367 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8370 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8375 return bgp_show (vty
, bgp
, afi
, safi
,
8376 (exact
? bgp_show_type_community_list_exact
:
8377 bgp_show_type_community_list
), list
, 0);
8381 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
8382 const char *prefix
, afi_t afi
,
8383 safi_t safi
, enum bgp_show_type type
)
8387 struct bgp
*bgp
= NULL
;
8389 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8391 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8397 ret
= str2prefix (prefix
, p
);
8400 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8404 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8409 static struct peer
*
8410 peer_lookup_in_view (struct vty
*vty
, const char *view_name
,
8411 const char *ip_str
, u_char use_json
)
8418 /* BGP structure lookup. */
8421 bgp
= bgp_lookup_by_name (view_name
);
8426 json_object
*json_no
= NULL
;
8427 json_no
= json_object_new_object();
8428 json_object_string_add(json_no
, "warning", "Can't find BGP view");
8429 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8430 json_object_free(json_no
);
8433 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8439 bgp
= bgp_get_default ();
8444 json_object
*json_no
= NULL
;
8445 json_no
= json_object_new_object();
8446 json_object_string_add(json_no
, "warning", "No BGP process configured");
8447 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8448 json_object_free(json_no
);
8451 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8456 /* Get peer sockunion. */
8457 ret
= str2sockunion (ip_str
, &su
);
8460 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8463 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8469 json_object
*json_no
= NULL
;
8470 json_no
= json_object_new_object();
8471 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8472 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8473 json_object_free(json_no
);
8476 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8483 /* Peer structure lookup. */
8484 peer
= peer_lookup (bgp
, &su
);
8489 json_object
*json_no
= NULL
;
8490 json_no
= json_object_new_object();
8491 json_object_string_add(json_no
, "warning","No such neighbor");
8492 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8493 json_object_free(json_no
);
8496 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8505 BGP_STATS_MAXBITLEN
= 0,
8509 BGP_STATS_UNAGGREGATEABLE
,
8510 BGP_STATS_MAX_AGGREGATEABLE
,
8511 BGP_STATS_AGGREGATES
,
8513 BGP_STATS_ASPATH_COUNT
,
8514 BGP_STATS_ASPATH_MAXHOPS
,
8515 BGP_STATS_ASPATH_TOTHOPS
,
8516 BGP_STATS_ASPATH_MAXSIZE
,
8517 BGP_STATS_ASPATH_TOTSIZE
,
8518 BGP_STATS_ASN_HIGHEST
,
8522 static const char *table_stats_strs
[] =
8524 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8525 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8526 [BGP_STATS_RIB
] = "Total Advertisements",
8527 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8528 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8529 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8530 [BGP_STATS_SPACE
] = "Address space advertised",
8531 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8532 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8533 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8534 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8535 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8536 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8537 [BGP_STATS_MAX
] = NULL
,
8540 struct bgp_table_stats
8542 struct bgp_table
*table
;
8543 unsigned long long counts
[BGP_STATS_MAX
];
8547 #define TALLY_SIGFIG 100000
8548 static unsigned long
8549 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8551 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8552 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8553 unsigned long ret
= newtot
/ count
;
8555 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8563 bgp_table_stats_walker (struct thread
*t
)
8565 struct bgp_node
*rn
;
8566 struct bgp_node
*top
;
8567 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8568 unsigned int space
= 0;
8570 if (!(top
= bgp_table_top (ts
->table
)))
8573 switch (top
->p
.family
)
8576 space
= IPV4_MAX_BITLEN
;
8579 space
= IPV6_MAX_BITLEN
;
8583 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8585 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8587 struct bgp_info
*ri
;
8588 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8589 unsigned int rinum
= 0;
8597 ts
->counts
[BGP_STATS_PREFIXES
]++;
8598 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8601 ts
->counts
[BGP_STATS_AVGPLEN
]
8602 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8603 ts
->counts
[BGP_STATS_AVGPLEN
],
8607 /* check if the prefix is included by any other announcements */
8608 while (prn
&& !prn
->info
)
8609 prn
= bgp_node_parent_nolock (prn
);
8611 if (prn
== NULL
|| prn
== top
)
8613 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8614 /* announced address space */
8616 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8619 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8621 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8624 ts
->counts
[BGP_STATS_RIB
]++;
8627 (CHECK_FLAG (ri
->attr
->flag
,
8628 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8629 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8632 if (ri
->attr
&& ri
->attr
->aspath
)
8634 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8635 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8636 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8638 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8640 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8641 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8643 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8644 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8646 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8647 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8649 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8650 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8651 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8653 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8654 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8655 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8658 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8659 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8667 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8669 struct bgp_table_stats ts
;
8672 if (!bgp
->rib
[afi
][safi
])
8674 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8675 afi
, safi
, VTY_NEWLINE
);
8679 memset (&ts
, 0, sizeof (ts
));
8680 ts
.table
= bgp
->rib
[afi
][safi
];
8681 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8683 vty_out (vty
, "BGP %s RIB statistics%s%s",
8684 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8686 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8688 if (!table_stats_strs
[i
])
8694 case BGP_STATS_ASPATH_AVGHOPS
:
8695 case BGP_STATS_ASPATH_AVGSIZE
:
8696 case BGP_STATS_AVGPLEN
:
8697 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8698 vty_out (vty
, "%12.2f",
8699 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8702 case BGP_STATS_ASPATH_TOTHOPS
:
8703 case BGP_STATS_ASPATH_TOTSIZE
:
8704 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8705 vty_out (vty
, "%12.2f",
8707 (float)ts
.counts
[i
] /
8708 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8711 case BGP_STATS_TOTPLEN
:
8712 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8713 vty_out (vty
, "%12.2f",
8715 (float)ts
.counts
[i
] /
8716 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8719 case BGP_STATS_SPACE
:
8720 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8721 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8722 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8724 vty_out (vty
, "%30s: ", "%% announced ");
8725 vty_out (vty
, "%12.2f%s",
8726 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8727 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8729 vty_out (vty
, "%30s: ", "/8 equivalent ");
8730 vty_out (vty
, "%12.2f%s",
8731 (float)ts
.counts
[BGP_STATS_SPACE
] /
8732 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8734 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8736 vty_out (vty
, "%30s: ", "/24 equivalent ");
8737 vty_out (vty
, "%12.2f",
8738 (float)ts
.counts
[BGP_STATS_SPACE
] /
8739 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8742 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8743 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8746 vty_out (vty
, "%s", VTY_NEWLINE
);
8752 bgp_table_stats_vty (struct vty
*vty
, const char *name
,
8753 const char *afi_str
, const char *safi_str
)
8760 bgp
= bgp_lookup_by_name (name
);
8762 bgp
= bgp_get_default ();
8766 vty_out (vty
, "%% No such BGP instance exist%s", VTY_NEWLINE
);
8769 afi
= bgp_vty_afi_from_arg(afi_str
);
8772 vty_out (vty
, "%% Invalid address family \"%s\"%s",
8773 afi_str
, VTY_NEWLINE
);
8776 safi
= bgp_vty_safi_from_arg(safi_str
);
8777 if (safi
== SAFI_MAX
)
8779 vty_out (vty
, "%% Invalid subsequent address family %s%s",
8780 safi_str
, VTY_NEWLINE
);
8784 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8787 DEFUN (show_bgp_statistics
,
8788 show_bgp_statistics_cmd
,
8789 "show [ip] bgp <ipv4|ipv6> <encap|multicast|unicast|vpn> statistics",
8795 "Address Family modifier\n"
8796 "Address Family modifier\n"
8797 "Address Family modifier\n"
8798 "Address Family modifier\n"
8799 "BGP RIB advertisement statistics\n")
8803 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_afi
]->arg
, argv
[idx_safi
]->arg
);
8806 DEFUN (show_bgp_statistics_view
,
8807 show_bgp_statistics_view_cmd
,
8808 "show [ip] bgp <view|vrf> WORD <ipv4|ipv6> <unicast|multicast|vpn|encap> statistics",
8812 BGP_INSTANCE_HELP_STR
8815 "Address Family modifier\n"
8816 "Address Family modifier\n"
8817 "Address Family modifier\n"
8818 "Address Family modifier\n"
8819 "BGP RIB advertisement statistics\n")
8823 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_word
]->arg
, argv
[idx_afi
]->arg
);
8836 PCOUNT_PFCNT
, /* the figure we display to users */
8840 static const char *pcount_strs
[] =
8842 [PCOUNT_ADJ_IN
] = "Adj-in",
8843 [PCOUNT_DAMPED
] = "Damped",
8844 [PCOUNT_REMOVED
] = "Removed",
8845 [PCOUNT_HISTORY
] = "History",
8846 [PCOUNT_STALE
] = "Stale",
8847 [PCOUNT_VALID
] = "Valid",
8848 [PCOUNT_ALL
] = "All RIB",
8849 [PCOUNT_COUNTED
] = "PfxCt counted",
8850 [PCOUNT_PFCNT
] = "Useable",
8851 [PCOUNT_MAX
] = NULL
,
8856 unsigned int count
[PCOUNT_MAX
];
8857 const struct peer
*peer
;
8858 const struct bgp_table
*table
;
8862 bgp_peer_count_walker (struct thread
*t
)
8864 struct bgp_node
*rn
;
8865 struct peer_pcounts
*pc
= THREAD_ARG (t
);
8866 const struct peer
*peer
= pc
->peer
;
8868 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
8870 struct bgp_adj_in
*ain
;
8871 struct bgp_info
*ri
;
8873 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
8874 if (ain
->peer
== peer
)
8875 pc
->count
[PCOUNT_ADJ_IN
]++;
8877 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8879 char buf
[SU_ADDRSTRLEN
];
8881 if (ri
->peer
!= peer
)
8884 pc
->count
[PCOUNT_ALL
]++;
8886 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
8887 pc
->count
[PCOUNT_DAMPED
]++;
8888 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
8889 pc
->count
[PCOUNT_HISTORY
]++;
8890 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
8891 pc
->count
[PCOUNT_REMOVED
]++;
8892 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
8893 pc
->count
[PCOUNT_STALE
]++;
8894 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
8895 pc
->count
[PCOUNT_VALID
]++;
8896 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8897 pc
->count
[PCOUNT_PFCNT
]++;
8899 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
8901 pc
->count
[PCOUNT_COUNTED
]++;
8902 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8903 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
8905 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8906 buf
, SU_ADDRSTRLEN
),
8912 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8913 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
8915 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8916 buf
, SU_ADDRSTRLEN
),
8926 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
8928 struct peer_pcounts pcounts
= { .peer
= peer
};
8930 json_object
*json
= NULL
;
8931 json_object
*json_loop
= NULL
;
8935 json
= json_object_new_object();
8936 json_loop
= json_object_new_object();
8939 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
8940 || !peer
->bgp
->rib
[afi
][safi
])
8944 json_object_string_add(json
, "warning", "No such neighbor or address family");
8945 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8946 json_object_free(json
);
8949 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
8954 memset (&pcounts
, 0, sizeof(pcounts
));
8955 pcounts
.peer
= peer
;
8956 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
8958 /* in-place call via thread subsystem so as to record execution time
8959 * * stats for the thread-walk (i.e. ensure this can't be blamed on
8960 * * on just vty_read()).
8962 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
8966 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
8967 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
8968 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
8970 for (i
= 0; i
< PCOUNT_MAX
; i
++)
8971 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
8973 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
8975 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
8977 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
8978 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
8980 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8981 json_object_free(json
);
8986 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
8988 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
8989 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
8994 vty_out (vty
, "Prefix counts for %s, %s%s",
8995 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
8998 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
8999 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9000 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9002 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9003 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9005 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9007 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9008 peer
->host
, VTY_NEWLINE
);
9009 vty_out (vty
, "Please report this bug, with the above command output%s",
9017 DEFUN (show_ip_bgp_neighbor_prefix_counts
,
9018 show_ip_bgp_neighbor_prefix_counts_cmd
,
9019 "show [ip] bgp neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9023 "Detailed information on TCP and BGP neighbor connections\n"
9024 "Neighbor to display information about\n"
9025 "Neighbor to display information about\n"
9026 "Neighbor on BGP configured interface\n"
9027 "Display detailed prefix count information\n"
9032 u_char uj
= use_json(argc
, argv
);
9034 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9038 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9041 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9042 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9043 "show [ip] bgp <view|vrf> WORD neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9047 BGP_INSTANCE_HELP_STR
9048 "Detailed information on TCP and BGP neighbor connections\n"
9049 "Neighbor to display information about\n"
9050 "Neighbor to display information about\n"
9051 "Neighbor on BGP configured interface\n"
9052 "Display detailed prefix count information\n"
9058 u_char uj
= use_json(argc
, argv
);
9060 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9064 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9067 DEFUN (show_bgp_ipv6_neighbor_prefix_counts
,
9068 show_bgp_ipv6_neighbor_prefix_counts_cmd
,
9069 "show [ip] bgp ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9074 "Detailed information on TCP and BGP neighbor connections\n"
9075 "Neighbor to display information about\n"
9076 "Neighbor to display information about\n"
9077 "Neighbor on BGP configured interface\n"
9078 "Display detailed prefix count information\n"
9083 u_char uj
= use_json(argc
, argv
);
9085 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9089 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9092 DEFUN (show_bgp_instance_ipv6_neighbor_prefix_counts
,
9093 show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
,
9094 "show [ip] bgp <view|vrf> WORD ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9098 BGP_INSTANCE_HELP_STR
9100 "Detailed information on TCP and BGP neighbor connections\n"
9101 "Neighbor to display information about\n"
9102 "Neighbor to display information about\n"
9103 "Neighbor on BGP configured interface\n"
9104 "Display detailed prefix count information\n"
9110 u_char uj
= use_json(argc
, argv
);
9112 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9116 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9119 DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts
,
9120 show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
,
9121 "show [ip] bgp ipv4 <unicast|multicast> neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9126 "Address Family modifier\n"
9127 "Address Family modifier\n"
9128 "Detailed information on TCP and BGP neighbor connections\n"
9129 "Neighbor to display information about\n"
9130 "Neighbor to display information about\n"
9131 "Neighbor on BGP configured interface\n"
9132 "Display detailed prefix count information\n"
9138 u_char uj
= use_json(argc
, argv
);
9140 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9144 if (strncmp (argv
[idx_safi
]->arg
, "m", 1) == 0)
9145 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MULTICAST
, uj
);
9147 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9150 DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts
,
9151 show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
,
9152 "show [ip] bgp vpnv4 all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9157 "Display information about all VPNv4 NLRIs\n"
9158 "Detailed information on TCP and BGP neighbor connections\n"
9159 "Neighbor to display information about\n"
9160 "Neighbor to display information about\n"
9161 "Neighbor on BGP configured interface\n"
9162 "Display detailed prefix count information\n"
9167 u_char uj
= use_json(argc
, argv
);
9169 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9173 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9176 DEFUN (show_ip_bgp_vpnv4_all_route_prefix
,
9177 show_ip_bgp_vpnv4_all_route_prefix_cmd
,
9178 "show [ip] bgp vpnv4 all <A.B.C.D|A.B.C.D/M> [json]",
9183 "Display information about all VPNv4 NLRIs\n"
9184 "Network in the BGP routing table to display\n"
9185 "Network in the BGP routing table to display\n"
9189 char *network
= NULL
;
9190 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9191 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9192 return bgp_show_route (vty
, NULL
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9196 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9197 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9199 struct bgp_table
*table
;
9200 struct bgp_adj_in
*ain
;
9201 struct bgp_adj_out
*adj
;
9202 unsigned long output_count
;
9203 unsigned long filtered_count
;
9204 struct bgp_node
*rn
;
9209 struct attr_extra extra
;
9211 struct update_subgroup
*subgrp
;
9212 json_object
*json_scode
= NULL
;
9213 json_object
*json_ocode
= NULL
;
9214 json_object
*json_ar
= NULL
;
9215 struct peer_af
*paf
;
9219 json_scode
= json_object_new_object();
9220 json_ocode
= json_object_new_object();
9221 json_ar
= json_object_new_object();
9223 json_object_string_add(json_scode
, "suppressed", "s");
9224 json_object_string_add(json_scode
, "damped", "d");
9225 json_object_string_add(json_scode
, "history", "h");
9226 json_object_string_add(json_scode
, "valid", "*");
9227 json_object_string_add(json_scode
, "best", ">");
9228 json_object_string_add(json_scode
, "multipath", "=");
9229 json_object_string_add(json_scode
, "internal", "i");
9230 json_object_string_add(json_scode
, "ribFailure", "r");
9231 json_object_string_add(json_scode
, "stale", "S");
9232 json_object_string_add(json_scode
, "removed", "R");
9234 json_object_string_add(json_ocode
, "igp", "i");
9235 json_object_string_add(json_ocode
, "egp", "e");
9236 json_object_string_add(json_ocode
, "incomplete", "?");
9245 json_object_string_add(json
, "alert", "no BGP");
9246 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9247 json_object_free(json
);
9250 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9254 table
= bgp
->rib
[afi
][safi
];
9256 output_count
= filtered_count
= 0;
9257 subgrp
= peer_subgroup(peer
, afi
, safi
);
9259 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9263 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9264 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9265 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9266 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9267 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9271 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9272 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9273 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9275 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9276 VTY_NEWLINE
, VTY_NEWLINE
);
9281 attr
.extra
= &extra
;
9282 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9286 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9288 if (ain
->peer
== peer
)
9294 json_object_int_add(json
, "bgpTableVersion", 0);
9295 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9296 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9297 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9301 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9302 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9303 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9310 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9315 bgp_attr_dup(&attr
, ain
->attr
);
9316 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9318 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9329 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9330 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9331 if (paf
->peer
== peer
)
9337 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9338 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9339 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9340 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9344 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9345 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9346 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9347 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9355 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9361 bgp_attr_dup(&attr
, adj
->attr
);
9362 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9363 if (ret
!= RMAP_DENY
)
9365 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9375 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9377 if (output_count
!= 0)
9380 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9382 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9383 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9387 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9388 json_object_free(json
);
9394 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9395 int in
, const char *rmap_name
, u_char use_json
)
9397 json_object
*json
= NULL
;
9400 json
= json_object_new_object();
9402 if (!peer
|| !peer
->afc
[afi
][safi
])
9406 json_object_string_add(json
, "warning", "No such neighbor or address family");
9407 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9408 json_object_free(json
);
9411 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9416 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9420 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9421 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9422 json_object_free(json
);
9425 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9430 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9435 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9436 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9437 "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]",
9441 BGP_INSTANCE_HELP_STR
9443 "Address Family modifier\n"
9444 "Address Family modifier\n"
9446 "Address Family modifier\n"
9447 "Address Family modifier\n"
9449 "Address Family modifier\n"
9451 "Address Family modifier\n"
9452 "Detailed information on TCP and BGP neighbor connections\n"
9453 "Neighbor to display information about\n"
9454 "Neighbor to display information about\n"
9455 "Neighbor on BGP configured interface\n"
9456 "Display the received routes from neighbor\n"
9457 "Display the routes advertised to a BGP neighbor\n"
9458 "Route-map to modify the attributes\n"
9459 "Name of the route map\n"
9462 afi_t afi
= AFI_IP6
;
9463 safi_t safi
= SAFI_UNICAST
;
9465 char *rmap_name
= NULL
;
9466 char *peerstr
= NULL
;
9474 if (argv_find (argv
, argc
, "ip", &idx
))
9476 /* [<view|vrf> WORD] */
9477 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9478 vrf
= argv
[++idx
]->arg
;
9479 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9480 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9482 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9483 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9484 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9486 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9489 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9490 // advance idx if necessary
9491 argv_find (argv
, argc
, "unicast", &idx
);
9494 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9495 argv_find (argv
, argc
, "neighbors", &idx
);
9496 peerstr
= argv
[++idx
]->arg
;
9498 u_char uj
= use_json(argc
, argv
);
9500 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9504 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9508 if (argv_find (argv
, argc
, "received-routes", &idx
))
9510 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9512 if (argv_find (argv
, argc
, "route-map", &idx
))
9513 rmap_name
= argv
[++idx
]->arg
;
9515 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9518 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9519 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9520 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9526 "Address Family modifier\n"
9527 "Detailed information on TCP and BGP neighbor connections\n"
9528 "Neighbor to display information about\n"
9529 "Neighbor to display information about\n"
9530 "Neighbor on BGP configured interface\n"
9531 "Display information received from a BGP neighbor\n"
9532 "Display the prefixlist filter\n"
9535 afi_t afi
= AFI_IP6
;
9536 safi_t safi
= SAFI_UNICAST
;
9537 char *peerstr
= NULL
;
9547 if (argv_find (argv
, argc
, "ip", &idx
))
9549 /* [<ipv4|ipv6> [unicast]] */
9550 if (argv_find (argv
, argc
, "ipv4", &idx
))
9552 if (argv_find (argv
, argc
, "ipv6", &idx
))
9554 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9555 argv_find (argv
, argc
, "neighbors", &idx
);
9556 peerstr
= argv
[++idx
]->arg
;
9558 u_char uj
= use_json(argc
, argv
);
9560 ret
= str2sockunion (peerstr
, &su
);
9563 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9567 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9569 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9575 peer
= peer_lookup (NULL
, &su
);
9579 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9581 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9586 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9587 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9591 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9592 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9597 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9599 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9606 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9607 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9609 if (! peer
|| ! peer
->afc
[afi
][safi
])
9613 json_object
*json_no
= NULL
;
9614 json_no
= json_object_new_object();
9615 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9616 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9617 json_object_free(json_no
);
9620 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9624 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9627 DEFUN (show_ip_bgp_neighbor_routes
,
9628 show_ip_bgp_neighbor_routes_cmd
,
9629 "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]",
9633 BGP_INSTANCE_HELP_STR
9635 "Address Family modifier\n"
9636 "Address Family modifier\n"
9638 "Address Family modifier\n"
9639 "Address Family modifier\n"
9641 "Address Family modifier\n"
9643 "Address Family modifier\n"
9644 "Detailed information on TCP and BGP neighbor connections\n"
9645 "Neighbor to display information about\n"
9646 "Neighbor to display information about\n"
9647 "Neighbor on BGP configured interface\n"
9648 "Display flap statistics of the routes learned from neighbor\n"
9649 "Display the dampened routes received from neighbor\n"
9650 "Display routes learned from neighbor\n"
9654 char *peerstr
= NULL
;
9656 afi_t afi
= AFI_IP6
;
9657 safi_t safi
= SAFI_UNICAST
;
9659 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9664 if (argv_find (argv
, argc
, "ip", &idx
))
9666 /* [<view|vrf> WORD] */
9667 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9668 vrf
= argv
[++idx
]->arg
;
9669 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9670 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9672 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9673 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9674 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9676 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9679 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9680 // advance idx if necessary
9681 argv_find (argv
, argc
, "unicast", &idx
);
9683 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9684 argv_find (argv
, argc
, "neighbors", &idx
);
9685 peerstr
= argv
[++idx
]->arg
;
9687 u_char uj
= use_json(argc
, argv
);
9689 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9692 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9696 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9697 sh_type
= bgp_show_type_flap_neighbor
;
9698 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9699 sh_type
= bgp_show_type_damp_neighbor
;
9700 else if (argv_find (argv
, argc
, "routes", &idx
))
9701 sh_type
= bgp_show_type_neighbor
;
9703 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9706 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9710 /* Distance value for the IP source prefix. */
9713 /* Name of the access-list to be matched. */
9717 static struct bgp_distance
*
9718 bgp_distance_new (void)
9720 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9724 bgp_distance_free (struct bgp_distance
*bdistance
)
9726 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9730 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9731 const char *ip_str
, const char *access_list_str
)
9738 struct bgp_node
*rn
;
9739 struct bgp_distance
*bdistance
;
9741 afi
= bgp_node_afi (vty
);
9742 safi
= bgp_node_safi (vty
);
9744 ret
= str2prefix (ip_str
, &p
);
9747 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9751 distance
= atoi (distance_str
);
9753 /* Get BGP distance node. */
9754 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9757 bdistance
= rn
->info
;
9758 bgp_unlock_node (rn
);
9762 bdistance
= bgp_distance_new ();
9763 rn
->info
= bdistance
;
9766 /* Set distance value. */
9767 bdistance
->distance
= distance
;
9769 /* Reset access-list configuration. */
9770 if (bdistance
->access_list
)
9772 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9773 bdistance
->access_list
= NULL
;
9775 if (access_list_str
)
9776 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9782 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9783 const char *ip_str
, const char *access_list_str
)
9790 struct bgp_node
*rn
;
9791 struct bgp_distance
*bdistance
;
9793 afi
= bgp_node_afi (vty
);
9794 safi
= bgp_node_safi (vty
);
9796 ret
= str2prefix (ip_str
, &p
);
9799 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9803 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9806 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9810 bdistance
= rn
->info
;
9811 distance
= atoi(distance_str
);
9813 if (bdistance
->distance
!= distance
)
9815 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9819 if (bdistance
->access_list
)
9820 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9821 bgp_distance_free (bdistance
);
9824 bgp_unlock_node (rn
);
9825 bgp_unlock_node (rn
);
9830 /* Apply BGP information to distance method. */
9832 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9833 safi_t safi
, struct bgp
*bgp
)
9835 struct bgp_node
*rn
;
9838 struct bgp_distance
*bdistance
;
9839 struct access_list
*alist
;
9840 struct bgp_static
*bgp_static
;
9847 /* Check source address. */
9848 sockunion2hostprefix (&peer
->su
, &q
);
9849 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9852 bdistance
= rn
->info
;
9853 bgp_unlock_node (rn
);
9855 if (bdistance
->access_list
)
9857 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9858 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9859 return bdistance
->distance
;
9862 return bdistance
->distance
;
9865 /* Backdoor check. */
9866 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9869 bgp_static
= rn
->info
;
9870 bgp_unlock_node (rn
);
9872 if (bgp_static
->backdoor
)
9874 if (bgp
->distance_local
[afi
][safi
])
9875 return bgp
->distance_local
[afi
][safi
];
9877 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9881 if (peer
->sort
== BGP_PEER_EBGP
)
9883 if (bgp
->distance_ebgp
[afi
][safi
])
9884 return bgp
->distance_ebgp
[afi
][safi
];
9885 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
9889 if (bgp
->distance_ibgp
[afi
][safi
])
9890 return bgp
->distance_ibgp
[afi
][safi
];
9891 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9895 DEFUN (bgp_distance
,
9897 "distance bgp (1-255) (1-255) (1-255)",
9898 "Define an administrative distance\n"
9900 "Distance for routes external to the AS\n"
9901 "Distance for routes internal to the AS\n"
9902 "Distance for local routes\n")
9904 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9906 int idx_number_2
= 3;
9907 int idx_number_3
= 4;
9911 afi
= bgp_node_afi (vty
);
9912 safi
= bgp_node_safi (vty
);
9914 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
9915 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
9916 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
9920 DEFUN (no_bgp_distance
,
9921 no_bgp_distance_cmd
,
9922 "no distance bgp [(1-255) (1-255) (1-255)]",
9924 "Define an administrative distance\n"
9926 "Distance for routes external to the AS\n"
9927 "Distance for routes internal to the AS\n"
9928 "Distance for local routes\n")
9930 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9934 afi
= bgp_node_afi (vty
);
9935 safi
= bgp_node_safi (vty
);
9937 bgp
->distance_ebgp
[afi
][safi
] = 0;
9938 bgp
->distance_ibgp
[afi
][safi
] = 0;
9939 bgp
->distance_local
[afi
][safi
] = 0;
9944 DEFUN (bgp_distance_source
,
9945 bgp_distance_source_cmd
,
9946 "distance (1-255) A.B.C.D/M",
9947 "Define an administrative distance\n"
9948 "Administrative distance\n"
9949 "IP source prefix\n")
9952 int idx_ipv4_prefixlen
= 2;
9953 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9957 DEFUN (no_bgp_distance_source
,
9958 no_bgp_distance_source_cmd
,
9959 "no distance (1-255) A.B.C.D/M",
9961 "Define an administrative distance\n"
9962 "Administrative distance\n"
9963 "IP source prefix\n")
9966 int idx_ipv4_prefixlen
= 3;
9967 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9971 DEFUN (bgp_distance_source_access_list
,
9972 bgp_distance_source_access_list_cmd
,
9973 "distance (1-255) A.B.C.D/M WORD",
9974 "Define an administrative distance\n"
9975 "Administrative distance\n"
9976 "IP source prefix\n"
9977 "Access list name\n")
9980 int idx_ipv4_prefixlen
= 2;
9982 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9986 DEFUN (no_bgp_distance_source_access_list
,
9987 no_bgp_distance_source_access_list_cmd
,
9988 "no distance (1-255) A.B.C.D/M WORD",
9990 "Define an administrative distance\n"
9991 "Administrative distance\n"
9992 "IP source prefix\n"
9993 "Access list name\n")
9996 int idx_ipv4_prefixlen
= 3;
9998 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10002 DEFUN (ipv6_bgp_distance_source
,
10003 ipv6_bgp_distance_source_cmd
,
10004 "distance (1-255) X:X::X:X/M",
10005 "Define an administrative distance\n"
10006 "Administrative distance\n"
10007 "IP source prefix\n")
10009 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10010 return CMD_SUCCESS
;
10013 DEFUN (no_ipv6_bgp_distance_source
,
10014 no_ipv6_bgp_distance_source_cmd
,
10015 "no distance (1-255) X:X::X:X/M",
10017 "Define an administrative distance\n"
10018 "Administrative distance\n"
10019 "IP source prefix\n")
10021 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10022 return CMD_SUCCESS
;
10025 DEFUN (ipv6_bgp_distance_source_access_list
,
10026 ipv6_bgp_distance_source_access_list_cmd
,
10027 "distance (1-255) X:X::X:X/M WORD",
10028 "Define an administrative distance\n"
10029 "Administrative distance\n"
10030 "IP source prefix\n"
10031 "Access list name\n")
10033 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10034 return CMD_SUCCESS
;
10037 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10038 no_ipv6_bgp_distance_source_access_list_cmd
,
10039 "no distance (1-255) X:X::X:X/M WORD",
10041 "Define an administrative distance\n"
10042 "Administrative distance\n"
10043 "IP source prefix\n"
10044 "Access list name\n")
10046 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10047 return CMD_SUCCESS
;
10050 DEFUN (bgp_damp_set
,
10052 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10053 "BGP Specific commands\n"
10054 "Enable route-flap dampening\n"
10055 "Half-life time for the penalty\n"
10056 "Value to start reusing a route\n"
10057 "Value to start suppressing a route\n"
10058 "Maximum duration to suppress a stable route\n")
10060 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10061 int idx_half_life
= 2;
10063 int idx_suppress
= 4;
10064 int idx_max_suppress
= 5;
10065 int half
= DEFAULT_HALF_LIFE
* 60;
10066 int reuse
= DEFAULT_REUSE
;
10067 int suppress
= DEFAULT_SUPPRESS
;
10068 int max
= 4 * half
;
10072 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10073 reuse
= atoi (argv
[idx_reuse
]->arg
);
10074 suppress
= atoi (argv
[idx_suppress
]->arg
);
10075 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10077 else if (argc
== 3)
10079 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10083 if (suppress
< reuse
)
10085 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10090 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10091 half
, reuse
, suppress
, max
);
10094 DEFUN (bgp_damp_unset
,
10095 bgp_damp_unset_cmd
,
10096 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10098 "BGP Specific commands\n"
10099 "Enable route-flap dampening\n"
10100 "Half-life time for the penalty\n"
10101 "Value to start reusing a route\n"
10102 "Value to start suppressing a route\n"
10103 "Maximum duration to suppress a stable route\n")
10105 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10106 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10109 /* Display specified route of BGP table. */
10111 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10112 const char *ip_str
, afi_t afi
, safi_t safi
,
10113 struct prefix_rd
*prd
, int prefix_check
)
10116 struct prefix match
;
10117 struct bgp_node
*rn
;
10118 struct bgp_node
*rm
;
10119 struct bgp_info
*ri
;
10120 struct bgp_info
*ri_temp
;
10122 struct bgp_table
*table
;
10124 /* BGP structure lookup. */
10127 bgp
= bgp_lookup_by_name (view_name
);
10130 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10131 return CMD_WARNING
;
10136 bgp
= bgp_get_default ();
10139 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10140 return CMD_WARNING
;
10144 /* Check IP address argument. */
10145 ret
= str2prefix (ip_str
, &match
);
10148 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10149 return CMD_WARNING
;
10152 match
.family
= afi2family (afi
);
10154 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10156 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10158 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10161 if ((table
= rn
->info
) != NULL
)
10162 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10164 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10169 if (ri
->extra
&& ri
->extra
->damp_info
)
10171 ri_temp
= ri
->next
;
10172 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10180 bgp_unlock_node (rm
);
10186 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10188 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10193 if (ri
->extra
&& ri
->extra
->damp_info
)
10195 ri_temp
= ri
->next
;
10196 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10204 bgp_unlock_node (rn
);
10208 return CMD_SUCCESS
;
10211 DEFUN (clear_ip_bgp_dampening
,
10212 clear_ip_bgp_dampening_cmd
,
10213 "clear ip bgp dampening",
10217 "Clear route flap dampening information\n")
10219 bgp_damp_info_clean ();
10220 return CMD_SUCCESS
;
10223 DEFUN (clear_ip_bgp_dampening_prefix
,
10224 clear_ip_bgp_dampening_prefix_cmd
,
10225 "clear ip bgp dampening A.B.C.D/M",
10229 "Clear route flap dampening information\n"
10232 int idx_ipv4_prefixlen
= 4;
10233 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10234 SAFI_UNICAST
, NULL
, 1);
10237 DEFUN (clear_ip_bgp_dampening_address
,
10238 clear_ip_bgp_dampening_address_cmd
,
10239 "clear ip bgp dampening A.B.C.D",
10243 "Clear route flap dampening information\n"
10244 "Network to clear damping information\n")
10247 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10248 SAFI_UNICAST
, NULL
, 0);
10251 DEFUN (clear_ip_bgp_dampening_address_mask
,
10252 clear_ip_bgp_dampening_address_mask_cmd
,
10253 "clear ip bgp dampening A.B.C.D A.B.C.D",
10257 "Clear route flap dampening information\n"
10258 "Network to clear damping information\n"
10262 int idx_ipv4_2
= 5;
10264 char prefix_str
[BUFSIZ
];
10266 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10269 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10270 return CMD_WARNING
;
10273 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10274 SAFI_UNICAST
, NULL
, 0);
10277 /* also used for encap safi */
10279 bgp_config_write_network_vpnv4 (struct vty
*vty
, struct bgp
*bgp
,
10280 afi_t afi
, safi_t safi
, int *write
)
10282 struct bgp_node
*prn
;
10283 struct bgp_node
*rn
;
10284 struct bgp_table
*table
;
10286 struct prefix_rd
*prd
;
10287 struct bgp_static
*bgp_static
;
10289 char buf
[SU_ADDRSTRLEN
];
10290 char rdbuf
[RD_ADDRSTRLEN
];
10292 /* Network configuration. */
10293 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10294 if ((table
= prn
->info
) != NULL
)
10295 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10296 if ((bgp_static
= rn
->info
) != NULL
)
10299 prd
= (struct prefix_rd
*) &prn
->p
;
10301 /* "address-family" display. */
10302 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10304 /* "network" configuration display. */
10305 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10306 label
= decode_label (bgp_static
->tag
);
10308 vty_out (vty
, " network %s/%d rd %s tag %d",
10309 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10312 vty_out (vty
, "%s", VTY_NEWLINE
);
10317 /* Configuration of static route announcement and aggregate
10320 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10321 afi_t afi
, safi_t safi
, int *write
)
10323 struct bgp_node
*rn
;
10325 struct bgp_static
*bgp_static
;
10326 struct bgp_aggregate
*bgp_aggregate
;
10327 char buf
[SU_ADDRSTRLEN
];
10329 if (afi
== AFI_IP
&& ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)))
10330 return bgp_config_write_network_vpnv4 (vty
, bgp
, afi
, safi
, write
);
10332 /* Network configuration. */
10333 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10334 if ((bgp_static
= rn
->info
) != NULL
)
10338 /* "address-family" display. */
10339 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10341 /* "network" configuration display. */
10342 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10344 u_int32_t destination
;
10345 struct in_addr netmask
;
10347 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10348 masklen2ip (p
->prefixlen
, &netmask
);
10349 vty_out (vty
, " network %s",
10350 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10352 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10353 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10354 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10355 || p
->u
.prefix4
.s_addr
== 0)
10357 /* Natural mask is not display. */
10360 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10364 vty_out (vty
, " network %s/%d",
10365 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10369 if (bgp_static
->rmap
.name
)
10370 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10373 if (bgp_static
->backdoor
)
10374 vty_out (vty
, " backdoor");
10377 vty_out (vty
, "%s", VTY_NEWLINE
);
10380 /* Aggregate-address configuration. */
10381 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10382 if ((bgp_aggregate
= rn
->info
) != NULL
)
10386 /* "address-family" display. */
10387 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10389 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10391 struct in_addr netmask
;
10393 masklen2ip (p
->prefixlen
, &netmask
);
10394 vty_out (vty
, " aggregate-address %s %s",
10395 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10396 inet_ntoa (netmask
));
10400 vty_out (vty
, " aggregate-address %s/%d",
10401 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10405 if (bgp_aggregate
->as_set
)
10406 vty_out (vty
, " as-set");
10408 if (bgp_aggregate
->summary_only
)
10409 vty_out (vty
, " summary-only");
10411 vty_out (vty
, "%s", VTY_NEWLINE
);
10418 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10419 safi_t safi
, int *write
)
10421 struct bgp_node
*rn
;
10422 struct bgp_distance
*bdistance
;
10424 /* Distance configuration. */
10425 if (bgp
->distance_ebgp
[afi
][safi
]
10426 && bgp
->distance_ibgp
[afi
][safi
]
10427 && bgp
->distance_local
[afi
][safi
]
10428 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10429 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10430 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10432 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10433 vty_out (vty
, " distance bgp %d %d %d%s",
10434 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10435 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10438 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10439 rn
= bgp_route_next (rn
))
10440 if ((bdistance
= rn
->info
) != NULL
)
10442 char buf
[PREFIX_STRLEN
];
10444 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10445 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10446 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10447 bdistance
->access_list
? bdistance
->access_list
: "",
10454 /* Allocate routing table structure and install commands. */
10456 bgp_route_init (void)
10461 /* Init BGP distance table. */
10462 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10463 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10464 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10466 /* IPv4 BGP commands. */
10467 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10468 install_element (BGP_NODE
, &bgp_network_cmd
);
10469 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10470 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10471 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10472 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10473 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10474 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10475 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10476 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10477 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10478 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10479 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10480 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10482 install_element (BGP_NODE
, &aggregate_address_cmd
);
10483 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10484 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10485 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10487 /* IPv4 unicast configuration. */
10488 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10489 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10490 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10491 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10492 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10493 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10494 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10495 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10496 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10497 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10498 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10500 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10501 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10502 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10503 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10505 /* IPv4 multicast configuration. */
10506 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10507 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10508 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10509 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10510 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10511 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10512 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10513 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10514 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10515 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10516 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10517 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10518 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10519 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10520 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10522 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10523 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_cmd
);
10524 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10525 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10526 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10527 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10528 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10529 install_element (VIEW_NODE
, &show_ip_bgp_dampening_params_cmd
);
10530 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_dampening_parameters_cmd
);
10531 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_route_prefix_cmd
);
10533 /* BGP dampening clear commands */
10534 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10535 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10536 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10537 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10540 install_element (ENABLE_NODE
, &show_ip_bgp_neighbor_prefix_counts_cmd
);
10541 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10542 install_element (ENABLE_NODE
, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
);
10543 install_element (ENABLE_NODE
, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
);
10544 install_element (ENABLE_NODE
, &show_bgp_ipv6_neighbor_prefix_counts_cmd
);
10545 install_element (ENABLE_NODE
, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
);
10547 /* New config IPv6 BGP commands. */
10548 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10549 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10550 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10551 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10552 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10554 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10555 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10557 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10558 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10561 install_element (ENABLE_NODE
, &show_bgp_statistics_cmd
);
10562 install_element (ENABLE_NODE
, &show_bgp_statistics_view_cmd
);
10564 install_element (BGP_NODE
, &bgp_distance_cmd
);
10565 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10566 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10567 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10568 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10569 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10570 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10571 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10572 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10573 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10574 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10575 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10576 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10577 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10578 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10579 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10580 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10581 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10582 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10583 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10584 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10585 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10586 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10587 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10588 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10589 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10590 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10591 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10592 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10593 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10595 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10596 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10597 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10598 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10600 /* IPv4 Multicast Mode */
10601 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10602 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10606 bgp_route_finish (void)
10611 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10612 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10614 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10615 bgp_distance_table
[afi
][safi
] = NULL
;