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"
76 /* Extern from bgp_dump.c */
77 extern const char *bgp_origin_str
[];
78 extern const char *bgp_origin_long_str
[];
81 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
82 struct prefix_rd
*prd
)
85 struct bgp_node
*prn
= NULL
;
91 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
94 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
96 if (prn
->info
== NULL
)
97 prn
->info
= bgp_table_init (afi
, safi
);
99 bgp_unlock_node (prn
);
103 rn
= bgp_node_get (table
, p
);
105 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
112 /* Allocate bgp_info_extra */
113 static struct bgp_info_extra
*
114 bgp_info_extra_new (void)
116 struct bgp_info_extra
*new;
117 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
122 bgp_info_extra_free (struct bgp_info_extra
**extra
)
126 if ((*extra
)->damp_info
)
127 bgp_damp_info_free ((*extra
)->damp_info
, 0);
129 (*extra
)->damp_info
= NULL
;
131 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
137 /* Get bgp_info extra information for the given bgp_info, lazy allocated
140 struct bgp_info_extra
*
141 bgp_info_extra_get (struct bgp_info
*ri
)
144 ri
->extra
= bgp_info_extra_new();
148 /* Allocate new bgp info structure. */
152 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
155 /* Free bgp route information. */
157 bgp_info_free (struct bgp_info
*binfo
)
160 bgp_attr_unintern (&binfo
->attr
);
162 bgp_unlink_nexthop(binfo
);
163 bgp_info_extra_free (&binfo
->extra
);
164 bgp_info_mpath_free (&binfo
->mpath
);
166 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
168 XFREE (MTYPE_BGP_ROUTE
, binfo
);
172 bgp_info_lock (struct bgp_info
*binfo
)
179 bgp_info_unlock (struct bgp_info
*binfo
)
181 assert (binfo
&& binfo
->lock
> 0);
184 if (binfo
->lock
== 0)
187 zlog_debug ("%s: unlocked and freeing", __func__
);
188 zlog_backtrace (LOG_DEBUG
);
190 bgp_info_free (binfo
);
195 if (binfo
->lock
== 1)
197 zlog_debug ("%s: unlocked to 1", __func__
);
198 zlog_backtrace (LOG_DEBUG
);
206 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
208 struct bgp_info
*top
;
220 peer_lock (ri
->peer
); /* bgp_info peer reference */
223 /* Do the actual removal of info from RIB, for use by bgp_process
224 completion callback *only* */
226 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
229 ri
->next
->prev
= ri
->prev
;
231 ri
->prev
->next
= ri
->next
;
235 bgp_info_mpath_dequeue (ri
);
236 bgp_info_unlock (ri
);
237 bgp_unlock_node (rn
);
241 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
243 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
244 /* set of previous already took care of pcount */
245 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
248 /* undo the effects of a previous call to bgp_info_delete; typically
249 called when a route is deleted and then quickly re-added before the
250 deletion has been processed */
252 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
254 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
255 /* unset of previous already took care of pcount */
256 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
259 /* Adjust pcount as required */
261 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
263 struct bgp_table
*table
;
265 assert (rn
&& bgp_node_table (rn
));
266 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
268 table
= bgp_node_table (rn
);
270 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
273 if (!BGP_INFO_COUNTABLE (ri
)
274 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
277 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
279 /* slight hack, but more robust against errors. */
280 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
281 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
284 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
285 __func__
, ri
->peer
->host
);
286 zlog_backtrace (LOG_WARNING
);
287 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
290 else if (BGP_INFO_COUNTABLE (ri
)
291 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
293 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
294 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
299 /* Set/unset bgp_info flags, adjusting any other state as needed.
300 * This is here primarily to keep prefix-count in check.
303 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
305 SET_FLAG (ri
->flags
, flag
);
307 /* early bath if we know it's not a flag that changes countability state */
308 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
311 bgp_pcount_adjust (rn
, ri
);
315 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
317 UNSET_FLAG (ri
->flags
, flag
);
319 /* early bath if we know it's not a flag that changes countability state */
320 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
323 bgp_pcount_adjust (rn
, ri
);
326 /* Get MED value. If MED value is missing and "bgp bestpath
327 missing-as-worst" is specified, treat it as the worst value. */
329 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
331 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
335 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
343 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
345 if (ri
->addpath_rx_id
)
346 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
348 sprintf(buf
, "path %s", ri
->peer
->host
);
351 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
353 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
354 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
357 struct attr
*newattr
, *existattr
;
358 struct attr_extra
*newattre
, *existattre
;
359 bgp_peer_sort_t new_sort
;
360 bgp_peer_sort_t exist_sort
;
362 u_int32_t exist_pref
;
365 u_int32_t new_weight
;
366 u_int32_t exist_weight
;
367 uint32_t newm
, existm
;
368 struct in_addr new_id
;
369 struct in_addr exist_id
;
372 int internal_as_route
;
375 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
376 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
384 zlog_debug("%s: new is NULL", pfx_buf
);
389 bgp_info_path_with_addpath_rx_str (new, new_buf
);
394 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
400 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
401 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
402 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
406 existattr
= exist
->attr
;
407 newattre
= newattr
->extra
;
408 existattre
= existattr
->extra
;
410 /* 1. Weight check. */
411 new_weight
= exist_weight
= 0;
414 new_weight
= newattre
->weight
;
416 exist_weight
= existattre
->weight
;
418 if (new_weight
> exist_weight
)
421 zlog_debug("%s: %s wins over %s due to weight %d > %d",
422 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
426 if (new_weight
< exist_weight
)
429 zlog_debug("%s: %s loses to %s due to weight %d < %d",
430 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
434 /* 2. Local preference check. */
435 new_pref
= exist_pref
= bgp
->default_local_pref
;
437 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
438 new_pref
= newattr
->local_pref
;
439 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
440 exist_pref
= existattr
->local_pref
;
442 if (new_pref
> exist_pref
)
445 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
446 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
450 if (new_pref
< exist_pref
)
453 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
454 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
458 /* 3. Local route check. We prefer:
460 * - BGP_ROUTE_AGGREGATE
461 * - BGP_ROUTE_REDISTRIBUTE
463 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
466 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
467 pfx_buf
, new_buf
, exist_buf
);
471 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
474 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
475 pfx_buf
, new_buf
, exist_buf
);
479 /* 4. AS path length check. */
480 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
482 int exist_hops
= aspath_count_hops (existattr
->aspath
);
483 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
485 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
489 aspath_hops
= aspath_count_hops (newattr
->aspath
);
490 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
492 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
495 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
496 pfx_buf
, new_buf
, exist_buf
,
497 aspath_hops
, (exist_hops
+ exist_confeds
));
501 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
504 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
505 pfx_buf
, new_buf
, exist_buf
,
506 aspath_hops
, (exist_hops
+ exist_confeds
));
512 int newhops
= aspath_count_hops (newattr
->aspath
);
514 if (newhops
< exist_hops
)
517 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
518 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
522 if (newhops
> exist_hops
)
525 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
526 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
532 /* 5. Origin check. */
533 if (newattr
->origin
< existattr
->origin
)
536 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
537 pfx_buf
, new_buf
, exist_buf
,
538 bgp_origin_long_str
[newattr
->origin
],
539 bgp_origin_long_str
[existattr
->origin
]);
543 if (newattr
->origin
> existattr
->origin
)
546 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
547 pfx_buf
, new_buf
, exist_buf
,
548 bgp_origin_long_str
[newattr
->origin
],
549 bgp_origin_long_str
[existattr
->origin
]);
554 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
555 && aspath_count_hops (existattr
->aspath
) == 0);
556 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
557 && aspath_count_confeds (existattr
->aspath
) > 0
558 && aspath_count_hops (newattr
->aspath
) == 0
559 && aspath_count_hops (existattr
->aspath
) == 0);
561 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
562 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
564 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
565 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
566 || internal_as_route
)
568 new_med
= bgp_med_value (new->attr
, bgp
);
569 exist_med
= bgp_med_value (exist
->attr
, bgp
);
571 if (new_med
< exist_med
)
574 zlog_debug("%s: %s wins over %s due to MED %d < %d",
575 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
579 if (new_med
> exist_med
)
582 zlog_debug("%s: %s loses to %s due to MED %d > %d",
583 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
588 /* 7. Peer type check. */
589 new_sort
= new->peer
->sort
;
590 exist_sort
= exist
->peer
->sort
;
592 if (new_sort
== BGP_PEER_EBGP
593 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
596 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
597 pfx_buf
, new_buf
, exist_buf
);
601 if (exist_sort
== BGP_PEER_EBGP
602 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
605 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
606 pfx_buf
, new_buf
, exist_buf
);
610 /* 8. IGP metric check. */
614 newm
= new->extra
->igpmetric
;
616 existm
= exist
->extra
->igpmetric
;
621 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
622 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
629 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
630 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
634 /* 9. Same IGP metric. Compare the cluster list length as
635 representative of IGP hops metric. Rewrite the metric value
636 pair (newm, existm) with the cluster list length. Prefer the
637 path with smaller cluster list length. */
640 if (peer_sort (new->peer
) == BGP_PEER_IBGP
641 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
642 && (mpath_cfg
== NULL
||
643 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
644 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
646 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
647 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
652 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
653 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
660 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
661 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
667 /* 10. confed-external vs. confed-internal */
668 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
670 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
673 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
674 pfx_buf
, new_buf
, exist_buf
);
678 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
681 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
682 pfx_buf
, new_buf
, exist_buf
);
687 /* 11. Maximum path check. */
690 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
694 * For the two paths, all comparison steps till IGP metric
695 * have succeeded - including AS_PATH hop count. Since 'bgp
696 * bestpath as-path multipath-relax' knob is on, we don't need
697 * an exact match of AS_PATH. Thus, mark the paths are equal.
698 * That will trigger both these paths to get into the multipath
704 zlog_debug("%s: %s and %s are equal via multipath-relax",
705 pfx_buf
, new_buf
, exist_buf
);
707 else if (new->peer
->sort
== BGP_PEER_IBGP
)
709 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
714 zlog_debug("%s: %s and %s are equal via matching aspaths",
715 pfx_buf
, new_buf
, exist_buf
);
718 else if (new->peer
->as
== exist
->peer
->as
)
723 zlog_debug("%s: %s and %s are equal via same remote-as",
724 pfx_buf
, new_buf
, exist_buf
);
730 * TODO: If unequal cost ibgp multipath is enabled we can
731 * mark the paths as equal here instead of returning
736 zlog_debug("%s: %s wins over %s after IGP metric comparison",
737 pfx_buf
, new_buf
, exist_buf
);
739 zlog_debug("%s: %s loses to %s after IGP metric comparison",
740 pfx_buf
, new_buf
, exist_buf
);
745 /* 12. If both paths are external, prefer the path that was received
746 first (the oldest one). This step minimizes route-flap, since a
747 newer path won't displace an older one, even if it was the
748 preferred route based on the additional decision criteria below. */
749 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
750 && new_sort
== BGP_PEER_EBGP
751 && exist_sort
== BGP_PEER_EBGP
)
753 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
756 zlog_debug("%s: %s wins over %s due to oldest external",
757 pfx_buf
, new_buf
, exist_buf
);
761 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
764 zlog_debug("%s: %s loses to %s due to oldest external",
765 pfx_buf
, new_buf
, exist_buf
);
770 /* 13. Router-ID comparision. */
771 /* If one of the paths is "stale", the corresponding peer router-id will
772 * be 0 and would always win over the other path. If originator id is
773 * used for the comparision, it will decide which path is better.
775 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
776 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
778 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
779 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
780 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
782 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
784 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
787 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
788 pfx_buf
, new_buf
, exist_buf
);
792 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
795 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
796 pfx_buf
, new_buf
, exist_buf
);
800 /* 14. Cluster length comparision. */
801 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
802 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
804 if (new_cluster
< exist_cluster
)
807 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
808 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
812 if (new_cluster
> exist_cluster
)
815 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
816 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
820 /* 15. Neighbor address comparision. */
821 /* Do this only if neither path is "stale" as stale paths do not have
822 * valid peer information (as the connection may or may not be up).
824 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
827 zlog_debug("%s: %s wins over %s due to latter path being STALE",
828 pfx_buf
, new_buf
, exist_buf
);
832 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
835 zlog_debug("%s: %s loses to %s due to former path being STALE",
836 pfx_buf
, new_buf
, exist_buf
);
840 /* locally configured routes to advertise do not have su_remote */
841 if (new->peer
->su_remote
== NULL
)
843 if (exist
->peer
->su_remote
== NULL
)
846 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
851 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
852 pfx_buf
, new_buf
, exist_buf
);
859 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
860 pfx_buf
, new_buf
, exist_buf
);
865 zlog_debug("%s: %s wins over %s due to nothing left to compare",
866 pfx_buf
, new_buf
, exist_buf
);
871 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
872 * is preferred, or 0 if they are the same (usually will only occur if
873 * multipath is enabled
874 * This version is compatible with */
876 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
877 afi_t afi
, safi_t safi
)
881 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
895 static enum filter_type
896 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
897 afi_t afi
, safi_t safi
)
899 struct bgp_filter
*filter
;
901 filter
= &peer
->filter
[afi
][safi
];
903 #define FILTER_EXIST_WARN(F,f,filter) \
904 if (BGP_DEBUG (update, UPDATE_IN) \
905 && !(F ## _IN (filter))) \
906 zlog_warn ("%s: Could not find configured input %s-list %s!", \
907 peer->host, #f, F ## _IN_NAME(filter));
909 if (DISTRIBUTE_IN_NAME (filter
)) {
910 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
912 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
916 if (PREFIX_LIST_IN_NAME (filter
)) {
917 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
919 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
923 if (FILTER_LIST_IN_NAME (filter
)) {
924 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
926 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
930 return FILTER_PERMIT
;
931 #undef FILTER_EXIST_WARN
934 static enum filter_type
935 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
936 afi_t afi
, safi_t safi
)
938 struct bgp_filter
*filter
;
940 filter
= &peer
->filter
[afi
][safi
];
942 #define FILTER_EXIST_WARN(F,f,filter) \
943 if (BGP_DEBUG (update, UPDATE_OUT) \
944 && !(F ## _OUT (filter))) \
945 zlog_warn ("%s: Could not find configured output %s-list %s!", \
946 peer->host, #f, F ## _OUT_NAME(filter));
948 if (DISTRIBUTE_OUT_NAME (filter
)) {
949 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
951 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
955 if (PREFIX_LIST_OUT_NAME (filter
)) {
956 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
958 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
962 if (FILTER_LIST_OUT_NAME (filter
)) {
963 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
965 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
969 return FILTER_PERMIT
;
970 #undef FILTER_EXIST_WARN
973 /* If community attribute includes no_export then return 1. */
975 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
979 /* NO_ADVERTISE check. */
980 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
983 /* NO_EXPORT check. */
984 if (peer
->sort
== BGP_PEER_EBGP
&&
985 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
988 /* NO_EXPORT_SUBCONFED check. */
989 if (peer
->sort
== BGP_PEER_EBGP
990 || peer
->sort
== BGP_PEER_CONFED
)
991 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
997 /* Route reflection loop check. */
999 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
1001 struct in_addr cluster_id
;
1003 if (attr
->extra
&& attr
->extra
->cluster
)
1005 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1006 cluster_id
= peer
->bgp
->cluster_id
;
1008 cluster_id
= peer
->bgp
->router_id
;
1010 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1017 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1018 afi_t afi
, safi_t safi
, const char *rmap_name
)
1020 struct bgp_filter
*filter
;
1021 struct bgp_info info
;
1022 route_map_result_t ret
;
1023 struct route_map
*rmap
= NULL
;
1025 filter
= &peer
->filter
[afi
][safi
];
1027 /* Apply default weight value. */
1028 if (peer
->weight
[afi
][safi
])
1029 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1033 rmap
= route_map_lookup_by_name(rmap_name
);
1040 if (ROUTE_MAP_IN_NAME(filter
))
1042 rmap
= ROUTE_MAP_IN (filter
);
1049 /* Route map apply. */
1052 /* Duplicate current value to new strucutre for modification. */
1056 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1058 /* Apply BGP route map to the attribute. */
1059 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1061 peer
->rmap_type
= 0;
1063 if (ret
== RMAP_DENYMATCH
)
1065 /* Free newly generated AS path and community by route-map. */
1066 bgp_attr_flush (attr
);
1074 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1075 afi_t afi
, safi_t safi
, const char *rmap_name
)
1077 struct bgp_filter
*filter
;
1078 struct bgp_info info
;
1079 route_map_result_t ret
;
1080 struct route_map
*rmap
= NULL
;
1082 filter
= &peer
->filter
[afi
][safi
];
1084 /* Apply default weight value. */
1085 if (peer
->weight
[afi
][safi
])
1086 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1090 rmap
= route_map_lookup_by_name(rmap_name
);
1097 if (ROUTE_MAP_OUT_NAME(filter
))
1099 rmap
= ROUTE_MAP_OUT (filter
);
1106 /* Route map apply. */
1109 /* Duplicate current value to new strucutre for modification. */
1113 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1115 /* Apply BGP route map to the attribute. */
1116 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1118 peer
->rmap_type
= 0;
1120 if (ret
== RMAP_DENYMATCH
)
1121 /* caller has multiple error paths with bgp_attr_flush() */
1127 /* If this is an EBGP peer with remove-private-AS */
1129 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1130 struct peer
*peer
, struct attr
*attr
)
1132 if (peer
->sort
== BGP_PEER_EBGP
&&
1133 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1134 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1135 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1136 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1138 // Take action on the entire aspath
1139 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1140 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1142 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1143 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1145 // The entire aspath consists of private ASNs so create an empty aspath
1146 else if (aspath_private_as_check (attr
->aspath
))
1147 attr
->aspath
= aspath_empty_get ();
1149 // There are some public and some private ASNs, remove the private ASNs
1151 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1154 // 'all' was not specified so the entire aspath must be private ASNs
1155 // for us to do anything
1156 else if (aspath_private_as_check (attr
->aspath
))
1158 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1159 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1161 attr
->aspath
= aspath_empty_get ();
1166 /* If this is an EBGP peer with as-override */
1168 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1169 struct peer
*peer
, struct attr
*attr
)
1171 if (peer
->sort
== BGP_PEER_EBGP
&&
1172 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1174 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1175 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1180 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1182 if (family
== AF_INET
)
1183 attr
->nexthop
.s_addr
= 0;
1184 if (family
== AF_INET6
)
1185 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1189 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1190 struct prefix
*p
, struct attr
*attr
)
1192 struct bgp_filter
*filter
;
1195 struct peer
*onlypeer
;
1197 struct attr
*riattr
;
1198 struct peer_af
*paf
;
1199 char buf
[PREFIX_STRLEN
];
1205 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1207 if (DISABLE_BGP_ANNOUNCE
)
1210 afi
= SUBGRP_AFI(subgrp
);
1211 safi
= SUBGRP_SAFI(subgrp
);
1212 peer
= SUBGRP_PEER(subgrp
);
1214 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1215 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1218 filter
= &peer
->filter
[afi
][safi
];
1219 bgp
= SUBGRP_INST(subgrp
);
1220 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1223 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1224 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1225 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1228 * direct and direct_ext type routes originate internally even
1229 * though they can have peer pointers that reference other systems
1231 prefix2str(p
, buf
, PREFIX_STRLEN
);
1232 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1237 /* With addpath we may be asked to TX all kinds of paths so make sure
1239 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1240 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1241 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1246 /* If this is not the bestpath then check to see if there is an enabled addpath
1247 * feature that requires us to advertise it */
1248 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1250 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1256 /* Aggregate-address suppress check. */
1257 if (ri
->extra
&& ri
->extra
->suppress
)
1258 if (! UNSUPPRESS_MAP_NAME (filter
))
1263 /* Do not send back route to sender. */
1264 if (onlypeer
&& from
== onlypeer
)
1269 /* Do not send the default route in the BGP table if the neighbor is
1270 * configured for default-originate */
1271 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1273 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1275 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1279 /* Transparency check. */
1280 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1281 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1286 /* If community is not disabled check the no-export and local. */
1287 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1289 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1290 zlog_debug ("subgrpannouncecheck: community filter check fail");
1294 /* If the attribute has originator-id and it is same as remote
1297 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1298 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1300 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1301 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1303 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1307 /* ORF prefix-list filter check */
1308 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1309 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1310 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1311 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1312 if (peer
->orf_plist
[afi
][safi
])
1314 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1316 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1317 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1318 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1323 /* Output filter check. */
1324 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1326 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1327 zlog_debug ("%s [Update:SEND] %s is filtered",
1328 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1332 #ifdef BGP_SEND_ASPATH_CHECK
1333 /* AS path loop check. */
1334 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1336 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1337 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1338 "that is part of AS path.",
1339 onlypeer
->host
, onlypeer
->as
);
1342 #endif /* BGP_SEND_ASPATH_CHECK */
1344 /* If we're a CONFED we need to loop check the CONFED ID too */
1345 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1347 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1349 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1350 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1358 /* Route-Reflect check. */
1359 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1364 /* IBGP reflection check. */
1365 if (reflect
&& !samepeer_safe
)
1367 /* A route from a Client peer. */
1368 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1370 /* Reflect to all the Non-Client peers and also to the
1371 Client peers other than the originator. Originator check
1372 is already done. So there is noting to do. */
1373 /* no bgp client-to-client reflection check. */
1374 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1375 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1376 PEER_FLAG_REFLECTOR_CLIENT
))
1381 /* A route from a Non-client peer. Reflect to all other
1383 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1384 PEER_FLAG_REFLECTOR_CLIENT
))
1389 /* For modify attribute, copy it to temporary structure. */
1390 bgp_attr_dup (attr
, riattr
);
1392 /* If local-preference is not set. */
1393 if ((peer
->sort
== BGP_PEER_IBGP
1394 || peer
->sort
== BGP_PEER_CONFED
)
1395 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1397 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1398 attr
->local_pref
= bgp
->default_local_pref
;
1401 /* If originator-id is not set and the route is to be reflected,
1402 set the originator id */
1403 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1405 attr
->extra
= bgp_attr_extra_get(attr
);
1406 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1407 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1410 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1411 if (peer
->sort
== BGP_PEER_EBGP
1412 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1414 if (from
!= bgp
->peer_self
&& ! transparent
1415 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1416 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1419 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1420 * in announce check, only certain flags and length (or number of nexthops
1421 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1422 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1423 * Typically, the source nexthop in the attribute is preserved but in the
1424 * scenarios where we know it will always be overwritten, we reset the
1425 * nexthop to "0" in an attempt to achieve better Update packing. An
1426 * example of this is when a prefix from each of 2 IBGP peers needs to be
1427 * announced to an EBGP peer (and they have the same attributes barring
1431 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1433 #define NEXTHOP_IS_V6 (\
1434 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1435 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1436 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1437 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1439 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1440 * the peer (group) is configured to receive link-local nexthop unchanged
1441 * and it is available in the prefix OR we're not reflecting the route and
1442 * the peer (group) to whom we're going to announce is on a shared network
1443 * and this is either a self-originated route or the peer is EBGP.
1447 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1448 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1449 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1450 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1451 (!reflect
&& peer
->shared_network
&&
1452 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1454 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1457 /* Clear off link-local nexthop in source, whenever it is not needed to
1458 * ensure more prefixes share the same attribute for announcement.
1460 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1461 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1462 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1465 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1466 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1468 /* Route map & unsuppress-map apply. */
1469 if (ROUTE_MAP_OUT_NAME (filter
)
1470 || (ri
->extra
&& ri
->extra
->suppress
) )
1472 struct bgp_info info
;
1473 struct attr dummy_attr
;
1474 struct attr_extra dummy_extra
;
1476 dummy_attr
.extra
= &dummy_extra
;
1480 /* don't confuse inbound and outbound setting */
1481 RESET_FLAG(attr
->rmap_change_flags
);
1484 * The route reflector is not allowed to modify the attributes
1485 * of the reflected IBGP routes unless explicitly allowed.
1487 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1488 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1490 bgp_attr_dup (&dummy_attr
, attr
);
1491 info
.attr
= &dummy_attr
;
1494 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1496 if (ri
->extra
&& ri
->extra
->suppress
)
1497 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1499 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1501 peer
->rmap_type
= 0;
1503 if (ret
== RMAP_DENYMATCH
)
1505 bgp_attr_flush (attr
);
1510 /* After route-map has been applied, we check to see if the nexthop to
1511 * be carried in the attribute (that is used for the announcement) can
1512 * be cleared off or not. We do this in all cases where we would be
1513 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1514 * the global nexthop here; the link-local nexthop would have been cleared
1515 * already, and if not, it is required by the update formation code.
1516 * Also see earlier comments in this function.
1519 * If route-map has performed some operation on the nexthop or the peer
1520 * configuration says to pass it unchanged, we cannot reset the nexthop
1521 * here, so only attempt to do it if these aren't true. Note that the
1522 * route-map handler itself might have cleared the nexthop, if for example,
1523 * it is configured as 'peer-address'.
1525 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1526 riattr
->rmap_change_flags
) &&
1528 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1530 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1531 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1532 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1535 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1536 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1537 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ?
1538 AF_INET6
: p
->family
), attr
);
1540 else if (peer
->sort
== BGP_PEER_EBGP
)
1542 /* Can also reset the nexthop if announcing to EBGP, but only if
1543 * no peer in the subgroup is on a shared subnet.
1544 * Note: 3rd party nexthop currently implemented for IPv4 only.
1546 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1548 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1552 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ? AF_INET6
: p
->family
), attr
);
1554 /* If IPv6/MP and nexthop does not have any override and happens to
1555 * be a link-local address, reset it so that we don't pass along the
1556 * source's link-local IPv6 address to recipients who may not be on
1557 * the same interface.
1559 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
))
1561 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1562 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1569 struct bgp_info_pair
1571 struct bgp_info
*old
;
1572 struct bgp_info
*new;
1576 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1577 struct bgp_maxpaths_cfg
*mpath_cfg
,
1578 struct bgp_info_pair
*result
)
1580 struct bgp_info
*new_select
;
1581 struct bgp_info
*old_select
;
1582 struct bgp_info
*ri
;
1583 struct bgp_info
*ri1
;
1584 struct bgp_info
*ri2
;
1585 struct bgp_info
*nextri
= NULL
;
1586 int paths_eq
, do_mpath
, debug
;
1587 struct list mp_list
;
1588 char pfx_buf
[PREFIX2STR_BUFFER
];
1589 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1591 bgp_mp_list_init (&mp_list
);
1592 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1594 debug
= bgp_debug_bestpath(&rn
->p
);
1597 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1599 /* bgp deterministic-med */
1601 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1604 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1605 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1606 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1608 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1610 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1612 if (BGP_INFO_HOLDDOWN (ri1
))
1614 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1615 if (ri1
->peer
->status
!= Established
)
1621 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1623 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1625 if (BGP_INFO_HOLDDOWN (ri2
))
1628 ri2
->peer
!= bgp
->peer_self
&&
1629 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1630 if (ri2
->peer
->status
!= Established
)
1633 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1634 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1637 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1638 mpath_cfg
, debug
, pfx_buf
))
1640 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1644 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1648 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1649 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1653 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1654 zlog_debug("%s: %s is the bestpath from AS %d",
1655 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1660 /* Check old selected route and new selected route. */
1663 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1665 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1668 if (BGP_INFO_HOLDDOWN (ri
))
1670 /* reap REMOVED routes, if needs be
1671 * selected route must stay for a while longer though
1673 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1674 && (ri
!= old_select
))
1675 bgp_info_reap (rn
, ri
);
1681 ri
->peer
!= bgp
->peer_self
&&
1682 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1683 if (ri
->peer
->status
!= Established
)
1686 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1687 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1689 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1693 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1695 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1701 /* Now that we know which path is the bestpath see if any of the other paths
1702 * qualify as multipaths
1707 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1709 sprintf (path_buf
, "NONE");
1710 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1712 old_select
? old_select
->peer
->host
: "NONE");
1715 if (do_mpath
&& new_select
)
1717 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1721 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1723 if (ri
== new_select
)
1726 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1728 bgp_mp_list_add (&mp_list
, ri
);
1732 if (BGP_INFO_HOLDDOWN (ri
))
1736 ri
->peer
!= bgp
->peer_self
&&
1737 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1738 if (ri
->peer
->status
!= Established
)
1741 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1744 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1749 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1754 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1756 bgp_mp_list_add (&mp_list
, ri
);
1761 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1762 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1763 bgp_mp_list_clear (&mp_list
);
1765 result
->old
= old_select
;
1766 result
->new = new_select
;
1772 * A new route/change in bestpath of an existing route. Evaluate the path
1773 * for advertisement to the subgroup.
1776 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1777 struct bgp_info
*selected
,
1778 struct bgp_node
*rn
,
1779 u_int32_t addpath_tx_id
)
1782 struct peer
*onlypeer
;
1784 struct attr_extra extra
;
1789 afi
= SUBGRP_AFI(subgrp
);
1790 safi
= SUBGRP_SAFI(subgrp
);
1791 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1792 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1794 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1795 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1796 PEER_STATUS_ORF_WAIT_REFRESH
))
1799 memset(&extra
, 0, sizeof(struct attr_extra
));
1800 /* It's initialized in bgp_announce_check() */
1801 attr
.extra
= &extra
;
1803 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1806 if (subgroup_announce_check(selected
, subgrp
, p
, &attr
))
1807 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1809 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1812 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1815 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1822 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1823 * This is called at the end of route processing.
1826 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1828 struct bgp_info
*ri
;
1830 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1832 if (BGP_INFO_HOLDDOWN (ri
))
1834 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1835 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1840 * Has the route changed from the RIB's perspective? This is invoked only
1841 * if the route selection returns the same best route as earlier - to
1842 * determine if we need to update zebra or not.
1845 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1847 struct bgp_info
*mpinfo
;
1849 /* If this is multipath, check all selected paths for any nexthop change or
1850 * attribute change. Some attribute changes (e.g., community) aren't of
1851 * relevance to the RIB, but we'll update zebra to ensure we handle the
1852 * case of BGP nexthop change. This is the behavior when the best path has
1853 * an attribute change anyway.
1855 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1856 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1859 /* If this is multipath, check all selected paths for any nexthop change */
1860 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1861 mpinfo
= bgp_info_mpath_next (mpinfo
))
1863 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1864 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1868 /* Nothing has changed from the RIB's perspective. */
1872 struct bgp_process_queue
1875 struct bgp_node
*rn
;
1880 static wq_item_status
1881 bgp_process_main (struct work_queue
*wq
, void *data
)
1883 struct bgp_process_queue
*pq
= data
;
1884 struct bgp
*bgp
= pq
->bgp
;
1885 struct bgp_node
*rn
= pq
->rn
;
1886 afi_t afi
= pq
->afi
;
1887 safi_t safi
= pq
->safi
;
1888 struct prefix
*p
= &rn
->p
;
1889 struct bgp_info
*new_select
;
1890 struct bgp_info
*old_select
;
1891 struct bgp_info_pair old_and_new
;
1893 /* Is it end of initial update? (after startup) */
1896 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1897 sizeof(bgp
->update_delay_zebra_resume_time
));
1899 bgp
->main_zebra_update_hold
= 0;
1900 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1901 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1903 bgp_zebra_announce_table(bgp
, afi
, safi
);
1905 bgp
->main_peers_update_hold
= 0;
1907 bgp_start_routeadv(bgp
);
1911 /* Best path selection. */
1912 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1913 old_select
= old_and_new
.old
;
1914 new_select
= old_and_new
.new;
1916 /* Nothing to do. */
1917 if (old_select
&& old_select
== new_select
&&
1918 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1919 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1920 !bgp
->addpath_tx_used
[afi
][safi
])
1922 if (bgp_zebra_has_route_changed (rn
, old_select
))
1925 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1926 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1928 bgp_zebra_announce (p
, old_select
, bgp
, afi
, safi
);
1930 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1931 bgp_zebra_clear_route_change_flags (rn
);
1932 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
1936 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
1937 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1939 /* bestpath has changed; bump version */
1940 if (old_select
|| new_select
)
1942 bgp_bump_version(rn
);
1944 if (!bgp
->t_rmap_def_originate_eval
)
1947 THREAD_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
1948 update_group_refresh_default_originate_route_map
,
1949 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
1954 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
1957 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
1958 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
1959 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1963 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
1964 if (old_select
!= new_select
) {
1966 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
1967 vnc_import_bgp_del_route(bgp
, p
, old_select
);
1970 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
1971 vnc_import_bgp_add_route(bgp
, p
, new_select
);
1977 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
1980 if ((safi
== SAFI_UNICAST
|| safi
== SAFI_MULTICAST
) &&
1981 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
1982 !bgp_option_check (BGP_OPT_NO_FIB
))
1985 && new_select
->type
== ZEBRA_ROUTE_BGP
1986 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
1987 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1988 bgp_zebra_announce (p
, new_select
, bgp
, afi
, safi
);
1991 /* Withdraw the route from the kernel. */
1993 && old_select
->type
== ZEBRA_ROUTE_BGP
1994 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
1995 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1996 bgp_zebra_withdraw (p
, old_select
, safi
);
2000 /* Clear any route change flags. */
2001 bgp_zebra_clear_route_change_flags (rn
);
2003 /* Reap old select bgp_info, if it has been removed */
2004 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2005 bgp_info_reap (rn
, old_select
);
2007 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2012 bgp_processq_del (struct work_queue
*wq
, void *data
)
2014 struct bgp_process_queue
*pq
= data
;
2015 struct bgp_table
*table
;
2017 bgp_unlock (pq
->bgp
);
2020 table
= bgp_node_table (pq
->rn
);
2021 bgp_unlock_node (pq
->rn
);
2022 bgp_table_unlock (table
);
2024 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2028 bgp_process_queue_init (void)
2030 if (!bm
->process_main_queue
)
2032 bm
->process_main_queue
2033 = work_queue_new (bm
->master
, "process_main_queue");
2035 if ( !bm
->process_main_queue
)
2037 zlog_err ("%s: Failed to allocate work queue", __func__
);
2042 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2043 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2044 bm
->process_main_queue
->spec
.max_retries
= 0;
2045 bm
->process_main_queue
->spec
.hold
= 50;
2046 /* Use a higher yield value of 50ms for main queue processing */
2047 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2051 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2053 struct bgp_process_queue
*pqnode
;
2055 /* already scheduled for processing? */
2056 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2059 if (bm
->process_main_queue
== NULL
)
2060 bgp_process_queue_init ();
2062 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2063 sizeof (struct bgp_process_queue
));
2067 /* all unlocked in bgp_processq_del */
2068 bgp_table_lock (bgp_node_table (rn
));
2069 pqnode
->rn
= bgp_lock_node (rn
);
2073 pqnode
->safi
= safi
;
2074 work_queue_add (bm
->process_main_queue
, pqnode
);
2075 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2080 bgp_add_eoiu_mark (struct bgp
*bgp
)
2082 struct bgp_process_queue
*pqnode
;
2084 if (bm
->process_main_queue
== NULL
)
2085 bgp_process_queue_init ();
2087 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2088 sizeof (struct bgp_process_queue
));
2095 work_queue_add (bm
->process_main_queue
, pqnode
);
2099 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2103 peer
= THREAD_ARG (thread
);
2104 peer
->t_pmax_restart
= NULL
;
2106 if (bgp_debug_neighbor_events(peer
))
2107 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2110 peer_clear (peer
, NULL
);
2116 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2117 safi_t safi
, int always
)
2122 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2125 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2127 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2131 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2132 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2133 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2134 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2136 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2139 /* Convert AFI, SAFI to values for packet. */
2140 pkt_afi
= afi_int2iana (afi
);
2141 pkt_safi
= safi_int2iana (safi
);
2145 ndata
[0] = (pkt_afi
>> 8);
2147 ndata
[2] = pkt_safi
;
2148 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2149 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2150 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2151 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2153 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2154 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2155 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2158 /* Dynamic peers will just close their connection. */
2159 if (peer_dynamic_neighbor (peer
))
2162 /* restart timer start */
2163 if (peer
->pmax_restart
[afi
][safi
])
2165 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2167 if (bgp_debug_neighbor_events(peer
))
2168 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2169 peer
->host
, peer
->v_pmax_restart
);
2171 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2172 peer
->v_pmax_restart
);
2178 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2180 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2182 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2186 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2187 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2188 peer
->pmax
[afi
][safi
]);
2189 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2192 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2196 /* Unconditionally remove the route from the RIB, without taking
2197 * damping into consideration (eg, because the session went down)
2200 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2201 afi_t afi
, safi_t safi
)
2203 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2205 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2206 bgp_info_delete (rn
, ri
); /* keep historical info */
2208 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2212 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2213 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2215 int status
= BGP_DAMP_NONE
;
2217 /* apply dampening, if result is suppressed, we'll be retaining
2218 * the bgp_info in the RIB for historical reference.
2220 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2221 && peer
->sort
== BGP_PEER_EBGP
)
2222 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2223 == BGP_DAMP_SUPPRESSED
)
2225 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2230 if (safi
== SAFI_MPLS_VPN
) {
2231 struct bgp_node
*prn
= NULL
;
2232 struct bgp_table
*table
= NULL
;
2234 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2236 table
= (struct bgp_table
*)(prn
->info
);
2238 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2245 bgp_unlock_node(prn
);
2247 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2248 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2250 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2251 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2255 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2258 static struct bgp_info
*
2259 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2260 struct bgp_node
*rn
)
2262 struct bgp_info
*new;
2264 /* Make new BGP info. */
2265 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2267 new->instance
= instance
;
2268 new->sub_type
= sub_type
;
2271 new->uptime
= bgp_clock ();
2273 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2278 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2280 struct attr_extra
*extra
;
2284 extra
= bgp_attr_extra_get(attr
);
2286 if(eth_s_id
== NULL
)
2288 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2292 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2296 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2300 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2305 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2307 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2308 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2311 if(afi
!= AFI_L2VPN
)
2313 if (!info
->attr
|| !info
->attr
->extra
)
2315 memset(&temp
, 0, 16);
2316 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2317 info_gw_ip
= (union gw_addr
*)&temp
;
2318 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2323 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2324 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2327 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2329 info_gw_ip_remote
= gw_ip
;
2330 if(eth_s_id
== NULL
)
2331 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2333 info_eth_s_id_remote
= eth_s_id
;
2334 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2336 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2339 /* Check if received nexthop is valid or not. */
2341 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2343 struct attr_extra
*attre
= attr
->extra
;
2346 /* Only validated for unicast and multicast currently. */
2347 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2350 /* If NEXT_HOP is present, validate it. */
2351 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2353 if (attr
->nexthop
.s_addr
== 0 ||
2354 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2355 bgp_nexthop_self (bgp
, attr
))
2359 /* If MP_NEXTHOP is present, validate it. */
2360 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2361 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2362 * it is not an IPv6 link-local address.
2364 if (attre
&& attre
->mp_nexthop_len
)
2366 switch (attre
->mp_nexthop_len
)
2368 case BGP_ATTR_NHLEN_IPV4
:
2369 case BGP_ATTR_NHLEN_VPNV4
:
2370 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2371 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2374 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2375 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2376 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2377 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2378 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2379 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2392 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2393 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2394 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2395 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2398 int aspath_loop_count
= 0;
2399 struct bgp_node
*rn
;
2401 struct attr new_attr
;
2402 struct attr_extra new_extra
;
2403 struct attr
*attr_new
;
2404 struct bgp_info
*ri
;
2405 struct bgp_info
*new;
2407 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2409 int do_loop_check
= 1;
2411 int vnc_implicit_withdraw
= 0;
2414 memset (&new_attr
, 0, sizeof(struct attr
));
2415 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2418 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2420 /* When peer's soft reconfiguration enabled. Record input packet in
2422 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2423 && peer
!= bgp
->peer_self
)
2424 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2426 /* Check previously received route. */
2427 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2428 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2429 ri
->addpath_rx_id
== addpath_id
)
2432 /* AS path local-as loop check. */
2433 if (peer
->change_local_as
)
2435 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2436 aspath_loop_count
= 1;
2438 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2440 reason
= "as-path contains our own AS;";
2445 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2446 * as-path is our ASN then we do not need to call aspath_loop_check
2448 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2449 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2452 /* AS path loop check. */
2455 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2456 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2457 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2459 reason
= "as-path contains our own AS;";
2464 /* Route reflector originator ID check. */
2465 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2466 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2468 reason
= "originator is us;";
2472 /* Route reflector cluster ID check. */
2473 if (bgp_cluster_filter (peer
, attr
))
2475 reason
= "reflected from the same cluster;";
2479 /* Apply incoming filter. */
2480 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2486 new_attr
.extra
= &new_extra
;
2487 bgp_attr_dup (&new_attr
, attr
);
2489 /* Apply incoming route-map.
2490 * NB: new_attr may now contain newly allocated values from route-map "set"
2491 * commands, so we need bgp_attr_flush in the error paths, until we intern
2492 * the attr (which takes over the memory references) */
2493 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2495 reason
= "route-map;";
2496 bgp_attr_flush (&new_attr
);
2500 /* next hop check. */
2501 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2503 reason
= "martian or self next-hop;";
2504 bgp_attr_flush (&new_attr
);
2508 attr_new
= bgp_attr_intern (&new_attr
);
2510 /* If the update is implicit withdraw. */
2513 ri
->uptime
= bgp_clock ();
2515 /* Same attribute comes in. */
2516 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2517 && attrhash_cmp (ri
->attr
, attr_new
)
2518 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2519 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2521 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2522 && peer
->sort
== BGP_PEER_EBGP
2523 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2525 if (bgp_debug_update(peer
, p
, NULL
, 1))
2526 zlog_debug ("%s rcvd %s", peer
->host
,
2527 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2528 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2530 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2532 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2533 bgp_process (bgp
, rn
, afi
, safi
);
2536 else /* Duplicate - odd */
2538 if (bgp_debug_update(peer
, p
, NULL
, 1))
2540 if (!peer
->rcvd_attr_printed
)
2542 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2543 peer
->rcvd_attr_printed
= 1;
2546 zlog_debug ("%s rcvd %s...duplicate ignored",
2548 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2549 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2552 /* graceful restart STALE flag unset. */
2553 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2555 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2556 bgp_process (bgp
, rn
, afi
, safi
);
2560 bgp_unlock_node (rn
);
2561 bgp_attr_unintern (&attr_new
);
2566 /* Withdraw/Announce before we fully processed the withdraw */
2567 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2569 if (bgp_debug_update(peer
, p
, NULL
, 1))
2570 zlog_debug ("%s rcvd %s, flapped quicker than processing",
2572 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2573 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2574 bgp_info_restore (rn
, ri
);
2577 /* Received Logging. */
2578 if (bgp_debug_update(peer
, p
, NULL
, 1))
2579 zlog_debug ("%s rcvd %s", peer
->host
,
2580 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2581 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2583 /* graceful restart STALE flag unset. */
2584 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2585 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2587 /* The attribute is changed. */
2588 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2590 /* implicit withdraw, decrement aggregate and pcount here.
2591 * only if update is accepted, they'll increment below.
2593 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2595 /* Update bgp route dampening information. */
2596 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2597 && peer
->sort
== BGP_PEER_EBGP
)
2599 /* This is implicit withdraw so we should update dampening
2601 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2602 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2605 if (safi
== SAFI_MPLS_VPN
) {
2606 struct bgp_node
*prn
= NULL
;
2607 struct bgp_table
*table
= NULL
;
2609 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2611 table
= (struct bgp_table
*)(prn
->info
);
2613 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2620 bgp_unlock_node(prn
);
2622 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2623 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2625 * Implicit withdraw case.
2627 ++vnc_implicit_withdraw
;
2628 vnc_import_bgp_del_route(bgp
, p
, ri
);
2629 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2634 /* Update to new attribute. */
2635 bgp_attr_unintern (&ri
->attr
);
2636 ri
->attr
= attr_new
;
2638 /* Update MPLS tag. */
2639 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2640 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2643 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2645 if (vnc_implicit_withdraw
)
2648 * Add back the route with its new attributes (e.g., nexthop).
2649 * The route is still selected, until the route selection
2650 * queued by bgp_process actually runs. We have to make this
2651 * update to the VNC side immediately to avoid racing against
2652 * configuration changes (e.g., route-map changes) which
2653 * trigger re-importation of the entire RIB.
2655 vnc_import_bgp_add_route(bgp
, p
, ri
);
2656 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2660 /* Update Overlay Index */
2661 if(afi
== AFI_L2VPN
)
2663 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2664 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2667 /* Update bgp route dampening information. */
2668 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2669 && peer
->sort
== BGP_PEER_EBGP
)
2671 /* Now we do normal update dampening. */
2672 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2673 if (ret
== BGP_DAMP_SUPPRESSED
)
2675 bgp_unlock_node (rn
);
2680 /* Nexthop reachability check. */
2681 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2683 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2684 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2685 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2690 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2691 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2694 if (BGP_DEBUG(nht
, NHT
))
2696 char buf1
[INET6_ADDRSTRLEN
];
2697 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2698 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2700 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2704 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2707 if (safi
== SAFI_MPLS_VPN
)
2709 struct bgp_node
*prn
= NULL
;
2710 struct bgp_table
*table
= NULL
;
2712 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2715 table
= (struct bgp_table
*)(prn
->info
);
2717 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2724 bgp_unlock_node(prn
);
2728 /* Process change. */
2729 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2731 bgp_process (bgp
, rn
, afi
, safi
);
2732 bgp_unlock_node (rn
);
2735 if (SAFI_MPLS_VPN
== safi
)
2737 uint32_t label
= decode_label(tag
);
2739 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2742 if (SAFI_ENCAP
== safi
)
2744 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2750 } // End of implicit withdraw
2752 /* Received Logging. */
2753 if (bgp_debug_update(peer
, p
, NULL
, 1))
2755 if (!peer
->rcvd_attr_printed
)
2757 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2758 peer
->rcvd_attr_printed
= 1;
2761 zlog_debug ("%s rcvd %s", peer
->host
,
2762 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2763 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2766 /* Make new BGP info. */
2767 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2769 /* Update MPLS tag. */
2770 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2771 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2773 /* Update Overlay Index */
2774 if(afi
== AFI_L2VPN
)
2776 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2777 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2779 /* Nexthop reachability check. */
2780 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2782 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2783 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2784 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2789 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2790 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2793 if (BGP_DEBUG(nht
, NHT
))
2795 char buf1
[INET6_ADDRSTRLEN
];
2796 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2797 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2799 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2803 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2806 new->addpath_rx_id
= addpath_id
;
2808 /* Increment prefix */
2809 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2811 /* Register new BGP information. */
2812 bgp_info_add (rn
, new);
2814 /* route_node_get lock */
2815 bgp_unlock_node (rn
);
2818 if (safi
== SAFI_MPLS_VPN
)
2820 struct bgp_node
*prn
= NULL
;
2821 struct bgp_table
*table
= NULL
;
2823 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2826 table
= (struct bgp_table
*)(prn
->info
);
2828 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2835 bgp_unlock_node(prn
);
2839 /* If maximum prefix count is configured and current prefix
2841 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2844 /* Process change. */
2845 bgp_process (bgp
, rn
, afi
, safi
);
2848 if (SAFI_MPLS_VPN
== safi
)
2850 uint32_t label
= decode_label(tag
);
2852 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2855 if (SAFI_ENCAP
== safi
)
2857 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2864 /* This BGP update is filtered. Log the reason then update BGP
2867 if (bgp_debug_update(peer
, p
, NULL
, 1))
2869 if (!peer
->rcvd_attr_printed
)
2871 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2872 peer
->rcvd_attr_printed
= 1;
2875 zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
2877 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2878 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), reason
);
2882 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2884 bgp_unlock_node (rn
);
2888 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2889 * a few lines above)
2891 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2893 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2901 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2902 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2903 struct prefix_rd
*prd
, u_char
*tag
, struct bgp_route_evpn
*evpn
)
2906 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2907 struct bgp_node
*rn
;
2908 struct bgp_info
*ri
;
2911 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2913 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2920 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2922 /* If peer is soft reconfiguration enabled. Record input packet for
2923 * further calculation.
2925 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2926 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2927 * the iteration over all RS clients.
2928 * Since we need to remove the entry from adj_in anyway, do that first and
2929 * if there was no entry, we don't need to do anything more.
2931 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2932 && peer
!= bgp
->peer_self
)
2933 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2935 if (bgp_debug_update (peer
, p
, NULL
, 1))
2936 zlog_debug ("%s withdrawing route %s not in adj-in",
2938 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2939 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2940 bgp_unlock_node (rn
);
2944 /* Lookup withdrawn route. */
2945 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2946 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2947 ri
->addpath_rx_id
== addpath_id
)
2951 if (bgp_debug_update(peer
, p
, NULL
, 1))
2953 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
2955 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2956 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2959 /* Withdraw specified route from routing table. */
2960 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2961 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2962 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2963 zlog_debug ("%s Can't find the route %s",
2965 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2966 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2968 /* Unlock bgp_node_get() lock. */
2969 bgp_unlock_node (rn
);
2975 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2977 struct update_subgroup
*subgrp
;
2978 subgrp
= peer_subgroup(peer
, afi
, safi
);
2979 subgroup_default_originate(subgrp
, withdraw
);
2984 * bgp_stop_announce_route_timer
2987 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2989 if (!paf
->t_announce_route
)
2992 THREAD_TIMER_OFF (paf
->t_announce_route
);
2996 * bgp_announce_route_timer_expired
2998 * Callback that is invoked when the route announcement timer for a
3002 bgp_announce_route_timer_expired (struct thread
*t
)
3004 struct peer_af
*paf
;
3007 paf
= THREAD_ARG (t
);
3010 assert (paf
->t_announce_route
);
3011 paf
->t_announce_route
= NULL
;
3013 if (peer
->status
!= Established
)
3016 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3019 peer_af_announce_route (paf
, 1);
3024 * bgp_announce_route
3026 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3029 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3031 struct peer_af
*paf
;
3032 struct update_subgroup
*subgrp
;
3034 paf
= peer_af_find (peer
, afi
, safi
);
3037 subgrp
= PAF_SUBGRP(paf
);
3040 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3041 * or a refresh has already been triggered.
3043 if (!subgrp
|| paf
->t_announce_route
)
3047 * Start a timer to stagger/delay the announce. This serves
3048 * two purposes - announcement can potentially be combined for
3049 * multiple peers and the announcement doesn't happen in the
3052 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
3053 bgp_announce_route_timer_expired
, paf
,
3054 (subgrp
->peer_count
== 1) ?
3055 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
3056 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
3060 * Announce routes from all AF tables to a peer.
3062 * This should ONLY be called when there is a need to refresh the
3063 * routes to the peer based on a policy change for this peer alone
3064 * or a route refresh request received from the peer.
3065 * The operation will result in splitting the peer from its existing
3066 * subgroups and putting it in new subgroups.
3069 bgp_announce_route_all (struct peer
*peer
)
3074 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3075 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3076 bgp_announce_route (peer
, afi
, safi
);
3080 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3081 struct bgp_table
*table
, struct prefix_rd
*prd
)
3084 struct bgp_node
*rn
;
3085 struct bgp_adj_in
*ain
;
3088 table
= peer
->bgp
->rib
[afi
][safi
];
3090 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3091 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3093 if (ain
->peer
== peer
)
3095 struct bgp_info
*ri
= rn
->info
;
3096 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3098 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3099 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3104 bgp_unlock_node (rn
);
3112 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3114 struct bgp_node
*rn
;
3115 struct bgp_table
*table
;
3117 if (peer
->status
!= Established
)
3120 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3121 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3123 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3124 rn
= bgp_route_next (rn
))
3125 if ((table
= rn
->info
) != NULL
)
3127 struct prefix_rd prd
;
3128 prd
.family
= AF_UNSPEC
;
3130 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3132 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3137 struct bgp_clear_node_queue
3139 struct bgp_node
*rn
;
3142 static wq_item_status
3143 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3145 struct bgp_clear_node_queue
*cnq
= data
;
3146 struct bgp_node
*rn
= cnq
->rn
;
3147 struct peer
*peer
= wq
->spec
.data
;
3148 struct bgp_info
*ri
;
3149 afi_t afi
= bgp_node_table (rn
)->afi
;
3150 safi_t safi
= bgp_node_table (rn
)->safi
;
3152 assert (rn
&& peer
);
3154 /* It is possible that we have multiple paths for a prefix from a peer
3155 * if that peer is using AddPath.
3157 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3158 if (ri
->peer
== peer
)
3160 /* graceful restart STALE flag set. */
3161 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3162 && peer
->nsf
[afi
][safi
]
3163 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3164 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3165 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3167 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3173 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3175 struct bgp_clear_node_queue
*cnq
= data
;
3176 struct bgp_node
*rn
= cnq
->rn
;
3177 struct bgp_table
*table
= bgp_node_table (rn
);
3179 bgp_unlock_node (rn
);
3180 bgp_table_unlock (table
);
3181 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3185 bgp_clear_node_complete (struct work_queue
*wq
)
3187 struct peer
*peer
= wq
->spec
.data
;
3189 /* Tickle FSM to start moving again */
3190 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3192 peer_unlock (peer
); /* bgp_clear_route */
3196 bgp_clear_node_queue_init (struct peer
*peer
)
3198 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3200 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3201 #undef CLEAR_QUEUE_NAME_LEN
3203 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3205 zlog_err ("%s: Failed to allocate work queue", __func__
);
3208 peer
->clear_node_queue
->spec
.hold
= 10;
3209 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3210 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3211 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3212 peer
->clear_node_queue
->spec
.max_retries
= 0;
3214 /* we only 'lock' this peer reference when the queue is actually active */
3215 peer
->clear_node_queue
->spec
.data
= peer
;
3219 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3220 struct bgp_table
*table
)
3222 struct bgp_node
*rn
;
3223 int force
= bm
->process_main_queue
? 0 : 1;
3226 table
= peer
->bgp
->rib
[afi
][safi
];
3228 /* If still no table => afi/safi isn't configured at all or smth. */
3232 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3234 struct bgp_info
*ri
, *next
;
3235 struct bgp_adj_in
*ain
;
3236 struct bgp_adj_in
*ain_next
;
3238 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3239 * queued for every clearing peer, regardless of whether it is
3240 * relevant to the peer at hand.
3242 * Overview: There are 3 different indices which need to be
3243 * scrubbed, potentially, when a peer is removed:
3245 * 1 peer's routes visible via the RIB (ie accepted routes)
3246 * 2 peer's routes visible by the (optional) peer's adj-in index
3247 * 3 other routes visible by the peer's adj-out index
3249 * 3 there is no hurry in scrubbing, once the struct peer is
3250 * removed from bgp->peer, we could just GC such deleted peer's
3251 * adj-outs at our leisure.
3253 * 1 and 2 must be 'scrubbed' in some way, at least made
3254 * invisible via RIB index before peer session is allowed to be
3255 * brought back up. So one needs to know when such a 'search' is
3260 * - there'd be a single global queue or a single RIB walker
3261 * - rather than tracking which route_nodes still need to be
3262 * examined on a peer basis, we'd track which peers still
3265 * Given that our per-peer prefix-counts now should be reliable,
3266 * this may actually be achievable. It doesn't seem to be a huge
3267 * problem at this time,
3269 * It is possible that we have multiple paths for a prefix from a peer
3270 * if that peer is using AddPath.
3275 ain_next
= ain
->next
;
3277 if (ain
->peer
== peer
)
3279 bgp_adj_in_remove (rn
, ain
);
3280 bgp_unlock_node (rn
);
3286 for (ri
= rn
->info
; ri
; ri
= next
)
3289 if (ri
->peer
!= peer
)
3293 bgp_info_reap (rn
, ri
);
3296 struct bgp_clear_node_queue
*cnq
;
3298 /* both unlocked in bgp_clear_node_queue_del */
3299 bgp_table_lock (bgp_node_table (rn
));
3301 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3302 sizeof (struct bgp_clear_node_queue
));
3304 work_queue_add (peer
->clear_node_queue
, cnq
);
3313 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3315 struct bgp_node
*rn
;
3316 struct bgp_table
*table
;
3318 if (peer
->clear_node_queue
== NULL
)
3319 bgp_clear_node_queue_init (peer
);
3321 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3322 * Idle until it receives a Clearing_Completed event. This protects
3323 * against peers which flap faster than we can we clear, which could
3326 * a) race with routes from the new session being installed before
3327 * clear_route_node visits the node (to delete the route of that
3329 * b) resource exhaustion, clear_route_node likely leads to an entry
3330 * on the process_main queue. Fast-flapping could cause that queue
3334 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3335 * the unlock will happen upon work-queue completion; other wise, the
3336 * unlock happens at the end of this function.
3338 if (!peer
->clear_node_queue
->thread
)
3341 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3342 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3344 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3345 rn
= bgp_route_next (rn
))
3346 if ((table
= rn
->info
) != NULL
)
3347 bgp_clear_route_table (peer
, afi
, safi
, table
);
3349 /* unlock if no nodes got added to the clear-node-queue. */
3350 if (!peer
->clear_node_queue
->thread
)
3356 bgp_clear_route_all (struct peer
*peer
)
3361 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3362 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3363 bgp_clear_route (peer
, afi
, safi
);
3366 rfapiProcessPeerDown(peer
);
3371 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3373 struct bgp_table
*table
;
3374 struct bgp_node
*rn
;
3375 struct bgp_adj_in
*ain
;
3376 struct bgp_adj_in
*ain_next
;
3378 table
= peer
->bgp
->rib
[afi
][safi
];
3380 /* It is possible that we have multiple paths for a prefix from a peer
3381 * if that peer is using AddPath.
3383 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3389 ain_next
= ain
->next
;
3391 if (ain
->peer
== peer
)
3393 bgp_adj_in_remove (rn
, ain
);
3394 bgp_unlock_node (rn
);
3403 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3405 struct bgp_node
*rn
;
3406 struct bgp_info
*ri
;
3407 struct bgp_table
*table
;
3409 if ( safi
== SAFI_MPLS_VPN
)
3411 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3413 struct bgp_node
*rm
;
3414 struct bgp_info
*ri
;
3416 /* look for neighbor in tables */
3417 if ((table
= rn
->info
) != NULL
)
3419 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3420 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3421 if (ri
->peer
== peer
)
3423 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3424 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3432 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3433 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3434 if (ri
->peer
== peer
)
3436 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3437 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3444 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3446 struct bgp_node
*rn
;
3447 struct bgp_info
*ri
;
3448 struct bgp_info
*next
;
3450 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3451 for (ri
= rn
->info
; ri
; ri
= next
)
3454 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3455 && ri
->type
== ZEBRA_ROUTE_BGP
3456 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3457 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3460 if (table
->owner
&& table
->owner
->bgp
)
3461 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3463 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3464 bgp_info_reap (rn
, ri
);
3469 /* Delete all kernel routes. */
3471 bgp_cleanup_routes (struct bgp
*bgp
)
3474 struct bgp_node
*rn
;
3476 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3478 if (afi
== AFI_L2VPN
)
3480 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3482 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3484 if (afi
!= AFI_L2VPN
)
3487 safi
= SAFI_MPLS_VPN
;
3488 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3489 rn
= bgp_route_next (rn
))
3493 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3494 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3496 bgp_unlock_node(rn
);
3500 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3501 rn
= bgp_route_next (rn
))
3505 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3506 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3508 bgp_unlock_node(rn
);
3513 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3514 rn
= bgp_route_next (rn
))
3518 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3519 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3521 bgp_unlock_node(rn
);
3530 bgp_zclient_reset ();
3531 access_list_reset ();
3532 prefix_list_reset ();
3536 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3538 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3539 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3542 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3545 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3546 struct bgp_nlri
*packet
)
3555 int addpath_encoded
;
3556 u_int32_t addpath_id
;
3558 /* Check peer status. */
3559 if (peer
->status
!= Established
)
3563 lim
= pnt
+ packet
->length
;
3565 safi
= packet
->safi
;
3567 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3569 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3570 syntactic validity. If the field is syntactically incorrect,
3571 then the Error Subcode is set to Invalid Network Field. */
3572 for (; pnt
< lim
; pnt
+= psize
)
3574 /* Clear prefix structure. */
3575 memset (&p
, 0, sizeof (struct prefix
));
3577 if (addpath_encoded
)
3580 /* When packet overflow occurs return immediately. */
3581 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3584 addpath_id
= ntohl(*((uint32_t*) pnt
));
3585 pnt
+= BGP_ADDPATH_ID_LEN
;
3588 /* Fetch prefix length. */
3589 p
.prefixlen
= *pnt
++;
3590 /* afi/safi validity already verified by caller, bgp_update_receive */
3591 p
.family
= afi2family (afi
);
3593 /* Prefix length check. */
3594 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3596 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3597 peer
->host
, p
.prefixlen
, packet
->afi
);
3601 /* Packet size overflow check. */
3602 psize
= PSIZE (p
.prefixlen
);
3604 /* When packet overflow occur return immediately. */
3605 if (pnt
+ psize
> lim
)
3607 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3608 peer
->host
, p
.prefixlen
);
3612 /* Defensive coding, double-check the psize fits in a struct prefix */
3613 if (psize
> (ssize_t
) sizeof(p
.u
))
3615 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3616 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3620 /* Fetch prefix from NLRI packet. */
3621 memcpy (&p
.u
.prefix
, pnt
, psize
);
3623 /* Check address. */
3624 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3626 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3628 /* From RFC4271 Section 6.3:
3630 * If a prefix in the NLRI field is semantically incorrect
3631 * (e.g., an unexpected multicast IP address), an error SHOULD
3632 * be logged locally, and the prefix SHOULD be ignored.
3634 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3635 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3640 /* Check address. */
3641 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3643 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3647 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3648 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3652 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3656 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3657 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3663 /* Normal process. */
3665 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3666 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3668 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3669 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3671 /* Address family configuration mismatch or maximum-prefix count
3677 /* Packet length consistency check. */
3680 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3688 static struct bgp_static
*
3689 bgp_static_new (void)
3691 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3695 bgp_static_free (struct bgp_static
*bgp_static
)
3697 if (bgp_static
->rmap
.name
)
3698 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3699 if(bgp_static
->eth_s_id
)
3700 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3701 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3705 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3706 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3708 struct bgp_node
*rn
;
3709 struct bgp_info
*ri
;
3710 struct bgp_info
*new;
3711 struct bgp_info info
;
3713 struct attr
*attr_new
;
3716 int vnc_implicit_withdraw
= 0;
3719 assert (bgp_static
);
3723 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3725 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3727 attr
.nexthop
= bgp_static
->igpnexthop
;
3728 attr
.med
= bgp_static
->igpmetric
;
3729 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3731 if (bgp_static
->atomic
)
3732 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3734 /* Apply route-map. */
3735 if (bgp_static
->rmap
.name
)
3737 struct attr attr_tmp
= attr
;
3738 info
.peer
= bgp
->peer_self
;
3739 info
.attr
= &attr_tmp
;
3741 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3743 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3745 bgp
->peer_self
->rmap_type
= 0;
3747 if (ret
== RMAP_DENYMATCH
)
3749 /* Free uninterned attribute. */
3750 bgp_attr_flush (&attr_tmp
);
3752 /* Unintern original. */
3753 aspath_unintern (&attr
.aspath
);
3754 bgp_attr_extra_free (&attr
);
3755 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3758 attr_new
= bgp_attr_intern (&attr_tmp
);
3761 attr_new
= bgp_attr_intern (&attr
);
3763 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3764 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3765 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3770 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3771 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3772 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3774 bgp_unlock_node (rn
);
3775 bgp_attr_unintern (&attr_new
);
3776 aspath_unintern (&attr
.aspath
);
3777 bgp_attr_extra_free (&attr
);
3782 /* The attribute is changed. */
3783 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3785 /* Rewrite BGP route information. */
3786 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3787 bgp_info_restore(rn
, ri
);
3789 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3791 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3793 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3796 * Implicit withdraw case.
3797 * We have to do this before ri is changed
3799 ++vnc_implicit_withdraw
;
3800 vnc_import_bgp_del_route(bgp
, p
, ri
);
3801 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3805 bgp_attr_unintern (&ri
->attr
);
3806 ri
->attr
= attr_new
;
3807 ri
->uptime
= bgp_clock ();
3809 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3811 if (vnc_implicit_withdraw
)
3813 vnc_import_bgp_add_route(bgp
, p
, ri
);
3814 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3819 /* Nexthop reachability check. */
3820 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3822 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3823 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3826 if (BGP_DEBUG(nht
, NHT
))
3828 char buf1
[INET6_ADDRSTRLEN
];
3829 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3831 zlog_debug("%s(%s): Route not in table, not advertising",
3832 __FUNCTION__
, buf1
);
3834 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3839 /* Delete the NHT structure if any, if we're toggling between
3840 * enabling/disabling import check. We deregister the route
3841 * from NHT to avoid overloading NHT and the process interaction
3843 bgp_unlink_nexthop(ri
);
3844 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3846 /* Process change. */
3847 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3848 bgp_process (bgp
, rn
, afi
, safi
);
3849 bgp_unlock_node (rn
);
3850 aspath_unintern (&attr
.aspath
);
3851 bgp_attr_extra_free (&attr
);
3856 /* Make new BGP info. */
3857 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3859 /* Nexthop reachability check. */
3860 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3862 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3863 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3866 if (BGP_DEBUG(nht
, NHT
))
3868 char buf1
[INET6_ADDRSTRLEN
];
3869 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3871 zlog_debug("%s(%s): Route not in table, not advertising",
3872 __FUNCTION__
, buf1
);
3874 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3879 /* Delete the NHT structure if any, if we're toggling between
3880 * enabling/disabling import check. We deregister the route
3881 * from NHT to avoid overloading NHT and the process interaction
3883 bgp_unlink_nexthop(new);
3885 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3888 /* Aggregate address increment. */
3889 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3891 /* Register new BGP information. */
3892 bgp_info_add (rn
, new);
3894 /* route_node_get lock */
3895 bgp_unlock_node (rn
);
3897 /* Process change. */
3898 bgp_process (bgp
, rn
, afi
, safi
);
3900 /* Unintern original. */
3901 aspath_unintern (&attr
.aspath
);
3902 bgp_attr_extra_free (&attr
);
3906 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3907 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3909 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3913 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3916 struct bgp_node
*rn
;
3917 struct bgp_info
*ri
;
3919 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3921 /* Check selected route and self inserted route. */
3922 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3923 if (ri
->peer
== bgp
->peer_self
3924 && ri
->type
== ZEBRA_ROUTE_BGP
3925 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3928 /* Withdraw static BGP route from routing table. */
3931 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3932 bgp_unlink_nexthop(ri
);
3933 bgp_info_delete (rn
, ri
);
3934 bgp_process (bgp
, rn
, afi
, safi
);
3937 /* Unlock bgp_node_lookup. */
3938 bgp_unlock_node (rn
);
3942 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3945 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3946 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3948 struct bgp_node
*rn
;
3949 struct bgp_info
*ri
;
3951 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3953 /* Check selected route and self inserted route. */
3954 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3955 if (ri
->peer
== bgp
->peer_self
3956 && ri
->type
== ZEBRA_ROUTE_BGP
3957 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3960 /* Withdraw static BGP route from routing table. */
3964 rfapiProcessWithdraw(
3973 1); /* Kill, since it is an administrative change */
3975 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3976 bgp_info_delete (rn
, ri
);
3977 bgp_process (bgp
, rn
, afi
, safi
);
3980 /* Unlock bgp_node_lookup. */
3981 bgp_unlock_node (rn
);
3985 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3986 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3988 struct bgp_node
*rn
;
3989 struct bgp_info
*new;
3990 struct attr
*attr_new
;
3991 struct attr attr
= { 0 };
3992 struct bgp_info
*ri
;
3994 u_int32_t label
= 0;
3998 assert (bgp_static
);
4000 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
4002 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4004 attr
.nexthop
= bgp_static
->igpnexthop
;
4005 attr
.med
= bgp_static
->igpmetric
;
4006 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4008 if(afi
== AFI_L2VPN
)
4010 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4011 add
.ipv4
.s_addr
= bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4012 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4013 memcpy( &(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
), sizeof (struct in6_addr
));
4014 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4015 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
)
4017 struct bgp_encap_type_vxlan bet
;
4018 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4019 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4020 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4022 if (bgp_static
->router_mac
)
4024 bgp_add_routermac_ecom (&attr
, bgp_static
->router_mac
);
4027 /* Apply route-map. */
4028 if (bgp_static
->rmap
.name
)
4030 struct attr attr_tmp
= attr
;
4031 struct bgp_info info
;
4034 info
.peer
= bgp
->peer_self
;
4035 info
.attr
= &attr_tmp
;
4037 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4039 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4041 bgp
->peer_self
->rmap_type
= 0;
4043 if (ret
== RMAP_DENYMATCH
)
4045 /* Free uninterned attribute. */
4046 bgp_attr_flush (&attr_tmp
);
4048 /* Unintern original. */
4049 aspath_unintern (&attr
.aspath
);
4050 bgp_attr_extra_free (&attr
);
4051 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4056 attr_new
= bgp_attr_intern (&attr_tmp
);
4060 attr_new
= bgp_attr_intern (&attr
);
4063 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4064 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4065 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4071 memset(&add
, 0, sizeof(union gw_addr
));
4072 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4073 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4074 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4076 bgp_unlock_node (rn
);
4077 bgp_attr_unintern (&attr_new
);
4078 aspath_unintern (&attr
.aspath
);
4079 bgp_attr_extra_free (&attr
);
4084 /* The attribute is changed. */
4085 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4087 /* Rewrite BGP route information. */
4088 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4089 bgp_info_restore(rn
, ri
);
4091 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4092 bgp_attr_unintern (&ri
->attr
);
4093 ri
->attr
= attr_new
;
4094 ri
->uptime
= bgp_clock ();
4097 label
= decode_label (ri
->extra
->tag
);
4100 /* Process change. */
4101 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4102 bgp_process (bgp
, rn
, afi
, safi
);
4104 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4105 ri
->attr
, afi
, safi
,
4106 ri
->type
, ri
->sub_type
, &label
);
4108 bgp_unlock_node (rn
);
4109 aspath_unintern (&attr
.aspath
);
4110 bgp_attr_extra_free (&attr
);
4116 /* Make new BGP info. */
4117 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4119 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4120 new->extra
= bgp_info_extra_new();
4121 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4123 label
= decode_label (bgp_static
->tag
);
4126 /* Aggregate address increment. */
4127 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4129 /* Register new BGP information. */
4130 bgp_info_add (rn
, new);
4132 /* route_node_get lock */
4133 bgp_unlock_node (rn
);
4135 /* Process change. */
4136 bgp_process (bgp
, rn
, afi
, safi
);
4139 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4140 new->attr
, afi
, safi
,
4141 new->type
, new->sub_type
, &label
);
4144 /* Unintern original. */
4145 aspath_unintern (&attr
.aspath
);
4146 bgp_attr_extra_free (&attr
);
4149 /* Configure static BGP network. When user don't run zebra, static
4150 route should be installed as valid. */
4152 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4153 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4155 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4158 struct bgp_static
*bgp_static
;
4159 struct bgp_node
*rn
;
4160 u_char need_update
= 0;
4162 /* Convert IP prefix string to struct prefix. */
4163 ret
= str2prefix (ip_str
, &p
);
4166 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4169 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4171 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4178 /* Set BGP static route configuration. */
4179 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4183 /* Configuration change. */
4184 bgp_static
= rn
->info
;
4186 /* Check previous routes are installed into BGP. */
4187 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4190 bgp_static
->backdoor
= backdoor
;
4194 if (bgp_static
->rmap
.name
)
4195 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4196 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4197 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4201 if (bgp_static
->rmap
.name
)
4202 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4203 bgp_static
->rmap
.name
= NULL
;
4204 bgp_static
->rmap
.map
= NULL
;
4205 bgp_static
->valid
= 0;
4207 bgp_unlock_node (rn
);
4211 /* New configuration. */
4212 bgp_static
= bgp_static_new ();
4213 bgp_static
->backdoor
= backdoor
;
4214 bgp_static
->valid
= 0;
4215 bgp_static
->igpmetric
= 0;
4216 bgp_static
->igpnexthop
.s_addr
= 0;
4220 if (bgp_static
->rmap
.name
)
4221 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4222 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4223 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4225 rn
->info
= bgp_static
;
4228 bgp_static
->valid
= 1;
4230 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4232 if (! bgp_static
->backdoor
)
4233 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4238 /* Configure static BGP network. */
4240 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4241 afi_t afi
, safi_t safi
)
4243 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4246 struct bgp_static
*bgp_static
;
4247 struct bgp_node
*rn
;
4249 /* Convert IP prefix string to struct prefix. */
4250 ret
= str2prefix (ip_str
, &p
);
4253 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4256 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4258 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4265 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4268 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4273 bgp_static
= rn
->info
;
4275 /* Update BGP RIB. */
4276 if (! bgp_static
->backdoor
)
4277 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4279 /* Clear configuration. */
4280 bgp_static_free (bgp_static
);
4282 bgp_unlock_node (rn
);
4283 bgp_unlock_node (rn
);
4289 bgp_static_add (struct bgp
*bgp
)
4293 struct bgp_node
*rn
;
4294 struct bgp_node
*rm
;
4295 struct bgp_table
*table
;
4296 struct bgp_static
*bgp_static
;
4298 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4299 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4300 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4301 if (rn
->info
!= NULL
)
4303 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4307 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4309 bgp_static
= rn
->info
;
4310 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4315 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4320 /* Called from bgp_delete(). Delete all static routes from the BGP
4323 bgp_static_delete (struct bgp
*bgp
)
4327 struct bgp_node
*rn
;
4328 struct bgp_node
*rm
;
4329 struct bgp_table
*table
;
4330 struct bgp_static
*bgp_static
;
4332 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4333 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4334 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4335 if (rn
->info
!= NULL
)
4337 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4341 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4343 bgp_static
= rn
->info
;
4344 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4346 (struct prefix_rd
*)&rn
->p
,
4348 bgp_static_free (bgp_static
);
4350 bgp_unlock_node (rn
);
4355 bgp_static
= rn
->info
;
4356 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4357 bgp_static_free (bgp_static
);
4359 bgp_unlock_node (rn
);
4365 bgp_static_redo_import_check (struct bgp
*bgp
)
4369 struct bgp_node
*rn
;
4370 struct bgp_static
*bgp_static
;
4372 /* Use this flag to force reprocessing of the route */
4373 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4374 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4375 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4376 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4377 if (rn
->info
!= NULL
)
4379 bgp_static
= rn
->info
;
4380 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4382 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4386 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4388 struct bgp_table
*table
;
4389 struct bgp_node
*rn
;
4390 struct bgp_info
*ri
;
4392 table
= bgp
->rib
[afi
][safi
];
4393 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4395 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4397 if (ri
->peer
== bgp
->peer_self
&&
4398 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4399 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4400 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4401 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4403 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4404 bgp_unlink_nexthop(ri
);
4405 bgp_info_delete (rn
, ri
);
4406 bgp_process (bgp
, rn
, afi
, safi
);
4413 * Purge all networks and redistributed routes from routing table.
4414 * Invoked upon the instance going down.
4417 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4422 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4423 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4424 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4429 * Currently this is used to set static routes for VPN and ENCAP.
4430 * I think it can probably be factored with bgp_static_set.
4433 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4434 const char *rd_str
, const char *tag_str
,
4435 const char *rmap_str
)
4437 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4440 struct prefix_rd prd
;
4441 struct bgp_node
*prn
;
4442 struct bgp_node
*rn
;
4443 struct bgp_table
*table
;
4444 struct bgp_static
*bgp_static
;
4448 ret
= str2prefix (ip_str
, &p
);
4451 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4456 ret
= str2prefix_rd (rd_str
, &prd
);
4459 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4463 ret
= str2tag (tag_str
, tag
);
4466 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4469 if (p
.family
== AF_INET
)
4471 else if (p
.family
== AF_INET6
)
4475 vty_out (vty
, "%% Non Supported prefix%s", VTY_NEWLINE
);
4478 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4479 (struct prefix
*)&prd
);
4480 if (prn
->info
== NULL
)
4481 prn
->info
= bgp_table_init (afi
, safi
);
4483 bgp_unlock_node (prn
);
4486 rn
= bgp_node_get (table
, &p
);
4490 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4491 bgp_unlock_node (rn
);
4495 /* New configuration. */
4496 bgp_static
= bgp_static_new ();
4497 bgp_static
->backdoor
= 0;
4498 bgp_static
->valid
= 0;
4499 bgp_static
->igpmetric
= 0;
4500 bgp_static
->igpnexthop
.s_addr
= 0;
4501 memcpy(bgp_static
->tag
, tag
, 3);
4502 bgp_static
->prd
= prd
;
4506 if (bgp_static
->rmap
.name
)
4507 free (bgp_static
->rmap
.name
);
4508 bgp_static
->rmap
.name
= strdup (rmap_str
);
4509 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4511 rn
->info
= bgp_static
;
4513 bgp_static
->valid
= 1;
4514 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4520 /* Configure static BGP network. */
4522 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4523 const char *rd_str
, const char *tag_str
)
4525 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4528 struct prefix_rd prd
;
4529 struct bgp_node
*prn
;
4530 struct bgp_node
*rn
;
4531 struct bgp_table
*table
;
4532 struct bgp_static
*bgp_static
;
4535 /* Convert IP prefix string to struct prefix. */
4536 ret
= str2prefix (ip_str
, &p
);
4539 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4544 ret
= str2prefix_rd (rd_str
, &prd
);
4547 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4551 ret
= str2tag (tag_str
, tag
);
4554 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4558 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4559 (struct prefix
*)&prd
);
4560 if (prn
->info
== NULL
)
4561 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4563 bgp_unlock_node (prn
);
4566 rn
= bgp_node_lookup (table
, &p
);
4570 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4572 bgp_static
= rn
->info
;
4573 bgp_static_free (bgp_static
);
4575 bgp_unlock_node (rn
);
4576 bgp_unlock_node (rn
);
4579 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4585 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4586 const char *rmap_name
)
4588 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4589 struct bgp_rmap
*rmap
;
4591 rmap
= &bgp
->table_map
[afi
][safi
];
4595 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4596 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4597 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4602 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4607 bgp_zebra_announce_table(bgp
, afi
, safi
);
4613 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4614 const char *rmap_name
)
4616 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4617 struct bgp_rmap
*rmap
;
4619 rmap
= &bgp
->table_map
[afi
][safi
];
4621 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4625 bgp_zebra_announce_table(bgp
, afi
, safi
);
4631 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4632 safi_t safi
, int *write
)
4634 if (bgp
->table_map
[afi
][safi
].name
)
4636 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4637 vty_out (vty
, " table-map %s%s",
4638 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4644 DEFUN (bgp_table_map
,
4647 "BGP table to RIB route download filter\n"
4648 "Name of the route map\n")
4651 return bgp_table_map_set (vty
,
4652 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4654 DEFUN (no_bgp_table_map
,
4655 no_bgp_table_map_cmd
,
4656 "no table-map WORD",
4658 "BGP table to RIB route download filter\n"
4659 "Name of the route map\n")
4662 return bgp_table_map_unset (vty
,
4663 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4668 "network A.B.C.D/M",
4669 "Specify a network to announce via BGP\n"
4672 int idx_ipv4_prefixlen
= 1;
4673 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4674 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4677 DEFUN (bgp_network_route_map
,
4678 bgp_network_route_map_cmd
,
4679 "network A.B.C.D/M route-map WORD",
4680 "Specify a network to announce via BGP\n"
4682 "Route-map to modify the attributes\n"
4683 "Name of the route map\n")
4685 int idx_ipv4_prefixlen
= 1;
4687 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4688 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4691 DEFUN (bgp_network_backdoor
,
4692 bgp_network_backdoor_cmd
,
4693 "network A.B.C.D/M backdoor",
4694 "Specify a network to announce via BGP\n"
4696 "Specify a BGP backdoor route\n")
4698 int idx_ipv4_prefixlen
= 1;
4699 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4703 DEFUN (bgp_network_mask
,
4704 bgp_network_mask_cmd
,
4705 "network A.B.C.D mask A.B.C.D",
4706 "Specify a network to announce via BGP\n"
4714 char prefix_str
[BUFSIZ
];
4716 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4719 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4723 return bgp_static_set (vty
, prefix_str
,
4724 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4727 DEFUN (bgp_network_mask_route_map
,
4728 bgp_network_mask_route_map_cmd
,
4729 "network A.B.C.D mask A.B.C.D route-map WORD",
4730 "Specify a network to announce via BGP\n"
4734 "Route-map to modify the attributes\n"
4735 "Name of the route map\n")
4741 char prefix_str
[BUFSIZ
];
4743 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4746 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4750 return bgp_static_set (vty
, prefix_str
,
4751 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4754 DEFUN (bgp_network_mask_backdoor
,
4755 bgp_network_mask_backdoor_cmd
,
4756 "network A.B.C.D mask A.B.C.D backdoor",
4757 "Specify a network to announce via BGP\n"
4761 "Specify a BGP backdoor route\n")
4766 char prefix_str
[BUFSIZ
];
4768 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4771 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4775 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4779 DEFUN (bgp_network_mask_natural
,
4780 bgp_network_mask_natural_cmd
,
4782 "Specify a network to announce via BGP\n"
4787 char prefix_str
[BUFSIZ
];
4789 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4792 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4796 return bgp_static_set (vty
, prefix_str
,
4797 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4800 DEFUN (bgp_network_mask_natural_route_map
,
4801 bgp_network_mask_natural_route_map_cmd
,
4802 "network A.B.C.D route-map WORD",
4803 "Specify a network to announce via BGP\n"
4805 "Route-map to modify the attributes\n"
4806 "Name of the route map\n")
4811 char prefix_str
[BUFSIZ
];
4813 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4816 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4820 return bgp_static_set (vty
, prefix_str
,
4821 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4824 DEFUN (bgp_network_mask_natural_backdoor
,
4825 bgp_network_mask_natural_backdoor_cmd
,
4826 "network A.B.C.D backdoor",
4827 "Specify a network to announce via BGP\n"
4829 "Specify a BGP backdoor route\n")
4833 char prefix_str
[BUFSIZ
];
4835 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4838 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4842 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4846 DEFUN (no_bgp_network
,
4848 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4850 "Specify a network to announce via BGP\n"
4852 "Specify a BGP backdoor route\n"
4853 "Route-map to modify the attributes\n"
4854 "Name of the route map\n")
4856 int idx_ipv4_prefixlen
= 2;
4857 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4858 bgp_node_safi (vty
));
4861 DEFUN (no_bgp_network_mask
,
4862 no_bgp_network_mask_cmd
,
4863 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4865 "Specify a network to announce via BGP\n"
4869 "Specify a BGP backdoor route\n"
4870 "Route-map to modify the attributes\n"
4871 "Name of the route map\n")
4876 char prefix_str
[BUFSIZ
];
4878 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4881 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4885 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4886 bgp_node_safi (vty
));
4889 DEFUN (no_bgp_network_mask_natural
,
4890 no_bgp_network_mask_natural_cmd
,
4891 "no network A.B.C.D [<backdoor|route-map WORD>]",
4893 "Specify a network to announce via BGP\n"
4895 "Specify a BGP backdoor route\n"
4896 "Route-map to modify the attributes\n"
4897 "Name of the route map\n")
4901 char prefix_str
[BUFSIZ
];
4903 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4906 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4910 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4911 bgp_node_safi (vty
));
4914 DEFUN (ipv6_bgp_network
,
4915 ipv6_bgp_network_cmd
,
4916 "network X:X::X:X/M",
4917 "Specify a network to announce via BGP\n"
4920 int idx_ipv6_prefixlen
= 1;
4921 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4925 DEFUN (ipv6_bgp_network_route_map
,
4926 ipv6_bgp_network_route_map_cmd
,
4927 "network X:X::X:X/M route-map WORD",
4928 "Specify a network to announce via BGP\n"
4930 "Route-map to modify the attributes\n"
4931 "Name of the route map\n")
4933 int idx_ipv6_prefixlen
= 1;
4935 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4936 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4939 DEFUN (no_ipv6_bgp_network
,
4940 no_ipv6_bgp_network_cmd
,
4941 "no network X:X::X:X/M [route-map WORD]",
4943 "Specify a network to announce via BGP\n"
4945 "Route-map to modify the attributes\n"
4946 "Name of the route map\n")
4948 int idx_ipv6_prefixlen
= 2;
4949 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4952 /* Aggreagete address:
4954 advertise-map Set condition to advertise attribute
4955 as-set Generate AS set path information
4956 attribute-map Set attributes of aggregate
4957 route-map Set parameters of aggregate
4958 summary-only Filter more specific routes from updates
4959 suppress-map Conditionally filter more specific routes from updates
4962 struct bgp_aggregate
4964 /* Summary-only flag. */
4965 u_char summary_only
;
4967 /* AS set generation. */
4970 /* Route-map for aggregated route. */
4971 struct route_map
*map
;
4973 /* Suppress-count. */
4974 unsigned long count
;
4976 /* SAFI configuration. */
4980 static struct bgp_aggregate
*
4981 bgp_aggregate_new (void)
4983 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4987 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4989 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4992 /* Update an aggregate as routes are added/removed from the BGP table */
4994 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4995 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4996 struct bgp_aggregate
*aggregate
)
4998 struct bgp_table
*table
;
4999 struct bgp_node
*top
;
5000 struct bgp_node
*rn
;
5002 struct aspath
*aspath
= NULL
;
5003 struct aspath
*asmerge
= NULL
;
5004 struct community
*community
= NULL
;
5005 struct community
*commerge
= NULL
;
5006 #if defined(AGGREGATE_NEXTHOP_CHECK)
5007 struct in_addr nexthop
;
5010 struct bgp_info
*ri
;
5011 struct bgp_info
*new;
5013 unsigned long match
= 0;
5014 u_char atomic_aggregate
= 0;
5016 /* Record adding route's nexthop and med. */
5019 #if defined(AGGREGATE_NEXTHOP_CHECK)
5020 nexthop
= rinew
->attr
->nexthop
;
5021 med
= rinew
->attr
->med
;
5025 /* ORIGIN attribute: If at least one route among routes that are
5026 aggregated has ORIGIN with the value INCOMPLETE, then the
5027 aggregated route must have the ORIGIN attribute with the value
5028 INCOMPLETE. Otherwise, if at least one route among routes that
5029 are aggregated has ORIGIN with the value EGP, then the aggregated
5030 route must have the origin attribute with the value EGP. In all
5031 other case the value of the ORIGIN attribute of the aggregated
5032 route is INTERNAL. */
5033 origin
= BGP_ORIGIN_IGP
;
5035 table
= bgp
->rib
[afi
][safi
];
5037 top
= bgp_node_get (table
, p
);
5038 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5039 if (rn
->p
.prefixlen
> p
->prefixlen
)
5043 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5045 if (BGP_INFO_HOLDDOWN (ri
))
5048 if (del
&& ri
== del
)
5051 if (! rinew
&& first
)
5053 #if defined(AGGREGATE_NEXTHOP_CHECK)
5054 nexthop
= ri
->attr
->nexthop
;
5055 med
= ri
->attr
->med
;
5060 #ifdef AGGREGATE_NEXTHOP_CHECK
5061 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5062 || ri
->attr
->med
!= med
)
5065 aspath_free (aspath
);
5067 community_free (community
);
5068 bgp_unlock_node (rn
);
5069 bgp_unlock_node (top
);
5072 #endif /* AGGREGATE_NEXTHOP_CHECK */
5074 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5075 atomic_aggregate
= 1;
5077 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5079 if (aggregate
->summary_only
)
5081 (bgp_info_extra_get (ri
))->suppress
++;
5082 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5088 if (origin
< ri
->attr
->origin
)
5089 origin
= ri
->attr
->origin
;
5091 if (aggregate
->as_set
)
5095 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5096 aspath_free (aspath
);
5100 aspath
= aspath_dup (ri
->attr
->aspath
);
5102 if (ri
->attr
->community
)
5106 commerge
= community_merge (community
,
5107 ri
->attr
->community
);
5108 community
= community_uniq_sort (commerge
);
5109 community_free (commerge
);
5112 community
= community_dup (ri
->attr
->community
);
5118 bgp_process (bgp
, rn
, afi
, safi
);
5120 bgp_unlock_node (top
);
5126 if (aggregate
->summary_only
)
5127 (bgp_info_extra_get (rinew
))->suppress
++;
5129 if (origin
< rinew
->attr
->origin
)
5130 origin
= rinew
->attr
->origin
;
5132 if (aggregate
->as_set
)
5136 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5137 aspath_free (aspath
);
5141 aspath
= aspath_dup (rinew
->attr
->aspath
);
5143 if (rinew
->attr
->community
)
5147 commerge
= community_merge (community
,
5148 rinew
->attr
->community
);
5149 community
= community_uniq_sort (commerge
);
5150 community_free (commerge
);
5153 community
= community_dup (rinew
->attr
->community
);
5158 if (aggregate
->count
> 0)
5160 rn
= bgp_node_get (table
, p
);
5161 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5162 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5164 atomic_aggregate
), rn
);
5165 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5167 bgp_info_add (rn
, new);
5168 bgp_unlock_node (rn
);
5169 bgp_process (bgp
, rn
, afi
, safi
);
5174 aspath_free (aspath
);
5176 community_free (community
);
5180 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5181 struct bgp_aggregate
*);
5184 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5185 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5187 struct bgp_node
*child
;
5188 struct bgp_node
*rn
;
5189 struct bgp_aggregate
*aggregate
;
5190 struct bgp_table
*table
;
5192 /* MPLS-VPN aggregation is not yet supported. */
5193 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
= SAFI_EVPN
))
5196 table
= bgp
->aggregate
[afi
][safi
];
5198 /* No aggregates configured. */
5199 if (bgp_table_top_nolock (table
) == NULL
)
5202 if (p
->prefixlen
== 0)
5205 if (BGP_INFO_HOLDDOWN (ri
))
5208 child
= bgp_node_get (table
, p
);
5210 /* Aggregate address configuration check. */
5211 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5212 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5214 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5215 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5217 bgp_unlock_node (child
);
5221 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5222 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5224 struct bgp_node
*child
;
5225 struct bgp_node
*rn
;
5226 struct bgp_aggregate
*aggregate
;
5227 struct bgp_table
*table
;
5229 /* MPLS-VPN aggregation is not yet supported. */
5230 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
= SAFI_EVPN
))
5233 table
= bgp
->aggregate
[afi
][safi
];
5235 /* No aggregates configured. */
5236 if (bgp_table_top_nolock (table
) == NULL
)
5239 if (p
->prefixlen
== 0)
5242 child
= bgp_node_get (table
, p
);
5244 /* Aggregate address configuration check. */
5245 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5246 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5248 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5249 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5251 bgp_unlock_node (child
);
5254 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5256 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5257 struct bgp_aggregate
*aggregate
)
5259 struct bgp_table
*table
;
5260 struct bgp_node
*top
;
5261 struct bgp_node
*rn
;
5262 struct bgp_info
*new;
5263 struct bgp_info
*ri
;
5264 unsigned long match
;
5265 u_char origin
= BGP_ORIGIN_IGP
;
5266 struct aspath
*aspath
= NULL
;
5267 struct aspath
*asmerge
= NULL
;
5268 struct community
*community
= NULL
;
5269 struct community
*commerge
= NULL
;
5270 u_char atomic_aggregate
= 0;
5272 table
= bgp
->rib
[afi
][safi
];
5275 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5277 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5280 /* If routes exists below this node, generate aggregate routes. */
5281 top
= bgp_node_get (table
, p
);
5282 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5283 if (rn
->p
.prefixlen
> p
->prefixlen
)
5287 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5289 if (BGP_INFO_HOLDDOWN (ri
))
5292 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5293 atomic_aggregate
= 1;
5295 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5297 /* summary-only aggregate route suppress aggregated
5298 route announcement. */
5299 if (aggregate
->summary_only
)
5301 (bgp_info_extra_get (ri
))->suppress
++;
5302 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5306 /* If at least one route among routes that are aggregated has
5307 * ORIGIN with the value INCOMPLETE, then the aggregated route
5308 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5309 * Otherwise, if at least one route among routes that are
5310 * aggregated has ORIGIN with the value EGP, then the aggregated
5311 * route MUST have the ORIGIN attribute with the value EGP.
5313 if (origin
< ri
->attr
->origin
)
5314 origin
= ri
->attr
->origin
;
5316 /* as-set aggregate route generate origin, as path,
5317 community aggregation. */
5318 if (aggregate
->as_set
)
5322 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5323 aspath_free (aspath
);
5327 aspath
= aspath_dup (ri
->attr
->aspath
);
5329 if (ri
->attr
->community
)
5333 commerge
= community_merge (community
,
5334 ri
->attr
->community
);
5335 community
= community_uniq_sort (commerge
);
5336 community_free (commerge
);
5339 community
= community_dup (ri
->attr
->community
);
5346 /* If this node is suppressed, process the change. */
5348 bgp_process (bgp
, rn
, afi
, safi
);
5350 bgp_unlock_node (top
);
5352 /* Add aggregate route to BGP table. */
5353 if (aggregate
->count
)
5355 rn
= bgp_node_get (table
, p
);
5356 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5357 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5359 atomic_aggregate
), rn
);
5360 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5362 bgp_info_add (rn
, new);
5363 bgp_unlock_node (rn
);
5365 /* Process change. */
5366 bgp_process (bgp
, rn
, afi
, safi
);
5371 aspath_free (aspath
);
5373 community_free (community
);
5378 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5379 safi_t safi
, struct bgp_aggregate
*aggregate
)
5381 struct bgp_table
*table
;
5382 struct bgp_node
*top
;
5383 struct bgp_node
*rn
;
5384 struct bgp_info
*ri
;
5385 unsigned long match
;
5387 table
= bgp
->rib
[afi
][safi
];
5389 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5391 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5394 /* If routes exists below this node, generate aggregate routes. */
5395 top
= bgp_node_get (table
, p
);
5396 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5397 if (rn
->p
.prefixlen
> p
->prefixlen
)
5401 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5403 if (BGP_INFO_HOLDDOWN (ri
))
5406 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5408 if (aggregate
->summary_only
&& ri
->extra
)
5410 ri
->extra
->suppress
--;
5412 if (ri
->extra
->suppress
== 0)
5414 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5422 /* If this node was suppressed, process the change. */
5424 bgp_process (bgp
, rn
, afi
, safi
);
5426 bgp_unlock_node (top
);
5428 /* Delete aggregate route from BGP table. */
5429 rn
= bgp_node_get (table
, p
);
5431 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5432 if (ri
->peer
== bgp
->peer_self
5433 && ri
->type
== ZEBRA_ROUTE_BGP
5434 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5437 /* Withdraw static BGP route from routing table. */
5440 bgp_info_delete (rn
, ri
);
5441 bgp_process (bgp
, rn
, afi
, safi
);
5444 /* Unlock bgp_node_lookup. */
5445 bgp_unlock_node (rn
);
5448 /* Aggregate route attribute. */
5449 #define AGGREGATE_SUMMARY_ONLY 1
5450 #define AGGREGATE_AS_SET 1
5453 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5454 afi_t afi
, safi_t safi
)
5456 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5459 struct bgp_node
*rn
;
5460 struct bgp_aggregate
*aggregate
;
5462 /* Convert string to prefix structure. */
5463 ret
= str2prefix (prefix_str
, &p
);
5466 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5471 /* Old configuration check. */
5472 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5475 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5480 aggregate
= rn
->info
;
5481 if (aggregate
->safi
& SAFI_UNICAST
)
5482 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5483 if (aggregate
->safi
& SAFI_MULTICAST
)
5484 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5486 /* Unlock aggregate address configuration. */
5488 bgp_aggregate_free (aggregate
);
5489 bgp_unlock_node (rn
);
5490 bgp_unlock_node (rn
);
5496 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5497 afi_t afi
, safi_t safi
,
5498 u_char summary_only
, u_char as_set
)
5500 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5503 struct bgp_node
*rn
;
5504 struct bgp_aggregate
*aggregate
;
5506 /* Convert string to prefix structure. */
5507 ret
= str2prefix (prefix_str
, &p
);
5510 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5515 /* Old configuration check. */
5516 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5520 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5521 /* try to remove the old entry */
5522 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5525 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5526 bgp_unlock_node (rn
);
5531 /* Make aggregate address structure. */
5532 aggregate
= bgp_aggregate_new ();
5533 aggregate
->summary_only
= summary_only
;
5534 aggregate
->as_set
= as_set
;
5535 aggregate
->safi
= safi
;
5536 rn
->info
= aggregate
;
5538 /* Aggregate address insert into BGP routing table. */
5539 if (safi
& SAFI_UNICAST
)
5540 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5541 if (safi
& SAFI_MULTICAST
)
5542 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5547 DEFUN (aggregate_address
,
5548 aggregate_address_cmd
,
5549 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5550 "Configure BGP aggregate entries\n"
5551 "Aggregate prefix\n"
5552 "Generate AS set path information\n"
5553 "Filter more specific routes from updates\n"
5554 "Filter more specific routes from updates\n"
5555 "Generate AS set path information\n")
5558 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5559 char *prefix
= argv
[idx
]->arg
;
5560 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5562 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5564 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5567 DEFUN (aggregate_address_mask
,
5568 aggregate_address_mask_cmd
,
5569 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5570 "Configure BGP aggregate entries\n"
5571 "Aggregate address\n"
5573 "Generate AS set path information\n"
5574 "Filter more specific routes from updates\n"
5575 "Filter more specific routes from updates\n"
5576 "Generate AS set path information\n")
5579 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5580 char *prefix
= argv
[idx
++]->arg
;
5581 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5582 char *mask
= argv
[idx
]->arg
;
5583 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5585 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5587 char prefix_str
[BUFSIZ
];
5588 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5592 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5596 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5599 DEFUN (no_aggregate_address
,
5600 no_aggregate_address_cmd
,
5601 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5603 "Configure BGP aggregate entries\n"
5604 "Aggregate prefix\n"
5605 "Generate AS set path information\n"
5606 "Filter more specific routes from updates\n"
5607 "Filter more specific routes from updates\n"
5608 "Generate AS set path information\n")
5611 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5612 char *prefix
= argv
[idx
]->arg
;
5613 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5616 DEFUN (no_aggregate_address_mask
,
5617 no_aggregate_address_mask_cmd
,
5618 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5620 "Configure BGP aggregate entries\n"
5621 "Aggregate address\n"
5623 "Generate AS set path information\n"
5624 "Filter more specific routes from updates\n"
5625 "Filter more specific routes from updates\n"
5626 "Generate AS set path information\n")
5629 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5630 char *prefix
= argv
[idx
++]->arg
;
5631 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5632 char *mask
= argv
[idx
]->arg
;
5634 char prefix_str
[BUFSIZ
];
5635 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5639 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5643 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5646 DEFUN (ipv6_aggregate_address
,
5647 ipv6_aggregate_address_cmd
,
5648 "aggregate-address X:X::X:X/M [summary-only]",
5649 "Configure BGP aggregate entries\n"
5650 "Aggregate prefix\n"
5651 "Filter more specific routes from updates\n")
5654 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5655 char *prefix
= argv
[idx
]->arg
;
5656 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5657 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5660 DEFUN (no_ipv6_aggregate_address
,
5661 no_ipv6_aggregate_address_cmd
,
5662 "no aggregate-address X:X::X:X/M [summary-only]",
5664 "Configure BGP aggregate entries\n"
5665 "Aggregate prefix\n"
5666 "Filter more specific routes from updates\n")
5669 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5670 char *prefix
= argv
[idx
]->arg
;
5671 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5674 /* Redistribute route treatment. */
5676 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5677 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5678 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5680 struct bgp_info
*new;
5681 struct bgp_info
*bi
;
5682 struct bgp_info info
;
5683 struct bgp_node
*bn
;
5685 struct attr
*new_attr
;
5688 struct bgp_redist
*red
;
5690 /* Make default attribute. */
5691 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5693 attr
.nexthop
= *nexthop
;
5694 attr
.nh_ifindex
= ifindex
;
5698 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5699 extra
->mp_nexthop_global
= *nexthop6
;
5700 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5704 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5705 attr
.extra
->tag
= tag
;
5707 afi
= family2afi (p
->family
);
5709 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5712 struct attr attr_new
;
5713 struct attr_extra extra_new
;
5715 /* Copy attribute for modification. */
5716 attr_new
.extra
= &extra_new
;
5717 bgp_attr_dup (&attr_new
, &attr
);
5719 if (red
->redist_metric_flag
)
5720 attr_new
.med
= red
->redist_metric
;
5722 /* Apply route-map. */
5725 info
.peer
= bgp
->peer_self
;
5726 info
.attr
= &attr_new
;
5728 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5730 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5732 bgp
->peer_self
->rmap_type
= 0;
5734 if (ret
== RMAP_DENYMATCH
)
5736 /* Free uninterned attribute. */
5737 bgp_attr_flush (&attr_new
);
5739 /* Unintern original. */
5740 aspath_unintern (&attr
.aspath
);
5741 bgp_attr_extra_free (&attr
);
5742 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5747 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5748 afi
, SAFI_UNICAST
, p
, NULL
);
5750 new_attr
= bgp_attr_intern (&attr_new
);
5752 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5753 if (bi
->peer
== bgp
->peer_self
5754 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5759 /* Ensure the (source route) type is updated. */
5761 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5762 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5764 bgp_attr_unintern (&new_attr
);
5765 aspath_unintern (&attr
.aspath
);
5766 bgp_attr_extra_free (&attr
);
5767 bgp_unlock_node (bn
);
5772 /* The attribute is changed. */
5773 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5775 /* Rewrite BGP route information. */
5776 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5777 bgp_info_restore(bn
, bi
);
5779 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5780 bgp_attr_unintern (&bi
->attr
);
5781 bi
->attr
= new_attr
;
5782 bi
->uptime
= bgp_clock ();
5784 /* Process change. */
5785 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5786 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5787 bgp_unlock_node (bn
);
5788 aspath_unintern (&attr
.aspath
);
5789 bgp_attr_extra_free (&attr
);
5794 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5796 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5798 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5799 bgp_info_add (bn
, new);
5800 bgp_unlock_node (bn
);
5801 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5804 /* Unintern original. */
5805 aspath_unintern (&attr
.aspath
);
5806 bgp_attr_extra_free (&attr
);
5810 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5813 struct bgp_node
*rn
;
5814 struct bgp_info
*ri
;
5815 struct bgp_redist
*red
;
5817 afi
= family2afi (p
->family
);
5819 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5822 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5824 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5825 if (ri
->peer
== bgp
->peer_self
5826 && ri
->type
== type
)
5831 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5832 bgp_info_delete (rn
, ri
);
5833 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5835 bgp_unlock_node (rn
);
5839 /* Withdraw specified route type's route. */
5841 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5843 struct bgp_node
*rn
;
5844 struct bgp_info
*ri
;
5845 struct bgp_table
*table
;
5847 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5849 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5851 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5852 if (ri
->peer
== bgp
->peer_self
5854 && ri
->instance
== instance
)
5859 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5860 bgp_info_delete (rn
, ri
);
5861 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5866 /* Static function to display route. */
5868 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5871 u_int32_t destination
;
5874 if (p
->family
== AF_INET
)
5876 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5877 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5879 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5880 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5881 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5882 || p
->u
.prefix4
.s_addr
== 0)
5884 /* When mask is natural, mask is not displayed. */
5887 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5889 else if (p
->family
== AF_ETHERNET
)
5891 prefix2str(p
, buf
, PREFIX_STRLEN
);
5892 len
= vty_out (vty
, "%s", buf
);
5895 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5900 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5902 vty_out (vty
, "%*s", len
, " ");
5905 enum bgp_display_type
5910 /* Print the short form route status for a bgp_info */
5912 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5913 json_object
*json_path
)
5918 /* Route status display. */
5919 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5920 json_object_boolean_true_add(json_path
, "removed");
5922 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5923 json_object_boolean_true_add(json_path
, "stale");
5925 if (binfo
->extra
&& binfo
->extra
->suppress
)
5926 json_object_boolean_true_add(json_path
, "suppressed");
5928 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5929 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5930 json_object_boolean_true_add(json_path
, "valid");
5933 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5934 json_object_boolean_true_add(json_path
, "history");
5936 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5937 json_object_boolean_true_add(json_path
, "damped");
5939 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5940 json_object_boolean_true_add(json_path
, "bestpath");
5942 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5943 json_object_boolean_true_add(json_path
, "multipath");
5945 /* Internal route. */
5946 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5947 json_object_string_add(json_path
, "pathFrom", "internal");
5949 json_object_string_add(json_path
, "pathFrom", "external");
5954 /* Route status display. */
5955 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5957 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5959 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5961 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5962 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5968 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5970 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5972 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5974 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5979 /* Internal route. */
5981 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5987 /* called from terminal list command */
5989 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5990 struct bgp_info
*binfo
, int display
, safi_t safi
,
5991 json_object
*json_paths
)
5994 json_object
*json_path
= NULL
;
5995 json_object
*json_nexthops
= NULL
;
5996 json_object
*json_nexthop_global
= NULL
;
5997 json_object
*json_nexthop_ll
= NULL
;
6000 json_path
= json_object_new_object();
6002 /* short status lead text */
6003 route_vty_short_status_out (vty
, binfo
, json_path
);
6007 /* print prefix and mask */
6009 route_vty_out_route (p
, vty
);
6011 vty_out (vty
, "%*s", 17, " ");
6014 /* Print attribute */
6019 * For ENCAP routes, nexthop address family is not
6020 * neccessarily the same as the prefix address family.
6021 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6023 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6028 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6033 vty_out (vty
, "%s", inet_ntop(af
,
6034 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6037 vty_out (vty
, "%s", inet_ntop(af
,
6038 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6049 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6053 json_nexthop_global
= json_object_new_object();
6055 if ((safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6056 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6058 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6060 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6061 json_object_boolean_true_add(json_nexthop_global
, "used");
6065 if ((safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6066 vty_out (vty
, "%-16s",
6067 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6069 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6074 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6081 json_nexthop_global
= json_object_new_object();
6082 json_object_string_add(json_nexthop_global
, "ip",
6083 inet_ntop (AF_INET6
,
6084 &attr
->extra
->mp_nexthop_global
,
6086 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6087 json_object_string_add(json_nexthop_global
, "scope", "global");
6089 /* We display both LL & GL if both have been received */
6090 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6092 json_nexthop_ll
= json_object_new_object();
6093 json_object_string_add(json_nexthop_ll
, "ip",
6094 inet_ntop (AF_INET6
,
6095 &attr
->extra
->mp_nexthop_local
,
6097 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6098 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6100 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6101 &attr
->extra
->mp_nexthop_local
) != 0) &&
6102 !attr
->extra
->mp_nexthop_prefer_global
)
6103 json_object_boolean_true_add(json_nexthop_ll
, "used");
6105 json_object_boolean_true_add(json_nexthop_global
, "used");
6108 json_object_boolean_true_add(json_nexthop_global
, "used");
6112 /* Display LL if LL/Global both in table unless prefer-global is set */
6113 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6114 !attr
->extra
->mp_nexthop_prefer_global
) ||
6115 (binfo
->peer
->conf_if
))
6117 if (binfo
->peer
->conf_if
)
6119 len
= vty_out (vty
, "%s",
6120 binfo
->peer
->conf_if
);
6121 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6124 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6126 vty_out (vty
, "%*s", len
, " ");
6130 len
= vty_out (vty
, "%s",
6131 inet_ntop (AF_INET6
,
6132 &attr
->extra
->mp_nexthop_local
,
6137 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6139 vty_out (vty
, "%*s", len
, " ");
6144 len
= vty_out (vty
, "%s",
6145 inet_ntop (AF_INET6
,
6146 &attr
->extra
->mp_nexthop_global
,
6151 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6153 vty_out (vty
, "%*s", len
, " ");
6159 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6161 json_object_int_add(json_path
, "med", attr
->med
);
6163 vty_out (vty
, "%10u", attr
->med
);
6169 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6171 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6173 vty_out (vty
, "%7u", attr
->local_pref
);
6181 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6183 json_object_int_add(json_path
, "weight", 0);
6186 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6190 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6197 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6199 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6204 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6206 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6211 json_object_string_add(json_path
, "alert", "No attributes");
6213 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6218 if (json_nexthop_global
|| json_nexthop_ll
)
6220 json_nexthops
= json_object_new_array();
6222 if (json_nexthop_global
)
6223 json_object_array_add(json_nexthops
, json_nexthop_global
);
6225 if (json_nexthop_ll
)
6226 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6228 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6231 json_object_array_add(json_paths
, json_path
);
6235 vty_out (vty
, "%s", VTY_NEWLINE
);
6237 /* prints an additional line, indented, with VNC info, if present */
6238 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6239 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6244 /* called from terminal list command */
6246 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6247 u_char use_json
, json_object
*json_ar
)
6249 json_object
*json_status
= NULL
;
6250 json_object
*json_net
= NULL
;
6252 /* Route status display. */
6255 json_status
= json_object_new_object();
6256 json_net
= json_object_new_object();
6265 /* print prefix and mask */
6267 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6269 route_vty_out_route (p
, vty
);
6271 /* Print attribute */
6276 if (p
->family
== AF_INET
&&
6277 (safi
== SAFI_MPLS_VPN
||
6278 safi
== SAFI_ENCAP
||
6279 safi
== SAFI_EVPN
||
6280 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6282 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6283 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6285 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6287 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6291 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6295 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6296 json_object_int_add(json_net
, "metric", attr
->med
);
6298 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6299 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6302 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6304 json_object_int_add(json_net
, "weight", 0);
6308 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6311 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6315 if (p
->family
== AF_INET
&&
6316 (safi
== SAFI_MPLS_VPN
||
6317 safi
== SAFI_ENCAP
||
6318 safi
== SAFI_EVPN
||
6319 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6321 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6322 vty_out (vty
, "%-16s",
6323 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6325 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6327 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6332 assert (attr
->extra
);
6334 len
= vty_out (vty
, "%s",
6335 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6339 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6341 vty_out (vty
, "%*s", len
, " ");
6343 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6344 vty_out (vty
, "%10u", attr
->med
);
6348 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6349 vty_out (vty
, "%7u", attr
->local_pref
);
6353 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6357 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6360 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6365 json_object_boolean_true_add(json_status
, "*");
6366 json_object_boolean_true_add(json_status
, ">");
6367 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6368 char buf_cut
[BUFSIZ
];
6369 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6372 vty_out (vty
, "%s", VTY_NEWLINE
);
6376 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6377 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6379 json_object
*json_out
= NULL
;
6381 u_int32_t label
= 0;
6387 json_out
= json_object_new_object();
6389 /* short status lead text */
6390 route_vty_short_status_out (vty
, binfo
, json_out
);
6392 /* print prefix and mask */
6396 route_vty_out_route (p
, vty
);
6398 vty_out (vty
, "%*s", 17, " ");
6401 /* Print attribute */
6405 if (p
->family
== AF_INET
6406 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6408 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6411 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6413 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6418 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6420 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6423 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6425 assert (attr
->extra
);
6429 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6432 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6433 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6436 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6439 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6443 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6445 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6447 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6448 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6451 vty_out (vty
, "%s(%s)",
6452 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6454 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6461 label
= decode_label (binfo
->extra
->tag
);
6466 json_object_int_add(json_out
, "notag", label
);
6467 json_object_array_add(json
, json_out
);
6471 vty_out (vty
, "notag/%d", label
);
6473 vty_out (vty
, "%s", VTY_NEWLINE
);
6478 route_vty_out_overlay (struct vty
*vty
, struct prefix
*p
,
6479 struct bgp_info
*binfo
, int display
, json_object
*json_paths
)
6483 json_object
*json_path
= NULL
;
6486 json_path
= json_object_new_object();
6491 /* short status lead text */
6492 route_vty_short_status_out (vty
, binfo
, json_path
);
6494 /* print prefix and mask */
6496 route_vty_out_route (p
, vty
);
6498 vty_out (vty
, "%*s", 17, " ");
6500 /* Print attribute */
6507 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6511 vty_out (vty
, "%-16s", inet_ntop(af
,
6512 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6515 vty_out (vty
, "%s(%s)",
6517 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
),
6519 &attr
->extra
->mp_nexthop_local
, buf1
, BUFSIZ
));
6531 struct eth_segment_id
*id
= &(attr
->extra
->evpn_overlay
.eth_s_id
);
6532 char *str
= esi2str(id
);
6533 vty_out (vty
, "%s", str
);
6535 if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V4
)
6537 vty_out (vty
, "/%s", inet_ntoa (attr
->extra
->evpn_overlay
.gw_ip
.ipv4
));
6539 else if (p
->u
.prefix_evpn
.flags
& IP_PREFIX_V6
)
6541 vty_out (vty
, "/%s",
6542 inet_ntop (AF_INET6
, &(attr
->extra
->evpn_overlay
.gw_ip
.ipv6
),
6545 if(attr
->extra
->ecommunity
)
6548 struct ecommunity_val
*routermac
= ecommunity_lookup (attr
->extra
->ecommunity
,
6549 ECOMMUNITY_ENCODE_EVPN
,
6550 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6552 mac
= ecom_mac2str((char *)routermac
->val
);
6555 vty_out (vty
, "/%s",(char *)mac
);
6560 vty_out (vty
, "%s", VTY_NEWLINE
);
6563 /* dampening route */
6565 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6566 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6570 char timebuf
[BGP_UPTIME_LEN
];
6572 /* short status lead text */
6573 route_vty_short_status_out (vty
, binfo
, json
);
6575 /* print prefix and mask */
6579 route_vty_out_route (p
, vty
);
6581 vty_out (vty
, "%*s", 17, " ");
6584 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6589 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6594 json_object_int_add(json
, "peerHost", len
);
6596 vty_out (vty
, "%*s", len
, " ");
6600 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6602 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6604 /* Print attribute */
6612 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6614 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6619 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6621 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6624 vty_out (vty
, "%s", VTY_NEWLINE
);
6629 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6630 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6633 struct bgp_damp_info
*bdi
;
6634 char timebuf
[BGP_UPTIME_LEN
];
6640 bdi
= binfo
->extra
->damp_info
;
6642 /* short status lead text */
6643 route_vty_short_status_out (vty
, binfo
, json
);
6645 /* print prefix and mask */
6649 route_vty_out_route (p
, vty
);
6651 vty_out (vty
, "%*s", 17, " ");
6654 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6659 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6664 json_object_int_add(json
, "peerHost", len
);
6666 vty_out (vty
, "%*s", len
, " ");
6669 len
= vty_out (vty
, "%d", bdi
->flap
);
6679 json_object_int_add(json
, "bdiFlap", len
);
6681 vty_out (vty
, "%*s", len
, " ");
6685 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6687 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6688 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6690 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6691 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6694 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6696 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6701 vty_out (vty
, "%*s ", 8, " ");
6704 /* Print attribute */
6712 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6714 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6719 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6721 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6724 vty_out (vty
, "%s", VTY_NEWLINE
);
6728 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6729 const char *header
, json_object
*json_adv_to
)
6731 char buf1
[INET6_ADDRSTRLEN
];
6732 json_object
*json_peer
= NULL
;
6736 /* 'advertised-to' is a dictionary of peers we have advertised this
6737 * prefix too. The key is the peer's IP or swpX, the value is the
6738 * hostname if we know it and "" if not.
6740 json_peer
= json_object_new_object();
6743 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6746 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6748 json_object_object_add(json_adv_to
,
6749 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6756 vty_out (vty
, "%s", header
);
6760 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6763 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6765 vty_out (vty
, " %s(%s)", peer
->hostname
,
6766 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6771 vty_out (vty
, " %s", peer
->conf_if
);
6773 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6779 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6780 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6781 json_object
*json_paths
)
6783 char buf
[INET6_ADDRSTRLEN
];
6786 int sockunion_vty_out (struct vty
*, union sockunion
*);
6788 json_object
*json_bestpath
= NULL
;
6789 json_object
*json_cluster_list
= NULL
;
6790 json_object
*json_cluster_list_list
= NULL
;
6791 json_object
*json_ext_community
= NULL
;
6792 json_object
*json_last_update
= NULL
;
6793 json_object
*json_nexthop_global
= NULL
;
6794 json_object
*json_nexthop_ll
= NULL
;
6795 json_object
*json_nexthops
= NULL
;
6796 json_object
*json_path
= NULL
;
6797 json_object
*json_peer
= NULL
;
6798 json_object
*json_string
= NULL
;
6799 json_object
*json_adv_to
= NULL
;
6801 struct listnode
*node
, *nnode
;
6803 int addpath_capable
;
6805 unsigned int first_as
;
6809 json_path
= json_object_new_object();
6810 json_peer
= json_object_new_object();
6811 json_nexthop_global
= json_object_new_object();
6818 /* Line1 display AS-path, Aggregator */
6823 json_object_lock(attr
->aspath
->json
);
6824 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6828 if (attr
->aspath
->segments
)
6829 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6831 vty_out (vty
, " Local");
6835 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6838 json_object_boolean_true_add(json_path
, "removed");
6840 vty_out (vty
, ", (removed)");
6843 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6846 json_object_boolean_true_add(json_path
, "stale");
6848 vty_out (vty
, ", (stale)");
6851 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6855 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6856 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6860 vty_out (vty
, ", (aggregated by %u %s)",
6861 attr
->extra
->aggregator_as
,
6862 inet_ntoa (attr
->extra
->aggregator_addr
));
6866 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6869 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6871 vty_out (vty
, ", (Received from a RR-client)");
6874 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6877 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6879 vty_out (vty
, ", (Received from a RS-client)");
6882 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6885 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6887 vty_out (vty
, ", (history entry)");
6889 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6892 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6894 vty_out (vty
, ", (suppressed due to dampening)");
6898 vty_out (vty
, "%s", VTY_NEWLINE
);
6900 /* Line2 display Next-hop, Neighbor, Router-id */
6901 /* Display the nexthop */
6902 if (p
->family
== AF_INET
&&
6903 (safi
== SAFI_MPLS_VPN
||
6904 safi
== SAFI_ENCAP
||
6905 safi
== SAFI_EVPN
||
6906 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6908 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6911 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6913 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6918 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6920 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6924 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6928 assert (attr
->extra
);
6931 json_object_string_add(json_nexthop_global
, "ip",
6932 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6933 buf
, INET6_ADDRSTRLEN
));
6934 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6935 json_object_string_add(json_nexthop_global
, "scope", "global");
6939 vty_out (vty
, " %s",
6940 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6941 buf
, INET6_ADDRSTRLEN
));
6945 /* Display the IGP cost or 'inaccessible' */
6946 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6949 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6951 vty_out (vty
, " (inaccessible)");
6955 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6958 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6960 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6963 /* IGP cost is 0, display this only for json */
6967 json_object_int_add(json_nexthop_global
, "metric", 0);
6971 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6974 /* Display peer "from" output */
6975 /* This path was originated locally */
6976 if (binfo
->peer
== bgp
->peer_self
)
6979 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6982 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6984 vty_out (vty
, " from 0.0.0.0 ");
6989 json_object_string_add(json_peer
, "peerId", "::");
6991 vty_out (vty
, " from :: ");
6995 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6997 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7000 /* We RXed this path from one of our peers */
7006 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7007 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7009 if (binfo
->peer
->hostname
)
7010 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
7012 if (binfo
->peer
->domainname
)
7013 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
7015 if (binfo
->peer
->conf_if
)
7016 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
7020 if (binfo
->peer
->conf_if
)
7022 if (binfo
->peer
->hostname
&&
7023 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7024 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7025 binfo
->peer
->conf_if
);
7027 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
7031 if (binfo
->peer
->hostname
&&
7032 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
7033 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
7036 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7039 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7040 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
7042 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
7047 vty_out (vty
, "%s", VTY_NEWLINE
);
7049 /* display the link-local nexthop */
7050 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
7054 json_nexthop_ll
= json_object_new_object();
7055 json_object_string_add(json_nexthop_ll
, "ip",
7056 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7057 buf
, INET6_ADDRSTRLEN
));
7058 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
7059 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
7061 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
7063 if (!attr
->extra
->mp_nexthop_prefer_global
)
7064 json_object_boolean_true_add(json_nexthop_ll
, "used");
7066 json_object_boolean_true_add(json_nexthop_global
, "used");
7070 vty_out (vty
, " (%s) %s%s",
7071 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
7072 buf
, INET6_ADDRSTRLEN
),
7073 attr
->extra
->mp_nexthop_prefer_global
?
7074 "(prefer-global)" : "(used)",
7078 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7082 json_object_boolean_true_add(json_nexthop_global
, "used");
7085 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7087 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
7089 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
7091 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7094 json_object_int_add(json_path
, "med", attr
->med
);
7096 vty_out (vty
, ", metric %u", attr
->med
);
7099 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7102 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
7104 vty_out (vty
, ", localpref %u", attr
->local_pref
);
7109 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
7111 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7114 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7117 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7119 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7122 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7125 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7127 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7130 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7133 json_object_boolean_false_add(json_path
, "valid");
7135 vty_out (vty
, ", invalid");
7137 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7140 json_object_boolean_true_add(json_path
, "valid");
7142 vty_out (vty
, ", valid");
7145 if (binfo
->peer
!= bgp
->peer_self
)
7147 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7149 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7152 json_object_string_add(json_peer
, "type", "confed-internal");
7154 vty_out (vty
, ", confed-internal");
7159 json_object_string_add(json_peer
, "type", "internal");
7161 vty_out (vty
, ", internal");
7166 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7169 json_object_string_add(json_peer
, "type", "confed-external");
7171 vty_out (vty
, ", confed-external");
7176 json_object_string_add(json_peer
, "type", "external");
7178 vty_out (vty
, ", external");
7182 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7186 json_object_boolean_true_add(json_path
, "aggregated");
7187 json_object_boolean_true_add(json_path
, "local");
7191 vty_out (vty
, ", aggregated, local");
7194 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7197 json_object_boolean_true_add(json_path
, "sourced");
7199 vty_out (vty
, ", sourced");
7205 json_object_boolean_true_add(json_path
, "sourced");
7206 json_object_boolean_true_add(json_path
, "local");
7210 vty_out (vty
, ", sourced, local");
7214 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7217 json_object_boolean_true_add(json_path
, "atomicAggregate");
7219 vty_out (vty
, ", atomic-aggregate");
7222 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7223 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7224 bgp_info_mpath_count (binfo
)))
7227 json_object_boolean_true_add(json_path
, "multipath");
7229 vty_out (vty
, ", multipath");
7232 // Mark the bestpath(s)
7233 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7235 first_as
= aspath_get_first_as(attr
->aspath
);
7240 json_bestpath
= json_object_new_object();
7241 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7246 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7248 vty_out (vty
, ", bestpath-from-AS Local");
7252 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7257 json_bestpath
= json_object_new_object();
7258 json_object_boolean_true_add(json_bestpath
, "overall");
7261 vty_out (vty
, ", best");
7265 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7268 vty_out (vty
, "%s", VTY_NEWLINE
);
7270 /* Line 4 display Community */
7271 if (attr
->community
)
7275 json_object_lock(attr
->community
->json
);
7276 json_object_object_add(json_path
, "community", attr
->community
->json
);
7280 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7285 /* Line 5 display Extended-community */
7286 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7290 json_ext_community
= json_object_new_object();
7291 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7292 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7296 vty_out (vty
, " Extended Community: %s%s",
7297 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7301 /* Line 6 display Large community */
7302 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7303 vty_out (vty
, " Large Community: %s%s",
7304 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7306 /* Line 7 display Originator, Cluster-id */
7307 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7308 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7310 assert (attr
->extra
);
7311 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7314 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7316 vty_out (vty
, " Originator: %s",
7317 inet_ntoa (attr
->extra
->originator_id
));
7320 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7326 json_cluster_list
= json_object_new_object();
7327 json_cluster_list_list
= json_object_new_array();
7329 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7331 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7332 json_object_array_add(json_cluster_list_list
, json_string
);
7335 /* struct cluster_list does not have "str" variable like
7336 * aspath and community do. Add this someday if someone
7338 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7340 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7341 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7345 vty_out (vty
, ", Cluster list: ");
7347 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7349 vty_out (vty
, "%s ",
7350 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7356 vty_out (vty
, "%s", VTY_NEWLINE
);
7359 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7360 bgp_damp_info_vty (vty
, binfo
, json_path
);
7362 /* Line 8 display Addpath IDs */
7363 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7367 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7368 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7372 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7373 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7378 /* If we used addpath to TX a non-bestpath we need to display
7379 * "Advertised to" on a path-by-path basis */
7380 if (bgp
->addpath_tx_used
[afi
][safi
])
7384 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7386 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7387 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7389 if ((addpath_capable
&& has_adj
) ||
7390 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7392 if (json_path
&& !json_adv_to
)
7393 json_adv_to
= json_object_new_object();
7395 route_vty_out_advertised_to(vty
, peer
, &first
,
7405 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7412 vty_out (vty
, "%s", VTY_NEWLINE
);
7417 /* Line 9 display Uptime */
7418 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7421 json_last_update
= json_object_new_object();
7422 json_object_int_add(json_last_update
, "epoch", tbuf
);
7423 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7424 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7427 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7430 /* We've constructed the json object for this path, add it to the json
7435 if (json_nexthop_global
|| json_nexthop_ll
)
7437 json_nexthops
= json_object_new_array();
7439 if (json_nexthop_global
)
7440 json_object_array_add(json_nexthops
, json_nexthop_global
);
7442 if (json_nexthop_ll
)
7443 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7445 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7448 json_object_object_add(json_path
, "peer", json_peer
);
7449 json_object_array_add(json_paths
, json_path
);
7452 vty_out (vty
, "%s", VTY_NEWLINE
);
7455 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7456 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7457 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7460 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7461 const char *prefix_list_str
, afi_t afi
,
7462 safi_t safi
, enum bgp_show_type type
);
7464 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7465 const char *filter
, afi_t afi
,
7466 safi_t safi
, enum bgp_show_type type
);
7468 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7469 const char *rmap_str
, afi_t afi
,
7470 safi_t safi
, enum bgp_show_type type
);
7472 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7473 const char *com
, int exact
,
7474 afi_t afi
, safi_t safi
);
7476 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7477 const char *prefix
, afi_t afi
,
7478 safi_t safi
, enum bgp_show_type type
);
7480 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7481 safi_t safi
, enum bgp_show_type type
);
7483 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7484 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7487 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7488 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7490 struct bgp_info
*ri
;
7491 struct bgp_node
*rn
;
7494 unsigned long output_count
;
7495 unsigned long total_count
;
7499 json_object
*json_paths
= NULL
;
7504 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7505 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7506 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7507 table
->version
, inet_ntoa (bgp
->router_id
));
7508 json_paths
= json_object_new_object();
7511 /* This is first entry point, so reset total line. */
7515 /* Start processing of routes. */
7516 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7517 if (rn
->info
!= NULL
)
7520 if (!first
&& use_json
)
7525 json_paths
= json_object_new_array();
7529 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7532 if (type
== bgp_show_type_flap_statistics
7533 || type
== bgp_show_type_flap_neighbor
7534 || type
== bgp_show_type_dampend_paths
7535 || type
== bgp_show_type_damp_neighbor
)
7537 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7540 if (type
== bgp_show_type_regexp
)
7542 regex_t
*regex
= output_arg
;
7544 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7547 if (type
== bgp_show_type_prefix_list
)
7549 struct prefix_list
*plist
= output_arg
;
7551 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7554 if (type
== bgp_show_type_filter_list
)
7556 struct as_list
*as_list
= output_arg
;
7558 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7561 if (type
== bgp_show_type_route_map
)
7563 struct route_map
*rmap
= output_arg
;
7564 struct bgp_info binfo
;
7565 struct attr dummy_attr
;
7566 struct attr_extra dummy_extra
;
7569 dummy_attr
.extra
= &dummy_extra
;
7570 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7572 binfo
.peer
= ri
->peer
;
7573 binfo
.attr
= &dummy_attr
;
7575 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7576 if (ret
== RMAP_DENYMATCH
)
7579 if (type
== bgp_show_type_neighbor
7580 || type
== bgp_show_type_flap_neighbor
7581 || type
== bgp_show_type_damp_neighbor
)
7583 union sockunion
*su
= output_arg
;
7585 if (ri
->peer
== NULL
||
7586 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7589 if (type
== bgp_show_type_cidr_only
)
7591 u_int32_t destination
;
7593 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7594 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7596 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7598 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7601 if (type
== bgp_show_type_prefix_longer
)
7603 struct prefix
*p
= output_arg
;
7605 if (! prefix_match (p
, &rn
->p
))
7608 if (type
== bgp_show_type_community_all
)
7610 if (! ri
->attr
->community
)
7613 if (type
== bgp_show_type_community
)
7615 struct community
*com
= output_arg
;
7617 if (! ri
->attr
->community
||
7618 ! community_match (ri
->attr
->community
, com
))
7621 if (type
== bgp_show_type_community_exact
)
7623 struct community
*com
= output_arg
;
7625 if (! ri
->attr
->community
||
7626 ! community_cmp (ri
->attr
->community
, com
))
7629 if (type
== bgp_show_type_community_list
)
7631 struct community_list
*list
= output_arg
;
7633 if (! community_list_match (ri
->attr
->community
, list
))
7636 if (type
== bgp_show_type_community_list_exact
)
7638 struct community_list
*list
= output_arg
;
7640 if (! community_list_exact_match (ri
->attr
->community
, list
))
7643 if (type
== bgp_show_type_lcommunity
)
7645 struct lcommunity
*lcom
= output_arg
;
7647 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7648 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7651 if (type
== bgp_show_type_lcommunity_list
)
7653 struct community_list
*list
= output_arg
;
7655 if (! ri
->attr
->extra
||
7656 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7659 if (type
== bgp_show_type_lcommunity_all
)
7661 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7664 if (type
== bgp_show_type_dampend_paths
7665 || type
== bgp_show_type_damp_neighbor
)
7667 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7668 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7672 if (!use_json
&& header
)
7674 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7675 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7676 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7677 if (type
== bgp_show_type_dampend_paths
7678 || type
== bgp_show_type_damp_neighbor
)
7679 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7680 else if (type
== bgp_show_type_flap_statistics
7681 || type
== bgp_show_type_flap_neighbor
)
7682 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7684 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7688 if (type
== bgp_show_type_dampend_paths
7689 || type
== bgp_show_type_damp_neighbor
)
7690 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7691 else if (type
== bgp_show_type_flap_statistics
7692 || type
== bgp_show_type_flap_neighbor
)
7693 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7695 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7705 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7706 vty_out (vty
, "\"%s\": ", buf2
);
7707 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7708 json_object_free (json_paths
);
7717 json_object_free (json_paths
);
7718 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7722 /* No route is displayed */
7723 if (output_count
== 0)
7725 if (type
== bgp_show_type_normal
)
7726 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7729 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7730 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7737 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7738 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7740 struct bgp_table
*table
;
7744 bgp
= bgp_get_default ();
7750 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7753 /* use MPLS and ENCAP specific shows until they are merged */
7754 if (safi
== SAFI_MPLS_VPN
)
7756 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
7759 if (safi
== SAFI_ENCAP
)
7761 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
7766 table
= bgp
->rib
[afi
][safi
];
7768 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7773 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7776 struct listnode
*node
, *nnode
;
7778 struct bgp_table
*table
;
7782 vty_out (vty
, "{%s", VTY_NEWLINE
);
7784 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7789 vty_out (vty
, ",%s", VTY_NEWLINE
);
7793 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7794 ? "Default" : bgp
->name
);
7798 vty_out (vty
, "%sInstance %s:%s",
7800 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7801 ? "Default" : bgp
->name
,
7804 table
= bgp
->rib
[afi
][safi
];
7805 bgp_show_table (vty
, bgp
, table
,
7806 bgp_show_type_normal
, NULL
, use_json
);
7811 vty_out (vty
, "}%s", VTY_NEWLINE
);
7814 /* Header of detailed BGP route information */
7816 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7817 struct bgp_node
*rn
,
7818 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7821 struct bgp_info
*ri
;
7824 struct listnode
*node
, *nnode
;
7825 char buf1
[INET6_ADDRSTRLEN
];
7826 char buf2
[INET6_ADDRSTRLEN
];
7831 int no_advertise
= 0;
7834 json_object
*json_adv_to
= NULL
;
7840 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7841 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7845 if (p
->family
== AF_ETHERNET
)
7846 prefix2str (p
, buf2
, INET6_ADDRSTRLEN
);
7848 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
);
7849 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7850 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
7851 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7852 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
7854 p
->prefixlen
, VTY_NEWLINE
);
7857 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7860 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7863 if (ri
->extra
&& ri
->extra
->suppress
)
7865 if (ri
->attr
->community
!= NULL
)
7867 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7869 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7871 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7879 vty_out (vty
, "Paths: (%d available", count
);
7882 vty_out (vty
, ", best #%d", best
);
7883 if (safi
== SAFI_UNICAST
)
7884 vty_out (vty
, ", table %s",
7885 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7886 ? "Default-IP-Routing-Table" : bgp
->name
);
7889 vty_out (vty
, ", no best path");
7892 vty_out (vty
, ", not advertised to any peer");
7894 vty_out (vty
, ", not advertised to EBGP peer");
7896 vty_out (vty
, ", not advertised outside local AS");
7899 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7900 vty_out (vty
, ")%s", VTY_NEWLINE
);
7903 /* If we are not using addpath then we can display Advertised to and that will
7904 * show what peers we advertised the bestpath to. If we are using addpath
7905 * though then we must display Advertised to on a path-by-path basis. */
7906 if (!bgp
->addpath_tx_used
[afi
][safi
])
7908 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7910 if (bgp_adj_out_lookup (peer
, rn
, 0))
7912 if (json
&& !json_adv_to
)
7913 json_adv_to
= json_object_new_object();
7915 route_vty_out_advertised_to(vty
, peer
, &first
,
7916 " Advertised to non peer-group peers:\n ",
7925 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7931 vty_out (vty
, " Not advertised to any peer");
7932 vty_out (vty
, "%s", VTY_NEWLINE
);
7937 /* Display specified route of BGP table. */
7939 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7940 struct bgp_table
*rib
, const char *ip_str
,
7941 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7942 int prefix_check
, enum bgp_path_type pathtype
,
7948 struct prefix match
;
7949 struct bgp_node
*rn
;
7950 struct bgp_node
*rm
;
7951 struct bgp_info
*ri
;
7952 struct bgp_table
*table
;
7953 json_object
*json
= NULL
;
7954 json_object
*json_paths
= NULL
;
7956 /* Check IP address argument. */
7957 ret
= str2prefix (ip_str
, &match
);
7960 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7964 match
.family
= afi2family (afi
);
7968 json
= json_object_new_object();
7969 json_paths
= json_object_new_array();
7972 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7974 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7976 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7979 if ((table
= rn
->info
) != NULL
)
7983 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7985 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7987 bgp_unlock_node (rm
);
7991 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7995 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7996 AFI_IP
, safi
, json
);
8001 if (pathtype
== BGP_PATH_ALL
||
8002 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8003 (pathtype
== BGP_PATH_MULTIPATH
&&
8004 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8005 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
8008 bgp_unlock_node (rm
);
8017 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
8019 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
8021 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8025 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
8030 if (pathtype
== BGP_PATH_ALL
||
8031 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
8032 (pathtype
== BGP_PATH_MULTIPATH
&&
8033 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
8034 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
8038 bgp_unlock_node (rn
);
8045 json_object_object_add(json
, "paths", json_paths
);
8047 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
8048 json_object_free(json
);
8054 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
8062 /* Display specified route of Main RIB */
8064 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8065 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8066 int prefix_check
, enum bgp_path_type pathtype
,
8070 bgp
= bgp_get_default ();
8072 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8073 afi
, safi
, prd
, prefix_check
, pathtype
,
8078 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8079 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
8081 struct lcommunity
*lcom
;
8087 b
= buffer_new (1024);
8088 for (i
= 0; i
< argc
; i
++)
8091 buffer_putc (b
, ' ');
8094 if (strmatch (argv
[i
]->text
, "<AA:BB:CC>"))
8097 buffer_putstr (b
, argv
[i
]->arg
);
8101 buffer_putc (b
, '\0');
8103 str
= buffer_getstr (b
);
8106 lcom
= lcommunity_str2com (str
);
8107 XFREE (MTYPE_TMP
, str
);
8110 vty_out (vty
, "%% Large-community malformed: %s", VTY_NEWLINE
);
8114 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8118 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8119 afi_t afi
, safi_t safi
, u_char uj
)
8121 struct community_list
*list
;
8123 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8126 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8131 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8134 DEFUN (show_ip_bgp_large_community_list
,
8135 show_ip_bgp_large_community_list_cmd
,
8136 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
8140 BGP_INSTANCE_HELP_STR
8143 "Address Family modifier\n"
8144 "Address Family modifier\n"
8145 "Address Family modifier\n"
8146 "Address Family modifier\n"
8147 "Display routes matching the large-community-list\n"
8148 "large-community-list number\n"
8149 "large-community-list name\n"
8153 afi_t afi
= AFI_IP6
;
8154 safi_t safi
= SAFI_UNICAST
;
8157 if (argv_find (argv
, argc
, "ip", &idx
))
8159 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8160 vrf
= argv
[++idx
]->arg
;
8161 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8163 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8164 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8165 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8168 int uj
= use_json (argc
, argv
);
8170 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8173 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8177 argv_find (argv
, argc
, "large-community-list", &idx
);
8178 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8180 DEFUN (show_ip_bgp_large_community
,
8181 show_ip_bgp_large_community_cmd
,
8182 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
8186 BGP_INSTANCE_HELP_STR
8189 "Address Family modifier\n"
8190 "Address Family modifier\n"
8191 "Address Family modifier\n"
8192 "Address Family modifier\n"
8193 "Display routes matching the large-communities\n"
8194 "List of large-community numbers\n"
8198 afi_t afi
= AFI_IP6
;
8199 safi_t safi
= SAFI_UNICAST
;
8202 if (argv_find (argv
, argc
, "ip", &idx
))
8204 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8205 vrf
= argv
[++idx
]->arg
;
8206 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8208 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8209 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8210 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8213 int uj
= use_json (argc
, argv
);
8215 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8218 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8222 argv_find (argv
, argc
, "large-community", &idx
);
8223 if (strmatch(argv
[idx
+1]->text
, "AA:BB:CC"))
8224 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8226 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8229 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8231 /* BGP route print out function. */
8234 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8237 |dampening <flap-statistics|dampened-paths|parameters>\
8242 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8243 |community-list <(1-500)|WORD> [exact-match]\
8244 |A.B.C.D/M longer-prefixes\
8245 |X:X::X:X/M longer-prefixes>\
8250 BGP_INSTANCE_HELP_STR
8253 "Display only routes with non-natural netmasks\n"
8254 "Display detailed information about dampening\n"
8255 "Display flap statistics of routes\n"
8256 "Display paths suppressed due to dampening\n"
8257 "Display detail of configured dampening parameters\n"
8258 "Display routes matching the route-map\n"
8259 "A route-map to match on\n"
8260 "Display routes conforming to the prefix-list\n"
8261 "Prefix-list name\n"
8262 "Display routes conforming to the filter-list\n"
8263 "Regular expression access list name\n"
8264 "BGP RIB advertisement statistics\n"
8265 "Display routes matching the communities\n"
8267 "Do not send outside local AS (well-known community)\n"
8268 "Do not advertise to any peer (well-known community)\n"
8269 "Do not export to next AS (well-known community)\n"
8270 "Exact match of the communities\n"
8271 "Display routes matching the community-list\n"
8272 "community-list number\n"
8273 "community-list name\n"
8274 "Exact match of the communities\n"
8276 "Display route and more specific routes\n"
8278 "Display route and more specific routes\n"
8281 vrf_id_t vrf
= VRF_DEFAULT
;
8282 afi_t afi
= AFI_IP6
;
8283 safi_t safi
= SAFI_UNICAST
;
8284 int exact_match
= 0;
8285 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8286 struct bgp
*bgp
= NULL
;
8289 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8293 int uj
= use_json (argc
, argv
);
8296 bgp
= bgp_lookup_by_vrf_id (vrf
);
8299 if (vrf
== VRF_DEFAULT
)
8300 vty_out (vty
, "Can't find BGP instance (default)%s", VTY_NEWLINE
);
8302 vty_out (vty
, "Can't find BGP instance %d%s", vrf
, VTY_NEWLINE
);
8306 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8307 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8309 if (argv_find(argv
, argc
, "dampening", &idx
))
8311 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8312 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8313 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8314 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8315 else if (argv_find (argv
, argc
, "parameters", &idx
))
8316 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8319 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8320 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8322 if (argv_find(argv
, argc
, "filter-list", &idx
))
8323 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8325 if (argv_find(argv
, argc
, "statistics", &idx
))
8326 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8328 if (argv_find(argv
, argc
, "route-map", &idx
))
8329 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8331 if (argv_find(argv
, argc
, "community", &idx
))
8333 /* show a specific community */
8334 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8335 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8336 argv_find (argv
, argc
, "no-export", &idx
))
8338 if (argv_find (argv
, argc
, "exact_match", &idx
))
8340 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8342 /* show all communities */
8344 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8347 if (argv_find(argv
, argc
, "community-list", &idx
))
8349 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8350 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8352 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8355 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8356 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8358 if (safi
== SAFI_MPLS_VPN
)
8359 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8360 else if (safi
== SAFI_ENCAP
)
8361 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8363 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8366 DEFUN (show_ip_bgp_route
,
8367 show_ip_bgp_route_cmd
,
8368 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8369 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8373 BGP_INSTANCE_HELP_STR
8376 "Network in the BGP routing table to display\n"
8378 "Network in the BGP routing table to display\n"
8380 "Display only the bestpath\n"
8381 "Display only multipaths\n"
8384 int prefix_check
= 0;
8386 afi_t afi
= AFI_IP6
;
8387 safi_t safi
= SAFI_UNICAST
;
8388 vrf_id_t vrf
= VRF_DEFAULT
;;
8389 char *prefix
= NULL
;
8390 struct bgp
*bgp
= NULL
;
8391 enum bgp_path_type path_type
;
8392 u_char uj
= use_json(argc
, argv
);
8396 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8402 bgp
= bgp_lookup_by_vrf_id (vrf
);
8405 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
8411 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8415 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8416 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8418 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8421 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8423 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8426 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8428 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8432 prefix
= argv
[idx
]->arg
;
8434 /* [<bestpath|multipath>] */
8435 if (argv_find (argv
, argc
, "bestpath", &idx
))
8436 path_type
= BGP_PATH_BESTPATH
;
8437 else if (argv_find (argv
, argc
, "multipath", &idx
))
8438 path_type
= BGP_PATH_MULTIPATH
;
8440 path_type
= BGP_PATH_ALL
;
8442 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8445 DEFUN (show_ip_bgp_regexp
,
8446 show_ip_bgp_regexp_cmd
,
8447 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8451 BGP_INSTANCE_HELP_STR
8454 "Display routes matching the AS path regular expression\n"
8455 "A regular-expression to match the BGP AS paths\n")
8457 vrf_id_t vrf
= VRF_DEFAULT
;
8458 afi_t afi
= AFI_IP6
;
8459 safi_t safi
= SAFI_UNICAST
;
8462 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8466 // get index of regex
8467 argv_find (argv
, argc
, "regexp", &idx
);
8470 char *regstr
= argv_concat (argv
, argc
, idx
);
8471 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8472 XFREE (MTYPE_TMP
, regstr
);
8476 DEFUN (show_ip_bgp_instance_all
,
8477 show_ip_bgp_instance_all_cmd
,
8478 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8482 BGP_INSTANCE_ALL_HELP_STR
8487 vrf_id_t vrf
= VRF_DEFAULT
;
8489 safi_t safi
= SAFI_UNICAST
;
8492 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8496 int uj
= use_json (argc
, argv
);
8499 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8504 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8505 safi_t safi
, enum bgp_show_type type
)
8512 regex
= bgp_regcomp (regstr
);
8515 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8519 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8520 bgp_regex_free (regex
);
8525 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8526 const char *prefix_list_str
, afi_t afi
,
8527 safi_t safi
, enum bgp_show_type type
)
8529 struct prefix_list
*plist
;
8531 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8534 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8535 prefix_list_str
, VTY_NEWLINE
);
8539 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8543 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8544 const char *filter
, afi_t afi
,
8545 safi_t safi
, enum bgp_show_type type
)
8547 struct as_list
*as_list
;
8549 as_list
= as_list_lookup (filter
);
8550 if (as_list
== NULL
)
8552 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8556 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8560 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8561 const char *rmap_str
, afi_t afi
,
8562 safi_t safi
, enum bgp_show_type type
)
8564 struct route_map
*rmap
;
8566 rmap
= route_map_lookup_by_name (rmap_str
);
8569 vty_out (vty
, "%% %s is not a valid route-map name%s",
8570 rmap_str
, VTY_NEWLINE
);
8574 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8578 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8579 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8581 struct community
*com
;
8587 b
= buffer_new (1024);
8588 for (i
= 0; i
< argc
; i
++)
8591 buffer_putc (b
, ' ');
8594 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8599 buffer_putstr (b
, argv
[i
]->arg
);
8601 buffer_putc (b
, '\0');
8603 str
= buffer_getstr (b
);
8606 com
= community_str2com (str
);
8607 XFREE (MTYPE_TMP
, str
);
8610 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8614 return bgp_show (vty
, bgp
, afi
, safi
,
8615 (exact
? bgp_show_type_community_exact
:
8616 bgp_show_type_community
), com
, 0);
8620 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8621 const char *com
, int exact
,
8622 afi_t afi
, safi_t safi
)
8624 struct community_list
*list
;
8626 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8629 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8634 return bgp_show (vty
, bgp
, afi
, safi
,
8635 (exact
? bgp_show_type_community_list_exact
:
8636 bgp_show_type_community_list
), list
, 0);
8640 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8641 const char *prefix
, afi_t afi
,
8642 safi_t safi
, enum bgp_show_type type
)
8649 ret
= str2prefix (prefix
, p
);
8652 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8656 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8661 static struct peer
*
8662 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8663 const char *ip_str
, u_char use_json
)
8669 /* Get peer sockunion. */
8670 ret
= str2sockunion (ip_str
, &su
);
8673 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8676 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8682 json_object
*json_no
= NULL
;
8683 json_no
= json_object_new_object();
8684 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8685 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8686 json_object_free(json_no
);
8689 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8696 /* Peer structure lookup. */
8697 peer
= peer_lookup (bgp
, &su
);
8702 json_object
*json_no
= NULL
;
8703 json_no
= json_object_new_object();
8704 json_object_string_add(json_no
, "warning","No such neighbor");
8705 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8706 json_object_free(json_no
);
8709 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8718 BGP_STATS_MAXBITLEN
= 0,
8722 BGP_STATS_UNAGGREGATEABLE
,
8723 BGP_STATS_MAX_AGGREGATEABLE
,
8724 BGP_STATS_AGGREGATES
,
8726 BGP_STATS_ASPATH_COUNT
,
8727 BGP_STATS_ASPATH_MAXHOPS
,
8728 BGP_STATS_ASPATH_TOTHOPS
,
8729 BGP_STATS_ASPATH_MAXSIZE
,
8730 BGP_STATS_ASPATH_TOTSIZE
,
8731 BGP_STATS_ASN_HIGHEST
,
8735 static const char *table_stats_strs
[] =
8737 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8738 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8739 [BGP_STATS_RIB
] = "Total Advertisements",
8740 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8741 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8742 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8743 [BGP_STATS_SPACE
] = "Address space advertised",
8744 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8745 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8746 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8747 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8748 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8749 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8750 [BGP_STATS_MAX
] = NULL
,
8753 struct bgp_table_stats
8755 struct bgp_table
*table
;
8756 unsigned long long counts
[BGP_STATS_MAX
];
8760 #define TALLY_SIGFIG 100000
8761 static unsigned long
8762 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8764 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8765 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8766 unsigned long ret
= newtot
/ count
;
8768 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8776 bgp_table_stats_walker (struct thread
*t
)
8778 struct bgp_node
*rn
;
8779 struct bgp_node
*top
;
8780 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8781 unsigned int space
= 0;
8783 if (!(top
= bgp_table_top (ts
->table
)))
8786 switch (top
->p
.family
)
8789 space
= IPV4_MAX_BITLEN
;
8792 space
= IPV6_MAX_BITLEN
;
8796 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8798 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8800 struct bgp_info
*ri
;
8801 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8802 unsigned int rinum
= 0;
8810 ts
->counts
[BGP_STATS_PREFIXES
]++;
8811 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8814 ts
->counts
[BGP_STATS_AVGPLEN
]
8815 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8816 ts
->counts
[BGP_STATS_AVGPLEN
],
8820 /* check if the prefix is included by any other announcements */
8821 while (prn
&& !prn
->info
)
8822 prn
= bgp_node_parent_nolock (prn
);
8824 if (prn
== NULL
|| prn
== top
)
8826 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8827 /* announced address space */
8829 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8832 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8834 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8837 ts
->counts
[BGP_STATS_RIB
]++;
8840 (CHECK_FLAG (ri
->attr
->flag
,
8841 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8842 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8845 if (ri
->attr
&& ri
->attr
->aspath
)
8847 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8848 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8849 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8851 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8853 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8854 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8856 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8857 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8859 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8860 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8862 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8863 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8864 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8866 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8867 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8868 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8871 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8872 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8880 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8882 struct bgp_table_stats ts
;
8885 if (!bgp
->rib
[afi
][safi
])
8887 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8888 afi
, safi
, VTY_NEWLINE
);
8892 memset (&ts
, 0, sizeof (ts
));
8893 ts
.table
= bgp
->rib
[afi
][safi
];
8894 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8896 vty_out (vty
, "BGP %s RIB statistics%s%s",
8897 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8899 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8901 if (!table_stats_strs
[i
])
8907 case BGP_STATS_ASPATH_AVGHOPS
:
8908 case BGP_STATS_ASPATH_AVGSIZE
:
8909 case BGP_STATS_AVGPLEN
:
8910 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8911 vty_out (vty
, "%12.2f",
8912 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8915 case BGP_STATS_ASPATH_TOTHOPS
:
8916 case BGP_STATS_ASPATH_TOTSIZE
:
8917 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8918 vty_out (vty
, "%12.2f",
8920 (float)ts
.counts
[i
] /
8921 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8924 case BGP_STATS_TOTPLEN
:
8925 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8926 vty_out (vty
, "%12.2f",
8928 (float)ts
.counts
[i
] /
8929 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8932 case BGP_STATS_SPACE
:
8933 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8934 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8935 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8937 vty_out (vty
, "%30s: ", "%% announced ");
8938 vty_out (vty
, "%12.2f%s",
8939 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8940 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8942 vty_out (vty
, "%30s: ", "/8 equivalent ");
8943 vty_out (vty
, "%12.2f%s",
8944 (float)ts
.counts
[BGP_STATS_SPACE
] /
8945 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8947 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8949 vty_out (vty
, "%30s: ", "/24 equivalent ");
8950 vty_out (vty
, "%12.2f",
8951 (float)ts
.counts
[BGP_STATS_SPACE
] /
8952 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8955 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8956 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8959 vty_out (vty
, "%s", VTY_NEWLINE
);
8974 PCOUNT_PFCNT
, /* the figure we display to users */
8978 static const char *pcount_strs
[] =
8980 [PCOUNT_ADJ_IN
] = "Adj-in",
8981 [PCOUNT_DAMPED
] = "Damped",
8982 [PCOUNT_REMOVED
] = "Removed",
8983 [PCOUNT_HISTORY
] = "History",
8984 [PCOUNT_STALE
] = "Stale",
8985 [PCOUNT_VALID
] = "Valid",
8986 [PCOUNT_ALL
] = "All RIB",
8987 [PCOUNT_COUNTED
] = "PfxCt counted",
8988 [PCOUNT_PFCNT
] = "Useable",
8989 [PCOUNT_MAX
] = NULL
,
8994 unsigned int count
[PCOUNT_MAX
];
8995 const struct peer
*peer
;
8996 const struct bgp_table
*table
;
9000 bgp_peer_count_walker (struct thread
*t
)
9002 struct bgp_node
*rn
;
9003 struct peer_pcounts
*pc
= THREAD_ARG (t
);
9004 const struct peer
*peer
= pc
->peer
;
9006 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
9008 struct bgp_adj_in
*ain
;
9009 struct bgp_info
*ri
;
9011 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9012 if (ain
->peer
== peer
)
9013 pc
->count
[PCOUNT_ADJ_IN
]++;
9015 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
9017 char buf
[SU_ADDRSTRLEN
];
9019 if (ri
->peer
!= peer
)
9022 pc
->count
[PCOUNT_ALL
]++;
9024 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
9025 pc
->count
[PCOUNT_DAMPED
]++;
9026 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
9027 pc
->count
[PCOUNT_HISTORY
]++;
9028 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
9029 pc
->count
[PCOUNT_REMOVED
]++;
9030 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
9031 pc
->count
[PCOUNT_STALE
]++;
9032 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
9033 pc
->count
[PCOUNT_VALID
]++;
9034 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9035 pc
->count
[PCOUNT_PFCNT
]++;
9037 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
9039 pc
->count
[PCOUNT_COUNTED
]++;
9040 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9041 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9043 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9044 buf
, SU_ADDRSTRLEN
),
9050 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
9051 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9053 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
9054 buf
, SU_ADDRSTRLEN
),
9064 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
9066 struct peer_pcounts pcounts
= { .peer
= peer
};
9068 json_object
*json
= NULL
;
9069 json_object
*json_loop
= NULL
;
9073 json
= json_object_new_object();
9074 json_loop
= json_object_new_object();
9077 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9078 || !peer
->bgp
->rib
[afi
][safi
])
9082 json_object_string_add(json
, "warning", "No such neighbor or address family");
9083 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9084 json_object_free(json
);
9087 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9092 memset (&pcounts
, 0, sizeof(pcounts
));
9093 pcounts
.peer
= peer
;
9094 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9096 /* in-place call via thread subsystem so as to record execution time
9097 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9098 * * on just vty_read()).
9100 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9104 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9105 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
9106 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
9108 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9109 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
9111 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9113 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9115 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
9116 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9118 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9119 json_object_free(json
);
9124 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9126 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9127 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9132 vty_out (vty
, "Prefix counts for %s, %s%s",
9133 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9136 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9137 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9138 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9140 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9141 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9143 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9145 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9146 peer
->host
, VTY_NEWLINE
);
9147 vty_out (vty
, "Please report this bug, with the above command output%s",
9155 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9156 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9157 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
9158 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9162 BGP_INSTANCE_HELP_STR
9165 "Address Family modifier\n"
9166 "Address Family modifier\n"
9167 "Address Family modifier\n"
9168 "Address Family modifier\n"
9169 "Detailed information on TCP and BGP neighbor connections\n"
9170 "Neighbor to display information about\n"
9171 "Neighbor to display information about\n"
9172 "Neighbor on BGP configured interface\n"
9173 "Display detailed prefix count information\n"
9176 vrf_id_t vrf
= VRF_DEFAULT
;
9177 afi_t afi
= AFI_IP6
;
9178 safi_t safi
= SAFI_UNICAST
;
9181 struct bgp
*bgp
= NULL
;
9183 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9187 int uj
= use_json (argc
, argv
);
9192 bgp
= bgp_lookup_by_vrf_id (vrf
);
9197 json_object
*json_no
= NULL
;
9198 json_no
= json_object_new_object();
9199 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9200 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9201 json_object_free(json_no
);
9204 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9211 argv_find (argv
, argc
, "neighbors", &idx
);
9212 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9216 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9219 #ifdef KEEP_OLD_VPN_COMMANDS
9220 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9221 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9222 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9227 "Display information about all VPNv4 NLRIs\n"
9228 "Detailed information on TCP and BGP neighbor connections\n"
9229 "Neighbor to display information about\n"
9230 "Neighbor to display information about\n"
9231 "Neighbor on BGP configured interface\n"
9232 "Display detailed prefix count information\n"
9237 u_char uj
= use_json(argc
, argv
);
9239 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9243 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9246 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9247 show_ip_bgp_vpn_all_route_prefix_cmd
,
9248 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9253 "Display information about all VPNv4 NLRIs\n"
9254 "Network in the BGP routing table to display\n"
9255 "Network in the BGP routing table to display\n"
9259 char *network
= NULL
;
9260 struct bgp
*bgp
= bgp_get_default();
9263 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9266 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9267 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9268 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9270 #endif /* KEEP_OLD_VPN_COMMANDS */
9273 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9274 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9276 struct bgp_table
*table
;
9277 struct bgp_adj_in
*ain
;
9278 struct bgp_adj_out
*adj
;
9279 unsigned long output_count
;
9280 unsigned long filtered_count
;
9281 struct bgp_node
*rn
;
9286 struct attr_extra extra
;
9288 struct update_subgroup
*subgrp
;
9289 json_object
*json_scode
= NULL
;
9290 json_object
*json_ocode
= NULL
;
9291 json_object
*json_ar
= NULL
;
9292 struct peer_af
*paf
;
9296 json_scode
= json_object_new_object();
9297 json_ocode
= json_object_new_object();
9298 json_ar
= json_object_new_object();
9300 json_object_string_add(json_scode
, "suppressed", "s");
9301 json_object_string_add(json_scode
, "damped", "d");
9302 json_object_string_add(json_scode
, "history", "h");
9303 json_object_string_add(json_scode
, "valid", "*");
9304 json_object_string_add(json_scode
, "best", ">");
9305 json_object_string_add(json_scode
, "multipath", "=");
9306 json_object_string_add(json_scode
, "internal", "i");
9307 json_object_string_add(json_scode
, "ribFailure", "r");
9308 json_object_string_add(json_scode
, "stale", "S");
9309 json_object_string_add(json_scode
, "removed", "R");
9311 json_object_string_add(json_ocode
, "igp", "i");
9312 json_object_string_add(json_ocode
, "egp", "e");
9313 json_object_string_add(json_ocode
, "incomplete", "?");
9322 json_object_string_add(json
, "alert", "no BGP");
9323 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9324 json_object_free(json
);
9327 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9331 table
= bgp
->rib
[afi
][safi
];
9333 output_count
= filtered_count
= 0;
9334 subgrp
= peer_subgroup(peer
, afi
, safi
);
9336 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9340 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9341 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9342 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9343 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9344 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9348 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9349 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9350 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9352 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9353 VTY_NEWLINE
, VTY_NEWLINE
);
9358 attr
.extra
= &extra
;
9359 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9363 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9365 if (ain
->peer
== peer
)
9371 json_object_int_add(json
, "bgpTableVersion", 0);
9372 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9373 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9374 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9378 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9379 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9380 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9387 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9392 bgp_attr_dup(&attr
, ain
->attr
);
9393 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9395 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9406 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9407 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9408 if (paf
->peer
== peer
)
9414 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9415 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9416 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9417 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9421 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9422 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9423 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9424 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9432 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9438 bgp_attr_dup(&attr
, adj
->attr
);
9439 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9440 if (ret
!= RMAP_DENY
)
9442 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9452 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9454 if (output_count
!= 0)
9457 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9459 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9460 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9464 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9465 json_object_free(json
);
9471 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9472 int in
, const char *rmap_name
, u_char use_json
)
9474 json_object
*json
= NULL
;
9477 json
= json_object_new_object();
9479 if (!peer
|| !peer
->afc
[afi
][safi
])
9483 json_object_string_add(json
, "warning", "No such neighbor or address family");
9484 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9485 json_object_free(json
);
9488 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9493 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9497 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9498 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9499 json_object_free(json
);
9502 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9507 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9512 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9513 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9514 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9515 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9519 BGP_INSTANCE_HELP_STR
9522 "Detailed information on TCP and BGP neighbor connections\n"
9523 "Neighbor to display information about\n"
9524 "Neighbor to display information about\n"
9525 "Neighbor on BGP configured interface\n"
9526 "Display the received routes from neighbor\n"
9527 "Display the routes advertised to a BGP neighbor\n"
9528 "Route-map to modify the attributes\n"
9529 "Name of the route map\n"
9532 vrf_id_t vrf
= VRF_DEFAULT
;
9533 afi_t afi
= AFI_IP6
;
9534 safi_t safi
= SAFI_UNICAST
;
9535 char *rmap_name
= NULL
;
9536 char *peerstr
= NULL
;
9538 struct bgp
*bgp
= NULL
;
9543 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9547 int uj
= use_json (argc
, argv
);
9550 bgp
= bgp_lookup_by_vrf_id (vrf
);
9555 json_object
*json_no
= NULL
;
9556 json_no
= json_object_new_object();
9557 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9558 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9559 json_object_free(json_no
);
9562 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9566 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9567 argv_find (argv
, argc
, "neighbors", &idx
);
9568 peerstr
= argv
[++idx
]->arg
;
9570 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9574 if (argv_find (argv
, argc
, "received-routes", &idx
))
9576 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9578 if (argv_find (argv
, argc
, "route-map", &idx
))
9579 rmap_name
= argv
[++idx
]->arg
;
9581 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9584 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9585 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9586 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9592 "Address Family modifier\n"
9593 "Detailed information on TCP and BGP neighbor connections\n"
9594 "Neighbor to display information about\n"
9595 "Neighbor to display information about\n"
9596 "Neighbor on BGP configured interface\n"
9597 "Display information received from a BGP neighbor\n"
9598 "Display the prefixlist filter\n"
9601 afi_t afi
= AFI_IP6
;
9602 safi_t safi
= SAFI_UNICAST
;
9603 char *peerstr
= NULL
;
9613 if (argv_find (argv
, argc
, "ip", &idx
))
9615 /* [<ipv4|ipv6> [unicast]] */
9616 if (argv_find (argv
, argc
, "ipv4", &idx
))
9618 if (argv_find (argv
, argc
, "ipv6", &idx
))
9620 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9621 argv_find (argv
, argc
, "neighbors", &idx
);
9622 peerstr
= argv
[++idx
]->arg
;
9624 u_char uj
= use_json(argc
, argv
);
9626 ret
= str2sockunion (peerstr
, &su
);
9629 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9633 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9635 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9641 peer
= peer_lookup (NULL
, &su
);
9645 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9647 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9652 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9653 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9657 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9658 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9663 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9665 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9672 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9673 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9675 if (! peer
|| ! peer
->afc
[afi
][safi
])
9679 json_object
*json_no
= NULL
;
9680 json_no
= json_object_new_object();
9681 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9682 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9683 json_object_free(json_no
);
9686 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9690 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9693 DEFUN (show_ip_bgp_neighbor_routes
,
9694 show_ip_bgp_neighbor_routes_cmd
,
9695 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9696 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9700 BGP_INSTANCE_HELP_STR
9703 "Detailed information on TCP and BGP neighbor connections\n"
9704 "Neighbor to display information about\n"
9705 "Neighbor to display information about\n"
9706 "Neighbor on BGP configured interface\n"
9707 "Display flap statistics of the routes learned from neighbor\n"
9708 "Display the dampened routes received from neighbor\n"
9709 "Display routes learned from neighbor\n"
9712 vrf_id_t vrf
= VRF_DEFAULT
;
9713 char *peerstr
= NULL
;
9714 struct bgp
*bgp
= NULL
;
9715 afi_t afi
= AFI_IP6
;
9716 safi_t safi
= SAFI_UNICAST
;
9718 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9722 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9726 int uj
= use_json (argc
, argv
);
9731 bgp
= bgp_lookup_by_vrf_id (vrf
);
9736 json_object
*json_no
= NULL
;
9737 json_no
= json_object_new_object();
9738 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9739 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9740 json_object_free(json_no
);
9743 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9750 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9751 argv_find (argv
, argc
, "neighbors", &idx
);
9752 peerstr
= argv
[++idx
]->arg
;
9754 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9757 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9761 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9762 sh_type
= bgp_show_type_flap_neighbor
;
9763 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9764 sh_type
= bgp_show_type_damp_neighbor
;
9765 else if (argv_find (argv
, argc
, "routes", &idx
))
9766 sh_type
= bgp_show_type_neighbor
;
9768 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9771 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9775 /* Distance value for the IP source prefix. */
9778 /* Name of the access-list to be matched. */
9782 DEFUN (show_bgp_afi_vpn_rd_route
,
9783 show_bgp_afi_vpn_rd_route_cmd
,
9784 "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]",
9788 "Address Family modifier\n"
9789 "Display information for a route distinguisher\n"
9790 "Route Distinguisher\n"
9791 "Network in the BGP routing table to display\n"
9792 "Network in the BGP routing table to display\n"
9796 struct prefix_rd prd
;
9797 afi_t afi
= AFI_MAX
;
9800 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
9801 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
9804 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
9807 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
9810 static struct bgp_distance
*
9811 bgp_distance_new (void)
9813 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9817 bgp_distance_free (struct bgp_distance
*bdistance
)
9819 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9823 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9824 const char *ip_str
, const char *access_list_str
)
9831 struct bgp_node
*rn
;
9832 struct bgp_distance
*bdistance
;
9834 afi
= bgp_node_afi (vty
);
9835 safi
= bgp_node_safi (vty
);
9837 ret
= str2prefix (ip_str
, &p
);
9840 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9844 distance
= atoi (distance_str
);
9846 /* Get BGP distance node. */
9847 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9850 bdistance
= rn
->info
;
9851 bgp_unlock_node (rn
);
9855 bdistance
= bgp_distance_new ();
9856 rn
->info
= bdistance
;
9859 /* Set distance value. */
9860 bdistance
->distance
= distance
;
9862 /* Reset access-list configuration. */
9863 if (bdistance
->access_list
)
9865 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9866 bdistance
->access_list
= NULL
;
9868 if (access_list_str
)
9869 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9875 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9876 const char *ip_str
, const char *access_list_str
)
9883 struct bgp_node
*rn
;
9884 struct bgp_distance
*bdistance
;
9886 afi
= bgp_node_afi (vty
);
9887 safi
= bgp_node_safi (vty
);
9889 ret
= str2prefix (ip_str
, &p
);
9892 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9896 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9899 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9903 bdistance
= rn
->info
;
9904 distance
= atoi(distance_str
);
9906 if (bdistance
->distance
!= distance
)
9908 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9912 if (bdistance
->access_list
)
9913 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9914 bgp_distance_free (bdistance
);
9917 bgp_unlock_node (rn
);
9918 bgp_unlock_node (rn
);
9923 /* Apply BGP information to distance method. */
9925 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9926 safi_t safi
, struct bgp
*bgp
)
9928 struct bgp_node
*rn
;
9931 struct bgp_distance
*bdistance
;
9932 struct access_list
*alist
;
9933 struct bgp_static
*bgp_static
;
9940 /* Check source address. */
9941 sockunion2hostprefix (&peer
->su
, &q
);
9942 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9945 bdistance
= rn
->info
;
9946 bgp_unlock_node (rn
);
9948 if (bdistance
->access_list
)
9950 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9951 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9952 return bdistance
->distance
;
9955 return bdistance
->distance
;
9958 /* Backdoor check. */
9959 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9962 bgp_static
= rn
->info
;
9963 bgp_unlock_node (rn
);
9965 if (bgp_static
->backdoor
)
9967 if (bgp
->distance_local
[afi
][safi
])
9968 return bgp
->distance_local
[afi
][safi
];
9970 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9974 if (peer
->sort
== BGP_PEER_EBGP
)
9976 if (bgp
->distance_ebgp
[afi
][safi
])
9977 return bgp
->distance_ebgp
[afi
][safi
];
9978 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
9982 if (bgp
->distance_ibgp
[afi
][safi
])
9983 return bgp
->distance_ibgp
[afi
][safi
];
9984 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9988 DEFUN (bgp_distance
,
9990 "distance bgp (1-255) (1-255) (1-255)",
9991 "Define an administrative distance\n"
9993 "Distance for routes external to the AS\n"
9994 "Distance for routes internal to the AS\n"
9995 "Distance for local routes\n")
9997 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9999 int idx_number_2
= 3;
10000 int idx_number_3
= 4;
10004 afi
= bgp_node_afi (vty
);
10005 safi
= bgp_node_safi (vty
);
10007 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
10008 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
10009 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
10010 return CMD_SUCCESS
;
10013 DEFUN (no_bgp_distance
,
10014 no_bgp_distance_cmd
,
10015 "no distance bgp [(1-255) (1-255) (1-255)]",
10017 "Define an administrative distance\n"
10019 "Distance for routes external to the AS\n"
10020 "Distance for routes internal to the AS\n"
10021 "Distance for local routes\n")
10023 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10027 afi
= bgp_node_afi (vty
);
10028 safi
= bgp_node_safi (vty
);
10030 bgp
->distance_ebgp
[afi
][safi
] = 0;
10031 bgp
->distance_ibgp
[afi
][safi
] = 0;
10032 bgp
->distance_local
[afi
][safi
] = 0;
10033 return CMD_SUCCESS
;
10037 DEFUN (bgp_distance_source
,
10038 bgp_distance_source_cmd
,
10039 "distance (1-255) A.B.C.D/M",
10040 "Define an administrative distance\n"
10041 "Administrative distance\n"
10042 "IP source prefix\n")
10044 int idx_number
= 1;
10045 int idx_ipv4_prefixlen
= 2;
10046 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10047 return CMD_SUCCESS
;
10050 DEFUN (no_bgp_distance_source
,
10051 no_bgp_distance_source_cmd
,
10052 "no distance (1-255) A.B.C.D/M",
10054 "Define an administrative distance\n"
10055 "Administrative distance\n"
10056 "IP source prefix\n")
10058 int idx_number
= 2;
10059 int idx_ipv4_prefixlen
= 3;
10060 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10061 return CMD_SUCCESS
;
10064 DEFUN (bgp_distance_source_access_list
,
10065 bgp_distance_source_access_list_cmd
,
10066 "distance (1-255) A.B.C.D/M WORD",
10067 "Define an administrative distance\n"
10068 "Administrative distance\n"
10069 "IP source prefix\n"
10070 "Access list name\n")
10072 int idx_number
= 1;
10073 int idx_ipv4_prefixlen
= 2;
10075 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10076 return CMD_SUCCESS
;
10079 DEFUN (no_bgp_distance_source_access_list
,
10080 no_bgp_distance_source_access_list_cmd
,
10081 "no distance (1-255) A.B.C.D/M WORD",
10083 "Define an administrative distance\n"
10084 "Administrative distance\n"
10085 "IP source prefix\n"
10086 "Access list name\n")
10088 int idx_number
= 2;
10089 int idx_ipv4_prefixlen
= 3;
10091 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10092 return CMD_SUCCESS
;
10095 DEFUN (ipv6_bgp_distance_source
,
10096 ipv6_bgp_distance_source_cmd
,
10097 "distance (1-255) X:X::X:X/M",
10098 "Define an administrative distance\n"
10099 "Administrative distance\n"
10100 "IP source prefix\n")
10102 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10103 return CMD_SUCCESS
;
10106 DEFUN (no_ipv6_bgp_distance_source
,
10107 no_ipv6_bgp_distance_source_cmd
,
10108 "no distance (1-255) X:X::X:X/M",
10110 "Define an administrative distance\n"
10111 "Administrative distance\n"
10112 "IP source prefix\n")
10114 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10115 return CMD_SUCCESS
;
10118 DEFUN (ipv6_bgp_distance_source_access_list
,
10119 ipv6_bgp_distance_source_access_list_cmd
,
10120 "distance (1-255) X:X::X:X/M WORD",
10121 "Define an administrative distance\n"
10122 "Administrative distance\n"
10123 "IP source prefix\n"
10124 "Access list name\n")
10126 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10127 return CMD_SUCCESS
;
10130 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10131 no_ipv6_bgp_distance_source_access_list_cmd
,
10132 "no distance (1-255) X:X::X:X/M WORD",
10134 "Define an administrative distance\n"
10135 "Administrative distance\n"
10136 "IP source prefix\n"
10137 "Access list name\n")
10139 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10140 return CMD_SUCCESS
;
10143 DEFUN (bgp_damp_set
,
10145 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10146 "BGP Specific commands\n"
10147 "Enable route-flap dampening\n"
10148 "Half-life time for the penalty\n"
10149 "Value to start reusing a route\n"
10150 "Value to start suppressing a route\n"
10151 "Maximum duration to suppress a stable route\n")
10153 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10154 int idx_half_life
= 2;
10156 int idx_suppress
= 4;
10157 int idx_max_suppress
= 5;
10158 int half
= DEFAULT_HALF_LIFE
* 60;
10159 int reuse
= DEFAULT_REUSE
;
10160 int suppress
= DEFAULT_SUPPRESS
;
10161 int max
= 4 * half
;
10165 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10166 reuse
= atoi (argv
[idx_reuse
]->arg
);
10167 suppress
= atoi (argv
[idx_suppress
]->arg
);
10168 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10170 else if (argc
== 3)
10172 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10176 if (suppress
< reuse
)
10178 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10183 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10184 half
, reuse
, suppress
, max
);
10187 DEFUN (bgp_damp_unset
,
10188 bgp_damp_unset_cmd
,
10189 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10191 "BGP Specific commands\n"
10192 "Enable route-flap dampening\n"
10193 "Half-life time for the penalty\n"
10194 "Value to start reusing a route\n"
10195 "Value to start suppressing a route\n"
10196 "Maximum duration to suppress a stable route\n")
10198 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10199 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10202 /* Display specified route of BGP table. */
10204 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10205 const char *ip_str
, afi_t afi
, safi_t safi
,
10206 struct prefix_rd
*prd
, int prefix_check
)
10209 struct prefix match
;
10210 struct bgp_node
*rn
;
10211 struct bgp_node
*rm
;
10212 struct bgp_info
*ri
;
10213 struct bgp_info
*ri_temp
;
10215 struct bgp_table
*table
;
10217 /* BGP structure lookup. */
10220 bgp
= bgp_lookup_by_name (view_name
);
10223 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10224 return CMD_WARNING
;
10229 bgp
= bgp_get_default ();
10232 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10233 return CMD_WARNING
;
10237 /* Check IP address argument. */
10238 ret
= str2prefix (ip_str
, &match
);
10241 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10242 return CMD_WARNING
;
10245 match
.family
= afi2family (afi
);
10247 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10249 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10251 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10254 if ((table
= rn
->info
) != NULL
)
10255 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10257 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10262 if (ri
->extra
&& ri
->extra
->damp_info
)
10264 ri_temp
= ri
->next
;
10265 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10273 bgp_unlock_node (rm
);
10279 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10281 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10286 if (ri
->extra
&& ri
->extra
->damp_info
)
10288 ri_temp
= ri
->next
;
10289 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10297 bgp_unlock_node (rn
);
10301 return CMD_SUCCESS
;
10304 DEFUN (clear_ip_bgp_dampening
,
10305 clear_ip_bgp_dampening_cmd
,
10306 "clear ip bgp dampening",
10310 "Clear route flap dampening information\n")
10312 bgp_damp_info_clean ();
10313 return CMD_SUCCESS
;
10316 DEFUN (clear_ip_bgp_dampening_prefix
,
10317 clear_ip_bgp_dampening_prefix_cmd
,
10318 "clear ip bgp dampening A.B.C.D/M",
10322 "Clear route flap dampening information\n"
10325 int idx_ipv4_prefixlen
= 4;
10326 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10327 SAFI_UNICAST
, NULL
, 1);
10330 DEFUN (clear_ip_bgp_dampening_address
,
10331 clear_ip_bgp_dampening_address_cmd
,
10332 "clear ip bgp dampening A.B.C.D",
10336 "Clear route flap dampening information\n"
10337 "Network to clear damping information\n")
10340 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10341 SAFI_UNICAST
, NULL
, 0);
10344 DEFUN (clear_ip_bgp_dampening_address_mask
,
10345 clear_ip_bgp_dampening_address_mask_cmd
,
10346 "clear ip bgp dampening A.B.C.D A.B.C.D",
10350 "Clear route flap dampening information\n"
10351 "Network to clear damping information\n"
10355 int idx_ipv4_2
= 5;
10357 char prefix_str
[BUFSIZ
];
10359 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10362 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10363 return CMD_WARNING
;
10366 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10367 SAFI_UNICAST
, NULL
, 0);
10370 /* also used for encap safi */
10372 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10373 afi_t afi
, safi_t safi
, int *write
)
10375 struct bgp_node
*prn
;
10376 struct bgp_node
*rn
;
10377 struct bgp_table
*table
;
10379 struct prefix_rd
*prd
;
10380 struct bgp_static
*bgp_static
;
10382 char buf
[SU_ADDRSTRLEN
];
10383 char rdbuf
[RD_ADDRSTRLEN
];
10385 /* Network configuration. */
10386 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10387 if ((table
= prn
->info
) != NULL
)
10388 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10389 if ((bgp_static
= rn
->info
) != NULL
)
10392 prd
= (struct prefix_rd
*) &prn
->p
;
10394 /* "address-family" display. */
10395 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10397 /* "network" configuration display. */
10398 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10399 label
= decode_label (bgp_static
->tag
);
10401 vty_out (vty
, " network %s/%d rd %s tag %d",
10402 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10405 vty_out (vty
, "%s", VTY_NEWLINE
);
10410 /* Configuration of static route announcement and aggregate
10413 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10414 afi_t afi
, safi_t safi
, int *write
)
10416 struct bgp_node
*rn
;
10418 struct bgp_static
*bgp_static
;
10419 struct bgp_aggregate
*bgp_aggregate
;
10420 char buf
[SU_ADDRSTRLEN
];
10422 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10423 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10425 /* Network configuration. */
10426 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10427 if ((bgp_static
= rn
->info
) != NULL
)
10431 /* "address-family" display. */
10432 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10434 /* "network" configuration display. */
10435 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10437 u_int32_t destination
;
10438 struct in_addr netmask
;
10440 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10441 masklen2ip (p
->prefixlen
, &netmask
);
10442 vty_out (vty
, " network %s",
10443 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10445 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10446 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10447 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10448 || p
->u
.prefix4
.s_addr
== 0)
10450 /* Natural mask is not display. */
10453 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10457 vty_out (vty
, " network %s/%d",
10458 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10462 if (bgp_static
->rmap
.name
)
10463 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10466 if (bgp_static
->backdoor
)
10467 vty_out (vty
, " backdoor");
10470 vty_out (vty
, "%s", VTY_NEWLINE
);
10473 /* Aggregate-address configuration. */
10474 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10475 if ((bgp_aggregate
= rn
->info
) != NULL
)
10479 /* "address-family" display. */
10480 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10482 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10484 struct in_addr netmask
;
10486 masklen2ip (p
->prefixlen
, &netmask
);
10487 vty_out (vty
, " aggregate-address %s %s",
10488 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10489 inet_ntoa (netmask
));
10493 vty_out (vty
, " aggregate-address %s/%d",
10494 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10498 if (bgp_aggregate
->as_set
)
10499 vty_out (vty
, " as-set");
10501 if (bgp_aggregate
->summary_only
)
10502 vty_out (vty
, " summary-only");
10504 vty_out (vty
, "%s", VTY_NEWLINE
);
10511 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10512 safi_t safi
, int *write
)
10514 struct bgp_node
*rn
;
10515 struct bgp_distance
*bdistance
;
10517 /* Distance configuration. */
10518 if (bgp
->distance_ebgp
[afi
][safi
]
10519 && bgp
->distance_ibgp
[afi
][safi
]
10520 && bgp
->distance_local
[afi
][safi
]
10521 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10522 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10523 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10525 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10526 vty_out (vty
, " distance bgp %d %d %d%s",
10527 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10528 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10531 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10532 rn
= bgp_route_next (rn
))
10533 if ((bdistance
= rn
->info
) != NULL
)
10535 char buf
[PREFIX_STRLEN
];
10537 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10538 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10539 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10540 bdistance
->access_list
? bdistance
->access_list
: "",
10547 /* Allocate routing table structure and install commands. */
10549 bgp_route_init (void)
10554 /* Init BGP distance table. */
10555 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10556 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10557 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10559 /* IPv4 BGP commands. */
10560 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10561 install_element (BGP_NODE
, &bgp_network_cmd
);
10562 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10563 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10564 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10565 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10566 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10567 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10568 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10569 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10570 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10571 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10572 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10573 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10575 install_element (BGP_NODE
, &aggregate_address_cmd
);
10576 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10577 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10578 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10580 /* IPv4 unicast configuration. */
10581 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10582 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10583 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10584 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10585 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10586 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10587 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10588 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10589 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10590 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10591 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10593 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10594 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10595 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10596 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10598 /* IPv4 multicast configuration. */
10599 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10600 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10601 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10602 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10603 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10604 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10605 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10606 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10607 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10608 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10609 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10610 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10611 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10612 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10613 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10615 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10616 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10617 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10618 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10620 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10621 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10622 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10623 #ifdef KEEP_OLD_VPN_COMMANDS
10624 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10625 #endif /* KEEP_OLD_VPN_COMMANDS */
10626 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10628 /* BGP dampening clear commands */
10629 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10630 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10632 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10633 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10636 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10637 #ifdef KEEP_OLD_VPN_COMMANDS
10638 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10639 #endif /* KEEP_OLD_VPN_COMMANDS */
10641 /* New config IPv6 BGP commands. */
10642 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10643 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10644 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10645 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10646 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10648 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10649 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10651 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10652 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10654 install_element (BGP_NODE
, &bgp_distance_cmd
);
10655 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10656 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10657 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10658 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10659 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10660 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10661 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10662 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10663 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10664 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10665 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10666 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10667 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10668 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10669 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10670 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10671 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10672 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10673 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10674 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10675 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10676 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10677 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10678 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10679 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10680 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10681 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10682 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10683 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10685 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10686 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10687 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10688 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10690 /* IPv4 Multicast Mode */
10691 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10692 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10694 /* Large Communities */
10695 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
10696 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
10700 bgp_route_finish (void)
10705 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10706 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10708 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10709 bgp_distance_table
[afi
][safi
] = NULL
;