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
)
2119 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2122 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2124 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2128 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2129 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2130 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2131 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2133 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2136 /* Convert AFI, SAFI to values for packet. */
2137 pkt_afi
= afi_int2iana (afi
);
2138 pkt_safi
= safi_int2iana (safi
);
2142 ndata
[0] = (pkt_afi
>> 8);
2144 ndata
[2] = pkt_safi
;
2145 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2146 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2147 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2148 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2150 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2151 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2152 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2155 /* Dynamic peers will just close their connection. */
2156 if (peer_dynamic_neighbor (peer
))
2159 /* restart timer start */
2160 if (peer
->pmax_restart
[afi
][safi
])
2162 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2164 if (bgp_debug_neighbor_events(peer
))
2165 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2166 peer
->host
, peer
->v_pmax_restart
);
2168 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2169 peer
->v_pmax_restart
);
2175 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2177 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2179 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2183 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2184 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2185 peer
->pmax
[afi
][safi
]);
2186 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2189 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2193 /* Unconditionally remove the route from the RIB, without taking
2194 * damping into consideration (eg, because the session went down)
2197 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2198 afi_t afi
, safi_t safi
)
2200 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2202 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2203 bgp_info_delete (rn
, ri
); /* keep historical info */
2205 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2209 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2210 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2212 int status
= BGP_DAMP_NONE
;
2214 /* apply dampening, if result is suppressed, we'll be retaining
2215 * the bgp_info in the RIB for historical reference.
2217 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2218 && peer
->sort
== BGP_PEER_EBGP
)
2219 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2220 == BGP_DAMP_SUPPRESSED
)
2222 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2227 if (safi
== SAFI_MPLS_VPN
) {
2228 struct bgp_node
*prn
= NULL
;
2229 struct bgp_table
*table
= NULL
;
2231 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2233 table
= (struct bgp_table
*)(prn
->info
);
2235 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2242 bgp_unlock_node(prn
);
2244 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2245 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2247 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2248 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2252 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2255 static struct bgp_info
*
2256 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2257 struct bgp_node
*rn
)
2259 struct bgp_info
*new;
2261 /* Make new BGP info. */
2262 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2264 new->instance
= instance
;
2265 new->sub_type
= sub_type
;
2268 new->uptime
= bgp_clock ();
2270 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2275 bgp_info_addpath_rx_str(u_int32_t addpath_id
, char *buf
)
2278 sprintf(buf
, " with addpath ID %d", addpath_id
);
2282 /* Check if received nexthop is valid or not. */
2284 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2286 struct attr_extra
*attre
= attr
->extra
;
2289 /* Only validated for unicast and multicast currently. */
2290 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2293 /* If NEXT_HOP is present, validate it. */
2294 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2296 if (attr
->nexthop
.s_addr
== 0 ||
2297 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2298 bgp_nexthop_self (bgp
, attr
))
2302 /* If MP_NEXTHOP is present, validate it. */
2303 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2304 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2305 * it is not an IPv6 link-local address.
2307 if (attre
&& attre
->mp_nexthop_len
)
2309 switch (attre
->mp_nexthop_len
)
2311 case BGP_ATTR_NHLEN_IPV4
:
2312 case BGP_ATTR_NHLEN_VPNV4
:
2313 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2314 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2317 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2318 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2319 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2320 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2321 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2322 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2335 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2336 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2337 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2341 int aspath_loop_count
= 0;
2342 struct bgp_node
*rn
;
2344 struct attr new_attr
;
2345 struct attr_extra new_extra
;
2346 struct attr
*attr_new
;
2347 struct bgp_info
*ri
;
2348 struct bgp_info
*new;
2350 char buf
[SU_ADDRSTRLEN
];
2353 int do_loop_check
= 1;
2355 int vnc_implicit_withdraw
= 0;
2358 memset (&new_attr
, 0, sizeof(struct attr
));
2359 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2362 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2364 /* When peer's soft reconfiguration enabled. Record input packet in
2366 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2367 && peer
!= bgp
->peer_self
)
2368 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2370 /* Check previously received route. */
2371 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2372 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2373 ri
->addpath_rx_id
== addpath_id
)
2376 /* AS path local-as loop check. */
2377 if (peer
->change_local_as
)
2379 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2380 aspath_loop_count
= 1;
2382 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2384 reason
= "as-path contains our own AS;";
2389 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2390 * as-path is our ASN then we do not need to call aspath_loop_check
2392 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2393 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2396 /* AS path loop check. */
2399 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2400 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2401 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2403 reason
= "as-path contains our own AS;";
2408 /* Route reflector originator ID check. */
2409 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2410 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2412 reason
= "originator is us;";
2416 /* Route reflector cluster ID check. */
2417 if (bgp_cluster_filter (peer
, attr
))
2419 reason
= "reflected from the same cluster;";
2423 /* Apply incoming filter. */
2424 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2430 new_attr
.extra
= &new_extra
;
2431 bgp_attr_dup (&new_attr
, attr
);
2433 /* Apply incoming route-map.
2434 * NB: new_attr may now contain newly allocated values from route-map "set"
2435 * commands, so we need bgp_attr_flush in the error paths, until we intern
2436 * the attr (which takes over the memory references) */
2437 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2439 reason
= "route-map;";
2440 bgp_attr_flush (&new_attr
);
2444 /* next hop check. */
2445 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2447 reason
= "martian or self next-hop;";
2448 bgp_attr_flush (&new_attr
);
2452 attr_new
= bgp_attr_intern (&new_attr
);
2454 /* If the update is implicit withdraw. */
2457 ri
->uptime
= bgp_clock ();
2459 /* Same attribute comes in. */
2460 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2461 && attrhash_cmp (ri
->attr
, attr_new
))
2463 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2464 && peer
->sort
== BGP_PEER_EBGP
2465 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2467 if (bgp_debug_update(peer
, p
, NULL
, 1))
2469 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2470 zlog_debug ("%s rcvd %s/%d%s",
2472 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2473 p
->prefixlen
, buf2
);
2476 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2478 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2479 bgp_process (bgp
, rn
, afi
, safi
);
2482 else /* Duplicate - odd */
2484 if (bgp_debug_update(peer
, p
, NULL
, 1))
2486 if (!peer
->rcvd_attr_printed
)
2488 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2489 peer
->rcvd_attr_printed
= 1;
2492 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2493 zlog_debug ("%s rcvd %s/%d%s...duplicate ignored",
2495 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2496 p
->prefixlen
, buf2
);
2499 /* graceful restart STALE flag unset. */
2500 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2502 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2503 bgp_process (bgp
, rn
, afi
, safi
);
2507 bgp_unlock_node (rn
);
2508 bgp_attr_unintern (&attr_new
);
2513 /* Withdraw/Announce before we fully processed the withdraw */
2514 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2516 if (bgp_debug_update(peer
, p
, NULL
, 1))
2518 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2519 zlog_debug ("%s rcvd %s/%d%s, flapped quicker than processing",
2521 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2522 p
->prefixlen
, buf2
);
2524 bgp_info_restore (rn
, ri
);
2527 /* Received Logging. */
2528 if (bgp_debug_update(peer
, p
, NULL
, 1))
2530 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2531 zlog_debug ("%s rcvd %s/%d%s",
2533 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2534 p
->prefixlen
, buf2
);
2537 /* graceful restart STALE flag unset. */
2538 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2539 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2541 /* The attribute is changed. */
2542 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2544 /* implicit withdraw, decrement aggregate and pcount here.
2545 * only if update is accepted, they'll increment below.
2547 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2549 /* Update bgp route dampening information. */
2550 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2551 && peer
->sort
== BGP_PEER_EBGP
)
2553 /* This is implicit withdraw so we should update dampening
2555 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2556 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2559 if (safi
== SAFI_MPLS_VPN
) {
2560 struct bgp_node
*prn
= NULL
;
2561 struct bgp_table
*table
= NULL
;
2563 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2565 table
= (struct bgp_table
*)(prn
->info
);
2567 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2574 bgp_unlock_node(prn
);
2576 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2577 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2579 * Implicit withdraw case.
2581 ++vnc_implicit_withdraw
;
2582 vnc_import_bgp_del_route(bgp
, p
, ri
);
2583 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2588 /* Update to new attribute. */
2589 bgp_attr_unintern (&ri
->attr
);
2590 ri
->attr
= attr_new
;
2592 /* Update MPLS tag. */
2593 if (safi
== SAFI_MPLS_VPN
)
2594 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2597 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2599 if (vnc_implicit_withdraw
)
2602 * Add back the route with its new attributes (e.g., nexthop).
2603 * The route is still selected, until the route selection
2604 * queued by bgp_process actually runs. We have to make this
2605 * update to the VNC side immediately to avoid racing against
2606 * configuration changes (e.g., route-map changes) which
2607 * trigger re-importation of the entire RIB.
2609 vnc_import_bgp_add_route(bgp
, p
, ri
);
2610 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2615 /* Update bgp route dampening information. */
2616 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2617 && peer
->sort
== BGP_PEER_EBGP
)
2619 /* Now we do normal update dampening. */
2620 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2621 if (ret
== BGP_DAMP_SUPPRESSED
)
2623 bgp_unlock_node (rn
);
2628 /* Nexthop reachability check. */
2629 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2631 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2632 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2633 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2638 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2639 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2642 if (BGP_DEBUG(nht
, NHT
))
2644 char buf1
[INET6_ADDRSTRLEN
];
2645 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2646 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2648 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2652 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2655 if (safi
== SAFI_MPLS_VPN
)
2657 struct bgp_node
*prn
= NULL
;
2658 struct bgp_table
*table
= NULL
;
2660 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2663 table
= (struct bgp_table
*)(prn
->info
);
2665 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2672 bgp_unlock_node(prn
);
2676 /* Process change. */
2677 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2679 bgp_process (bgp
, rn
, afi
, safi
);
2680 bgp_unlock_node (rn
);
2683 } // End of implicit withdraw
2685 /* Received Logging. */
2686 if (bgp_debug_update(peer
, p
, NULL
, 1))
2688 if (!peer
->rcvd_attr_printed
)
2690 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2691 peer
->rcvd_attr_printed
= 1;
2694 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2695 zlog_debug ("%s rcvd %s/%d%s",
2697 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2698 p
->prefixlen
, buf2
);
2701 /* Make new BGP info. */
2702 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2704 /* Update MPLS tag. */
2705 if (safi
== SAFI_MPLS_VPN
)
2706 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2708 /* Nexthop reachability check. */
2709 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2711 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2712 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2713 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2718 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2719 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2722 if (BGP_DEBUG(nht
, NHT
))
2724 char buf1
[INET6_ADDRSTRLEN
];
2725 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2726 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2728 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2732 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2735 new->addpath_rx_id
= addpath_id
;
2737 /* Increment prefix */
2738 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2740 /* Register new BGP information. */
2741 bgp_info_add (rn
, new);
2743 /* route_node_get lock */
2744 bgp_unlock_node (rn
);
2747 if (safi
== SAFI_MPLS_VPN
)
2749 struct bgp_node
*prn
= NULL
;
2750 struct bgp_table
*table
= NULL
;
2752 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2755 table
= (struct bgp_table
*)(prn
->info
);
2757 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2764 bgp_unlock_node(prn
);
2768 /* If maximum prefix count is configured and current prefix
2770 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2773 /* Process change. */
2774 bgp_process (bgp
, rn
, afi
, safi
);
2778 /* This BGP update is filtered. Log the reason then update BGP
2781 if (bgp_debug_update(peer
, p
, NULL
, 1))
2783 if (!peer
->rcvd_attr_printed
)
2785 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2786 peer
->rcvd_attr_printed
= 1;
2789 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2790 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- DENIED due to: %s",
2792 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2793 p
->prefixlen
, buf2
, reason
);
2797 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2799 bgp_unlock_node (rn
);
2805 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2806 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2807 struct prefix_rd
*prd
, u_char
*tag
)
2810 char buf
[SU_ADDRSTRLEN
];
2812 struct bgp_node
*rn
;
2813 struct bgp_info
*ri
;
2818 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2820 /* If peer is soft reconfiguration enabled. Record input packet for
2821 * further calculation.
2823 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2824 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2825 * the iteration over all RS clients.
2826 * Since we need to remove the entry from adj_in anyway, do that first and
2827 * if there was no entry, we don't need to do anything more.
2829 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2830 && peer
!= bgp
->peer_self
)
2831 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2833 if (bgp_debug_update (peer
, p
, NULL
, 1))
2834 zlog_debug ("%s withdrawing route %s/%d "
2835 "not in adj-in", peer
->host
,
2836 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2838 bgp_unlock_node (rn
);
2842 /* Lookup withdrawn route. */
2843 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2844 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2845 ri
->addpath_rx_id
== addpath_id
)
2849 if (bgp_debug_update(peer
, p
, NULL
, 1))
2851 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2852 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- withdrawn",
2854 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2855 p
->prefixlen
, buf2
);
2858 /* Withdraw specified route from routing table. */
2859 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2860 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2861 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2862 zlog_debug ("%s Can't find the route %s/%d", peer
->host
,
2863 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2866 /* Unlock bgp_node_get() lock. */
2867 bgp_unlock_node (rn
);
2873 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2875 struct update_subgroup
*subgrp
;
2876 subgrp
= peer_subgroup(peer
, afi
, safi
);
2877 subgroup_default_originate(subgrp
, withdraw
);
2882 * bgp_stop_announce_route_timer
2885 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2887 if (!paf
->t_announce_route
)
2890 THREAD_TIMER_OFF (paf
->t_announce_route
);
2894 * bgp_announce_route_timer_expired
2896 * Callback that is invoked when the route announcement timer for a
2900 bgp_announce_route_timer_expired (struct thread
*t
)
2902 struct peer_af
*paf
;
2905 paf
= THREAD_ARG (t
);
2908 assert (paf
->t_announce_route
);
2909 paf
->t_announce_route
= NULL
;
2911 if (peer
->status
!= Established
)
2914 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
2917 peer_af_announce_route (paf
, 1);
2922 * bgp_announce_route
2924 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
2927 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
2929 struct peer_af
*paf
;
2930 struct update_subgroup
*subgrp
;
2932 paf
= peer_af_find (peer
, afi
, safi
);
2935 subgrp
= PAF_SUBGRP(paf
);
2938 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
2939 * or a refresh has already been triggered.
2941 if (!subgrp
|| paf
->t_announce_route
)
2945 * Start a timer to stagger/delay the announce. This serves
2946 * two purposes - announcement can potentially be combined for
2947 * multiple peers and the announcement doesn't happen in the
2950 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
2951 bgp_announce_route_timer_expired
, paf
,
2952 (subgrp
->peer_count
== 1) ?
2953 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
2954 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
2958 * Announce routes from all AF tables to a peer.
2960 * This should ONLY be called when there is a need to refresh the
2961 * routes to the peer based on a policy change for this peer alone
2962 * or a route refresh request received from the peer.
2963 * The operation will result in splitting the peer from its existing
2964 * subgroups and putting it in new subgroups.
2967 bgp_announce_route_all (struct peer
*peer
)
2972 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2973 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2974 bgp_announce_route (peer
, afi
, safi
);
2978 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
2979 struct bgp_table
*table
, struct prefix_rd
*prd
)
2982 struct bgp_node
*rn
;
2983 struct bgp_adj_in
*ain
;
2986 table
= peer
->bgp
->rib
[afi
][safi
];
2988 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
2989 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
2991 if (ain
->peer
== peer
)
2993 struct bgp_info
*ri
= rn
->info
;
2994 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
2996 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
2997 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3002 bgp_unlock_node (rn
);
3010 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3012 struct bgp_node
*rn
;
3013 struct bgp_table
*table
;
3015 if (peer
->status
!= Established
)
3018 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
))
3019 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3021 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3022 rn
= bgp_route_next (rn
))
3023 if ((table
= rn
->info
) != NULL
)
3025 struct prefix_rd prd
;
3026 prd
.family
= AF_UNSPEC
;
3028 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3030 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3035 struct bgp_clear_node_queue
3037 struct bgp_node
*rn
;
3040 static wq_item_status
3041 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3043 struct bgp_clear_node_queue
*cnq
= data
;
3044 struct bgp_node
*rn
= cnq
->rn
;
3045 struct peer
*peer
= wq
->spec
.data
;
3046 struct bgp_info
*ri
;
3047 afi_t afi
= bgp_node_table (rn
)->afi
;
3048 safi_t safi
= bgp_node_table (rn
)->safi
;
3050 assert (rn
&& peer
);
3052 /* It is possible that we have multiple paths for a prefix from a peer
3053 * if that peer is using AddPath.
3055 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3056 if (ri
->peer
== peer
)
3058 /* graceful restart STALE flag set. */
3059 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3060 && peer
->nsf
[afi
][safi
]
3061 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3062 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3063 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3065 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3071 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3073 struct bgp_clear_node_queue
*cnq
= data
;
3074 struct bgp_node
*rn
= cnq
->rn
;
3075 struct bgp_table
*table
= bgp_node_table (rn
);
3077 bgp_unlock_node (rn
);
3078 bgp_table_unlock (table
);
3079 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3083 bgp_clear_node_complete (struct work_queue
*wq
)
3085 struct peer
*peer
= wq
->spec
.data
;
3087 /* Tickle FSM to start moving again */
3088 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3090 peer_unlock (peer
); /* bgp_clear_route */
3094 bgp_clear_node_queue_init (struct peer
*peer
)
3096 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3098 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3099 #undef CLEAR_QUEUE_NAME_LEN
3101 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3103 zlog_err ("%s: Failed to allocate work queue", __func__
);
3106 peer
->clear_node_queue
->spec
.hold
= 10;
3107 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3108 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3109 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3110 peer
->clear_node_queue
->spec
.max_retries
= 0;
3112 /* we only 'lock' this peer reference when the queue is actually active */
3113 peer
->clear_node_queue
->spec
.data
= peer
;
3117 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3118 struct bgp_table
*table
)
3120 struct bgp_node
*rn
;
3121 int force
= bm
->process_main_queue
? 0 : 1;
3124 table
= peer
->bgp
->rib
[afi
][safi
];
3126 /* If still no table => afi/safi isn't configured at all or smth. */
3130 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3132 struct bgp_info
*ri
, *next
;
3133 struct bgp_adj_in
*ain
;
3134 struct bgp_adj_in
*ain_next
;
3136 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3137 * queued for every clearing peer, regardless of whether it is
3138 * relevant to the peer at hand.
3140 * Overview: There are 3 different indices which need to be
3141 * scrubbed, potentially, when a peer is removed:
3143 * 1 peer's routes visible via the RIB (ie accepted routes)
3144 * 2 peer's routes visible by the (optional) peer's adj-in index
3145 * 3 other routes visible by the peer's adj-out index
3147 * 3 there is no hurry in scrubbing, once the struct peer is
3148 * removed from bgp->peer, we could just GC such deleted peer's
3149 * adj-outs at our leisure.
3151 * 1 and 2 must be 'scrubbed' in some way, at least made
3152 * invisible via RIB index before peer session is allowed to be
3153 * brought back up. So one needs to know when such a 'search' is
3158 * - there'd be a single global queue or a single RIB walker
3159 * - rather than tracking which route_nodes still need to be
3160 * examined on a peer basis, we'd track which peers still
3163 * Given that our per-peer prefix-counts now should be reliable,
3164 * this may actually be achievable. It doesn't seem to be a huge
3165 * problem at this time,
3167 * It is possible that we have multiple paths for a prefix from a peer
3168 * if that peer is using AddPath.
3173 ain_next
= ain
->next
;
3175 if (ain
->peer
== peer
)
3177 bgp_adj_in_remove (rn
, ain
);
3178 bgp_unlock_node (rn
);
3184 for (ri
= rn
->info
; ri
; ri
= next
)
3187 if (ri
->peer
!= peer
)
3191 bgp_info_reap (rn
, ri
);
3194 struct bgp_clear_node_queue
*cnq
;
3196 /* both unlocked in bgp_clear_node_queue_del */
3197 bgp_table_lock (bgp_node_table (rn
));
3199 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3200 sizeof (struct bgp_clear_node_queue
));
3202 work_queue_add (peer
->clear_node_queue
, cnq
);
3211 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3213 struct bgp_node
*rn
;
3214 struct bgp_table
*table
;
3216 if (peer
->clear_node_queue
== NULL
)
3217 bgp_clear_node_queue_init (peer
);
3219 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3220 * Idle until it receives a Clearing_Completed event. This protects
3221 * against peers which flap faster than we can we clear, which could
3224 * a) race with routes from the new session being installed before
3225 * clear_route_node visits the node (to delete the route of that
3227 * b) resource exhaustion, clear_route_node likely leads to an entry
3228 * on the process_main queue. Fast-flapping could cause that queue
3232 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3233 * the unlock will happen upon work-queue completion; other wise, the
3234 * unlock happens at the end of this function.
3236 if (!peer
->clear_node_queue
->thread
)
3239 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
)
3240 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3242 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3243 rn
= bgp_route_next (rn
))
3244 if ((table
= rn
->info
) != NULL
)
3245 bgp_clear_route_table (peer
, afi
, safi
, table
);
3247 /* unlock if no nodes got added to the clear-node-queue. */
3248 if (!peer
->clear_node_queue
->thread
)
3254 bgp_clear_route_all (struct peer
*peer
)
3259 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3260 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3261 bgp_clear_route (peer
, afi
, safi
);
3264 rfapiProcessPeerDown(peer
);
3269 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3271 struct bgp_table
*table
;
3272 struct bgp_node
*rn
;
3273 struct bgp_adj_in
*ain
;
3274 struct bgp_adj_in
*ain_next
;
3276 table
= peer
->bgp
->rib
[afi
][safi
];
3278 /* It is possible that we have multiple paths for a prefix from a peer
3279 * if that peer is using AddPath.
3281 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3287 ain_next
= ain
->next
;
3289 if (ain
->peer
== peer
)
3291 bgp_adj_in_remove (rn
, ain
);
3292 bgp_unlock_node (rn
);
3301 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3303 struct bgp_node
*rn
;
3304 struct bgp_info
*ri
;
3305 struct bgp_table
*table
;
3307 if ( safi
== SAFI_MPLS_VPN
)
3309 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3311 struct bgp_node
*rm
;
3312 struct bgp_info
*ri
;
3314 /* look for neighbor in tables */
3315 if ((table
= rn
->info
) != NULL
)
3317 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3318 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3319 if (ri
->peer
== peer
)
3321 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3322 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3330 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3331 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3332 if (ri
->peer
== peer
)
3334 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3335 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3342 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3344 struct bgp_node
*rn
;
3345 struct bgp_info
*ri
;
3346 struct bgp_info
*next
;
3348 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3349 for (ri
= rn
->info
; ri
; ri
= next
)
3352 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3353 && ri
->type
== ZEBRA_ROUTE_BGP
3354 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3355 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3358 if (table
->owner
&& table
->owner
->bgp
)
3359 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3361 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3362 bgp_info_reap (rn
, ri
);
3367 /* Delete all kernel routes. */
3369 bgp_cleanup_routes (struct bgp
*bgp
)
3373 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3375 struct bgp_node
*rn
;
3377 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3380 * VPN and ENCAP tables are two-level (RD is top level)
3382 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
3383 rn
= bgp_route_next (rn
))
3387 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_MPLS_VPN
);
3388 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3390 bgp_unlock_node(rn
);
3394 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_ENCAP
]); rn
;
3395 rn
= bgp_route_next (rn
))
3399 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_ENCAP
);
3400 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3402 bgp_unlock_node(rn
);
3412 bgp_zclient_reset ();
3413 access_list_reset ();
3414 prefix_list_reset ();
3418 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3420 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3421 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3424 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3427 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3428 struct bgp_nlri
*packet
)
3437 int addpath_encoded
;
3438 u_int32_t addpath_id
;
3440 /* Check peer status. */
3441 if (peer
->status
!= Established
)
3445 lim
= pnt
+ packet
->length
;
3447 safi
= packet
->safi
;
3449 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3451 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3452 syntactic validity. If the field is syntactically incorrect,
3453 then the Error Subcode is set to Invalid Network Field. */
3454 for (; pnt
< lim
; pnt
+= psize
)
3456 /* Clear prefix structure. */
3457 memset (&p
, 0, sizeof (struct prefix
));
3459 if (addpath_encoded
)
3462 /* When packet overflow occurs return immediately. */
3463 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3466 addpath_id
= ntohl(*((uint32_t*) pnt
));
3467 pnt
+= BGP_ADDPATH_ID_LEN
;
3470 /* Fetch prefix length. */
3471 p
.prefixlen
= *pnt
++;
3472 /* afi/safi validity already verified by caller, bgp_update_receive */
3473 p
.family
= afi2family (afi
);
3475 /* Prefix length check. */
3476 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3478 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3479 peer
->host
, p
.prefixlen
, packet
->afi
);
3483 /* Packet size overflow check. */
3484 psize
= PSIZE (p
.prefixlen
);
3486 /* When packet overflow occur return immediately. */
3487 if (pnt
+ psize
> lim
)
3489 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3490 peer
->host
, p
.prefixlen
);
3494 /* Defensive coding, double-check the psize fits in a struct prefix */
3495 if (psize
> (ssize_t
) sizeof(p
.u
))
3497 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3498 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3502 /* Fetch prefix from NLRI packet. */
3503 memcpy (&p
.u
.prefix
, pnt
, psize
);
3505 /* Check address. */
3506 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3508 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3510 /* From RFC4271 Section 6.3:
3512 * If a prefix in the NLRI field is semantically incorrect
3513 * (e.g., an unexpected multicast IP address), an error SHOULD
3514 * be logged locally, and the prefix SHOULD be ignored.
3516 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3517 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3522 /* Check address. */
3523 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3525 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3529 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3530 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3534 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3538 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3539 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3545 /* Normal process. */
3547 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3548 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0);
3550 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3551 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
);
3553 /* Address family configuration mismatch or maximum-prefix count
3559 /* Packet length consistency check. */
3562 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3570 static struct bgp_static
*
3571 bgp_static_new (void)
3573 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3577 bgp_static_free (struct bgp_static
*bgp_static
)
3579 if (bgp_static
->rmap
.name
)
3580 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3581 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3585 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3586 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3588 struct bgp_node
*rn
;
3589 struct bgp_info
*ri
;
3590 struct bgp_info
*new;
3591 struct bgp_info info
;
3593 struct attr
*attr_new
;
3596 int vnc_implicit_withdraw
= 0;
3599 assert (bgp_static
);
3603 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3605 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3607 attr
.nexthop
= bgp_static
->igpnexthop
;
3608 attr
.med
= bgp_static
->igpmetric
;
3609 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3611 if (bgp_static
->atomic
)
3612 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3614 /* Apply route-map. */
3615 if (bgp_static
->rmap
.name
)
3617 struct attr attr_tmp
= attr
;
3618 info
.peer
= bgp
->peer_self
;
3619 info
.attr
= &attr_tmp
;
3621 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3623 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3625 bgp
->peer_self
->rmap_type
= 0;
3627 if (ret
== RMAP_DENYMATCH
)
3629 /* Free uninterned attribute. */
3630 bgp_attr_flush (&attr_tmp
);
3632 /* Unintern original. */
3633 aspath_unintern (&attr
.aspath
);
3634 bgp_attr_extra_free (&attr
);
3635 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3638 attr_new
= bgp_attr_intern (&attr_tmp
);
3641 attr_new
= bgp_attr_intern (&attr
);
3643 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3644 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3645 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3650 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3651 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3652 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3654 bgp_unlock_node (rn
);
3655 bgp_attr_unintern (&attr_new
);
3656 aspath_unintern (&attr
.aspath
);
3657 bgp_attr_extra_free (&attr
);
3662 /* The attribute is changed. */
3663 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3665 /* Rewrite BGP route information. */
3666 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3667 bgp_info_restore(rn
, ri
);
3669 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3671 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3673 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3676 * Implicit withdraw case.
3677 * We have to do this before ri is changed
3679 ++vnc_implicit_withdraw
;
3680 vnc_import_bgp_del_route(bgp
, p
, ri
);
3681 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3685 bgp_attr_unintern (&ri
->attr
);
3686 ri
->attr
= attr_new
;
3687 ri
->uptime
= bgp_clock ();
3689 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3691 if (vnc_implicit_withdraw
)
3693 vnc_import_bgp_add_route(bgp
, p
, ri
);
3694 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3699 /* Nexthop reachability check. */
3700 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3702 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3703 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3706 if (BGP_DEBUG(nht
, NHT
))
3708 char buf1
[INET6_ADDRSTRLEN
];
3709 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3711 zlog_debug("%s(%s): Route not in table, not advertising",
3712 __FUNCTION__
, buf1
);
3714 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3719 /* Delete the NHT structure if any, if we're toggling between
3720 * enabling/disabling import check. We deregister the route
3721 * from NHT to avoid overloading NHT and the process interaction
3723 bgp_unlink_nexthop(ri
);
3724 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3726 /* Process change. */
3727 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3728 bgp_process (bgp
, rn
, afi
, safi
);
3729 bgp_unlock_node (rn
);
3730 aspath_unintern (&attr
.aspath
);
3731 bgp_attr_extra_free (&attr
);
3736 /* Make new BGP info. */
3737 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3739 /* Nexthop reachability check. */
3740 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3742 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3743 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3746 if (BGP_DEBUG(nht
, NHT
))
3748 char buf1
[INET6_ADDRSTRLEN
];
3749 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3751 zlog_debug("%s(%s): Route not in table, not advertising",
3752 __FUNCTION__
, buf1
);
3754 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3759 /* Delete the NHT structure if any, if we're toggling between
3760 * enabling/disabling import check. We deregister the route
3761 * from NHT to avoid overloading NHT and the process interaction
3763 bgp_unlink_nexthop(new);
3765 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3768 /* Aggregate address increment. */
3769 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3771 /* Register new BGP information. */
3772 bgp_info_add (rn
, new);
3774 /* route_node_get lock */
3775 bgp_unlock_node (rn
);
3777 /* Process change. */
3778 bgp_process (bgp
, rn
, afi
, safi
);
3780 /* Unintern original. */
3781 aspath_unintern (&attr
.aspath
);
3782 bgp_attr_extra_free (&attr
);
3786 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3787 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3789 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3793 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3796 struct bgp_node
*rn
;
3797 struct bgp_info
*ri
;
3799 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3801 /* Check selected route and self inserted route. */
3802 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3803 if (ri
->peer
== bgp
->peer_self
3804 && ri
->type
== ZEBRA_ROUTE_BGP
3805 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3808 /* Withdraw static BGP route from routing table. */
3811 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3812 bgp_unlink_nexthop(ri
);
3813 bgp_info_delete (rn
, ri
);
3814 bgp_process (bgp
, rn
, afi
, safi
);
3817 /* Unlock bgp_node_lookup. */
3818 bgp_unlock_node (rn
);
3822 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3825 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3826 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3828 struct bgp_node
*rn
;
3829 struct bgp_info
*ri
;
3831 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3833 /* Check selected route and self inserted route. */
3834 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3835 if (ri
->peer
== bgp
->peer_self
3836 && ri
->type
== ZEBRA_ROUTE_BGP
3837 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3840 /* Withdraw static BGP route from routing table. */
3844 rfapiProcessWithdraw(
3853 1); /* Kill, since it is an administrative change */
3855 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3856 bgp_info_delete (rn
, ri
);
3857 bgp_process (bgp
, rn
, afi
, safi
);
3860 /* Unlock bgp_node_lookup. */
3861 bgp_unlock_node (rn
);
3865 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3866 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3868 struct bgp_node
*rn
;
3869 struct bgp_info
*new;
3870 struct attr
*attr_new
;
3871 struct attr attr
= { 0 };
3872 struct bgp_info
*ri
;
3874 u_int32_t label
= 0;
3877 assert (bgp_static
);
3879 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
3881 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3883 attr
.nexthop
= bgp_static
->igpnexthop
;
3884 attr
.med
= bgp_static
->igpmetric
;
3885 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3887 /* Apply route-map. */
3888 if (bgp_static
->rmap
.name
)
3890 struct attr attr_tmp
= attr
;
3891 struct bgp_info info
;
3894 info
.peer
= bgp
->peer_self
;
3895 info
.attr
= &attr_tmp
;
3897 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3899 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3901 bgp
->peer_self
->rmap_type
= 0;
3903 if (ret
== RMAP_DENYMATCH
)
3905 /* Free uninterned attribute. */
3906 bgp_attr_flush (&attr_tmp
);
3908 /* Unintern original. */
3909 aspath_unintern (&attr
.aspath
);
3910 bgp_attr_extra_free (&attr
);
3911 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
3916 attr_new
= bgp_attr_intern (&attr_tmp
);
3920 attr_new
= bgp_attr_intern (&attr
);
3923 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3924 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3925 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3930 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3931 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3933 bgp_unlock_node (rn
);
3934 bgp_attr_unintern (&attr_new
);
3935 aspath_unintern (&attr
.aspath
);
3936 bgp_attr_extra_free (&attr
);
3941 /* The attribute is changed. */
3942 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3944 /* Rewrite BGP route information. */
3945 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3946 bgp_info_restore(rn
, ri
);
3948 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3949 bgp_attr_unintern (&ri
->attr
);
3950 ri
->attr
= attr_new
;
3951 ri
->uptime
= bgp_clock ();
3954 label
= decode_label (ri
->extra
->tag
);
3957 /* Process change. */
3958 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3959 bgp_process (bgp
, rn
, afi
, safi
);
3961 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
3962 ri
->attr
, afi
, safi
,
3963 ri
->type
, ri
->sub_type
, &label
);
3965 bgp_unlock_node (rn
);
3966 aspath_unintern (&attr
.aspath
);
3967 bgp_attr_extra_free (&attr
);
3973 /* Make new BGP info. */
3974 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3976 SET_FLAG (new->flags
, BGP_INFO_VALID
);
3977 new->extra
= bgp_info_extra_new();
3978 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
3980 label
= decode_label (bgp_static
->tag
);
3983 /* Aggregate address increment. */
3984 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3986 /* Register new BGP information. */
3987 bgp_info_add (rn
, new);
3989 /* route_node_get lock */
3990 bgp_unlock_node (rn
);
3992 /* Process change. */
3993 bgp_process (bgp
, rn
, afi
, safi
);
3996 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
3997 new->attr
, afi
, safi
,
3998 new->type
, new->sub_type
, &label
);
4001 /* Unintern original. */
4002 aspath_unintern (&attr
.aspath
);
4003 bgp_attr_extra_free (&attr
);
4006 /* Configure static BGP network. When user don't run zebra, static
4007 route should be installed as valid. */
4009 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4010 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4012 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4015 struct bgp_static
*bgp_static
;
4016 struct bgp_node
*rn
;
4017 u_char need_update
= 0;
4019 /* Convert IP prefix string to struct prefix. */
4020 ret
= str2prefix (ip_str
, &p
);
4023 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4026 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4028 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4035 /* Set BGP static route configuration. */
4036 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4040 /* Configuration change. */
4041 bgp_static
= rn
->info
;
4043 /* Check previous routes are installed into BGP. */
4044 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4047 bgp_static
->backdoor
= backdoor
;
4051 if (bgp_static
->rmap
.name
)
4052 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4053 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4054 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4058 if (bgp_static
->rmap
.name
)
4059 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4060 bgp_static
->rmap
.name
= NULL
;
4061 bgp_static
->rmap
.map
= NULL
;
4062 bgp_static
->valid
= 0;
4064 bgp_unlock_node (rn
);
4068 /* New configuration. */
4069 bgp_static
= bgp_static_new ();
4070 bgp_static
->backdoor
= backdoor
;
4071 bgp_static
->valid
= 0;
4072 bgp_static
->igpmetric
= 0;
4073 bgp_static
->igpnexthop
.s_addr
= 0;
4077 if (bgp_static
->rmap
.name
)
4078 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4079 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4080 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4082 rn
->info
= bgp_static
;
4085 bgp_static
->valid
= 1;
4087 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4089 if (! bgp_static
->backdoor
)
4090 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4095 /* Configure static BGP network. */
4097 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4098 afi_t afi
, safi_t safi
)
4100 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4103 struct bgp_static
*bgp_static
;
4104 struct bgp_node
*rn
;
4106 /* Convert IP prefix string to struct prefix. */
4107 ret
= str2prefix (ip_str
, &p
);
4110 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4113 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4115 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4122 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4125 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4130 bgp_static
= rn
->info
;
4132 /* Update BGP RIB. */
4133 if (! bgp_static
->backdoor
)
4134 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4136 /* Clear configuration. */
4137 bgp_static_free (bgp_static
);
4139 bgp_unlock_node (rn
);
4140 bgp_unlock_node (rn
);
4146 bgp_static_add (struct bgp
*bgp
)
4150 struct bgp_node
*rn
;
4151 struct bgp_node
*rm
;
4152 struct bgp_table
*table
;
4153 struct bgp_static
*bgp_static
;
4155 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4156 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4157 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4158 if (rn
->info
!= NULL
)
4160 if (safi
== SAFI_MPLS_VPN
)
4164 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4166 bgp_static
= rn
->info
;
4167 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4172 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4177 /* Called from bgp_delete(). Delete all static routes from the BGP
4180 bgp_static_delete (struct bgp
*bgp
)
4184 struct bgp_node
*rn
;
4185 struct bgp_node
*rm
;
4186 struct bgp_table
*table
;
4187 struct bgp_static
*bgp_static
;
4189 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4190 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4191 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4192 if (rn
->info
!= NULL
)
4194 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4198 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4200 bgp_static
= rn
->info
;
4201 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4203 (struct prefix_rd
*)&rn
->p
,
4205 bgp_static_free (bgp_static
);
4207 bgp_unlock_node (rn
);
4212 bgp_static
= rn
->info
;
4213 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4214 bgp_static_free (bgp_static
);
4216 bgp_unlock_node (rn
);
4222 bgp_static_redo_import_check (struct bgp
*bgp
)
4226 struct bgp_node
*rn
;
4227 struct bgp_static
*bgp_static
;
4229 /* Use this flag to force reprocessing of the route */
4230 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4231 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4232 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4233 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4234 if (rn
->info
!= NULL
)
4236 bgp_static
= rn
->info
;
4237 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4239 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4243 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4245 struct bgp_table
*table
;
4246 struct bgp_node
*rn
;
4247 struct bgp_info
*ri
;
4249 table
= bgp
->rib
[afi
][safi
];
4250 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4252 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4254 if (ri
->peer
== bgp
->peer_self
&&
4255 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4256 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4257 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4258 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4260 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4261 bgp_unlink_nexthop(ri
);
4262 bgp_info_delete (rn
, ri
);
4263 bgp_process (bgp
, rn
, afi
, safi
);
4270 * Purge all networks and redistributed routes from routing table.
4271 * Invoked upon the instance going down.
4274 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4279 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4280 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4281 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4286 * Currently this is used to set static routes for VPN and ENCAP.
4287 * I think it can probably be factored with bgp_static_set.
4290 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4291 const char *rd_str
, const char *tag_str
,
4292 const char *rmap_str
)
4294 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4297 struct prefix_rd prd
;
4298 struct bgp_node
*prn
;
4299 struct bgp_node
*rn
;
4300 struct bgp_table
*table
;
4301 struct bgp_static
*bgp_static
;
4305 ret
= str2prefix (ip_str
, &p
);
4308 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4313 ret
= str2prefix_rd (rd_str
, &prd
);
4316 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4320 ret
= str2tag (tag_str
, tag
);
4323 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4326 if (p
.family
== AF_INET
)
4328 else if (p
.family
== AF_INET6
)
4332 vty_out (vty
, "%% Non Supported prefix%s", VTY_NEWLINE
);
4335 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4336 (struct prefix
*)&prd
);
4337 if (prn
->info
== NULL
)
4338 prn
->info
= bgp_table_init (afi
, safi
);
4340 bgp_unlock_node (prn
);
4343 rn
= bgp_node_get (table
, &p
);
4347 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4348 bgp_unlock_node (rn
);
4352 /* New configuration. */
4353 bgp_static
= bgp_static_new ();
4354 bgp_static
->backdoor
= 0;
4355 bgp_static
->valid
= 0;
4356 bgp_static
->igpmetric
= 0;
4357 bgp_static
->igpnexthop
.s_addr
= 0;
4358 memcpy(bgp_static
->tag
, tag
, 3);
4359 bgp_static
->prd
= prd
;
4363 if (bgp_static
->rmap
.name
)
4364 free (bgp_static
->rmap
.name
);
4365 bgp_static
->rmap
.name
= strdup (rmap_str
);
4366 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4368 rn
->info
= bgp_static
;
4370 bgp_static
->valid
= 1;
4371 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4377 /* Configure static BGP network. */
4379 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4380 const char *rd_str
, const char *tag_str
)
4382 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4385 struct prefix_rd prd
;
4386 struct bgp_node
*prn
;
4387 struct bgp_node
*rn
;
4388 struct bgp_table
*table
;
4389 struct bgp_static
*bgp_static
;
4392 /* Convert IP prefix string to struct prefix. */
4393 ret
= str2prefix (ip_str
, &p
);
4396 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4401 ret
= str2prefix_rd (rd_str
, &prd
);
4404 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4408 ret
= str2tag (tag_str
, tag
);
4411 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4415 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4416 (struct prefix
*)&prd
);
4417 if (prn
->info
== NULL
)
4418 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4420 bgp_unlock_node (prn
);
4423 rn
= bgp_node_lookup (table
, &p
);
4427 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4429 bgp_static
= rn
->info
;
4430 bgp_static_free (bgp_static
);
4432 bgp_unlock_node (rn
);
4433 bgp_unlock_node (rn
);
4436 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4442 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4443 const char *rmap_name
)
4445 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4446 struct bgp_rmap
*rmap
;
4448 rmap
= &bgp
->table_map
[afi
][safi
];
4452 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4453 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4454 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4459 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4464 bgp_zebra_announce_table(bgp
, afi
, safi
);
4470 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4471 const char *rmap_name
)
4473 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4474 struct bgp_rmap
*rmap
;
4476 rmap
= &bgp
->table_map
[afi
][safi
];
4478 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4482 bgp_zebra_announce_table(bgp
, afi
, safi
);
4488 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4489 safi_t safi
, int *write
)
4491 if (bgp
->table_map
[afi
][safi
].name
)
4493 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4494 vty_out (vty
, " table-map %s%s",
4495 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4501 DEFUN (bgp_table_map
,
4504 "BGP table to RIB route download filter\n"
4505 "Name of the route map\n")
4508 return bgp_table_map_set (vty
,
4509 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4511 DEFUN (no_bgp_table_map
,
4512 no_bgp_table_map_cmd
,
4513 "no table-map WORD",
4515 "BGP table to RIB route download filter\n"
4516 "Name of the route map\n")
4519 return bgp_table_map_unset (vty
,
4520 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4525 "network A.B.C.D/M",
4526 "Specify a network to announce via BGP\n"
4529 int idx_ipv4_prefixlen
= 1;
4530 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4531 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4534 DEFUN (bgp_network_route_map
,
4535 bgp_network_route_map_cmd
,
4536 "network A.B.C.D/M route-map WORD",
4537 "Specify a network to announce via BGP\n"
4539 "Route-map to modify the attributes\n"
4540 "Name of the route map\n")
4542 int idx_ipv4_prefixlen
= 1;
4544 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4545 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4548 DEFUN (bgp_network_backdoor
,
4549 bgp_network_backdoor_cmd
,
4550 "network A.B.C.D/M backdoor",
4551 "Specify a network to announce via BGP\n"
4553 "Specify a BGP backdoor route\n")
4555 int idx_ipv4_prefixlen
= 1;
4556 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4560 DEFUN (bgp_network_mask
,
4561 bgp_network_mask_cmd
,
4562 "network A.B.C.D mask A.B.C.D",
4563 "Specify a network to announce via BGP\n"
4571 char prefix_str
[BUFSIZ
];
4573 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4576 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4580 return bgp_static_set (vty
, prefix_str
,
4581 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4584 DEFUN (bgp_network_mask_route_map
,
4585 bgp_network_mask_route_map_cmd
,
4586 "network A.B.C.D mask A.B.C.D route-map WORD",
4587 "Specify a network to announce via BGP\n"
4591 "Route-map to modify the attributes\n"
4592 "Name of the route map\n")
4598 char prefix_str
[BUFSIZ
];
4600 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4603 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4607 return bgp_static_set (vty
, prefix_str
,
4608 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4611 DEFUN (bgp_network_mask_backdoor
,
4612 bgp_network_mask_backdoor_cmd
,
4613 "network A.B.C.D mask A.B.C.D backdoor",
4614 "Specify a network to announce via BGP\n"
4618 "Specify a BGP backdoor route\n")
4623 char prefix_str
[BUFSIZ
];
4625 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4628 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4632 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4636 DEFUN (bgp_network_mask_natural
,
4637 bgp_network_mask_natural_cmd
,
4639 "Specify a network to announce via BGP\n"
4644 char prefix_str
[BUFSIZ
];
4646 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4649 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4653 return bgp_static_set (vty
, prefix_str
,
4654 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4657 DEFUN (bgp_network_mask_natural_route_map
,
4658 bgp_network_mask_natural_route_map_cmd
,
4659 "network A.B.C.D route-map WORD",
4660 "Specify a network to announce via BGP\n"
4662 "Route-map to modify the attributes\n"
4663 "Name of the route map\n")
4668 char prefix_str
[BUFSIZ
];
4670 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4673 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4677 return bgp_static_set (vty
, prefix_str
,
4678 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4681 DEFUN (bgp_network_mask_natural_backdoor
,
4682 bgp_network_mask_natural_backdoor_cmd
,
4683 "network A.B.C.D backdoor",
4684 "Specify a network to announce via BGP\n"
4686 "Specify a BGP backdoor route\n")
4690 char prefix_str
[BUFSIZ
];
4692 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4695 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4699 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4703 DEFUN (no_bgp_network
,
4705 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4707 "Specify a network to announce via BGP\n"
4709 "Specify a BGP backdoor route\n"
4710 "Route-map to modify the attributes\n"
4711 "Name of the route map\n")
4713 int idx_ipv4_prefixlen
= 2;
4714 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4715 bgp_node_safi (vty
));
4718 DEFUN (no_bgp_network_mask
,
4719 no_bgp_network_mask_cmd
,
4720 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4722 "Specify a network to announce via BGP\n"
4726 "Specify a BGP backdoor route\n"
4727 "Route-map to modify the attributes\n"
4728 "Name of the route map\n")
4733 char prefix_str
[BUFSIZ
];
4735 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4738 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4742 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4743 bgp_node_safi (vty
));
4746 DEFUN (no_bgp_network_mask_natural
,
4747 no_bgp_network_mask_natural_cmd
,
4748 "no network A.B.C.D [<backdoor|route-map WORD>]",
4750 "Specify a network to announce via BGP\n"
4752 "Specify a BGP backdoor route\n"
4753 "Route-map to modify the attributes\n"
4754 "Name of the route map\n")
4758 char prefix_str
[BUFSIZ
];
4760 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4763 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4767 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4768 bgp_node_safi (vty
));
4771 DEFUN (ipv6_bgp_network
,
4772 ipv6_bgp_network_cmd
,
4773 "network X:X::X:X/M",
4774 "Specify a network to announce via BGP\n"
4777 int idx_ipv6_prefixlen
= 1;
4778 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4782 DEFUN (ipv6_bgp_network_route_map
,
4783 ipv6_bgp_network_route_map_cmd
,
4784 "network X:X::X:X/M route-map WORD",
4785 "Specify a network to announce via BGP\n"
4787 "Route-map to modify the attributes\n"
4788 "Name of the route map\n")
4790 int idx_ipv6_prefixlen
= 1;
4792 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4793 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4796 DEFUN (no_ipv6_bgp_network
,
4797 no_ipv6_bgp_network_cmd
,
4798 "no network X:X::X:X/M [route-map WORD]",
4800 "Specify a network to announce via BGP\n"
4802 "Route-map to modify the attributes\n"
4803 "Name of the route map\n")
4805 int idx_ipv6_prefixlen
= 2;
4806 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4809 /* Aggreagete address:
4811 advertise-map Set condition to advertise attribute
4812 as-set Generate AS set path information
4813 attribute-map Set attributes of aggregate
4814 route-map Set parameters of aggregate
4815 summary-only Filter more specific routes from updates
4816 suppress-map Conditionally filter more specific routes from updates
4819 struct bgp_aggregate
4821 /* Summary-only flag. */
4822 u_char summary_only
;
4824 /* AS set generation. */
4827 /* Route-map for aggregated route. */
4828 struct route_map
*map
;
4830 /* Suppress-count. */
4831 unsigned long count
;
4833 /* SAFI configuration. */
4837 static struct bgp_aggregate
*
4838 bgp_aggregate_new (void)
4840 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4844 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4846 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4849 /* Update an aggregate as routes are added/removed from the BGP table */
4851 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4852 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4853 struct bgp_aggregate
*aggregate
)
4855 struct bgp_table
*table
;
4856 struct bgp_node
*top
;
4857 struct bgp_node
*rn
;
4859 struct aspath
*aspath
= NULL
;
4860 struct aspath
*asmerge
= NULL
;
4861 struct community
*community
= NULL
;
4862 struct community
*commerge
= NULL
;
4863 #if defined(AGGREGATE_NEXTHOP_CHECK)
4864 struct in_addr nexthop
;
4867 struct bgp_info
*ri
;
4868 struct bgp_info
*new;
4870 unsigned long match
= 0;
4871 u_char atomic_aggregate
= 0;
4873 /* Record adding route's nexthop and med. */
4876 #if defined(AGGREGATE_NEXTHOP_CHECK)
4877 nexthop
= rinew
->attr
->nexthop
;
4878 med
= rinew
->attr
->med
;
4882 /* ORIGIN attribute: If at least one route among routes that are
4883 aggregated has ORIGIN with the value INCOMPLETE, then the
4884 aggregated route must have the ORIGIN attribute with the value
4885 INCOMPLETE. Otherwise, if at least one route among routes that
4886 are aggregated has ORIGIN with the value EGP, then the aggregated
4887 route must have the origin attribute with the value EGP. In all
4888 other case the value of the ORIGIN attribute of the aggregated
4889 route is INTERNAL. */
4890 origin
= BGP_ORIGIN_IGP
;
4892 table
= bgp
->rib
[afi
][safi
];
4894 top
= bgp_node_get (table
, p
);
4895 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
4896 if (rn
->p
.prefixlen
> p
->prefixlen
)
4900 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4902 if (BGP_INFO_HOLDDOWN (ri
))
4905 if (del
&& ri
== del
)
4908 if (! rinew
&& first
)
4910 #if defined(AGGREGATE_NEXTHOP_CHECK)
4911 nexthop
= ri
->attr
->nexthop
;
4912 med
= ri
->attr
->med
;
4917 #ifdef AGGREGATE_NEXTHOP_CHECK
4918 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
4919 || ri
->attr
->med
!= med
)
4922 aspath_free (aspath
);
4924 community_free (community
);
4925 bgp_unlock_node (rn
);
4926 bgp_unlock_node (top
);
4929 #endif /* AGGREGATE_NEXTHOP_CHECK */
4931 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
4932 atomic_aggregate
= 1;
4934 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
4936 if (aggregate
->summary_only
)
4938 (bgp_info_extra_get (ri
))->suppress
++;
4939 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4945 if (origin
< ri
->attr
->origin
)
4946 origin
= ri
->attr
->origin
;
4948 if (aggregate
->as_set
)
4952 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
4953 aspath_free (aspath
);
4957 aspath
= aspath_dup (ri
->attr
->aspath
);
4959 if (ri
->attr
->community
)
4963 commerge
= community_merge (community
,
4964 ri
->attr
->community
);
4965 community
= community_uniq_sort (commerge
);
4966 community_free (commerge
);
4969 community
= community_dup (ri
->attr
->community
);
4975 bgp_process (bgp
, rn
, afi
, safi
);
4977 bgp_unlock_node (top
);
4983 if (aggregate
->summary_only
)
4984 (bgp_info_extra_get (rinew
))->suppress
++;
4986 if (origin
< rinew
->attr
->origin
)
4987 origin
= rinew
->attr
->origin
;
4989 if (aggregate
->as_set
)
4993 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
4994 aspath_free (aspath
);
4998 aspath
= aspath_dup (rinew
->attr
->aspath
);
5000 if (rinew
->attr
->community
)
5004 commerge
= community_merge (community
,
5005 rinew
->attr
->community
);
5006 community
= community_uniq_sort (commerge
);
5007 community_free (commerge
);
5010 community
= community_dup (rinew
->attr
->community
);
5015 if (aggregate
->count
> 0)
5017 rn
= bgp_node_get (table
, p
);
5018 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5019 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5021 atomic_aggregate
), rn
);
5022 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5024 bgp_info_add (rn
, new);
5025 bgp_unlock_node (rn
);
5026 bgp_process (bgp
, rn
, afi
, safi
);
5031 aspath_free (aspath
);
5033 community_free (community
);
5037 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5038 struct bgp_aggregate
*);
5041 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5042 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5044 struct bgp_node
*child
;
5045 struct bgp_node
*rn
;
5046 struct bgp_aggregate
*aggregate
;
5047 struct bgp_table
*table
;
5049 /* MPLS-VPN aggregation is not yet supported. */
5050 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5053 table
= bgp
->aggregate
[afi
][safi
];
5055 /* No aggregates configured. */
5056 if (bgp_table_top_nolock (table
) == NULL
)
5059 if (p
->prefixlen
== 0)
5062 if (BGP_INFO_HOLDDOWN (ri
))
5065 child
= bgp_node_get (table
, p
);
5067 /* Aggregate address configuration check. */
5068 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5069 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5071 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5072 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5074 bgp_unlock_node (child
);
5078 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5079 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5081 struct bgp_node
*child
;
5082 struct bgp_node
*rn
;
5083 struct bgp_aggregate
*aggregate
;
5084 struct bgp_table
*table
;
5086 /* MPLS-VPN aggregation is not yet supported. */
5087 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5090 table
= bgp
->aggregate
[afi
][safi
];
5092 /* No aggregates configured. */
5093 if (bgp_table_top_nolock (table
) == NULL
)
5096 if (p
->prefixlen
== 0)
5099 child
= bgp_node_get (table
, p
);
5101 /* Aggregate address configuration check. */
5102 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5103 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5105 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5106 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5108 bgp_unlock_node (child
);
5111 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5113 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5114 struct bgp_aggregate
*aggregate
)
5116 struct bgp_table
*table
;
5117 struct bgp_node
*top
;
5118 struct bgp_node
*rn
;
5119 struct bgp_info
*new;
5120 struct bgp_info
*ri
;
5121 unsigned long match
;
5122 u_char origin
= BGP_ORIGIN_IGP
;
5123 struct aspath
*aspath
= NULL
;
5124 struct aspath
*asmerge
= NULL
;
5125 struct community
*community
= NULL
;
5126 struct community
*commerge
= NULL
;
5127 u_char atomic_aggregate
= 0;
5129 table
= bgp
->rib
[afi
][safi
];
5132 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5134 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5137 /* If routes exists below this node, generate aggregate routes. */
5138 top
= bgp_node_get (table
, p
);
5139 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5140 if (rn
->p
.prefixlen
> p
->prefixlen
)
5144 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5146 if (BGP_INFO_HOLDDOWN (ri
))
5149 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5150 atomic_aggregate
= 1;
5152 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5154 /* summary-only aggregate route suppress aggregated
5155 route announcement. */
5156 if (aggregate
->summary_only
)
5158 (bgp_info_extra_get (ri
))->suppress
++;
5159 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5163 /* If at least one route among routes that are aggregated has
5164 * ORIGIN with the value INCOMPLETE, then the aggregated route
5165 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5166 * Otherwise, if at least one route among routes that are
5167 * aggregated has ORIGIN with the value EGP, then the aggregated
5168 * route MUST have the ORIGIN attribute with the value EGP.
5170 if (origin
< ri
->attr
->origin
)
5171 origin
= ri
->attr
->origin
;
5173 /* as-set aggregate route generate origin, as path,
5174 community aggregation. */
5175 if (aggregate
->as_set
)
5179 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5180 aspath_free (aspath
);
5184 aspath
= aspath_dup (ri
->attr
->aspath
);
5186 if (ri
->attr
->community
)
5190 commerge
= community_merge (community
,
5191 ri
->attr
->community
);
5192 community
= community_uniq_sort (commerge
);
5193 community_free (commerge
);
5196 community
= community_dup (ri
->attr
->community
);
5203 /* If this node is suppressed, process the change. */
5205 bgp_process (bgp
, rn
, afi
, safi
);
5207 bgp_unlock_node (top
);
5209 /* Add aggregate route to BGP table. */
5210 if (aggregate
->count
)
5212 rn
= bgp_node_get (table
, p
);
5213 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5214 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5216 atomic_aggregate
), rn
);
5217 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5219 bgp_info_add (rn
, new);
5220 bgp_unlock_node (rn
);
5222 /* Process change. */
5223 bgp_process (bgp
, rn
, afi
, safi
);
5228 aspath_free (aspath
);
5230 community_free (community
);
5235 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5236 safi_t safi
, struct bgp_aggregate
*aggregate
)
5238 struct bgp_table
*table
;
5239 struct bgp_node
*top
;
5240 struct bgp_node
*rn
;
5241 struct bgp_info
*ri
;
5242 unsigned long match
;
5244 table
= bgp
->rib
[afi
][safi
];
5246 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5248 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5251 /* If routes exists below this node, generate aggregate routes. */
5252 top
= bgp_node_get (table
, p
);
5253 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5254 if (rn
->p
.prefixlen
> p
->prefixlen
)
5258 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5260 if (BGP_INFO_HOLDDOWN (ri
))
5263 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5265 if (aggregate
->summary_only
&& ri
->extra
)
5267 ri
->extra
->suppress
--;
5269 if (ri
->extra
->suppress
== 0)
5271 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5279 /* If this node was suppressed, process the change. */
5281 bgp_process (bgp
, rn
, afi
, safi
);
5283 bgp_unlock_node (top
);
5285 /* Delete aggregate route from BGP table. */
5286 rn
= bgp_node_get (table
, p
);
5288 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5289 if (ri
->peer
== bgp
->peer_self
5290 && ri
->type
== ZEBRA_ROUTE_BGP
5291 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5294 /* Withdraw static BGP route from routing table. */
5297 bgp_info_delete (rn
, ri
);
5298 bgp_process (bgp
, rn
, afi
, safi
);
5301 /* Unlock bgp_node_lookup. */
5302 bgp_unlock_node (rn
);
5305 /* Aggregate route attribute. */
5306 #define AGGREGATE_SUMMARY_ONLY 1
5307 #define AGGREGATE_AS_SET 1
5310 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5311 afi_t afi
, safi_t safi
)
5313 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5316 struct bgp_node
*rn
;
5317 struct bgp_aggregate
*aggregate
;
5319 /* Convert string to prefix structure. */
5320 ret
= str2prefix (prefix_str
, &p
);
5323 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5328 /* Old configuration check. */
5329 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5332 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5337 aggregate
= rn
->info
;
5338 if (aggregate
->safi
& SAFI_UNICAST
)
5339 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5340 if (aggregate
->safi
& SAFI_MULTICAST
)
5341 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5343 /* Unlock aggregate address configuration. */
5345 bgp_aggregate_free (aggregate
);
5346 bgp_unlock_node (rn
);
5347 bgp_unlock_node (rn
);
5353 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5354 afi_t afi
, safi_t safi
,
5355 u_char summary_only
, u_char as_set
)
5357 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5360 struct bgp_node
*rn
;
5361 struct bgp_aggregate
*aggregate
;
5363 /* Convert string to prefix structure. */
5364 ret
= str2prefix (prefix_str
, &p
);
5367 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5372 /* Old configuration check. */
5373 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5377 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5378 /* try to remove the old entry */
5379 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5382 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5383 bgp_unlock_node (rn
);
5388 /* Make aggregate address structure. */
5389 aggregate
= bgp_aggregate_new ();
5390 aggregate
->summary_only
= summary_only
;
5391 aggregate
->as_set
= as_set
;
5392 aggregate
->safi
= safi
;
5393 rn
->info
= aggregate
;
5395 /* Aggregate address insert into BGP routing table. */
5396 if (safi
& SAFI_UNICAST
)
5397 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5398 if (safi
& SAFI_MULTICAST
)
5399 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5404 DEFUN (aggregate_address
,
5405 aggregate_address_cmd
,
5406 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5407 "Configure BGP aggregate entries\n"
5408 "Aggregate prefix\n"
5409 "Generate AS set path information\n"
5410 "Filter more specific routes from updates\n"
5411 "Filter more specific routes from updates\n"
5412 "Generate AS set path information\n")
5415 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5416 char *prefix
= argv
[idx
]->arg
;
5417 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5419 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5421 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5424 DEFUN (aggregate_address_mask
,
5425 aggregate_address_mask_cmd
,
5426 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5427 "Configure BGP aggregate entries\n"
5428 "Aggregate address\n"
5430 "Generate AS set path information\n"
5431 "Filter more specific routes from updates\n"
5432 "Filter more specific routes from updates\n"
5433 "Generate AS set path information\n")
5436 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5437 char *prefix
= argv
[idx
++]->arg
;
5438 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5439 char *mask
= argv
[idx
]->arg
;
5440 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5442 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5444 char prefix_str
[BUFSIZ
];
5445 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5449 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5453 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5456 DEFUN (no_aggregate_address
,
5457 no_aggregate_address_cmd
,
5458 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5460 "Configure BGP aggregate entries\n"
5461 "Aggregate prefix\n"
5462 "Generate AS set path information\n"
5463 "Filter more specific routes from updates\n"
5464 "Filter more specific routes from updates\n"
5465 "Generate AS set path information\n")
5468 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5469 char *prefix
= argv
[idx
]->arg
;
5470 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5473 DEFUN (no_aggregate_address_mask
,
5474 no_aggregate_address_mask_cmd
,
5475 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5477 "Configure BGP aggregate entries\n"
5478 "Aggregate address\n"
5480 "Generate AS set path information\n"
5481 "Filter more specific routes from updates\n"
5482 "Filter more specific routes from updates\n"
5483 "Generate AS set path information\n")
5486 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5487 char *prefix
= argv
[idx
++]->arg
;
5488 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5489 char *mask
= argv
[idx
]->arg
;
5491 char prefix_str
[BUFSIZ
];
5492 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5496 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5500 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5503 DEFUN (ipv6_aggregate_address
,
5504 ipv6_aggregate_address_cmd
,
5505 "aggregate-address X:X::X:X/M [summary-only]",
5506 "Configure BGP aggregate entries\n"
5507 "Aggregate prefix\n"
5508 "Filter more specific routes from updates\n")
5511 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5512 char *prefix
= argv
[idx
]->arg
;
5513 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5514 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5517 DEFUN (no_ipv6_aggregate_address
,
5518 no_ipv6_aggregate_address_cmd
,
5519 "no aggregate-address X:X::X:X/M [summary-only]",
5521 "Configure BGP aggregate entries\n"
5522 "Aggregate prefix\n"
5523 "Filter more specific routes from updates\n")
5526 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5527 char *prefix
= argv
[idx
]->arg
;
5528 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5531 /* Redistribute route treatment. */
5533 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5534 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5535 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5537 struct bgp_info
*new;
5538 struct bgp_info
*bi
;
5539 struct bgp_info info
;
5540 struct bgp_node
*bn
;
5542 struct attr
*new_attr
;
5545 struct bgp_redist
*red
;
5547 /* Make default attribute. */
5548 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5550 attr
.nexthop
= *nexthop
;
5551 attr
.nh_ifindex
= ifindex
;
5555 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5556 extra
->mp_nexthop_global
= *nexthop6
;
5557 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5561 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5562 attr
.extra
->tag
= tag
;
5564 afi
= family2afi (p
->family
);
5566 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5569 struct attr attr_new
;
5570 struct attr_extra extra_new
;
5572 /* Copy attribute for modification. */
5573 attr_new
.extra
= &extra_new
;
5574 bgp_attr_dup (&attr_new
, &attr
);
5576 if (red
->redist_metric_flag
)
5577 attr_new
.med
= red
->redist_metric
;
5579 /* Apply route-map. */
5582 info
.peer
= bgp
->peer_self
;
5583 info
.attr
= &attr_new
;
5585 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5587 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5589 bgp
->peer_self
->rmap_type
= 0;
5591 if (ret
== RMAP_DENYMATCH
)
5593 /* Free uninterned attribute. */
5594 bgp_attr_flush (&attr_new
);
5596 /* Unintern original. */
5597 aspath_unintern (&attr
.aspath
);
5598 bgp_attr_extra_free (&attr
);
5599 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5604 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5605 afi
, SAFI_UNICAST
, p
, NULL
);
5607 new_attr
= bgp_attr_intern (&attr_new
);
5609 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5610 if (bi
->peer
== bgp
->peer_self
5611 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5616 /* Ensure the (source route) type is updated. */
5618 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5619 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5621 bgp_attr_unintern (&new_attr
);
5622 aspath_unintern (&attr
.aspath
);
5623 bgp_attr_extra_free (&attr
);
5624 bgp_unlock_node (bn
);
5629 /* The attribute is changed. */
5630 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5632 /* Rewrite BGP route information. */
5633 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5634 bgp_info_restore(bn
, bi
);
5636 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5637 bgp_attr_unintern (&bi
->attr
);
5638 bi
->attr
= new_attr
;
5639 bi
->uptime
= bgp_clock ();
5641 /* Process change. */
5642 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5643 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5644 bgp_unlock_node (bn
);
5645 aspath_unintern (&attr
.aspath
);
5646 bgp_attr_extra_free (&attr
);
5651 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5653 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5655 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5656 bgp_info_add (bn
, new);
5657 bgp_unlock_node (bn
);
5658 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5661 /* Unintern original. */
5662 aspath_unintern (&attr
.aspath
);
5663 bgp_attr_extra_free (&attr
);
5667 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5670 struct bgp_node
*rn
;
5671 struct bgp_info
*ri
;
5672 struct bgp_redist
*red
;
5674 afi
= family2afi (p
->family
);
5676 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5679 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5681 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5682 if (ri
->peer
== bgp
->peer_self
5683 && ri
->type
== type
)
5688 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5689 bgp_info_delete (rn
, ri
);
5690 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5692 bgp_unlock_node (rn
);
5696 /* Withdraw specified route type's route. */
5698 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5700 struct bgp_node
*rn
;
5701 struct bgp_info
*ri
;
5702 struct bgp_table
*table
;
5704 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5706 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5708 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5709 if (ri
->peer
== bgp
->peer_self
5711 && ri
->instance
== instance
)
5716 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5717 bgp_info_delete (rn
, ri
);
5718 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5723 /* Static function to display route. */
5725 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5728 u_int32_t destination
;
5731 if (p
->family
== AF_INET
)
5733 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5734 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5736 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5737 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5738 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5739 || p
->u
.prefix4
.s_addr
== 0)
5741 /* When mask is natural, mask is not displayed. */
5744 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5747 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5752 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5754 vty_out (vty
, "%*s", len
, " ");
5757 enum bgp_display_type
5762 /* Print the short form route status for a bgp_info */
5764 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5765 json_object
*json_path
)
5770 /* Route status display. */
5771 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5772 json_object_boolean_true_add(json_path
, "removed");
5774 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5775 json_object_boolean_true_add(json_path
, "stale");
5777 if (binfo
->extra
&& binfo
->extra
->suppress
)
5778 json_object_boolean_true_add(json_path
, "suppressed");
5780 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5781 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5782 json_object_boolean_true_add(json_path
, "valid");
5785 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5786 json_object_boolean_true_add(json_path
, "history");
5788 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5789 json_object_boolean_true_add(json_path
, "damped");
5791 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5792 json_object_boolean_true_add(json_path
, "bestpath");
5794 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5795 json_object_boolean_true_add(json_path
, "multipath");
5797 /* Internal route. */
5798 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5799 json_object_string_add(json_path
, "pathFrom", "internal");
5801 json_object_string_add(json_path
, "pathFrom", "external");
5806 /* Route status display. */
5807 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5809 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5811 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5813 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5814 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5820 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5822 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5824 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5826 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5831 /* Internal route. */
5832 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5838 /* called from terminal list command */
5840 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5841 struct bgp_info
*binfo
, int display
, safi_t safi
,
5842 json_object
*json_paths
)
5845 json_object
*json_path
= NULL
;
5846 json_object
*json_nexthops
= NULL
;
5847 json_object
*json_nexthop_global
= NULL
;
5848 json_object
*json_nexthop_ll
= NULL
;
5851 json_path
= json_object_new_object();
5853 /* short status lead text */
5854 route_vty_short_status_out (vty
, binfo
, json_path
);
5858 /* print prefix and mask */
5860 route_vty_out_route (p
, vty
);
5862 vty_out (vty
, "%*s", 17, " ");
5865 /* Print attribute */
5870 * For ENCAP routes, nexthop address family is not
5871 * neccessarily the same as the prefix address family.
5872 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
5874 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
))
5879 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
5884 vty_out (vty
, "%s", inet_ntop(af
,
5885 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
5888 vty_out (vty
, "%s", inet_ntop(af
,
5889 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
5900 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5904 json_nexthop_global
= json_object_new_object();
5906 if (safi
== SAFI_MPLS_VPN
)
5907 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5909 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
5911 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
5912 json_object_boolean_true_add(json_nexthop_global
, "used");
5916 if (safi
== SAFI_MPLS_VPN
)
5917 vty_out (vty
, "%-16s",
5918 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5920 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
5925 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5932 json_nexthop_global
= json_object_new_object();
5933 json_object_string_add(json_nexthop_global
, "ip",
5934 inet_ntop (AF_INET6
,
5935 &attr
->extra
->mp_nexthop_global
,
5937 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
5938 json_object_string_add(json_nexthop_global
, "scope", "global");
5940 /* We display both LL & GL if both have been received */
5941 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
5943 json_nexthop_ll
= json_object_new_object();
5944 json_object_string_add(json_nexthop_ll
, "ip",
5945 inet_ntop (AF_INET6
,
5946 &attr
->extra
->mp_nexthop_local
,
5948 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
5949 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
5951 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
5952 &attr
->extra
->mp_nexthop_local
) != 0) &&
5953 !attr
->extra
->mp_nexthop_prefer_global
)
5954 json_object_boolean_true_add(json_nexthop_ll
, "used");
5956 json_object_boolean_true_add(json_nexthop_global
, "used");
5959 json_object_boolean_true_add(json_nexthop_global
, "used");
5963 /* Display LL if LL/Global both in table unless prefer-global is set */
5964 if (((attr
->extra
->mp_nexthop_len
== 32) &&
5965 !attr
->extra
->mp_nexthop_prefer_global
) ||
5966 (binfo
->peer
->conf_if
))
5968 if (binfo
->peer
->conf_if
)
5970 len
= vty_out (vty
, "%s",
5971 binfo
->peer
->conf_if
);
5972 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
5975 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
5977 vty_out (vty
, "%*s", len
, " ");
5981 len
= vty_out (vty
, "%s",
5982 inet_ntop (AF_INET6
,
5983 &attr
->extra
->mp_nexthop_local
,
5988 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
5990 vty_out (vty
, "%*s", len
, " ");
5995 len
= vty_out (vty
, "%s",
5996 inet_ntop (AF_INET6
,
5997 &attr
->extra
->mp_nexthop_global
,
6002 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6004 vty_out (vty
, "%*s", len
, " ");
6010 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6012 json_object_int_add(json_path
, "med", attr
->med
);
6014 vty_out (vty
, "%10u", attr
->med
);
6020 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6022 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6024 vty_out (vty
, "%7u", attr
->local_pref
);
6032 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6034 json_object_int_add(json_path
, "weight", 0);
6037 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6041 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6048 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6050 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6055 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6057 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6062 json_object_string_add(json_path
, "alert", "No attributes");
6064 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6069 if (json_nexthop_global
|| json_nexthop_ll
)
6071 json_nexthops
= json_object_new_array();
6073 if (json_nexthop_global
)
6074 json_object_array_add(json_nexthops
, json_nexthop_global
);
6076 if (json_nexthop_ll
)
6077 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6079 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6082 json_object_array_add(json_paths
, json_path
);
6086 vty_out (vty
, "%s", VTY_NEWLINE
);
6088 /* prints an additional line, indented, with VNC info, if present */
6089 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6090 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6095 /* called from terminal list command */
6097 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6098 u_char use_json
, json_object
*json_ar
)
6100 json_object
*json_status
= NULL
;
6101 json_object
*json_net
= NULL
;
6103 /* Route status display. */
6106 json_status
= json_object_new_object();
6107 json_net
= json_object_new_object();
6116 /* print prefix and mask */
6118 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6120 route_vty_out_route (p
, vty
);
6122 /* Print attribute */
6127 if (p
->family
== AF_INET
&&
6128 (safi
== SAFI_MPLS_VPN
||
6129 safi
== SAFI_ENCAP
||
6130 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6132 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6133 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6135 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6137 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6141 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6145 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6146 json_object_int_add(json_net
, "metric", attr
->med
);
6148 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6149 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6152 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6154 json_object_int_add(json_net
, "weight", 0);
6158 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6161 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6165 if (p
->family
== AF_INET
&&
6166 (safi
== SAFI_MPLS_VPN
||
6167 safi
== SAFI_ENCAP
||
6168 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6170 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6171 vty_out (vty
, "%-16s",
6172 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6174 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6176 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6181 assert (attr
->extra
);
6183 len
= vty_out (vty
, "%s",
6184 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6188 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6190 vty_out (vty
, "%*s", len
, " ");
6192 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6193 vty_out (vty
, "%10u", attr
->med
);
6197 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6198 vty_out (vty
, "%7u", attr
->local_pref
);
6202 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6206 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6209 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6214 json_object_boolean_true_add(json_status
, "*");
6215 json_object_boolean_true_add(json_status
, ">");
6216 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6217 char buf_cut
[BUFSIZ
];
6218 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6221 vty_out (vty
, "%s", VTY_NEWLINE
);
6225 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6226 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6228 json_object
*json_out
= NULL
;
6230 u_int32_t label
= 0;
6236 json_out
= json_object_new_object();
6238 /* short status lead text */
6239 route_vty_short_status_out (vty
, binfo
, json_out
);
6241 /* print prefix and mask */
6245 route_vty_out_route (p
, vty
);
6247 vty_out (vty
, "%*s", 17, " ");
6250 /* Print attribute */
6254 if (p
->family
== AF_INET
6255 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6257 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6260 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6262 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6267 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6269 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6272 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6274 assert (attr
->extra
);
6278 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6281 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6282 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6285 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6288 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6292 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6294 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6296 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6297 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6300 vty_out (vty
, "%s(%s)",
6301 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6303 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6310 label
= decode_label (binfo
->extra
->tag
);
6315 json_object_int_add(json_out
, "notag", label
);
6316 json_object_array_add(json
, json_out
);
6320 vty_out (vty
, "notag/%d", label
);
6321 vty_out (vty
, "%s", VTY_NEWLINE
);
6325 /* dampening route */
6327 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6328 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6332 char timebuf
[BGP_UPTIME_LEN
];
6334 /* short status lead text */
6335 route_vty_short_status_out (vty
, binfo
, json
);
6337 /* print prefix and mask */
6341 route_vty_out_route (p
, vty
);
6343 vty_out (vty
, "%*s", 17, " ");
6346 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6351 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6356 json_object_int_add(json
, "peerHost", len
);
6358 vty_out (vty
, "%*s", len
, " ");
6362 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6364 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6366 /* Print attribute */
6374 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6376 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6381 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6383 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6386 vty_out (vty
, "%s", VTY_NEWLINE
);
6391 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6392 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6395 struct bgp_damp_info
*bdi
;
6396 char timebuf
[BGP_UPTIME_LEN
];
6402 bdi
= binfo
->extra
->damp_info
;
6404 /* short status lead text */
6405 route_vty_short_status_out (vty
, binfo
, json
);
6407 /* print prefix and mask */
6411 route_vty_out_route (p
, vty
);
6413 vty_out (vty
, "%*s", 17, " ");
6416 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6421 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6426 json_object_int_add(json
, "peerHost", len
);
6428 vty_out (vty
, "%*s", len
, " ");
6431 len
= vty_out (vty
, "%d", bdi
->flap
);
6441 json_object_int_add(json
, "bdiFlap", len
);
6443 vty_out (vty
, "%*s", len
, " ");
6447 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6449 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6450 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6452 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6453 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6456 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6458 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6463 vty_out (vty
, "%*s ", 8, " ");
6466 /* Print attribute */
6474 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6476 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6481 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6483 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6486 vty_out (vty
, "%s", VTY_NEWLINE
);
6490 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6491 const char *header
, json_object
*json_adv_to
)
6493 char buf1
[INET6_ADDRSTRLEN
];
6494 json_object
*json_peer
= NULL
;
6498 /* 'advertised-to' is a dictionary of peers we have advertised this
6499 * prefix too. The key is the peer's IP or swpX, the value is the
6500 * hostname if we know it and "" if not.
6502 json_peer
= json_object_new_object();
6505 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6508 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6510 json_object_object_add(json_adv_to
,
6511 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6518 vty_out (vty
, "%s", header
);
6522 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6525 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6527 vty_out (vty
, " %s(%s)", peer
->hostname
,
6528 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6533 vty_out (vty
, " %s", peer
->conf_if
);
6535 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6541 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6542 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6543 json_object
*json_paths
)
6545 char buf
[INET6_ADDRSTRLEN
];
6548 int sockunion_vty_out (struct vty
*, union sockunion
*);
6550 json_object
*json_bestpath
= NULL
;
6551 json_object
*json_cluster_list
= NULL
;
6552 json_object
*json_cluster_list_list
= NULL
;
6553 json_object
*json_ext_community
= NULL
;
6554 json_object
*json_last_update
= NULL
;
6555 json_object
*json_nexthop_global
= NULL
;
6556 json_object
*json_nexthop_ll
= NULL
;
6557 json_object
*json_nexthops
= NULL
;
6558 json_object
*json_path
= NULL
;
6559 json_object
*json_peer
= NULL
;
6560 json_object
*json_string
= NULL
;
6561 json_object
*json_adv_to
= NULL
;
6563 struct listnode
*node
, *nnode
;
6565 int addpath_capable
;
6567 unsigned int first_as
;
6571 json_path
= json_object_new_object();
6572 json_peer
= json_object_new_object();
6573 json_nexthop_global
= json_object_new_object();
6580 /* Line1 display AS-path, Aggregator */
6585 json_object_lock(attr
->aspath
->json
);
6586 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6590 if (attr
->aspath
->segments
)
6591 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6593 vty_out (vty
, " Local");
6597 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6600 json_object_boolean_true_add(json_path
, "removed");
6602 vty_out (vty
, ", (removed)");
6605 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6608 json_object_boolean_true_add(json_path
, "stale");
6610 vty_out (vty
, ", (stale)");
6613 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6617 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6618 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6622 vty_out (vty
, ", (aggregated by %u %s)",
6623 attr
->extra
->aggregator_as
,
6624 inet_ntoa (attr
->extra
->aggregator_addr
));
6628 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6631 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6633 vty_out (vty
, ", (Received from a RR-client)");
6636 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6639 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6641 vty_out (vty
, ", (Received from a RS-client)");
6644 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6647 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6649 vty_out (vty
, ", (history entry)");
6651 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6654 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6656 vty_out (vty
, ", (suppressed due to dampening)");
6660 vty_out (vty
, "%s", VTY_NEWLINE
);
6662 /* Line2 display Next-hop, Neighbor, Router-id */
6663 /* Display the nexthop */
6664 if (p
->family
== AF_INET
&&
6665 (safi
== SAFI_MPLS_VPN
||
6666 safi
== SAFI_ENCAP
||
6667 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6669 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6672 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6674 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6679 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6681 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6685 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6689 assert (attr
->extra
);
6692 json_object_string_add(json_nexthop_global
, "ip",
6693 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6694 buf
, INET6_ADDRSTRLEN
));
6695 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6696 json_object_string_add(json_nexthop_global
, "scope", "global");
6700 vty_out (vty
, " %s",
6701 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6702 buf
, INET6_ADDRSTRLEN
));
6706 /* Display the IGP cost or 'inaccessible' */
6707 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6710 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6712 vty_out (vty
, " (inaccessible)");
6716 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6719 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6721 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6724 /* IGP cost is 0, display this only for json */
6728 json_object_int_add(json_nexthop_global
, "metric", 0);
6732 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6735 /* Display peer "from" output */
6736 /* This path was originated locally */
6737 if (binfo
->peer
== bgp
->peer_self
)
6740 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6743 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6745 vty_out (vty
, " from 0.0.0.0 ");
6750 json_object_string_add(json_peer
, "peerId", "::");
6752 vty_out (vty
, " from :: ");
6756 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6758 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
6761 /* We RXed this path from one of our peers */
6767 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6768 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6770 if (binfo
->peer
->hostname
)
6771 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
6773 if (binfo
->peer
->domainname
)
6774 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
6776 if (binfo
->peer
->conf_if
)
6777 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
6781 if (binfo
->peer
->conf_if
)
6783 if (binfo
->peer
->hostname
&&
6784 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6785 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6786 binfo
->peer
->conf_if
);
6788 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
6792 if (binfo
->peer
->hostname
&&
6793 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6794 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6797 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6800 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
6801 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
6803 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6808 vty_out (vty
, "%s", VTY_NEWLINE
);
6810 /* display the link-local nexthop */
6811 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6815 json_nexthop_ll
= json_object_new_object();
6816 json_object_string_add(json_nexthop_ll
, "ip",
6817 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6818 buf
, INET6_ADDRSTRLEN
));
6819 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6820 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6822 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
6824 if (!attr
->extra
->mp_nexthop_prefer_global
)
6825 json_object_boolean_true_add(json_nexthop_ll
, "used");
6827 json_object_boolean_true_add(json_nexthop_global
, "used");
6831 vty_out (vty
, " (%s) %s%s",
6832 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6833 buf
, INET6_ADDRSTRLEN
),
6834 attr
->extra
->mp_nexthop_prefer_global
?
6835 "(prefer-global)" : "(used)",
6839 /* If we do not have a link-local nexthop then we must flag the global as "used" */
6843 json_object_boolean_true_add(json_nexthop_global
, "used");
6846 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
6848 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6850 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
6852 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6855 json_object_int_add(json_path
, "med", attr
->med
);
6857 vty_out (vty
, ", metric %u", attr
->med
);
6860 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6863 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6865 vty_out (vty
, ", localpref %u", attr
->local_pref
);
6870 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
6872 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
6875 if (attr
->extra
&& attr
->extra
->weight
!= 0)
6878 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6880 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
6883 if (attr
->extra
&& attr
->extra
->tag
!= 0)
6886 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
6888 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
6891 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6894 json_object_boolean_false_add(json_path
, "valid");
6896 vty_out (vty
, ", invalid");
6898 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6901 json_object_boolean_true_add(json_path
, "valid");
6903 vty_out (vty
, ", valid");
6906 if (binfo
->peer
!= bgp
->peer_self
)
6908 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
6910 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
6913 json_object_string_add(json_peer
, "type", "confed-internal");
6915 vty_out (vty
, ", confed-internal");
6920 json_object_string_add(json_peer
, "type", "internal");
6922 vty_out (vty
, ", internal");
6927 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
6930 json_object_string_add(json_peer
, "type", "confed-external");
6932 vty_out (vty
, ", confed-external");
6937 json_object_string_add(json_peer
, "type", "external");
6939 vty_out (vty
, ", external");
6943 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
6947 json_object_boolean_true_add(json_path
, "aggregated");
6948 json_object_boolean_true_add(json_path
, "local");
6952 vty_out (vty
, ", aggregated, local");
6955 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
6958 json_object_boolean_true_add(json_path
, "sourced");
6960 vty_out (vty
, ", sourced");
6966 json_object_boolean_true_add(json_path
, "sourced");
6967 json_object_boolean_true_add(json_path
, "local");
6971 vty_out (vty
, ", sourced, local");
6975 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
6978 json_object_boolean_true_add(json_path
, "atomicAggregate");
6980 vty_out (vty
, ", atomic-aggregate");
6983 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
6984 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
6985 bgp_info_mpath_count (binfo
)))
6988 json_object_boolean_true_add(json_path
, "multipath");
6990 vty_out (vty
, ", multipath");
6993 // Mark the bestpath(s)
6994 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
6996 first_as
= aspath_get_first_as(attr
->aspath
);
7001 json_bestpath
= json_object_new_object();
7002 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7007 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7009 vty_out (vty
, ", bestpath-from-AS Local");
7013 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7018 json_bestpath
= json_object_new_object();
7019 json_object_boolean_true_add(json_bestpath
, "overall");
7022 vty_out (vty
, ", best");
7026 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7029 vty_out (vty
, "%s", VTY_NEWLINE
);
7031 /* Line 4 display Community */
7032 if (attr
->community
)
7036 json_object_lock(attr
->community
->json
);
7037 json_object_object_add(json_path
, "community", attr
->community
->json
);
7041 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7046 /* Line 5 display Extended-community */
7047 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7051 json_ext_community
= json_object_new_object();
7052 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7053 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7057 vty_out (vty
, " Extended Community: %s%s",
7058 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7062 /* Line 6 display Originator, Cluster-id */
7063 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7064 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7066 assert (attr
->extra
);
7067 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7070 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7072 vty_out (vty
, " Originator: %s",
7073 inet_ntoa (attr
->extra
->originator_id
));
7076 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7082 json_cluster_list
= json_object_new_object();
7083 json_cluster_list_list
= json_object_new_array();
7085 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7087 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7088 json_object_array_add(json_cluster_list_list
, json_string
);
7091 /* struct cluster_list does not have "str" variable like
7092 * aspath and community do. Add this someday if someone
7094 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7096 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7097 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7101 vty_out (vty
, ", Cluster list: ");
7103 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7105 vty_out (vty
, "%s ",
7106 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7112 vty_out (vty
, "%s", VTY_NEWLINE
);
7115 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7116 bgp_damp_info_vty (vty
, binfo
, json_path
);
7118 /* Line 7 display Addpath IDs */
7119 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7123 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7124 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7128 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7129 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7134 /* If we used addpath to TX a non-bestpath we need to display
7135 * "Advertised to" on a path-by-path basis */
7136 if (bgp
->addpath_tx_used
[afi
][safi
])
7140 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7142 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7143 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7145 if ((addpath_capable
&& has_adj
) ||
7146 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7148 if (json_path
&& !json_adv_to
)
7149 json_adv_to
= json_object_new_object();
7151 route_vty_out_advertised_to(vty
, peer
, &first
,
7161 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7168 vty_out (vty
, "%s", VTY_NEWLINE
);
7173 /* Line 8 display Uptime */
7174 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7177 json_last_update
= json_object_new_object();
7178 json_object_int_add(json_last_update
, "epoch", tbuf
);
7179 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7180 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7183 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7186 /* We've constructed the json object for this path, add it to the json
7191 if (json_nexthop_global
|| json_nexthop_ll
)
7193 json_nexthops
= json_object_new_array();
7195 if (json_nexthop_global
)
7196 json_object_array_add(json_nexthops
, json_nexthop_global
);
7198 if (json_nexthop_ll
)
7199 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7201 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7204 json_object_object_add(json_path
, "peer", json_peer
);
7205 json_object_array_add(json_paths
, json_path
);
7208 vty_out (vty
, "%s", VTY_NEWLINE
);
7211 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7212 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7213 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7217 bgp_show_type_normal
,
7218 bgp_show_type_regexp
,
7219 bgp_show_type_prefix_list
,
7220 bgp_show_type_filter_list
,
7221 bgp_show_type_route_map
,
7222 bgp_show_type_neighbor
,
7223 bgp_show_type_cidr_only
,
7224 bgp_show_type_prefix_longer
,
7225 bgp_show_type_community_all
,
7226 bgp_show_type_community
,
7227 bgp_show_type_community_exact
,
7228 bgp_show_type_community_list
,
7229 bgp_show_type_community_list_exact
,
7230 bgp_show_type_flap_statistics
,
7231 bgp_show_type_flap_neighbor
,
7232 bgp_show_type_dampend_paths
,
7233 bgp_show_type_damp_neighbor
7237 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
7238 const char *prefix_list_str
, afi_t afi
,
7239 safi_t safi
, enum bgp_show_type type
);
7241 bgp_show_filter_list (struct vty
*vty
, const char *name
,
7242 const char *filter
, afi_t afi
,
7243 safi_t safi
, enum bgp_show_type type
);
7245 bgp_show_route_map (struct vty
*vty
, const char *name
,
7246 const char *rmap_str
, afi_t afi
,
7247 safi_t safi
, enum bgp_show_type type
);
7249 bgp_show_community_list (struct vty
*vty
, const char *name
,
7250 const char *com
, int exact
,
7251 afi_t afi
, safi_t safi
);
7253 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
7254 const char *prefix
, afi_t afi
,
7255 safi_t safi
, enum bgp_show_type type
);
7257 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7258 safi_t safi
, enum bgp_show_type type
);
7260 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
7261 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7264 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7265 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7267 struct bgp_info
*ri
;
7268 struct bgp_node
*rn
;
7271 unsigned long output_count
;
7272 unsigned long total_count
;
7276 json_object
*json_paths
= NULL
;
7281 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7282 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7283 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7284 table
->version
, inet_ntoa (bgp
->router_id
));
7285 json_paths
= json_object_new_object();
7288 /* This is first entry point, so reset total line. */
7292 /* Start processing of routes. */
7293 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7294 if (rn
->info
!= NULL
)
7297 if (!first
&& use_json
)
7302 json_paths
= json_object_new_array();
7306 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7309 if (type
== bgp_show_type_flap_statistics
7310 || type
== bgp_show_type_flap_neighbor
7311 || type
== bgp_show_type_dampend_paths
7312 || type
== bgp_show_type_damp_neighbor
)
7314 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7317 if (type
== bgp_show_type_regexp
)
7319 regex_t
*regex
= output_arg
;
7321 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7324 if (type
== bgp_show_type_prefix_list
)
7326 struct prefix_list
*plist
= output_arg
;
7328 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7331 if (type
== bgp_show_type_filter_list
)
7333 struct as_list
*as_list
= output_arg
;
7335 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7338 if (type
== bgp_show_type_route_map
)
7340 struct route_map
*rmap
= output_arg
;
7341 struct bgp_info binfo
;
7342 struct attr dummy_attr
;
7343 struct attr_extra dummy_extra
;
7346 dummy_attr
.extra
= &dummy_extra
;
7347 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7349 binfo
.peer
= ri
->peer
;
7350 binfo
.attr
= &dummy_attr
;
7352 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7353 if (ret
== RMAP_DENYMATCH
)
7356 if (type
== bgp_show_type_neighbor
7357 || type
== bgp_show_type_flap_neighbor
7358 || type
== bgp_show_type_damp_neighbor
)
7360 union sockunion
*su
= output_arg
;
7362 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7365 if (type
== bgp_show_type_cidr_only
)
7367 u_int32_t destination
;
7369 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7370 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7372 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7374 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7377 if (type
== bgp_show_type_prefix_longer
)
7379 struct prefix
*p
= output_arg
;
7381 if (! prefix_match (p
, &rn
->p
))
7384 if (type
== bgp_show_type_community_all
)
7386 if (! ri
->attr
->community
)
7389 if (type
== bgp_show_type_community
)
7391 struct community
*com
= output_arg
;
7393 if (! ri
->attr
->community
||
7394 ! community_match (ri
->attr
->community
, com
))
7397 if (type
== bgp_show_type_community_exact
)
7399 struct community
*com
= output_arg
;
7401 if (! ri
->attr
->community
||
7402 ! community_cmp (ri
->attr
->community
, com
))
7405 if (type
== bgp_show_type_community_list
)
7407 struct community_list
*list
= output_arg
;
7409 if (! community_list_match (ri
->attr
->community
, list
))
7412 if (type
== bgp_show_type_community_list_exact
)
7414 struct community_list
*list
= output_arg
;
7416 if (! community_list_exact_match (ri
->attr
->community
, list
))
7419 if (type
== bgp_show_type_dampend_paths
7420 || type
== bgp_show_type_damp_neighbor
)
7422 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7423 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7427 if (!use_json
&& header
)
7429 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7430 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7431 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7432 if (type
== bgp_show_type_dampend_paths
7433 || type
== bgp_show_type_damp_neighbor
)
7434 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7435 else if (type
== bgp_show_type_flap_statistics
7436 || type
== bgp_show_type_flap_neighbor
)
7437 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7439 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7443 if (type
== bgp_show_type_dampend_paths
7444 || type
== bgp_show_type_damp_neighbor
)
7445 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7446 else if (type
== bgp_show_type_flap_statistics
7447 || type
== bgp_show_type_flap_neighbor
)
7448 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7450 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7460 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7461 vty_out (vty
, "\"%s\": ", buf2
);
7462 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7463 json_object_free (json_paths
);
7472 json_object_free (json_paths
);
7473 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7477 /* No route is displayed */
7478 if (output_count
== 0)
7480 if (type
== bgp_show_type_normal
)
7481 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7484 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7485 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7492 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7493 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7495 struct bgp_table
*table
;
7499 bgp
= bgp_get_default ();
7505 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7509 table
= bgp
->rib
[afi
][safi
];
7511 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7516 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7519 struct listnode
*node
, *nnode
;
7521 struct bgp_table
*table
;
7525 vty_out (vty
, "{%s", VTY_NEWLINE
);
7527 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7532 vty_out (vty
, ",%s", VTY_NEWLINE
);
7536 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7537 ? "Default" : bgp
->name
);
7541 vty_out (vty
, "%sInstance %s:%s",
7543 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7544 ? "Default" : bgp
->name
,
7547 table
= bgp
->rib
[afi
][safi
];
7548 bgp_show_table (vty
, bgp
, table
,
7549 bgp_show_type_normal
, NULL
, use_json
);
7554 vty_out (vty
, "}%s", VTY_NEWLINE
);
7557 /* Header of detailed BGP route information */
7559 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7560 struct bgp_node
*rn
,
7561 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7564 struct bgp_info
*ri
;
7567 struct listnode
*node
, *nnode
;
7568 char buf1
[INET6_ADDRSTRLEN
];
7569 char buf2
[INET6_ADDRSTRLEN
];
7574 int no_advertise
= 0;
7577 json_object
*json_adv_to
= NULL
;
7583 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7584 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7588 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7589 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
) ?
7590 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7591 safi
== SAFI_MPLS_VPN
? ":" : "",
7592 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
7593 p
->prefixlen
, VTY_NEWLINE
);
7596 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7599 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7602 if (ri
->extra
&& ri
->extra
->suppress
)
7604 if (ri
->attr
->community
!= NULL
)
7606 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7608 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7610 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7618 vty_out (vty
, "Paths: (%d available", count
);
7621 vty_out (vty
, ", best #%d", best
);
7622 if (safi
== SAFI_UNICAST
)
7623 vty_out (vty
, ", table %s",
7624 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7625 ? "Default-IP-Routing-Table" : bgp
->name
);
7628 vty_out (vty
, ", no best path");
7631 vty_out (vty
, ", not advertised to any peer");
7633 vty_out (vty
, ", not advertised to EBGP peer");
7635 vty_out (vty
, ", not advertised outside local AS");
7638 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7639 vty_out (vty
, ")%s", VTY_NEWLINE
);
7642 /* If we are not using addpath then we can display Advertised to and that will
7643 * show what peers we advertised the bestpath to. If we are using addpath
7644 * though then we must display Advertised to on a path-by-path basis. */
7645 if (!bgp
->addpath_tx_used
[afi
][safi
])
7647 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7649 if (bgp_adj_out_lookup (peer
, rn
, 0))
7651 if (json
&& !json_adv_to
)
7652 json_adv_to
= json_object_new_object();
7654 route_vty_out_advertised_to(vty
, peer
, &first
,
7655 " Advertised to non peer-group peers:\n ",
7664 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7670 vty_out (vty
, " Not advertised to any peer");
7671 vty_out (vty
, "%s", VTY_NEWLINE
);
7676 /* Display specified route of BGP table. */
7678 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7679 struct bgp_table
*rib
, const char *ip_str
,
7680 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7681 int prefix_check
, enum bgp_path_type pathtype
,
7687 struct prefix match
;
7688 struct bgp_node
*rn
;
7689 struct bgp_node
*rm
;
7690 struct bgp_info
*ri
;
7691 struct bgp_table
*table
;
7692 json_object
*json
= NULL
;
7693 json_object
*json_paths
= NULL
;
7695 /* Check IP address argument. */
7696 ret
= str2prefix (ip_str
, &match
);
7699 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7703 match
.family
= afi2family (afi
);
7707 json
= json_object_new_object();
7708 json_paths
= json_object_new_array();
7711 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
7713 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7715 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7718 if ((table
= rn
->info
) != NULL
)
7722 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7724 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7726 bgp_unlock_node (rm
);
7730 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7734 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7735 AFI_IP
, safi
, json
);
7740 if (pathtype
== BGP_PATH_ALL
||
7741 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7742 (pathtype
== BGP_PATH_MULTIPATH
&&
7743 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7744 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
7747 bgp_unlock_node (rm
);
7756 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
7758 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
7760 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7764 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
7769 if (pathtype
== BGP_PATH_ALL
||
7770 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7771 (pathtype
== BGP_PATH_MULTIPATH
&&
7772 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7773 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
7777 bgp_unlock_node (rn
);
7784 json_object_object_add(json
, "paths", json_paths
);
7786 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
7787 json_object_free(json
);
7793 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
7801 /* Display specified route of Main RIB */
7803 bgp_show_route (struct vty
*vty
, const char *view_name
, const char *ip_str
,
7804 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7805 int prefix_check
, enum bgp_path_type pathtype
,
7810 /* BGP structure lookup. */
7813 bgp
= bgp_lookup_by_name (view_name
);
7816 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
7822 bgp
= bgp_get_default ();
7825 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7830 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
7831 afi
, safi
, prd
, prefix_check
, pathtype
,
7835 /* BGP route print out function. */
7836 DEFUN (show_ip_bgp_ipv4
,
7837 show_ip_bgp_ipv4_cmd
,
7838 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]]\
7841 |dampening <flap-statistics|dampened-paths|parameters>\
7845 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
7846 |community-list <(1-500)|WORD> [exact-match]\
7847 |A.B.C.D/M longer-prefixes\
7848 |X:X::X:X/M longer-prefixes\
7854 BGP_INSTANCE_HELP_STR
7856 "Address Family modifier\n"
7857 "Address Family modifier\n"
7858 "Address Family modifier\n"
7859 "Address Family modifier\n"
7861 "Address Family modifier\n"
7862 "Address Family modifier\n"
7863 "Address Family modifier\n"
7864 "Address Family modifier\n"
7865 "Display only routes with non-natural netmasks\n"
7866 "Display detailed information about dampening\n"
7867 "Display flap statistics of routes\n"
7868 "Display paths suppressed due to dampening\n"
7869 "Display dampening parameters\n"
7870 "Display routes matching the route-map\n"
7871 "A route-map to match on\n"
7872 "Display routes conforming to the prefix-list\n"
7873 "Prefix-list name\n"
7874 "Display routes conforming to the filter-list\n"
7875 "Regular expression access list name\n"
7876 "Display routes matching the communities\n"
7878 "Do not send outside local AS (well-known community)\n"
7879 "Do not advertise to any peer (well-known community)\n"
7880 "Do not export to next AS (well-known community)\n"
7881 "Exact match of the communities\n"
7882 "Display routes matching the community-list\n"
7883 "community-list number\n"
7884 "community-list name\n"
7885 "Exact match of the communities\n"
7887 "Display route and more specific routes\n"
7889 "Display route and more specific routes\n"
7893 afi_t afi
= AFI_IP6
;
7894 safi_t safi
= SAFI_UNICAST
;
7895 int exact_match
= 0;
7896 enum bgp_show_type sh_type
= bgp_show_type_normal
;
7900 if (argv_find (argv
, argc
, "ip", &idx
))
7902 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
7903 vrf
= argv
[++idx
]->arg
;
7904 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
7906 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
7907 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
7908 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
7910 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
7913 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
7914 // advance idx if necessary
7915 argv_find (argv
, argc
, "unicast", &idx
);
7918 int uj
= use_json (argc
, argv
);
7921 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
7924 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
7930 if (strmatch(argv
[idx
]->text
, "cidr-only"))
7931 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
7933 else if (strmatch(argv
[idx
]->text
, "dampening"))
7935 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
7936 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
7937 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
7938 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
7939 else if (argv_find (argv
, argc
, "parameters", &idx
))
7940 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
7943 else if (strmatch(argv
[idx
]->text
, "prefix-list"))
7944 return bgp_show_prefix_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
7946 else if (strmatch(argv
[idx
]->text
, "filter-list"))
7947 return bgp_show_filter_list (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
7949 else if (strmatch(argv
[idx
]->text
, "route-map"))
7950 return bgp_show_route_map (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
7952 else if (strmatch(argv
[idx
]->text
, "community"))
7954 /* show a specific community */
7955 if (argv
[idx
+ 1]->type
== VARIABLE_TKN
||
7956 strmatch(argv
[idx
+ 1]->text
, "local-AS") ||
7957 strmatch(argv
[idx
+ 1]->text
, "no-advertise") ||
7958 strmatch(argv
[idx
+ 1]->text
, "no-export"))
7960 if (strmatch(argv
[idx
+ 2]->text
, "exact_match"))
7962 return bgp_show_community (vty
, vrf
, argc
, argv
, exact_match
, afi
, safi
);
7964 /* show all communities */
7966 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
7968 else if (strmatch(argv
[idx
]->text
, "community-list"))
7970 const char *clist_number_or_name
= argv
[++idx
]->arg
;
7971 if (++idx
< argc
&& strmatch (argv
[idx
]->arg
, "exact-match"))
7973 return bgp_show_community_list (vty
, vrf
, clist_number_or_name
, exact_match
, afi
, safi
);
7976 else if (argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV6_TKN
)
7977 return bgp_show_prefix_longer (vty
, vrf
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
7980 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
7983 DEFUN (show_ip_bgp_route
,
7984 show_ip_bgp_route_cmd
,
7985 "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]]"
7986 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
7990 BGP_INSTANCE_HELP_STR
7992 "Address Family modifier\n"
7993 "Address Family modifier\n"
7994 "Address Family modifier\n"
7995 "Address Family modifier\n"
7997 "Address Family modifier\n"
7998 "Address Family modifier\n"
7999 "Address Family modifier\n"
8000 "Address Family modifier\n"
8001 "Network in the BGP routing table to display\n"
8003 "Network in the BGP routing table to display\n"
8005 "Display only the bestpath\n"
8006 "Display only multipaths\n"
8009 int prefix_check
= 0;
8011 afi_t afi
= AFI_IP6
;
8012 safi_t safi
= SAFI_UNICAST
;
8014 char *prefix
= NULL
;
8016 enum bgp_path_type path_type
;
8017 u_char uj
= use_json(argc
, argv
);
8022 if (argv_find (argv
, argc
, "ip", &idx
))
8024 /* [<view|vrf> WORD] */
8025 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8026 vrf
= argv
[++idx
]->arg
;
8027 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8028 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8030 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8031 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8032 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8034 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8037 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8038 // advance idx if necessary
8039 argv_find (argv
, argc
, "unicast", &idx
);
8042 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8043 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8045 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8048 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8050 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8053 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8055 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8059 prefix
= argv
[idx
]->arg
;
8061 /* [<bestpath|multipath>] */
8062 if (argv_find (argv
, argc
, "bestpath", &idx
))
8063 path_type
= BGP_PATH_BESTPATH
;
8064 else if (argv_find (argv
, argc
, "multipath", &idx
))
8065 path_type
= BGP_PATH_MULTIPATH
;
8067 path_type
= BGP_PATH_ALL
;
8069 return bgp_show_route (vty
, vrf
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8072 DEFUN (show_ip_bgp_regexp
,
8073 show_ip_bgp_regexp_cmd
,
8074 "show [ip] bgp [<ipv4 [<unicast|multicast|vpn|encap>]|ipv6 [<unicast|multicast|vpn|encap>]|encap [unicast]|vpnv4 [unicast]>] regexp REGEX...",
8079 "Address Family modifier\n"
8080 "Address Family modifier\n"
8081 "Address Family modifier\n"
8082 "Address Family modifier\n"
8084 "Address Family modifier\n"
8085 "Address Family modifier\n"
8086 "Address Family modifier\n"
8087 "Address Family modifier\n"
8089 "Address Family modifier\n"
8091 "Address Family modifier\n"
8092 "Display routes matching the AS path regular expression\n"
8093 "A regular-expression to match the BGP AS paths\n")
8095 afi_t afi
= AFI_IP6
;
8096 safi_t safi
= SAFI_UNICAST
;
8100 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8101 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8103 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8104 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8105 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8107 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8110 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8111 // advance idx if necessary
8112 argv_find (argv
, argc
, "unicast", &idx
);
8115 // get index of regex
8116 argv_find (argv
, argc
, "regexp", &idx
);
8119 char *regstr
= argv_concat (argv
, argc
, idx
);
8120 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8121 XFREE (MTYPE_TMP
, regstr
);
8125 DEFUN (show_ip_bgp_instance_all
,
8126 show_ip_bgp_instance_all_cmd
,
8127 "show [ip] bgp <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [json]",
8131 BGP_INSTANCE_ALL_HELP_STR
8133 "Address Family modifier\n"
8134 "Address Family modifier\n"
8136 "Address Family modifier\n"
8137 "Address Family modifier\n"
8139 "Address Family modifier\n"
8141 "Address Family modifier\n"
8145 safi_t safi
= SAFI_UNICAST
;
8150 if (argv_find (argv
, argc
, "ip", &idx
))
8152 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
8153 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8155 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8156 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8157 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
8159 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
8162 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
8163 // advance idx if necessary
8164 argv_find (argv
, argc
, "unicast", &idx
);
8167 u_char uj
= use_json(argc
, argv
);
8169 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8175 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8176 safi_t safi
, enum bgp_show_type type
)
8183 regex
= bgp_regcomp (regstr
);
8186 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8190 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8191 bgp_regex_free (regex
);
8196 bgp_show_prefix_list (struct vty
*vty
, const char *name
,
8197 const char *prefix_list_str
, afi_t afi
,
8198 safi_t safi
, enum bgp_show_type type
)
8200 struct prefix_list
*plist
;
8201 struct bgp
*bgp
= NULL
;
8203 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8205 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8209 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8212 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8213 prefix_list_str
, VTY_NEWLINE
);
8217 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8221 bgp_show_filter_list (struct vty
*vty
, const char *name
,
8222 const char *filter
, afi_t afi
,
8223 safi_t safi
, enum bgp_show_type type
)
8225 struct as_list
*as_list
;
8226 struct bgp
*bgp
= NULL
;
8228 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8230 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8234 as_list
= as_list_lookup (filter
);
8235 if (as_list
== NULL
)
8237 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8241 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8244 DEFUN (show_ip_bgp_dampening_info
,
8245 show_ip_bgp_dampening_params_cmd
,
8246 "show [ip] bgp dampening parameters",
8250 "Display detailed information about dampening\n"
8251 "Display detail of configured dampening parameters\n")
8253 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8257 DEFUN (show_ip_bgp_ipv4_dampening_parameters
,
8258 show_ip_bgp_ipv4_dampening_parameters_cmd
,
8259 "show [ip] bgp ipv4 <unicast|multicast> dampening parameters",
8264 "Address Family modifier\n"
8265 "Address Family modifier\n"
8266 "Display detailed information about dampening\n"
8267 "Display detail of configured dampening parameters\n")
8270 if (strncmp(argv
[idx_safi
]->arg
, "m", 1) == 0)
8271 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_MULTICAST
);
8273 return bgp_show_dampening_parameters (vty
, AFI_IP
, SAFI_UNICAST
);
8277 bgp_show_route_map (struct vty
*vty
, const char *name
,
8278 const char *rmap_str
, afi_t afi
,
8279 safi_t safi
, enum bgp_show_type type
)
8281 struct route_map
*rmap
;
8282 struct bgp
*bgp
= NULL
;
8284 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8288 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8292 rmap
= route_map_lookup_by_name (rmap_str
);
8295 vty_out (vty
, "%% %s is not a valid route-map name%s",
8296 rmap_str
, VTY_NEWLINE
);
8300 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8304 bgp_show_community (struct vty
*vty
, const char *view_name
, int argc
,
8305 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8307 struct community
*com
;
8314 /* BGP structure lookup */
8317 bgp
= bgp_lookup_by_name (view_name
);
8320 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8326 bgp
= bgp_get_default ();
8329 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8334 b
= buffer_new (1024);
8335 for (i
= 0; i
< argc
; i
++)
8338 buffer_putc (b
, ' ');
8341 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8346 buffer_putstr (b
, argv
[i
]->arg
);
8348 buffer_putc (b
, '\0');
8350 str
= buffer_getstr (b
);
8353 com
= community_str2com (str
);
8354 XFREE (MTYPE_TMP
, str
);
8357 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8361 return bgp_show (vty
, bgp
, afi
, safi
,
8362 (exact
? bgp_show_type_community_exact
:
8363 bgp_show_type_community
), com
, 0);
8367 bgp_show_community_list (struct vty
*vty
, const char *name
,
8368 const char *com
, int exact
,
8369 afi_t afi
, safi_t safi
)
8371 struct community_list
*list
;
8372 struct bgp
*bgp
= NULL
;
8374 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8376 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8380 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8383 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8388 return bgp_show (vty
, bgp
, afi
, safi
,
8389 (exact
? bgp_show_type_community_list_exact
:
8390 bgp_show_type_community_list
), list
, 0);
8394 bgp_show_prefix_longer (struct vty
*vty
, const char *name
,
8395 const char *prefix
, afi_t afi
,
8396 safi_t safi
, enum bgp_show_type type
)
8400 struct bgp
*bgp
= NULL
;
8402 if (name
&& !(bgp
= bgp_lookup_by_name(name
)))
8404 vty_out (vty
, "%% No such BGP instance exists%s", VTY_NEWLINE
);
8410 ret
= str2prefix (prefix
, p
);
8413 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8417 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8422 static struct peer
*
8423 peer_lookup_in_view (struct vty
*vty
, const char *view_name
,
8424 const char *ip_str
, u_char use_json
)
8431 /* BGP structure lookup. */
8434 bgp
= bgp_lookup_by_name (view_name
);
8439 json_object
*json_no
= NULL
;
8440 json_no
= json_object_new_object();
8441 json_object_string_add(json_no
, "warning", "Can't find BGP view");
8442 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8443 json_object_free(json_no
);
8446 vty_out (vty
, "Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
8452 bgp
= bgp_get_default ();
8457 json_object
*json_no
= NULL
;
8458 json_no
= json_object_new_object();
8459 json_object_string_add(json_no
, "warning", "No BGP process configured");
8460 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8461 json_object_free(json_no
);
8464 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
8469 /* Get peer sockunion. */
8470 ret
= str2sockunion (ip_str
, &su
);
8473 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8476 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8482 json_object
*json_no
= NULL
;
8483 json_no
= json_object_new_object();
8484 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8485 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8486 json_object_free(json_no
);
8489 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8496 /* Peer structure lookup. */
8497 peer
= peer_lookup (bgp
, &su
);
8502 json_object
*json_no
= NULL
;
8503 json_no
= json_object_new_object();
8504 json_object_string_add(json_no
, "warning","No such neighbor");
8505 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8506 json_object_free(json_no
);
8509 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8518 BGP_STATS_MAXBITLEN
= 0,
8522 BGP_STATS_UNAGGREGATEABLE
,
8523 BGP_STATS_MAX_AGGREGATEABLE
,
8524 BGP_STATS_AGGREGATES
,
8526 BGP_STATS_ASPATH_COUNT
,
8527 BGP_STATS_ASPATH_MAXHOPS
,
8528 BGP_STATS_ASPATH_TOTHOPS
,
8529 BGP_STATS_ASPATH_MAXSIZE
,
8530 BGP_STATS_ASPATH_TOTSIZE
,
8531 BGP_STATS_ASN_HIGHEST
,
8535 static const char *table_stats_strs
[] =
8537 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8538 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8539 [BGP_STATS_RIB
] = "Total Advertisements",
8540 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8541 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8542 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8543 [BGP_STATS_SPACE
] = "Address space advertised",
8544 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8545 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8546 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8547 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8548 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8549 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8550 [BGP_STATS_MAX
] = NULL
,
8553 struct bgp_table_stats
8555 struct bgp_table
*table
;
8556 unsigned long long counts
[BGP_STATS_MAX
];
8560 #define TALLY_SIGFIG 100000
8561 static unsigned long
8562 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8564 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8565 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8566 unsigned long ret
= newtot
/ count
;
8568 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8576 bgp_table_stats_walker (struct thread
*t
)
8578 struct bgp_node
*rn
;
8579 struct bgp_node
*top
;
8580 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8581 unsigned int space
= 0;
8583 if (!(top
= bgp_table_top (ts
->table
)))
8586 switch (top
->p
.family
)
8589 space
= IPV4_MAX_BITLEN
;
8592 space
= IPV6_MAX_BITLEN
;
8596 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8598 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8600 struct bgp_info
*ri
;
8601 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8602 unsigned int rinum
= 0;
8610 ts
->counts
[BGP_STATS_PREFIXES
]++;
8611 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8614 ts
->counts
[BGP_STATS_AVGPLEN
]
8615 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8616 ts
->counts
[BGP_STATS_AVGPLEN
],
8620 /* check if the prefix is included by any other announcements */
8621 while (prn
&& !prn
->info
)
8622 prn
= bgp_node_parent_nolock (prn
);
8624 if (prn
== NULL
|| prn
== top
)
8626 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8627 /* announced address space */
8629 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8632 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8634 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8637 ts
->counts
[BGP_STATS_RIB
]++;
8640 (CHECK_FLAG (ri
->attr
->flag
,
8641 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8642 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8645 if (ri
->attr
&& ri
->attr
->aspath
)
8647 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8648 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8649 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8651 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8653 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8654 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8656 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8657 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8659 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8660 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8662 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8663 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8664 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8666 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8667 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8668 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8671 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8672 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8680 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8682 struct bgp_table_stats ts
;
8685 if (!bgp
->rib
[afi
][safi
])
8687 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8688 afi
, safi
, VTY_NEWLINE
);
8692 memset (&ts
, 0, sizeof (ts
));
8693 ts
.table
= bgp
->rib
[afi
][safi
];
8694 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8696 vty_out (vty
, "BGP %s RIB statistics%s%s",
8697 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8699 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8701 if (!table_stats_strs
[i
])
8707 case BGP_STATS_ASPATH_AVGHOPS
:
8708 case BGP_STATS_ASPATH_AVGSIZE
:
8709 case BGP_STATS_AVGPLEN
:
8710 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8711 vty_out (vty
, "%12.2f",
8712 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8715 case BGP_STATS_ASPATH_TOTHOPS
:
8716 case BGP_STATS_ASPATH_TOTSIZE
:
8717 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8718 vty_out (vty
, "%12.2f",
8720 (float)ts
.counts
[i
] /
8721 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8724 case BGP_STATS_TOTPLEN
:
8725 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8726 vty_out (vty
, "%12.2f",
8728 (float)ts
.counts
[i
] /
8729 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8732 case BGP_STATS_SPACE
:
8733 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8734 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8735 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8737 vty_out (vty
, "%30s: ", "%% announced ");
8738 vty_out (vty
, "%12.2f%s",
8739 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8740 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8742 vty_out (vty
, "%30s: ", "/8 equivalent ");
8743 vty_out (vty
, "%12.2f%s",
8744 (float)ts
.counts
[BGP_STATS_SPACE
] /
8745 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8747 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8749 vty_out (vty
, "%30s: ", "/24 equivalent ");
8750 vty_out (vty
, "%12.2f",
8751 (float)ts
.counts
[BGP_STATS_SPACE
] /
8752 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8755 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8756 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8759 vty_out (vty
, "%s", VTY_NEWLINE
);
8765 bgp_table_stats_vty (struct vty
*vty
, const char *name
,
8766 const char *afi_str
, const char *safi_str
)
8773 bgp
= bgp_lookup_by_name (name
);
8775 bgp
= bgp_get_default ();
8779 vty_out (vty
, "%% No such BGP instance exist%s", VTY_NEWLINE
);
8782 afi
= bgp_vty_afi_from_arg(afi_str
);
8785 vty_out (vty
, "%% Invalid address family \"%s\"%s",
8786 afi_str
, VTY_NEWLINE
);
8789 safi
= bgp_vty_safi_from_arg(safi_str
);
8790 if (safi
== SAFI_MAX
)
8792 vty_out (vty
, "%% Invalid subsequent address family %s%s",
8793 safi_str
, VTY_NEWLINE
);
8797 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8800 DEFUN (show_bgp_statistics
,
8801 show_bgp_statistics_cmd
,
8802 "show [ip] bgp <ipv4|ipv6> <encap|multicast|unicast|vpn> statistics",
8808 "Address Family modifier\n"
8809 "Address Family modifier\n"
8810 "Address Family modifier\n"
8811 "Address Family modifier\n"
8812 "BGP RIB advertisement statistics\n")
8816 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_afi
]->arg
, argv
[idx_safi
]->arg
);
8819 DEFUN (show_bgp_statistics_view
,
8820 show_bgp_statistics_view_cmd
,
8821 "show [ip] bgp <view|vrf> WORD <ipv4|ipv6> <unicast|multicast|vpn|encap> statistics",
8825 BGP_INSTANCE_HELP_STR
8828 "Address Family modifier\n"
8829 "Address Family modifier\n"
8830 "Address Family modifier\n"
8831 "Address Family modifier\n"
8832 "BGP RIB advertisement statistics\n")
8836 return bgp_table_stats_vty (vty
, NULL
, argv
[idx_word
]->arg
, argv
[idx_afi
]->arg
);
8849 PCOUNT_PFCNT
, /* the figure we display to users */
8853 static const char *pcount_strs
[] =
8855 [PCOUNT_ADJ_IN
] = "Adj-in",
8856 [PCOUNT_DAMPED
] = "Damped",
8857 [PCOUNT_REMOVED
] = "Removed",
8858 [PCOUNT_HISTORY
] = "History",
8859 [PCOUNT_STALE
] = "Stale",
8860 [PCOUNT_VALID
] = "Valid",
8861 [PCOUNT_ALL
] = "All RIB",
8862 [PCOUNT_COUNTED
] = "PfxCt counted",
8863 [PCOUNT_PFCNT
] = "Useable",
8864 [PCOUNT_MAX
] = NULL
,
8869 unsigned int count
[PCOUNT_MAX
];
8870 const struct peer
*peer
;
8871 const struct bgp_table
*table
;
8875 bgp_peer_count_walker (struct thread
*t
)
8877 struct bgp_node
*rn
;
8878 struct peer_pcounts
*pc
= THREAD_ARG (t
);
8879 const struct peer
*peer
= pc
->peer
;
8881 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
8883 struct bgp_adj_in
*ain
;
8884 struct bgp_info
*ri
;
8886 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
8887 if (ain
->peer
== peer
)
8888 pc
->count
[PCOUNT_ADJ_IN
]++;
8890 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8892 char buf
[SU_ADDRSTRLEN
];
8894 if (ri
->peer
!= peer
)
8897 pc
->count
[PCOUNT_ALL
]++;
8899 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
8900 pc
->count
[PCOUNT_DAMPED
]++;
8901 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
8902 pc
->count
[PCOUNT_HISTORY
]++;
8903 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
8904 pc
->count
[PCOUNT_REMOVED
]++;
8905 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
8906 pc
->count
[PCOUNT_STALE
]++;
8907 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
8908 pc
->count
[PCOUNT_VALID
]++;
8909 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8910 pc
->count
[PCOUNT_PFCNT
]++;
8912 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
8914 pc
->count
[PCOUNT_COUNTED
]++;
8915 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8916 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
8918 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8919 buf
, SU_ADDRSTRLEN
),
8925 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8926 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
8928 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8929 buf
, SU_ADDRSTRLEN
),
8939 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
8941 struct peer_pcounts pcounts
= { .peer
= peer
};
8943 json_object
*json
= NULL
;
8944 json_object
*json_loop
= NULL
;
8948 json
= json_object_new_object();
8949 json_loop
= json_object_new_object();
8952 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
8953 || !peer
->bgp
->rib
[afi
][safi
])
8957 json_object_string_add(json
, "warning", "No such neighbor or address family");
8958 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8959 json_object_free(json
);
8962 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
8967 memset (&pcounts
, 0, sizeof(pcounts
));
8968 pcounts
.peer
= peer
;
8969 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
8971 /* in-place call via thread subsystem so as to record execution time
8972 * * stats for the thread-walk (i.e. ensure this can't be blamed on
8973 * * on just vty_read()).
8975 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
8979 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
8980 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
8981 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
8983 for (i
= 0; i
< PCOUNT_MAX
; i
++)
8984 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
8986 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
8988 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
8990 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
8991 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
8993 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8994 json_object_free(json
);
8999 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9001 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9002 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9007 vty_out (vty
, "Prefix counts for %s, %s%s",
9008 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9011 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9012 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9013 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9015 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9016 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9018 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9020 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9021 peer
->host
, VTY_NEWLINE
);
9022 vty_out (vty
, "Please report this bug, with the above command output%s",
9030 DEFUN (show_ip_bgp_neighbor_prefix_counts
,
9031 show_ip_bgp_neighbor_prefix_counts_cmd
,
9032 "show [ip] bgp neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9036 "Detailed information on TCP and BGP neighbor connections\n"
9037 "Neighbor to display information about\n"
9038 "Neighbor to display information about\n"
9039 "Neighbor on BGP configured interface\n"
9040 "Display detailed prefix count information\n"
9045 u_char uj
= use_json(argc
, argv
);
9047 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9051 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9054 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9055 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9056 "show [ip] bgp <view|vrf> WORD neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9060 BGP_INSTANCE_HELP_STR
9061 "Detailed information on TCP and BGP neighbor connections\n"
9062 "Neighbor to display information about\n"
9063 "Neighbor to display information about\n"
9064 "Neighbor on BGP configured interface\n"
9065 "Display detailed prefix count information\n"
9071 u_char uj
= use_json(argc
, argv
);
9073 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9077 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9080 DEFUN (show_bgp_ipv6_neighbor_prefix_counts
,
9081 show_bgp_ipv6_neighbor_prefix_counts_cmd
,
9082 "show [ip] bgp ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9087 "Detailed information on TCP and BGP neighbor connections\n"
9088 "Neighbor to display information about\n"
9089 "Neighbor to display information about\n"
9090 "Neighbor on BGP configured interface\n"
9091 "Display detailed prefix count information\n"
9096 u_char uj
= use_json(argc
, argv
);
9098 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9102 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9105 DEFUN (show_bgp_instance_ipv6_neighbor_prefix_counts
,
9106 show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
,
9107 "show [ip] bgp <view|vrf> WORD ipv6 neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9111 BGP_INSTANCE_HELP_STR
9113 "Detailed information on TCP and BGP neighbor connections\n"
9114 "Neighbor to display information about\n"
9115 "Neighbor to display information about\n"
9116 "Neighbor on BGP configured interface\n"
9117 "Display detailed prefix count information\n"
9123 u_char uj
= use_json(argc
, argv
);
9125 peer
= peer_lookup_in_view (vty
, argv
[idx_word
]->arg
, argv
[idx_peer
]->arg
, uj
);
9129 return bgp_peer_counts (vty
, peer
, AFI_IP6
, SAFI_UNICAST
, uj
);
9132 DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts
,
9133 show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
,
9134 "show [ip] bgp ipv4 <unicast|multicast> neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9139 "Address Family modifier\n"
9140 "Address Family modifier\n"
9141 "Detailed information on TCP and BGP neighbor connections\n"
9142 "Neighbor to display information about\n"
9143 "Neighbor to display information about\n"
9144 "Neighbor on BGP configured interface\n"
9145 "Display detailed prefix count information\n"
9151 u_char uj
= use_json(argc
, argv
);
9153 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9157 if (strncmp (argv
[idx_safi
]->arg
, "m", 1) == 0)
9158 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MULTICAST
, uj
);
9160 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9163 DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts
,
9164 show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
,
9165 "show [ip] bgp vpnv4 all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9170 "Display information about all VPNv4 NLRIs\n"
9171 "Detailed information on TCP and BGP neighbor connections\n"
9172 "Neighbor to display information about\n"
9173 "Neighbor to display information about\n"
9174 "Neighbor on BGP configured interface\n"
9175 "Display detailed prefix count information\n"
9180 u_char uj
= use_json(argc
, argv
);
9182 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9186 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9189 DEFUN (show_ip_bgp_vpnv4_all_route_prefix
,
9190 show_ip_bgp_vpnv4_all_route_prefix_cmd
,
9191 "show [ip] bgp vpnv4 all <A.B.C.D|A.B.C.D/M> [json]",
9196 "Display information about all VPNv4 NLRIs\n"
9197 "Network in the BGP routing table to display\n"
9198 "Network in the BGP routing table to display\n"
9202 char *network
= NULL
;
9203 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9204 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9205 return bgp_show_route (vty
, NULL
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9209 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9210 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9212 struct bgp_table
*table
;
9213 struct bgp_adj_in
*ain
;
9214 struct bgp_adj_out
*adj
;
9215 unsigned long output_count
;
9216 unsigned long filtered_count
;
9217 struct bgp_node
*rn
;
9222 struct attr_extra extra
;
9224 struct update_subgroup
*subgrp
;
9225 json_object
*json_scode
= NULL
;
9226 json_object
*json_ocode
= NULL
;
9227 json_object
*json_ar
= NULL
;
9228 struct peer_af
*paf
;
9232 json_scode
= json_object_new_object();
9233 json_ocode
= json_object_new_object();
9234 json_ar
= json_object_new_object();
9236 json_object_string_add(json_scode
, "suppressed", "s");
9237 json_object_string_add(json_scode
, "damped", "d");
9238 json_object_string_add(json_scode
, "history", "h");
9239 json_object_string_add(json_scode
, "valid", "*");
9240 json_object_string_add(json_scode
, "best", ">");
9241 json_object_string_add(json_scode
, "multipath", "=");
9242 json_object_string_add(json_scode
, "internal", "i");
9243 json_object_string_add(json_scode
, "ribFailure", "r");
9244 json_object_string_add(json_scode
, "stale", "S");
9245 json_object_string_add(json_scode
, "removed", "R");
9247 json_object_string_add(json_ocode
, "igp", "i");
9248 json_object_string_add(json_ocode
, "egp", "e");
9249 json_object_string_add(json_ocode
, "incomplete", "?");
9258 json_object_string_add(json
, "alert", "no BGP");
9259 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9260 json_object_free(json
);
9263 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9267 table
= bgp
->rib
[afi
][safi
];
9269 output_count
= filtered_count
= 0;
9270 subgrp
= peer_subgroup(peer
, afi
, safi
);
9272 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9276 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9277 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9278 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9279 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9280 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9284 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9285 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9286 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9288 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9289 VTY_NEWLINE
, VTY_NEWLINE
);
9294 attr
.extra
= &extra
;
9295 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9299 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9301 if (ain
->peer
== peer
)
9307 json_object_int_add(json
, "bgpTableVersion", 0);
9308 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9309 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9310 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9314 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9315 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9316 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9323 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9328 bgp_attr_dup(&attr
, ain
->attr
);
9329 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9331 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9342 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9343 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9344 if (paf
->peer
== peer
)
9350 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9351 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9352 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9353 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9357 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9358 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9359 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9360 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9368 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9374 bgp_attr_dup(&attr
, adj
->attr
);
9375 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9376 if (ret
!= RMAP_DENY
)
9378 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9388 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9390 if (output_count
!= 0)
9393 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9395 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9396 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9400 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9401 json_object_free(json
);
9407 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9408 int in
, const char *rmap_name
, u_char use_json
)
9410 json_object
*json
= NULL
;
9413 json
= json_object_new_object();
9415 if (!peer
|| !peer
->afc
[afi
][safi
])
9419 json_object_string_add(json
, "warning", "No such neighbor or address family");
9420 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9421 json_object_free(json
);
9424 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9429 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9433 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9434 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9435 json_object_free(json
);
9438 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9443 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9448 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9449 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9450 "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]",
9454 BGP_INSTANCE_HELP_STR
9456 "Address Family modifier\n"
9457 "Address Family modifier\n"
9459 "Address Family modifier\n"
9460 "Address Family modifier\n"
9462 "Address Family modifier\n"
9464 "Address Family modifier\n"
9465 "Detailed information on TCP and BGP neighbor connections\n"
9466 "Neighbor to display information about\n"
9467 "Neighbor to display information about\n"
9468 "Neighbor on BGP configured interface\n"
9469 "Display the received routes from neighbor\n"
9470 "Display the routes advertised to a BGP neighbor\n"
9471 "Route-map to modify the attributes\n"
9472 "Name of the route map\n"
9475 afi_t afi
= AFI_IP6
;
9476 safi_t safi
= SAFI_UNICAST
;
9478 char *rmap_name
= NULL
;
9479 char *peerstr
= NULL
;
9487 if (argv_find (argv
, argc
, "ip", &idx
))
9489 /* [<view|vrf> WORD] */
9490 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9491 vrf
= argv
[++idx
]->arg
;
9492 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9493 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9495 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9496 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9497 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9499 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9502 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9503 // advance idx if necessary
9504 argv_find (argv
, argc
, "unicast", &idx
);
9507 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9508 argv_find (argv
, argc
, "neighbors", &idx
);
9509 peerstr
= argv
[++idx
]->arg
;
9511 u_char uj
= use_json(argc
, argv
);
9513 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9517 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9521 if (argv_find (argv
, argc
, "received-routes", &idx
))
9523 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9525 if (argv_find (argv
, argc
, "route-map", &idx
))
9526 rmap_name
= argv
[++idx
]->arg
;
9528 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9531 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9532 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9533 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9539 "Address Family modifier\n"
9540 "Detailed information on TCP and BGP neighbor connections\n"
9541 "Neighbor to display information about\n"
9542 "Neighbor to display information about\n"
9543 "Neighbor on BGP configured interface\n"
9544 "Display information received from a BGP neighbor\n"
9545 "Display the prefixlist filter\n"
9548 afi_t afi
= AFI_IP6
;
9549 safi_t safi
= SAFI_UNICAST
;
9550 char *peerstr
= NULL
;
9560 if (argv_find (argv
, argc
, "ip", &idx
))
9562 /* [<ipv4|ipv6> [unicast]] */
9563 if (argv_find (argv
, argc
, "ipv4", &idx
))
9565 if (argv_find (argv
, argc
, "ipv6", &idx
))
9567 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9568 argv_find (argv
, argc
, "neighbors", &idx
);
9569 peerstr
= argv
[++idx
]->arg
;
9571 u_char uj
= use_json(argc
, argv
);
9573 ret
= str2sockunion (peerstr
, &su
);
9576 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9580 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9582 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9588 peer
= peer_lookup (NULL
, &su
);
9592 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9594 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9599 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9600 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9604 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9605 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9610 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9612 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9619 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9620 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9622 if (! peer
|| ! peer
->afc
[afi
][safi
])
9626 json_object
*json_no
= NULL
;
9627 json_no
= json_object_new_object();
9628 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9629 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9630 json_object_free(json_no
);
9633 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9637 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9640 DEFUN (show_ip_bgp_neighbor_routes
,
9641 show_ip_bgp_neighbor_routes_cmd
,
9642 "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]",
9646 BGP_INSTANCE_HELP_STR
9648 "Address Family modifier\n"
9649 "Address Family modifier\n"
9651 "Address Family modifier\n"
9652 "Address Family modifier\n"
9654 "Address Family modifier\n"
9656 "Address Family modifier\n"
9657 "Detailed information on TCP and BGP neighbor connections\n"
9658 "Neighbor to display information about\n"
9659 "Neighbor to display information about\n"
9660 "Neighbor on BGP configured interface\n"
9661 "Display flap statistics of the routes learned from neighbor\n"
9662 "Display the dampened routes received from neighbor\n"
9663 "Display routes learned from neighbor\n"
9667 char *peerstr
= NULL
;
9669 afi_t afi
= AFI_IP6
;
9670 safi_t safi
= SAFI_UNICAST
;
9672 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9677 if (argv_find (argv
, argc
, "ip", &idx
))
9679 /* [<view|vrf> WORD] */
9680 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
9681 vrf
= argv
[++idx
]->arg
;
9682 /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
9683 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
9685 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9686 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
9687 safi
= strmatch (argv
[idx
]->text
, "unicast") ? SAFI_UNICAST
: SAFI_MULTICAST
;
9689 else if (argv_find (argv
, argc
, "encap", &idx
) || argv_find (argv
, argc
, "vpnv4", &idx
))
9692 safi
= strmatch (argv
[idx
]->text
, "encap") ? SAFI_ENCAP
: SAFI_MPLS_VPN
;
9693 // advance idx if necessary
9694 argv_find (argv
, argc
, "unicast", &idx
);
9696 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9697 argv_find (argv
, argc
, "neighbors", &idx
);
9698 peerstr
= argv
[++idx
]->arg
;
9700 u_char uj
= use_json(argc
, argv
);
9702 peer
= peer_lookup_in_view (vty
, vrf
, peerstr
, uj
);
9705 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9709 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9710 sh_type
= bgp_show_type_flap_neighbor
;
9711 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9712 sh_type
= bgp_show_type_damp_neighbor
;
9713 else if (argv_find (argv
, argc
, "routes", &idx
))
9714 sh_type
= bgp_show_type_neighbor
;
9716 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9719 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9723 /* Distance value for the IP source prefix. */
9726 /* Name of the access-list to be matched. */
9730 static struct bgp_distance
*
9731 bgp_distance_new (void)
9733 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9737 bgp_distance_free (struct bgp_distance
*bdistance
)
9739 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9743 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9744 const char *ip_str
, const char *access_list_str
)
9751 struct bgp_node
*rn
;
9752 struct bgp_distance
*bdistance
;
9754 afi
= bgp_node_afi (vty
);
9755 safi
= bgp_node_safi (vty
);
9757 ret
= str2prefix (ip_str
, &p
);
9760 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9764 distance
= atoi (distance_str
);
9766 /* Get BGP distance node. */
9767 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9770 bdistance
= rn
->info
;
9771 bgp_unlock_node (rn
);
9775 bdistance
= bgp_distance_new ();
9776 rn
->info
= bdistance
;
9779 /* Set distance value. */
9780 bdistance
->distance
= distance
;
9782 /* Reset access-list configuration. */
9783 if (bdistance
->access_list
)
9785 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9786 bdistance
->access_list
= NULL
;
9788 if (access_list_str
)
9789 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9795 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9796 const char *ip_str
, const char *access_list_str
)
9803 struct bgp_node
*rn
;
9804 struct bgp_distance
*bdistance
;
9806 afi
= bgp_node_afi (vty
);
9807 safi
= bgp_node_safi (vty
);
9809 ret
= str2prefix (ip_str
, &p
);
9812 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9816 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9819 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9823 bdistance
= rn
->info
;
9824 distance
= atoi(distance_str
);
9826 if (bdistance
->distance
!= distance
)
9828 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9832 if (bdistance
->access_list
)
9833 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9834 bgp_distance_free (bdistance
);
9837 bgp_unlock_node (rn
);
9838 bgp_unlock_node (rn
);
9843 /* Apply BGP information to distance method. */
9845 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9846 safi_t safi
, struct bgp
*bgp
)
9848 struct bgp_node
*rn
;
9851 struct bgp_distance
*bdistance
;
9852 struct access_list
*alist
;
9853 struct bgp_static
*bgp_static
;
9860 /* Check source address. */
9861 sockunion2hostprefix (&peer
->su
, &q
);
9862 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9865 bdistance
= rn
->info
;
9866 bgp_unlock_node (rn
);
9868 if (bdistance
->access_list
)
9870 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9871 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9872 return bdistance
->distance
;
9875 return bdistance
->distance
;
9878 /* Backdoor check. */
9879 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9882 bgp_static
= rn
->info
;
9883 bgp_unlock_node (rn
);
9885 if (bgp_static
->backdoor
)
9887 if (bgp
->distance_local
[afi
][safi
])
9888 return bgp
->distance_local
[afi
][safi
];
9890 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9894 if (peer
->sort
== BGP_PEER_EBGP
)
9896 if (bgp
->distance_ebgp
[afi
][safi
])
9897 return bgp
->distance_ebgp
[afi
][safi
];
9898 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
9902 if (bgp
->distance_ibgp
[afi
][safi
])
9903 return bgp
->distance_ibgp
[afi
][safi
];
9904 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9908 DEFUN (bgp_distance
,
9910 "distance bgp (1-255) (1-255) (1-255)",
9911 "Define an administrative distance\n"
9913 "Distance for routes external to the AS\n"
9914 "Distance for routes internal to the AS\n"
9915 "Distance for local routes\n")
9917 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9919 int idx_number_2
= 3;
9920 int idx_number_3
= 4;
9924 afi
= bgp_node_afi (vty
);
9925 safi
= bgp_node_safi (vty
);
9927 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
9928 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
9929 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
9933 DEFUN (no_bgp_distance
,
9934 no_bgp_distance_cmd
,
9935 "no distance bgp [(1-255) (1-255) (1-255)]",
9937 "Define an administrative distance\n"
9939 "Distance for routes external to the AS\n"
9940 "Distance for routes internal to the AS\n"
9941 "Distance for local routes\n")
9943 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9947 afi
= bgp_node_afi (vty
);
9948 safi
= bgp_node_safi (vty
);
9950 bgp
->distance_ebgp
[afi
][safi
] = 0;
9951 bgp
->distance_ibgp
[afi
][safi
] = 0;
9952 bgp
->distance_local
[afi
][safi
] = 0;
9957 DEFUN (bgp_distance_source
,
9958 bgp_distance_source_cmd
,
9959 "distance (1-255) A.B.C.D/M",
9960 "Define an administrative distance\n"
9961 "Administrative distance\n"
9962 "IP source prefix\n")
9965 int idx_ipv4_prefixlen
= 2;
9966 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9970 DEFUN (no_bgp_distance_source
,
9971 no_bgp_distance_source_cmd
,
9972 "no distance (1-255) A.B.C.D/M",
9974 "Define an administrative distance\n"
9975 "Administrative distance\n"
9976 "IP source prefix\n")
9979 int idx_ipv4_prefixlen
= 3;
9980 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9984 DEFUN (bgp_distance_source_access_list
,
9985 bgp_distance_source_access_list_cmd
,
9986 "distance (1-255) A.B.C.D/M WORD",
9987 "Define an administrative distance\n"
9988 "Administrative distance\n"
9989 "IP source prefix\n"
9990 "Access list name\n")
9993 int idx_ipv4_prefixlen
= 2;
9995 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9999 DEFUN (no_bgp_distance_source_access_list
,
10000 no_bgp_distance_source_access_list_cmd
,
10001 "no distance (1-255) A.B.C.D/M WORD",
10003 "Define an administrative distance\n"
10004 "Administrative distance\n"
10005 "IP source prefix\n"
10006 "Access list name\n")
10008 int idx_number
= 2;
10009 int idx_ipv4_prefixlen
= 3;
10011 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10012 return CMD_SUCCESS
;
10015 DEFUN (ipv6_bgp_distance_source
,
10016 ipv6_bgp_distance_source_cmd
,
10017 "distance (1-255) X:X::X:X/M",
10018 "Define an administrative distance\n"
10019 "Administrative distance\n"
10020 "IP source prefix\n")
10022 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10023 return CMD_SUCCESS
;
10026 DEFUN (no_ipv6_bgp_distance_source
,
10027 no_ipv6_bgp_distance_source_cmd
,
10028 "no distance (1-255) X:X::X:X/M",
10030 "Define an administrative distance\n"
10031 "Administrative distance\n"
10032 "IP source prefix\n")
10034 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10035 return CMD_SUCCESS
;
10038 DEFUN (ipv6_bgp_distance_source_access_list
,
10039 ipv6_bgp_distance_source_access_list_cmd
,
10040 "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_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10047 return CMD_SUCCESS
;
10050 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10051 no_ipv6_bgp_distance_source_access_list_cmd
,
10052 "no distance (1-255) X:X::X:X/M WORD",
10054 "Define an administrative distance\n"
10055 "Administrative distance\n"
10056 "IP source prefix\n"
10057 "Access list name\n")
10059 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10060 return CMD_SUCCESS
;
10063 DEFUN (bgp_damp_set
,
10065 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10066 "BGP Specific commands\n"
10067 "Enable route-flap dampening\n"
10068 "Half-life time for the penalty\n"
10069 "Value to start reusing a route\n"
10070 "Value to start suppressing a route\n"
10071 "Maximum duration to suppress a stable route\n")
10073 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10074 int idx_half_life
= 2;
10076 int idx_suppress
= 4;
10077 int idx_max_suppress
= 5;
10078 int half
= DEFAULT_HALF_LIFE
* 60;
10079 int reuse
= DEFAULT_REUSE
;
10080 int suppress
= DEFAULT_SUPPRESS
;
10081 int max
= 4 * half
;
10085 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10086 reuse
= atoi (argv
[idx_reuse
]->arg
);
10087 suppress
= atoi (argv
[idx_suppress
]->arg
);
10088 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10090 else if (argc
== 3)
10092 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10096 if (suppress
< reuse
)
10098 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10103 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10104 half
, reuse
, suppress
, max
);
10107 DEFUN (bgp_damp_unset
,
10108 bgp_damp_unset_cmd
,
10109 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10111 "BGP Specific commands\n"
10112 "Enable route-flap dampening\n"
10113 "Half-life time for the penalty\n"
10114 "Value to start reusing a route\n"
10115 "Value to start suppressing a route\n"
10116 "Maximum duration to suppress a stable route\n")
10118 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10119 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10122 /* Display specified route of BGP table. */
10124 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10125 const char *ip_str
, afi_t afi
, safi_t safi
,
10126 struct prefix_rd
*prd
, int prefix_check
)
10129 struct prefix match
;
10130 struct bgp_node
*rn
;
10131 struct bgp_node
*rm
;
10132 struct bgp_info
*ri
;
10133 struct bgp_info
*ri_temp
;
10135 struct bgp_table
*table
;
10137 /* BGP structure lookup. */
10140 bgp
= bgp_lookup_by_name (view_name
);
10143 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10144 return CMD_WARNING
;
10149 bgp
= bgp_get_default ();
10152 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10153 return CMD_WARNING
;
10157 /* Check IP address argument. */
10158 ret
= str2prefix (ip_str
, &match
);
10161 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10162 return CMD_WARNING
;
10165 match
.family
= afi2family (afi
);
10167 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10169 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10171 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10174 if ((table
= rn
->info
) != NULL
)
10175 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10177 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10182 if (ri
->extra
&& ri
->extra
->damp_info
)
10184 ri_temp
= ri
->next
;
10185 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10193 bgp_unlock_node (rm
);
10199 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10201 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10206 if (ri
->extra
&& ri
->extra
->damp_info
)
10208 ri_temp
= ri
->next
;
10209 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10217 bgp_unlock_node (rn
);
10221 return CMD_SUCCESS
;
10224 DEFUN (clear_ip_bgp_dampening
,
10225 clear_ip_bgp_dampening_cmd
,
10226 "clear ip bgp dampening",
10230 "Clear route flap dampening information\n")
10232 bgp_damp_info_clean ();
10233 return CMD_SUCCESS
;
10236 DEFUN (clear_ip_bgp_dampening_prefix
,
10237 clear_ip_bgp_dampening_prefix_cmd
,
10238 "clear ip bgp dampening A.B.C.D/M",
10242 "Clear route flap dampening information\n"
10245 int idx_ipv4_prefixlen
= 4;
10246 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10247 SAFI_UNICAST
, NULL
, 1);
10250 DEFUN (clear_ip_bgp_dampening_address
,
10251 clear_ip_bgp_dampening_address_cmd
,
10252 "clear ip bgp dampening A.B.C.D",
10256 "Clear route flap dampening information\n"
10257 "Network to clear damping information\n")
10260 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10261 SAFI_UNICAST
, NULL
, 0);
10264 DEFUN (clear_ip_bgp_dampening_address_mask
,
10265 clear_ip_bgp_dampening_address_mask_cmd
,
10266 "clear ip bgp dampening A.B.C.D A.B.C.D",
10270 "Clear route flap dampening information\n"
10271 "Network to clear damping information\n"
10275 int idx_ipv4_2
= 5;
10277 char prefix_str
[BUFSIZ
];
10279 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10282 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10283 return CMD_WARNING
;
10286 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10287 SAFI_UNICAST
, NULL
, 0);
10290 /* also used for encap safi */
10292 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10293 afi_t afi
, safi_t safi
, int *write
)
10295 struct bgp_node
*prn
;
10296 struct bgp_node
*rn
;
10297 struct bgp_table
*table
;
10299 struct prefix_rd
*prd
;
10300 struct bgp_static
*bgp_static
;
10302 char buf
[SU_ADDRSTRLEN
];
10303 char rdbuf
[RD_ADDRSTRLEN
];
10305 /* Network configuration. */
10306 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10307 if ((table
= prn
->info
) != NULL
)
10308 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10309 if ((bgp_static
= rn
->info
) != NULL
)
10312 prd
= (struct prefix_rd
*) &prn
->p
;
10314 /* "address-family" display. */
10315 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10317 /* "network" configuration display. */
10318 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10319 label
= decode_label (bgp_static
->tag
);
10321 vty_out (vty
, " network %s/%d rd %s tag %d",
10322 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10325 vty_out (vty
, "%s", VTY_NEWLINE
);
10330 /* Configuration of static route announcement and aggregate
10333 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10334 afi_t afi
, safi_t safi
, int *write
)
10336 struct bgp_node
*rn
;
10338 struct bgp_static
*bgp_static
;
10339 struct bgp_aggregate
*bgp_aggregate
;
10340 char buf
[SU_ADDRSTRLEN
];
10342 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10343 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10345 /* Network configuration. */
10346 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10347 if ((bgp_static
= rn
->info
) != NULL
)
10351 /* "address-family" display. */
10352 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10354 /* "network" configuration display. */
10355 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10357 u_int32_t destination
;
10358 struct in_addr netmask
;
10360 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10361 masklen2ip (p
->prefixlen
, &netmask
);
10362 vty_out (vty
, " network %s",
10363 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10365 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10366 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10367 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10368 || p
->u
.prefix4
.s_addr
== 0)
10370 /* Natural mask is not display. */
10373 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10377 vty_out (vty
, " network %s/%d",
10378 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10382 if (bgp_static
->rmap
.name
)
10383 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10386 if (bgp_static
->backdoor
)
10387 vty_out (vty
, " backdoor");
10390 vty_out (vty
, "%s", VTY_NEWLINE
);
10393 /* Aggregate-address configuration. */
10394 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10395 if ((bgp_aggregate
= rn
->info
) != NULL
)
10399 /* "address-family" display. */
10400 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10402 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10404 struct in_addr netmask
;
10406 masklen2ip (p
->prefixlen
, &netmask
);
10407 vty_out (vty
, " aggregate-address %s %s",
10408 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10409 inet_ntoa (netmask
));
10413 vty_out (vty
, " aggregate-address %s/%d",
10414 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10418 if (bgp_aggregate
->as_set
)
10419 vty_out (vty
, " as-set");
10421 if (bgp_aggregate
->summary_only
)
10422 vty_out (vty
, " summary-only");
10424 vty_out (vty
, "%s", VTY_NEWLINE
);
10431 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10432 safi_t safi
, int *write
)
10434 struct bgp_node
*rn
;
10435 struct bgp_distance
*bdistance
;
10437 /* Distance configuration. */
10438 if (bgp
->distance_ebgp
[afi
][safi
]
10439 && bgp
->distance_ibgp
[afi
][safi
]
10440 && bgp
->distance_local
[afi
][safi
]
10441 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10442 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10443 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10445 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10446 vty_out (vty
, " distance bgp %d %d %d%s",
10447 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10448 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10451 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10452 rn
= bgp_route_next (rn
))
10453 if ((bdistance
= rn
->info
) != NULL
)
10455 char buf
[PREFIX_STRLEN
];
10457 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10458 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10459 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10460 bdistance
->access_list
? bdistance
->access_list
: "",
10467 /* Allocate routing table structure and install commands. */
10469 bgp_route_init (void)
10474 /* Init BGP distance table. */
10475 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10476 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10477 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10479 /* IPv4 BGP commands. */
10480 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10481 install_element (BGP_NODE
, &bgp_network_cmd
);
10482 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10483 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10484 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10485 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10486 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10487 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10488 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10489 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10490 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10491 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10492 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10493 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10495 install_element (BGP_NODE
, &aggregate_address_cmd
);
10496 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10497 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10498 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10500 /* IPv4 unicast configuration. */
10501 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10502 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10503 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10504 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10505 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10506 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10507 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10508 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10509 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10510 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10511 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10513 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10514 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10515 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10516 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10518 /* IPv4 multicast configuration. */
10519 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10520 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10521 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10522 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10523 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10524 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10525 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10526 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10527 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10528 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10529 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10530 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10531 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10532 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10533 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10535 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10536 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_cmd
);
10537 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10538 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10539 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10540 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10541 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10542 install_element (VIEW_NODE
, &show_ip_bgp_dampening_params_cmd
);
10543 install_element (VIEW_NODE
, &show_ip_bgp_ipv4_dampening_parameters_cmd
);
10544 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_route_prefix_cmd
);
10546 /* BGP dampening clear commands */
10547 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10548 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10549 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10550 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10553 install_element (ENABLE_NODE
, &show_ip_bgp_neighbor_prefix_counts_cmd
);
10554 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10555 install_element (ENABLE_NODE
, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd
);
10556 install_element (ENABLE_NODE
, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd
);
10557 install_element (ENABLE_NODE
, &show_bgp_ipv6_neighbor_prefix_counts_cmd
);
10558 install_element (ENABLE_NODE
, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd
);
10560 /* New config IPv6 BGP commands. */
10561 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10562 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10563 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10564 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10565 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10567 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10568 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10570 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10571 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10574 install_element (ENABLE_NODE
, &show_bgp_statistics_cmd
);
10575 install_element (ENABLE_NODE
, &show_bgp_statistics_view_cmd
);
10577 install_element (BGP_NODE
, &bgp_distance_cmd
);
10578 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10579 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10580 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10581 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10582 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10583 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10584 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10585 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10586 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10587 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10588 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10589 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10590 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10591 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10592 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10593 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10594 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10595 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10596 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10597 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10598 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10599 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10600 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10601 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10602 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10603 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10604 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10605 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10606 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10608 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10609 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10610 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10611 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10613 /* IPv4 Multicast Mode */
10614 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10615 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10619 bgp_route_finish (void)
10624 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10625 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10627 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10628 bgp_distance_table
[afi
][safi
] = NULL
;