1 /* BGP routing information
2 Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 Copyright (C) 2016 Job Snijders <job@instituut.net>
5 This file is part of GNU Zebra.
7 GNU Zebra is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 GNU Zebra is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Zebra; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "sockunion.h"
36 #include "workqueue.h"
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_route.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_debug.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_regex.h"
48 #include "bgpd/bgp_community.h"
49 #include "bgpd/bgp_ecommunity.h"
50 #include "bgpd/bgp_lcommunity.h"
51 #include "bgpd/bgp_clist.h"
52 #include "bgpd/bgp_packet.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_fsm.h"
55 #include "bgpd/bgp_mplsvpn.h"
56 #include "bgpd/bgp_encap.h"
57 #include "bgpd/bgp_nexthop.h"
58 #include "bgpd/bgp_damp.h"
59 #include "bgpd/bgp_advertise.h"
60 #include "bgpd/bgp_zebra.h"
61 #include "bgpd/bgp_vty.h"
62 #include "bgpd/bgp_mpath.h"
63 #include "bgpd/bgp_nht.h"
64 #include "bgpd/bgp_updgrp.h"
67 #include "bgpd/rfapi/rfapi_backend.h"
68 #include "bgpd/rfapi/vnc_import_bgp.h"
69 #include "bgpd/rfapi/vnc_export_bgp.h"
72 /* Extern from bgp_dump.c */
73 extern const char *bgp_origin_str
[];
74 extern const char *bgp_origin_long_str
[];
77 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
78 struct prefix_rd
*prd
)
81 struct bgp_node
*prn
= NULL
;
87 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
89 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
91 if (prn
->info
== NULL
)
92 prn
->info
= bgp_table_init (afi
, safi
);
94 bgp_unlock_node (prn
);
98 rn
= bgp_node_get (table
, p
);
100 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
106 /* Allocate bgp_info_extra */
107 static struct bgp_info_extra
*
108 bgp_info_extra_new (void)
110 struct bgp_info_extra
*new;
111 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
116 bgp_info_extra_free (struct bgp_info_extra
**extra
)
120 if ((*extra
)->damp_info
)
121 bgp_damp_info_free ((*extra
)->damp_info
, 0);
123 (*extra
)->damp_info
= NULL
;
125 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
131 /* Get bgp_info extra information for the given bgp_info, lazy allocated
134 struct bgp_info_extra
*
135 bgp_info_extra_get (struct bgp_info
*ri
)
138 ri
->extra
= bgp_info_extra_new();
142 /* Allocate new bgp info structure. */
146 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
149 /* Free bgp route information. */
151 bgp_info_free (struct bgp_info
*binfo
)
154 bgp_attr_unintern (&binfo
->attr
);
156 bgp_unlink_nexthop(binfo
);
157 bgp_info_extra_free (&binfo
->extra
);
158 bgp_info_mpath_free (&binfo
->mpath
);
160 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
162 XFREE (MTYPE_BGP_ROUTE
, binfo
);
166 bgp_info_lock (struct bgp_info
*binfo
)
173 bgp_info_unlock (struct bgp_info
*binfo
)
175 assert (binfo
&& binfo
->lock
> 0);
178 if (binfo
->lock
== 0)
181 zlog_debug ("%s: unlocked and freeing", __func__
);
182 zlog_backtrace (LOG_DEBUG
);
184 bgp_info_free (binfo
);
189 if (binfo
->lock
== 1)
191 zlog_debug ("%s: unlocked to 1", __func__
);
192 zlog_backtrace (LOG_DEBUG
);
200 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
202 struct bgp_info
*top
;
214 peer_lock (ri
->peer
); /* bgp_info peer reference */
217 /* Do the actual removal of info from RIB, for use by bgp_process
218 completion callback *only* */
220 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
223 ri
->next
->prev
= ri
->prev
;
225 ri
->prev
->next
= ri
->next
;
229 bgp_info_mpath_dequeue (ri
);
230 bgp_info_unlock (ri
);
231 bgp_unlock_node (rn
);
235 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
237 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
238 /* set of previous already took care of pcount */
239 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
242 /* undo the effects of a previous call to bgp_info_delete; typically
243 called when a route is deleted and then quickly re-added before the
244 deletion has been processed */
246 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
248 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
249 /* unset of previous already took care of pcount */
250 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
253 /* Adjust pcount as required */
255 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
257 struct bgp_table
*table
;
259 assert (rn
&& bgp_node_table (rn
));
260 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
262 table
= bgp_node_table (rn
);
264 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
267 if (!BGP_INFO_COUNTABLE (ri
)
268 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
271 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
273 /* slight hack, but more robust against errors. */
274 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
275 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
278 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
279 __func__
, ri
->peer
->host
);
280 zlog_backtrace (LOG_WARNING
);
281 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
284 else if (BGP_INFO_COUNTABLE (ri
)
285 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
287 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
288 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
293 /* Set/unset bgp_info flags, adjusting any other state as needed.
294 * This is here primarily to keep prefix-count in check.
297 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
299 SET_FLAG (ri
->flags
, flag
);
301 /* early bath if we know it's not a flag that changes countability state */
302 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
305 bgp_pcount_adjust (rn
, ri
);
309 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
311 UNSET_FLAG (ri
->flags
, flag
);
313 /* early bath if we know it's not a flag that changes countability state */
314 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
317 bgp_pcount_adjust (rn
, ri
);
320 /* Get MED value. If MED value is missing and "bgp bestpath
321 missing-as-worst" is specified, treat it as the worst value. */
323 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
325 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
329 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
337 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
339 if (ri
->addpath_rx_id
)
340 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
342 sprintf(buf
, "path %s", ri
->peer
->host
);
345 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
347 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
348 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
351 struct attr
*newattr
, *existattr
;
352 struct attr_extra
*newattre
, *existattre
;
353 bgp_peer_sort_t new_sort
;
354 bgp_peer_sort_t exist_sort
;
356 u_int32_t exist_pref
;
359 u_int32_t new_weight
;
360 u_int32_t exist_weight
;
361 uint32_t newm
, existm
;
362 struct in_addr new_id
;
363 struct in_addr exist_id
;
366 int internal_as_route
;
369 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
370 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
378 zlog_debug("%s: new is NULL", pfx_buf
);
383 bgp_info_path_with_addpath_rx_str (new, new_buf
);
388 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
394 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
395 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
396 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
400 existattr
= exist
->attr
;
401 newattre
= newattr
->extra
;
402 existattre
= existattr
->extra
;
404 /* 1. Weight check. */
405 new_weight
= exist_weight
= 0;
408 new_weight
= newattre
->weight
;
410 exist_weight
= existattre
->weight
;
412 if (new_weight
> exist_weight
)
415 zlog_debug("%s: %s wins over %s due to weight %d > %d",
416 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
420 if (new_weight
< exist_weight
)
423 zlog_debug("%s: %s loses to %s due to weight %d < %d",
424 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
428 /* 2. Local preference check. */
429 new_pref
= exist_pref
= bgp
->default_local_pref
;
431 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
432 new_pref
= newattr
->local_pref
;
433 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
434 exist_pref
= existattr
->local_pref
;
436 if (new_pref
> exist_pref
)
439 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
440 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
444 if (new_pref
< exist_pref
)
447 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
448 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
452 /* 3. Local route check. We prefer:
454 * - BGP_ROUTE_AGGREGATE
455 * - BGP_ROUTE_REDISTRIBUTE
457 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
460 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
461 pfx_buf
, new_buf
, exist_buf
);
465 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
468 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
469 pfx_buf
, new_buf
, exist_buf
);
473 /* 4. AS path length check. */
474 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
476 int exist_hops
= aspath_count_hops (existattr
->aspath
);
477 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
479 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
483 aspath_hops
= aspath_count_hops (newattr
->aspath
);
484 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
486 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
489 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
490 pfx_buf
, new_buf
, exist_buf
,
491 aspath_hops
, (exist_hops
+ exist_confeds
));
495 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
498 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
499 pfx_buf
, new_buf
, exist_buf
,
500 aspath_hops
, (exist_hops
+ exist_confeds
));
506 int newhops
= aspath_count_hops (newattr
->aspath
);
508 if (newhops
< exist_hops
)
511 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
512 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
516 if (newhops
> exist_hops
)
519 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
520 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
526 /* 5. Origin check. */
527 if (newattr
->origin
< existattr
->origin
)
530 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
531 pfx_buf
, new_buf
, exist_buf
,
532 bgp_origin_long_str
[newattr
->origin
],
533 bgp_origin_long_str
[existattr
->origin
]);
537 if (newattr
->origin
> existattr
->origin
)
540 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
541 pfx_buf
, new_buf
, exist_buf
,
542 bgp_origin_long_str
[newattr
->origin
],
543 bgp_origin_long_str
[existattr
->origin
]);
548 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
549 && aspath_count_hops (existattr
->aspath
) == 0);
550 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
551 && aspath_count_confeds (existattr
->aspath
) > 0
552 && aspath_count_hops (newattr
->aspath
) == 0
553 && aspath_count_hops (existattr
->aspath
) == 0);
555 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
556 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
558 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
559 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
560 || internal_as_route
)
562 new_med
= bgp_med_value (new->attr
, bgp
);
563 exist_med
= bgp_med_value (exist
->attr
, bgp
);
565 if (new_med
< exist_med
)
568 zlog_debug("%s: %s wins over %s due to MED %d < %d",
569 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
573 if (new_med
> exist_med
)
576 zlog_debug("%s: %s loses to %s due to MED %d > %d",
577 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
582 /* 7. Peer type check. */
583 new_sort
= new->peer
->sort
;
584 exist_sort
= exist
->peer
->sort
;
586 if (new_sort
== BGP_PEER_EBGP
587 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
590 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
591 pfx_buf
, new_buf
, exist_buf
);
595 if (exist_sort
== BGP_PEER_EBGP
596 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
599 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
600 pfx_buf
, new_buf
, exist_buf
);
604 /* 8. IGP metric check. */
608 newm
= new->extra
->igpmetric
;
610 existm
= exist
->extra
->igpmetric
;
615 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
616 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
623 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
624 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
628 /* 9. Same IGP metric. Compare the cluster list length as
629 representative of IGP hops metric. Rewrite the metric value
630 pair (newm, existm) with the cluster list length. Prefer the
631 path with smaller cluster list length. */
634 if (peer_sort (new->peer
) == BGP_PEER_IBGP
635 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
636 && (mpath_cfg
== NULL
||
637 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
638 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
640 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
641 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
646 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
647 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
654 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
655 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
661 /* 10. confed-external vs. confed-internal */
662 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
664 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
667 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
668 pfx_buf
, new_buf
, exist_buf
);
672 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
675 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
676 pfx_buf
, new_buf
, exist_buf
);
681 /* 11. Maximum path check. */
684 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
688 * For the two paths, all comparison steps till IGP metric
689 * have succeeded - including AS_PATH hop count. Since 'bgp
690 * bestpath as-path multipath-relax' knob is on, we don't need
691 * an exact match of AS_PATH. Thus, mark the paths are equal.
692 * That will trigger both these paths to get into the multipath
698 zlog_debug("%s: %s and %s are equal via multipath-relax",
699 pfx_buf
, new_buf
, exist_buf
);
701 else if (new->peer
->sort
== BGP_PEER_IBGP
)
703 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
708 zlog_debug("%s: %s and %s are equal via matching aspaths",
709 pfx_buf
, new_buf
, exist_buf
);
712 else if (new->peer
->as
== exist
->peer
->as
)
717 zlog_debug("%s: %s and %s are equal via same remote-as",
718 pfx_buf
, new_buf
, exist_buf
);
724 * TODO: If unequal cost ibgp multipath is enabled we can
725 * mark the paths as equal here instead of returning
730 zlog_debug("%s: %s wins over %s after IGP metric comparison",
731 pfx_buf
, new_buf
, exist_buf
);
733 zlog_debug("%s: %s loses to %s after IGP metric comparison",
734 pfx_buf
, new_buf
, exist_buf
);
739 /* 12. If both paths are external, prefer the path that was received
740 first (the oldest one). This step minimizes route-flap, since a
741 newer path won't displace an older one, even if it was the
742 preferred route based on the additional decision criteria below. */
743 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
744 && new_sort
== BGP_PEER_EBGP
745 && exist_sort
== BGP_PEER_EBGP
)
747 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
750 zlog_debug("%s: %s wins over %s due to oldest external",
751 pfx_buf
, new_buf
, exist_buf
);
755 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
758 zlog_debug("%s: %s loses to %s due to oldest external",
759 pfx_buf
, new_buf
, exist_buf
);
764 /* 13. Router-ID comparision. */
765 /* If one of the paths is "stale", the corresponding peer router-id will
766 * be 0 and would always win over the other path. If originator id is
767 * used for the comparision, it will decide which path is better.
769 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
770 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
772 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
773 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
774 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
776 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
778 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
781 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
782 pfx_buf
, new_buf
, exist_buf
);
786 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
789 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
790 pfx_buf
, new_buf
, exist_buf
);
794 /* 14. Cluster length comparision. */
795 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
796 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
798 if (new_cluster
< exist_cluster
)
801 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
802 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
806 if (new_cluster
> exist_cluster
)
809 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
810 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
814 /* 15. Neighbor address comparision. */
815 /* Do this only if neither path is "stale" as stale paths do not have
816 * valid peer information (as the connection may or may not be up).
818 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
821 zlog_debug("%s: %s wins over %s due to latter path being STALE",
822 pfx_buf
, new_buf
, exist_buf
);
826 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
829 zlog_debug("%s: %s loses to %s due to former path being STALE",
830 pfx_buf
, new_buf
, exist_buf
);
834 /* locally configured routes to advertise do not have su_remote */
835 if (new->peer
->su_remote
== NULL
)
837 if (exist
->peer
->su_remote
== NULL
)
840 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
845 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
846 pfx_buf
, new_buf
, exist_buf
);
853 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
854 pfx_buf
, new_buf
, exist_buf
);
859 zlog_debug("%s: %s wins over %s due to nothing left to compare",
860 pfx_buf
, new_buf
, exist_buf
);
865 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
866 * is preferred, or 0 if they are the same (usually will only occur if
867 * multipath is enabled
868 * This version is compatible with */
870 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
871 afi_t afi
, safi_t safi
)
875 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
889 static enum filter_type
890 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
891 afi_t afi
, safi_t safi
)
893 struct bgp_filter
*filter
;
895 filter
= &peer
->filter
[afi
][safi
];
897 #define FILTER_EXIST_WARN(F,f,filter) \
898 if (BGP_DEBUG (update, UPDATE_IN) \
899 && !(F ## _IN (filter))) \
900 zlog_warn ("%s: Could not find configured input %s-list %s!", \
901 peer->host, #f, F ## _IN_NAME(filter));
903 if (DISTRIBUTE_IN_NAME (filter
)) {
904 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
906 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
910 if (PREFIX_LIST_IN_NAME (filter
)) {
911 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
913 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
917 if (FILTER_LIST_IN_NAME (filter
)) {
918 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
920 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
924 return FILTER_PERMIT
;
925 #undef FILTER_EXIST_WARN
928 static enum filter_type
929 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
930 afi_t afi
, safi_t safi
)
932 struct bgp_filter
*filter
;
934 filter
= &peer
->filter
[afi
][safi
];
936 #define FILTER_EXIST_WARN(F,f,filter) \
937 if (BGP_DEBUG (update, UPDATE_OUT) \
938 && !(F ## _OUT (filter))) \
939 zlog_warn ("%s: Could not find configured output %s-list %s!", \
940 peer->host, #f, F ## _OUT_NAME(filter));
942 if (DISTRIBUTE_OUT_NAME (filter
)) {
943 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
945 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
949 if (PREFIX_LIST_OUT_NAME (filter
)) {
950 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
952 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
956 if (FILTER_LIST_OUT_NAME (filter
)) {
957 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
959 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
963 return FILTER_PERMIT
;
964 #undef FILTER_EXIST_WARN
967 /* If community attribute includes no_export then return 1. */
969 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
973 /* NO_ADVERTISE check. */
974 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
977 /* NO_EXPORT check. */
978 if (peer
->sort
== BGP_PEER_EBGP
&&
979 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
982 /* NO_EXPORT_SUBCONFED check. */
983 if (peer
->sort
== BGP_PEER_EBGP
984 || peer
->sort
== BGP_PEER_CONFED
)
985 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
991 /* Route reflection loop check. */
993 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
995 struct in_addr cluster_id
;
997 if (attr
->extra
&& attr
->extra
->cluster
)
999 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1000 cluster_id
= peer
->bgp
->cluster_id
;
1002 cluster_id
= peer
->bgp
->router_id
;
1004 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1011 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1012 afi_t afi
, safi_t safi
, const char *rmap_name
)
1014 struct bgp_filter
*filter
;
1015 struct bgp_info info
;
1016 route_map_result_t ret
;
1017 struct route_map
*rmap
= NULL
;
1019 filter
= &peer
->filter
[afi
][safi
];
1021 /* Apply default weight value. */
1022 if (peer
->weight
[afi
][safi
])
1023 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1027 rmap
= route_map_lookup_by_name(rmap_name
);
1034 if (ROUTE_MAP_IN_NAME(filter
))
1036 rmap
= ROUTE_MAP_IN (filter
);
1043 /* Route map apply. */
1046 /* Duplicate current value to new strucutre for modification. */
1050 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1052 /* Apply BGP route map to the attribute. */
1053 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1055 peer
->rmap_type
= 0;
1057 if (ret
== RMAP_DENYMATCH
)
1059 /* Free newly generated AS path and community by route-map. */
1060 bgp_attr_flush (attr
);
1068 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1069 afi_t afi
, safi_t safi
, const char *rmap_name
)
1071 struct bgp_filter
*filter
;
1072 struct bgp_info info
;
1073 route_map_result_t ret
;
1074 struct route_map
*rmap
= NULL
;
1076 filter
= &peer
->filter
[afi
][safi
];
1078 /* Apply default weight value. */
1079 if (peer
->weight
[afi
][safi
])
1080 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1084 rmap
= route_map_lookup_by_name(rmap_name
);
1091 if (ROUTE_MAP_OUT_NAME(filter
))
1093 rmap
= ROUTE_MAP_OUT (filter
);
1100 /* Route map apply. */
1103 /* Duplicate current value to new strucutre for modification. */
1107 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1109 /* Apply BGP route map to the attribute. */
1110 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1112 peer
->rmap_type
= 0;
1114 if (ret
== RMAP_DENYMATCH
)
1115 /* caller has multiple error paths with bgp_attr_flush() */
1121 /* If this is an EBGP peer with remove-private-AS */
1123 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1124 struct peer
*peer
, struct attr
*attr
)
1126 if (peer
->sort
== BGP_PEER_EBGP
&&
1127 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1128 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1129 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1130 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1132 // Take action on the entire aspath
1133 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1134 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1136 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1137 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1139 // The entire aspath consists of private ASNs so create an empty aspath
1140 else if (aspath_private_as_check (attr
->aspath
))
1141 attr
->aspath
= aspath_empty_get ();
1143 // There are some public and some private ASNs, remove the private ASNs
1145 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1148 // 'all' was not specified so the entire aspath must be private ASNs
1149 // for us to do anything
1150 else if (aspath_private_as_check (attr
->aspath
))
1152 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1153 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1155 attr
->aspath
= aspath_empty_get ();
1160 /* If this is an EBGP peer with as-override */
1162 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1163 struct peer
*peer
, struct attr
*attr
)
1165 if (peer
->sort
== BGP_PEER_EBGP
&&
1166 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1168 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1169 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1174 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1176 if (family
== AF_INET
)
1177 attr
->nexthop
.s_addr
= 0;
1178 if (family
== AF_INET6
)
1179 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1183 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1184 struct prefix
*p
, struct attr
*attr
)
1186 struct bgp_filter
*filter
;
1189 struct peer
*onlypeer
;
1191 struct attr
*riattr
;
1192 struct peer_af
*paf
;
1193 char buf
[SU_ADDRSTRLEN
];
1199 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1201 if (DISABLE_BGP_ANNOUNCE
)
1204 afi
= SUBGRP_AFI(subgrp
);
1205 safi
= SUBGRP_SAFI(subgrp
);
1206 peer
= SUBGRP_PEER(subgrp
);
1208 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1209 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1212 filter
= &peer
->filter
[afi
][safi
];
1213 bgp
= SUBGRP_INST(subgrp
);
1214 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1217 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1218 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1219 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1222 * direct and direct_ext type routes originate internally even
1223 * though they can have peer pointers that reference other systems
1226 prefix2str(p
, buf
, BUFSIZ
);
1227 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1232 /* With addpath we may be asked to TX all kinds of paths so make sure
1234 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1235 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1236 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1241 /* If this is not the bestpath then check to see if there is an enabled addpath
1242 * feature that requires us to advertise it */
1243 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1245 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1251 /* Aggregate-address suppress check. */
1252 if (ri
->extra
&& ri
->extra
->suppress
)
1253 if (! UNSUPPRESS_MAP_NAME (filter
))
1258 /* Do not send back route to sender. */
1259 if (onlypeer
&& from
== onlypeer
)
1264 /* Do not send the default route in the BGP table if the neighbor is
1265 * configured for default-originate */
1266 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1268 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1270 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1274 /* Transparency check. */
1275 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1276 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1281 /* If community is not disabled check the no-export and local. */
1282 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1284 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1285 zlog_debug ("subgrpannouncecheck: community filter check fail");
1289 /* If the attribute has originator-id and it is same as remote
1292 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1293 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1295 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1296 zlog_debug ("%s [Update:SEND] %s/%d originator-id is same as "
1299 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1304 /* ORF prefix-list filter check */
1305 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1306 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1307 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1308 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1309 if (peer
->orf_plist
[afi
][safi
])
1311 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1313 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1314 zlog_debug ("%s [Update:SEND] %s/%d is filtered via ORF",
1316 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1322 /* Output filter check. */
1323 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1325 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1326 zlog_debug ("%s [Update:SEND] %s/%d is filtered",
1328 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
1333 #ifdef BGP_SEND_ASPATH_CHECK
1334 /* AS path loop check. */
1335 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1337 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1338 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1339 "that is part of AS path.",
1340 onlypeer
->host
, onlypeer
->as
);
1343 #endif /* BGP_SEND_ASPATH_CHECK */
1345 /* If we're a CONFED we need to loop check the CONFED ID too */
1346 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1348 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1350 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1351 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1359 /* Route-Reflect check. */
1360 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1365 /* IBGP reflection check. */
1366 if (reflect
&& !samepeer_safe
)
1368 /* A route from a Client peer. */
1369 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1371 /* Reflect to all the Non-Client peers and also to the
1372 Client peers other than the originator. Originator check
1373 is already done. So there is noting to do. */
1374 /* no bgp client-to-client reflection check. */
1375 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1376 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1377 PEER_FLAG_REFLECTOR_CLIENT
))
1382 /* A route from a Non-client peer. Reflect to all other
1384 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1385 PEER_FLAG_REFLECTOR_CLIENT
))
1390 /* For modify attribute, copy it to temporary structure. */
1391 bgp_attr_dup (attr
, riattr
);
1393 /* If local-preference is not set. */
1394 if ((peer
->sort
== BGP_PEER_IBGP
1395 || peer
->sort
== BGP_PEER_CONFED
)
1396 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1398 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1399 attr
->local_pref
= bgp
->default_local_pref
;
1402 /* If originator-id is not set and the route is to be reflected,
1403 set the originator id */
1404 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1406 attr
->extra
= bgp_attr_extra_get(attr
);
1407 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1408 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1411 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1412 if (peer
->sort
== BGP_PEER_EBGP
1413 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1415 if (from
!= bgp
->peer_self
&& ! transparent
1416 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1417 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1420 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1421 * in announce check, only certain flags and length (or number of nexthops
1422 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1423 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1424 * Typically, the source nexthop in the attribute is preserved but in the
1425 * scenarios where we know it will always be overwritten, we reset the
1426 * nexthop to "0" in an attempt to achieve better Update packing. An
1427 * example of this is when a prefix from each of 2 IBGP peers needs to be
1428 * announced to an EBGP peer (and they have the same attributes barring
1432 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1434 #define NEXTHOP_IS_V6 (\
1435 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1436 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1437 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1438 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1440 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1441 * the peer (group) is configured to receive link-local nexthop unchanged
1442 * and it is available in the prefix OR we're not reflecting the route and
1443 * the peer (group) to whom we're going to announce is on a shared network
1444 * and this is either a self-originated route or the peer is EBGP.
1448 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1449 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1450 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1451 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1452 (!reflect
&& peer
->shared_network
&&
1453 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1455 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1458 /* Clear off link-local nexthop in source, whenever it is not needed to
1459 * ensure more prefixes share the same attribute for announcement.
1461 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1462 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1463 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1466 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1467 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1469 /* Route map & unsuppress-map apply. */
1470 if (ROUTE_MAP_OUT_NAME (filter
)
1471 || (ri
->extra
&& ri
->extra
->suppress
) )
1473 struct bgp_info info
;
1474 struct attr dummy_attr
;
1475 struct attr_extra dummy_extra
;
1477 dummy_attr
.extra
= &dummy_extra
;
1481 /* don't confuse inbound and outbound setting */
1482 RESET_FLAG(attr
->rmap_change_flags
);
1485 * The route reflector is not allowed to modify the attributes
1486 * of the reflected IBGP routes unless explicitly allowed.
1488 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1489 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1491 bgp_attr_dup (&dummy_attr
, attr
);
1492 info
.attr
= &dummy_attr
;
1495 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1497 if (ri
->extra
&& ri
->extra
->suppress
)
1498 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1500 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1502 peer
->rmap_type
= 0;
1504 if (ret
== RMAP_DENYMATCH
)
1506 bgp_attr_flush (attr
);
1511 /* After route-map has been applied, we check to see if the nexthop to
1512 * be carried in the attribute (that is used for the announcement) can
1513 * be cleared off or not. We do this in all cases where we would be
1514 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1515 * the global nexthop here; the link-local nexthop would have been cleared
1516 * already, and if not, it is required by the update formation code.
1517 * Also see earlier comments in this function.
1520 * If route-map has performed some operation on the nexthop or the peer
1521 * configuration says to pass it unchanged, we cannot reset the nexthop
1522 * here, so only attempt to do it if these aren't true. Note that the
1523 * route-map handler itself might have cleared the nexthop, if for example,
1524 * it is configured as 'peer-address'.
1526 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1527 riattr
->rmap_change_flags
) &&
1529 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1531 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1532 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1533 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1536 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1537 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1538 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ?
1539 AF_INET6
: p
->family
), attr
);
1541 else if (peer
->sort
== BGP_PEER_EBGP
)
1543 /* Can also reset the nexthop if announcing to EBGP, but only if
1544 * no peer in the subgroup is on a shared subnet.
1545 * Note: 3rd party nexthop currently implemented for IPv4 only.
1547 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1549 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1553 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ? AF_INET6
: p
->family
), attr
);
1555 /* If IPv6/MP and nexthop does not have any override and happens to
1556 * be a link-local address, reset it so that we don't pass along the
1557 * source's link-local IPv6 address to recipients who may not be on
1558 * the same interface.
1560 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
))
1562 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1563 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1570 struct bgp_info_pair
1572 struct bgp_info
*old
;
1573 struct bgp_info
*new;
1577 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1578 struct bgp_maxpaths_cfg
*mpath_cfg
,
1579 struct bgp_info_pair
*result
)
1581 struct bgp_info
*new_select
;
1582 struct bgp_info
*old_select
;
1583 struct bgp_info
*ri
;
1584 struct bgp_info
*ri1
;
1585 struct bgp_info
*ri2
;
1586 struct bgp_info
*nextri
= NULL
;
1587 int paths_eq
, do_mpath
, debug
;
1588 struct list mp_list
;
1589 char pfx_buf
[PREFIX2STR_BUFFER
];
1590 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1592 bgp_mp_list_init (&mp_list
);
1593 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1595 debug
= bgp_debug_bestpath(&rn
->p
);
1598 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1600 /* bgp deterministic-med */
1602 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1605 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1606 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1607 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1609 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1611 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1613 if (BGP_INFO_HOLDDOWN (ri1
))
1615 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1616 if (ri1
->peer
->status
!= Established
)
1622 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1624 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1626 if (BGP_INFO_HOLDDOWN (ri2
))
1629 ri2
->peer
!= bgp
->peer_self
&&
1630 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1631 if (ri2
->peer
->status
!= Established
)
1634 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1635 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1638 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1639 mpath_cfg
, debug
, pfx_buf
))
1641 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1645 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1649 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1650 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1654 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1655 zlog_debug("%s: %s is the bestpath from AS %d",
1656 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1661 /* Check old selected route and new selected route. */
1664 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1666 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1669 if (BGP_INFO_HOLDDOWN (ri
))
1671 /* reap REMOVED routes, if needs be
1672 * selected route must stay for a while longer though
1674 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1675 && (ri
!= old_select
))
1676 bgp_info_reap (rn
, ri
);
1682 ri
->peer
!= bgp
->peer_self
&&
1683 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1684 if (ri
->peer
->status
!= Established
)
1687 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1688 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1690 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1694 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1696 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1702 /* Now that we know which path is the bestpath see if any of the other paths
1703 * qualify as multipaths
1708 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1710 sprintf (path_buf
, "NONE");
1711 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1713 old_select
? old_select
->peer
->host
: "NONE");
1716 if (do_mpath
&& new_select
)
1718 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1722 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1724 if (ri
== new_select
)
1727 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1729 bgp_mp_list_add (&mp_list
, ri
);
1733 if (BGP_INFO_HOLDDOWN (ri
))
1737 ri
->peer
!= bgp
->peer_self
&&
1738 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1739 if (ri
->peer
->status
!= Established
)
1742 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1745 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1750 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1755 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1757 bgp_mp_list_add (&mp_list
, ri
);
1762 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1763 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1764 bgp_mp_list_clear (&mp_list
);
1766 result
->old
= old_select
;
1767 result
->new = new_select
;
1773 * A new route/change in bestpath of an existing route. Evaluate the path
1774 * for advertisement to the subgroup.
1777 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1778 struct bgp_info
*selected
,
1779 struct bgp_node
*rn
,
1780 u_int32_t addpath_tx_id
)
1783 struct peer
*onlypeer
;
1785 struct attr_extra extra
;
1790 afi
= SUBGRP_AFI(subgrp
);
1791 safi
= SUBGRP_SAFI(subgrp
);
1792 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1793 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1795 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1796 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1797 PEER_STATUS_ORF_WAIT_REFRESH
))
1800 memset(&extra
, 0, sizeof(struct attr_extra
));
1801 /* It's initialized in bgp_announce_check() */
1802 attr
.extra
= &extra
;
1804 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1807 if (subgroup_announce_check(selected
, subgrp
, p
, &attr
))
1808 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1810 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1813 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1816 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1823 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1824 * This is called at the end of route processing.
1827 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1829 struct bgp_info
*ri
;
1831 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1833 if (BGP_INFO_HOLDDOWN (ri
))
1835 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1836 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1841 * Has the route changed from the RIB's perspective? This is invoked only
1842 * if the route selection returns the same best route as earlier - to
1843 * determine if we need to update zebra or not.
1846 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1848 struct bgp_info
*mpinfo
;
1850 /* If this is multipath, check all selected paths for any nexthop change or
1851 * attribute change. Some attribute changes (e.g., community) aren't of
1852 * relevance to the RIB, but we'll update zebra to ensure we handle the
1853 * case of BGP nexthop change. This is the behavior when the best path has
1854 * an attribute change anyway.
1856 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1857 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1860 /* If this is multipath, check all selected paths for any nexthop change */
1861 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1862 mpinfo
= bgp_info_mpath_next (mpinfo
))
1864 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1865 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1869 /* Nothing has changed from the RIB's perspective. */
1873 struct bgp_process_queue
1876 struct bgp_node
*rn
;
1881 static wq_item_status
1882 bgp_process_main (struct work_queue
*wq
, void *data
)
1884 struct bgp_process_queue
*pq
= data
;
1885 struct bgp
*bgp
= pq
->bgp
;
1886 struct bgp_node
*rn
= pq
->rn
;
1887 afi_t afi
= pq
->afi
;
1888 safi_t safi
= pq
->safi
;
1889 struct prefix
*p
= &rn
->p
;
1890 struct bgp_info
*new_select
;
1891 struct bgp_info
*old_select
;
1892 struct bgp_info_pair old_and_new
;
1894 /* Is it end of initial update? (after startup) */
1897 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1898 sizeof(bgp
->update_delay_zebra_resume_time
));
1900 bgp
->main_zebra_update_hold
= 0;
1901 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1902 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1904 bgp_zebra_announce_table(bgp
, afi
, safi
);
1906 bgp
->main_peers_update_hold
= 0;
1908 bgp_start_routeadv(bgp
);
1912 /* Best path selection. */
1913 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1914 old_select
= old_and_new
.old
;
1915 new_select
= old_and_new
.new;
1917 /* Nothing to do. */
1918 if (old_select
&& old_select
== new_select
&&
1919 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1920 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1921 !bgp
->addpath_tx_used
[afi
][safi
])
1923 if (bgp_zebra_has_route_changed (rn
, old_select
))
1926 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1927 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1929 bgp_zebra_announce (p
, old_select
, bgp
, afi
, safi
);
1931 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1932 bgp_zebra_clear_route_change_flags (rn
);
1933 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
1937 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
1938 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1940 /* bestpath has changed; bump version */
1941 if (old_select
|| new_select
)
1943 bgp_bump_version(rn
);
1945 if (!bgp
->t_rmap_def_originate_eval
)
1948 THREAD_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
1949 update_group_refresh_default_originate_route_map
,
1950 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
1955 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
1958 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
1959 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
1960 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1964 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
1965 if (old_select
!= new_select
) {
1967 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
1968 vnc_import_bgp_del_route(bgp
, p
, old_select
);
1971 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
1972 vnc_import_bgp_add_route(bgp
, p
, new_select
);
1978 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
1981 if ((safi
== SAFI_UNICAST
|| safi
== SAFI_MULTICAST
) &&
1982 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
1983 !bgp_option_check (BGP_OPT_NO_FIB
))
1986 && new_select
->type
== ZEBRA_ROUTE_BGP
1987 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
1988 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1989 bgp_zebra_announce (p
, new_select
, bgp
, afi
, safi
);
1992 /* Withdraw the route from the kernel. */
1994 && old_select
->type
== ZEBRA_ROUTE_BGP
1995 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
1996 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1997 bgp_zebra_withdraw (p
, old_select
, safi
);
2001 /* Clear any route change flags. */
2002 bgp_zebra_clear_route_change_flags (rn
);
2004 /* Reap old select bgp_info, if it has been removed */
2005 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2006 bgp_info_reap (rn
, old_select
);
2008 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2013 bgp_processq_del (struct work_queue
*wq
, void *data
)
2015 struct bgp_process_queue
*pq
= data
;
2016 struct bgp_table
*table
;
2018 bgp_unlock (pq
->bgp
);
2021 table
= bgp_node_table (pq
->rn
);
2022 bgp_unlock_node (pq
->rn
);
2023 bgp_table_unlock (table
);
2025 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2029 bgp_process_queue_init (void)
2031 if (!bm
->process_main_queue
)
2033 bm
->process_main_queue
2034 = work_queue_new (bm
->master
, "process_main_queue");
2036 if ( !bm
->process_main_queue
)
2038 zlog_err ("%s: Failed to allocate work queue", __func__
);
2043 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2044 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2045 bm
->process_main_queue
->spec
.max_retries
= 0;
2046 bm
->process_main_queue
->spec
.hold
= 50;
2047 /* Use a higher yield value of 50ms for main queue processing */
2048 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2052 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2054 struct bgp_process_queue
*pqnode
;
2056 /* already scheduled for processing? */
2057 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2060 if (bm
->process_main_queue
== NULL
)
2061 bgp_process_queue_init ();
2063 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2064 sizeof (struct bgp_process_queue
));
2068 /* all unlocked in bgp_processq_del */
2069 bgp_table_lock (bgp_node_table (rn
));
2070 pqnode
->rn
= bgp_lock_node (rn
);
2074 pqnode
->safi
= safi
;
2075 work_queue_add (bm
->process_main_queue
, pqnode
);
2076 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2081 bgp_add_eoiu_mark (struct bgp
*bgp
)
2083 struct bgp_process_queue
*pqnode
;
2085 if (bm
->process_main_queue
== NULL
)
2086 bgp_process_queue_init ();
2088 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2089 sizeof (struct bgp_process_queue
));
2096 work_queue_add (bm
->process_main_queue
, pqnode
);
2100 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2104 peer
= THREAD_ARG (thread
);
2105 peer
->t_pmax_restart
= NULL
;
2107 if (bgp_debug_neighbor_events(peer
))
2108 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2111 peer_clear (peer
, NULL
);
2117 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2118 safi_t safi
, int always
)
2123 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2126 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2128 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2132 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2133 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2134 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2135 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2137 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2140 /* Convert AFI, SAFI to values for packet. */
2141 pkt_afi
= afi_int2iana (afi
);
2142 pkt_safi
= safi_int2iana (safi
);
2146 ndata
[0] = (pkt_afi
>> 8);
2148 ndata
[2] = pkt_safi
;
2149 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2150 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2151 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2152 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2154 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2155 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2156 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2159 /* Dynamic peers will just close their connection. */
2160 if (peer_dynamic_neighbor (peer
))
2163 /* restart timer start */
2164 if (peer
->pmax_restart
[afi
][safi
])
2166 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2168 if (bgp_debug_neighbor_events(peer
))
2169 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2170 peer
->host
, peer
->v_pmax_restart
);
2172 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2173 peer
->v_pmax_restart
);
2179 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2181 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2183 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2187 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2188 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2189 peer
->pmax
[afi
][safi
]);
2190 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2193 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2197 /* Unconditionally remove the route from the RIB, without taking
2198 * damping into consideration (eg, because the session went down)
2201 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2202 afi_t afi
, safi_t safi
)
2204 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2206 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2207 bgp_info_delete (rn
, ri
); /* keep historical info */
2209 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2213 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2214 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2216 int status
= BGP_DAMP_NONE
;
2218 /* apply dampening, if result is suppressed, we'll be retaining
2219 * the bgp_info in the RIB for historical reference.
2221 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2222 && peer
->sort
== BGP_PEER_EBGP
)
2223 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2224 == BGP_DAMP_SUPPRESSED
)
2226 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2231 if (safi
== SAFI_MPLS_VPN
) {
2232 struct bgp_node
*prn
= NULL
;
2233 struct bgp_table
*table
= NULL
;
2235 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2237 table
= (struct bgp_table
*)(prn
->info
);
2239 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2246 bgp_unlock_node(prn
);
2248 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2249 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2251 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2252 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2256 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2259 static struct bgp_info
*
2260 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2261 struct bgp_node
*rn
)
2263 struct bgp_info
*new;
2265 /* Make new BGP info. */
2266 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2268 new->instance
= instance
;
2269 new->sub_type
= sub_type
;
2272 new->uptime
= bgp_clock ();
2274 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2279 bgp_info_addpath_rx_str(u_int32_t addpath_id
, char *buf
)
2282 sprintf(buf
, " with addpath ID %d", addpath_id
);
2286 /* Check if received nexthop is valid or not. */
2288 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2290 struct attr_extra
*attre
= attr
->extra
;
2293 /* Only validated for unicast and multicast currently. */
2294 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2297 /* If NEXT_HOP is present, validate it. */
2298 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2300 if (attr
->nexthop
.s_addr
== 0 ||
2301 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2302 bgp_nexthop_self (bgp
, attr
))
2306 /* If MP_NEXTHOP is present, validate it. */
2307 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2308 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2309 * it is not an IPv6 link-local address.
2311 if (attre
&& attre
->mp_nexthop_len
)
2313 switch (attre
->mp_nexthop_len
)
2315 case BGP_ATTR_NHLEN_IPV4
:
2316 case BGP_ATTR_NHLEN_VPNV4
:
2317 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2318 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2321 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2322 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2323 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2324 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2325 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2326 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2339 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2340 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2341 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2345 int aspath_loop_count
= 0;
2346 struct bgp_node
*rn
;
2348 struct attr new_attr
;
2349 struct attr_extra new_extra
;
2350 struct attr
*attr_new
;
2351 struct bgp_info
*ri
;
2352 struct bgp_info
*new;
2354 char buf
[SU_ADDRSTRLEN
];
2357 int do_loop_check
= 1;
2359 int vnc_implicit_withdraw
= 0;
2362 memset (&new_attr
, 0, sizeof(struct attr
));
2363 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2366 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2368 /* When peer's soft reconfiguration enabled. Record input packet in
2370 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2371 && peer
!= bgp
->peer_self
)
2372 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2374 /* Check previously received route. */
2375 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2376 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2377 ri
->addpath_rx_id
== addpath_id
)
2380 /* AS path local-as loop check. */
2381 if (peer
->change_local_as
)
2383 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2384 aspath_loop_count
= 1;
2386 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2388 reason
= "as-path contains our own AS;";
2393 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2394 * as-path is our ASN then we do not need to call aspath_loop_check
2396 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2397 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2400 /* AS path loop check. */
2403 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2404 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2405 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2407 reason
= "as-path contains our own AS;";
2412 /* Route reflector originator ID check. */
2413 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2414 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2416 reason
= "originator is us;";
2420 /* Route reflector cluster ID check. */
2421 if (bgp_cluster_filter (peer
, attr
))
2423 reason
= "reflected from the same cluster;";
2427 /* Apply incoming filter. */
2428 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2434 new_attr
.extra
= &new_extra
;
2435 bgp_attr_dup (&new_attr
, attr
);
2437 /* Apply incoming route-map.
2438 * NB: new_attr may now contain newly allocated values from route-map "set"
2439 * commands, so we need bgp_attr_flush in the error paths, until we intern
2440 * the attr (which takes over the memory references) */
2441 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2443 reason
= "route-map;";
2444 bgp_attr_flush (&new_attr
);
2448 /* next hop check. */
2449 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2451 reason
= "martian or self next-hop;";
2452 bgp_attr_flush (&new_attr
);
2456 attr_new
= bgp_attr_intern (&new_attr
);
2458 /* If the update is implicit withdraw. */
2461 ri
->uptime
= bgp_clock ();
2463 /* Same attribute comes in. */
2464 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2465 && attrhash_cmp (ri
->attr
, attr_new
))
2467 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2468 && peer
->sort
== BGP_PEER_EBGP
2469 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2471 if (bgp_debug_update(peer
, p
, NULL
, 1))
2473 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2474 zlog_debug ("%s rcvd %s/%d%s",
2476 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2477 p
->prefixlen
, buf2
);
2480 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2482 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2483 bgp_process (bgp
, rn
, afi
, safi
);
2486 else /* Duplicate - odd */
2488 if (bgp_debug_update(peer
, p
, NULL
, 1))
2490 if (!peer
->rcvd_attr_printed
)
2492 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2493 peer
->rcvd_attr_printed
= 1;
2496 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2497 zlog_debug ("%s rcvd %s/%d%s...duplicate ignored",
2499 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2500 p
->prefixlen
, buf2
);
2503 /* graceful restart STALE flag unset. */
2504 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2506 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2507 bgp_process (bgp
, rn
, afi
, safi
);
2511 bgp_unlock_node (rn
);
2512 bgp_attr_unintern (&attr_new
);
2517 /* Withdraw/Announce before we fully processed the withdraw */
2518 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2520 if (bgp_debug_update(peer
, p
, NULL
, 1))
2522 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2523 zlog_debug ("%s rcvd %s/%d%s, flapped quicker than processing",
2525 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2526 p
->prefixlen
, buf2
);
2528 bgp_info_restore (rn
, ri
);
2531 /* Received Logging. */
2532 if (bgp_debug_update(peer
, p
, NULL
, 1))
2534 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2535 zlog_debug ("%s rcvd %s/%d%s",
2537 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2538 p
->prefixlen
, buf2
);
2541 /* graceful restart STALE flag unset. */
2542 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2543 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2545 /* The attribute is changed. */
2546 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2548 /* implicit withdraw, decrement aggregate and pcount here.
2549 * only if update is accepted, they'll increment below.
2551 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2553 /* Update bgp route dampening information. */
2554 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2555 && peer
->sort
== BGP_PEER_EBGP
)
2557 /* This is implicit withdraw so we should update dampening
2559 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2560 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2563 if (safi
== SAFI_MPLS_VPN
) {
2564 struct bgp_node
*prn
= NULL
;
2565 struct bgp_table
*table
= NULL
;
2567 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2569 table
= (struct bgp_table
*)(prn
->info
);
2571 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2578 bgp_unlock_node(prn
);
2580 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2581 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2583 * Implicit withdraw case.
2585 ++vnc_implicit_withdraw
;
2586 vnc_import_bgp_del_route(bgp
, p
, ri
);
2587 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2592 /* Update to new attribute. */
2593 bgp_attr_unintern (&ri
->attr
);
2594 ri
->attr
= attr_new
;
2596 /* Update MPLS tag. */
2597 if (safi
== SAFI_MPLS_VPN
)
2598 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2601 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2603 if (vnc_implicit_withdraw
)
2606 * Add back the route with its new attributes (e.g., nexthop).
2607 * The route is still selected, until the route selection
2608 * queued by bgp_process actually runs. We have to make this
2609 * update to the VNC side immediately to avoid racing against
2610 * configuration changes (e.g., route-map changes) which
2611 * trigger re-importation of the entire RIB.
2613 vnc_import_bgp_add_route(bgp
, p
, ri
);
2614 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2619 /* Update bgp route dampening information. */
2620 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2621 && peer
->sort
== BGP_PEER_EBGP
)
2623 /* Now we do normal update dampening. */
2624 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2625 if (ret
== BGP_DAMP_SUPPRESSED
)
2627 bgp_unlock_node (rn
);
2632 /* Nexthop reachability check. */
2633 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2635 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2636 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2637 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2642 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2643 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2646 if (BGP_DEBUG(nht
, NHT
))
2648 char buf1
[INET6_ADDRSTRLEN
];
2649 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2650 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2652 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2656 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2659 if (safi
== SAFI_MPLS_VPN
)
2661 struct bgp_node
*prn
= NULL
;
2662 struct bgp_table
*table
= NULL
;
2664 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2667 table
= (struct bgp_table
*)(prn
->info
);
2669 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2676 bgp_unlock_node(prn
);
2680 /* Process change. */
2681 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2683 bgp_process (bgp
, rn
, afi
, safi
);
2684 bgp_unlock_node (rn
);
2687 if (SAFI_MPLS_VPN
== safi
)
2689 uint32_t label
= decode_label(tag
);
2691 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2694 if (SAFI_ENCAP
== safi
)
2696 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2702 } // End of implicit withdraw
2704 /* Received Logging. */
2705 if (bgp_debug_update(peer
, p
, NULL
, 1))
2707 if (!peer
->rcvd_attr_printed
)
2709 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2710 peer
->rcvd_attr_printed
= 1;
2713 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2714 zlog_debug ("%s rcvd %s/%d%s",
2716 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2717 p
->prefixlen
, buf2
);
2720 /* Make new BGP info. */
2721 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2723 /* Update MPLS tag. */
2724 if (safi
== SAFI_MPLS_VPN
)
2725 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2727 /* Nexthop reachability check. */
2728 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2730 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2731 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2732 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2737 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2738 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2741 if (BGP_DEBUG(nht
, NHT
))
2743 char buf1
[INET6_ADDRSTRLEN
];
2744 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2745 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2747 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2751 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2754 new->addpath_rx_id
= addpath_id
;
2756 /* Increment prefix */
2757 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2759 /* Register new BGP information. */
2760 bgp_info_add (rn
, new);
2762 /* route_node_get lock */
2763 bgp_unlock_node (rn
);
2766 if (safi
== SAFI_MPLS_VPN
)
2768 struct bgp_node
*prn
= NULL
;
2769 struct bgp_table
*table
= NULL
;
2771 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2774 table
= (struct bgp_table
*)(prn
->info
);
2776 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2783 bgp_unlock_node(prn
);
2787 /* If maximum prefix count is configured and current prefix
2789 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2792 /* Process change. */
2793 bgp_process (bgp
, rn
, afi
, safi
);
2796 if (SAFI_MPLS_VPN
== safi
)
2798 uint32_t label
= decode_label(tag
);
2800 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2803 if (SAFI_ENCAP
== safi
)
2805 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2812 /* This BGP update is filtered. Log the reason then update BGP
2815 if (bgp_debug_update(peer
, p
, NULL
, 1))
2817 if (!peer
->rcvd_attr_printed
)
2819 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2820 peer
->rcvd_attr_printed
= 1;
2823 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2824 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- DENIED due to: %s",
2826 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2827 p
->prefixlen
, buf2
, reason
);
2831 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2833 bgp_unlock_node (rn
);
2839 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2840 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2841 struct prefix_rd
*prd
, u_char
*tag
)
2844 char buf
[SU_ADDRSTRLEN
];
2846 struct bgp_node
*rn
;
2847 struct bgp_info
*ri
;
2850 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2852 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2859 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2861 /* If peer is soft reconfiguration enabled. Record input packet for
2862 * further calculation.
2864 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2865 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2866 * the iteration over all RS clients.
2867 * Since we need to remove the entry from adj_in anyway, do that first and
2868 * if there was no entry, we don't need to do anything more.
2870 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2871 && peer
!= bgp
->peer_self
)
2872 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2874 if (bgp_debug_update (peer
, p
, NULL
, 1))
2875 zlog_debug ("%s withdrawing route %s/%d "
2876 "not in adj-in", peer
->host
,
2877 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2879 bgp_unlock_node (rn
);
2883 /* Lookup withdrawn route. */
2884 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2885 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2886 ri
->addpath_rx_id
== addpath_id
)
2890 if (bgp_debug_update(peer
, p
, NULL
, 1))
2892 bgp_info_addpath_rx_str(addpath_id
, buf2
);
2893 zlog_debug ("%s rcvd UPDATE about %s/%d%s -- withdrawn",
2895 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2896 p
->prefixlen
, buf2
);
2899 /* Withdraw specified route from routing table. */
2900 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2901 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2902 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2903 zlog_debug ("%s Can't find the route %s/%d", peer
->host
,
2904 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
2907 /* Unlock bgp_node_get() lock. */
2908 bgp_unlock_node (rn
);
2914 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2916 struct update_subgroup
*subgrp
;
2917 subgrp
= peer_subgroup(peer
, afi
, safi
);
2918 subgroup_default_originate(subgrp
, withdraw
);
2923 * bgp_stop_announce_route_timer
2926 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2928 if (!paf
->t_announce_route
)
2931 THREAD_TIMER_OFF (paf
->t_announce_route
);
2935 * bgp_announce_route_timer_expired
2937 * Callback that is invoked when the route announcement timer for a
2941 bgp_announce_route_timer_expired (struct thread
*t
)
2943 struct peer_af
*paf
;
2946 paf
= THREAD_ARG (t
);
2949 assert (paf
->t_announce_route
);
2950 paf
->t_announce_route
= NULL
;
2952 if (peer
->status
!= Established
)
2955 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
2958 peer_af_announce_route (paf
, 1);
2963 * bgp_announce_route
2965 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
2968 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
2970 struct peer_af
*paf
;
2971 struct update_subgroup
*subgrp
;
2973 paf
= peer_af_find (peer
, afi
, safi
);
2976 subgrp
= PAF_SUBGRP(paf
);
2979 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
2980 * or a refresh has already been triggered.
2982 if (!subgrp
|| paf
->t_announce_route
)
2986 * Start a timer to stagger/delay the announce. This serves
2987 * two purposes - announcement can potentially be combined for
2988 * multiple peers and the announcement doesn't happen in the
2991 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
2992 bgp_announce_route_timer_expired
, paf
,
2993 (subgrp
->peer_count
== 1) ?
2994 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
2995 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
2999 * Announce routes from all AF tables to a peer.
3001 * This should ONLY be called when there is a need to refresh the
3002 * routes to the peer based on a policy change for this peer alone
3003 * or a route refresh request received from the peer.
3004 * The operation will result in splitting the peer from its existing
3005 * subgroups and putting it in new subgroups.
3008 bgp_announce_route_all (struct peer
*peer
)
3013 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3014 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3015 bgp_announce_route (peer
, afi
, safi
);
3019 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3020 struct bgp_table
*table
, struct prefix_rd
*prd
)
3023 struct bgp_node
*rn
;
3024 struct bgp_adj_in
*ain
;
3027 table
= peer
->bgp
->rib
[afi
][safi
];
3029 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3030 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3032 if (ain
->peer
== peer
)
3034 struct bgp_info
*ri
= rn
->info
;
3035 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3037 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3038 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3043 bgp_unlock_node (rn
);
3051 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3053 struct bgp_node
*rn
;
3054 struct bgp_table
*table
;
3056 if (peer
->status
!= Established
)
3059 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
))
3060 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3062 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3063 rn
= bgp_route_next (rn
))
3064 if ((table
= rn
->info
) != NULL
)
3066 struct prefix_rd prd
;
3067 prd
.family
= AF_UNSPEC
;
3069 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3071 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3076 struct bgp_clear_node_queue
3078 struct bgp_node
*rn
;
3081 static wq_item_status
3082 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3084 struct bgp_clear_node_queue
*cnq
= data
;
3085 struct bgp_node
*rn
= cnq
->rn
;
3086 struct peer
*peer
= wq
->spec
.data
;
3087 struct bgp_info
*ri
;
3088 afi_t afi
= bgp_node_table (rn
)->afi
;
3089 safi_t safi
= bgp_node_table (rn
)->safi
;
3091 assert (rn
&& peer
);
3093 /* It is possible that we have multiple paths for a prefix from a peer
3094 * if that peer is using AddPath.
3096 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3097 if (ri
->peer
== peer
)
3099 /* graceful restart STALE flag set. */
3100 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3101 && peer
->nsf
[afi
][safi
]
3102 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3103 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3104 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3106 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3112 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3114 struct bgp_clear_node_queue
*cnq
= data
;
3115 struct bgp_node
*rn
= cnq
->rn
;
3116 struct bgp_table
*table
= bgp_node_table (rn
);
3118 bgp_unlock_node (rn
);
3119 bgp_table_unlock (table
);
3120 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3124 bgp_clear_node_complete (struct work_queue
*wq
)
3126 struct peer
*peer
= wq
->spec
.data
;
3128 /* Tickle FSM to start moving again */
3129 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3131 peer_unlock (peer
); /* bgp_clear_route */
3135 bgp_clear_node_queue_init (struct peer
*peer
)
3137 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3139 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3140 #undef CLEAR_QUEUE_NAME_LEN
3142 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3144 zlog_err ("%s: Failed to allocate work queue", __func__
);
3147 peer
->clear_node_queue
->spec
.hold
= 10;
3148 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3149 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3150 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3151 peer
->clear_node_queue
->spec
.max_retries
= 0;
3153 /* we only 'lock' this peer reference when the queue is actually active */
3154 peer
->clear_node_queue
->spec
.data
= peer
;
3158 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3159 struct bgp_table
*table
)
3161 struct bgp_node
*rn
;
3162 int force
= bm
->process_main_queue
? 0 : 1;
3165 table
= peer
->bgp
->rib
[afi
][safi
];
3167 /* If still no table => afi/safi isn't configured at all or smth. */
3171 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3173 struct bgp_info
*ri
, *next
;
3174 struct bgp_adj_in
*ain
;
3175 struct bgp_adj_in
*ain_next
;
3177 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3178 * queued for every clearing peer, regardless of whether it is
3179 * relevant to the peer at hand.
3181 * Overview: There are 3 different indices which need to be
3182 * scrubbed, potentially, when a peer is removed:
3184 * 1 peer's routes visible via the RIB (ie accepted routes)
3185 * 2 peer's routes visible by the (optional) peer's adj-in index
3186 * 3 other routes visible by the peer's adj-out index
3188 * 3 there is no hurry in scrubbing, once the struct peer is
3189 * removed from bgp->peer, we could just GC such deleted peer's
3190 * adj-outs at our leisure.
3192 * 1 and 2 must be 'scrubbed' in some way, at least made
3193 * invisible via RIB index before peer session is allowed to be
3194 * brought back up. So one needs to know when such a 'search' is
3199 * - there'd be a single global queue or a single RIB walker
3200 * - rather than tracking which route_nodes still need to be
3201 * examined on a peer basis, we'd track which peers still
3204 * Given that our per-peer prefix-counts now should be reliable,
3205 * this may actually be achievable. It doesn't seem to be a huge
3206 * problem at this time,
3208 * It is possible that we have multiple paths for a prefix from a peer
3209 * if that peer is using AddPath.
3214 ain_next
= ain
->next
;
3216 if (ain
->peer
== peer
)
3218 bgp_adj_in_remove (rn
, ain
);
3219 bgp_unlock_node (rn
);
3225 for (ri
= rn
->info
; ri
; ri
= next
)
3228 if (ri
->peer
!= peer
)
3232 bgp_info_reap (rn
, ri
);
3235 struct bgp_clear_node_queue
*cnq
;
3237 /* both unlocked in bgp_clear_node_queue_del */
3238 bgp_table_lock (bgp_node_table (rn
));
3240 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3241 sizeof (struct bgp_clear_node_queue
));
3243 work_queue_add (peer
->clear_node_queue
, cnq
);
3252 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3254 struct bgp_node
*rn
;
3255 struct bgp_table
*table
;
3257 if (peer
->clear_node_queue
== NULL
)
3258 bgp_clear_node_queue_init (peer
);
3260 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3261 * Idle until it receives a Clearing_Completed event. This protects
3262 * against peers which flap faster than we can we clear, which could
3265 * a) race with routes from the new session being installed before
3266 * clear_route_node visits the node (to delete the route of that
3268 * b) resource exhaustion, clear_route_node likely leads to an entry
3269 * on the process_main queue. Fast-flapping could cause that queue
3273 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3274 * the unlock will happen upon work-queue completion; other wise, the
3275 * unlock happens at the end of this function.
3277 if (!peer
->clear_node_queue
->thread
)
3280 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
)
3281 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3283 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3284 rn
= bgp_route_next (rn
))
3285 if ((table
= rn
->info
) != NULL
)
3286 bgp_clear_route_table (peer
, afi
, safi
, table
);
3288 /* unlock if no nodes got added to the clear-node-queue. */
3289 if (!peer
->clear_node_queue
->thread
)
3295 bgp_clear_route_all (struct peer
*peer
)
3300 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3301 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3302 bgp_clear_route (peer
, afi
, safi
);
3305 rfapiProcessPeerDown(peer
);
3310 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3312 struct bgp_table
*table
;
3313 struct bgp_node
*rn
;
3314 struct bgp_adj_in
*ain
;
3315 struct bgp_adj_in
*ain_next
;
3317 table
= peer
->bgp
->rib
[afi
][safi
];
3319 /* It is possible that we have multiple paths for a prefix from a peer
3320 * if that peer is using AddPath.
3322 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3328 ain_next
= ain
->next
;
3330 if (ain
->peer
== peer
)
3332 bgp_adj_in_remove (rn
, ain
);
3333 bgp_unlock_node (rn
);
3342 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3344 struct bgp_node
*rn
;
3345 struct bgp_info
*ri
;
3346 struct bgp_table
*table
;
3348 if ( safi
== SAFI_MPLS_VPN
)
3350 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3352 struct bgp_node
*rm
;
3353 struct bgp_info
*ri
;
3355 /* look for neighbor in tables */
3356 if ((table
= rn
->info
) != NULL
)
3358 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3359 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3360 if (ri
->peer
== peer
)
3362 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3363 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3371 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3372 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3373 if (ri
->peer
== peer
)
3375 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3376 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3383 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3385 struct bgp_node
*rn
;
3386 struct bgp_info
*ri
;
3387 struct bgp_info
*next
;
3389 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3390 for (ri
= rn
->info
; ri
; ri
= next
)
3393 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3394 && ri
->type
== ZEBRA_ROUTE_BGP
3395 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3396 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3399 if (table
->owner
&& table
->owner
->bgp
)
3400 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3402 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3403 bgp_info_reap (rn
, ri
);
3408 /* Delete all kernel routes. */
3410 bgp_cleanup_routes (struct bgp
*bgp
)
3414 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3416 struct bgp_node
*rn
;
3418 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3421 * VPN and ENCAP tables are two-level (RD is top level)
3423 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
3424 rn
= bgp_route_next (rn
))
3428 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_MPLS_VPN
);
3429 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3431 bgp_unlock_node(rn
);
3435 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_ENCAP
]); rn
;
3436 rn
= bgp_route_next (rn
))
3440 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_ENCAP
);
3441 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3443 bgp_unlock_node(rn
);
3453 bgp_zclient_reset ();
3454 access_list_reset ();
3455 prefix_list_reset ();
3459 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3461 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3462 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3465 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3468 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3469 struct bgp_nlri
*packet
)
3478 int addpath_encoded
;
3479 u_int32_t addpath_id
;
3481 /* Check peer status. */
3482 if (peer
->status
!= Established
)
3486 lim
= pnt
+ packet
->length
;
3488 safi
= packet
->safi
;
3490 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3492 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3493 syntactic validity. If the field is syntactically incorrect,
3494 then the Error Subcode is set to Invalid Network Field. */
3495 for (; pnt
< lim
; pnt
+= psize
)
3497 /* Clear prefix structure. */
3498 memset (&p
, 0, sizeof (struct prefix
));
3500 if (addpath_encoded
)
3503 /* When packet overflow occurs return immediately. */
3504 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3507 addpath_id
= ntohl(*((uint32_t*) pnt
));
3508 pnt
+= BGP_ADDPATH_ID_LEN
;
3511 /* Fetch prefix length. */
3512 p
.prefixlen
= *pnt
++;
3513 /* afi/safi validity already verified by caller, bgp_update_receive */
3514 p
.family
= afi2family (afi
);
3516 /* Prefix length check. */
3517 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3519 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3520 peer
->host
, p
.prefixlen
, packet
->afi
);
3524 /* Packet size overflow check. */
3525 psize
= PSIZE (p
.prefixlen
);
3527 /* When packet overflow occur return immediately. */
3528 if (pnt
+ psize
> lim
)
3530 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3531 peer
->host
, p
.prefixlen
);
3535 /* Defensive coding, double-check the psize fits in a struct prefix */
3536 if (psize
> (ssize_t
) sizeof(p
.u
))
3538 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3539 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3543 /* Fetch prefix from NLRI packet. */
3544 memcpy (&p
.u
.prefix
, pnt
, psize
);
3546 /* Check address. */
3547 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3549 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3551 /* From RFC4271 Section 6.3:
3553 * If a prefix in the NLRI field is semantically incorrect
3554 * (e.g., an unexpected multicast IP address), an error SHOULD
3555 * be logged locally, and the prefix SHOULD be ignored.
3557 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3558 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3563 /* Check address. */
3564 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3566 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3570 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3571 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3575 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3579 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3580 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3586 /* Normal process. */
3588 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3589 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0);
3591 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3592 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
);
3594 /* Address family configuration mismatch or maximum-prefix count
3600 /* Packet length consistency check. */
3603 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3611 static struct bgp_static
*
3612 bgp_static_new (void)
3614 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3618 bgp_static_free (struct bgp_static
*bgp_static
)
3620 if (bgp_static
->rmap
.name
)
3621 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3622 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3626 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3627 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3629 struct bgp_node
*rn
;
3630 struct bgp_info
*ri
;
3631 struct bgp_info
*new;
3632 struct bgp_info info
;
3634 struct attr
*attr_new
;
3637 int vnc_implicit_withdraw
= 0;
3640 assert (bgp_static
);
3644 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3646 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3648 attr
.nexthop
= bgp_static
->igpnexthop
;
3649 attr
.med
= bgp_static
->igpmetric
;
3650 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3652 if (bgp_static
->atomic
)
3653 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3655 /* Apply route-map. */
3656 if (bgp_static
->rmap
.name
)
3658 struct attr attr_tmp
= attr
;
3659 info
.peer
= bgp
->peer_self
;
3660 info
.attr
= &attr_tmp
;
3662 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3664 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3666 bgp
->peer_self
->rmap_type
= 0;
3668 if (ret
== RMAP_DENYMATCH
)
3670 /* Free uninterned attribute. */
3671 bgp_attr_flush (&attr_tmp
);
3673 /* Unintern original. */
3674 aspath_unintern (&attr
.aspath
);
3675 bgp_attr_extra_free (&attr
);
3676 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3679 attr_new
= bgp_attr_intern (&attr_tmp
);
3682 attr_new
= bgp_attr_intern (&attr
);
3684 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3685 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3686 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3691 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3692 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3693 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3695 bgp_unlock_node (rn
);
3696 bgp_attr_unintern (&attr_new
);
3697 aspath_unintern (&attr
.aspath
);
3698 bgp_attr_extra_free (&attr
);
3703 /* The attribute is changed. */
3704 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3706 /* Rewrite BGP route information. */
3707 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3708 bgp_info_restore(rn
, ri
);
3710 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3712 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3714 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3717 * Implicit withdraw case.
3718 * We have to do this before ri is changed
3720 ++vnc_implicit_withdraw
;
3721 vnc_import_bgp_del_route(bgp
, p
, ri
);
3722 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3726 bgp_attr_unintern (&ri
->attr
);
3727 ri
->attr
= attr_new
;
3728 ri
->uptime
= bgp_clock ();
3730 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3732 if (vnc_implicit_withdraw
)
3734 vnc_import_bgp_add_route(bgp
, p
, ri
);
3735 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3740 /* Nexthop reachability check. */
3741 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3743 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3744 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3747 if (BGP_DEBUG(nht
, NHT
))
3749 char buf1
[INET6_ADDRSTRLEN
];
3750 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3752 zlog_debug("%s(%s): Route not in table, not advertising",
3753 __FUNCTION__
, buf1
);
3755 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3760 /* Delete the NHT structure if any, if we're toggling between
3761 * enabling/disabling import check. We deregister the route
3762 * from NHT to avoid overloading NHT and the process interaction
3764 bgp_unlink_nexthop(ri
);
3765 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3767 /* Process change. */
3768 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3769 bgp_process (bgp
, rn
, afi
, safi
);
3770 bgp_unlock_node (rn
);
3771 aspath_unintern (&attr
.aspath
);
3772 bgp_attr_extra_free (&attr
);
3777 /* Make new BGP info. */
3778 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3780 /* Nexthop reachability check. */
3781 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3783 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3784 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3787 if (BGP_DEBUG(nht
, NHT
))
3789 char buf1
[INET6_ADDRSTRLEN
];
3790 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3792 zlog_debug("%s(%s): Route not in table, not advertising",
3793 __FUNCTION__
, buf1
);
3795 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3800 /* Delete the NHT structure if any, if we're toggling between
3801 * enabling/disabling import check. We deregister the route
3802 * from NHT to avoid overloading NHT and the process interaction
3804 bgp_unlink_nexthop(new);
3806 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3809 /* Aggregate address increment. */
3810 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3812 /* Register new BGP information. */
3813 bgp_info_add (rn
, new);
3815 /* route_node_get lock */
3816 bgp_unlock_node (rn
);
3818 /* Process change. */
3819 bgp_process (bgp
, rn
, afi
, safi
);
3821 /* Unintern original. */
3822 aspath_unintern (&attr
.aspath
);
3823 bgp_attr_extra_free (&attr
);
3827 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3828 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3830 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3834 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3837 struct bgp_node
*rn
;
3838 struct bgp_info
*ri
;
3840 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3842 /* Check selected route and self inserted route. */
3843 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3844 if (ri
->peer
== bgp
->peer_self
3845 && ri
->type
== ZEBRA_ROUTE_BGP
3846 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3849 /* Withdraw static BGP route from routing table. */
3852 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3853 bgp_unlink_nexthop(ri
);
3854 bgp_info_delete (rn
, ri
);
3855 bgp_process (bgp
, rn
, afi
, safi
);
3858 /* Unlock bgp_node_lookup. */
3859 bgp_unlock_node (rn
);
3863 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3866 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3867 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3869 struct bgp_node
*rn
;
3870 struct bgp_info
*ri
;
3872 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3874 /* Check selected route and self inserted route. */
3875 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3876 if (ri
->peer
== bgp
->peer_self
3877 && ri
->type
== ZEBRA_ROUTE_BGP
3878 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3881 /* Withdraw static BGP route from routing table. */
3885 rfapiProcessWithdraw(
3894 1); /* Kill, since it is an administrative change */
3896 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3897 bgp_info_delete (rn
, ri
);
3898 bgp_process (bgp
, rn
, afi
, safi
);
3901 /* Unlock bgp_node_lookup. */
3902 bgp_unlock_node (rn
);
3906 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3907 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3909 struct bgp_node
*rn
;
3910 struct bgp_info
*new;
3911 struct attr
*attr_new
;
3912 struct attr attr
= { 0 };
3913 struct bgp_info
*ri
;
3915 u_int32_t label
= 0;
3918 assert (bgp_static
);
3920 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
3922 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3924 attr
.nexthop
= bgp_static
->igpnexthop
;
3925 attr
.med
= bgp_static
->igpmetric
;
3926 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3928 /* Apply route-map. */
3929 if (bgp_static
->rmap
.name
)
3931 struct attr attr_tmp
= attr
;
3932 struct bgp_info info
;
3935 info
.peer
= bgp
->peer_self
;
3936 info
.attr
= &attr_tmp
;
3938 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3940 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3942 bgp
->peer_self
->rmap_type
= 0;
3944 if (ret
== RMAP_DENYMATCH
)
3946 /* Free uninterned attribute. */
3947 bgp_attr_flush (&attr_tmp
);
3949 /* Unintern original. */
3950 aspath_unintern (&attr
.aspath
);
3951 bgp_attr_extra_free (&attr
);
3952 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
3957 attr_new
= bgp_attr_intern (&attr_tmp
);
3961 attr_new
= bgp_attr_intern (&attr
);
3964 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3965 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3966 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3971 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3972 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3974 bgp_unlock_node (rn
);
3975 bgp_attr_unintern (&attr_new
);
3976 aspath_unintern (&attr
.aspath
);
3977 bgp_attr_extra_free (&attr
);
3982 /* The attribute is changed. */
3983 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3985 /* Rewrite BGP route information. */
3986 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3987 bgp_info_restore(rn
, ri
);
3989 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3990 bgp_attr_unintern (&ri
->attr
);
3991 ri
->attr
= attr_new
;
3992 ri
->uptime
= bgp_clock ();
3995 label
= decode_label (ri
->extra
->tag
);
3998 /* Process change. */
3999 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4000 bgp_process (bgp
, rn
, afi
, safi
);
4002 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4003 ri
->attr
, afi
, safi
,
4004 ri
->type
, ri
->sub_type
, &label
);
4006 bgp_unlock_node (rn
);
4007 aspath_unintern (&attr
.aspath
);
4008 bgp_attr_extra_free (&attr
);
4014 /* Make new BGP info. */
4015 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4017 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4018 new->extra
= bgp_info_extra_new();
4019 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4021 label
= decode_label (bgp_static
->tag
);
4024 /* Aggregate address increment. */
4025 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4027 /* Register new BGP information. */
4028 bgp_info_add (rn
, new);
4030 /* route_node_get lock */
4031 bgp_unlock_node (rn
);
4033 /* Process change. */
4034 bgp_process (bgp
, rn
, afi
, safi
);
4037 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4038 new->attr
, afi
, safi
,
4039 new->type
, new->sub_type
, &label
);
4042 /* Unintern original. */
4043 aspath_unintern (&attr
.aspath
);
4044 bgp_attr_extra_free (&attr
);
4047 /* Configure static BGP network. When user don't run zebra, static
4048 route should be installed as valid. */
4050 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4051 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4053 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4056 struct bgp_static
*bgp_static
;
4057 struct bgp_node
*rn
;
4058 u_char need_update
= 0;
4060 /* Convert IP prefix string to struct prefix. */
4061 ret
= str2prefix (ip_str
, &p
);
4064 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4067 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4069 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4076 /* Set BGP static route configuration. */
4077 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4081 /* Configuration change. */
4082 bgp_static
= rn
->info
;
4084 /* Check previous routes are installed into BGP. */
4085 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4088 bgp_static
->backdoor
= backdoor
;
4092 if (bgp_static
->rmap
.name
)
4093 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4094 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4095 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4099 if (bgp_static
->rmap
.name
)
4100 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4101 bgp_static
->rmap
.name
= NULL
;
4102 bgp_static
->rmap
.map
= NULL
;
4103 bgp_static
->valid
= 0;
4105 bgp_unlock_node (rn
);
4109 /* New configuration. */
4110 bgp_static
= bgp_static_new ();
4111 bgp_static
->backdoor
= backdoor
;
4112 bgp_static
->valid
= 0;
4113 bgp_static
->igpmetric
= 0;
4114 bgp_static
->igpnexthop
.s_addr
= 0;
4118 if (bgp_static
->rmap
.name
)
4119 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4120 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4121 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4123 rn
->info
= bgp_static
;
4126 bgp_static
->valid
= 1;
4128 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4130 if (! bgp_static
->backdoor
)
4131 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4136 /* Configure static BGP network. */
4138 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4139 afi_t afi
, safi_t safi
)
4141 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4144 struct bgp_static
*bgp_static
;
4145 struct bgp_node
*rn
;
4147 /* Convert IP prefix string to struct prefix. */
4148 ret
= str2prefix (ip_str
, &p
);
4151 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4154 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4156 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4163 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4166 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4171 bgp_static
= rn
->info
;
4173 /* Update BGP RIB. */
4174 if (! bgp_static
->backdoor
)
4175 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4177 /* Clear configuration. */
4178 bgp_static_free (bgp_static
);
4180 bgp_unlock_node (rn
);
4181 bgp_unlock_node (rn
);
4187 bgp_static_add (struct bgp
*bgp
)
4191 struct bgp_node
*rn
;
4192 struct bgp_node
*rm
;
4193 struct bgp_table
*table
;
4194 struct bgp_static
*bgp_static
;
4196 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4197 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4198 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4199 if (rn
->info
!= NULL
)
4201 if (safi
== SAFI_MPLS_VPN
)
4205 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4207 bgp_static
= rn
->info
;
4208 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4213 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4218 /* Called from bgp_delete(). Delete all static routes from the BGP
4221 bgp_static_delete (struct bgp
*bgp
)
4225 struct bgp_node
*rn
;
4226 struct bgp_node
*rm
;
4227 struct bgp_table
*table
;
4228 struct bgp_static
*bgp_static
;
4230 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4231 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4232 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4233 if (rn
->info
!= NULL
)
4235 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4239 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4241 bgp_static
= rn
->info
;
4242 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4244 (struct prefix_rd
*)&rn
->p
,
4246 bgp_static_free (bgp_static
);
4248 bgp_unlock_node (rn
);
4253 bgp_static
= rn
->info
;
4254 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4255 bgp_static_free (bgp_static
);
4257 bgp_unlock_node (rn
);
4263 bgp_static_redo_import_check (struct bgp
*bgp
)
4267 struct bgp_node
*rn
;
4268 struct bgp_static
*bgp_static
;
4270 /* Use this flag to force reprocessing of the route */
4271 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4272 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4273 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4274 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4275 if (rn
->info
!= NULL
)
4277 bgp_static
= rn
->info
;
4278 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4280 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4284 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4286 struct bgp_table
*table
;
4287 struct bgp_node
*rn
;
4288 struct bgp_info
*ri
;
4290 table
= bgp
->rib
[afi
][safi
];
4291 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4293 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4295 if (ri
->peer
== bgp
->peer_self
&&
4296 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4297 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4298 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4299 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4301 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4302 bgp_unlink_nexthop(ri
);
4303 bgp_info_delete (rn
, ri
);
4304 bgp_process (bgp
, rn
, afi
, safi
);
4311 * Purge all networks and redistributed routes from routing table.
4312 * Invoked upon the instance going down.
4315 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4320 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4321 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4322 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4327 * Currently this is used to set static routes for VPN and ENCAP.
4328 * I think it can probably be factored with bgp_static_set.
4331 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4332 const char *rd_str
, const char *tag_str
,
4333 const char *rmap_str
)
4335 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4338 struct prefix_rd prd
;
4339 struct bgp_node
*prn
;
4340 struct bgp_node
*rn
;
4341 struct bgp_table
*table
;
4342 struct bgp_static
*bgp_static
;
4346 ret
= str2prefix (ip_str
, &p
);
4349 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4354 ret
= str2prefix_rd (rd_str
, &prd
);
4357 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4361 ret
= str2tag (tag_str
, tag
);
4364 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4367 if (p
.family
== AF_INET
)
4369 else if (p
.family
== AF_INET6
)
4373 vty_out (vty
, "%% Non Supported prefix%s", VTY_NEWLINE
);
4376 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4377 (struct prefix
*)&prd
);
4378 if (prn
->info
== NULL
)
4379 prn
->info
= bgp_table_init (afi
, safi
);
4381 bgp_unlock_node (prn
);
4384 rn
= bgp_node_get (table
, &p
);
4388 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4389 bgp_unlock_node (rn
);
4393 /* New configuration. */
4394 bgp_static
= bgp_static_new ();
4395 bgp_static
->backdoor
= 0;
4396 bgp_static
->valid
= 0;
4397 bgp_static
->igpmetric
= 0;
4398 bgp_static
->igpnexthop
.s_addr
= 0;
4399 memcpy(bgp_static
->tag
, tag
, 3);
4400 bgp_static
->prd
= prd
;
4404 if (bgp_static
->rmap
.name
)
4405 free (bgp_static
->rmap
.name
);
4406 bgp_static
->rmap
.name
= strdup (rmap_str
);
4407 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4409 rn
->info
= bgp_static
;
4411 bgp_static
->valid
= 1;
4412 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4418 /* Configure static BGP network. */
4420 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4421 const char *rd_str
, const char *tag_str
)
4423 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4426 struct prefix_rd prd
;
4427 struct bgp_node
*prn
;
4428 struct bgp_node
*rn
;
4429 struct bgp_table
*table
;
4430 struct bgp_static
*bgp_static
;
4433 /* Convert IP prefix string to struct prefix. */
4434 ret
= str2prefix (ip_str
, &p
);
4437 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4442 ret
= str2prefix_rd (rd_str
, &prd
);
4445 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4449 ret
= str2tag (tag_str
, tag
);
4452 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4456 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4457 (struct prefix
*)&prd
);
4458 if (prn
->info
== NULL
)
4459 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4461 bgp_unlock_node (prn
);
4464 rn
= bgp_node_lookup (table
, &p
);
4468 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4470 bgp_static
= rn
->info
;
4471 bgp_static_free (bgp_static
);
4473 bgp_unlock_node (rn
);
4474 bgp_unlock_node (rn
);
4477 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4483 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4484 const char *rmap_name
)
4486 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4487 struct bgp_rmap
*rmap
;
4489 rmap
= &bgp
->table_map
[afi
][safi
];
4493 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4494 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4495 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4500 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4505 bgp_zebra_announce_table(bgp
, afi
, safi
);
4511 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4512 const char *rmap_name
)
4514 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4515 struct bgp_rmap
*rmap
;
4517 rmap
= &bgp
->table_map
[afi
][safi
];
4519 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4523 bgp_zebra_announce_table(bgp
, afi
, safi
);
4529 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4530 safi_t safi
, int *write
)
4532 if (bgp
->table_map
[afi
][safi
].name
)
4534 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4535 vty_out (vty
, " table-map %s%s",
4536 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4542 DEFUN (bgp_table_map
,
4545 "BGP table to RIB route download filter\n"
4546 "Name of the route map\n")
4549 return bgp_table_map_set (vty
,
4550 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4552 DEFUN (no_bgp_table_map
,
4553 no_bgp_table_map_cmd
,
4554 "no table-map WORD",
4556 "BGP table to RIB route download filter\n"
4557 "Name of the route map\n")
4560 return bgp_table_map_unset (vty
,
4561 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4566 "network A.B.C.D/M",
4567 "Specify a network to announce via BGP\n"
4570 int idx_ipv4_prefixlen
= 1;
4571 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4572 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4575 DEFUN (bgp_network_route_map
,
4576 bgp_network_route_map_cmd
,
4577 "network A.B.C.D/M route-map WORD",
4578 "Specify a network to announce via BGP\n"
4580 "Route-map to modify the attributes\n"
4581 "Name of the route map\n")
4583 int idx_ipv4_prefixlen
= 1;
4585 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4586 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4589 DEFUN (bgp_network_backdoor
,
4590 bgp_network_backdoor_cmd
,
4591 "network A.B.C.D/M backdoor",
4592 "Specify a network to announce via BGP\n"
4594 "Specify a BGP backdoor route\n")
4596 int idx_ipv4_prefixlen
= 1;
4597 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4601 DEFUN (bgp_network_mask
,
4602 bgp_network_mask_cmd
,
4603 "network A.B.C.D mask A.B.C.D",
4604 "Specify a network to announce via BGP\n"
4612 char prefix_str
[BUFSIZ
];
4614 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4617 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4621 return bgp_static_set (vty
, prefix_str
,
4622 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4625 DEFUN (bgp_network_mask_route_map
,
4626 bgp_network_mask_route_map_cmd
,
4627 "network A.B.C.D mask A.B.C.D route-map WORD",
4628 "Specify a network to announce via BGP\n"
4632 "Route-map to modify the attributes\n"
4633 "Name of the route map\n")
4639 char prefix_str
[BUFSIZ
];
4641 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4644 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4648 return bgp_static_set (vty
, prefix_str
,
4649 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4652 DEFUN (bgp_network_mask_backdoor
,
4653 bgp_network_mask_backdoor_cmd
,
4654 "network A.B.C.D mask A.B.C.D backdoor",
4655 "Specify a network to announce via BGP\n"
4659 "Specify a BGP backdoor route\n")
4664 char prefix_str
[BUFSIZ
];
4666 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4669 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4673 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4677 DEFUN (bgp_network_mask_natural
,
4678 bgp_network_mask_natural_cmd
,
4680 "Specify a network to announce via BGP\n"
4685 char prefix_str
[BUFSIZ
];
4687 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4690 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4694 return bgp_static_set (vty
, prefix_str
,
4695 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4698 DEFUN (bgp_network_mask_natural_route_map
,
4699 bgp_network_mask_natural_route_map_cmd
,
4700 "network A.B.C.D route-map WORD",
4701 "Specify a network to announce via BGP\n"
4703 "Route-map to modify the attributes\n"
4704 "Name of the route map\n")
4709 char prefix_str
[BUFSIZ
];
4711 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4714 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4718 return bgp_static_set (vty
, prefix_str
,
4719 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4722 DEFUN (bgp_network_mask_natural_backdoor
,
4723 bgp_network_mask_natural_backdoor_cmd
,
4724 "network A.B.C.D backdoor",
4725 "Specify a network to announce via BGP\n"
4727 "Specify a BGP backdoor route\n")
4731 char prefix_str
[BUFSIZ
];
4733 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4736 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4740 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4744 DEFUN (no_bgp_network
,
4746 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4748 "Specify a network to announce via BGP\n"
4750 "Specify a BGP backdoor route\n"
4751 "Route-map to modify the attributes\n"
4752 "Name of the route map\n")
4754 int idx_ipv4_prefixlen
= 2;
4755 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4756 bgp_node_safi (vty
));
4759 DEFUN (no_bgp_network_mask
,
4760 no_bgp_network_mask_cmd
,
4761 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4763 "Specify a network to announce via BGP\n"
4767 "Specify a BGP backdoor route\n"
4768 "Route-map to modify the attributes\n"
4769 "Name of the route map\n")
4774 char prefix_str
[BUFSIZ
];
4776 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4779 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4783 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4784 bgp_node_safi (vty
));
4787 DEFUN (no_bgp_network_mask_natural
,
4788 no_bgp_network_mask_natural_cmd
,
4789 "no network A.B.C.D [<backdoor|route-map WORD>]",
4791 "Specify a network to announce via BGP\n"
4793 "Specify a BGP backdoor route\n"
4794 "Route-map to modify the attributes\n"
4795 "Name of the route map\n")
4799 char prefix_str
[BUFSIZ
];
4801 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4804 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4808 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4809 bgp_node_safi (vty
));
4812 DEFUN (ipv6_bgp_network
,
4813 ipv6_bgp_network_cmd
,
4814 "network X:X::X:X/M",
4815 "Specify a network to announce via BGP\n"
4818 int idx_ipv6_prefixlen
= 1;
4819 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4823 DEFUN (ipv6_bgp_network_route_map
,
4824 ipv6_bgp_network_route_map_cmd
,
4825 "network X:X::X:X/M route-map WORD",
4826 "Specify a network to announce via BGP\n"
4828 "Route-map to modify the attributes\n"
4829 "Name of the route map\n")
4831 int idx_ipv6_prefixlen
= 1;
4833 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4834 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4837 DEFUN (no_ipv6_bgp_network
,
4838 no_ipv6_bgp_network_cmd
,
4839 "no network X:X::X:X/M [route-map WORD]",
4841 "Specify a network to announce via BGP\n"
4843 "Route-map to modify the attributes\n"
4844 "Name of the route map\n")
4846 int idx_ipv6_prefixlen
= 2;
4847 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4850 /* Aggreagete address:
4852 advertise-map Set condition to advertise attribute
4853 as-set Generate AS set path information
4854 attribute-map Set attributes of aggregate
4855 route-map Set parameters of aggregate
4856 summary-only Filter more specific routes from updates
4857 suppress-map Conditionally filter more specific routes from updates
4860 struct bgp_aggregate
4862 /* Summary-only flag. */
4863 u_char summary_only
;
4865 /* AS set generation. */
4868 /* Route-map for aggregated route. */
4869 struct route_map
*map
;
4871 /* Suppress-count. */
4872 unsigned long count
;
4874 /* SAFI configuration. */
4878 static struct bgp_aggregate
*
4879 bgp_aggregate_new (void)
4881 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4885 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4887 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4890 /* Update an aggregate as routes are added/removed from the BGP table */
4892 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4893 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4894 struct bgp_aggregate
*aggregate
)
4896 struct bgp_table
*table
;
4897 struct bgp_node
*top
;
4898 struct bgp_node
*rn
;
4900 struct aspath
*aspath
= NULL
;
4901 struct aspath
*asmerge
= NULL
;
4902 struct community
*community
= NULL
;
4903 struct community
*commerge
= NULL
;
4904 #if defined(AGGREGATE_NEXTHOP_CHECK)
4905 struct in_addr nexthop
;
4908 struct bgp_info
*ri
;
4909 struct bgp_info
*new;
4911 unsigned long match
= 0;
4912 u_char atomic_aggregate
= 0;
4914 /* Record adding route's nexthop and med. */
4917 #if defined(AGGREGATE_NEXTHOP_CHECK)
4918 nexthop
= rinew
->attr
->nexthop
;
4919 med
= rinew
->attr
->med
;
4923 /* ORIGIN attribute: If at least one route among routes that are
4924 aggregated has ORIGIN with the value INCOMPLETE, then the
4925 aggregated route must have the ORIGIN attribute with the value
4926 INCOMPLETE. Otherwise, if at least one route among routes that
4927 are aggregated has ORIGIN with the value EGP, then the aggregated
4928 route must have the origin attribute with the value EGP. In all
4929 other case the value of the ORIGIN attribute of the aggregated
4930 route is INTERNAL. */
4931 origin
= BGP_ORIGIN_IGP
;
4933 table
= bgp
->rib
[afi
][safi
];
4935 top
= bgp_node_get (table
, p
);
4936 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
4937 if (rn
->p
.prefixlen
> p
->prefixlen
)
4941 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4943 if (BGP_INFO_HOLDDOWN (ri
))
4946 if (del
&& ri
== del
)
4949 if (! rinew
&& first
)
4951 #if defined(AGGREGATE_NEXTHOP_CHECK)
4952 nexthop
= ri
->attr
->nexthop
;
4953 med
= ri
->attr
->med
;
4958 #ifdef AGGREGATE_NEXTHOP_CHECK
4959 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
4960 || ri
->attr
->med
!= med
)
4963 aspath_free (aspath
);
4965 community_free (community
);
4966 bgp_unlock_node (rn
);
4967 bgp_unlock_node (top
);
4970 #endif /* AGGREGATE_NEXTHOP_CHECK */
4972 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
4973 atomic_aggregate
= 1;
4975 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
4977 if (aggregate
->summary_only
)
4979 (bgp_info_extra_get (ri
))->suppress
++;
4980 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4986 if (origin
< ri
->attr
->origin
)
4987 origin
= ri
->attr
->origin
;
4989 if (aggregate
->as_set
)
4993 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
4994 aspath_free (aspath
);
4998 aspath
= aspath_dup (ri
->attr
->aspath
);
5000 if (ri
->attr
->community
)
5004 commerge
= community_merge (community
,
5005 ri
->attr
->community
);
5006 community
= community_uniq_sort (commerge
);
5007 community_free (commerge
);
5010 community
= community_dup (ri
->attr
->community
);
5016 bgp_process (bgp
, rn
, afi
, safi
);
5018 bgp_unlock_node (top
);
5024 if (aggregate
->summary_only
)
5025 (bgp_info_extra_get (rinew
))->suppress
++;
5027 if (origin
< rinew
->attr
->origin
)
5028 origin
= rinew
->attr
->origin
;
5030 if (aggregate
->as_set
)
5034 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5035 aspath_free (aspath
);
5039 aspath
= aspath_dup (rinew
->attr
->aspath
);
5041 if (rinew
->attr
->community
)
5045 commerge
= community_merge (community
,
5046 rinew
->attr
->community
);
5047 community
= community_uniq_sort (commerge
);
5048 community_free (commerge
);
5051 community
= community_dup (rinew
->attr
->community
);
5056 if (aggregate
->count
> 0)
5058 rn
= bgp_node_get (table
, p
);
5059 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5060 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5062 atomic_aggregate
), rn
);
5063 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5065 bgp_info_add (rn
, new);
5066 bgp_unlock_node (rn
);
5067 bgp_process (bgp
, rn
, afi
, safi
);
5072 aspath_free (aspath
);
5074 community_free (community
);
5078 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5079 struct bgp_aggregate
*);
5082 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5083 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5085 struct bgp_node
*child
;
5086 struct bgp_node
*rn
;
5087 struct bgp_aggregate
*aggregate
;
5088 struct bgp_table
*table
;
5090 /* MPLS-VPN aggregation is not yet supported. */
5091 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5094 table
= bgp
->aggregate
[afi
][safi
];
5096 /* No aggregates configured. */
5097 if (bgp_table_top_nolock (table
) == NULL
)
5100 if (p
->prefixlen
== 0)
5103 if (BGP_INFO_HOLDDOWN (ri
))
5106 child
= bgp_node_get (table
, p
);
5108 /* Aggregate address configuration check. */
5109 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5110 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5112 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5113 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5115 bgp_unlock_node (child
);
5119 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5120 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5122 struct bgp_node
*child
;
5123 struct bgp_node
*rn
;
5124 struct bgp_aggregate
*aggregate
;
5125 struct bgp_table
*table
;
5127 /* MPLS-VPN aggregation is not yet supported. */
5128 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
5131 table
= bgp
->aggregate
[afi
][safi
];
5133 /* No aggregates configured. */
5134 if (bgp_table_top_nolock (table
) == NULL
)
5137 if (p
->prefixlen
== 0)
5140 child
= bgp_node_get (table
, p
);
5142 /* Aggregate address configuration check. */
5143 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5144 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5146 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5147 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5149 bgp_unlock_node (child
);
5152 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5154 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5155 struct bgp_aggregate
*aggregate
)
5157 struct bgp_table
*table
;
5158 struct bgp_node
*top
;
5159 struct bgp_node
*rn
;
5160 struct bgp_info
*new;
5161 struct bgp_info
*ri
;
5162 unsigned long match
;
5163 u_char origin
= BGP_ORIGIN_IGP
;
5164 struct aspath
*aspath
= NULL
;
5165 struct aspath
*asmerge
= NULL
;
5166 struct community
*community
= NULL
;
5167 struct community
*commerge
= NULL
;
5168 u_char atomic_aggregate
= 0;
5170 table
= bgp
->rib
[afi
][safi
];
5173 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5175 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5178 /* If routes exists below this node, generate aggregate routes. */
5179 top
= bgp_node_get (table
, p
);
5180 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5181 if (rn
->p
.prefixlen
> p
->prefixlen
)
5185 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5187 if (BGP_INFO_HOLDDOWN (ri
))
5190 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5191 atomic_aggregate
= 1;
5193 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5195 /* summary-only aggregate route suppress aggregated
5196 route announcement. */
5197 if (aggregate
->summary_only
)
5199 (bgp_info_extra_get (ri
))->suppress
++;
5200 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5204 /* If at least one route among routes that are aggregated has
5205 * ORIGIN with the value INCOMPLETE, then the aggregated route
5206 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5207 * Otherwise, if at least one route among routes that are
5208 * aggregated has ORIGIN with the value EGP, then the aggregated
5209 * route MUST have the ORIGIN attribute with the value EGP.
5211 if (origin
< ri
->attr
->origin
)
5212 origin
= ri
->attr
->origin
;
5214 /* as-set aggregate route generate origin, as path,
5215 community aggregation. */
5216 if (aggregate
->as_set
)
5220 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5221 aspath_free (aspath
);
5225 aspath
= aspath_dup (ri
->attr
->aspath
);
5227 if (ri
->attr
->community
)
5231 commerge
= community_merge (community
,
5232 ri
->attr
->community
);
5233 community
= community_uniq_sort (commerge
);
5234 community_free (commerge
);
5237 community
= community_dup (ri
->attr
->community
);
5244 /* If this node is suppressed, process the change. */
5246 bgp_process (bgp
, rn
, afi
, safi
);
5248 bgp_unlock_node (top
);
5250 /* Add aggregate route to BGP table. */
5251 if (aggregate
->count
)
5253 rn
= bgp_node_get (table
, p
);
5254 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5255 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5257 atomic_aggregate
), rn
);
5258 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5260 bgp_info_add (rn
, new);
5261 bgp_unlock_node (rn
);
5263 /* Process change. */
5264 bgp_process (bgp
, rn
, afi
, safi
);
5269 aspath_free (aspath
);
5271 community_free (community
);
5276 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5277 safi_t safi
, struct bgp_aggregate
*aggregate
)
5279 struct bgp_table
*table
;
5280 struct bgp_node
*top
;
5281 struct bgp_node
*rn
;
5282 struct bgp_info
*ri
;
5283 unsigned long match
;
5285 table
= bgp
->rib
[afi
][safi
];
5287 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5289 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5292 /* If routes exists below this node, generate aggregate routes. */
5293 top
= bgp_node_get (table
, p
);
5294 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5295 if (rn
->p
.prefixlen
> p
->prefixlen
)
5299 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5301 if (BGP_INFO_HOLDDOWN (ri
))
5304 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5306 if (aggregate
->summary_only
&& ri
->extra
)
5308 ri
->extra
->suppress
--;
5310 if (ri
->extra
->suppress
== 0)
5312 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5320 /* If this node was suppressed, process the change. */
5322 bgp_process (bgp
, rn
, afi
, safi
);
5324 bgp_unlock_node (top
);
5326 /* Delete aggregate route from BGP table. */
5327 rn
= bgp_node_get (table
, p
);
5329 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5330 if (ri
->peer
== bgp
->peer_self
5331 && ri
->type
== ZEBRA_ROUTE_BGP
5332 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5335 /* Withdraw static BGP route from routing table. */
5338 bgp_info_delete (rn
, ri
);
5339 bgp_process (bgp
, rn
, afi
, safi
);
5342 /* Unlock bgp_node_lookup. */
5343 bgp_unlock_node (rn
);
5346 /* Aggregate route attribute. */
5347 #define AGGREGATE_SUMMARY_ONLY 1
5348 #define AGGREGATE_AS_SET 1
5351 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5352 afi_t afi
, safi_t safi
)
5354 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5357 struct bgp_node
*rn
;
5358 struct bgp_aggregate
*aggregate
;
5360 /* Convert string to prefix structure. */
5361 ret
= str2prefix (prefix_str
, &p
);
5364 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5369 /* Old configuration check. */
5370 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5373 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5378 aggregate
= rn
->info
;
5379 if (aggregate
->safi
& SAFI_UNICAST
)
5380 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5381 if (aggregate
->safi
& SAFI_MULTICAST
)
5382 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5384 /* Unlock aggregate address configuration. */
5386 bgp_aggregate_free (aggregate
);
5387 bgp_unlock_node (rn
);
5388 bgp_unlock_node (rn
);
5394 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5395 afi_t afi
, safi_t safi
,
5396 u_char summary_only
, u_char as_set
)
5398 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5401 struct bgp_node
*rn
;
5402 struct bgp_aggregate
*aggregate
;
5404 /* Convert string to prefix structure. */
5405 ret
= str2prefix (prefix_str
, &p
);
5408 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5413 /* Old configuration check. */
5414 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5418 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5419 /* try to remove the old entry */
5420 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5423 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5424 bgp_unlock_node (rn
);
5429 /* Make aggregate address structure. */
5430 aggregate
= bgp_aggregate_new ();
5431 aggregate
->summary_only
= summary_only
;
5432 aggregate
->as_set
= as_set
;
5433 aggregate
->safi
= safi
;
5434 rn
->info
= aggregate
;
5436 /* Aggregate address insert into BGP routing table. */
5437 if (safi
& SAFI_UNICAST
)
5438 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5439 if (safi
& SAFI_MULTICAST
)
5440 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5445 DEFUN (aggregate_address
,
5446 aggregate_address_cmd
,
5447 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5448 "Configure BGP aggregate entries\n"
5449 "Aggregate prefix\n"
5450 "Generate AS set path information\n"
5451 "Filter more specific routes from updates\n"
5452 "Filter more specific routes from updates\n"
5453 "Generate AS set path information\n")
5456 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5457 char *prefix
= argv
[idx
]->arg
;
5458 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5460 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5462 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5465 DEFUN (aggregate_address_mask
,
5466 aggregate_address_mask_cmd
,
5467 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5468 "Configure BGP aggregate entries\n"
5469 "Aggregate address\n"
5471 "Generate AS set path information\n"
5472 "Filter more specific routes from updates\n"
5473 "Filter more specific routes from updates\n"
5474 "Generate AS set path information\n")
5477 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5478 char *prefix
= argv
[idx
++]->arg
;
5479 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5480 char *mask
= argv
[idx
]->arg
;
5481 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5483 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5485 char prefix_str
[BUFSIZ
];
5486 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5490 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5494 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5497 DEFUN (no_aggregate_address
,
5498 no_aggregate_address_cmd
,
5499 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5501 "Configure BGP aggregate entries\n"
5502 "Aggregate prefix\n"
5503 "Generate AS set path information\n"
5504 "Filter more specific routes from updates\n"
5505 "Filter more specific routes from updates\n"
5506 "Generate AS set path information\n")
5509 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5510 char *prefix
= argv
[idx
]->arg
;
5511 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5514 DEFUN (no_aggregate_address_mask
,
5515 no_aggregate_address_mask_cmd
,
5516 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5518 "Configure BGP aggregate entries\n"
5519 "Aggregate address\n"
5521 "Generate AS set path information\n"
5522 "Filter more specific routes from updates\n"
5523 "Filter more specific routes from updates\n"
5524 "Generate AS set path information\n")
5527 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5528 char *prefix
= argv
[idx
++]->arg
;
5529 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5530 char *mask
= argv
[idx
]->arg
;
5532 char prefix_str
[BUFSIZ
];
5533 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5537 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5541 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5544 DEFUN (ipv6_aggregate_address
,
5545 ipv6_aggregate_address_cmd
,
5546 "aggregate-address X:X::X:X/M [summary-only]",
5547 "Configure BGP aggregate entries\n"
5548 "Aggregate prefix\n"
5549 "Filter more specific routes from updates\n")
5552 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5553 char *prefix
= argv
[idx
]->arg
;
5554 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5555 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5558 DEFUN (no_ipv6_aggregate_address
,
5559 no_ipv6_aggregate_address_cmd
,
5560 "no aggregate-address X:X::X:X/M [summary-only]",
5562 "Configure BGP aggregate entries\n"
5563 "Aggregate prefix\n"
5564 "Filter more specific routes from updates\n")
5567 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5568 char *prefix
= argv
[idx
]->arg
;
5569 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5572 /* Redistribute route treatment. */
5574 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5575 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5576 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5578 struct bgp_info
*new;
5579 struct bgp_info
*bi
;
5580 struct bgp_info info
;
5581 struct bgp_node
*bn
;
5583 struct attr
*new_attr
;
5586 struct bgp_redist
*red
;
5588 /* Make default attribute. */
5589 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5591 attr
.nexthop
= *nexthop
;
5592 attr
.nh_ifindex
= ifindex
;
5596 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5597 extra
->mp_nexthop_global
= *nexthop6
;
5598 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5602 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5603 attr
.extra
->tag
= tag
;
5605 afi
= family2afi (p
->family
);
5607 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5610 struct attr attr_new
;
5611 struct attr_extra extra_new
;
5613 /* Copy attribute for modification. */
5614 attr_new
.extra
= &extra_new
;
5615 bgp_attr_dup (&attr_new
, &attr
);
5617 if (red
->redist_metric_flag
)
5618 attr_new
.med
= red
->redist_metric
;
5620 /* Apply route-map. */
5623 info
.peer
= bgp
->peer_self
;
5624 info
.attr
= &attr_new
;
5626 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5628 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5630 bgp
->peer_self
->rmap_type
= 0;
5632 if (ret
== RMAP_DENYMATCH
)
5634 /* Free uninterned attribute. */
5635 bgp_attr_flush (&attr_new
);
5637 /* Unintern original. */
5638 aspath_unintern (&attr
.aspath
);
5639 bgp_attr_extra_free (&attr
);
5640 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5645 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5646 afi
, SAFI_UNICAST
, p
, NULL
);
5648 new_attr
= bgp_attr_intern (&attr_new
);
5650 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5651 if (bi
->peer
== bgp
->peer_self
5652 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5657 /* Ensure the (source route) type is updated. */
5659 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5660 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5662 bgp_attr_unintern (&new_attr
);
5663 aspath_unintern (&attr
.aspath
);
5664 bgp_attr_extra_free (&attr
);
5665 bgp_unlock_node (bn
);
5670 /* The attribute is changed. */
5671 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5673 /* Rewrite BGP route information. */
5674 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5675 bgp_info_restore(bn
, bi
);
5677 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5678 bgp_attr_unintern (&bi
->attr
);
5679 bi
->attr
= new_attr
;
5680 bi
->uptime
= bgp_clock ();
5682 /* Process change. */
5683 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5684 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5685 bgp_unlock_node (bn
);
5686 aspath_unintern (&attr
.aspath
);
5687 bgp_attr_extra_free (&attr
);
5692 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5694 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5696 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5697 bgp_info_add (bn
, new);
5698 bgp_unlock_node (bn
);
5699 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5702 /* Unintern original. */
5703 aspath_unintern (&attr
.aspath
);
5704 bgp_attr_extra_free (&attr
);
5708 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5711 struct bgp_node
*rn
;
5712 struct bgp_info
*ri
;
5713 struct bgp_redist
*red
;
5715 afi
= family2afi (p
->family
);
5717 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5720 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5722 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5723 if (ri
->peer
== bgp
->peer_self
5724 && ri
->type
== type
)
5729 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5730 bgp_info_delete (rn
, ri
);
5731 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5733 bgp_unlock_node (rn
);
5737 /* Withdraw specified route type's route. */
5739 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5741 struct bgp_node
*rn
;
5742 struct bgp_info
*ri
;
5743 struct bgp_table
*table
;
5745 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5747 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5749 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5750 if (ri
->peer
== bgp
->peer_self
5752 && ri
->instance
== instance
)
5757 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5758 bgp_info_delete (rn
, ri
);
5759 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5764 /* Static function to display route. */
5766 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5769 u_int32_t destination
;
5772 if (p
->family
== AF_INET
)
5774 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5775 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5777 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5778 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5779 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5780 || p
->u
.prefix4
.s_addr
== 0)
5782 /* When mask is natural, mask is not displayed. */
5785 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5788 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5793 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5795 vty_out (vty
, "%*s", len
, " ");
5798 enum bgp_display_type
5803 /* Print the short form route status for a bgp_info */
5805 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5806 json_object
*json_path
)
5811 /* Route status display. */
5812 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5813 json_object_boolean_true_add(json_path
, "removed");
5815 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5816 json_object_boolean_true_add(json_path
, "stale");
5818 if (binfo
->extra
&& binfo
->extra
->suppress
)
5819 json_object_boolean_true_add(json_path
, "suppressed");
5821 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5822 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5823 json_object_boolean_true_add(json_path
, "valid");
5826 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5827 json_object_boolean_true_add(json_path
, "history");
5829 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5830 json_object_boolean_true_add(json_path
, "damped");
5832 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5833 json_object_boolean_true_add(json_path
, "bestpath");
5835 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5836 json_object_boolean_true_add(json_path
, "multipath");
5838 /* Internal route. */
5839 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5840 json_object_string_add(json_path
, "pathFrom", "internal");
5842 json_object_string_add(json_path
, "pathFrom", "external");
5847 /* Route status display. */
5848 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5850 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5852 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5854 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5855 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5861 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5863 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5865 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5867 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5872 /* Internal route. */
5874 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5880 /* called from terminal list command */
5882 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5883 struct bgp_info
*binfo
, int display
, safi_t safi
,
5884 json_object
*json_paths
)
5887 json_object
*json_path
= NULL
;
5888 json_object
*json_nexthops
= NULL
;
5889 json_object
*json_nexthop_global
= NULL
;
5890 json_object
*json_nexthop_ll
= NULL
;
5893 json_path
= json_object_new_object();
5895 /* short status lead text */
5896 route_vty_short_status_out (vty
, binfo
, json_path
);
5900 /* print prefix and mask */
5902 route_vty_out_route (p
, vty
);
5904 vty_out (vty
, "%*s", 17, " ");
5907 /* Print attribute */
5912 * For ENCAP routes, nexthop address family is not
5913 * neccessarily the same as the prefix address family.
5914 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
5916 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
))
5921 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
5926 vty_out (vty
, "%s", inet_ntop(af
,
5927 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
5930 vty_out (vty
, "%s", inet_ntop(af
,
5931 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
5942 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5946 json_nexthop_global
= json_object_new_object();
5948 if (safi
== SAFI_MPLS_VPN
)
5949 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5951 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
5953 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
5954 json_object_boolean_true_add(json_nexthop_global
, "used");
5958 if (safi
== SAFI_MPLS_VPN
)
5959 vty_out (vty
, "%-16s",
5960 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
5962 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
5967 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
5974 json_nexthop_global
= json_object_new_object();
5975 json_object_string_add(json_nexthop_global
, "ip",
5976 inet_ntop (AF_INET6
,
5977 &attr
->extra
->mp_nexthop_global
,
5979 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
5980 json_object_string_add(json_nexthop_global
, "scope", "global");
5982 /* We display both LL & GL if both have been received */
5983 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
5985 json_nexthop_ll
= json_object_new_object();
5986 json_object_string_add(json_nexthop_ll
, "ip",
5987 inet_ntop (AF_INET6
,
5988 &attr
->extra
->mp_nexthop_local
,
5990 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
5991 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
5993 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
5994 &attr
->extra
->mp_nexthop_local
) != 0) &&
5995 !attr
->extra
->mp_nexthop_prefer_global
)
5996 json_object_boolean_true_add(json_nexthop_ll
, "used");
5998 json_object_boolean_true_add(json_nexthop_global
, "used");
6001 json_object_boolean_true_add(json_nexthop_global
, "used");
6005 /* Display LL if LL/Global both in table unless prefer-global is set */
6006 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6007 !attr
->extra
->mp_nexthop_prefer_global
) ||
6008 (binfo
->peer
->conf_if
))
6010 if (binfo
->peer
->conf_if
)
6012 len
= vty_out (vty
, "%s",
6013 binfo
->peer
->conf_if
);
6014 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6017 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6019 vty_out (vty
, "%*s", len
, " ");
6023 len
= vty_out (vty
, "%s",
6024 inet_ntop (AF_INET6
,
6025 &attr
->extra
->mp_nexthop_local
,
6030 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6032 vty_out (vty
, "%*s", len
, " ");
6037 len
= vty_out (vty
, "%s",
6038 inet_ntop (AF_INET6
,
6039 &attr
->extra
->mp_nexthop_global
,
6044 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6046 vty_out (vty
, "%*s", len
, " ");
6052 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6054 json_object_int_add(json_path
, "med", attr
->med
);
6056 vty_out (vty
, "%10u", attr
->med
);
6062 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6064 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6066 vty_out (vty
, "%7u", attr
->local_pref
);
6074 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6076 json_object_int_add(json_path
, "weight", 0);
6079 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6083 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6090 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6092 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6097 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6099 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6104 json_object_string_add(json_path
, "alert", "No attributes");
6106 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6111 if (json_nexthop_global
|| json_nexthop_ll
)
6113 json_nexthops
= json_object_new_array();
6115 if (json_nexthop_global
)
6116 json_object_array_add(json_nexthops
, json_nexthop_global
);
6118 if (json_nexthop_ll
)
6119 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6121 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6124 json_object_array_add(json_paths
, json_path
);
6128 vty_out (vty
, "%s", VTY_NEWLINE
);
6130 /* prints an additional line, indented, with VNC info, if present */
6131 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6132 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6137 /* called from terminal list command */
6139 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6140 u_char use_json
, json_object
*json_ar
)
6142 json_object
*json_status
= NULL
;
6143 json_object
*json_net
= NULL
;
6145 /* Route status display. */
6148 json_status
= json_object_new_object();
6149 json_net
= json_object_new_object();
6158 /* print prefix and mask */
6160 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6162 route_vty_out_route (p
, vty
);
6164 /* Print attribute */
6169 if (p
->family
== AF_INET
&&
6170 (safi
== SAFI_MPLS_VPN
||
6171 safi
== SAFI_ENCAP
||
6172 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6174 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6175 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6177 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6179 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6183 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6187 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6188 json_object_int_add(json_net
, "metric", attr
->med
);
6190 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6191 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6194 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6196 json_object_int_add(json_net
, "weight", 0);
6200 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6203 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6207 if (p
->family
== AF_INET
&&
6208 (safi
== SAFI_MPLS_VPN
||
6209 safi
== SAFI_ENCAP
||
6210 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6212 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6213 vty_out (vty
, "%-16s",
6214 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6216 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6218 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6223 assert (attr
->extra
);
6225 len
= vty_out (vty
, "%s",
6226 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6230 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6232 vty_out (vty
, "%*s", len
, " ");
6234 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6235 vty_out (vty
, "%10u", attr
->med
);
6239 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6240 vty_out (vty
, "%7u", attr
->local_pref
);
6244 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6248 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6251 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6256 json_object_boolean_true_add(json_status
, "*");
6257 json_object_boolean_true_add(json_status
, ">");
6258 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6259 char buf_cut
[BUFSIZ
];
6260 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6263 vty_out (vty
, "%s", VTY_NEWLINE
);
6267 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6268 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6270 json_object
*json_out
= NULL
;
6272 u_int32_t label
= 0;
6278 json_out
= json_object_new_object();
6280 /* short status lead text */
6281 route_vty_short_status_out (vty
, binfo
, json_out
);
6283 /* print prefix and mask */
6287 route_vty_out_route (p
, vty
);
6289 vty_out (vty
, "%*s", 17, " ");
6292 /* Print attribute */
6296 if (p
->family
== AF_INET
6297 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6299 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6302 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6304 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6309 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6311 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6314 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6316 assert (attr
->extra
);
6320 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6323 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6324 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6327 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6330 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6334 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6336 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6338 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6339 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6342 vty_out (vty
, "%s(%s)",
6343 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6345 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6352 label
= decode_label (binfo
->extra
->tag
);
6357 json_object_int_add(json_out
, "notag", label
);
6358 json_object_array_add(json
, json_out
);
6362 vty_out (vty
, "notag/%d", label
);
6363 vty_out (vty
, "%s", VTY_NEWLINE
);
6367 /* dampening route */
6369 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6370 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6374 char timebuf
[BGP_UPTIME_LEN
];
6376 /* short status lead text */
6377 route_vty_short_status_out (vty
, binfo
, json
);
6379 /* print prefix and mask */
6383 route_vty_out_route (p
, vty
);
6385 vty_out (vty
, "%*s", 17, " ");
6388 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6393 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6398 json_object_int_add(json
, "peerHost", len
);
6400 vty_out (vty
, "%*s", len
, " ");
6404 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6406 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6408 /* Print attribute */
6416 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6418 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6423 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6425 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6428 vty_out (vty
, "%s", VTY_NEWLINE
);
6433 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6434 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6437 struct bgp_damp_info
*bdi
;
6438 char timebuf
[BGP_UPTIME_LEN
];
6444 bdi
= binfo
->extra
->damp_info
;
6446 /* short status lead text */
6447 route_vty_short_status_out (vty
, binfo
, json
);
6449 /* print prefix and mask */
6453 route_vty_out_route (p
, vty
);
6455 vty_out (vty
, "%*s", 17, " ");
6458 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6463 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6468 json_object_int_add(json
, "peerHost", len
);
6470 vty_out (vty
, "%*s", len
, " ");
6473 len
= vty_out (vty
, "%d", bdi
->flap
);
6483 json_object_int_add(json
, "bdiFlap", len
);
6485 vty_out (vty
, "%*s", len
, " ");
6489 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6491 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6492 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6494 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6495 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6498 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6500 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6505 vty_out (vty
, "%*s ", 8, " ");
6508 /* Print attribute */
6516 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6518 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6523 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6525 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6528 vty_out (vty
, "%s", VTY_NEWLINE
);
6532 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6533 const char *header
, json_object
*json_adv_to
)
6535 char buf1
[INET6_ADDRSTRLEN
];
6536 json_object
*json_peer
= NULL
;
6540 /* 'advertised-to' is a dictionary of peers we have advertised this
6541 * prefix too. The key is the peer's IP or swpX, the value is the
6542 * hostname if we know it and "" if not.
6544 json_peer
= json_object_new_object();
6547 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6550 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6552 json_object_object_add(json_adv_to
,
6553 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6560 vty_out (vty
, "%s", header
);
6564 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6567 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6569 vty_out (vty
, " %s(%s)", peer
->hostname
,
6570 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6575 vty_out (vty
, " %s", peer
->conf_if
);
6577 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6583 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6584 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6585 json_object
*json_paths
)
6587 char buf
[INET6_ADDRSTRLEN
];
6590 int sockunion_vty_out (struct vty
*, union sockunion
*);
6592 json_object
*json_bestpath
= NULL
;
6593 json_object
*json_cluster_list
= NULL
;
6594 json_object
*json_cluster_list_list
= NULL
;
6595 json_object
*json_ext_community
= NULL
;
6596 json_object
*json_last_update
= NULL
;
6597 json_object
*json_nexthop_global
= NULL
;
6598 json_object
*json_nexthop_ll
= NULL
;
6599 json_object
*json_nexthops
= NULL
;
6600 json_object
*json_path
= NULL
;
6601 json_object
*json_peer
= NULL
;
6602 json_object
*json_string
= NULL
;
6603 json_object
*json_adv_to
= NULL
;
6605 struct listnode
*node
, *nnode
;
6607 int addpath_capable
;
6609 unsigned int first_as
;
6613 json_path
= json_object_new_object();
6614 json_peer
= json_object_new_object();
6615 json_nexthop_global
= json_object_new_object();
6622 /* Line1 display AS-path, Aggregator */
6627 json_object_lock(attr
->aspath
->json
);
6628 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6632 if (attr
->aspath
->segments
)
6633 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6635 vty_out (vty
, " Local");
6639 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6642 json_object_boolean_true_add(json_path
, "removed");
6644 vty_out (vty
, ", (removed)");
6647 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6650 json_object_boolean_true_add(json_path
, "stale");
6652 vty_out (vty
, ", (stale)");
6655 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6659 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6660 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6664 vty_out (vty
, ", (aggregated by %u %s)",
6665 attr
->extra
->aggregator_as
,
6666 inet_ntoa (attr
->extra
->aggregator_addr
));
6670 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6673 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6675 vty_out (vty
, ", (Received from a RR-client)");
6678 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6681 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6683 vty_out (vty
, ", (Received from a RS-client)");
6686 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6689 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6691 vty_out (vty
, ", (history entry)");
6693 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6696 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6698 vty_out (vty
, ", (suppressed due to dampening)");
6702 vty_out (vty
, "%s", VTY_NEWLINE
);
6704 /* Line2 display Next-hop, Neighbor, Router-id */
6705 /* Display the nexthop */
6706 if (p
->family
== AF_INET
&&
6707 (safi
== SAFI_MPLS_VPN
||
6708 safi
== SAFI_ENCAP
||
6709 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6711 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
6714 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6716 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6721 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6723 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6727 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6731 assert (attr
->extra
);
6734 json_object_string_add(json_nexthop_global
, "ip",
6735 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6736 buf
, INET6_ADDRSTRLEN
));
6737 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6738 json_object_string_add(json_nexthop_global
, "scope", "global");
6742 vty_out (vty
, " %s",
6743 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6744 buf
, INET6_ADDRSTRLEN
));
6748 /* Display the IGP cost or 'inaccessible' */
6749 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6752 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6754 vty_out (vty
, " (inaccessible)");
6758 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6761 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6763 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6766 /* IGP cost is 0, display this only for json */
6770 json_object_int_add(json_nexthop_global
, "metric", 0);
6774 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6777 /* Display peer "from" output */
6778 /* This path was originated locally */
6779 if (binfo
->peer
== bgp
->peer_self
)
6782 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6785 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6787 vty_out (vty
, " from 0.0.0.0 ");
6792 json_object_string_add(json_peer
, "peerId", "::");
6794 vty_out (vty
, " from :: ");
6798 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6800 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
6803 /* We RXed this path from one of our peers */
6809 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6810 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6812 if (binfo
->peer
->hostname
)
6813 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
6815 if (binfo
->peer
->domainname
)
6816 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
6818 if (binfo
->peer
->conf_if
)
6819 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
6823 if (binfo
->peer
->conf_if
)
6825 if (binfo
->peer
->hostname
&&
6826 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6827 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6828 binfo
->peer
->conf_if
);
6830 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
6834 if (binfo
->peer
->hostname
&&
6835 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6836 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6839 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6842 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
6843 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
6845 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6850 vty_out (vty
, "%s", VTY_NEWLINE
);
6852 /* display the link-local nexthop */
6853 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6857 json_nexthop_ll
= json_object_new_object();
6858 json_object_string_add(json_nexthop_ll
, "ip",
6859 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6860 buf
, INET6_ADDRSTRLEN
));
6861 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6862 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6864 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
6866 if (!attr
->extra
->mp_nexthop_prefer_global
)
6867 json_object_boolean_true_add(json_nexthop_ll
, "used");
6869 json_object_boolean_true_add(json_nexthop_global
, "used");
6873 vty_out (vty
, " (%s) %s%s",
6874 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6875 buf
, INET6_ADDRSTRLEN
),
6876 attr
->extra
->mp_nexthop_prefer_global
?
6877 "(prefer-global)" : "(used)",
6881 /* If we do not have a link-local nexthop then we must flag the global as "used" */
6885 json_object_boolean_true_add(json_nexthop_global
, "used");
6888 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
6890 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6892 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
6894 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6897 json_object_int_add(json_path
, "med", attr
->med
);
6899 vty_out (vty
, ", metric %u", attr
->med
);
6902 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6905 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6907 vty_out (vty
, ", localpref %u", attr
->local_pref
);
6912 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
6914 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
6917 if (attr
->extra
&& attr
->extra
->weight
!= 0)
6920 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6922 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
6925 if (attr
->extra
&& attr
->extra
->tag
!= 0)
6928 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
6930 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
6933 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6936 json_object_boolean_false_add(json_path
, "valid");
6938 vty_out (vty
, ", invalid");
6940 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6943 json_object_boolean_true_add(json_path
, "valid");
6945 vty_out (vty
, ", valid");
6948 if (binfo
->peer
!= bgp
->peer_self
)
6950 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
6952 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
6955 json_object_string_add(json_peer
, "type", "confed-internal");
6957 vty_out (vty
, ", confed-internal");
6962 json_object_string_add(json_peer
, "type", "internal");
6964 vty_out (vty
, ", internal");
6969 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
6972 json_object_string_add(json_peer
, "type", "confed-external");
6974 vty_out (vty
, ", confed-external");
6979 json_object_string_add(json_peer
, "type", "external");
6981 vty_out (vty
, ", external");
6985 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
6989 json_object_boolean_true_add(json_path
, "aggregated");
6990 json_object_boolean_true_add(json_path
, "local");
6994 vty_out (vty
, ", aggregated, local");
6997 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7000 json_object_boolean_true_add(json_path
, "sourced");
7002 vty_out (vty
, ", sourced");
7008 json_object_boolean_true_add(json_path
, "sourced");
7009 json_object_boolean_true_add(json_path
, "local");
7013 vty_out (vty
, ", sourced, local");
7017 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7020 json_object_boolean_true_add(json_path
, "atomicAggregate");
7022 vty_out (vty
, ", atomic-aggregate");
7025 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7026 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7027 bgp_info_mpath_count (binfo
)))
7030 json_object_boolean_true_add(json_path
, "multipath");
7032 vty_out (vty
, ", multipath");
7035 // Mark the bestpath(s)
7036 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7038 first_as
= aspath_get_first_as(attr
->aspath
);
7043 json_bestpath
= json_object_new_object();
7044 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7049 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7051 vty_out (vty
, ", bestpath-from-AS Local");
7055 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7060 json_bestpath
= json_object_new_object();
7061 json_object_boolean_true_add(json_bestpath
, "overall");
7064 vty_out (vty
, ", best");
7068 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7071 vty_out (vty
, "%s", VTY_NEWLINE
);
7073 /* Line 4 display Community */
7074 if (attr
->community
)
7078 json_object_lock(attr
->community
->json
);
7079 json_object_object_add(json_path
, "community", attr
->community
->json
);
7083 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7088 /* Line 5 display Extended-community */
7089 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7093 json_ext_community
= json_object_new_object();
7094 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7095 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7099 vty_out (vty
, " Extended Community: %s%s",
7100 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7104 /* Line 6 display Large community */
7105 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7106 vty_out (vty
, " Large Community: %s%s",
7107 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7109 /* Line 7 display Originator, Cluster-id */
7110 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7111 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7113 assert (attr
->extra
);
7114 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7117 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7119 vty_out (vty
, " Originator: %s",
7120 inet_ntoa (attr
->extra
->originator_id
));
7123 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7129 json_cluster_list
= json_object_new_object();
7130 json_cluster_list_list
= json_object_new_array();
7132 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7134 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7135 json_object_array_add(json_cluster_list_list
, json_string
);
7138 /* struct cluster_list does not have "str" variable like
7139 * aspath and community do. Add this someday if someone
7141 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7143 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7144 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7148 vty_out (vty
, ", Cluster list: ");
7150 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7152 vty_out (vty
, "%s ",
7153 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7159 vty_out (vty
, "%s", VTY_NEWLINE
);
7162 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7163 bgp_damp_info_vty (vty
, binfo
, json_path
);
7165 /* Line 8 display Addpath IDs */
7166 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7170 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7171 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7175 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7176 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7181 /* If we used addpath to TX a non-bestpath we need to display
7182 * "Advertised to" on a path-by-path basis */
7183 if (bgp
->addpath_tx_used
[afi
][safi
])
7187 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7189 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7190 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7192 if ((addpath_capable
&& has_adj
) ||
7193 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7195 if (json_path
&& !json_adv_to
)
7196 json_adv_to
= json_object_new_object();
7198 route_vty_out_advertised_to(vty
, peer
, &first
,
7208 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7215 vty_out (vty
, "%s", VTY_NEWLINE
);
7220 /* Line 9 display Uptime */
7221 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7224 json_last_update
= json_object_new_object();
7225 json_object_int_add(json_last_update
, "epoch", tbuf
);
7226 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7227 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7230 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7233 /* We've constructed the json object for this path, add it to the json
7238 if (json_nexthop_global
|| json_nexthop_ll
)
7240 json_nexthops
= json_object_new_array();
7242 if (json_nexthop_global
)
7243 json_object_array_add(json_nexthops
, json_nexthop_global
);
7245 if (json_nexthop_ll
)
7246 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7248 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7251 json_object_object_add(json_path
, "peer", json_peer
);
7252 json_object_array_add(json_paths
, json_path
);
7255 vty_out (vty
, "%s", VTY_NEWLINE
);
7258 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7259 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7260 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7263 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7264 const char *prefix_list_str
, afi_t afi
,
7265 safi_t safi
, enum bgp_show_type type
);
7267 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7268 const char *filter
, afi_t afi
,
7269 safi_t safi
, enum bgp_show_type type
);
7271 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7272 const char *rmap_str
, afi_t afi
,
7273 safi_t safi
, enum bgp_show_type type
);
7275 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7276 const char *com
, int exact
,
7277 afi_t afi
, safi_t safi
);
7279 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7280 const char *prefix
, afi_t afi
,
7281 safi_t safi
, enum bgp_show_type type
);
7283 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7284 safi_t safi
, enum bgp_show_type type
);
7286 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7287 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7290 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7291 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7293 struct bgp_info
*ri
;
7294 struct bgp_node
*rn
;
7297 unsigned long output_count
;
7298 unsigned long total_count
;
7302 json_object
*json_paths
= NULL
;
7307 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7308 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7309 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7310 table
->version
, inet_ntoa (bgp
->router_id
));
7311 json_paths
= json_object_new_object();
7314 /* This is first entry point, so reset total line. */
7318 /* Start processing of routes. */
7319 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7320 if (rn
->info
!= NULL
)
7323 if (!first
&& use_json
)
7328 json_paths
= json_object_new_array();
7332 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7335 if (type
== bgp_show_type_flap_statistics
7336 || type
== bgp_show_type_flap_neighbor
7337 || type
== bgp_show_type_dampend_paths
7338 || type
== bgp_show_type_damp_neighbor
)
7340 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7343 if (type
== bgp_show_type_regexp
)
7345 regex_t
*regex
= output_arg
;
7347 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7350 if (type
== bgp_show_type_prefix_list
)
7352 struct prefix_list
*plist
= output_arg
;
7354 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7357 if (type
== bgp_show_type_filter_list
)
7359 struct as_list
*as_list
= output_arg
;
7361 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7364 if (type
== bgp_show_type_route_map
)
7366 struct route_map
*rmap
= output_arg
;
7367 struct bgp_info binfo
;
7368 struct attr dummy_attr
;
7369 struct attr_extra dummy_extra
;
7372 dummy_attr
.extra
= &dummy_extra
;
7373 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7375 binfo
.peer
= ri
->peer
;
7376 binfo
.attr
= &dummy_attr
;
7378 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7379 if (ret
== RMAP_DENYMATCH
)
7382 if (type
== bgp_show_type_neighbor
7383 || type
== bgp_show_type_flap_neighbor
7384 || type
== bgp_show_type_damp_neighbor
)
7386 union sockunion
*su
= output_arg
;
7388 if (ri
->peer
== NULL
||
7389 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7392 if (type
== bgp_show_type_cidr_only
)
7394 u_int32_t destination
;
7396 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7397 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7399 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7401 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7404 if (type
== bgp_show_type_prefix_longer
)
7406 struct prefix
*p
= output_arg
;
7408 if (! prefix_match (p
, &rn
->p
))
7411 if (type
== bgp_show_type_community_all
)
7413 if (! ri
->attr
->community
)
7416 if (type
== bgp_show_type_community
)
7418 struct community
*com
= output_arg
;
7420 if (! ri
->attr
->community
||
7421 ! community_match (ri
->attr
->community
, com
))
7424 if (type
== bgp_show_type_community_exact
)
7426 struct community
*com
= output_arg
;
7428 if (! ri
->attr
->community
||
7429 ! community_cmp (ri
->attr
->community
, com
))
7432 if (type
== bgp_show_type_community_list
)
7434 struct community_list
*list
= output_arg
;
7436 if (! community_list_match (ri
->attr
->community
, list
))
7439 if (type
== bgp_show_type_community_list_exact
)
7441 struct community_list
*list
= output_arg
;
7443 if (! community_list_exact_match (ri
->attr
->community
, list
))
7446 if (type
== bgp_show_type_lcommunity
)
7448 struct lcommunity
*lcom
= output_arg
;
7450 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7451 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7454 if (type
== bgp_show_type_lcommunity_list
)
7456 struct community_list
*list
= output_arg
;
7458 if (! ri
->attr
->extra
||
7459 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7462 if (type
== bgp_show_type_lcommunity_all
)
7464 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7467 if (type
== bgp_show_type_dampend_paths
7468 || type
== bgp_show_type_damp_neighbor
)
7470 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7471 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7475 if (!use_json
&& header
)
7477 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7478 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7479 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7480 if (type
== bgp_show_type_dampend_paths
7481 || type
== bgp_show_type_damp_neighbor
)
7482 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7483 else if (type
== bgp_show_type_flap_statistics
7484 || type
== bgp_show_type_flap_neighbor
)
7485 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7487 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7491 if (type
== bgp_show_type_dampend_paths
7492 || type
== bgp_show_type_damp_neighbor
)
7493 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7494 else if (type
== bgp_show_type_flap_statistics
7495 || type
== bgp_show_type_flap_neighbor
)
7496 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7498 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7508 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7509 vty_out (vty
, "\"%s\": ", buf2
);
7510 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7511 json_object_free (json_paths
);
7520 json_object_free (json_paths
);
7521 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7525 /* No route is displayed */
7526 if (output_count
== 0)
7528 if (type
== bgp_show_type_normal
)
7529 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7532 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7533 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7540 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7541 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7543 struct bgp_table
*table
;
7547 bgp
= bgp_get_default ();
7553 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7556 /* use MPLS and ENCAP specific shows until they are merged */
7557 if (safi
== SAFI_MPLS_VPN
)
7559 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
7562 if (safi
== SAFI_ENCAP
)
7564 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
7569 table
= bgp
->rib
[afi
][safi
];
7571 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7576 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7579 struct listnode
*node
, *nnode
;
7581 struct bgp_table
*table
;
7585 vty_out (vty
, "{%s", VTY_NEWLINE
);
7587 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7592 vty_out (vty
, ",%s", VTY_NEWLINE
);
7596 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7597 ? "Default" : bgp
->name
);
7601 vty_out (vty
, "%sInstance %s:%s",
7603 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7604 ? "Default" : bgp
->name
,
7607 table
= bgp
->rib
[afi
][safi
];
7608 bgp_show_table (vty
, bgp
, table
,
7609 bgp_show_type_normal
, NULL
, use_json
);
7614 vty_out (vty
, "}%s", VTY_NEWLINE
);
7617 /* Header of detailed BGP route information */
7619 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7620 struct bgp_node
*rn
,
7621 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7624 struct bgp_info
*ri
;
7627 struct listnode
*node
, *nnode
;
7628 char buf1
[INET6_ADDRSTRLEN
];
7629 char buf2
[INET6_ADDRSTRLEN
];
7634 int no_advertise
= 0;
7637 json_object
*json_adv_to
= NULL
;
7643 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7644 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7648 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7649 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
) ?
7650 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7651 safi
== SAFI_MPLS_VPN
? ":" : "",
7652 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
7653 p
->prefixlen
, VTY_NEWLINE
);
7656 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7659 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7662 if (ri
->extra
&& ri
->extra
->suppress
)
7664 if (ri
->attr
->community
!= NULL
)
7666 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7668 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7670 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7678 vty_out (vty
, "Paths: (%d available", count
);
7681 vty_out (vty
, ", best #%d", best
);
7682 if (safi
== SAFI_UNICAST
)
7683 vty_out (vty
, ", table %s",
7684 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7685 ? "Default-IP-Routing-Table" : bgp
->name
);
7688 vty_out (vty
, ", no best path");
7691 vty_out (vty
, ", not advertised to any peer");
7693 vty_out (vty
, ", not advertised to EBGP peer");
7695 vty_out (vty
, ", not advertised outside local AS");
7698 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7699 vty_out (vty
, ")%s", VTY_NEWLINE
);
7702 /* If we are not using addpath then we can display Advertised to and that will
7703 * show what peers we advertised the bestpath to. If we are using addpath
7704 * though then we must display Advertised to on a path-by-path basis. */
7705 if (!bgp
->addpath_tx_used
[afi
][safi
])
7707 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7709 if (bgp_adj_out_lookup (peer
, rn
, 0))
7711 if (json
&& !json_adv_to
)
7712 json_adv_to
= json_object_new_object();
7714 route_vty_out_advertised_to(vty
, peer
, &first
,
7715 " Advertised to non peer-group peers:\n ",
7724 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7730 vty_out (vty
, " Not advertised to any peer");
7731 vty_out (vty
, "%s", VTY_NEWLINE
);
7736 /* Display specified route of BGP table. */
7738 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7739 struct bgp_table
*rib
, const char *ip_str
,
7740 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7741 int prefix_check
, enum bgp_path_type pathtype
,
7747 struct prefix match
;
7748 struct bgp_node
*rn
;
7749 struct bgp_node
*rm
;
7750 struct bgp_info
*ri
;
7751 struct bgp_table
*table
;
7752 json_object
*json
= NULL
;
7753 json_object
*json_paths
= NULL
;
7755 /* Check IP address argument. */
7756 ret
= str2prefix (ip_str
, &match
);
7759 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7763 match
.family
= afi2family (afi
);
7767 json
= json_object_new_object();
7768 json_paths
= json_object_new_array();
7771 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
7773 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7775 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7778 if ((table
= rn
->info
) != NULL
)
7782 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7784 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7786 bgp_unlock_node (rm
);
7790 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7794 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7795 AFI_IP
, safi
, json
);
7800 if (pathtype
== BGP_PATH_ALL
||
7801 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7802 (pathtype
== BGP_PATH_MULTIPATH
&&
7803 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7804 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
7807 bgp_unlock_node (rm
);
7816 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
7818 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
7820 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7824 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
7829 if (pathtype
== BGP_PATH_ALL
||
7830 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7831 (pathtype
== BGP_PATH_MULTIPATH
&&
7832 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7833 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
7837 bgp_unlock_node (rn
);
7844 json_object_object_add(json
, "paths", json_paths
);
7846 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
7847 json_object_free(json
);
7853 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
7861 /* Display specified route of Main RIB */
7863 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
7864 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7865 int prefix_check
, enum bgp_path_type pathtype
,
7869 bgp
= bgp_get_default ();
7871 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
7872 afi
, safi
, prd
, prefix_check
, pathtype
,
7877 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7878 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
7880 struct lcommunity
*lcom
;
7886 b
= buffer_new (1024);
7887 for (i
= 0; i
< argc
; i
++)
7890 buffer_putc (b
, ' ');
7893 if (strmatch (argv
[i
]->text
, "<AA:BB:CC>"))
7896 buffer_putstr (b
, argv
[i
]->arg
);
7900 buffer_putc (b
, '\0');
7902 str
= buffer_getstr (b
);
7905 lcom
= lcommunity_str2com (str
);
7906 XFREE (MTYPE_TMP
, str
);
7909 vty_out (vty
, "%% Large-community malformed: %s", VTY_NEWLINE
);
7913 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
7917 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
7918 afi_t afi
, safi_t safi
, u_char uj
)
7920 struct community_list
*list
;
7922 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
7925 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
7930 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
7933 DEFUN (show_ip_bgp_large_community_list
,
7934 show_ip_bgp_large_community_list_cmd
,
7935 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
7939 BGP_INSTANCE_HELP_STR
7942 "Address Family modifier\n"
7943 "Address Family modifier\n"
7944 "Address Family modifier\n"
7945 "Address Family modifier\n"
7946 "Display routes matching the large-community-list\n"
7947 "large-community-list number\n"
7948 "large-community-list name\n"
7952 afi_t afi
= AFI_IP6
;
7953 safi_t safi
= SAFI_UNICAST
;
7956 if (argv_find (argv
, argc
, "ip", &idx
))
7958 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
7959 vrf
= argv
[++idx
]->arg
;
7960 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
7962 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
7963 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
7964 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
7967 int uj
= use_json (argc
, argv
);
7969 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
7972 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
7976 argv_find (argv
, argc
, "large-community-list", &idx
);
7977 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
7979 DEFUN (show_ip_bgp_large_community
,
7980 show_ip_bgp_large_community_cmd
,
7981 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
7985 BGP_INSTANCE_HELP_STR
7988 "Address Family modifier\n"
7989 "Address Family modifier\n"
7990 "Address Family modifier\n"
7991 "Address Family modifier\n"
7992 "Display routes matching the large-communities\n"
7993 "List of large-community numbers\n"
7997 afi_t afi
= AFI_IP6
;
7998 safi_t safi
= SAFI_UNICAST
;
8001 if (argv_find (argv
, argc
, "ip", &idx
))
8003 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8004 vrf
= argv
[++idx
]->arg
;
8005 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8007 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8008 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8009 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8012 int uj
= use_json (argc
, argv
);
8014 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8017 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8021 argv_find (argv
, argc
, "large-community", &idx
);
8022 if (strmatch(argv
[idx
+1]->text
, "AA:BB:CC"))
8023 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8025 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8028 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8030 /* BGP route print out function. */
8033 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8036 |dampening <flap-statistics|dampened-paths|parameters>\
8041 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8042 |community-list <(1-500)|WORD> [exact-match]\
8043 |A.B.C.D/M longer-prefixes\
8044 |X:X::X:X/M longer-prefixes>\
8049 BGP_INSTANCE_HELP_STR
8052 "Display only routes with non-natural netmasks\n"
8053 "Display detailed information about dampening\n"
8054 "Display flap statistics of routes\n"
8055 "Display paths suppressed due to dampening\n"
8056 "Display detail of configured dampening parameters\n"
8057 "Display routes matching the route-map\n"
8058 "A route-map to match on\n"
8059 "Display routes conforming to the prefix-list\n"
8060 "Prefix-list name\n"
8061 "Display routes conforming to the filter-list\n"
8062 "Regular expression access list name\n"
8063 "BGP RIB advertisement statistics\n"
8064 "Display routes matching the communities\n"
8066 "Do not send outside local AS (well-known community)\n"
8067 "Do not advertise to any peer (well-known community)\n"
8068 "Do not export to next AS (well-known community)\n"
8069 "Exact match of the communities\n"
8070 "Display routes matching the community-list\n"
8071 "community-list number\n"
8072 "community-list name\n"
8073 "Exact match of the communities\n"
8075 "Display route and more specific routes\n"
8077 "Display route and more specific routes\n"
8080 vrf_id_t vrf
= VRF_DEFAULT
;
8081 afi_t afi
= AFI_IP6
;
8082 safi_t safi
= SAFI_UNICAST
;
8083 int exact_match
= 0;
8084 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8085 struct bgp
*bgp
= NULL
;
8088 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8092 int uj
= use_json (argc
, argv
);
8095 bgp
= bgp_lookup_by_vrf_id (vrf
);
8098 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
8102 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8103 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8105 if (argv_find(argv
, argc
, "dampening", &idx
))
8107 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8108 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8109 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8110 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8111 else if (argv_find (argv
, argc
, "parameters", &idx
))
8112 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8115 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8116 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8118 if (argv_find(argv
, argc
, "filter-list", &idx
))
8119 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8121 if (argv_find(argv
, argc
, "statistics", &idx
))
8122 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8124 if (argv_find(argv
, argc
, "route-map", &idx
))
8125 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8127 if (argv_find(argv
, argc
, "community", &idx
))
8129 /* show a specific community */
8130 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8131 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8132 argv_find (argv
, argc
, "no-export", &idx
))
8134 if (argv_find (argv
, argc
, "exact_match", &idx
))
8136 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8138 /* show all communities */
8140 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8143 if (argv_find(argv
, argc
, "community-list", &idx
))
8145 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8146 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8148 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8151 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8152 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8154 if (safi
== SAFI_MPLS_VPN
)
8155 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8156 else if (safi
== SAFI_ENCAP
)
8157 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8159 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8162 DEFUN (show_ip_bgp_route
,
8163 show_ip_bgp_route_cmd
,
8164 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8165 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8169 BGP_INSTANCE_HELP_STR
8172 "Network in the BGP routing table to display\n"
8174 "Network in the BGP routing table to display\n"
8176 "Display only the bestpath\n"
8177 "Display only multipaths\n"
8180 int prefix_check
= 0;
8182 afi_t afi
= AFI_IP6
;
8183 safi_t safi
= SAFI_UNICAST
;
8184 vrf_id_t vrf
= VRF_DEFAULT
;;
8185 char *prefix
= NULL
;
8186 struct bgp
*bgp
= NULL
;
8187 enum bgp_path_type path_type
;
8188 u_char uj
= use_json(argc
, argv
);
8192 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8198 bgp
= bgp_lookup_by_vrf_id (vrf
);
8201 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
8207 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8211 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8212 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8214 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8217 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8219 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8222 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8224 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8228 prefix
= argv
[idx
]->arg
;
8230 /* [<bestpath|multipath>] */
8231 if (argv_find (argv
, argc
, "bestpath", &idx
))
8232 path_type
= BGP_PATH_BESTPATH
;
8233 else if (argv_find (argv
, argc
, "multipath", &idx
))
8234 path_type
= BGP_PATH_MULTIPATH
;
8236 path_type
= BGP_PATH_ALL
;
8238 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8241 DEFUN (show_ip_bgp_regexp
,
8242 show_ip_bgp_regexp_cmd
,
8243 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8247 BGP_INSTANCE_HELP_STR
8250 "Display routes matching the AS path regular expression\n"
8251 "A regular-expression to match the BGP AS paths\n")
8253 vrf_id_t vrf
= VRF_DEFAULT
;
8254 afi_t afi
= AFI_IP6
;
8255 safi_t safi
= SAFI_UNICAST
;
8258 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8262 // get index of regex
8263 argv_find (argv
, argc
, "regexp", &idx
);
8266 char *regstr
= argv_concat (argv
, argc
, idx
);
8267 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8268 XFREE (MTYPE_TMP
, regstr
);
8272 DEFUN (show_ip_bgp_instance_all
,
8273 show_ip_bgp_instance_all_cmd
,
8274 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8278 BGP_INSTANCE_ALL_HELP_STR
8283 vrf_id_t vrf
= VRF_DEFAULT
;
8285 safi_t safi
= SAFI_UNICAST
;
8288 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8292 int uj
= use_json (argc
, argv
);
8295 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8300 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8301 safi_t safi
, enum bgp_show_type type
)
8308 regex
= bgp_regcomp (regstr
);
8311 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8315 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8316 bgp_regex_free (regex
);
8321 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8322 const char *prefix_list_str
, afi_t afi
,
8323 safi_t safi
, enum bgp_show_type type
)
8325 struct prefix_list
*plist
;
8327 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8330 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8331 prefix_list_str
, VTY_NEWLINE
);
8335 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8339 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8340 const char *filter
, afi_t afi
,
8341 safi_t safi
, enum bgp_show_type type
)
8343 struct as_list
*as_list
;
8345 as_list
= as_list_lookup (filter
);
8346 if (as_list
== NULL
)
8348 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8352 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8356 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8357 const char *rmap_str
, afi_t afi
,
8358 safi_t safi
, enum bgp_show_type type
)
8360 struct route_map
*rmap
;
8362 rmap
= route_map_lookup_by_name (rmap_str
);
8365 vty_out (vty
, "%% %s is not a valid route-map name%s",
8366 rmap_str
, VTY_NEWLINE
);
8370 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8374 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8375 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8377 struct community
*com
;
8383 b
= buffer_new (1024);
8384 for (i
= 0; i
< argc
; i
++)
8387 buffer_putc (b
, ' ');
8390 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8395 buffer_putstr (b
, argv
[i
]->arg
);
8397 buffer_putc (b
, '\0');
8399 str
= buffer_getstr (b
);
8402 com
= community_str2com (str
);
8403 XFREE (MTYPE_TMP
, str
);
8406 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8410 return bgp_show (vty
, bgp
, afi
, safi
,
8411 (exact
? bgp_show_type_community_exact
:
8412 bgp_show_type_community
), com
, 0);
8416 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8417 const char *com
, int exact
,
8418 afi_t afi
, safi_t safi
)
8420 struct community_list
*list
;
8422 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8425 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8430 return bgp_show (vty
, bgp
, afi
, safi
,
8431 (exact
? bgp_show_type_community_list_exact
:
8432 bgp_show_type_community_list
), list
, 0);
8436 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8437 const char *prefix
, afi_t afi
,
8438 safi_t safi
, enum bgp_show_type type
)
8445 ret
= str2prefix (prefix
, p
);
8448 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8452 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8457 static struct peer
*
8458 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8459 const char *ip_str
, u_char use_json
)
8465 /* Get peer sockunion. */
8466 ret
= str2sockunion (ip_str
, &su
);
8469 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8472 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8478 json_object
*json_no
= NULL
;
8479 json_no
= json_object_new_object();
8480 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8481 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8482 json_object_free(json_no
);
8485 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8492 /* Peer structure lookup. */
8493 peer
= peer_lookup (bgp
, &su
);
8498 json_object
*json_no
= NULL
;
8499 json_no
= json_object_new_object();
8500 json_object_string_add(json_no
, "warning","No such neighbor");
8501 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8502 json_object_free(json_no
);
8505 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8514 BGP_STATS_MAXBITLEN
= 0,
8518 BGP_STATS_UNAGGREGATEABLE
,
8519 BGP_STATS_MAX_AGGREGATEABLE
,
8520 BGP_STATS_AGGREGATES
,
8522 BGP_STATS_ASPATH_COUNT
,
8523 BGP_STATS_ASPATH_MAXHOPS
,
8524 BGP_STATS_ASPATH_TOTHOPS
,
8525 BGP_STATS_ASPATH_MAXSIZE
,
8526 BGP_STATS_ASPATH_TOTSIZE
,
8527 BGP_STATS_ASN_HIGHEST
,
8531 static const char *table_stats_strs
[] =
8533 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8534 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8535 [BGP_STATS_RIB
] = "Total Advertisements",
8536 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8537 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8538 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8539 [BGP_STATS_SPACE
] = "Address space advertised",
8540 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8541 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8542 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8543 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8544 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8545 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8546 [BGP_STATS_MAX
] = NULL
,
8549 struct bgp_table_stats
8551 struct bgp_table
*table
;
8552 unsigned long long counts
[BGP_STATS_MAX
];
8556 #define TALLY_SIGFIG 100000
8557 static unsigned long
8558 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8560 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8561 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8562 unsigned long ret
= newtot
/ count
;
8564 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8572 bgp_table_stats_walker (struct thread
*t
)
8574 struct bgp_node
*rn
;
8575 struct bgp_node
*top
;
8576 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8577 unsigned int space
= 0;
8579 if (!(top
= bgp_table_top (ts
->table
)))
8582 switch (top
->p
.family
)
8585 space
= IPV4_MAX_BITLEN
;
8588 space
= IPV6_MAX_BITLEN
;
8592 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8594 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8596 struct bgp_info
*ri
;
8597 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8598 unsigned int rinum
= 0;
8606 ts
->counts
[BGP_STATS_PREFIXES
]++;
8607 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8610 ts
->counts
[BGP_STATS_AVGPLEN
]
8611 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8612 ts
->counts
[BGP_STATS_AVGPLEN
],
8616 /* check if the prefix is included by any other announcements */
8617 while (prn
&& !prn
->info
)
8618 prn
= bgp_node_parent_nolock (prn
);
8620 if (prn
== NULL
|| prn
== top
)
8622 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8623 /* announced address space */
8625 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8628 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8630 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8633 ts
->counts
[BGP_STATS_RIB
]++;
8636 (CHECK_FLAG (ri
->attr
->flag
,
8637 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8638 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8641 if (ri
->attr
&& ri
->attr
->aspath
)
8643 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8644 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8645 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8647 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8649 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8650 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8652 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8653 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8655 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8656 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8658 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8659 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8660 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8662 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8663 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8664 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8667 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8668 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8676 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8678 struct bgp_table_stats ts
;
8681 if (!bgp
->rib
[afi
][safi
])
8683 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8684 afi
, safi
, VTY_NEWLINE
);
8688 memset (&ts
, 0, sizeof (ts
));
8689 ts
.table
= bgp
->rib
[afi
][safi
];
8690 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8692 vty_out (vty
, "BGP %s RIB statistics%s%s",
8693 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8695 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8697 if (!table_stats_strs
[i
])
8703 case BGP_STATS_ASPATH_AVGHOPS
:
8704 case BGP_STATS_ASPATH_AVGSIZE
:
8705 case BGP_STATS_AVGPLEN
:
8706 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8707 vty_out (vty
, "%12.2f",
8708 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8711 case BGP_STATS_ASPATH_TOTHOPS
:
8712 case BGP_STATS_ASPATH_TOTSIZE
:
8713 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8714 vty_out (vty
, "%12.2f",
8716 (float)ts
.counts
[i
] /
8717 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8720 case BGP_STATS_TOTPLEN
:
8721 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8722 vty_out (vty
, "%12.2f",
8724 (float)ts
.counts
[i
] /
8725 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8728 case BGP_STATS_SPACE
:
8729 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8730 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8731 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8733 vty_out (vty
, "%30s: ", "%% announced ");
8734 vty_out (vty
, "%12.2f%s",
8735 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8736 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8738 vty_out (vty
, "%30s: ", "/8 equivalent ");
8739 vty_out (vty
, "%12.2f%s",
8740 (float)ts
.counts
[BGP_STATS_SPACE
] /
8741 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8743 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8745 vty_out (vty
, "%30s: ", "/24 equivalent ");
8746 vty_out (vty
, "%12.2f",
8747 (float)ts
.counts
[BGP_STATS_SPACE
] /
8748 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8751 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8752 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8755 vty_out (vty
, "%s", VTY_NEWLINE
);
8770 PCOUNT_PFCNT
, /* the figure we display to users */
8774 static const char *pcount_strs
[] =
8776 [PCOUNT_ADJ_IN
] = "Adj-in",
8777 [PCOUNT_DAMPED
] = "Damped",
8778 [PCOUNT_REMOVED
] = "Removed",
8779 [PCOUNT_HISTORY
] = "History",
8780 [PCOUNT_STALE
] = "Stale",
8781 [PCOUNT_VALID
] = "Valid",
8782 [PCOUNT_ALL
] = "All RIB",
8783 [PCOUNT_COUNTED
] = "PfxCt counted",
8784 [PCOUNT_PFCNT
] = "Useable",
8785 [PCOUNT_MAX
] = NULL
,
8790 unsigned int count
[PCOUNT_MAX
];
8791 const struct peer
*peer
;
8792 const struct bgp_table
*table
;
8796 bgp_peer_count_walker (struct thread
*t
)
8798 struct bgp_node
*rn
;
8799 struct peer_pcounts
*pc
= THREAD_ARG (t
);
8800 const struct peer
*peer
= pc
->peer
;
8802 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
8804 struct bgp_adj_in
*ain
;
8805 struct bgp_info
*ri
;
8807 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
8808 if (ain
->peer
== peer
)
8809 pc
->count
[PCOUNT_ADJ_IN
]++;
8811 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8813 char buf
[SU_ADDRSTRLEN
];
8815 if (ri
->peer
!= peer
)
8818 pc
->count
[PCOUNT_ALL
]++;
8820 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
8821 pc
->count
[PCOUNT_DAMPED
]++;
8822 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
8823 pc
->count
[PCOUNT_HISTORY
]++;
8824 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
8825 pc
->count
[PCOUNT_REMOVED
]++;
8826 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
8827 pc
->count
[PCOUNT_STALE
]++;
8828 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
8829 pc
->count
[PCOUNT_VALID
]++;
8830 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8831 pc
->count
[PCOUNT_PFCNT
]++;
8833 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
8835 pc
->count
[PCOUNT_COUNTED
]++;
8836 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8837 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
8839 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8840 buf
, SU_ADDRSTRLEN
),
8846 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8847 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
8849 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8850 buf
, SU_ADDRSTRLEN
),
8860 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
8862 struct peer_pcounts pcounts
= { .peer
= peer
};
8864 json_object
*json
= NULL
;
8865 json_object
*json_loop
= NULL
;
8869 json
= json_object_new_object();
8870 json_loop
= json_object_new_object();
8873 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
8874 || !peer
->bgp
->rib
[afi
][safi
])
8878 json_object_string_add(json
, "warning", "No such neighbor or address family");
8879 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8880 json_object_free(json
);
8883 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
8888 memset (&pcounts
, 0, sizeof(pcounts
));
8889 pcounts
.peer
= peer
;
8890 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
8892 /* in-place call via thread subsystem so as to record execution time
8893 * * stats for the thread-walk (i.e. ensure this can't be blamed on
8894 * * on just vty_read()).
8896 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
8900 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
8901 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
8902 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
8904 for (i
= 0; i
< PCOUNT_MAX
; i
++)
8905 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
8907 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
8909 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
8911 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
8912 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
8914 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8915 json_object_free(json
);
8920 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
8922 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
8923 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
8928 vty_out (vty
, "Prefix counts for %s, %s%s",
8929 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
8932 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
8933 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
8934 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
8936 for (i
= 0; i
< PCOUNT_MAX
; i
++)
8937 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
8939 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
8941 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
8942 peer
->host
, VTY_NEWLINE
);
8943 vty_out (vty
, "Please report this bug, with the above command output%s",
8951 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
8952 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
8953 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
8954 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
8958 BGP_INSTANCE_HELP_STR
8961 "Address Family modifier\n"
8962 "Address Family modifier\n"
8963 "Address Family modifier\n"
8964 "Address Family modifier\n"
8965 "Detailed information on TCP and BGP neighbor connections\n"
8966 "Neighbor to display information about\n"
8967 "Neighbor to display information about\n"
8968 "Neighbor on BGP configured interface\n"
8969 "Display detailed prefix count information\n"
8972 vrf_id_t vrf
= VRF_DEFAULT
;
8973 afi_t afi
= AFI_IP6
;
8974 safi_t safi
= SAFI_UNICAST
;
8977 struct bgp
*bgp
= NULL
;
8979 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8983 int uj
= use_json (argc
, argv
);
8988 bgp
= bgp_lookup_by_vrf_id (vrf
);
8993 json_object
*json_no
= NULL
;
8994 json_no
= json_object_new_object();
8995 json_object_string_add(json_no
, "warning", "Can't find BGP view");
8996 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8997 json_object_free(json_no
);
9000 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9007 argv_find (argv
, argc
, "neighbors", &idx
);
9008 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9012 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9015 #ifdef KEEP_OLD_VPN_COMMANDS
9016 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9017 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9018 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9023 "Display information about all VPNv4 NLRIs\n"
9024 "Detailed information on TCP and BGP neighbor connections\n"
9025 "Neighbor to display information about\n"
9026 "Neighbor to display information about\n"
9027 "Neighbor on BGP configured interface\n"
9028 "Display detailed prefix count information\n"
9033 u_char uj
= use_json(argc
, argv
);
9035 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9039 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9042 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9043 show_ip_bgp_vpn_all_route_prefix_cmd
,
9044 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9049 "Display information about all VPNv4 NLRIs\n"
9050 "Network in the BGP routing table to display\n"
9051 "Network in the BGP routing table to display\n"
9055 char *network
= NULL
;
9056 struct bgp
*bgp
= bgp_get_default();
9059 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9062 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9063 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9064 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9066 #endif /* KEEP_OLD_VPN_COMMANDS */
9069 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9070 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9072 struct bgp_table
*table
;
9073 struct bgp_adj_in
*ain
;
9074 struct bgp_adj_out
*adj
;
9075 unsigned long output_count
;
9076 unsigned long filtered_count
;
9077 struct bgp_node
*rn
;
9082 struct attr_extra extra
;
9084 struct update_subgroup
*subgrp
;
9085 json_object
*json_scode
= NULL
;
9086 json_object
*json_ocode
= NULL
;
9087 json_object
*json_ar
= NULL
;
9088 struct peer_af
*paf
;
9092 json_scode
= json_object_new_object();
9093 json_ocode
= json_object_new_object();
9094 json_ar
= json_object_new_object();
9096 json_object_string_add(json_scode
, "suppressed", "s");
9097 json_object_string_add(json_scode
, "damped", "d");
9098 json_object_string_add(json_scode
, "history", "h");
9099 json_object_string_add(json_scode
, "valid", "*");
9100 json_object_string_add(json_scode
, "best", ">");
9101 json_object_string_add(json_scode
, "multipath", "=");
9102 json_object_string_add(json_scode
, "internal", "i");
9103 json_object_string_add(json_scode
, "ribFailure", "r");
9104 json_object_string_add(json_scode
, "stale", "S");
9105 json_object_string_add(json_scode
, "removed", "R");
9107 json_object_string_add(json_ocode
, "igp", "i");
9108 json_object_string_add(json_ocode
, "egp", "e");
9109 json_object_string_add(json_ocode
, "incomplete", "?");
9118 json_object_string_add(json
, "alert", "no BGP");
9119 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9120 json_object_free(json
);
9123 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9127 table
= bgp
->rib
[afi
][safi
];
9129 output_count
= filtered_count
= 0;
9130 subgrp
= peer_subgroup(peer
, afi
, safi
);
9132 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9136 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9137 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9138 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9139 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9140 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9144 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9145 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9146 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9148 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9149 VTY_NEWLINE
, VTY_NEWLINE
);
9154 attr
.extra
= &extra
;
9155 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9159 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9161 if (ain
->peer
== peer
)
9167 json_object_int_add(json
, "bgpTableVersion", 0);
9168 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9169 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9170 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9174 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9175 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9176 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9183 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9188 bgp_attr_dup(&attr
, ain
->attr
);
9189 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9191 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9202 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9203 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9204 if (paf
->peer
== peer
)
9210 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9211 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9212 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9213 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9217 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9218 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9219 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9220 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9228 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9234 bgp_attr_dup(&attr
, adj
->attr
);
9235 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9236 if (ret
!= RMAP_DENY
)
9238 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9248 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9250 if (output_count
!= 0)
9253 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9255 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9256 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9260 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9261 json_object_free(json
);
9267 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9268 int in
, const char *rmap_name
, u_char use_json
)
9270 json_object
*json
= NULL
;
9273 json
= json_object_new_object();
9275 if (!peer
|| !peer
->afc
[afi
][safi
])
9279 json_object_string_add(json
, "warning", "No such neighbor or address family");
9280 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9281 json_object_free(json
);
9284 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9289 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9293 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9294 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9295 json_object_free(json
);
9298 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9303 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9308 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9309 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9310 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9311 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9315 BGP_INSTANCE_HELP_STR
9318 "Detailed information on TCP and BGP neighbor connections\n"
9319 "Neighbor to display information about\n"
9320 "Neighbor to display information about\n"
9321 "Neighbor on BGP configured interface\n"
9322 "Display the received routes from neighbor\n"
9323 "Display the routes advertised to a BGP neighbor\n"
9324 "Route-map to modify the attributes\n"
9325 "Name of the route map\n"
9328 vrf_id_t vrf
= VRF_DEFAULT
;
9329 afi_t afi
= AFI_IP6
;
9330 safi_t safi
= SAFI_UNICAST
;
9331 char *rmap_name
= NULL
;
9332 char *peerstr
= NULL
;
9334 struct bgp
*bgp
= NULL
;
9339 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9343 int uj
= use_json (argc
, argv
);
9346 bgp
= bgp_lookup_by_vrf_id (vrf
);
9351 json_object
*json_no
= NULL
;
9352 json_no
= json_object_new_object();
9353 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9354 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9355 json_object_free(json_no
);
9358 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9362 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9363 argv_find (argv
, argc
, "neighbors", &idx
);
9364 peerstr
= argv
[++idx
]->arg
;
9366 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9370 if (argv_find (argv
, argc
, "received-routes", &idx
))
9372 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9374 if (argv_find (argv
, argc
, "route-map", &idx
))
9375 rmap_name
= argv
[++idx
]->arg
;
9377 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9380 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9381 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9382 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9388 "Address Family modifier\n"
9389 "Detailed information on TCP and BGP neighbor connections\n"
9390 "Neighbor to display information about\n"
9391 "Neighbor to display information about\n"
9392 "Neighbor on BGP configured interface\n"
9393 "Display information received from a BGP neighbor\n"
9394 "Display the prefixlist filter\n"
9397 afi_t afi
= AFI_IP6
;
9398 safi_t safi
= SAFI_UNICAST
;
9399 char *peerstr
= NULL
;
9409 if (argv_find (argv
, argc
, "ip", &idx
))
9411 /* [<ipv4|ipv6> [unicast]] */
9412 if (argv_find (argv
, argc
, "ipv4", &idx
))
9414 if (argv_find (argv
, argc
, "ipv6", &idx
))
9416 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9417 argv_find (argv
, argc
, "neighbors", &idx
);
9418 peerstr
= argv
[++idx
]->arg
;
9420 u_char uj
= use_json(argc
, argv
);
9422 ret
= str2sockunion (peerstr
, &su
);
9425 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9429 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9431 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9437 peer
= peer_lookup (NULL
, &su
);
9441 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9443 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9448 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9449 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9453 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9454 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9459 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9461 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9468 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9469 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9471 if (! peer
|| ! peer
->afc
[afi
][safi
])
9475 json_object
*json_no
= NULL
;
9476 json_no
= json_object_new_object();
9477 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9478 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9479 json_object_free(json_no
);
9482 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9486 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9489 DEFUN (show_ip_bgp_neighbor_routes
,
9490 show_ip_bgp_neighbor_routes_cmd
,
9491 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9492 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9496 BGP_INSTANCE_HELP_STR
9499 "Detailed information on TCP and BGP neighbor connections\n"
9500 "Neighbor to display information about\n"
9501 "Neighbor to display information about\n"
9502 "Neighbor on BGP configured interface\n"
9503 "Display flap statistics of the routes learned from neighbor\n"
9504 "Display the dampened routes received from neighbor\n"
9505 "Display routes learned from neighbor\n"
9508 vrf_id_t vrf
= VRF_DEFAULT
;
9509 char *peerstr
= NULL
;
9510 struct bgp
*bgp
= NULL
;
9511 afi_t afi
= AFI_IP6
;
9512 safi_t safi
= SAFI_UNICAST
;
9514 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9518 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9522 int uj
= use_json (argc
, argv
);
9527 bgp
= bgp_lookup_by_vrf_id (vrf
);
9532 json_object
*json_no
= NULL
;
9533 json_no
= json_object_new_object();
9534 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9535 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9536 json_object_free(json_no
);
9539 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9546 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9547 argv_find (argv
, argc
, "neighbors", &idx
);
9548 peerstr
= argv
[++idx
]->arg
;
9550 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9553 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9557 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9558 sh_type
= bgp_show_type_flap_neighbor
;
9559 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9560 sh_type
= bgp_show_type_damp_neighbor
;
9561 else if (argv_find (argv
, argc
, "routes", &idx
))
9562 sh_type
= bgp_show_type_neighbor
;
9564 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9567 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9571 /* Distance value for the IP source prefix. */
9574 /* Name of the access-list to be matched. */
9578 DEFUN (show_bgp_afi_vpn_rd_route
,
9579 show_bgp_afi_vpn_rd_route_cmd
,
9580 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
9584 "Address Family modifier\n"
9585 "Display information for a route distinguisher\n"
9586 "Route Distinguisher\n"
9587 "Network in the BGP routing table to display\n"
9588 "Network in the BGP routing table to display\n"
9592 struct prefix_rd prd
;
9593 afi_t afi
= AFI_MAX
;
9596 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
9597 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
9600 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
9603 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
9606 static struct bgp_distance
*
9607 bgp_distance_new (void)
9609 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9613 bgp_distance_free (struct bgp_distance
*bdistance
)
9615 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9619 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9620 const char *ip_str
, const char *access_list_str
)
9627 struct bgp_node
*rn
;
9628 struct bgp_distance
*bdistance
;
9630 afi
= bgp_node_afi (vty
);
9631 safi
= bgp_node_safi (vty
);
9633 ret
= str2prefix (ip_str
, &p
);
9636 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9640 distance
= atoi (distance_str
);
9642 /* Get BGP distance node. */
9643 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9646 bdistance
= rn
->info
;
9647 bgp_unlock_node (rn
);
9651 bdistance
= bgp_distance_new ();
9652 rn
->info
= bdistance
;
9655 /* Set distance value. */
9656 bdistance
->distance
= distance
;
9658 /* Reset access-list configuration. */
9659 if (bdistance
->access_list
)
9661 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9662 bdistance
->access_list
= NULL
;
9664 if (access_list_str
)
9665 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9671 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9672 const char *ip_str
, const char *access_list_str
)
9679 struct bgp_node
*rn
;
9680 struct bgp_distance
*bdistance
;
9682 afi
= bgp_node_afi (vty
);
9683 safi
= bgp_node_safi (vty
);
9685 ret
= str2prefix (ip_str
, &p
);
9688 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9692 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9695 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9699 bdistance
= rn
->info
;
9700 distance
= atoi(distance_str
);
9702 if (bdistance
->distance
!= distance
)
9704 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9708 if (bdistance
->access_list
)
9709 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9710 bgp_distance_free (bdistance
);
9713 bgp_unlock_node (rn
);
9714 bgp_unlock_node (rn
);
9719 /* Apply BGP information to distance method. */
9721 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9722 safi_t safi
, struct bgp
*bgp
)
9724 struct bgp_node
*rn
;
9727 struct bgp_distance
*bdistance
;
9728 struct access_list
*alist
;
9729 struct bgp_static
*bgp_static
;
9736 /* Check source address. */
9737 sockunion2hostprefix (&peer
->su
, &q
);
9738 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9741 bdistance
= rn
->info
;
9742 bgp_unlock_node (rn
);
9744 if (bdistance
->access_list
)
9746 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9747 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9748 return bdistance
->distance
;
9751 return bdistance
->distance
;
9754 /* Backdoor check. */
9755 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9758 bgp_static
= rn
->info
;
9759 bgp_unlock_node (rn
);
9761 if (bgp_static
->backdoor
)
9763 if (bgp
->distance_local
[afi
][safi
])
9764 return bgp
->distance_local
[afi
][safi
];
9766 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9770 if (peer
->sort
== BGP_PEER_EBGP
)
9772 if (bgp
->distance_ebgp
[afi
][safi
])
9773 return bgp
->distance_ebgp
[afi
][safi
];
9774 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
9778 if (bgp
->distance_ibgp
[afi
][safi
])
9779 return bgp
->distance_ibgp
[afi
][safi
];
9780 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9784 DEFUN (bgp_distance
,
9786 "distance bgp (1-255) (1-255) (1-255)",
9787 "Define an administrative distance\n"
9789 "Distance for routes external to the AS\n"
9790 "Distance for routes internal to the AS\n"
9791 "Distance for local routes\n")
9793 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9795 int idx_number_2
= 3;
9796 int idx_number_3
= 4;
9800 afi
= bgp_node_afi (vty
);
9801 safi
= bgp_node_safi (vty
);
9803 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
9804 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
9805 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
9809 DEFUN (no_bgp_distance
,
9810 no_bgp_distance_cmd
,
9811 "no distance bgp [(1-255) (1-255) (1-255)]",
9813 "Define an administrative distance\n"
9815 "Distance for routes external to the AS\n"
9816 "Distance for routes internal to the AS\n"
9817 "Distance for local routes\n")
9819 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9823 afi
= bgp_node_afi (vty
);
9824 safi
= bgp_node_safi (vty
);
9826 bgp
->distance_ebgp
[afi
][safi
] = 0;
9827 bgp
->distance_ibgp
[afi
][safi
] = 0;
9828 bgp
->distance_local
[afi
][safi
] = 0;
9833 DEFUN (bgp_distance_source
,
9834 bgp_distance_source_cmd
,
9835 "distance (1-255) A.B.C.D/M",
9836 "Define an administrative distance\n"
9837 "Administrative distance\n"
9838 "IP source prefix\n")
9841 int idx_ipv4_prefixlen
= 2;
9842 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9846 DEFUN (no_bgp_distance_source
,
9847 no_bgp_distance_source_cmd
,
9848 "no distance (1-255) A.B.C.D/M",
9850 "Define an administrative distance\n"
9851 "Administrative distance\n"
9852 "IP source prefix\n")
9855 int idx_ipv4_prefixlen
= 3;
9856 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9860 DEFUN (bgp_distance_source_access_list
,
9861 bgp_distance_source_access_list_cmd
,
9862 "distance (1-255) A.B.C.D/M WORD",
9863 "Define an administrative distance\n"
9864 "Administrative distance\n"
9865 "IP source prefix\n"
9866 "Access list name\n")
9869 int idx_ipv4_prefixlen
= 2;
9871 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9875 DEFUN (no_bgp_distance_source_access_list
,
9876 no_bgp_distance_source_access_list_cmd
,
9877 "no distance (1-255) A.B.C.D/M WORD",
9879 "Define an administrative distance\n"
9880 "Administrative distance\n"
9881 "IP source prefix\n"
9882 "Access list name\n")
9885 int idx_ipv4_prefixlen
= 3;
9887 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9891 DEFUN (ipv6_bgp_distance_source
,
9892 ipv6_bgp_distance_source_cmd
,
9893 "distance (1-255) X:X::X:X/M",
9894 "Define an administrative distance\n"
9895 "Administrative distance\n"
9896 "IP source prefix\n")
9898 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
9902 DEFUN (no_ipv6_bgp_distance_source
,
9903 no_ipv6_bgp_distance_source_cmd
,
9904 "no distance (1-255) X:X::X:X/M",
9906 "Define an administrative distance\n"
9907 "Administrative distance\n"
9908 "IP source prefix\n")
9910 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
9914 DEFUN (ipv6_bgp_distance_source_access_list
,
9915 ipv6_bgp_distance_source_access_list_cmd
,
9916 "distance (1-255) X:X::X:X/M WORD",
9917 "Define an administrative distance\n"
9918 "Administrative distance\n"
9919 "IP source prefix\n"
9920 "Access list name\n")
9922 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
9926 DEFUN (no_ipv6_bgp_distance_source_access_list
,
9927 no_ipv6_bgp_distance_source_access_list_cmd
,
9928 "no distance (1-255) X:X::X:X/M WORD",
9930 "Define an administrative distance\n"
9931 "Administrative distance\n"
9932 "IP source prefix\n"
9933 "Access list name\n")
9935 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
9939 DEFUN (bgp_damp_set
,
9941 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
9942 "BGP Specific commands\n"
9943 "Enable route-flap dampening\n"
9944 "Half-life time for the penalty\n"
9945 "Value to start reusing a route\n"
9946 "Value to start suppressing a route\n"
9947 "Maximum duration to suppress a stable route\n")
9949 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9950 int idx_half_life
= 2;
9952 int idx_suppress
= 4;
9953 int idx_max_suppress
= 5;
9954 int half
= DEFAULT_HALF_LIFE
* 60;
9955 int reuse
= DEFAULT_REUSE
;
9956 int suppress
= DEFAULT_SUPPRESS
;
9961 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
9962 reuse
= atoi (argv
[idx_reuse
]->arg
);
9963 suppress
= atoi (argv
[idx_suppress
]->arg
);
9964 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
9968 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
9972 if (suppress
< reuse
)
9974 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
9979 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
9980 half
, reuse
, suppress
, max
);
9983 DEFUN (bgp_damp_unset
,
9985 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
9987 "BGP Specific commands\n"
9988 "Enable route-flap dampening\n"
9989 "Half-life time for the penalty\n"
9990 "Value to start reusing a route\n"
9991 "Value to start suppressing a route\n"
9992 "Maximum duration to suppress a stable route\n")
9994 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9995 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
9998 /* Display specified route of BGP table. */
10000 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10001 const char *ip_str
, afi_t afi
, safi_t safi
,
10002 struct prefix_rd
*prd
, int prefix_check
)
10005 struct prefix match
;
10006 struct bgp_node
*rn
;
10007 struct bgp_node
*rm
;
10008 struct bgp_info
*ri
;
10009 struct bgp_info
*ri_temp
;
10011 struct bgp_table
*table
;
10013 /* BGP structure lookup. */
10016 bgp
= bgp_lookup_by_name (view_name
);
10019 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10020 return CMD_WARNING
;
10025 bgp
= bgp_get_default ();
10028 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10029 return CMD_WARNING
;
10033 /* Check IP address argument. */
10034 ret
= str2prefix (ip_str
, &match
);
10037 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10038 return CMD_WARNING
;
10041 match
.family
= afi2family (afi
);
10043 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10045 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10047 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10050 if ((table
= rn
->info
) != NULL
)
10051 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10053 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10058 if (ri
->extra
&& ri
->extra
->damp_info
)
10060 ri_temp
= ri
->next
;
10061 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10069 bgp_unlock_node (rm
);
10075 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10077 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10082 if (ri
->extra
&& ri
->extra
->damp_info
)
10084 ri_temp
= ri
->next
;
10085 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10093 bgp_unlock_node (rn
);
10097 return CMD_SUCCESS
;
10100 DEFUN (clear_ip_bgp_dampening
,
10101 clear_ip_bgp_dampening_cmd
,
10102 "clear ip bgp dampening",
10106 "Clear route flap dampening information\n")
10108 bgp_damp_info_clean ();
10109 return CMD_SUCCESS
;
10112 DEFUN (clear_ip_bgp_dampening_prefix
,
10113 clear_ip_bgp_dampening_prefix_cmd
,
10114 "clear ip bgp dampening A.B.C.D/M",
10118 "Clear route flap dampening information\n"
10121 int idx_ipv4_prefixlen
= 4;
10122 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10123 SAFI_UNICAST
, NULL
, 1);
10126 DEFUN (clear_ip_bgp_dampening_address
,
10127 clear_ip_bgp_dampening_address_cmd
,
10128 "clear ip bgp dampening A.B.C.D",
10132 "Clear route flap dampening information\n"
10133 "Network to clear damping information\n")
10136 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10137 SAFI_UNICAST
, NULL
, 0);
10140 DEFUN (clear_ip_bgp_dampening_address_mask
,
10141 clear_ip_bgp_dampening_address_mask_cmd
,
10142 "clear ip bgp dampening A.B.C.D A.B.C.D",
10146 "Clear route flap dampening information\n"
10147 "Network to clear damping information\n"
10151 int idx_ipv4_2
= 5;
10153 char prefix_str
[BUFSIZ
];
10155 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10158 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10159 return CMD_WARNING
;
10162 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10163 SAFI_UNICAST
, NULL
, 0);
10166 /* also used for encap safi */
10168 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10169 afi_t afi
, safi_t safi
, int *write
)
10171 struct bgp_node
*prn
;
10172 struct bgp_node
*rn
;
10173 struct bgp_table
*table
;
10175 struct prefix_rd
*prd
;
10176 struct bgp_static
*bgp_static
;
10178 char buf
[SU_ADDRSTRLEN
];
10179 char rdbuf
[RD_ADDRSTRLEN
];
10181 /* Network configuration. */
10182 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10183 if ((table
= prn
->info
) != NULL
)
10184 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10185 if ((bgp_static
= rn
->info
) != NULL
)
10188 prd
= (struct prefix_rd
*) &prn
->p
;
10190 /* "address-family" display. */
10191 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10193 /* "network" configuration display. */
10194 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10195 label
= decode_label (bgp_static
->tag
);
10197 vty_out (vty
, " network %s/%d rd %s tag %d",
10198 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10201 vty_out (vty
, "%s", VTY_NEWLINE
);
10206 /* Configuration of static route announcement and aggregate
10209 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10210 afi_t afi
, safi_t safi
, int *write
)
10212 struct bgp_node
*rn
;
10214 struct bgp_static
*bgp_static
;
10215 struct bgp_aggregate
*bgp_aggregate
;
10216 char buf
[SU_ADDRSTRLEN
];
10218 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10219 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10221 /* Network configuration. */
10222 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10223 if ((bgp_static
= rn
->info
) != NULL
)
10227 /* "address-family" display. */
10228 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10230 /* "network" configuration display. */
10231 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10233 u_int32_t destination
;
10234 struct in_addr netmask
;
10236 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10237 masklen2ip (p
->prefixlen
, &netmask
);
10238 vty_out (vty
, " network %s",
10239 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10241 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10242 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10243 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10244 || p
->u
.prefix4
.s_addr
== 0)
10246 /* Natural mask is not display. */
10249 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10253 vty_out (vty
, " network %s/%d",
10254 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10258 if (bgp_static
->rmap
.name
)
10259 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10262 if (bgp_static
->backdoor
)
10263 vty_out (vty
, " backdoor");
10266 vty_out (vty
, "%s", VTY_NEWLINE
);
10269 /* Aggregate-address configuration. */
10270 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10271 if ((bgp_aggregate
= rn
->info
) != NULL
)
10275 /* "address-family" display. */
10276 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10278 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10280 struct in_addr netmask
;
10282 masklen2ip (p
->prefixlen
, &netmask
);
10283 vty_out (vty
, " aggregate-address %s %s",
10284 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10285 inet_ntoa (netmask
));
10289 vty_out (vty
, " aggregate-address %s/%d",
10290 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10294 if (bgp_aggregate
->as_set
)
10295 vty_out (vty
, " as-set");
10297 if (bgp_aggregate
->summary_only
)
10298 vty_out (vty
, " summary-only");
10300 vty_out (vty
, "%s", VTY_NEWLINE
);
10307 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10308 safi_t safi
, int *write
)
10310 struct bgp_node
*rn
;
10311 struct bgp_distance
*bdistance
;
10313 /* Distance configuration. */
10314 if (bgp
->distance_ebgp
[afi
][safi
]
10315 && bgp
->distance_ibgp
[afi
][safi
]
10316 && bgp
->distance_local
[afi
][safi
]
10317 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10318 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10319 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10321 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10322 vty_out (vty
, " distance bgp %d %d %d%s",
10323 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10324 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10327 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10328 rn
= bgp_route_next (rn
))
10329 if ((bdistance
= rn
->info
) != NULL
)
10331 char buf
[PREFIX_STRLEN
];
10333 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10334 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10335 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10336 bdistance
->access_list
? bdistance
->access_list
: "",
10343 /* Allocate routing table structure and install commands. */
10345 bgp_route_init (void)
10350 /* Init BGP distance table. */
10351 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10352 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10353 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10355 /* IPv4 BGP commands. */
10356 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10357 install_element (BGP_NODE
, &bgp_network_cmd
);
10358 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10359 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10360 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10361 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10362 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10363 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10364 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10365 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10366 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10367 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10368 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10369 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10371 install_element (BGP_NODE
, &aggregate_address_cmd
);
10372 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10373 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10374 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10376 /* IPv4 unicast configuration. */
10377 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10378 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10379 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10380 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10381 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10382 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10383 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10384 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10385 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10386 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10387 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10389 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10390 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10391 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10392 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10394 /* IPv4 multicast configuration. */
10395 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10396 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10397 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10398 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10399 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10400 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10401 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10402 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10403 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10404 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10405 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10406 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10407 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10408 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10409 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10411 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10412 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10413 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10414 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10416 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10417 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10418 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10419 #ifdef KEEP_OLD_VPN_COMMANDS
10420 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10421 #endif /* KEEP_OLD_VPN_COMMANDS */
10422 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10424 /* BGP dampening clear commands */
10425 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10426 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10428 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10429 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10432 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10433 #ifdef KEEP_OLD_VPN_COMMANDS
10434 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10435 #endif /* KEEP_OLD_VPN_COMMANDS */
10437 /* New config IPv6 BGP commands. */
10438 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10439 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10440 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10441 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10442 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10444 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10445 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10447 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10448 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10450 install_element (BGP_NODE
, &bgp_distance_cmd
);
10451 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10452 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10453 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10454 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10455 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10456 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10457 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10458 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10459 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10460 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10461 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10462 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10463 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10464 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10465 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10466 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10467 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10468 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10469 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10470 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10471 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10472 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10473 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10474 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10475 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10476 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10477 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10478 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10479 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10481 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10482 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10483 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10484 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10486 /* IPv4 Multicast Mode */
10487 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10488 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10490 /* Large Communities */
10491 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
10492 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
10496 bgp_route_finish (void)
10501 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10502 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10504 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10505 bgp_distance_table
[afi
][safi
] = NULL
;