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"
71 #include "bgpd/bgp_encap_types.h"
72 #include "bgpd/bgp_encap_tlv.h"
73 #include "bgpd/bgp_evpn.h"
74 #include "bgpd/bgp_evpn_vty.h"
77 /* Extern from bgp_dump.c */
78 extern const char *bgp_origin_str
[];
79 extern const char *bgp_origin_long_str
[];
82 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
83 struct prefix_rd
*prd
)
86 struct bgp_node
*prn
= NULL
;
92 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
95 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
97 if (prn
->info
== NULL
)
98 prn
->info
= bgp_table_init (afi
, safi
);
100 bgp_unlock_node (prn
);
104 rn
= bgp_node_get (table
, p
);
106 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
113 /* Allocate bgp_info_extra */
114 static struct bgp_info_extra
*
115 bgp_info_extra_new (void)
117 struct bgp_info_extra
*new;
118 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
123 bgp_info_extra_free (struct bgp_info_extra
**extra
)
127 if ((*extra
)->damp_info
)
128 bgp_damp_info_free ((*extra
)->damp_info
, 0);
130 (*extra
)->damp_info
= NULL
;
132 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
138 /* Get bgp_info extra information for the given bgp_info, lazy allocated
141 struct bgp_info_extra
*
142 bgp_info_extra_get (struct bgp_info
*ri
)
145 ri
->extra
= bgp_info_extra_new();
149 /* Allocate new bgp info structure. */
153 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
156 /* Free bgp route information. */
158 bgp_info_free (struct bgp_info
*binfo
)
161 bgp_attr_unintern (&binfo
->attr
);
163 bgp_unlink_nexthop(binfo
);
164 bgp_info_extra_free (&binfo
->extra
);
165 bgp_info_mpath_free (&binfo
->mpath
);
167 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
169 XFREE (MTYPE_BGP_ROUTE
, binfo
);
173 bgp_info_lock (struct bgp_info
*binfo
)
180 bgp_info_unlock (struct bgp_info
*binfo
)
182 assert (binfo
&& binfo
->lock
> 0);
185 if (binfo
->lock
== 0)
188 zlog_debug ("%s: unlocked and freeing", __func__
);
189 zlog_backtrace (LOG_DEBUG
);
191 bgp_info_free (binfo
);
196 if (binfo
->lock
== 1)
198 zlog_debug ("%s: unlocked to 1", __func__
);
199 zlog_backtrace (LOG_DEBUG
);
207 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
209 struct bgp_info
*top
;
221 peer_lock (ri
->peer
); /* bgp_info peer reference */
224 /* Do the actual removal of info from RIB, for use by bgp_process
225 completion callback *only* */
227 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
230 ri
->next
->prev
= ri
->prev
;
232 ri
->prev
->next
= ri
->next
;
236 bgp_info_mpath_dequeue (ri
);
237 bgp_info_unlock (ri
);
238 bgp_unlock_node (rn
);
242 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
244 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
245 /* set of previous already took care of pcount */
246 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
249 /* undo the effects of a previous call to bgp_info_delete; typically
250 called when a route is deleted and then quickly re-added before the
251 deletion has been processed */
253 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
255 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
256 /* unset of previous already took care of pcount */
257 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
260 /* Adjust pcount as required */
262 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
264 struct bgp_table
*table
;
266 assert (rn
&& bgp_node_table (rn
));
267 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
269 table
= bgp_node_table (rn
);
271 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
274 if (!BGP_INFO_COUNTABLE (ri
)
275 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
278 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
280 /* slight hack, but more robust against errors. */
281 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
282 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
285 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
286 __func__
, ri
->peer
->host
);
287 zlog_backtrace (LOG_WARNING
);
288 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
291 else if (BGP_INFO_COUNTABLE (ri
)
292 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
294 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
295 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
300 /* Set/unset bgp_info flags, adjusting any other state as needed.
301 * This is here primarily to keep prefix-count in check.
304 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
306 SET_FLAG (ri
->flags
, flag
);
308 /* early bath if we know it's not a flag that changes countability state */
309 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
312 bgp_pcount_adjust (rn
, ri
);
316 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
318 UNSET_FLAG (ri
->flags
, flag
);
320 /* early bath if we know it's not a flag that changes countability state */
321 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
324 bgp_pcount_adjust (rn
, ri
);
327 /* Get MED value. If MED value is missing and "bgp bestpath
328 missing-as-worst" is specified, treat it as the worst value. */
330 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
332 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
336 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
344 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
346 if (ri
->addpath_rx_id
)
347 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
349 sprintf(buf
, "path %s", ri
->peer
->host
);
352 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
354 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
355 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
358 struct attr
*newattr
, *existattr
;
359 struct attr_extra
*newattre
, *existattre
;
360 bgp_peer_sort_t new_sort
;
361 bgp_peer_sort_t exist_sort
;
363 u_int32_t exist_pref
;
366 u_int32_t new_weight
;
367 u_int32_t exist_weight
;
368 uint32_t newm
, existm
;
369 struct in_addr new_id
;
370 struct in_addr exist_id
;
373 int internal_as_route
;
376 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
377 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
385 zlog_debug("%s: new is NULL", pfx_buf
);
390 bgp_info_path_with_addpath_rx_str (new, new_buf
);
395 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
401 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
402 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
403 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
407 existattr
= exist
->attr
;
408 newattre
= newattr
->extra
;
409 existattre
= existattr
->extra
;
411 /* 1. Weight check. */
412 new_weight
= exist_weight
= 0;
415 new_weight
= newattre
->weight
;
417 exist_weight
= existattre
->weight
;
419 if (new_weight
> exist_weight
)
422 zlog_debug("%s: %s wins over %s due to weight %d > %d",
423 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
427 if (new_weight
< exist_weight
)
430 zlog_debug("%s: %s loses to %s due to weight %d < %d",
431 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
435 /* 2. Local preference check. */
436 new_pref
= exist_pref
= bgp
->default_local_pref
;
438 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
439 new_pref
= newattr
->local_pref
;
440 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
441 exist_pref
= existattr
->local_pref
;
443 if (new_pref
> exist_pref
)
446 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
447 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
451 if (new_pref
< exist_pref
)
454 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
455 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
459 /* 3. Local route check. We prefer:
461 * - BGP_ROUTE_AGGREGATE
462 * - BGP_ROUTE_REDISTRIBUTE
464 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
467 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
468 pfx_buf
, new_buf
, exist_buf
);
472 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
475 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
476 pfx_buf
, new_buf
, exist_buf
);
480 /* 4. AS path length check. */
481 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
483 int exist_hops
= aspath_count_hops (existattr
->aspath
);
484 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
486 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
490 aspath_hops
= aspath_count_hops (newattr
->aspath
);
491 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
493 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
496 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
497 pfx_buf
, new_buf
, exist_buf
,
498 aspath_hops
, (exist_hops
+ exist_confeds
));
502 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
505 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
506 pfx_buf
, new_buf
, exist_buf
,
507 aspath_hops
, (exist_hops
+ exist_confeds
));
513 int newhops
= aspath_count_hops (newattr
->aspath
);
515 if (newhops
< exist_hops
)
518 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
519 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
523 if (newhops
> exist_hops
)
526 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
527 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
533 /* 5. Origin check. */
534 if (newattr
->origin
< existattr
->origin
)
537 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
538 pfx_buf
, new_buf
, exist_buf
,
539 bgp_origin_long_str
[newattr
->origin
],
540 bgp_origin_long_str
[existattr
->origin
]);
544 if (newattr
->origin
> existattr
->origin
)
547 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
548 pfx_buf
, new_buf
, exist_buf
,
549 bgp_origin_long_str
[newattr
->origin
],
550 bgp_origin_long_str
[existattr
->origin
]);
555 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
556 && aspath_count_hops (existattr
->aspath
) == 0);
557 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
558 && aspath_count_confeds (existattr
->aspath
) > 0
559 && aspath_count_hops (newattr
->aspath
) == 0
560 && aspath_count_hops (existattr
->aspath
) == 0);
562 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
563 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
565 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
566 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
567 || internal_as_route
)
569 new_med
= bgp_med_value (new->attr
, bgp
);
570 exist_med
= bgp_med_value (exist
->attr
, bgp
);
572 if (new_med
< exist_med
)
575 zlog_debug("%s: %s wins over %s due to MED %d < %d",
576 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
580 if (new_med
> exist_med
)
583 zlog_debug("%s: %s loses to %s due to MED %d > %d",
584 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
589 /* 7. Peer type check. */
590 new_sort
= new->peer
->sort
;
591 exist_sort
= exist
->peer
->sort
;
593 if (new_sort
== BGP_PEER_EBGP
594 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
597 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
598 pfx_buf
, new_buf
, exist_buf
);
602 if (exist_sort
== BGP_PEER_EBGP
603 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
606 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
607 pfx_buf
, new_buf
, exist_buf
);
611 /* 8. IGP metric check. */
615 newm
= new->extra
->igpmetric
;
617 existm
= exist
->extra
->igpmetric
;
622 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
623 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
630 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
631 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
635 /* 9. Same IGP metric. Compare the cluster list length as
636 representative of IGP hops metric. Rewrite the metric value
637 pair (newm, existm) with the cluster list length. Prefer the
638 path with smaller cluster list length. */
641 if (peer_sort (new->peer
) == BGP_PEER_IBGP
642 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
643 && (mpath_cfg
== NULL
||
644 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
645 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
647 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
648 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
653 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
654 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
661 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
662 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
668 /* 10. confed-external vs. confed-internal */
669 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
671 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
674 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
675 pfx_buf
, new_buf
, exist_buf
);
679 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
682 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
683 pfx_buf
, new_buf
, exist_buf
);
688 /* 11. Maximum path check. */
691 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
695 * For the two paths, all comparison steps till IGP metric
696 * have succeeded - including AS_PATH hop count. Since 'bgp
697 * bestpath as-path multipath-relax' knob is on, we don't need
698 * an exact match of AS_PATH. Thus, mark the paths are equal.
699 * That will trigger both these paths to get into the multipath
705 zlog_debug("%s: %s and %s are equal via multipath-relax",
706 pfx_buf
, new_buf
, exist_buf
);
708 else if (new->peer
->sort
== BGP_PEER_IBGP
)
710 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
715 zlog_debug("%s: %s and %s are equal via matching aspaths",
716 pfx_buf
, new_buf
, exist_buf
);
719 else if (new->peer
->as
== exist
->peer
->as
)
724 zlog_debug("%s: %s and %s are equal via same remote-as",
725 pfx_buf
, new_buf
, exist_buf
);
731 * TODO: If unequal cost ibgp multipath is enabled we can
732 * mark the paths as equal here instead of returning
737 zlog_debug("%s: %s wins over %s after IGP metric comparison",
738 pfx_buf
, new_buf
, exist_buf
);
740 zlog_debug("%s: %s loses to %s after IGP metric comparison",
741 pfx_buf
, new_buf
, exist_buf
);
746 /* 12. If both paths are external, prefer the path that was received
747 first (the oldest one). This step minimizes route-flap, since a
748 newer path won't displace an older one, even if it was the
749 preferred route based on the additional decision criteria below. */
750 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
751 && new_sort
== BGP_PEER_EBGP
752 && exist_sort
== BGP_PEER_EBGP
)
754 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
757 zlog_debug("%s: %s wins over %s due to oldest external",
758 pfx_buf
, new_buf
, exist_buf
);
762 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
765 zlog_debug("%s: %s loses to %s due to oldest external",
766 pfx_buf
, new_buf
, exist_buf
);
771 /* 13. Router-ID comparision. */
772 /* If one of the paths is "stale", the corresponding peer router-id will
773 * be 0 and would always win over the other path. If originator id is
774 * used for the comparision, it will decide which path is better.
776 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
777 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
779 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
780 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
781 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
783 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
785 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
788 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
789 pfx_buf
, new_buf
, exist_buf
);
793 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
796 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
797 pfx_buf
, new_buf
, exist_buf
);
801 /* 14. Cluster length comparision. */
802 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
803 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
805 if (new_cluster
< exist_cluster
)
808 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
809 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
813 if (new_cluster
> exist_cluster
)
816 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
817 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
821 /* 15. Neighbor address comparision. */
822 /* Do this only if neither path is "stale" as stale paths do not have
823 * valid peer information (as the connection may or may not be up).
825 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
828 zlog_debug("%s: %s wins over %s due to latter path being STALE",
829 pfx_buf
, new_buf
, exist_buf
);
833 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
836 zlog_debug("%s: %s loses to %s due to former path being STALE",
837 pfx_buf
, new_buf
, exist_buf
);
841 /* locally configured routes to advertise do not have su_remote */
842 if (new->peer
->su_remote
== NULL
)
844 if (exist
->peer
->su_remote
== NULL
)
847 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
852 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
853 pfx_buf
, new_buf
, exist_buf
);
860 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
861 pfx_buf
, new_buf
, exist_buf
);
866 zlog_debug("%s: %s wins over %s due to nothing left to compare",
867 pfx_buf
, new_buf
, exist_buf
);
872 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
873 * is preferred, or 0 if they are the same (usually will only occur if
874 * multipath is enabled
875 * This version is compatible with */
877 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
878 afi_t afi
, safi_t safi
)
882 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
896 static enum filter_type
897 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
898 afi_t afi
, safi_t safi
)
900 struct bgp_filter
*filter
;
902 filter
= &peer
->filter
[afi
][safi
];
904 #define FILTER_EXIST_WARN(F,f,filter) \
905 if (BGP_DEBUG (update, UPDATE_IN) \
906 && !(F ## _IN (filter))) \
907 zlog_warn ("%s: Could not find configured input %s-list %s!", \
908 peer->host, #f, F ## _IN_NAME(filter));
910 if (DISTRIBUTE_IN_NAME (filter
)) {
911 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
913 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
917 if (PREFIX_LIST_IN_NAME (filter
)) {
918 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
920 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
924 if (FILTER_LIST_IN_NAME (filter
)) {
925 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
927 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
931 return FILTER_PERMIT
;
932 #undef FILTER_EXIST_WARN
935 static enum filter_type
936 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
937 afi_t afi
, safi_t safi
)
939 struct bgp_filter
*filter
;
941 filter
= &peer
->filter
[afi
][safi
];
943 #define FILTER_EXIST_WARN(F,f,filter) \
944 if (BGP_DEBUG (update, UPDATE_OUT) \
945 && !(F ## _OUT (filter))) \
946 zlog_warn ("%s: Could not find configured output %s-list %s!", \
947 peer->host, #f, F ## _OUT_NAME(filter));
949 if (DISTRIBUTE_OUT_NAME (filter
)) {
950 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
952 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
956 if (PREFIX_LIST_OUT_NAME (filter
)) {
957 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
959 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
963 if (FILTER_LIST_OUT_NAME (filter
)) {
964 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
966 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
970 return FILTER_PERMIT
;
971 #undef FILTER_EXIST_WARN
974 /* If community attribute includes no_export then return 1. */
976 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
980 /* NO_ADVERTISE check. */
981 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
984 /* NO_EXPORT check. */
985 if (peer
->sort
== BGP_PEER_EBGP
&&
986 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
989 /* NO_EXPORT_SUBCONFED check. */
990 if (peer
->sort
== BGP_PEER_EBGP
991 || peer
->sort
== BGP_PEER_CONFED
)
992 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
998 /* Route reflection loop check. */
1000 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1002 struct in_addr cluster_id
;
1004 if (attr
->extra
&& attr
->extra
->cluster
)
1006 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1007 cluster_id
= peer
->bgp
->cluster_id
;
1009 cluster_id
= peer
->bgp
->router_id
;
1011 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1018 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1019 afi_t afi
, safi_t safi
, const char *rmap_name
)
1021 struct bgp_filter
*filter
;
1022 struct bgp_info info
;
1023 route_map_result_t ret
;
1024 struct route_map
*rmap
= NULL
;
1026 filter
= &peer
->filter
[afi
][safi
];
1028 /* Apply default weight value. */
1029 if (peer
->weight
[afi
][safi
])
1030 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1034 rmap
= route_map_lookup_by_name(rmap_name
);
1041 if (ROUTE_MAP_IN_NAME(filter
))
1043 rmap
= ROUTE_MAP_IN (filter
);
1050 /* Route map apply. */
1053 /* Duplicate current value to new strucutre for modification. */
1057 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1059 /* Apply BGP route map to the attribute. */
1060 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1062 peer
->rmap_type
= 0;
1064 if (ret
== RMAP_DENYMATCH
)
1066 /* Free newly generated AS path and community by route-map. */
1067 bgp_attr_flush (attr
);
1075 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1076 afi_t afi
, safi_t safi
, const char *rmap_name
)
1078 struct bgp_filter
*filter
;
1079 struct bgp_info info
;
1080 route_map_result_t ret
;
1081 struct route_map
*rmap
= NULL
;
1083 filter
= &peer
->filter
[afi
][safi
];
1085 /* Apply default weight value. */
1086 if (peer
->weight
[afi
][safi
])
1087 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1091 rmap
= route_map_lookup_by_name(rmap_name
);
1098 if (ROUTE_MAP_OUT_NAME(filter
))
1100 rmap
= ROUTE_MAP_OUT (filter
);
1107 /* Route map apply. */
1110 /* Duplicate current value to new strucutre for modification. */
1114 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1116 /* Apply BGP route map to the attribute. */
1117 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1119 peer
->rmap_type
= 0;
1121 if (ret
== RMAP_DENYMATCH
)
1122 /* caller has multiple error paths with bgp_attr_flush() */
1128 /* If this is an EBGP peer with remove-private-AS */
1130 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1131 struct peer
*peer
, struct attr
*attr
)
1133 if (peer
->sort
== BGP_PEER_EBGP
&&
1134 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1135 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1136 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1137 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1139 // Take action on the entire aspath
1140 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1141 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1143 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1144 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1146 // The entire aspath consists of private ASNs so create an empty aspath
1147 else if (aspath_private_as_check (attr
->aspath
))
1148 attr
->aspath
= aspath_empty_get ();
1150 // There are some public and some private ASNs, remove the private ASNs
1152 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1155 // 'all' was not specified so the entire aspath must be private ASNs
1156 // for us to do anything
1157 else if (aspath_private_as_check (attr
->aspath
))
1159 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1160 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1162 attr
->aspath
= aspath_empty_get ();
1167 /* If this is an EBGP peer with as-override */
1169 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1170 struct peer
*peer
, struct attr
*attr
)
1172 if (peer
->sort
== BGP_PEER_EBGP
&&
1173 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1175 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1176 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1181 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1183 if (family
== AF_INET
)
1184 attr
->nexthop
.s_addr
= 0;
1185 if (family
== AF_INET6
)
1186 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1190 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1191 struct prefix
*p
, struct attr
*attr
)
1193 struct bgp_filter
*filter
;
1196 struct peer
*onlypeer
;
1198 struct attr
*riattr
;
1199 struct peer_af
*paf
;
1200 char buf
[PREFIX_STRLEN
];
1206 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1208 if (DISABLE_BGP_ANNOUNCE
)
1211 afi
= SUBGRP_AFI(subgrp
);
1212 safi
= SUBGRP_SAFI(subgrp
);
1213 peer
= SUBGRP_PEER(subgrp
);
1215 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1216 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1219 filter
= &peer
->filter
[afi
][safi
];
1220 bgp
= SUBGRP_INST(subgrp
);
1221 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1224 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1225 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1226 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1229 * direct and direct_ext type routes originate internally even
1230 * though they can have peer pointers that reference other systems
1232 prefix2str(p
, buf
, PREFIX_STRLEN
);
1233 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1238 /* With addpath we may be asked to TX all kinds of paths so make sure
1240 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1241 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1242 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1247 /* If this is not the bestpath then check to see if there is an enabled addpath
1248 * feature that requires us to advertise it */
1249 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1251 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1257 /* Aggregate-address suppress check. */
1258 if (ri
->extra
&& ri
->extra
->suppress
)
1259 if (! UNSUPPRESS_MAP_NAME (filter
))
1264 /* Do not send back route to sender. */
1265 if (onlypeer
&& from
== onlypeer
)
1270 /* Do not send the default route in the BGP table if the neighbor is
1271 * configured for default-originate */
1272 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1274 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1276 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1280 /* Transparency check. */
1281 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1282 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1287 /* If community is not disabled check the no-export and local. */
1288 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1290 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1291 zlog_debug ("subgrpannouncecheck: community filter check fail");
1295 /* If the attribute has originator-id and it is same as remote
1298 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1299 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1301 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1302 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1304 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1308 /* ORF prefix-list filter check */
1309 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1310 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1311 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1312 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1313 if (peer
->orf_plist
[afi
][safi
])
1315 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1317 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1318 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1319 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1324 /* Output filter check. */
1325 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1327 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1328 zlog_debug ("%s [Update:SEND] %s is filtered",
1329 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
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
)
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
)
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 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2281 struct attr_extra
*extra
;
2285 extra
= bgp_attr_extra_get(attr
);
2287 if(eth_s_id
== NULL
)
2289 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2293 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2297 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2301 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2306 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2308 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2309 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2312 if(afi
!= AFI_L2VPN
)
2314 if (!info
->attr
|| !info
->attr
->extra
)
2316 memset(&temp
, 0, 16);
2317 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2318 info_gw_ip
= (union gw_addr
*)&temp
;
2319 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2324 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2325 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2328 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2330 info_gw_ip_remote
= gw_ip
;
2331 if(eth_s_id
== NULL
)
2332 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2334 info_eth_s_id_remote
= eth_s_id
;
2335 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2337 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2340 /* Check if received nexthop is valid or not. */
2342 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2344 struct attr_extra
*attre
= attr
->extra
;
2347 /* Only validated for unicast and multicast currently. */
2348 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2351 /* If NEXT_HOP is present, validate it. */
2352 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2354 if (attr
->nexthop
.s_addr
== 0 ||
2355 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2356 bgp_nexthop_self (bgp
, attr
))
2360 /* If MP_NEXTHOP is present, validate it. */
2361 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2362 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2363 * it is not an IPv6 link-local address.
2365 if (attre
&& attre
->mp_nexthop_len
)
2367 switch (attre
->mp_nexthop_len
)
2369 case BGP_ATTR_NHLEN_IPV4
:
2370 case BGP_ATTR_NHLEN_VPNV4
:
2371 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2372 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2375 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2376 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2377 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2378 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2379 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2380 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2393 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2394 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2395 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2396 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2399 int aspath_loop_count
= 0;
2400 struct bgp_node
*rn
;
2402 struct attr new_attr
;
2403 struct attr_extra new_extra
;
2404 struct attr
*attr_new
;
2405 struct bgp_info
*ri
;
2406 struct bgp_info
*new;
2408 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2410 int do_loop_check
= 1;
2412 int vnc_implicit_withdraw
= 0;
2415 memset (&new_attr
, 0, sizeof(struct attr
));
2416 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2419 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2421 /* When peer's soft reconfiguration enabled. Record input packet in
2423 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2424 && peer
!= bgp
->peer_self
)
2425 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2427 /* Check previously received route. */
2428 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2429 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2430 ri
->addpath_rx_id
== addpath_id
)
2433 /* AS path local-as loop check. */
2434 if (peer
->change_local_as
)
2436 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2437 aspath_loop_count
= 1;
2439 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2441 reason
= "as-path contains our own AS;";
2446 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2447 * as-path is our ASN then we do not need to call aspath_loop_check
2449 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2450 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2453 /* AS path loop check. */
2456 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2457 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2458 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2460 reason
= "as-path contains our own AS;";
2465 /* Route reflector originator ID check. */
2466 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2467 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2469 reason
= "originator is us;";
2473 /* Route reflector cluster ID check. */
2474 if (bgp_cluster_filter (peer
, attr
))
2476 reason
= "reflected from the same cluster;";
2480 /* Apply incoming filter. */
2481 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2487 new_attr
.extra
= &new_extra
;
2488 bgp_attr_dup (&new_attr
, attr
);
2490 /* Apply incoming route-map.
2491 * NB: new_attr may now contain newly allocated values from route-map "set"
2492 * commands, so we need bgp_attr_flush in the error paths, until we intern
2493 * the attr (which takes over the memory references) */
2494 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2496 reason
= "route-map;";
2497 bgp_attr_flush (&new_attr
);
2501 /* next hop check. */
2502 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2504 reason
= "martian or self next-hop;";
2505 bgp_attr_flush (&new_attr
);
2509 attr_new
= bgp_attr_intern (&new_attr
);
2511 /* If the update is implicit withdraw. */
2514 ri
->uptime
= bgp_clock ();
2516 /* Same attribute comes in. */
2517 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2518 && attrhash_cmp (ri
->attr
, attr_new
)
2519 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2520 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2522 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2523 && peer
->sort
== BGP_PEER_EBGP
2524 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2526 if (bgp_debug_update(peer
, p
, NULL
, 1))
2527 zlog_debug ("%s rcvd %s", peer
->host
,
2528 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2529 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2531 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2533 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2534 bgp_process (bgp
, rn
, afi
, safi
);
2537 else /* Duplicate - odd */
2539 if (bgp_debug_update(peer
, p
, NULL
, 1))
2541 if (!peer
->rcvd_attr_printed
)
2543 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2544 peer
->rcvd_attr_printed
= 1;
2547 zlog_debug ("%s rcvd %s...duplicate ignored",
2549 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2550 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2553 /* graceful restart STALE flag unset. */
2554 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2556 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2557 bgp_process (bgp
, rn
, afi
, safi
);
2561 bgp_unlock_node (rn
);
2562 bgp_attr_unintern (&attr_new
);
2567 /* Withdraw/Announce before we fully processed the withdraw */
2568 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2570 if (bgp_debug_update(peer
, p
, NULL
, 1))
2571 zlog_debug ("%s rcvd %s, flapped quicker than processing",
2573 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2574 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2575 bgp_info_restore (rn
, ri
);
2578 /* Received Logging. */
2579 if (bgp_debug_update(peer
, p
, NULL
, 1))
2580 zlog_debug ("%s rcvd %s", peer
->host
,
2581 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2582 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2584 /* graceful restart STALE flag unset. */
2585 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2586 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2588 /* The attribute is changed. */
2589 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2591 /* implicit withdraw, decrement aggregate and pcount here.
2592 * only if update is accepted, they'll increment below.
2594 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2596 /* Update bgp route dampening information. */
2597 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2598 && peer
->sort
== BGP_PEER_EBGP
)
2600 /* This is implicit withdraw so we should update dampening
2602 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2603 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2606 if (safi
== SAFI_MPLS_VPN
) {
2607 struct bgp_node
*prn
= NULL
;
2608 struct bgp_table
*table
= NULL
;
2610 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2612 table
= (struct bgp_table
*)(prn
->info
);
2614 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2621 bgp_unlock_node(prn
);
2623 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2624 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2626 * Implicit withdraw case.
2628 ++vnc_implicit_withdraw
;
2629 vnc_import_bgp_del_route(bgp
, p
, ri
);
2630 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2635 /* Update to new attribute. */
2636 bgp_attr_unintern (&ri
->attr
);
2637 ri
->attr
= attr_new
;
2639 /* Update MPLS tag. */
2640 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2641 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2644 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2646 if (vnc_implicit_withdraw
)
2649 * Add back the route with its new attributes (e.g., nexthop).
2650 * The route is still selected, until the route selection
2651 * queued by bgp_process actually runs. We have to make this
2652 * update to the VNC side immediately to avoid racing against
2653 * configuration changes (e.g., route-map changes) which
2654 * trigger re-importation of the entire RIB.
2656 vnc_import_bgp_add_route(bgp
, p
, ri
);
2657 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2661 /* Update Overlay Index */
2662 if(afi
== AFI_L2VPN
)
2664 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2665 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2668 /* Update bgp route dampening information. */
2669 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2670 && peer
->sort
== BGP_PEER_EBGP
)
2672 /* Now we do normal update dampening. */
2673 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2674 if (ret
== BGP_DAMP_SUPPRESSED
)
2676 bgp_unlock_node (rn
);
2681 /* Nexthop reachability check. */
2682 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2684 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2685 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2686 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2691 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2692 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2695 if (BGP_DEBUG(nht
, NHT
))
2697 char buf1
[INET6_ADDRSTRLEN
];
2698 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2699 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2701 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2705 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2708 if (safi
== SAFI_MPLS_VPN
)
2710 struct bgp_node
*prn
= NULL
;
2711 struct bgp_table
*table
= NULL
;
2713 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2716 table
= (struct bgp_table
*)(prn
->info
);
2718 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2725 bgp_unlock_node(prn
);
2729 /* Process change. */
2730 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2732 bgp_process (bgp
, rn
, afi
, safi
);
2733 bgp_unlock_node (rn
);
2736 if (SAFI_MPLS_VPN
== safi
)
2738 uint32_t label
= decode_label(tag
);
2740 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2743 if (SAFI_ENCAP
== safi
)
2745 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2751 } // End of implicit withdraw
2753 /* Received Logging. */
2754 if (bgp_debug_update(peer
, p
, NULL
, 1))
2756 if (!peer
->rcvd_attr_printed
)
2758 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2759 peer
->rcvd_attr_printed
= 1;
2762 zlog_debug ("%s rcvd %s", peer
->host
,
2763 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2764 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2767 /* Make new BGP info. */
2768 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2770 /* Update MPLS tag. */
2771 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2772 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2774 /* Update Overlay Index */
2775 if(afi
== AFI_L2VPN
)
2777 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2778 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2780 /* Nexthop reachability check. */
2781 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2783 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2784 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2785 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2790 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2791 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2794 if (BGP_DEBUG(nht
, NHT
))
2796 char buf1
[INET6_ADDRSTRLEN
];
2797 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2798 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2800 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2804 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2807 new->addpath_rx_id
= addpath_id
;
2809 /* Increment prefix */
2810 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2812 /* Register new BGP information. */
2813 bgp_info_add (rn
, new);
2815 /* route_node_get lock */
2816 bgp_unlock_node (rn
);
2819 if (safi
== SAFI_MPLS_VPN
)
2821 struct bgp_node
*prn
= NULL
;
2822 struct bgp_table
*table
= NULL
;
2824 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2827 table
= (struct bgp_table
*)(prn
->info
);
2829 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2836 bgp_unlock_node(prn
);
2840 /* If maximum prefix count is configured and current prefix
2842 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2845 /* Process change. */
2846 bgp_process (bgp
, rn
, afi
, safi
);
2849 if (SAFI_MPLS_VPN
== safi
)
2851 uint32_t label
= decode_label(tag
);
2853 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2856 if (SAFI_ENCAP
== safi
)
2858 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2865 /* This BGP update is filtered. Log the reason then update BGP
2868 if (bgp_debug_update(peer
, p
, NULL
, 1))
2870 if (!peer
->rcvd_attr_printed
)
2872 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2873 peer
->rcvd_attr_printed
= 1;
2876 zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
2878 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2879 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), reason
);
2883 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2885 bgp_unlock_node (rn
);
2889 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2890 * a few lines above)
2892 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2894 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2902 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2903 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2904 struct prefix_rd
*prd
, u_char
*tag
, struct bgp_route_evpn
*evpn
)
2907 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2908 struct bgp_node
*rn
;
2909 struct bgp_info
*ri
;
2912 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2914 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2921 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2923 /* If peer is soft reconfiguration enabled. Record input packet for
2924 * further calculation.
2926 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2927 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2928 * the iteration over all RS clients.
2929 * Since we need to remove the entry from adj_in anyway, do that first and
2930 * if there was no entry, we don't need to do anything more.
2932 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2933 && peer
!= bgp
->peer_self
)
2934 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2936 if (bgp_debug_update (peer
, p
, NULL
, 1))
2937 zlog_debug ("%s withdrawing route %s not in adj-in",
2939 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2940 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2941 bgp_unlock_node (rn
);
2945 /* Lookup withdrawn route. */
2946 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2947 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2948 ri
->addpath_rx_id
== addpath_id
)
2952 if (bgp_debug_update(peer
, p
, NULL
, 1))
2954 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
2956 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2957 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2960 /* Withdraw specified route from routing table. */
2961 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2962 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2963 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2964 zlog_debug ("%s Can't find the route %s",
2966 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2967 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2969 /* Unlock bgp_node_get() lock. */
2970 bgp_unlock_node (rn
);
2976 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2978 struct update_subgroup
*subgrp
;
2979 subgrp
= peer_subgroup(peer
, afi
, safi
);
2980 subgroup_default_originate(subgrp
, withdraw
);
2985 * bgp_stop_announce_route_timer
2988 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2990 if (!paf
->t_announce_route
)
2993 THREAD_TIMER_OFF (paf
->t_announce_route
);
2997 * bgp_announce_route_timer_expired
2999 * Callback that is invoked when the route announcement timer for a
3003 bgp_announce_route_timer_expired (struct thread
*t
)
3005 struct peer_af
*paf
;
3008 paf
= THREAD_ARG (t
);
3011 assert (paf
->t_announce_route
);
3012 paf
->t_announce_route
= NULL
;
3014 if (peer
->status
!= Established
)
3017 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3020 peer_af_announce_route (paf
, 1);
3025 * bgp_announce_route
3027 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3030 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3032 struct peer_af
*paf
;
3033 struct update_subgroup
*subgrp
;
3035 paf
= peer_af_find (peer
, afi
, safi
);
3038 subgrp
= PAF_SUBGRP(paf
);
3041 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3042 * or a refresh has already been triggered.
3044 if (!subgrp
|| paf
->t_announce_route
)
3048 * Start a timer to stagger/delay the announce. This serves
3049 * two purposes - announcement can potentially be combined for
3050 * multiple peers and the announcement doesn't happen in the
3053 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
3054 bgp_announce_route_timer_expired
, paf
,
3055 (subgrp
->peer_count
== 1) ?
3056 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
3057 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
3061 * Announce routes from all AF tables to a peer.
3063 * This should ONLY be called when there is a need to refresh the
3064 * routes to the peer based on a policy change for this peer alone
3065 * or a route refresh request received from the peer.
3066 * The operation will result in splitting the peer from its existing
3067 * subgroups and putting it in new subgroups.
3070 bgp_announce_route_all (struct peer
*peer
)
3075 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3076 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3077 bgp_announce_route (peer
, afi
, safi
);
3081 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3082 struct bgp_table
*table
, struct prefix_rd
*prd
)
3085 struct bgp_node
*rn
;
3086 struct bgp_adj_in
*ain
;
3089 table
= peer
->bgp
->rib
[afi
][safi
];
3091 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3092 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3094 if (ain
->peer
== peer
)
3096 struct bgp_info
*ri
= rn
->info
;
3097 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3099 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3100 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3105 bgp_unlock_node (rn
);
3113 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3115 struct bgp_node
*rn
;
3116 struct bgp_table
*table
;
3118 if (peer
->status
!= Established
)
3121 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3122 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3124 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3125 rn
= bgp_route_next (rn
))
3126 if ((table
= rn
->info
) != NULL
)
3128 struct prefix_rd prd
;
3129 prd
.family
= AF_UNSPEC
;
3131 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3133 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3138 struct bgp_clear_node_queue
3140 struct bgp_node
*rn
;
3143 static wq_item_status
3144 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3146 struct bgp_clear_node_queue
*cnq
= data
;
3147 struct bgp_node
*rn
= cnq
->rn
;
3148 struct peer
*peer
= wq
->spec
.data
;
3149 struct bgp_info
*ri
;
3150 afi_t afi
= bgp_node_table (rn
)->afi
;
3151 safi_t safi
= bgp_node_table (rn
)->safi
;
3153 assert (rn
&& peer
);
3155 /* It is possible that we have multiple paths for a prefix from a peer
3156 * if that peer is using AddPath.
3158 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3159 if (ri
->peer
== peer
)
3161 /* graceful restart STALE flag set. */
3162 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3163 && peer
->nsf
[afi
][safi
]
3164 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3165 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3166 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3168 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3174 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3176 struct bgp_clear_node_queue
*cnq
= data
;
3177 struct bgp_node
*rn
= cnq
->rn
;
3178 struct bgp_table
*table
= bgp_node_table (rn
);
3180 bgp_unlock_node (rn
);
3181 bgp_table_unlock (table
);
3182 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3186 bgp_clear_node_complete (struct work_queue
*wq
)
3188 struct peer
*peer
= wq
->spec
.data
;
3190 /* Tickle FSM to start moving again */
3191 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3193 peer_unlock (peer
); /* bgp_clear_route */
3197 bgp_clear_node_queue_init (struct peer
*peer
)
3199 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3201 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3202 #undef CLEAR_QUEUE_NAME_LEN
3204 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3206 zlog_err ("%s: Failed to allocate work queue", __func__
);
3209 peer
->clear_node_queue
->spec
.hold
= 10;
3210 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3211 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3212 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3213 peer
->clear_node_queue
->spec
.max_retries
= 0;
3215 /* we only 'lock' this peer reference when the queue is actually active */
3216 peer
->clear_node_queue
->spec
.data
= peer
;
3220 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3221 struct bgp_table
*table
)
3223 struct bgp_node
*rn
;
3224 int force
= bm
->process_main_queue
? 0 : 1;
3227 table
= peer
->bgp
->rib
[afi
][safi
];
3229 /* If still no table => afi/safi isn't configured at all or smth. */
3233 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3235 struct bgp_info
*ri
, *next
;
3236 struct bgp_adj_in
*ain
;
3237 struct bgp_adj_in
*ain_next
;
3239 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3240 * queued for every clearing peer, regardless of whether it is
3241 * relevant to the peer at hand.
3243 * Overview: There are 3 different indices which need to be
3244 * scrubbed, potentially, when a peer is removed:
3246 * 1 peer's routes visible via the RIB (ie accepted routes)
3247 * 2 peer's routes visible by the (optional) peer's adj-in index
3248 * 3 other routes visible by the peer's adj-out index
3250 * 3 there is no hurry in scrubbing, once the struct peer is
3251 * removed from bgp->peer, we could just GC such deleted peer's
3252 * adj-outs at our leisure.
3254 * 1 and 2 must be 'scrubbed' in some way, at least made
3255 * invisible via RIB index before peer session is allowed to be
3256 * brought back up. So one needs to know when such a 'search' is
3261 * - there'd be a single global queue or a single RIB walker
3262 * - rather than tracking which route_nodes still need to be
3263 * examined on a peer basis, we'd track which peers still
3266 * Given that our per-peer prefix-counts now should be reliable,
3267 * this may actually be achievable. It doesn't seem to be a huge
3268 * problem at this time,
3270 * It is possible that we have multiple paths for a prefix from a peer
3271 * if that peer is using AddPath.
3276 ain_next
= ain
->next
;
3278 if (ain
->peer
== peer
)
3280 bgp_adj_in_remove (rn
, ain
);
3281 bgp_unlock_node (rn
);
3287 for (ri
= rn
->info
; ri
; ri
= next
)
3290 if (ri
->peer
!= peer
)
3294 bgp_info_reap (rn
, ri
);
3297 struct bgp_clear_node_queue
*cnq
;
3299 /* both unlocked in bgp_clear_node_queue_del */
3300 bgp_table_lock (bgp_node_table (rn
));
3302 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3303 sizeof (struct bgp_clear_node_queue
));
3305 work_queue_add (peer
->clear_node_queue
, cnq
);
3314 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3316 struct bgp_node
*rn
;
3317 struct bgp_table
*table
;
3319 if (peer
->clear_node_queue
== NULL
)
3320 bgp_clear_node_queue_init (peer
);
3322 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3323 * Idle until it receives a Clearing_Completed event. This protects
3324 * against peers which flap faster than we can we clear, which could
3327 * a) race with routes from the new session being installed before
3328 * clear_route_node visits the node (to delete the route of that
3330 * b) resource exhaustion, clear_route_node likely leads to an entry
3331 * on the process_main queue. Fast-flapping could cause that queue
3335 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3336 * the unlock will happen upon work-queue completion; other wise, the
3337 * unlock happens at the end of this function.
3339 if (!peer
->clear_node_queue
->thread
)
3342 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3343 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3345 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3346 rn
= bgp_route_next (rn
))
3347 if ((table
= rn
->info
) != NULL
)
3348 bgp_clear_route_table (peer
, afi
, safi
, table
);
3350 /* unlock if no nodes got added to the clear-node-queue. */
3351 if (!peer
->clear_node_queue
->thread
)
3357 bgp_clear_route_all (struct peer
*peer
)
3362 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3363 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3364 bgp_clear_route (peer
, afi
, safi
);
3367 rfapiProcessPeerDown(peer
);
3372 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3374 struct bgp_table
*table
;
3375 struct bgp_node
*rn
;
3376 struct bgp_adj_in
*ain
;
3377 struct bgp_adj_in
*ain_next
;
3379 table
= peer
->bgp
->rib
[afi
][safi
];
3381 /* It is possible that we have multiple paths for a prefix from a peer
3382 * if that peer is using AddPath.
3384 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3390 ain_next
= ain
->next
;
3392 if (ain
->peer
== peer
)
3394 bgp_adj_in_remove (rn
, ain
);
3395 bgp_unlock_node (rn
);
3404 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3406 struct bgp_node
*rn
;
3407 struct bgp_info
*ri
;
3408 struct bgp_table
*table
;
3410 if ( safi
== SAFI_MPLS_VPN
)
3412 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3414 struct bgp_node
*rm
;
3415 struct bgp_info
*ri
;
3417 /* look for neighbor in tables */
3418 if ((table
= rn
->info
) != NULL
)
3420 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3421 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3422 if (ri
->peer
== peer
)
3424 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3425 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3433 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3434 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3435 if (ri
->peer
== peer
)
3437 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3438 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3445 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3447 struct bgp_node
*rn
;
3448 struct bgp_info
*ri
;
3449 struct bgp_info
*next
;
3451 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3452 for (ri
= rn
->info
; ri
; ri
= next
)
3455 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3456 && ri
->type
== ZEBRA_ROUTE_BGP
3457 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3458 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3461 if (table
->owner
&& table
->owner
->bgp
)
3462 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3464 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3465 bgp_info_reap (rn
, ri
);
3470 /* Delete all kernel routes. */
3472 bgp_cleanup_routes (struct bgp
*bgp
)
3475 struct bgp_node
*rn
;
3477 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3479 if (afi
== AFI_L2VPN
)
3481 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3483 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3485 if (afi
!= AFI_L2VPN
)
3488 safi
= SAFI_MPLS_VPN
;
3489 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3490 rn
= bgp_route_next (rn
))
3494 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3495 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3497 bgp_unlock_node(rn
);
3501 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3502 rn
= bgp_route_next (rn
))
3506 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3507 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3509 bgp_unlock_node(rn
);
3514 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3515 rn
= bgp_route_next (rn
))
3519 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3520 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3522 bgp_unlock_node(rn
);
3531 bgp_zclient_reset ();
3532 access_list_reset ();
3533 prefix_list_reset ();
3537 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3539 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3540 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3543 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3546 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3547 struct bgp_nlri
*packet
)
3556 int addpath_encoded
;
3557 u_int32_t addpath_id
;
3559 /* Check peer status. */
3560 if (peer
->status
!= Established
)
3564 lim
= pnt
+ packet
->length
;
3566 safi
= packet
->safi
;
3568 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3570 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3571 syntactic validity. If the field is syntactically incorrect,
3572 then the Error Subcode is set to Invalid Network Field. */
3573 for (; pnt
< lim
; pnt
+= psize
)
3575 /* Clear prefix structure. */
3576 memset (&p
, 0, sizeof (struct prefix
));
3578 if (addpath_encoded
)
3581 /* When packet overflow occurs return immediately. */
3582 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3585 addpath_id
= ntohl(*((uint32_t*) pnt
));
3586 pnt
+= BGP_ADDPATH_ID_LEN
;
3589 /* Fetch prefix length. */
3590 p
.prefixlen
= *pnt
++;
3591 /* afi/safi validity already verified by caller, bgp_update_receive */
3592 p
.family
= afi2family (afi
);
3594 /* Prefix length check. */
3595 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3597 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3598 peer
->host
, p
.prefixlen
, packet
->afi
);
3602 /* Packet size overflow check. */
3603 psize
= PSIZE (p
.prefixlen
);
3605 /* When packet overflow occur return immediately. */
3606 if (pnt
+ psize
> lim
)
3608 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3609 peer
->host
, p
.prefixlen
);
3613 /* Defensive coding, double-check the psize fits in a struct prefix */
3614 if (psize
> (ssize_t
) sizeof(p
.u
))
3616 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3617 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3621 /* Fetch prefix from NLRI packet. */
3622 memcpy (&p
.u
.prefix
, pnt
, psize
);
3624 /* Check address. */
3625 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3627 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3629 /* From RFC4271 Section 6.3:
3631 * If a prefix in the NLRI field is semantically incorrect
3632 * (e.g., an unexpected multicast IP address), an error SHOULD
3633 * be logged locally, and the prefix SHOULD be ignored.
3635 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3636 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3641 /* Check address. */
3642 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3644 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3648 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3649 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3653 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3657 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3658 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3664 /* Normal process. */
3666 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3667 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3669 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3670 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3672 /* Address family configuration mismatch or maximum-prefix count
3678 /* Packet length consistency check. */
3681 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3689 static struct bgp_static
*
3690 bgp_static_new (void)
3692 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3696 bgp_static_free (struct bgp_static
*bgp_static
)
3698 if (bgp_static
->rmap
.name
)
3699 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3700 if(bgp_static
->eth_s_id
)
3701 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3702 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3706 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3707 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3709 struct bgp_node
*rn
;
3710 struct bgp_info
*ri
;
3711 struct bgp_info
*new;
3712 struct bgp_info info
;
3714 struct attr
*attr_new
;
3717 int vnc_implicit_withdraw
= 0;
3720 assert (bgp_static
);
3724 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3726 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3728 attr
.nexthop
= bgp_static
->igpnexthop
;
3729 attr
.med
= bgp_static
->igpmetric
;
3730 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3732 if (bgp_static
->atomic
)
3733 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3735 /* Apply route-map. */
3736 if (bgp_static
->rmap
.name
)
3738 struct attr attr_tmp
= attr
;
3739 info
.peer
= bgp
->peer_self
;
3740 info
.attr
= &attr_tmp
;
3742 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3744 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3746 bgp
->peer_self
->rmap_type
= 0;
3748 if (ret
== RMAP_DENYMATCH
)
3750 /* Free uninterned attribute. */
3751 bgp_attr_flush (&attr_tmp
);
3753 /* Unintern original. */
3754 aspath_unintern (&attr
.aspath
);
3755 bgp_attr_extra_free (&attr
);
3756 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3759 attr_new
= bgp_attr_intern (&attr_tmp
);
3762 attr_new
= bgp_attr_intern (&attr
);
3764 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3765 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3766 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3771 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3772 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3773 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3775 bgp_unlock_node (rn
);
3776 bgp_attr_unintern (&attr_new
);
3777 aspath_unintern (&attr
.aspath
);
3778 bgp_attr_extra_free (&attr
);
3783 /* The attribute is changed. */
3784 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3786 /* Rewrite BGP route information. */
3787 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3788 bgp_info_restore(rn
, ri
);
3790 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3792 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3794 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3797 * Implicit withdraw case.
3798 * We have to do this before ri is changed
3800 ++vnc_implicit_withdraw
;
3801 vnc_import_bgp_del_route(bgp
, p
, ri
);
3802 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3806 bgp_attr_unintern (&ri
->attr
);
3807 ri
->attr
= attr_new
;
3808 ri
->uptime
= bgp_clock ();
3810 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3812 if (vnc_implicit_withdraw
)
3814 vnc_import_bgp_add_route(bgp
, p
, ri
);
3815 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3820 /* Nexthop reachability check. */
3821 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3823 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3824 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3827 if (BGP_DEBUG(nht
, NHT
))
3829 char buf1
[INET6_ADDRSTRLEN
];
3830 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3832 zlog_debug("%s(%s): Route not in table, not advertising",
3833 __FUNCTION__
, buf1
);
3835 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3840 /* Delete the NHT structure if any, if we're toggling between
3841 * enabling/disabling import check. We deregister the route
3842 * from NHT to avoid overloading NHT and the process interaction
3844 bgp_unlink_nexthop(ri
);
3845 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3847 /* Process change. */
3848 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3849 bgp_process (bgp
, rn
, afi
, safi
);
3850 bgp_unlock_node (rn
);
3851 aspath_unintern (&attr
.aspath
);
3852 bgp_attr_extra_free (&attr
);
3857 /* Make new BGP info. */
3858 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3860 /* Nexthop reachability check. */
3861 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3863 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3864 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3867 if (BGP_DEBUG(nht
, NHT
))
3869 char buf1
[INET6_ADDRSTRLEN
];
3870 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3872 zlog_debug("%s(%s): Route not in table, not advertising",
3873 __FUNCTION__
, buf1
);
3875 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3880 /* Delete the NHT structure if any, if we're toggling between
3881 * enabling/disabling import check. We deregister the route
3882 * from NHT to avoid overloading NHT and the process interaction
3884 bgp_unlink_nexthop(new);
3886 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3889 /* Aggregate address increment. */
3890 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3892 /* Register new BGP information. */
3893 bgp_info_add (rn
, new);
3895 /* route_node_get lock */
3896 bgp_unlock_node (rn
);
3898 /* Process change. */
3899 bgp_process (bgp
, rn
, afi
, safi
);
3901 /* Unintern original. */
3902 aspath_unintern (&attr
.aspath
);
3903 bgp_attr_extra_free (&attr
);
3907 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3908 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3910 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3914 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3917 struct bgp_node
*rn
;
3918 struct bgp_info
*ri
;
3920 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3922 /* Check selected route and self inserted route. */
3923 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3924 if (ri
->peer
== bgp
->peer_self
3925 && ri
->type
== ZEBRA_ROUTE_BGP
3926 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3929 /* Withdraw static BGP route from routing table. */
3932 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3933 bgp_unlink_nexthop(ri
);
3934 bgp_info_delete (rn
, ri
);
3935 bgp_process (bgp
, rn
, afi
, safi
);
3938 /* Unlock bgp_node_lookup. */
3939 bgp_unlock_node (rn
);
3943 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3946 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3947 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3949 struct bgp_node
*rn
;
3950 struct bgp_info
*ri
;
3952 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3954 /* Check selected route and self inserted route. */
3955 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3956 if (ri
->peer
== bgp
->peer_self
3957 && ri
->type
== ZEBRA_ROUTE_BGP
3958 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3961 /* Withdraw static BGP route from routing table. */
3965 rfapiProcessWithdraw(
3974 1); /* Kill, since it is an administrative change */
3976 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3977 bgp_info_delete (rn
, ri
);
3978 bgp_process (bgp
, rn
, afi
, safi
);
3981 /* Unlock bgp_node_lookup. */
3982 bgp_unlock_node (rn
);
3986 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3987 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3989 struct bgp_node
*rn
;
3990 struct bgp_info
*new;
3991 struct attr
*attr_new
;
3992 struct attr attr
= { 0 };
3993 struct bgp_info
*ri
;
3995 u_int32_t label
= 0;
3999 assert (bgp_static
);
4001 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4003 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4005 attr
.nexthop
= bgp_static
->igpnexthop
;
4006 attr
.med
= bgp_static
->igpmetric
;
4007 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4009 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
4013 bgp_attr_extra_get (&attr
)->mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4014 bgp_attr_extra_get (&attr
)->mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4017 if(afi
== AFI_L2VPN
)
4019 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4020 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4021 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4022 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4023 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4024 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4026 struct bgp_encap_type_vxlan bet
;
4027 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4028 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4029 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4031 if (bgp_static
->router_mac
)
4033 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4036 /* Apply route-map. */
4037 if (bgp_static
->rmap
.name
)
4039 struct attr attr_tmp
= attr
;
4040 struct bgp_info info
;
4043 info
.peer
= bgp
->peer_self
;
4044 info
.attr
= &attr_tmp
;
4046 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4048 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4050 bgp
->peer_self
->rmap_type
= 0;
4052 if (ret
== RMAP_DENYMATCH
)
4054 /* Free uninterned attribute. */
4055 bgp_attr_flush (&attr_tmp
);
4057 /* Unintern original. */
4058 aspath_unintern (&attr
.aspath
);
4059 bgp_attr_extra_free (&attr
);
4060 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4065 attr_new
= bgp_attr_intern (&attr_tmp
);
4069 attr_new
= bgp_attr_intern (&attr
);
4072 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4073 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4074 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4080 memset(&add
, 0, sizeof(union gw_addr
));
4081 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4082 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4083 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4085 bgp_unlock_node (rn
);
4086 bgp_attr_unintern (&attr_new
);
4087 aspath_unintern (&attr
.aspath
);
4088 bgp_attr_extra_free (&attr
);
4093 /* The attribute is changed. */
4094 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4096 /* Rewrite BGP route information. */
4097 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4098 bgp_info_restore(rn
, ri
);
4100 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4101 bgp_attr_unintern (&ri
->attr
);
4102 ri
->attr
= attr_new
;
4103 ri
->uptime
= bgp_clock ();
4106 label
= decode_label (ri
->extra
->tag
);
4109 /* Process change. */
4110 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4111 bgp_process (bgp
, rn
, afi
, safi
);
4113 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4114 ri
->attr
, afi
, safi
,
4115 ri
->type
, ri
->sub_type
, &label
);
4117 bgp_unlock_node (rn
);
4118 aspath_unintern (&attr
.aspath
);
4119 bgp_attr_extra_free (&attr
);
4125 /* Make new BGP info. */
4126 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4128 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4129 new->extra
= bgp_info_extra_new();
4130 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4132 label
= decode_label (bgp_static
->tag
);
4135 /* Aggregate address increment. */
4136 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4138 /* Register new BGP information. */
4139 bgp_info_add (rn
, new);
4140 /* route_node_get lock */
4141 bgp_unlock_node (rn
);
4143 /* Process change. */
4144 bgp_process (bgp
, rn
, afi
, safi
);
4147 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4148 new->attr
, afi
, safi
,
4149 new->type
, new->sub_type
, &label
);
4152 /* Unintern original. */
4153 aspath_unintern (&attr
.aspath
);
4154 bgp_attr_extra_free (&attr
);
4157 /* Configure static BGP network. When user don't run zebra, static
4158 route should be installed as valid. */
4160 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4161 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4163 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4166 struct bgp_static
*bgp_static
;
4167 struct bgp_node
*rn
;
4168 u_char need_update
= 0;
4170 /* Convert IP prefix string to struct prefix. */
4171 ret
= str2prefix (ip_str
, &p
);
4174 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4177 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4179 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4186 /* Set BGP static route configuration. */
4187 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4191 /* Configuration change. */
4192 bgp_static
= rn
->info
;
4194 /* Check previous routes are installed into BGP. */
4195 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4198 bgp_static
->backdoor
= backdoor
;
4202 if (bgp_static
->rmap
.name
)
4203 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4204 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4205 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4209 if (bgp_static
->rmap
.name
)
4210 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4211 bgp_static
->rmap
.name
= NULL
;
4212 bgp_static
->rmap
.map
= NULL
;
4213 bgp_static
->valid
= 0;
4215 bgp_unlock_node (rn
);
4219 /* New configuration. */
4220 bgp_static
= bgp_static_new ();
4221 bgp_static
->backdoor
= backdoor
;
4222 bgp_static
->valid
= 0;
4223 bgp_static
->igpmetric
= 0;
4224 bgp_static
->igpnexthop
.s_addr
= 0;
4228 if (bgp_static
->rmap
.name
)
4229 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4230 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4231 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4233 rn
->info
= bgp_static
;
4236 bgp_static
->valid
= 1;
4238 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4240 if (! bgp_static
->backdoor
)
4241 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4246 /* Configure static BGP network. */
4248 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4249 afi_t afi
, safi_t safi
)
4251 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4254 struct bgp_static
*bgp_static
;
4255 struct bgp_node
*rn
;
4257 /* Convert IP prefix string to struct prefix. */
4258 ret
= str2prefix (ip_str
, &p
);
4261 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4264 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4266 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4273 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4276 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4281 bgp_static
= rn
->info
;
4283 /* Update BGP RIB. */
4284 if (! bgp_static
->backdoor
)
4285 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4287 /* Clear configuration. */
4288 bgp_static_free (bgp_static
);
4290 bgp_unlock_node (rn
);
4291 bgp_unlock_node (rn
);
4297 bgp_static_add (struct bgp
*bgp
)
4301 struct bgp_node
*rn
;
4302 struct bgp_node
*rm
;
4303 struct bgp_table
*table
;
4304 struct bgp_static
*bgp_static
;
4306 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4307 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4308 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4309 if (rn
->info
!= NULL
)
4311 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4315 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4317 bgp_static
= rm
->info
;
4318 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4323 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4328 /* Called from bgp_delete(). Delete all static routes from the BGP
4331 bgp_static_delete (struct bgp
*bgp
)
4335 struct bgp_node
*rn
;
4336 struct bgp_node
*rm
;
4337 struct bgp_table
*table
;
4338 struct bgp_static
*bgp_static
;
4340 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4341 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4342 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4343 if (rn
->info
!= NULL
)
4345 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4349 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4351 bgp_static
= rm
->info
;
4352 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4354 (struct prefix_rd
*)&rn
->p
,
4356 bgp_static_free (bgp_static
);
4358 bgp_unlock_node (rn
);
4363 bgp_static
= rn
->info
;
4364 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4365 bgp_static_free (bgp_static
);
4367 bgp_unlock_node (rn
);
4373 bgp_static_redo_import_check (struct bgp
*bgp
)
4377 struct bgp_node
*rn
;
4378 struct bgp_node
*rm
;
4379 struct bgp_table
*table
;
4380 struct bgp_static
*bgp_static
;
4382 /* Use this flag to force reprocessing of the route */
4383 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4384 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4385 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4386 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4387 if (rn
->info
!= NULL
)
4389 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4393 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4395 bgp_static
= rm
->info
;
4396 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4401 bgp_static
= rn
->info
;
4402 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4405 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4409 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4411 struct bgp_table
*table
;
4412 struct bgp_node
*rn
;
4413 struct bgp_info
*ri
;
4415 table
= bgp
->rib
[afi
][safi
];
4416 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4418 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4420 if (ri
->peer
== bgp
->peer_self
&&
4421 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4422 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4423 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4424 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4426 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4427 bgp_unlink_nexthop(ri
);
4428 bgp_info_delete (rn
, ri
);
4429 bgp_process (bgp
, rn
, afi
, safi
);
4436 * Purge all networks and redistributed routes from routing table.
4437 * Invoked upon the instance going down.
4440 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4445 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4446 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4447 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4452 * Currently this is used to set static routes for VPN and ENCAP.
4453 * I think it can probably be factored with bgp_static_set.
4456 bgp_static_set_safi (afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4457 const char *rd_str
, const char *label_str
,
4458 const char *rmap_str
, int evpn_type
, const char *esi
, const char *gwip
,
4459 const char *ethtag
, const char *routermac
)
4461 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4464 struct prefix_rd prd
;
4465 struct bgp_node
*prn
;
4466 struct bgp_node
*rn
;
4467 struct bgp_table
*table
;
4468 struct bgp_static
*bgp_static
;
4470 struct prefix gw_ip
;
4472 /* validate ip prefix */
4473 ret
= str2prefix (ip_str
, &p
);
4476 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4480 if ( (afi
== AFI_L2VPN
) &&
4481 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4483 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4487 ret
= str2prefix_rd (rd_str
, &prd
);
4490 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4496 unsigned long label_val
;
4497 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, 16777215);
4498 encode_label (label_val
, tag
);
4502 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4504 if (safi
== SAFI_EVPN
)
4506 if( esi
&& str2esi (esi
, NULL
) == 0)
4508 vty_out (vty
, "%% Malformed ESI%s", VTY_NEWLINE
);
4511 if( routermac
&& prefix_str2mac (routermac
, NULL
) == 0)
4513 vty_out (vty
, "%% Malformed Router MAC%s", VTY_NEWLINE
);
4518 memset (&gw_ip
, 0, sizeof (struct prefix
));
4519 ret
= str2prefix (gwip
, &gw_ip
);
4522 vty_out (vty
, "%% Malformed GatewayIp%s", VTY_NEWLINE
);
4525 if((gw_ip
.family
== AF_INET
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V6
))
4526 || (gw_ip
.family
== AF_INET6
&& (p
.u
.prefix_evpn
.flags
& IP_PREFIX_V4
)))
4528 vty_out (vty
, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE
);
4533 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4534 (struct prefix
*)&prd
);
4535 if (prn
->info
== NULL
)
4536 prn
->info
= bgp_table_init (afi
, safi
);
4538 bgp_unlock_node (prn
);
4541 rn
= bgp_node_get (table
, &p
);
4545 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4546 bgp_unlock_node (rn
);
4550 /* New configuration. */
4551 bgp_static
= bgp_static_new ();
4552 bgp_static
->backdoor
= 0;
4553 bgp_static
->valid
= 0;
4554 bgp_static
->igpmetric
= 0;
4555 bgp_static
->igpnexthop
.s_addr
= 0;
4556 memcpy(bgp_static
->tag
, tag
, 3);
4557 bgp_static
->prd
= prd
;
4561 if (bgp_static
->rmap
.name
)
4562 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4563 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4564 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4567 if (safi
== SAFI_EVPN
)
4571 bgp_static
->eth_s_id
= XCALLOC (MTYPE_ATTR
, sizeof(struct eth_segment_id
));
4572 str2esi (esi
, bgp_static
->eth_s_id
);
4576 bgp_static
->router_mac
= XCALLOC (MTYPE_ATTR
, ETHER_ADDR_LEN
+1);
4577 prefix_str2mac (routermac
, bgp_static
->router_mac
);
4580 prefix_copy (&bgp_static
->gatewayIp
, &gw_ip
);
4582 rn
->info
= bgp_static
;
4584 bgp_static
->valid
= 1;
4585 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4591 /* Configure static BGP network. */
4593 bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
, const char *ip_str
,
4594 const char *rd_str
, const char *label_str
,
4595 int evpn_type
, const char *esi
, const char *gwip
, const char *ethtag
)
4597 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4600 struct prefix_rd prd
;
4601 struct bgp_node
*prn
;
4602 struct bgp_node
*rn
;
4603 struct bgp_table
*table
;
4604 struct bgp_static
*bgp_static
;
4607 /* Convert IP prefix string to struct prefix. */
4608 ret
= str2prefix (ip_str
, &p
);
4611 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4615 if ( (afi
== AFI_L2VPN
) &&
4616 (bgp_build_evpn_prefix ( evpn_type
, ethtag
!=NULL
?atol(ethtag
):0, &p
)))
4618 vty_out (vty
, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE
);
4621 ret
= str2prefix_rd (rd_str
, &prd
);
4624 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4630 unsigned long label_val
;
4631 VTY_GET_INTEGER_RANGE("Label/tag", label_val
, label_str
, 0, MPLS_LABEL_MAX
);
4632 encode_label (label_val
, tag
);
4636 memset (tag
, 0, sizeof(tag
)); /* empty, not even BoS */
4639 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4640 (struct prefix
*)&prd
);
4641 if (prn
->info
== NULL
)
4642 prn
->info
= bgp_table_init (afi
, safi
);
4644 bgp_unlock_node (prn
);
4647 rn
= bgp_node_lookup (table
, &p
);
4651 bgp_static_withdraw_safi (bgp
, &p
, afi
, safi
, &prd
, tag
);
4653 bgp_static
= rn
->info
;
4654 bgp_static_free (bgp_static
);
4656 bgp_unlock_node (rn
);
4657 bgp_unlock_node (rn
);
4660 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4666 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4667 const char *rmap_name
)
4669 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4670 struct bgp_rmap
*rmap
;
4672 rmap
= &bgp
->table_map
[afi
][safi
];
4676 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4677 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4678 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4683 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4688 bgp_zebra_announce_table(bgp
, afi
, safi
);
4694 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4695 const char *rmap_name
)
4697 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4698 struct bgp_rmap
*rmap
;
4700 rmap
= &bgp
->table_map
[afi
][safi
];
4702 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4706 bgp_zebra_announce_table(bgp
, afi
, safi
);
4712 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4713 safi_t safi
, int *write
)
4715 if (bgp
->table_map
[afi
][safi
].name
)
4717 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4718 vty_out (vty
, " table-map %s%s",
4719 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4725 DEFUN (bgp_table_map
,
4728 "BGP table to RIB route download filter\n"
4729 "Name of the route map\n")
4732 return bgp_table_map_set (vty
,
4733 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4735 DEFUN (no_bgp_table_map
,
4736 no_bgp_table_map_cmd
,
4737 "no table-map WORD",
4739 "BGP table to RIB route download filter\n"
4740 "Name of the route map\n")
4743 return bgp_table_map_unset (vty
,
4744 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4749 "network A.B.C.D/M",
4750 "Specify a network to announce via BGP\n"
4753 int idx_ipv4_prefixlen
= 1;
4754 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4755 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4758 DEFUN (bgp_network_route_map
,
4759 bgp_network_route_map_cmd
,
4760 "network A.B.C.D/M route-map WORD",
4761 "Specify a network to announce via BGP\n"
4763 "Route-map to modify the attributes\n"
4764 "Name of the route map\n")
4766 int idx_ipv4_prefixlen
= 1;
4768 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4769 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4772 DEFUN (bgp_network_backdoor
,
4773 bgp_network_backdoor_cmd
,
4774 "network A.B.C.D/M backdoor",
4775 "Specify a network to announce via BGP\n"
4777 "Specify a BGP backdoor route\n")
4779 int idx_ipv4_prefixlen
= 1;
4780 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4784 DEFUN (bgp_network_mask
,
4785 bgp_network_mask_cmd
,
4786 "network A.B.C.D mask A.B.C.D",
4787 "Specify a network to announce via BGP\n"
4795 char prefix_str
[BUFSIZ
];
4797 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4800 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4804 return bgp_static_set (vty
, prefix_str
,
4805 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4808 DEFUN (bgp_network_mask_route_map
,
4809 bgp_network_mask_route_map_cmd
,
4810 "network A.B.C.D mask A.B.C.D route-map WORD",
4811 "Specify a network to announce via BGP\n"
4815 "Route-map to modify the attributes\n"
4816 "Name of the route map\n")
4822 char prefix_str
[BUFSIZ
];
4824 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4827 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4831 return bgp_static_set (vty
, prefix_str
,
4832 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4835 DEFUN (bgp_network_mask_backdoor
,
4836 bgp_network_mask_backdoor_cmd
,
4837 "network A.B.C.D mask A.B.C.D backdoor",
4838 "Specify a network to announce via BGP\n"
4842 "Specify a BGP backdoor route\n")
4847 char prefix_str
[BUFSIZ
];
4849 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4852 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4856 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4860 DEFUN (bgp_network_mask_natural
,
4861 bgp_network_mask_natural_cmd
,
4863 "Specify a network to announce via BGP\n"
4868 char prefix_str
[BUFSIZ
];
4870 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4873 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4877 return bgp_static_set (vty
, prefix_str
,
4878 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4881 DEFUN (bgp_network_mask_natural_route_map
,
4882 bgp_network_mask_natural_route_map_cmd
,
4883 "network A.B.C.D route-map WORD",
4884 "Specify a network to announce via BGP\n"
4886 "Route-map to modify the attributes\n"
4887 "Name of the route map\n")
4892 char prefix_str
[BUFSIZ
];
4894 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4897 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4901 return bgp_static_set (vty
, prefix_str
,
4902 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4905 DEFUN (bgp_network_mask_natural_backdoor
,
4906 bgp_network_mask_natural_backdoor_cmd
,
4907 "network A.B.C.D backdoor",
4908 "Specify a network to announce via BGP\n"
4910 "Specify a BGP backdoor route\n")
4914 char prefix_str
[BUFSIZ
];
4916 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4919 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4923 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4927 DEFUN (no_bgp_network
,
4929 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4931 "Specify a network to announce via BGP\n"
4933 "Specify a BGP backdoor route\n"
4934 "Route-map to modify the attributes\n"
4935 "Name of the route map\n")
4937 int idx_ipv4_prefixlen
= 2;
4938 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4939 bgp_node_safi (vty
));
4942 DEFUN (no_bgp_network_mask
,
4943 no_bgp_network_mask_cmd
,
4944 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4946 "Specify a network to announce via BGP\n"
4950 "Specify a BGP backdoor route\n"
4951 "Route-map to modify the attributes\n"
4952 "Name of the route map\n")
4957 char prefix_str
[BUFSIZ
];
4959 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4962 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4966 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4967 bgp_node_safi (vty
));
4970 DEFUN (no_bgp_network_mask_natural
,
4971 no_bgp_network_mask_natural_cmd
,
4972 "no network A.B.C.D [<backdoor|route-map WORD>]",
4974 "Specify a network to announce via BGP\n"
4976 "Specify a BGP backdoor route\n"
4977 "Route-map to modify the attributes\n"
4978 "Name of the route map\n")
4982 char prefix_str
[BUFSIZ
];
4984 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4987 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4991 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4992 bgp_node_safi (vty
));
4995 DEFUN (ipv6_bgp_network
,
4996 ipv6_bgp_network_cmd
,
4997 "network X:X::X:X/M",
4998 "Specify a network to announce via BGP\n"
5001 int idx_ipv6_prefixlen
= 1;
5002 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5006 DEFUN (ipv6_bgp_network_route_map
,
5007 ipv6_bgp_network_route_map_cmd
,
5008 "network X:X::X:X/M route-map WORD",
5009 "Specify a network to announce via BGP\n"
5011 "Route-map to modify the attributes\n"
5012 "Name of the route map\n")
5014 int idx_ipv6_prefixlen
= 1;
5016 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5017 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
5020 DEFUN (no_ipv6_bgp_network
,
5021 no_ipv6_bgp_network_cmd
,
5022 "no network X:X::X:X/M [route-map WORD]",
5024 "Specify a network to announce via BGP\n"
5026 "Route-map to modify the attributes\n"
5027 "Name of the route map\n")
5029 int idx_ipv6_prefixlen
= 2;
5030 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
5033 /* Aggreagete address:
5035 advertise-map Set condition to advertise attribute
5036 as-set Generate AS set path information
5037 attribute-map Set attributes of aggregate
5038 route-map Set parameters of aggregate
5039 summary-only Filter more specific routes from updates
5040 suppress-map Conditionally filter more specific routes from updates
5043 struct bgp_aggregate
5045 /* Summary-only flag. */
5046 u_char summary_only
;
5048 /* AS set generation. */
5051 /* Route-map for aggregated route. */
5052 struct route_map
*map
;
5054 /* Suppress-count. */
5055 unsigned long count
;
5057 /* SAFI configuration. */
5061 static struct bgp_aggregate
*
5062 bgp_aggregate_new (void)
5064 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
5068 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
5070 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
5073 /* Update an aggregate as routes are added/removed from the BGP table */
5075 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
5076 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
5077 struct bgp_aggregate
*aggregate
)
5079 struct bgp_table
*table
;
5080 struct bgp_node
*top
;
5081 struct bgp_node
*rn
;
5083 struct aspath
*aspath
= NULL
;
5084 struct aspath
*asmerge
= NULL
;
5085 struct community
*community
= NULL
;
5086 struct community
*commerge
= NULL
;
5087 #if defined(AGGREGATE_NEXTHOP_CHECK)
5088 struct in_addr nexthop
;
5091 struct bgp_info
*ri
;
5092 struct bgp_info
*new;
5094 unsigned long match
= 0;
5095 u_char atomic_aggregate
= 0;
5097 /* Record adding route's nexthop and med. */
5100 #if defined(AGGREGATE_NEXTHOP_CHECK)
5101 nexthop
= rinew
->attr
->nexthop
;
5102 med
= rinew
->attr
->med
;
5106 /* ORIGIN attribute: If at least one route among routes that are
5107 aggregated has ORIGIN with the value INCOMPLETE, then the
5108 aggregated route must have the ORIGIN attribute with the value
5109 INCOMPLETE. Otherwise, if at least one route among routes that
5110 are aggregated has ORIGIN with the value EGP, then the aggregated
5111 route must have the origin attribute with the value EGP. In all
5112 other case the value of the ORIGIN attribute of the aggregated
5113 route is INTERNAL. */
5114 origin
= BGP_ORIGIN_IGP
;
5116 table
= bgp
->rib
[afi
][safi
];
5118 top
= bgp_node_get (table
, p
);
5119 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5120 if (rn
->p
.prefixlen
> p
->prefixlen
)
5124 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5126 if (BGP_INFO_HOLDDOWN (ri
))
5129 if (del
&& ri
== del
)
5132 if (! rinew
&& first
)
5134 #if defined(AGGREGATE_NEXTHOP_CHECK)
5135 nexthop
= ri
->attr
->nexthop
;
5136 med
= ri
->attr
->med
;
5141 #ifdef AGGREGATE_NEXTHOP_CHECK
5142 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5143 || ri
->attr
->med
!= med
)
5146 aspath_free (aspath
);
5148 community_free (community
);
5149 bgp_unlock_node (rn
);
5150 bgp_unlock_node (top
);
5153 #endif /* AGGREGATE_NEXTHOP_CHECK */
5155 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5156 atomic_aggregate
= 1;
5158 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5160 if (aggregate
->summary_only
)
5162 (bgp_info_extra_get (ri
))->suppress
++;
5163 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5169 if (origin
< ri
->attr
->origin
)
5170 origin
= ri
->attr
->origin
;
5172 if (aggregate
->as_set
)
5176 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5177 aspath_free (aspath
);
5181 aspath
= aspath_dup (ri
->attr
->aspath
);
5183 if (ri
->attr
->community
)
5187 commerge
= community_merge (community
,
5188 ri
->attr
->community
);
5189 community
= community_uniq_sort (commerge
);
5190 community_free (commerge
);
5193 community
= community_dup (ri
->attr
->community
);
5199 bgp_process (bgp
, rn
, afi
, safi
);
5201 bgp_unlock_node (top
);
5207 if (aggregate
->summary_only
)
5208 (bgp_info_extra_get (rinew
))->suppress
++;
5210 if (origin
< rinew
->attr
->origin
)
5211 origin
= rinew
->attr
->origin
;
5213 if (aggregate
->as_set
)
5217 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5218 aspath_free (aspath
);
5222 aspath
= aspath_dup (rinew
->attr
->aspath
);
5224 if (rinew
->attr
->community
)
5228 commerge
= community_merge (community
,
5229 rinew
->attr
->community
);
5230 community
= community_uniq_sort (commerge
);
5231 community_free (commerge
);
5234 community
= community_dup (rinew
->attr
->community
);
5239 if (aggregate
->count
> 0)
5241 rn
= bgp_node_get (table
, p
);
5242 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5243 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5245 atomic_aggregate
), rn
);
5246 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5248 bgp_info_add (rn
, new);
5249 bgp_unlock_node (rn
);
5250 bgp_process (bgp
, rn
, afi
, safi
);
5255 aspath_free (aspath
);
5257 community_free (community
);
5261 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5262 struct bgp_aggregate
*);
5265 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5266 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5268 struct bgp_node
*child
;
5269 struct bgp_node
*rn
;
5270 struct bgp_aggregate
*aggregate
;
5271 struct bgp_table
*table
;
5273 /* MPLS-VPN aggregation is not yet supported. */
5274 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5277 table
= bgp
->aggregate
[afi
][safi
];
5279 /* No aggregates configured. */
5280 if (bgp_table_top_nolock (table
) == NULL
)
5283 if (p
->prefixlen
== 0)
5286 if (BGP_INFO_HOLDDOWN (ri
))
5289 child
= bgp_node_get (table
, p
);
5291 /* Aggregate address configuration check. */
5292 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5293 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5295 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5296 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5298 bgp_unlock_node (child
);
5302 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5303 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5305 struct bgp_node
*child
;
5306 struct bgp_node
*rn
;
5307 struct bgp_aggregate
*aggregate
;
5308 struct bgp_table
*table
;
5310 /* MPLS-VPN aggregation is not yet supported. */
5311 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
5314 table
= bgp
->aggregate
[afi
][safi
];
5316 /* No aggregates configured. */
5317 if (bgp_table_top_nolock (table
) == NULL
)
5320 if (p
->prefixlen
== 0)
5323 child
= bgp_node_get (table
, p
);
5325 /* Aggregate address configuration check. */
5326 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5327 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5329 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5330 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5332 bgp_unlock_node (child
);
5335 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5337 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5338 struct bgp_aggregate
*aggregate
)
5340 struct bgp_table
*table
;
5341 struct bgp_node
*top
;
5342 struct bgp_node
*rn
;
5343 struct bgp_info
*new;
5344 struct bgp_info
*ri
;
5345 unsigned long match
;
5346 u_char origin
= BGP_ORIGIN_IGP
;
5347 struct aspath
*aspath
= NULL
;
5348 struct aspath
*asmerge
= NULL
;
5349 struct community
*community
= NULL
;
5350 struct community
*commerge
= NULL
;
5351 u_char atomic_aggregate
= 0;
5353 table
= bgp
->rib
[afi
][safi
];
5356 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5358 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5361 /* If routes exists below this node, generate aggregate routes. */
5362 top
= bgp_node_get (table
, p
);
5363 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5364 if (rn
->p
.prefixlen
> p
->prefixlen
)
5368 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5370 if (BGP_INFO_HOLDDOWN (ri
))
5373 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5374 atomic_aggregate
= 1;
5376 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5378 /* summary-only aggregate route suppress aggregated
5379 route announcement. */
5380 if (aggregate
->summary_only
)
5382 (bgp_info_extra_get (ri
))->suppress
++;
5383 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5387 /* If at least one route among routes that are aggregated has
5388 * ORIGIN with the value INCOMPLETE, then the aggregated route
5389 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5390 * Otherwise, if at least one route among routes that are
5391 * aggregated has ORIGIN with the value EGP, then the aggregated
5392 * route MUST have the ORIGIN attribute with the value EGP.
5394 if (origin
< ri
->attr
->origin
)
5395 origin
= ri
->attr
->origin
;
5397 /* as-set aggregate route generate origin, as path,
5398 community aggregation. */
5399 if (aggregate
->as_set
)
5403 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5404 aspath_free (aspath
);
5408 aspath
= aspath_dup (ri
->attr
->aspath
);
5410 if (ri
->attr
->community
)
5414 commerge
= community_merge (community
,
5415 ri
->attr
->community
);
5416 community
= community_uniq_sort (commerge
);
5417 community_free (commerge
);
5420 community
= community_dup (ri
->attr
->community
);
5427 /* If this node is suppressed, process the change. */
5429 bgp_process (bgp
, rn
, afi
, safi
);
5431 bgp_unlock_node (top
);
5433 /* Add aggregate route to BGP table. */
5434 if (aggregate
->count
)
5436 rn
= bgp_node_get (table
, p
);
5437 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5438 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5440 atomic_aggregate
), rn
);
5441 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5443 bgp_info_add (rn
, new);
5444 bgp_unlock_node (rn
);
5446 /* Process change. */
5447 bgp_process (bgp
, rn
, afi
, safi
);
5452 aspath_free (aspath
);
5454 community_free (community
);
5459 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5460 safi_t safi
, struct bgp_aggregate
*aggregate
)
5462 struct bgp_table
*table
;
5463 struct bgp_node
*top
;
5464 struct bgp_node
*rn
;
5465 struct bgp_info
*ri
;
5466 unsigned long match
;
5468 table
= bgp
->rib
[afi
][safi
];
5470 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5472 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5475 /* If routes exists below this node, generate aggregate routes. */
5476 top
= bgp_node_get (table
, p
);
5477 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5478 if (rn
->p
.prefixlen
> p
->prefixlen
)
5482 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5484 if (BGP_INFO_HOLDDOWN (ri
))
5487 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5489 if (aggregate
->summary_only
&& ri
->extra
)
5491 ri
->extra
->suppress
--;
5493 if (ri
->extra
->suppress
== 0)
5495 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5503 /* If this node was suppressed, process the change. */
5505 bgp_process (bgp
, rn
, afi
, safi
);
5507 bgp_unlock_node (top
);
5509 /* Delete aggregate route from BGP table. */
5510 rn
= bgp_node_get (table
, p
);
5512 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5513 if (ri
->peer
== bgp
->peer_self
5514 && ri
->type
== ZEBRA_ROUTE_BGP
5515 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5518 /* Withdraw static BGP route from routing table. */
5521 bgp_info_delete (rn
, ri
);
5522 bgp_process (bgp
, rn
, afi
, safi
);
5525 /* Unlock bgp_node_lookup. */
5526 bgp_unlock_node (rn
);
5529 /* Aggregate route attribute. */
5530 #define AGGREGATE_SUMMARY_ONLY 1
5531 #define AGGREGATE_AS_SET 1
5534 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5535 afi_t afi
, safi_t safi
)
5537 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5540 struct bgp_node
*rn
;
5541 struct bgp_aggregate
*aggregate
;
5543 /* Convert string to prefix structure. */
5544 ret
= str2prefix (prefix_str
, &p
);
5547 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5552 /* Old configuration check. */
5553 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5556 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5561 aggregate
= rn
->info
;
5562 if (aggregate
->safi
& SAFI_UNICAST
)
5563 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5564 if (aggregate
->safi
& SAFI_MULTICAST
)
5565 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5567 /* Unlock aggregate address configuration. */
5569 bgp_aggregate_free (aggregate
);
5570 bgp_unlock_node (rn
);
5571 bgp_unlock_node (rn
);
5577 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5578 afi_t afi
, safi_t safi
,
5579 u_char summary_only
, u_char as_set
)
5581 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5584 struct bgp_node
*rn
;
5585 struct bgp_aggregate
*aggregate
;
5587 /* Convert string to prefix structure. */
5588 ret
= str2prefix (prefix_str
, &p
);
5591 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5596 /* Old configuration check. */
5597 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5601 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5602 /* try to remove the old entry */
5603 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5606 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5607 bgp_unlock_node (rn
);
5612 /* Make aggregate address structure. */
5613 aggregate
= bgp_aggregate_new ();
5614 aggregate
->summary_only
= summary_only
;
5615 aggregate
->as_set
= as_set
;
5616 aggregate
->safi
= safi
;
5617 rn
->info
= aggregate
;
5619 /* Aggregate address insert into BGP routing table. */
5620 if (safi
& SAFI_UNICAST
)
5621 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5622 if (safi
& SAFI_MULTICAST
)
5623 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5628 DEFUN (aggregate_address
,
5629 aggregate_address_cmd
,
5630 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5631 "Configure BGP aggregate entries\n"
5632 "Aggregate prefix\n"
5633 "Generate AS set path information\n"
5634 "Filter more specific routes from updates\n"
5635 "Filter more specific routes from updates\n"
5636 "Generate AS set path information\n")
5639 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5640 char *prefix
= argv
[idx
]->arg
;
5641 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5643 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5645 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5648 DEFUN (aggregate_address_mask
,
5649 aggregate_address_mask_cmd
,
5650 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5651 "Configure BGP aggregate entries\n"
5652 "Aggregate address\n"
5654 "Generate AS set path information\n"
5655 "Filter more specific routes from updates\n"
5656 "Filter more specific routes from updates\n"
5657 "Generate AS set path information\n")
5660 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5661 char *prefix
= argv
[idx
++]->arg
;
5662 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5663 char *mask
= argv
[idx
]->arg
;
5664 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5666 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5668 char prefix_str
[BUFSIZ
];
5669 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5673 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5677 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5680 DEFUN (no_aggregate_address
,
5681 no_aggregate_address_cmd
,
5682 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5684 "Configure BGP aggregate entries\n"
5685 "Aggregate prefix\n"
5686 "Generate AS set path information\n"
5687 "Filter more specific routes from updates\n"
5688 "Filter more specific routes from updates\n"
5689 "Generate AS set path information\n")
5692 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5693 char *prefix
= argv
[idx
]->arg
;
5694 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5697 DEFUN (no_aggregate_address_mask
,
5698 no_aggregate_address_mask_cmd
,
5699 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5701 "Configure BGP aggregate entries\n"
5702 "Aggregate address\n"
5704 "Generate AS set path information\n"
5705 "Filter more specific routes from updates\n"
5706 "Filter more specific routes from updates\n"
5707 "Generate AS set path information\n")
5710 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5711 char *prefix
= argv
[idx
++]->arg
;
5712 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5713 char *mask
= argv
[idx
]->arg
;
5715 char prefix_str
[BUFSIZ
];
5716 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5720 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5724 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5727 DEFUN (ipv6_aggregate_address
,
5728 ipv6_aggregate_address_cmd
,
5729 "aggregate-address X:X::X:X/M [summary-only]",
5730 "Configure BGP aggregate entries\n"
5731 "Aggregate prefix\n"
5732 "Filter more specific routes from updates\n")
5735 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5736 char *prefix
= argv
[idx
]->arg
;
5737 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5738 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5741 DEFUN (no_ipv6_aggregate_address
,
5742 no_ipv6_aggregate_address_cmd
,
5743 "no aggregate-address X:X::X:X/M [summary-only]",
5745 "Configure BGP aggregate entries\n"
5746 "Aggregate prefix\n"
5747 "Filter more specific routes from updates\n")
5750 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5751 char *prefix
= argv
[idx
]->arg
;
5752 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5755 /* Redistribute route treatment. */
5757 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5758 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5759 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5761 struct bgp_info
*new;
5762 struct bgp_info
*bi
;
5763 struct bgp_info info
;
5764 struct bgp_node
*bn
;
5766 struct attr
*new_attr
;
5769 struct bgp_redist
*red
;
5771 /* Make default attribute. */
5772 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5774 attr
.nexthop
= *nexthop
;
5775 attr
.nh_ifindex
= ifindex
;
5779 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5780 extra
->mp_nexthop_global
= *nexthop6
;
5781 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5785 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5786 attr
.extra
->tag
= tag
;
5788 afi
= family2afi (p
->family
);
5790 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5793 struct attr attr_new
;
5794 struct attr_extra extra_new
;
5796 /* Copy attribute for modification. */
5797 attr_new
.extra
= &extra_new
;
5798 bgp_attr_dup (&attr_new
, &attr
);
5800 if (red
->redist_metric_flag
)
5801 attr_new
.med
= red
->redist_metric
;
5803 /* Apply route-map. */
5806 info
.peer
= bgp
->peer_self
;
5807 info
.attr
= &attr_new
;
5809 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5811 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5813 bgp
->peer_self
->rmap_type
= 0;
5815 if (ret
== RMAP_DENYMATCH
)
5817 /* Free uninterned attribute. */
5818 bgp_attr_flush (&attr_new
);
5820 /* Unintern original. */
5821 aspath_unintern (&attr
.aspath
);
5822 bgp_attr_extra_free (&attr
);
5823 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5828 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5829 afi
, SAFI_UNICAST
, p
, NULL
);
5831 new_attr
= bgp_attr_intern (&attr_new
);
5833 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5834 if (bi
->peer
== bgp
->peer_self
5835 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5840 /* Ensure the (source route) type is updated. */
5842 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5843 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5845 bgp_attr_unintern (&new_attr
);
5846 aspath_unintern (&attr
.aspath
);
5847 bgp_attr_extra_free (&attr
);
5848 bgp_unlock_node (bn
);
5853 /* The attribute is changed. */
5854 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5856 /* Rewrite BGP route information. */
5857 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5858 bgp_info_restore(bn
, bi
);
5860 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5861 bgp_attr_unintern (&bi
->attr
);
5862 bi
->attr
= new_attr
;
5863 bi
->uptime
= bgp_clock ();
5865 /* Process change. */
5866 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5867 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5868 bgp_unlock_node (bn
);
5869 aspath_unintern (&attr
.aspath
);
5870 bgp_attr_extra_free (&attr
);
5875 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5877 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5879 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5880 bgp_info_add (bn
, new);
5881 bgp_unlock_node (bn
);
5882 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5885 /* Unintern original. */
5886 aspath_unintern (&attr
.aspath
);
5887 bgp_attr_extra_free (&attr
);
5891 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5894 struct bgp_node
*rn
;
5895 struct bgp_info
*ri
;
5896 struct bgp_redist
*red
;
5898 afi
= family2afi (p
->family
);
5900 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5903 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5905 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5906 if (ri
->peer
== bgp
->peer_self
5907 && ri
->type
== type
)
5912 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5913 bgp_info_delete (rn
, ri
);
5914 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5916 bgp_unlock_node (rn
);
5920 /* Withdraw specified route type's route. */
5922 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5924 struct bgp_node
*rn
;
5925 struct bgp_info
*ri
;
5926 struct bgp_table
*table
;
5928 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5930 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5932 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5933 if (ri
->peer
== bgp
->peer_self
5935 && ri
->instance
== instance
)
5940 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5941 bgp_info_delete (rn
, ri
);
5942 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5947 /* Static function to display route. */
5949 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5952 u_int32_t destination
;
5955 if (p
->family
== AF_INET
)
5957 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5958 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5960 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5961 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5962 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5963 || p
->u
.prefix4
.s_addr
== 0)
5965 /* When mask is natural, mask is not displayed. */
5968 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5970 else if (p
->family
== AF_ETHERNET
)
5972 prefix2str(p
, buf
, PREFIX_STRLEN
);
5973 len
= vty_out (vty
, "%s", buf
);
5976 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5981 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5983 vty_out (vty
, "%*s", len
, " ");
5986 enum bgp_display_type
5991 /* Print the short form route status for a bgp_info */
5993 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5994 json_object
*json_path
)
5999 /* Route status display. */
6000 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6001 json_object_boolean_true_add(json_path
, "removed");
6003 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6004 json_object_boolean_true_add(json_path
, "stale");
6006 if (binfo
->extra
&& binfo
->extra
->suppress
)
6007 json_object_boolean_true_add(json_path
, "suppressed");
6009 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6010 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6011 json_object_boolean_true_add(json_path
, "valid");
6014 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6015 json_object_boolean_true_add(json_path
, "history");
6017 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6018 json_object_boolean_true_add(json_path
, "damped");
6020 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6021 json_object_boolean_true_add(json_path
, "bestpath");
6023 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6024 json_object_boolean_true_add(json_path
, "multipath");
6026 /* Internal route. */
6027 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6028 json_object_string_add(json_path
, "pathFrom", "internal");
6030 json_object_string_add(json_path
, "pathFrom", "external");
6035 /* Route status display. */
6036 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6038 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6040 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6042 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
6043 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6049 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6051 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6053 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
6055 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
6060 /* Internal route. */
6062 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6068 /* called from terminal list command */
6070 route_vty_out (struct vty
*vty
, struct prefix
*p
,
6071 struct bgp_info
*binfo
, int display
, safi_t safi
,
6072 json_object
*json_paths
)
6075 json_object
*json_path
= NULL
;
6076 json_object
*json_nexthops
= NULL
;
6077 json_object
*json_nexthop_global
= NULL
;
6078 json_object
*json_nexthop_ll
= NULL
;
6081 json_path
= json_object_new_object();
6083 /* short status lead text */
6084 route_vty_short_status_out (vty
, binfo
, json_path
);
6088 /* print prefix and mask */
6090 route_vty_out_route (p
, vty
);
6092 vty_out (vty
, "%*s", 17, " ");
6095 /* Print attribute */
6100 * For ENCAP routes, nexthop address family is not
6101 * neccessarily the same as the prefix address family.
6102 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6104 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6109 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6114 vty_out (vty
, "%s", inet_ntop(af
,
6115 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6118 vty_out (vty
, "%s", inet_ntop(af
,
6119 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6130 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6134 json_nexthop_global
= json_object_new_object();
6136 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6137 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6139 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6141 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6142 json_object_boolean_true_add(json_nexthop_global
, "used");
6146 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6147 vty_out (vty
, "%-16s",
6148 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6150 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6155 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6162 json_nexthop_global
= json_object_new_object();
6163 json_object_string_add(json_nexthop_global
, "ip",
6164 inet_ntop (AF_INET6
,
6165 &attr
->extra
->mp_nexthop_global
,
6167 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6168 json_object_string_add(json_nexthop_global
, "scope", "global");
6170 /* We display both LL & GL if both have been received */
6171 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6173 json_nexthop_ll
= json_object_new_object();
6174 json_object_string_add(json_nexthop_ll
, "ip",
6175 inet_ntop (AF_INET6
,
6176 &attr
->extra
->mp_nexthop_local
,
6178 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6179 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6181 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6182 &attr
->extra
->mp_nexthop_local
) != 0) &&
6183 !attr
->extra
->mp_nexthop_prefer_global
)
6184 json_object_boolean_true_add(json_nexthop_ll
, "used");
6186 json_object_boolean_true_add(json_nexthop_global
, "used");
6189 json_object_boolean_true_add(json_nexthop_global
, "used");
6193 /* Display LL if LL/Global both in table unless prefer-global is set */
6194 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6195 !attr
->extra
->mp_nexthop_prefer_global
) ||
6196 (binfo
->peer
->conf_if
))
6198 if (binfo
->peer
->conf_if
)
6200 len
= vty_out (vty
, "%s",
6201 binfo
->peer
->conf_if
);
6202 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6205 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6207 vty_out (vty
, "%*s", len
, " ");
6211 len
= vty_out (vty
, "%s",
6212 inet_ntop (AF_INET6
,
6213 &attr
->extra
->mp_nexthop_local
,
6218 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6220 vty_out (vty
, "%*s", len
, " ");
6225 len
= vty_out (vty
, "%s",
6226 inet_ntop (AF_INET6
,
6227 &attr
->extra
->mp_nexthop_global
,
6232 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6234 vty_out (vty
, "%*s", len
, " ");
6240 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6242 json_object_int_add(json_path
, "med", attr
->med
);
6244 vty_out (vty
, "%10u", attr
->med
);
6250 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6252 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6254 vty_out (vty
, "%7u", attr
->local_pref
);
6262 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6264 json_object_int_add(json_path
, "weight", 0);
6267 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6271 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6278 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6280 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6285 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6287 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6292 json_object_string_add(json_path
, "alert", "No attributes");
6294 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6299 if (json_nexthop_global
|| json_nexthop_ll
)
6301 json_nexthops
= json_object_new_array();
6303 if (json_nexthop_global
)
6304 json_object_array_add(json_nexthops
, json_nexthop_global
);
6306 if (json_nexthop_ll
)
6307 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6309 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6312 json_object_array_add(json_paths
, json_path
);
6316 vty_out (vty
, "%s", VTY_NEWLINE
);
6318 /* prints an additional line, indented, with VNC info, if present */
6319 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6320 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6325 /* called from terminal list command */
6327 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6328 u_char use_json
, json_object
*json_ar
)
6330 json_object
*json_status
= NULL
;
6331 json_object
*json_net
= NULL
;
6333 /* Route status display. */
6336 json_status
= json_object_new_object();
6337 json_net
= json_object_new_object();
6346 /* print prefix and mask */
6348 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6350 route_vty_out_route (p
, vty
);
6352 /* Print attribute */
6357 if (p
->family
== AF_INET
&&
6358 (safi
== SAFI_MPLS_VPN
||
6359 safi
== SAFI_ENCAP
||
6360 safi
== SAFI_EVPN
||
6361 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6363 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6364 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6366 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6368 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6372 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6376 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6377 json_object_int_add(json_net
, "metric", attr
->med
);
6379 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6380 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6383 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6385 json_object_int_add(json_net
, "weight", 0);
6389 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6392 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6396 if (p
->family
== AF_INET
&&
6397 (safi
== SAFI_MPLS_VPN
||
6398 safi
== SAFI_ENCAP
||
6399 safi
== SAFI_EVPN
||
6400 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6402 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6403 vty_out (vty
, "%-16s",
6404 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6406 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6408 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6413 assert (attr
->extra
);
6415 len
= vty_out (vty
, "%s",
6416 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6420 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6422 vty_out (vty
, "%*s", len
, " ");
6424 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6425 vty_out (vty
, "%10u", attr
->med
);
6429 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6430 vty_out (vty
, "%7u", attr
->local_pref
);
6434 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6438 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6441 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6446 json_object_boolean_true_add(json_status
, "*");
6447 json_object_boolean_true_add(json_status
, ">");
6448 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6449 char buf_cut
[BUFSIZ
];
6450 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6453 vty_out (vty
, "%s", VTY_NEWLINE
);
6457 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6458 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6460 json_object
*json_out
= NULL
;
6462 u_int32_t label
= 0;
6468 json_out
= json_object_new_object();
6470 /* short status lead text */
6471 route_vty_short_status_out (vty
, binfo
, json_out
);
6473 /* print prefix and mask */
6477 route_vty_out_route (p
, vty
);
6479 vty_out (vty
, "%*s", 17, " ");
6482 /* Print attribute */
6486 if (((p
->family
== AF_INET
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6487 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6488 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6490 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6493 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6495 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6500 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6502 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6505 else if (((p
->family
== AF_INET6
) && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6506 || (safi
== SAFI_EVPN
&& p
->family
== AF_ETHERNET
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6507 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6509 assert (attr
->extra
);
6513 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6516 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6517 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6520 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6523 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6527 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6529 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6531 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6532 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6535 vty_out (vty
, "%s(%s)",
6536 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6538 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6545 label
= decode_label (binfo
->extra
->tag
);
6550 json_object_int_add(json_out
, "notag", label
);
6551 json_object_array_add(json
, json_out
);
6555 vty_out (vty
, "notag/%d", label
);
6557 vty_out (vty
, "%s", VTY_NEWLINE
);
6562 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6563 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6567 json_object
*json_path
= NULL
;
6570 json_path
= json_object_new_object();
6575 /* short status lead text */
6576 route_vty_short_status_out (vty
, binfo
, json_path
);
6578 /* print prefix and mask */
6580 route_vty_out_route (p
, vty
);
6582 vty_out (vty
, "%*s", 17, " ");
6584 /* Print attribute */
6591 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6595 vty_out (vty
, "%-16s", inet_ntop(af
,
6596 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6599 vty_out (vty
, "%s(%s)",
6601 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6603 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6615 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6616 char *str
= esi2str(id
);
6617 vty_out (vty
, "%s", str
);
6618 XFREE (MTYPE_TMP
, str
);
6619 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6621 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6623 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6625 vty_out (vty
, "/%s",
6626 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6629 if(attr
->extra
->ecommunity
)
6632 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6633 ECOMMUNITY_ENCODE_EVPN
,
6634 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6636 mac
= ecom_mac2str((char *)routermac
->val
);
6639 vty_out (vty
, "/%s",(char *)mac
);
6640 XFREE(MTYPE_TMP
, mac
);
6644 vty_out (vty
, "%s", VTY_NEWLINE
);
6647 /* dampening route */
6649 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6650 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6654 char timebuf
[BGP_UPTIME_LEN
];
6656 /* short status lead text */
6657 route_vty_short_status_out (vty
, binfo
, json
);
6659 /* print prefix and mask */
6663 route_vty_out_route (p
, vty
);
6665 vty_out (vty
, "%*s", 17, " ");
6668 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6673 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6678 json_object_int_add(json
, "peerHost", len
);
6680 vty_out (vty
, "%*s", len
, " ");
6684 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6686 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6688 /* Print attribute */
6696 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6698 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6703 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6705 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6708 vty_out (vty
, "%s", VTY_NEWLINE
);
6713 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6714 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6717 struct bgp_damp_info
*bdi
;
6718 char timebuf
[BGP_UPTIME_LEN
];
6724 bdi
= binfo
->extra
->damp_info
;
6726 /* short status lead text */
6727 route_vty_short_status_out (vty
, binfo
, json
);
6729 /* print prefix and mask */
6733 route_vty_out_route (p
, vty
);
6735 vty_out (vty
, "%*s", 17, " ");
6738 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6743 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6748 json_object_int_add(json
, "peerHost", len
);
6750 vty_out (vty
, "%*s", len
, " ");
6753 len
= vty_out (vty
, "%d", bdi
->flap
);
6763 json_object_int_add(json
, "bdiFlap", len
);
6765 vty_out (vty
, "%*s", len
, " ");
6769 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6771 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6772 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6774 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6775 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6778 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6780 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6785 vty_out (vty
, "%*s ", 8, " ");
6788 /* Print attribute */
6796 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6798 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6803 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6805 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6808 vty_out (vty
, "%s", VTY_NEWLINE
);
6812 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6813 const char *header
, json_object
*json_adv_to
)
6815 char buf1
[INET6_ADDRSTRLEN
];
6816 json_object
*json_peer
= NULL
;
6820 /* 'advertised-to' is a dictionary of peers we have advertised this
6821 * prefix too. The key is the peer's IP or swpX, the value is the
6822 * hostname if we know it and "" if not.
6824 json_peer
= json_object_new_object();
6827 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6830 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6832 json_object_object_add(json_adv_to
,
6833 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6840 vty_out (vty
, "%s", header
);
6844 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6847 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6849 vty_out (vty
, " %s(%s)", peer
->hostname
,
6850 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6855 vty_out (vty
, " %s", peer
->conf_if
);
6857 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6863 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6864 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6865 json_object
*json_paths
)
6867 char buf
[INET6_ADDRSTRLEN
];
6870 int sockunion_vty_out (struct vty
*, union sockunion
*);
6872 json_object
*json_bestpath
= NULL
;
6873 json_object
*json_cluster_list
= NULL
;
6874 json_object
*json_cluster_list_list
= NULL
;
6875 json_object
*json_ext_community
= NULL
;
6876 json_object
*json_last_update
= NULL
;
6877 json_object
*json_nexthop_global
= NULL
;
6878 json_object
*json_nexthop_ll
= NULL
;
6879 json_object
*json_nexthops
= NULL
;
6880 json_object
*json_path
= NULL
;
6881 json_object
*json_peer
= NULL
;
6882 json_object
*json_string
= NULL
;
6883 json_object
*json_adv_to
= NULL
;
6885 struct listnode
*node
, *nnode
;
6887 int addpath_capable
;
6889 unsigned int first_as
;
6893 json_path
= json_object_new_object();
6894 json_peer
= json_object_new_object();
6895 json_nexthop_global
= json_object_new_object();
6902 /* Line1 display AS-path, Aggregator */
6907 json_object_lock(attr
->aspath
->json
);
6908 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6912 if (attr
->aspath
->segments
)
6913 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6915 vty_out (vty
, " Local");
6919 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6922 json_object_boolean_true_add(json_path
, "removed");
6924 vty_out (vty
, ", (removed)");
6927 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6930 json_object_boolean_true_add(json_path
, "stale");
6932 vty_out (vty
, ", (stale)");
6935 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6939 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6940 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6944 vty_out (vty
, ", (aggregated by %u %s)",
6945 attr
->extra
->aggregator_as
,
6946 inet_ntoa (attr
->extra
->aggregator_addr
));
6950 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6953 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6955 vty_out (vty
, ", (Received from a RR-client)");
6958 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6961 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6963 vty_out (vty
, ", (Received from a RS-client)");
6966 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6969 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6971 vty_out (vty
, ", (history entry)");
6973 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6976 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6978 vty_out (vty
, ", (suppressed due to dampening)");
6982 vty_out (vty
, "%s", VTY_NEWLINE
);
6984 /* Line2 display Next-hop, Neighbor, Router-id */
6985 /* Display the nexthop */
6986 if (p
->family
== AF_INET
&&
6987 (safi
== SAFI_MPLS_VPN
||
6988 safi
== SAFI_ENCAP
||
6989 safi
== SAFI_EVPN
||
6990 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6992 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6995 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6997 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
7002 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
7004 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
7008 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
7012 assert (attr
->extra
);
7015 json_object_string_add(json_nexthop_global
, "ip",
7016 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7017 buf
, INET6_ADDRSTRLEN
));
7018 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
7019 json_object_string_add(json_nexthop_global
, "scope", "global");
7023 vty_out (vty
, " %s",
7024 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
7025 buf
, INET6_ADDRSTRLEN
));
7029 /* Display the IGP cost or 'inaccessible' */
7030 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7033 json_object_boolean_false_add(json_nexthop_global
, "accessible");
7035 vty_out (vty
, " (inaccessible)");
7039 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
7042 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
7044 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
7047 /* IGP cost is 0, display this only for json */
7051 json_object_int_add(json_nexthop_global
, "metric", 0);
7055 json_object_boolean_true_add(json_nexthop_global
, "accessible");
7058 /* Display peer "from" output */
7059 /* This path was originated locally */
7060 if (binfo
->peer
== bgp
->peer_self
)
7063 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7066 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
7068 vty_out (vty
, " from 0.0.0.0 ");
7073 json_object_string_add(json_peer
, "peerId", "::");
7075 vty_out (vty
, " from :: ");
7079 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
7081 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7084 /* We RXed this path from one of our peers */
7090 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7091 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7093 if (binfo
->peer
->hostname
)
7094 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7096 if (binfo
->peer
->domainname
)
7097 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7099 if (binfo
->peer
->conf_if
)
7100 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7104 if (binfo
->peer
->conf_if
)
7106 if (binfo
->peer
->hostname
&&
7107 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7108 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7109 binfo
->peer
->conf_if
);
7111 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7115 if (binfo
->peer
->hostname
&&
7116 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7117 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7120 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7123 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7124 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7126 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7131 vty_out (vty
, "%s", VTY_NEWLINE
);
7133 /* display the link-local nexthop */
7134 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7138 json_nexthop_ll
= json_object_new_object();
7139 json_object_string_add(json_nexthop_ll
, "ip",
7140 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7141 buf
, INET6_ADDRSTRLEN
));
7142 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7143 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7145 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7147 if (!attr
->extra
->mp_nexthop_prefer_global
)
7148 json_object_boolean_true_add(json_nexthop_ll
, "used");
7150 json_object_boolean_true_add(json_nexthop_global
, "used");
7154 vty_out (vty
, " (%s) %s%s",
7155 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7156 buf
, INET6_ADDRSTRLEN
),
7157 attr
->extra
->mp_nexthop_prefer_global
?
7158 "(prefer-global)" : "(used)",
7162 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7166 json_object_boolean_true_add(json_nexthop_global
, "used");
7169 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7171 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7173 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7175 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7178 json_object_int_add(json_path
, "med", attr
->med
);
7180 vty_out (vty
, ", metric %u", attr
->med
);
7183 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7186 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7188 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7193 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7195 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7198 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7201 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7203 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7206 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7209 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7211 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7214 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7217 json_object_boolean_false_add(json_path
, "valid");
7219 vty_out (vty
, ", invalid");
7221 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7224 json_object_boolean_true_add(json_path
, "valid");
7226 vty_out (vty
, ", valid");
7229 if (binfo
->peer
!= bgp
->peer_self
)
7231 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7233 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7236 json_object_string_add(json_peer
, "type", "confed-internal");
7238 vty_out (vty
, ", confed-internal");
7243 json_object_string_add(json_peer
, "type", "internal");
7245 vty_out (vty
, ", internal");
7250 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7253 json_object_string_add(json_peer
, "type", "confed-external");
7255 vty_out (vty
, ", confed-external");
7260 json_object_string_add(json_peer
, "type", "external");
7262 vty_out (vty
, ", external");
7266 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7270 json_object_boolean_true_add(json_path
, "aggregated");
7271 json_object_boolean_true_add(json_path
, "local");
7275 vty_out (vty
, ", aggregated, local");
7278 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7281 json_object_boolean_true_add(json_path
, "sourced");
7283 vty_out (vty
, ", sourced");
7289 json_object_boolean_true_add(json_path
, "sourced");
7290 json_object_boolean_true_add(json_path
, "local");
7294 vty_out (vty
, ", sourced, local");
7298 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7301 json_object_boolean_true_add(json_path
, "atomicAggregate");
7303 vty_out (vty
, ", atomic-aggregate");
7306 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7307 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7308 bgp_info_mpath_count (binfo
)))
7311 json_object_boolean_true_add(json_path
, "multipath");
7313 vty_out (vty
, ", multipath");
7316 // Mark the bestpath(s)
7317 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7319 first_as
= aspath_get_first_as(attr
->aspath
);
7324 json_bestpath
= json_object_new_object();
7325 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7330 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7332 vty_out (vty
, ", bestpath-from-AS Local");
7336 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7341 json_bestpath
= json_object_new_object();
7342 json_object_boolean_true_add(json_bestpath
, "overall");
7345 vty_out (vty
, ", best");
7349 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7352 vty_out (vty
, "%s", VTY_NEWLINE
);
7354 /* Line 4 display Community */
7355 if (attr
->community
)
7359 json_object_lock(attr
->community
->json
);
7360 json_object_object_add(json_path
, "community", attr
->community
->json
);
7364 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7369 /* Line 5 display Extended-community */
7370 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7374 json_ext_community
= json_object_new_object();
7375 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7376 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7380 vty_out (vty
, " Extended Community: %s%s",
7381 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7385 /* Line 6 display Large community */
7386 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7387 vty_out (vty
, " Large Community: %s%s",
7388 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7390 /* Line 7 display Originator, Cluster-id */
7391 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7392 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7394 assert (attr
->extra
);
7395 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7398 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7400 vty_out (vty
, " Originator: %s",
7401 inet_ntoa (attr
->extra
->originator_id
));
7404 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7410 json_cluster_list
= json_object_new_object();
7411 json_cluster_list_list
= json_object_new_array();
7413 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7415 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7416 json_object_array_add(json_cluster_list_list
, json_string
);
7419 /* struct cluster_list does not have "str" variable like
7420 * aspath and community do. Add this someday if someone
7422 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7424 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7425 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7429 vty_out (vty
, ", Cluster list: ");
7431 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7433 vty_out (vty
, "%s ",
7434 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7440 vty_out (vty
, "%s", VTY_NEWLINE
);
7443 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7444 bgp_damp_info_vty (vty
, binfo
, json_path
);
7446 /* Line 8 display Addpath IDs */
7447 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7451 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7452 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7456 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7457 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7462 /* If we used addpath to TX a non-bestpath we need to display
7463 * "Advertised to" on a path-by-path basis */
7464 if (bgp
->addpath_tx_used
[afi
][safi
])
7468 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7470 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7471 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7473 if ((addpath_capable
&& has_adj
) ||
7474 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7476 if (json_path
&& !json_adv_to
)
7477 json_adv_to
= json_object_new_object();
7479 route_vty_out_advertised_to(vty
, peer
, &first
,
7489 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7496 vty_out (vty
, "%s", VTY_NEWLINE
);
7501 /* Line 9 display Uptime */
7502 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7505 json_last_update
= json_object_new_object();
7506 json_object_int_add(json_last_update
, "epoch", tbuf
);
7507 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7508 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7511 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7514 /* We've constructed the json object for this path, add it to the json
7519 if (json_nexthop_global
|| json_nexthop_ll
)
7521 json_nexthops
= json_object_new_array();
7523 if (json_nexthop_global
)
7524 json_object_array_add(json_nexthops
, json_nexthop_global
);
7526 if (json_nexthop_ll
)
7527 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7529 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7532 json_object_object_add(json_path
, "peer", json_peer
);
7533 json_object_array_add(json_paths
, json_path
);
7536 vty_out (vty
, "%s", VTY_NEWLINE
);
7539 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7540 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7541 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7544 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7545 const char *prefix_list_str
, afi_t afi
,
7546 safi_t safi
, enum bgp_show_type type
);
7548 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7549 const char *filter
, afi_t afi
,
7550 safi_t safi
, enum bgp_show_type type
);
7552 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7553 const char *rmap_str
, afi_t afi
,
7554 safi_t safi
, enum bgp_show_type type
);
7556 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7557 const char *com
, int exact
,
7558 afi_t afi
, safi_t safi
);
7560 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7561 const char *prefix
, afi_t afi
,
7562 safi_t safi
, enum bgp_show_type type
);
7564 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7565 safi_t safi
, enum bgp_show_type type
);
7567 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7568 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7571 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7572 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7574 struct bgp_info
*ri
;
7575 struct bgp_node
*rn
;
7578 unsigned long output_count
;
7579 unsigned long total_count
;
7583 json_object
*json_paths
= NULL
;
7588 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7589 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7590 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7591 table
->version
, inet_ntoa (bgp
->router_id
));
7592 json_paths
= json_object_new_object();
7595 /* This is first entry point, so reset total line. */
7599 /* Start processing of routes. */
7600 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7601 if (rn
->info
!= NULL
)
7604 if (!first
&& use_json
)
7609 json_paths
= json_object_new_array();
7613 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7616 if (type
== bgp_show_type_flap_statistics
7617 || type
== bgp_show_type_flap_neighbor
7618 || type
== bgp_show_type_dampend_paths
7619 || type
== bgp_show_type_damp_neighbor
)
7621 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7624 if (type
== bgp_show_type_regexp
)
7626 regex_t
*regex
= output_arg
;
7628 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7631 if (type
== bgp_show_type_prefix_list
)
7633 struct prefix_list
*plist
= output_arg
;
7635 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7638 if (type
== bgp_show_type_filter_list
)
7640 struct as_list
*as_list
= output_arg
;
7642 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7645 if (type
== bgp_show_type_route_map
)
7647 struct route_map
*rmap
= output_arg
;
7648 struct bgp_info binfo
;
7649 struct attr dummy_attr
;
7650 struct attr_extra dummy_extra
;
7653 dummy_attr
.extra
= &dummy_extra
;
7654 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7656 binfo
.peer
= ri
->peer
;
7657 binfo
.attr
= &dummy_attr
;
7659 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7660 if (ret
== RMAP_DENYMATCH
)
7663 if (type
== bgp_show_type_neighbor
7664 || type
== bgp_show_type_flap_neighbor
7665 || type
== bgp_show_type_damp_neighbor
)
7667 union sockunion
*su
= output_arg
;
7669 if (ri
->peer
== NULL
||
7670 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7673 if (type
== bgp_show_type_cidr_only
)
7675 u_int32_t destination
;
7677 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7678 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7680 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7682 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7685 if (type
== bgp_show_type_prefix_longer
)
7687 struct prefix
*p
= output_arg
;
7689 if (! prefix_match (p
, &rn
->p
))
7692 if (type
== bgp_show_type_community_all
)
7694 if (! ri
->attr
->community
)
7697 if (type
== bgp_show_type_community
)
7699 struct community
*com
= output_arg
;
7701 if (! ri
->attr
->community
||
7702 ! community_match (ri
->attr
->community
, com
))
7705 if (type
== bgp_show_type_community_exact
)
7707 struct community
*com
= output_arg
;
7709 if (! ri
->attr
->community
||
7710 ! community_cmp (ri
->attr
->community
, com
))
7713 if (type
== bgp_show_type_community_list
)
7715 struct community_list
*list
= output_arg
;
7717 if (! community_list_match (ri
->attr
->community
, list
))
7720 if (type
== bgp_show_type_community_list_exact
)
7722 struct community_list
*list
= output_arg
;
7724 if (! community_list_exact_match (ri
->attr
->community
, list
))
7727 if (type
== bgp_show_type_lcommunity
)
7729 struct lcommunity
*lcom
= output_arg
;
7731 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7732 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7735 if (type
== bgp_show_type_lcommunity_list
)
7737 struct community_list
*list
= output_arg
;
7739 if (! ri
->attr
->extra
||
7740 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7743 if (type
== bgp_show_type_lcommunity_all
)
7745 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7748 if (type
== bgp_show_type_dampend_paths
7749 || type
== bgp_show_type_damp_neighbor
)
7751 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7752 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7756 if (!use_json
&& header
)
7758 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7759 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7760 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7761 if (type
== bgp_show_type_dampend_paths
7762 || type
== bgp_show_type_damp_neighbor
)
7763 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7764 else if (type
== bgp_show_type_flap_statistics
7765 || type
== bgp_show_type_flap_neighbor
)
7766 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7768 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7772 if (type
== bgp_show_type_dampend_paths
7773 || type
== bgp_show_type_damp_neighbor
)
7774 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7775 else if (type
== bgp_show_type_flap_statistics
7776 || type
== bgp_show_type_flap_neighbor
)
7777 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7779 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7789 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7790 vty_out (vty
, "\"%s\": ", buf2
);
7791 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7792 json_object_free (json_paths
);
7801 json_object_free (json_paths
);
7802 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7806 /* No route is displayed */
7807 if (output_count
== 0)
7809 if (type
== bgp_show_type_normal
)
7810 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7813 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7814 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7821 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7822 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7824 struct bgp_table
*table
;
7828 bgp
= bgp_get_default ();
7834 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7837 /* use MPLS and ENCAP specific shows until they are merged */
7838 if (safi
== SAFI_MPLS_VPN
)
7840 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
7843 if (safi
== SAFI_ENCAP
)
7845 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
7850 table
= bgp
->rib
[afi
][safi
];
7852 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7857 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7860 struct listnode
*node
, *nnode
;
7862 struct bgp_table
*table
;
7866 vty_out (vty
, "{%s", VTY_NEWLINE
);
7868 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7873 vty_out (vty
, ",%s", VTY_NEWLINE
);
7877 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7878 ? "Default" : bgp
->name
);
7882 vty_out (vty
, "%sInstance %s:%s",
7884 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7885 ? "Default" : bgp
->name
,
7888 table
= bgp
->rib
[afi
][safi
];
7889 bgp_show_table (vty
, bgp
, table
,
7890 bgp_show_type_normal
, NULL
, use_json
);
7895 vty_out (vty
, "}%s", VTY_NEWLINE
);
7898 /* Header of detailed BGP route information */
7900 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7901 struct bgp_node
*rn
,
7902 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7905 struct bgp_info
*ri
;
7908 struct listnode
*node
, *nnode
;
7909 char buf1
[INET6_ADDRSTRLEN
];
7910 char buf2
[INET6_ADDRSTRLEN
];
7915 int no_advertise
= 0;
7918 json_object
*json_adv_to
= NULL
;
7924 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7925 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7929 if (p
->family
== AF_ETHERNET
)
7930 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
7932 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
7933 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7934 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
7935 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7936 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
7938 p
->prefixlen
, VTY_NEWLINE
);
7941 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7944 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7947 if (ri
->extra
&& ri
->extra
->suppress
)
7949 if (ri
->attr
->community
!= NULL
)
7951 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7953 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7955 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7963 vty_out (vty
, "Paths: (%d available", count
);
7966 vty_out (vty
, ", best #%d", best
);
7967 if (safi
== SAFI_UNICAST
)
7968 vty_out (vty
, ", table %s",
7969 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7970 ? "Default-IP-Routing-Table" : bgp
->name
);
7973 vty_out (vty
, ", no best path");
7976 vty_out (vty
, ", not advertised to any peer");
7978 vty_out (vty
, ", not advertised to EBGP peer");
7980 vty_out (vty
, ", not advertised outside local AS");
7983 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7984 vty_out (vty
, ")%s", VTY_NEWLINE
);
7987 /* If we are not using addpath then we can display Advertised to and that will
7988 * show what peers we advertised the bestpath to. If we are using addpath
7989 * though then we must display Advertised to on a path-by-path basis. */
7990 if (!bgp
->addpath_tx_used
[afi
][safi
])
7992 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7994 if (bgp_adj_out_lookup (peer
, rn
, 0))
7996 if (json
&& !json_adv_to
)
7997 json_adv_to
= json_object_new_object();
7999 route_vty_out_advertised_to(vty
, peer
, &first
,
8000 " Advertised to non peer-group peers:\n ",
8009 json_object_object_add(json
, "advertisedTo", json_adv_to
);
8015 vty_out (vty
, " Not advertised to any peer");
8016 vty_out (vty
, "%s", VTY_NEWLINE
);
8021 /* Display specified route of BGP table. */
8023 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
8024 struct bgp_table
*rib
, const char *ip_str
,
8025 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8026 int prefix_check
, enum bgp_path_type pathtype
,
8032 struct prefix match
;
8033 struct bgp_node
*rn
;
8034 struct bgp_node
*rm
;
8035 struct bgp_info
*ri
;
8036 struct bgp_table
*table
;
8037 json_object
*json
= NULL
;
8038 json_object
*json_paths
= NULL
;
8040 /* Check IP address argument. */
8041 ret
= str2prefix (ip_str
, &match
);
8044 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
8048 match
.family
= afi2family (afi
);
8052 json
= json_object_new_object();
8053 json_paths
= json_object_new_array();
8056 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
8058 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
8060 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
8063 if ((table
= rn
->info
) != NULL
)
8067 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
8069 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
8071 bgp_unlock_node (rm
);
8075 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
8079 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
8080 AFI_IP
, safi
, json
);
8085 if (pathtype
== BGP_PATH_ALL
||
8086 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8087 (pathtype
== BGP_PATH_MULTIPATH
&&
8088 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8089 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8092 bgp_unlock_node (rm
);
8101 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8103 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8105 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8109 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8114 if (pathtype
== BGP_PATH_ALL
||
8115 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8116 (pathtype
== BGP_PATH_MULTIPATH
&&
8117 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8118 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8122 bgp_unlock_node (rn
);
8129 json_object_object_add(json
, "paths", json_paths
);
8131 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8132 json_object_free(json
);
8138 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8146 /* Display specified route of Main RIB */
8148 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8149 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8150 int prefix_check
, enum bgp_path_type pathtype
,
8154 bgp
= bgp_get_default ();
8156 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8157 afi
, safi
, prd
, prefix_check
, pathtype
,
8162 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8163 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8165 struct lcommunity
*lcom
;
8171 b
= buffer_new (1024);
8172 for (i
= 0; i
< argc
; i
++)
8175 buffer_putc (b
, ' ');
8178 if (strmatch (argv
[i
]->text
, "AA:BB:CC"))
8181 buffer_putstr (b
, argv
[i
]->arg
);
8185 buffer_putc (b
, '\0');
8187 str
= buffer_getstr (b
);
8190 lcom
= lcommunity_str2com (str
);
8191 XFREE (MTYPE_TMP
, str
);
8194 vty_out (vty
, "%% Large-community malformed%s", VTY_NEWLINE
);
8198 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8202 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8203 afi_t afi
, safi_t safi
, u_char uj
)
8205 struct community_list
*list
;
8207 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8210 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8215 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8218 DEFUN (show_ip_bgp_large_community_list
,
8219 show_ip_bgp_large_community_list_cmd
,
8220 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
8224 BGP_INSTANCE_HELP_STR
8227 "Address Family modifier\n"
8228 "Address Family modifier\n"
8229 "Address Family modifier\n"
8230 "Address Family modifier\n"
8231 "Display routes matching the large-community-list\n"
8232 "large-community-list number\n"
8233 "large-community-list name\n"
8237 afi_t afi
= AFI_IP6
;
8238 safi_t safi
= SAFI_UNICAST
;
8241 if (argv_find (argv
, argc
, "ip", &idx
))
8243 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8244 vrf
= argv
[++idx
]->arg
;
8245 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8247 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8248 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8249 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8252 int uj
= use_json (argc
, argv
);
8254 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8257 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8261 argv_find (argv
, argc
, "large-community-list", &idx
);
8262 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8264 DEFUN (show_ip_bgp_large_community
,
8265 show_ip_bgp_large_community_cmd
,
8266 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
8270 BGP_INSTANCE_HELP_STR
8273 "Address Family modifier\n"
8274 "Address Family modifier\n"
8275 "Address Family modifier\n"
8276 "Address Family modifier\n"
8277 "Display routes matching the large-communities\n"
8278 "List of large-community numbers\n"
8282 afi_t afi
= AFI_IP6
;
8283 safi_t safi
= SAFI_UNICAST
;
8286 if (argv_find (argv
, argc
, "ip", &idx
))
8288 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8289 vrf
= argv
[++idx
]->arg
;
8290 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8292 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8293 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8294 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8297 int uj
= use_json (argc
, argv
);
8299 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8302 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8306 if (argv_find (argv
, argc
, "AA:BB:CC", &idx
))
8307 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8309 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8312 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8314 /* BGP route print out function. */
8317 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8320 |dampening <flap-statistics|dampened-paths|parameters>\
8325 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8326 |community-list <(1-500)|WORD> [exact-match]\
8327 |A.B.C.D/M longer-prefixes\
8328 |X:X::X:X/M longer-prefixes>\
8333 BGP_INSTANCE_HELP_STR
8336 "Display only routes with non-natural netmasks\n"
8337 "Display detailed information about dampening\n"
8338 "Display flap statistics of routes\n"
8339 "Display paths suppressed due to dampening\n"
8340 "Display detail of configured dampening parameters\n"
8341 "Display routes matching the route-map\n"
8342 "A route-map to match on\n"
8343 "Display routes conforming to the prefix-list\n"
8344 "Prefix-list name\n"
8345 "Display routes conforming to the filter-list\n"
8346 "Regular expression access list name\n"
8347 "BGP RIB advertisement statistics\n"
8348 "Display routes matching the communities\n"
8350 "Do not send outside local AS (well-known community)\n"
8351 "Do not advertise to any peer (well-known community)\n"
8352 "Do not export to next AS (well-known community)\n"
8353 "Exact match of the communities\n"
8354 "Display routes matching the community-list\n"
8355 "community-list number\n"
8356 "community-list name\n"
8357 "Exact match of the communities\n"
8359 "Display route and more specific routes\n"
8361 "Display route and more specific routes\n"
8364 afi_t afi
= AFI_IP6
;
8365 safi_t safi
= SAFI_UNICAST
;
8366 int exact_match
= 0;
8367 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8368 struct bgp
*bgp
= NULL
;
8371 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8375 int uj
= use_json (argc
, argv
);
8378 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8379 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8381 if (argv_find(argv
, argc
, "dampening", &idx
))
8383 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8384 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8385 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8386 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8387 else if (argv_find (argv
, argc
, "parameters", &idx
))
8388 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8391 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8392 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8394 if (argv_find(argv
, argc
, "filter-list", &idx
))
8395 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8397 if (argv_find(argv
, argc
, "statistics", &idx
))
8398 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8400 if (argv_find(argv
, argc
, "route-map", &idx
))
8401 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8403 if (argv_find(argv
, argc
, "community", &idx
))
8405 /* show a specific community */
8406 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8407 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8408 argv_find (argv
, argc
, "no-export", &idx
))
8410 if (argv_find (argv
, argc
, "exact_match", &idx
))
8412 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8414 /* show all communities */
8416 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8419 if (argv_find(argv
, argc
, "community-list", &idx
))
8421 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8422 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8424 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8427 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8428 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8430 if (safi
== SAFI_MPLS_VPN
)
8431 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8432 else if (safi
== SAFI_ENCAP
)
8433 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8435 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8438 DEFUN (show_ip_bgp_route
,
8439 show_ip_bgp_route_cmd
,
8440 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8441 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8445 BGP_INSTANCE_HELP_STR
8448 "Network in the BGP routing table to display\n"
8450 "Network in the BGP routing table to display\n"
8452 "Display only the bestpath\n"
8453 "Display only multipaths\n"
8456 int prefix_check
= 0;
8458 afi_t afi
= AFI_IP6
;
8459 safi_t safi
= SAFI_UNICAST
;
8460 char *prefix
= NULL
;
8461 struct bgp
*bgp
= NULL
;
8462 enum bgp_path_type path_type
;
8463 u_char uj
= use_json(argc
, argv
);
8467 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8473 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8477 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8478 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8480 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8483 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8485 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8488 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8490 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8494 prefix
= argv
[idx
]->arg
;
8496 /* [<bestpath|multipath>] */
8497 if (argv_find (argv
, argc
, "bestpath", &idx
))
8498 path_type
= BGP_PATH_BESTPATH
;
8499 else if (argv_find (argv
, argc
, "multipath", &idx
))
8500 path_type
= BGP_PATH_MULTIPATH
;
8502 path_type
= BGP_PATH_ALL
;
8504 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8507 DEFUN (show_ip_bgp_regexp
,
8508 show_ip_bgp_regexp_cmd
,
8509 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8513 BGP_INSTANCE_HELP_STR
8516 "Display routes matching the AS path regular expression\n"
8517 "A regular-expression to match the BGP AS paths\n")
8519 afi_t afi
= AFI_IP6
;
8520 safi_t safi
= SAFI_UNICAST
;
8521 struct bgp
*bgp
= NULL
;
8524 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8528 // get index of regex
8529 argv_find (argv
, argc
, "regexp", &idx
);
8532 char *regstr
= argv_concat (argv
, argc
, idx
);
8533 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8534 XFREE (MTYPE_TMP
, regstr
);
8538 DEFUN (show_ip_bgp_instance_all
,
8539 show_ip_bgp_instance_all_cmd
,
8540 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8544 BGP_INSTANCE_ALL_HELP_STR
8550 safi_t safi
= SAFI_UNICAST
;
8551 struct bgp
*bgp
= NULL
;
8554 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
8558 int uj
= use_json (argc
, argv
);
8561 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8566 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8567 safi_t safi
, enum bgp_show_type type
)
8572 regex
= bgp_regcomp (regstr
);
8575 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8579 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8580 bgp_regex_free (regex
);
8585 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8586 const char *prefix_list_str
, afi_t afi
,
8587 safi_t safi
, enum bgp_show_type type
)
8589 struct prefix_list
*plist
;
8591 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8594 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8595 prefix_list_str
, VTY_NEWLINE
);
8599 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8603 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8604 const char *filter
, afi_t afi
,
8605 safi_t safi
, enum bgp_show_type type
)
8607 struct as_list
*as_list
;
8609 as_list
= as_list_lookup (filter
);
8610 if (as_list
== NULL
)
8612 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8616 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8620 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8621 const char *rmap_str
, afi_t afi
,
8622 safi_t safi
, enum bgp_show_type type
)
8624 struct route_map
*rmap
;
8626 rmap
= route_map_lookup_by_name (rmap_str
);
8629 vty_out (vty
, "%% %s is not a valid route-map name%s",
8630 rmap_str
, VTY_NEWLINE
);
8634 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8638 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8639 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8641 struct community
*com
;
8647 b
= buffer_new (1024);
8648 for (i
= 0; i
< argc
; i
++)
8651 buffer_putc (b
, ' ');
8654 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8659 buffer_putstr (b
, argv
[i
]->arg
);
8661 buffer_putc (b
, '\0');
8663 str
= buffer_getstr (b
);
8666 com
= community_str2com (str
);
8667 XFREE (MTYPE_TMP
, str
);
8670 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8674 return bgp_show (vty
, bgp
, afi
, safi
,
8675 (exact
? bgp_show_type_community_exact
:
8676 bgp_show_type_community
), com
, 0);
8680 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8681 const char *com
, int exact
,
8682 afi_t afi
, safi_t safi
)
8684 struct community_list
*list
;
8686 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8689 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8694 return bgp_show (vty
, bgp
, afi
, safi
,
8695 (exact
? bgp_show_type_community_list_exact
:
8696 bgp_show_type_community_list
), list
, 0);
8700 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8701 const char *prefix
, afi_t afi
,
8702 safi_t safi
, enum bgp_show_type type
)
8709 ret
= str2prefix (prefix
, p
);
8712 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8716 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8721 static struct peer
*
8722 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8723 const char *ip_str
, u_char use_json
)
8729 /* Get peer sockunion. */
8730 ret
= str2sockunion (ip_str
, &su
);
8733 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8736 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8742 json_object
*json_no
= NULL
;
8743 json_no
= json_object_new_object();
8744 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8745 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8746 json_object_free(json_no
);
8749 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8756 /* Peer structure lookup. */
8757 peer
= peer_lookup (bgp
, &su
);
8762 json_object
*json_no
= NULL
;
8763 json_no
= json_object_new_object();
8764 json_object_string_add(json_no
, "warning","No such neighbor");
8765 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8766 json_object_free(json_no
);
8769 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8778 BGP_STATS_MAXBITLEN
= 0,
8782 BGP_STATS_UNAGGREGATEABLE
,
8783 BGP_STATS_MAX_AGGREGATEABLE
,
8784 BGP_STATS_AGGREGATES
,
8786 BGP_STATS_ASPATH_COUNT
,
8787 BGP_STATS_ASPATH_MAXHOPS
,
8788 BGP_STATS_ASPATH_TOTHOPS
,
8789 BGP_STATS_ASPATH_MAXSIZE
,
8790 BGP_STATS_ASPATH_TOTSIZE
,
8791 BGP_STATS_ASN_HIGHEST
,
8795 static const char *table_stats_strs
[] =
8797 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8798 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8799 [BGP_STATS_RIB
] = "Total Advertisements",
8800 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8801 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8802 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8803 [BGP_STATS_SPACE
] = "Address space advertised",
8804 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8805 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8806 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8807 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8808 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8809 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8810 [BGP_STATS_MAX
] = NULL
,
8813 struct bgp_table_stats
8815 struct bgp_table
*table
;
8816 unsigned long long counts
[BGP_STATS_MAX
];
8820 #define TALLY_SIGFIG 100000
8821 static unsigned long
8822 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8824 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8825 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8826 unsigned long ret
= newtot
/ count
;
8828 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8836 bgp_table_stats_walker (struct thread
*t
)
8838 struct bgp_node
*rn
;
8839 struct bgp_node
*top
;
8840 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8841 unsigned int space
= 0;
8843 if (!(top
= bgp_table_top (ts
->table
)))
8846 switch (top
->p
.family
)
8849 space
= IPV4_MAX_BITLEN
;
8852 space
= IPV6_MAX_BITLEN
;
8856 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8858 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8860 struct bgp_info
*ri
;
8861 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8862 unsigned int rinum
= 0;
8870 ts
->counts
[BGP_STATS_PREFIXES
]++;
8871 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8874 ts
->counts
[BGP_STATS_AVGPLEN
]
8875 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8876 ts
->counts
[BGP_STATS_AVGPLEN
],
8880 /* check if the prefix is included by any other announcements */
8881 while (prn
&& !prn
->info
)
8882 prn
= bgp_node_parent_nolock (prn
);
8884 if (prn
== NULL
|| prn
== top
)
8886 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8887 /* announced address space */
8889 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8892 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8894 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8897 ts
->counts
[BGP_STATS_RIB
]++;
8900 (CHECK_FLAG (ri
->attr
->flag
,
8901 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8902 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8905 if (ri
->attr
&& ri
->attr
->aspath
)
8907 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8908 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8909 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8911 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8913 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8914 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8916 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8917 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8919 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8920 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8922 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8923 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8924 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8926 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8927 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8928 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8931 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8932 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8940 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8942 struct bgp_table_stats ts
;
8945 if (!bgp
->rib
[afi
][safi
])
8947 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8948 afi
, safi
, VTY_NEWLINE
);
8952 memset (&ts
, 0, sizeof (ts
));
8953 ts
.table
= bgp
->rib
[afi
][safi
];
8954 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8956 vty_out (vty
, "BGP %s RIB statistics%s%s",
8957 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8959 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8961 if (!table_stats_strs
[i
])
8967 case BGP_STATS_ASPATH_AVGHOPS
:
8968 case BGP_STATS_ASPATH_AVGSIZE
:
8969 case BGP_STATS_AVGPLEN
:
8970 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8971 vty_out (vty
, "%12.2f",
8972 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8975 case BGP_STATS_ASPATH_TOTHOPS
:
8976 case BGP_STATS_ASPATH_TOTSIZE
:
8977 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8978 vty_out (vty
, "%12.2f",
8980 (float)ts
.counts
[i
] /
8981 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8984 case BGP_STATS_TOTPLEN
:
8985 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8986 vty_out (vty
, "%12.2f",
8988 (float)ts
.counts
[i
] /
8989 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8992 case BGP_STATS_SPACE
:
8993 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8994 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8995 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8997 vty_out (vty
, "%30s: ", "%% announced ");
8998 vty_out (vty
, "%12.2f%s",
8999 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
9000 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
9002 vty_out (vty
, "%30s: ", "/8 equivalent ");
9003 vty_out (vty
, "%12.2f%s",
9004 (float)ts
.counts
[BGP_STATS_SPACE
] /
9005 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
9007 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
9009 vty_out (vty
, "%30s: ", "/24 equivalent ");
9010 vty_out (vty
, "%12.2f",
9011 (float)ts
.counts
[BGP_STATS_SPACE
] /
9012 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
9015 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9016 vty_out (vty
, "%12llu", ts
.counts
[i
]);
9019 vty_out (vty
, "%s", VTY_NEWLINE
);
9034 PCOUNT_PFCNT
, /* the figure we display to users */
9038 static const char *pcount_strs
[] =
9040 [PCOUNT_ADJ_IN
] = "Adj-in",
9041 [PCOUNT_DAMPED
] = "Damped",
9042 [PCOUNT_REMOVED
] = "Removed",
9043 [PCOUNT_HISTORY
] = "History",
9044 [PCOUNT_STALE
] = "Stale",
9045 [PCOUNT_VALID
] = "Valid",
9046 [PCOUNT_ALL
] = "All RIB",
9047 [PCOUNT_COUNTED
] = "PfxCt counted",
9048 [PCOUNT_PFCNT
] = "Useable",
9049 [PCOUNT_MAX
] = NULL
,
9054 unsigned int count
[PCOUNT_MAX
];
9055 const struct peer
*peer
;
9056 const struct bgp_table
*table
;
9060 bgp_peer_count_walker (struct thread
*t
)
9062 struct bgp_node
*rn
;
9063 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9064 const struct peer
*peer
= pc
->peer
;
9066 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9068 struct bgp_adj_in
*ain
;
9069 struct bgp_info
*ri
;
9071 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9072 if (ain
->peer
== peer
)
9073 pc
->count
[PCOUNT_ADJ_IN
]++;
9075 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9077 char buf
[SU_ADDRSTRLEN
];
9079 if (ri
->peer
!= peer
)
9082 pc
->count
[PCOUNT_ALL
]++;
9084 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9085 pc
->count
[PCOUNT_DAMPED
]++;
9086 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9087 pc
->count
[PCOUNT_HISTORY
]++;
9088 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9089 pc
->count
[PCOUNT_REMOVED
]++;
9090 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9091 pc
->count
[PCOUNT_STALE
]++;
9092 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9093 pc
->count
[PCOUNT_VALID
]++;
9094 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9095 pc
->count
[PCOUNT_PFCNT
]++;
9097 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9099 pc
->count
[PCOUNT_COUNTED
]++;
9100 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9101 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9103 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9104 buf
, SU_ADDRSTRLEN
),
9110 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9111 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9113 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9114 buf
, SU_ADDRSTRLEN
),
9124 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9126 struct peer_pcounts pcounts
= { .peer
= peer
};
9128 json_object
*json
= NULL
;
9129 json_object
*json_loop
= NULL
;
9133 json
= json_object_new_object();
9134 json_loop
= json_object_new_object();
9137 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9138 || !peer
->bgp
->rib
[afi
][safi
])
9142 json_object_string_add(json
, "warning", "No such neighbor or address family");
9143 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9144 json_object_free(json
);
9147 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9152 memset (&pcounts
, 0, sizeof(pcounts
));
9153 pcounts
.peer
= peer
;
9154 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9156 /* in-place call via thread subsystem so as to record execution time
9157 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9158 * * on just vty_read()).
9160 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9164 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9165 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9166 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9168 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9169 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9171 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9173 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9175 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9176 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9178 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9179 json_object_free(json
);
9184 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9186 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9187 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9192 vty_out (vty
, "Prefix counts for %s, %s%s",
9193 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9196 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9197 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9198 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9200 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9201 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9203 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9205 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9206 peer
->host
, VTY_NEWLINE
);
9207 vty_out (vty
, "Please report this bug, with the above command output%s",
9215 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9216 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9217 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
9218 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9222 BGP_INSTANCE_HELP_STR
9225 "Address Family modifier\n"
9226 "Address Family modifier\n"
9227 "Address Family modifier\n"
9228 "Address Family modifier\n"
9229 "Detailed information on TCP and BGP neighbor connections\n"
9230 "Neighbor to display information about\n"
9231 "Neighbor to display information about\n"
9232 "Neighbor on BGP configured interface\n"
9233 "Display detailed prefix count information\n"
9236 afi_t afi
= AFI_IP6
;
9237 safi_t safi
= SAFI_UNICAST
;
9240 struct bgp
*bgp
= NULL
;
9242 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9246 int uj
= use_json (argc
, argv
);
9249 argv_find (argv
, argc
, "neighbors", &idx
);
9250 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9254 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9257 #ifdef KEEP_OLD_VPN_COMMANDS
9258 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9259 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9260 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9265 "Display information about all VPNv4 NLRIs\n"
9266 "Detailed information on TCP and BGP neighbor connections\n"
9267 "Neighbor to display information about\n"
9268 "Neighbor to display information about\n"
9269 "Neighbor on BGP configured interface\n"
9270 "Display detailed prefix count information\n"
9275 u_char uj
= use_json(argc
, argv
);
9277 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9281 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9284 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9285 show_ip_bgp_vpn_all_route_prefix_cmd
,
9286 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9291 "Display information about all VPNv4 NLRIs\n"
9292 "Network in the BGP routing table to display\n"
9293 "Network in the BGP routing table to display\n"
9297 char *network
= NULL
;
9298 struct bgp
*bgp
= bgp_get_default();
9301 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9305 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9306 network
= argv
[idx
]->arg
;
9307 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9308 network
= argv
[idx
]->arg
;
9311 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9315 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9317 #endif /* KEEP_OLD_VPN_COMMANDS */
9319 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9320 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9321 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9327 "Display information about all EVPN NLRIs\n"
9328 "Network in the BGP routing table to display\n"
9329 "Network in the BGP routing table to display\n"
9333 char *network
= NULL
;
9335 if (argv_find (argv
, argc
, "A.B.C.D", &idx
))
9336 network
= argv
[idx
]->arg
;
9337 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
9338 network
= argv
[idx
]->arg
;
9341 vty_out (vty
, "Unable to figure out Network%s", VTY_NEWLINE
);
9344 return bgp_show_route (vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9348 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9349 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9351 struct bgp_table
*table
;
9352 struct bgp_adj_in
*ain
;
9353 struct bgp_adj_out
*adj
;
9354 unsigned long output_count
;
9355 unsigned long filtered_count
;
9356 struct bgp_node
*rn
;
9361 struct attr_extra extra
;
9363 struct update_subgroup
*subgrp
;
9364 json_object
*json_scode
= NULL
;
9365 json_object
*json_ocode
= NULL
;
9366 json_object
*json_ar
= NULL
;
9367 struct peer_af
*paf
;
9371 json_scode
= json_object_new_object();
9372 json_ocode
= json_object_new_object();
9373 json_ar
= json_object_new_object();
9375 json_object_string_add(json_scode
, "suppressed", "s");
9376 json_object_string_add(json_scode
, "damped", "d");
9377 json_object_string_add(json_scode
, "history", "h");
9378 json_object_string_add(json_scode
, "valid", "*");
9379 json_object_string_add(json_scode
, "best", ">");
9380 json_object_string_add(json_scode
, "multipath", "=");
9381 json_object_string_add(json_scode
, "internal", "i");
9382 json_object_string_add(json_scode
, "ribFailure", "r");
9383 json_object_string_add(json_scode
, "stale", "S");
9384 json_object_string_add(json_scode
, "removed", "R");
9386 json_object_string_add(json_ocode
, "igp", "i");
9387 json_object_string_add(json_ocode
, "egp", "e");
9388 json_object_string_add(json_ocode
, "incomplete", "?");
9397 json_object_string_add(json
, "alert", "no BGP");
9398 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9399 json_object_free(json
);
9402 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9406 table
= bgp
->rib
[afi
][safi
];
9408 output_count
= filtered_count
= 0;
9409 subgrp
= peer_subgroup(peer
, afi
, safi
);
9411 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9415 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9416 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9417 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9418 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9419 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9423 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9424 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9425 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9427 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9428 VTY_NEWLINE
, VTY_NEWLINE
);
9433 attr
.extra
= &extra
;
9434 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9438 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9440 if (ain
->peer
== peer
)
9446 json_object_int_add(json
, "bgpTableVersion", 0);
9447 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9448 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9449 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9453 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9454 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9455 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9462 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9467 bgp_attr_dup(&attr
, ain
->attr
);
9468 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9470 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9481 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9482 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9483 if (paf
->peer
== peer
)
9489 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9490 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9491 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9492 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9496 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9497 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9498 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9499 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9507 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9513 bgp_attr_dup(&attr
, adj
->attr
);
9514 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9515 if (ret
!= RMAP_DENY
)
9517 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9527 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9529 if (output_count
!= 0)
9532 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9534 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9535 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9539 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9540 json_object_free(json
);
9546 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9547 int in
, const char *rmap_name
, u_char use_json
)
9549 json_object
*json
= NULL
;
9552 json
= json_object_new_object();
9554 if (!peer
|| !peer
->afc
[afi
][safi
])
9558 json_object_string_add(json
, "warning", "No such neighbor or address family");
9559 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9560 json_object_free(json
);
9563 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9568 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9572 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9573 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9574 json_object_free(json
);
9577 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9582 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9587 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9588 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9589 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9590 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9594 BGP_INSTANCE_HELP_STR
9597 "Detailed information on TCP and BGP neighbor connections\n"
9598 "Neighbor to display information about\n"
9599 "Neighbor to display information about\n"
9600 "Neighbor on BGP configured interface\n"
9601 "Display the received routes from neighbor\n"
9602 "Display the routes advertised to a BGP neighbor\n"
9603 "Route-map to modify the attributes\n"
9604 "Name of the route map\n"
9607 afi_t afi
= AFI_IP6
;
9608 safi_t safi
= SAFI_UNICAST
;
9609 char *rmap_name
= NULL
;
9610 char *peerstr
= NULL
;
9612 struct bgp
*bgp
= NULL
;
9617 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9621 int uj
= use_json (argc
, argv
);
9624 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9625 argv_find (argv
, argc
, "neighbors", &idx
);
9626 peerstr
= argv
[++idx
]->arg
;
9628 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9632 if (argv_find (argv
, argc
, "received-routes", &idx
))
9634 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9636 if (argv_find (argv
, argc
, "route-map", &idx
))
9637 rmap_name
= argv
[++idx
]->arg
;
9639 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9642 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9643 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9644 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9650 "Address Family modifier\n"
9651 "Detailed information on TCP and BGP neighbor connections\n"
9652 "Neighbor to display information about\n"
9653 "Neighbor to display information about\n"
9654 "Neighbor on BGP configured interface\n"
9655 "Display information received from a BGP neighbor\n"
9656 "Display the prefixlist filter\n"
9659 afi_t afi
= AFI_IP6
;
9660 safi_t safi
= SAFI_UNICAST
;
9661 char *peerstr
= NULL
;
9671 if (argv_find (argv
, argc
, "ip", &idx
))
9673 /* [<ipv4|ipv6> [unicast]] */
9674 if (argv_find (argv
, argc
, "ipv4", &idx
))
9676 if (argv_find (argv
, argc
, "ipv6", &idx
))
9678 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9679 argv_find (argv
, argc
, "neighbors", &idx
);
9680 peerstr
= argv
[++idx
]->arg
;
9682 u_char uj
= use_json(argc
, argv
);
9684 ret
= str2sockunion (peerstr
, &su
);
9687 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9691 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9693 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9699 peer
= peer_lookup (NULL
, &su
);
9703 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9705 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9710 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9711 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9715 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9716 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9721 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9723 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9730 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9731 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9733 if (! peer
|| ! peer
->afc
[afi
][safi
])
9737 json_object
*json_no
= NULL
;
9738 json_no
= json_object_new_object();
9739 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9740 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9741 json_object_free(json_no
);
9744 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9748 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9751 DEFUN (show_ip_bgp_neighbor_routes
,
9752 show_ip_bgp_neighbor_routes_cmd
,
9753 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9754 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9758 BGP_INSTANCE_HELP_STR
9761 "Detailed information on TCP and BGP neighbor connections\n"
9762 "Neighbor to display information about\n"
9763 "Neighbor to display information about\n"
9764 "Neighbor on BGP configured interface\n"
9765 "Display flap statistics of the routes learned from neighbor\n"
9766 "Display the dampened routes received from neighbor\n"
9767 "Display routes learned from neighbor\n"
9770 char *peerstr
= NULL
;
9771 struct bgp
*bgp
= NULL
;
9772 afi_t afi
= AFI_IP6
;
9773 safi_t safi
= SAFI_UNICAST
;
9775 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9779 bgp_vty_find_and_parse_afi_safi_bgp (vty
, argv
, argc
, &idx
, &afi
, &safi
, &bgp
);
9783 int uj
= use_json (argc
, argv
);
9786 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9787 argv_find (argv
, argc
, "neighbors", &idx
);
9788 peerstr
= argv
[++idx
]->arg
;
9790 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9793 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9797 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9798 sh_type
= bgp_show_type_flap_neighbor
;
9799 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9800 sh_type
= bgp_show_type_damp_neighbor
;
9801 else if (argv_find (argv
, argc
, "routes", &idx
))
9802 sh_type
= bgp_show_type_neighbor
;
9804 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9807 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9811 /* Distance value for the IP source prefix. */
9814 /* Name of the access-list to be matched. */
9818 DEFUN (show_bgp_afi_vpn_rd_route
,
9819 show_bgp_afi_vpn_rd_route_cmd
,
9820 "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]",
9824 "Address Family modifier\n"
9825 "Display information for a route distinguisher\n"
9826 "Route Distinguisher\n"
9827 "Network in the BGP routing table to display\n"
9828 "Network in the BGP routing table to display\n"
9832 struct prefix_rd prd
;
9833 afi_t afi
= AFI_MAX
;
9836 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
9837 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
9840 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
9843 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
9846 static struct bgp_distance
*
9847 bgp_distance_new (void)
9849 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9853 bgp_distance_free (struct bgp_distance
*bdistance
)
9855 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9859 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9860 const char *ip_str
, const char *access_list_str
)
9867 struct bgp_node
*rn
;
9868 struct bgp_distance
*bdistance
;
9870 afi
= bgp_node_afi (vty
);
9871 safi
= bgp_node_safi (vty
);
9873 ret
= str2prefix (ip_str
, &p
);
9876 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9880 distance
= atoi (distance_str
);
9882 /* Get BGP distance node. */
9883 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9886 bdistance
= rn
->info
;
9887 bgp_unlock_node (rn
);
9891 bdistance
= bgp_distance_new ();
9892 rn
->info
= bdistance
;
9895 /* Set distance value. */
9896 bdistance
->distance
= distance
;
9898 /* Reset access-list configuration. */
9899 if (bdistance
->access_list
)
9901 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9902 bdistance
->access_list
= NULL
;
9904 if (access_list_str
)
9905 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9911 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9912 const char *ip_str
, const char *access_list_str
)
9919 struct bgp_node
*rn
;
9920 struct bgp_distance
*bdistance
;
9922 afi
= bgp_node_afi (vty
);
9923 safi
= bgp_node_safi (vty
);
9925 ret
= str2prefix (ip_str
, &p
);
9928 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9932 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9935 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9939 bdistance
= rn
->info
;
9940 distance
= atoi(distance_str
);
9942 if (bdistance
->distance
!= distance
)
9944 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9948 if (bdistance
->access_list
)
9949 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9950 bgp_distance_free (bdistance
);
9953 bgp_unlock_node (rn
);
9954 bgp_unlock_node (rn
);
9959 /* Apply BGP information to distance method. */
9961 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9962 safi_t safi
, struct bgp
*bgp
)
9964 struct bgp_node
*rn
;
9967 struct bgp_distance
*bdistance
;
9968 struct access_list
*alist
;
9969 struct bgp_static
*bgp_static
;
9976 /* Check source address. */
9977 sockunion2hostprefix (&peer
->su
, &q
);
9978 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9981 bdistance
= rn
->info
;
9982 bgp_unlock_node (rn
);
9984 if (bdistance
->access_list
)
9986 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9987 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9988 return bdistance
->distance
;
9991 return bdistance
->distance
;
9994 /* Backdoor check. */
9995 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9998 bgp_static
= rn
->info
;
9999 bgp_unlock_node (rn
);
10001 if (bgp_static
->backdoor
)
10003 if (bgp
->distance_local
[afi
][safi
])
10004 return bgp
->distance_local
[afi
][safi
];
10006 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10010 if (peer
->sort
== BGP_PEER_EBGP
)
10012 if (bgp
->distance_ebgp
[afi
][safi
])
10013 return bgp
->distance_ebgp
[afi
][safi
];
10014 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10018 if (bgp
->distance_ibgp
[afi
][safi
])
10019 return bgp
->distance_ibgp
[afi
][safi
];
10020 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10024 DEFUN (bgp_distance
,
10026 "distance bgp (1-255) (1-255) (1-255)",
10027 "Define an administrative distance\n"
10029 "Distance for routes external to the AS\n"
10030 "Distance for routes internal to the AS\n"
10031 "Distance for local routes\n")
10033 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10034 int idx_number
= 2;
10035 int idx_number_2
= 3;
10036 int idx_number_3
= 4;
10040 afi
= bgp_node_afi (vty
);
10041 safi
= bgp_node_safi (vty
);
10043 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10044 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10045 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10046 return CMD_SUCCESS
;
10049 DEFUN (no_bgp_distance
,
10050 no_bgp_distance_cmd
,
10051 "no distance bgp [(1-255) (1-255) (1-255)]",
10053 "Define an administrative distance\n"
10055 "Distance for routes external to the AS\n"
10056 "Distance for routes internal to the AS\n"
10057 "Distance for local routes\n")
10059 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10063 afi
= bgp_node_afi (vty
);
10064 safi
= bgp_node_safi (vty
);
10066 bgp
->distance_ebgp
[afi
][safi
] = 0;
10067 bgp
->distance_ibgp
[afi
][safi
] = 0;
10068 bgp
->distance_local
[afi
][safi
] = 0;
10069 return CMD_SUCCESS
;
10073 DEFUN (bgp_distance_source
,
10074 bgp_distance_source_cmd
,
10075 "distance (1-255) A.B.C.D/M",
10076 "Define an administrative distance\n"
10077 "Administrative distance\n"
10078 "IP source prefix\n")
10080 int idx_number
= 1;
10081 int idx_ipv4_prefixlen
= 2;
10082 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10083 return CMD_SUCCESS
;
10086 DEFUN (no_bgp_distance_source
,
10087 no_bgp_distance_source_cmd
,
10088 "no distance (1-255) A.B.C.D/M",
10090 "Define an administrative distance\n"
10091 "Administrative distance\n"
10092 "IP source prefix\n")
10094 int idx_number
= 2;
10095 int idx_ipv4_prefixlen
= 3;
10096 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10097 return CMD_SUCCESS
;
10100 DEFUN (bgp_distance_source_access_list
,
10101 bgp_distance_source_access_list_cmd
,
10102 "distance (1-255) A.B.C.D/M WORD",
10103 "Define an administrative distance\n"
10104 "Administrative distance\n"
10105 "IP source prefix\n"
10106 "Access list name\n")
10108 int idx_number
= 1;
10109 int idx_ipv4_prefixlen
= 2;
10111 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10112 return CMD_SUCCESS
;
10115 DEFUN (no_bgp_distance_source_access_list
,
10116 no_bgp_distance_source_access_list_cmd
,
10117 "no distance (1-255) A.B.C.D/M WORD",
10119 "Define an administrative distance\n"
10120 "Administrative distance\n"
10121 "IP source prefix\n"
10122 "Access list name\n")
10124 int idx_number
= 2;
10125 int idx_ipv4_prefixlen
= 3;
10127 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10128 return CMD_SUCCESS
;
10131 DEFUN (ipv6_bgp_distance_source
,
10132 ipv6_bgp_distance_source_cmd
,
10133 "distance (1-255) X:X::X:X/M",
10134 "Define an administrative distance\n"
10135 "Administrative distance\n"
10136 "IP source prefix\n")
10138 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10139 return CMD_SUCCESS
;
10142 DEFUN (no_ipv6_bgp_distance_source
,
10143 no_ipv6_bgp_distance_source_cmd
,
10144 "no distance (1-255) X:X::X:X/M",
10146 "Define an administrative distance\n"
10147 "Administrative distance\n"
10148 "IP source prefix\n")
10150 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10151 return CMD_SUCCESS
;
10154 DEFUN (ipv6_bgp_distance_source_access_list
,
10155 ipv6_bgp_distance_source_access_list_cmd
,
10156 "distance (1-255) X:X::X:X/M WORD",
10157 "Define an administrative distance\n"
10158 "Administrative distance\n"
10159 "IP source prefix\n"
10160 "Access list name\n")
10162 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10163 return CMD_SUCCESS
;
10166 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10167 no_ipv6_bgp_distance_source_access_list_cmd
,
10168 "no distance (1-255) X:X::X:X/M WORD",
10170 "Define an administrative distance\n"
10171 "Administrative distance\n"
10172 "IP source prefix\n"
10173 "Access list name\n")
10175 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10176 return CMD_SUCCESS
;
10179 DEFUN (bgp_damp_set
,
10181 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10182 "BGP Specific commands\n"
10183 "Enable route-flap dampening\n"
10184 "Half-life time for the penalty\n"
10185 "Value to start reusing a route\n"
10186 "Value to start suppressing a route\n"
10187 "Maximum duration to suppress a stable route\n")
10189 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10190 int idx_half_life
= 2;
10192 int idx_suppress
= 4;
10193 int idx_max_suppress
= 5;
10194 int half
= DEFAULT_HALF_LIFE
* 60;
10195 int reuse
= DEFAULT_REUSE
;
10196 int suppress
= DEFAULT_SUPPRESS
;
10197 int max
= 4 * half
;
10201 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10202 reuse
= atoi (argv
[idx_reuse
]->arg
);
10203 suppress
= atoi (argv
[idx_suppress
]->arg
);
10204 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10206 else if (argc
== 3)
10208 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10212 if (suppress
< reuse
)
10214 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10219 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10220 half
, reuse
, suppress
, max
);
10223 DEFUN (bgp_damp_unset
,
10224 bgp_damp_unset_cmd
,
10225 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10227 "BGP Specific commands\n"
10228 "Enable route-flap dampening\n"
10229 "Half-life time for the penalty\n"
10230 "Value to start reusing a route\n"
10231 "Value to start suppressing a route\n"
10232 "Maximum duration to suppress a stable route\n")
10234 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10235 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10238 /* Display specified route of BGP table. */
10240 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10241 const char *ip_str
, afi_t afi
, safi_t safi
,
10242 struct prefix_rd
*prd
, int prefix_check
)
10245 struct prefix match
;
10246 struct bgp_node
*rn
;
10247 struct bgp_node
*rm
;
10248 struct bgp_info
*ri
;
10249 struct bgp_info
*ri_temp
;
10251 struct bgp_table
*table
;
10253 /* BGP structure lookup. */
10256 bgp
= bgp_lookup_by_name (view_name
);
10259 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10260 return CMD_WARNING
;
10265 bgp
= bgp_get_default ();
10268 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10269 return CMD_WARNING
;
10273 /* Check IP address argument. */
10274 ret
= str2prefix (ip_str
, &match
);
10277 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10278 return CMD_WARNING
;
10281 match
.family
= afi2family (afi
);
10283 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10285 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10287 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10290 if ((table
= rn
->info
) != NULL
)
10291 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10293 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10298 if (ri
->extra
&& ri
->extra
->damp_info
)
10300 ri_temp
= ri
->next
;
10301 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10309 bgp_unlock_node (rm
);
10315 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10317 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10322 if (ri
->extra
&& ri
->extra
->damp_info
)
10324 ri_temp
= ri
->next
;
10325 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10333 bgp_unlock_node (rn
);
10337 return CMD_SUCCESS
;
10340 DEFUN (clear_ip_bgp_dampening
,
10341 clear_ip_bgp_dampening_cmd
,
10342 "clear ip bgp dampening",
10346 "Clear route flap dampening information\n")
10348 bgp_damp_info_clean ();
10349 return CMD_SUCCESS
;
10352 DEFUN (clear_ip_bgp_dampening_prefix
,
10353 clear_ip_bgp_dampening_prefix_cmd
,
10354 "clear ip bgp dampening A.B.C.D/M",
10358 "Clear route flap dampening information\n"
10361 int idx_ipv4_prefixlen
= 4;
10362 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10363 SAFI_UNICAST
, NULL
, 1);
10366 DEFUN (clear_ip_bgp_dampening_address
,
10367 clear_ip_bgp_dampening_address_cmd
,
10368 "clear ip bgp dampening A.B.C.D",
10372 "Clear route flap dampening information\n"
10373 "Network to clear damping information\n")
10376 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10377 SAFI_UNICAST
, NULL
, 0);
10380 DEFUN (clear_ip_bgp_dampening_address_mask
,
10381 clear_ip_bgp_dampening_address_mask_cmd
,
10382 "clear ip bgp dampening A.B.C.D A.B.C.D",
10386 "Clear route flap dampening information\n"
10387 "Network to clear damping information\n"
10391 int idx_ipv4_2
= 5;
10393 char prefix_str
[BUFSIZ
];
10395 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10398 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10399 return CMD_WARNING
;
10402 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10403 SAFI_UNICAST
, NULL
, 0);
10406 /* also used for encap safi */
10408 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10409 afi_t afi
, safi_t safi
, int *write
)
10411 struct bgp_node
*prn
;
10412 struct bgp_node
*rn
;
10413 struct bgp_table
*table
;
10415 struct prefix_rd
*prd
;
10416 struct bgp_static
*bgp_static
;
10418 char buf
[SU_ADDRSTRLEN
];
10419 char rdbuf
[RD_ADDRSTRLEN
];
10421 /* Network configuration. */
10422 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10423 if ((table
= prn
->info
) != NULL
)
10424 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10425 if ((bgp_static
= rn
->info
) != NULL
)
10428 prd
= (struct prefix_rd
*) &prn
->p
;
10430 /* "address-family" display. */
10431 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10433 /* "network" configuration display. */
10434 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10435 label
= decode_label (bgp_static
->tag
);
10437 vty_out (vty
, " network %s/%d rd %s label %d",
10438 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10441 if (bgp_static
->rmap
.name
)
10442 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10445 if (bgp_static
->backdoor
)
10446 vty_out (vty
, " backdoor");
10448 vty_out (vty
, "%s", VTY_NEWLINE
);
10454 bgp_config_write_network_evpn (struct vty
*vty
, struct bgp
*bgp
,
10455 afi_t afi
, safi_t safi
, int *write
)
10457 struct bgp_node
*prn
;
10458 struct bgp_node
*rn
;
10459 struct bgp_table
*table
;
10461 struct prefix_rd
*prd
;
10462 struct bgp_static
*bgp_static
;
10463 char buf
[PREFIX_STRLEN
];
10464 char buf2
[SU_ADDRSTRLEN
];
10465 char rdbuf
[RD_ADDRSTRLEN
];
10467 /* Network configuration. */
10468 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10469 if ((table
= prn
->info
) != NULL
)
10470 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10471 if ((bgp_static
= rn
->info
) != NULL
)
10473 char *macrouter
= NULL
;
10476 if(bgp_static
->router_mac
)
10477 macrouter
= prefix_mac2str(bgp_static
->router_mac
, NULL
, 0);
10478 if(bgp_static
->eth_s_id
)
10479 esi
= esi2str(bgp_static
->eth_s_id
);
10481 prd
= (struct prefix_rd
*) &prn
->p
;
10483 /* "address-family" display. */
10484 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10486 /* "network" configuration display. */
10487 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10489 inet_ntop (AF_INET
, &bgp_static
->igpnexthop
, buf2
, SU_ADDRSTRLEN
);
10491 prefix2str (p
, buf
, sizeof (buf
)),
10492 vty_out (vty
, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10493 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
10494 decode_label (bgp_static
->tag
), esi
, buf2
, macrouter
);
10495 vty_out (vty
, "%s", VTY_NEWLINE
);
10497 XFREE (MTYPE_TMP
, macrouter
);
10499 XFREE (MTYPE_TMP
, esi
);
10504 /* Configuration of static route announcement and aggregate
10507 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10508 afi_t afi
, safi_t safi
, int *write
)
10510 struct bgp_node
*rn
;
10512 struct bgp_static
*bgp_static
;
10513 struct bgp_aggregate
*bgp_aggregate
;
10514 char buf
[SU_ADDRSTRLEN
];
10516 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10517 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10519 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
10520 return bgp_config_write_network_evpn (vty
, bgp
, afi
, safi
, write
);
10522 /* Network configuration. */
10523 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10524 if ((bgp_static
= rn
->info
) != NULL
)
10528 /* "address-family" display. */
10529 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10531 /* "network" configuration display. */
10532 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10534 u_int32_t destination
;
10535 struct in_addr netmask
;
10537 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10538 masklen2ip (p
->prefixlen
, &netmask
);
10539 vty_out (vty
, " network %s",
10540 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10542 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10543 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10544 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10545 || p
->u
.prefix4
.s_addr
== 0)
10547 /* Natural mask is not display. */
10550 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10554 vty_out (vty
, " network %s/%d",
10555 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10559 if (bgp_static
->rmap
.name
)
10560 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10563 if (bgp_static
->backdoor
)
10564 vty_out (vty
, " backdoor");
10567 vty_out (vty
, "%s", VTY_NEWLINE
);
10570 /* Aggregate-address configuration. */
10571 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10572 if ((bgp_aggregate
= rn
->info
) != NULL
)
10576 /* "address-family" display. */
10577 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10579 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10581 struct in_addr netmask
;
10583 masklen2ip (p
->prefixlen
, &netmask
);
10584 vty_out (vty
, " aggregate-address %s %s",
10585 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10586 inet_ntoa (netmask
));
10590 vty_out (vty
, " aggregate-address %s/%d",
10591 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10595 if (bgp_aggregate
->as_set
)
10596 vty_out (vty
, " as-set");
10598 if (bgp_aggregate
->summary_only
)
10599 vty_out (vty
, " summary-only");
10601 vty_out (vty
, "%s", VTY_NEWLINE
);
10608 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10609 safi_t safi
, int *write
)
10611 struct bgp_node
*rn
;
10612 struct bgp_distance
*bdistance
;
10614 /* Distance configuration. */
10615 if (bgp
->distance_ebgp
[afi
][safi
]
10616 && bgp
->distance_ibgp
[afi
][safi
]
10617 && bgp
->distance_local
[afi
][safi
]
10618 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10619 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10620 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10622 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10623 vty_out (vty
, " distance bgp %d %d %d%s",
10624 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10625 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10628 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10629 rn
= bgp_route_next (rn
))
10630 if ((bdistance
= rn
->info
) != NULL
)
10632 char buf
[PREFIX_STRLEN
];
10634 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10635 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10636 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10637 bdistance
->access_list
? bdistance
->access_list
: "",
10644 /* Allocate routing table structure and install commands. */
10646 bgp_route_init (void)
10651 /* Init BGP distance table. */
10652 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10653 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10654 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10656 /* IPv4 BGP commands. */
10657 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10658 install_element (BGP_NODE
, &bgp_network_cmd
);
10659 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10660 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10661 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10662 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10663 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10664 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10665 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10666 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10667 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10668 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10669 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10670 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10672 install_element (BGP_NODE
, &aggregate_address_cmd
);
10673 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10674 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10675 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10677 /* IPv4 unicast configuration. */
10678 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10679 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10680 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10681 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10682 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10683 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10684 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10685 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10686 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10687 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10688 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10690 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10691 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10692 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10693 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10695 /* IPv4 multicast configuration. */
10696 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10697 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10698 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10699 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10700 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10701 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10702 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10703 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10704 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10705 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10706 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10707 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10708 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10709 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10710 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10712 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10713 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10714 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10715 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10717 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10718 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10719 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10720 #ifdef KEEP_OLD_VPN_COMMANDS
10721 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10722 #endif /* KEEP_OLD_VPN_COMMANDS */
10723 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10724 install_element (VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
10726 /* BGP dampening clear commands */
10727 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10728 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10730 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10731 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10734 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10735 #ifdef KEEP_OLD_VPN_COMMANDS
10736 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10737 #endif /* KEEP_OLD_VPN_COMMANDS */
10739 /* New config IPv6 BGP commands. */
10740 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10741 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10742 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10743 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10744 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10746 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10747 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10749 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10750 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10752 install_element (BGP_NODE
, &bgp_distance_cmd
);
10753 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10754 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10755 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10756 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10757 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10758 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10759 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10760 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10761 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10762 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10763 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10764 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10765 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10766 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10767 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10768 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10769 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10770 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10771 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10772 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10773 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10774 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10775 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10776 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10777 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10778 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10779 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10780 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10781 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10783 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10784 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10785 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10786 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10788 /* IPv4 Multicast Mode */
10789 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10790 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10792 /* Large Communities */
10793 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
10794 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
10798 bgp_route_finish (void)
10803 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10804 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10806 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10807 bgp_distance_table
[afi
][safi
] = NULL
;