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_evpn.h"
73 /* Extern from bgp_dump.c */
74 extern const char *bgp_origin_str
[];
75 extern const char *bgp_origin_long_str
[];
78 bgp_afi_node_get (struct bgp_table
*table
, afi_t afi
, safi_t safi
, struct prefix
*p
,
79 struct prefix_rd
*prd
)
82 struct bgp_node
*prn
= NULL
;
88 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
91 prn
= bgp_node_get (table
, (struct prefix
*) prd
);
93 if (prn
->info
== NULL
)
94 prn
->info
= bgp_table_init (afi
, safi
);
96 bgp_unlock_node (prn
);
100 rn
= bgp_node_get (table
, p
);
102 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) ||
109 /* Allocate bgp_info_extra */
110 static struct bgp_info_extra
*
111 bgp_info_extra_new (void)
113 struct bgp_info_extra
*new;
114 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA
, sizeof (struct bgp_info_extra
));
119 bgp_info_extra_free (struct bgp_info_extra
**extra
)
123 if ((*extra
)->damp_info
)
124 bgp_damp_info_free ((*extra
)->damp_info
, 0);
126 (*extra
)->damp_info
= NULL
;
128 XFREE (MTYPE_BGP_ROUTE_EXTRA
, *extra
);
134 /* Get bgp_info extra information for the given bgp_info, lazy allocated
137 struct bgp_info_extra
*
138 bgp_info_extra_get (struct bgp_info
*ri
)
141 ri
->extra
= bgp_info_extra_new();
145 /* Allocate new bgp info structure. */
149 return XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
152 /* Free bgp route information. */
154 bgp_info_free (struct bgp_info
*binfo
)
157 bgp_attr_unintern (&binfo
->attr
);
159 bgp_unlink_nexthop(binfo
);
160 bgp_info_extra_free (&binfo
->extra
);
161 bgp_info_mpath_free (&binfo
->mpath
);
163 peer_unlock (binfo
->peer
); /* bgp_info peer reference */
165 XFREE (MTYPE_BGP_ROUTE
, binfo
);
169 bgp_info_lock (struct bgp_info
*binfo
)
176 bgp_info_unlock (struct bgp_info
*binfo
)
178 assert (binfo
&& binfo
->lock
> 0);
181 if (binfo
->lock
== 0)
184 zlog_debug ("%s: unlocked and freeing", __func__
);
185 zlog_backtrace (LOG_DEBUG
);
187 bgp_info_free (binfo
);
192 if (binfo
->lock
== 1)
194 zlog_debug ("%s: unlocked to 1", __func__
);
195 zlog_backtrace (LOG_DEBUG
);
203 bgp_info_add (struct bgp_node
*rn
, struct bgp_info
*ri
)
205 struct bgp_info
*top
;
217 peer_lock (ri
->peer
); /* bgp_info peer reference */
220 /* Do the actual removal of info from RIB, for use by bgp_process
221 completion callback *only* */
223 bgp_info_reap (struct bgp_node
*rn
, struct bgp_info
*ri
)
226 ri
->next
->prev
= ri
->prev
;
228 ri
->prev
->next
= ri
->next
;
232 bgp_info_mpath_dequeue (ri
);
233 bgp_info_unlock (ri
);
234 bgp_unlock_node (rn
);
238 bgp_info_delete (struct bgp_node
*rn
, struct bgp_info
*ri
)
240 bgp_info_set_flag (rn
, ri
, BGP_INFO_REMOVED
);
241 /* set of previous already took care of pcount */
242 UNSET_FLAG (ri
->flags
, BGP_INFO_VALID
);
245 /* undo the effects of a previous call to bgp_info_delete; typically
246 called when a route is deleted and then quickly re-added before the
247 deletion has been processed */
249 bgp_info_restore (struct bgp_node
*rn
, struct bgp_info
*ri
)
251 bgp_info_unset_flag (rn
, ri
, BGP_INFO_REMOVED
);
252 /* unset of previous already took care of pcount */
253 SET_FLAG (ri
->flags
, BGP_INFO_VALID
);
256 /* Adjust pcount as required */
258 bgp_pcount_adjust (struct bgp_node
*rn
, struct bgp_info
*ri
)
260 struct bgp_table
*table
;
262 assert (rn
&& bgp_node_table (rn
));
263 assert (ri
&& ri
->peer
&& ri
->peer
->bgp
);
265 table
= bgp_node_table (rn
);
267 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
270 if (!BGP_INFO_COUNTABLE (ri
)
271 && CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
274 UNSET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
276 /* slight hack, but more robust against errors. */
277 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
278 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
281 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
282 __func__
, ri
->peer
->host
);
283 zlog_backtrace (LOG_WARNING
);
284 zlog_warn ("%s: Please report to Quagga bugzilla", __func__
);
287 else if (BGP_INFO_COUNTABLE (ri
)
288 && !CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
290 SET_FLAG (ri
->flags
, BGP_INFO_COUNTED
);
291 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
296 /* Set/unset bgp_info flags, adjusting any other state as needed.
297 * This is here primarily to keep prefix-count in check.
300 bgp_info_set_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
302 SET_FLAG (ri
->flags
, flag
);
304 /* early bath if we know it's not a flag that changes countability state */
305 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
308 bgp_pcount_adjust (rn
, ri
);
312 bgp_info_unset_flag (struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
314 UNSET_FLAG (ri
->flags
, flag
);
316 /* early bath if we know it's not a flag that changes countability state */
317 if (!CHECK_FLAG (flag
, BGP_INFO_VALID
|BGP_INFO_HISTORY
|BGP_INFO_REMOVED
))
320 bgp_pcount_adjust (rn
, ri
);
323 /* Get MED value. If MED value is missing and "bgp bestpath
324 missing-as-worst" is specified, treat it as the worst value. */
326 bgp_med_value (struct attr
*attr
, struct bgp
*bgp
)
328 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
332 if (bgp_flag_check (bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
340 bgp_info_path_with_addpath_rx_str (struct bgp_info
*ri
, char *buf
)
342 if (ri
->addpath_rx_id
)
343 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
, ri
->addpath_rx_id
);
345 sprintf(buf
, "path %s", ri
->peer
->host
);
348 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
350 bgp_info_cmp (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
351 int *paths_eq
, struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
354 struct attr
*newattr
, *existattr
;
355 struct attr_extra
*newattre
, *existattre
;
356 bgp_peer_sort_t new_sort
;
357 bgp_peer_sort_t exist_sort
;
359 u_int32_t exist_pref
;
362 u_int32_t new_weight
;
363 u_int32_t exist_weight
;
364 uint32_t newm
, existm
;
365 struct in_addr new_id
;
366 struct in_addr exist_id
;
369 int internal_as_route
;
372 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
373 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
381 zlog_debug("%s: new is NULL", pfx_buf
);
386 bgp_info_path_with_addpath_rx_str (new, new_buf
);
391 zlog_debug("%s: %s is the initial bestpath", pfx_buf
, new_buf
);
397 bgp_info_path_with_addpath_rx_str (exist
, exist_buf
);
398 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
399 pfx_buf
, new_buf
, new->flags
, exist_buf
, exist
->flags
);
403 existattr
= exist
->attr
;
404 newattre
= newattr
->extra
;
405 existattre
= existattr
->extra
;
407 /* 1. Weight check. */
408 new_weight
= exist_weight
= 0;
411 new_weight
= newattre
->weight
;
413 exist_weight
= existattre
->weight
;
415 if (new_weight
> exist_weight
)
418 zlog_debug("%s: %s wins over %s due to weight %d > %d",
419 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
423 if (new_weight
< exist_weight
)
426 zlog_debug("%s: %s loses to %s due to weight %d < %d",
427 pfx_buf
, new_buf
, exist_buf
, new_weight
, exist_weight
);
431 /* 2. Local preference check. */
432 new_pref
= exist_pref
= bgp
->default_local_pref
;
434 if (newattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
435 new_pref
= newattr
->local_pref
;
436 if (existattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
437 exist_pref
= existattr
->local_pref
;
439 if (new_pref
> exist_pref
)
442 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
443 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
447 if (new_pref
< exist_pref
)
450 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
451 pfx_buf
, new_buf
, exist_buf
, new_pref
, exist_pref
);
455 /* 3. Local route check. We prefer:
457 * - BGP_ROUTE_AGGREGATE
458 * - BGP_ROUTE_REDISTRIBUTE
460 if (! (new->sub_type
== BGP_ROUTE_NORMAL
))
463 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
464 pfx_buf
, new_buf
, exist_buf
);
468 if (! (exist
->sub_type
== BGP_ROUTE_NORMAL
))
471 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
472 pfx_buf
, new_buf
, exist_buf
);
476 /* 4. AS path length check. */
477 if (! bgp_flag_check (bgp
, BGP_FLAG_ASPATH_IGNORE
))
479 int exist_hops
= aspath_count_hops (existattr
->aspath
);
480 int exist_confeds
= aspath_count_confeds (existattr
->aspath
);
482 if (bgp_flag_check (bgp
, BGP_FLAG_ASPATH_CONFED
))
486 aspath_hops
= aspath_count_hops (newattr
->aspath
);
487 aspath_hops
+= aspath_count_confeds (newattr
->aspath
);
489 if ( aspath_hops
< (exist_hops
+ exist_confeds
))
492 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
493 pfx_buf
, new_buf
, exist_buf
,
494 aspath_hops
, (exist_hops
+ exist_confeds
));
498 if ( aspath_hops
> (exist_hops
+ exist_confeds
))
501 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
502 pfx_buf
, new_buf
, exist_buf
,
503 aspath_hops
, (exist_hops
+ exist_confeds
));
509 int newhops
= aspath_count_hops (newattr
->aspath
);
511 if (newhops
< exist_hops
)
514 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
515 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
519 if (newhops
> exist_hops
)
522 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
523 pfx_buf
, new_buf
, exist_buf
, newhops
, exist_hops
);
529 /* 5. Origin check. */
530 if (newattr
->origin
< existattr
->origin
)
533 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
534 pfx_buf
, new_buf
, exist_buf
,
535 bgp_origin_long_str
[newattr
->origin
],
536 bgp_origin_long_str
[existattr
->origin
]);
540 if (newattr
->origin
> existattr
->origin
)
543 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
544 pfx_buf
, new_buf
, exist_buf
,
545 bgp_origin_long_str
[newattr
->origin
],
546 bgp_origin_long_str
[existattr
->origin
]);
551 internal_as_route
= (aspath_count_hops (newattr
->aspath
) == 0
552 && aspath_count_hops (existattr
->aspath
) == 0);
553 confed_as_route
= (aspath_count_confeds (newattr
->aspath
) > 0
554 && aspath_count_confeds (existattr
->aspath
) > 0
555 && aspath_count_hops (newattr
->aspath
) == 0
556 && aspath_count_hops (existattr
->aspath
) == 0);
558 if (bgp_flag_check (bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
559 || (bgp_flag_check (bgp
, BGP_FLAG_MED_CONFED
)
561 || aspath_cmp_left (newattr
->aspath
, existattr
->aspath
)
562 || aspath_cmp_left_confed (newattr
->aspath
, existattr
->aspath
)
563 || internal_as_route
)
565 new_med
= bgp_med_value (new->attr
, bgp
);
566 exist_med
= bgp_med_value (exist
->attr
, bgp
);
568 if (new_med
< exist_med
)
571 zlog_debug("%s: %s wins over %s due to MED %d < %d",
572 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
576 if (new_med
> exist_med
)
579 zlog_debug("%s: %s loses to %s due to MED %d > %d",
580 pfx_buf
, new_buf
, exist_buf
, new_med
, exist_med
);
585 /* 7. Peer type check. */
586 new_sort
= new->peer
->sort
;
587 exist_sort
= exist
->peer
->sort
;
589 if (new_sort
== BGP_PEER_EBGP
590 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
))
593 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
594 pfx_buf
, new_buf
, exist_buf
);
598 if (exist_sort
== BGP_PEER_EBGP
599 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
))
602 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
603 pfx_buf
, new_buf
, exist_buf
);
607 /* 8. IGP metric check. */
611 newm
= new->extra
->igpmetric
;
613 existm
= exist
->extra
->igpmetric
;
618 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
619 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
626 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
627 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
631 /* 9. Same IGP metric. Compare the cluster list length as
632 representative of IGP hops metric. Rewrite the metric value
633 pair (newm, existm) with the cluster list length. Prefer the
634 path with smaller cluster list length. */
637 if (peer_sort (new->peer
) == BGP_PEER_IBGP
638 && peer_sort (exist
->peer
) == BGP_PEER_IBGP
639 && (mpath_cfg
== NULL
||
640 CHECK_FLAG (mpath_cfg
->ibgp_flags
,
641 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
)))
643 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
644 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
649 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
650 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
657 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
658 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
664 /* 10. confed-external vs. confed-internal */
665 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
667 if (new_sort
== BGP_PEER_CONFED
&& exist_sort
== BGP_PEER_IBGP
)
670 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
671 pfx_buf
, new_buf
, exist_buf
);
675 if (exist_sort
== BGP_PEER_CONFED
&& new_sort
== BGP_PEER_IBGP
)
678 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
679 pfx_buf
, new_buf
, exist_buf
);
684 /* 11. Maximum path check. */
687 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
))
691 * For the two paths, all comparison steps till IGP metric
692 * have succeeded - including AS_PATH hop count. Since 'bgp
693 * bestpath as-path multipath-relax' knob is on, we don't need
694 * an exact match of AS_PATH. Thus, mark the paths are equal.
695 * That will trigger both these paths to get into the multipath
701 zlog_debug("%s: %s and %s are equal via multipath-relax",
702 pfx_buf
, new_buf
, exist_buf
);
704 else if (new->peer
->sort
== BGP_PEER_IBGP
)
706 if (aspath_cmp (new->attr
->aspath
, exist
->attr
->aspath
))
711 zlog_debug("%s: %s and %s are equal via matching aspaths",
712 pfx_buf
, new_buf
, exist_buf
);
715 else if (new->peer
->as
== exist
->peer
->as
)
720 zlog_debug("%s: %s and %s are equal via same remote-as",
721 pfx_buf
, new_buf
, exist_buf
);
727 * TODO: If unequal cost ibgp multipath is enabled we can
728 * mark the paths as equal here instead of returning
733 zlog_debug("%s: %s wins over %s after IGP metric comparison",
734 pfx_buf
, new_buf
, exist_buf
);
736 zlog_debug("%s: %s loses to %s after IGP metric comparison",
737 pfx_buf
, new_buf
, exist_buf
);
742 /* 12. If both paths are external, prefer the path that was received
743 first (the oldest one). This step minimizes route-flap, since a
744 newer path won't displace an older one, even if it was the
745 preferred route based on the additional decision criteria below. */
746 if (! bgp_flag_check (bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
747 && new_sort
== BGP_PEER_EBGP
748 && exist_sort
== BGP_PEER_EBGP
)
750 if (CHECK_FLAG (new->flags
, BGP_INFO_SELECTED
))
753 zlog_debug("%s: %s wins over %s due to oldest external",
754 pfx_buf
, new_buf
, exist_buf
);
758 if (CHECK_FLAG (exist
->flags
, BGP_INFO_SELECTED
))
761 zlog_debug("%s: %s loses to %s due to oldest external",
762 pfx_buf
, new_buf
, exist_buf
);
767 /* 13. Router-ID comparision. */
768 /* If one of the paths is "stale", the corresponding peer router-id will
769 * be 0 and would always win over the other path. If originator id is
770 * used for the comparision, it will decide which path is better.
772 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
773 new_id
.s_addr
= newattre
->originator_id
.s_addr
;
775 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
776 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
777 exist_id
.s_addr
= existattre
->originator_id
.s_addr
;
779 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
781 if (ntohl (new_id
.s_addr
) < ntohl (exist_id
.s_addr
))
784 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
785 pfx_buf
, new_buf
, exist_buf
);
789 if (ntohl (new_id
.s_addr
) > ntohl (exist_id
.s_addr
))
792 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
793 pfx_buf
, new_buf
, exist_buf
);
797 /* 14. Cluster length comparision. */
798 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
799 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
801 if (new_cluster
< exist_cluster
)
804 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
805 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
809 if (new_cluster
> exist_cluster
)
812 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
813 pfx_buf
, new_buf
, exist_buf
, new_cluster
, exist_cluster
);
817 /* 15. Neighbor address comparision. */
818 /* Do this only if neither path is "stale" as stale paths do not have
819 * valid peer information (as the connection may or may not be up).
821 if (CHECK_FLAG (exist
->flags
, BGP_INFO_STALE
))
824 zlog_debug("%s: %s wins over %s due to latter path being STALE",
825 pfx_buf
, new_buf
, exist_buf
);
829 if (CHECK_FLAG (new->flags
, BGP_INFO_STALE
))
832 zlog_debug("%s: %s loses to %s due to former path being STALE",
833 pfx_buf
, new_buf
, exist_buf
);
837 /* locally configured routes to advertise do not have su_remote */
838 if (new->peer
->su_remote
== NULL
)
840 if (exist
->peer
->su_remote
== NULL
)
843 ret
= sockunion_cmp (new->peer
->su_remote
, exist
->peer
->su_remote
);
848 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
849 pfx_buf
, new_buf
, exist_buf
);
856 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
857 pfx_buf
, new_buf
, exist_buf
);
862 zlog_debug("%s: %s wins over %s due to nothing left to compare",
863 pfx_buf
, new_buf
, exist_buf
);
868 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
869 * is preferred, or 0 if they are the same (usually will only occur if
870 * multipath is enabled
871 * This version is compatible with */
873 bgp_info_cmp_compatible (struct bgp
*bgp
, struct bgp_info
*new, struct bgp_info
*exist
,
874 afi_t afi
, safi_t safi
)
878 ret
= bgp_info_cmp (bgp
, new, exist
, &paths_eq
, NULL
, 0, __func__
);
892 static enum filter_type
893 bgp_input_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
894 afi_t afi
, safi_t safi
)
896 struct bgp_filter
*filter
;
898 filter
= &peer
->filter
[afi
][safi
];
900 #define FILTER_EXIST_WARN(F,f,filter) \
901 if (BGP_DEBUG (update, UPDATE_IN) \
902 && !(F ## _IN (filter))) \
903 zlog_warn ("%s: Could not find configured input %s-list %s!", \
904 peer->host, #f, F ## _IN_NAME(filter));
906 if (DISTRIBUTE_IN_NAME (filter
)) {
907 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
909 if (access_list_apply (DISTRIBUTE_IN (filter
), p
) == FILTER_DENY
)
913 if (PREFIX_LIST_IN_NAME (filter
)) {
914 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
916 if (prefix_list_apply (PREFIX_LIST_IN (filter
), p
) == PREFIX_DENY
)
920 if (FILTER_LIST_IN_NAME (filter
)) {
921 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
923 if (as_list_apply (FILTER_LIST_IN (filter
), attr
->aspath
)== AS_FILTER_DENY
)
927 return FILTER_PERMIT
;
928 #undef FILTER_EXIST_WARN
931 static enum filter_type
932 bgp_output_filter (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
933 afi_t afi
, safi_t safi
)
935 struct bgp_filter
*filter
;
937 filter
= &peer
->filter
[afi
][safi
];
939 #define FILTER_EXIST_WARN(F,f,filter) \
940 if (BGP_DEBUG (update, UPDATE_OUT) \
941 && !(F ## _OUT (filter))) \
942 zlog_warn ("%s: Could not find configured output %s-list %s!", \
943 peer->host, #f, F ## _OUT_NAME(filter));
945 if (DISTRIBUTE_OUT_NAME (filter
)) {
946 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
948 if (access_list_apply (DISTRIBUTE_OUT (filter
), p
) == FILTER_DENY
)
952 if (PREFIX_LIST_OUT_NAME (filter
)) {
953 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
955 if (prefix_list_apply (PREFIX_LIST_OUT (filter
), p
) == PREFIX_DENY
)
959 if (FILTER_LIST_OUT_NAME (filter
)) {
960 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
962 if (as_list_apply (FILTER_LIST_OUT (filter
), attr
->aspath
) == AS_FILTER_DENY
)
966 return FILTER_PERMIT
;
967 #undef FILTER_EXIST_WARN
970 /* If community attribute includes no_export then return 1. */
972 bgp_community_filter (struct peer
*peer
, struct attr
*attr
)
976 /* NO_ADVERTISE check. */
977 if (community_include (attr
->community
, COMMUNITY_NO_ADVERTISE
))
980 /* NO_EXPORT check. */
981 if (peer
->sort
== BGP_PEER_EBGP
&&
982 community_include (attr
->community
, COMMUNITY_NO_EXPORT
))
985 /* NO_EXPORT_SUBCONFED check. */
986 if (peer
->sort
== BGP_PEER_EBGP
987 || peer
->sort
== BGP_PEER_CONFED
)
988 if (community_include (attr
->community
, COMMUNITY_NO_EXPORT_SUBCONFED
))
994 /* Route reflection loop check. */
996 bgp_cluster_filter (struct peer
*peer
, struct attr
*attr
)
998 struct in_addr cluster_id
;
1000 if (attr
->extra
&& attr
->extra
->cluster
)
1002 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1003 cluster_id
= peer
->bgp
->cluster_id
;
1005 cluster_id
= peer
->bgp
->router_id
;
1007 if (cluster_loop_check (attr
->extra
->cluster
, cluster_id
))
1014 bgp_input_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1015 afi_t afi
, safi_t safi
, const char *rmap_name
)
1017 struct bgp_filter
*filter
;
1018 struct bgp_info info
;
1019 route_map_result_t ret
;
1020 struct route_map
*rmap
= NULL
;
1022 filter
= &peer
->filter
[afi
][safi
];
1024 /* Apply default weight value. */
1025 if (peer
->weight
[afi
][safi
])
1026 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1030 rmap
= route_map_lookup_by_name(rmap_name
);
1037 if (ROUTE_MAP_IN_NAME(filter
))
1039 rmap
= ROUTE_MAP_IN (filter
);
1046 /* Route map apply. */
1049 /* Duplicate current value to new strucutre for modification. */
1053 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1055 /* Apply BGP route map to the attribute. */
1056 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1058 peer
->rmap_type
= 0;
1060 if (ret
== RMAP_DENYMATCH
)
1062 /* Free newly generated AS path and community by route-map. */
1063 bgp_attr_flush (attr
);
1071 bgp_output_modifier (struct peer
*peer
, struct prefix
*p
, struct attr
*attr
,
1072 afi_t afi
, safi_t safi
, const char *rmap_name
)
1074 struct bgp_filter
*filter
;
1075 struct bgp_info info
;
1076 route_map_result_t ret
;
1077 struct route_map
*rmap
= NULL
;
1079 filter
= &peer
->filter
[afi
][safi
];
1081 /* Apply default weight value. */
1082 if (peer
->weight
[afi
][safi
])
1083 (bgp_attr_extra_get (attr
))->weight
= peer
->weight
[afi
][safi
];
1087 rmap
= route_map_lookup_by_name(rmap_name
);
1094 if (ROUTE_MAP_OUT_NAME(filter
))
1096 rmap
= ROUTE_MAP_OUT (filter
);
1103 /* Route map apply. */
1106 /* Duplicate current value to new strucutre for modification. */
1110 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1112 /* Apply BGP route map to the attribute. */
1113 ret
= route_map_apply (rmap
, p
, RMAP_BGP
, &info
);
1115 peer
->rmap_type
= 0;
1117 if (ret
== RMAP_DENYMATCH
)
1118 /* caller has multiple error paths with bgp_attr_flush() */
1124 /* If this is an EBGP peer with remove-private-AS */
1126 bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1127 struct peer
*peer
, struct attr
*attr
)
1129 if (peer
->sort
== BGP_PEER_EBGP
&&
1130 (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1131 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
) ||
1132 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
) ||
1133 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS
)))
1135 // Take action on the entire aspath
1136 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
) ||
1137 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL
))
1139 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1140 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1142 // The entire aspath consists of private ASNs so create an empty aspath
1143 else if (aspath_private_as_check (attr
->aspath
))
1144 attr
->aspath
= aspath_empty_get ();
1146 // There are some public and some private ASNs, remove the private ASNs
1148 attr
->aspath
= aspath_remove_private_asns (attr
->aspath
);
1151 // 'all' was not specified so the entire aspath must be private ASNs
1152 // for us to do anything
1153 else if (aspath_private_as_check (attr
->aspath
))
1155 if (peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1156 attr
->aspath
= aspath_replace_private_asns (attr
->aspath
, bgp
->as
);
1158 attr
->aspath
= aspath_empty_get ();
1163 /* If this is an EBGP peer with as-override */
1165 bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1166 struct peer
*peer
, struct attr
*attr
)
1168 if (peer
->sort
== BGP_PEER_EBGP
&&
1169 peer_af_flag_check (peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
))
1171 if (aspath_single_asn_check (attr
->aspath
, peer
->as
))
1172 attr
->aspath
= aspath_replace_specific_asn (attr
->aspath
, peer
->as
, bgp
->as
);
1177 subgroup_announce_reset_nhop (u_char family
, struct attr
*attr
)
1179 if (family
== AF_INET
)
1180 attr
->nexthop
.s_addr
= 0;
1181 if (family
== AF_INET6
)
1182 memset (&attr
->extra
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1186 subgroup_announce_check (struct bgp_info
*ri
, struct update_subgroup
*subgrp
,
1187 struct prefix
*p
, struct attr
*attr
)
1189 struct bgp_filter
*filter
;
1192 struct peer
*onlypeer
;
1194 struct attr
*riattr
;
1195 struct peer_af
*paf
;
1196 char buf
[PREFIX_STRLEN
];
1202 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1204 if (DISABLE_BGP_ANNOUNCE
)
1207 afi
= SUBGRP_AFI(subgrp
);
1208 safi
= SUBGRP_SAFI(subgrp
);
1209 peer
= SUBGRP_PEER(subgrp
);
1211 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_LONESOUL
))
1212 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1215 filter
= &peer
->filter
[afi
][safi
];
1216 bgp
= SUBGRP_INST(subgrp
);
1217 riattr
= bgp_info_mpath_count (ri
) ? bgp_info_mpath_attr (ri
) : ri
->attr
;
1220 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
) &&
1221 ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
) ||
1222 (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1225 * direct and direct_ext type routes originate internally even
1226 * though they can have peer pointers that reference other systems
1228 prefix2str(p
, buf
, PREFIX_STRLEN
);
1229 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__
, buf
);
1234 /* With addpath we may be asked to TX all kinds of paths so make sure
1236 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
) ||
1237 CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
) ||
1238 CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
1243 /* If this is not the bestpath then check to see if there is an enabled addpath
1244 * feature that requires us to advertise it */
1245 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1247 if (! bgp_addpath_tx_path(peer
, afi
, safi
, ri
))
1253 /* Aggregate-address suppress check. */
1254 if (ri
->extra
&& ri
->extra
->suppress
)
1255 if (! UNSUPPRESS_MAP_NAME (filter
))
1260 /* Do not send back route to sender. */
1261 if (onlypeer
&& from
== onlypeer
)
1266 /* Do not send the default route in the BGP table if the neighbor is
1267 * configured for default-originate */
1268 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
))
1270 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1272 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1276 /* Transparency check. */
1277 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1278 && CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1283 /* If community is not disabled check the no-export and local. */
1284 if (! transparent
&& bgp_community_filter (peer
, riattr
))
1286 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1287 zlog_debug ("subgrpannouncecheck: community filter check fail");
1291 /* If the attribute has originator-id and it is same as remote
1294 riattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
) &&
1295 (IPV4_ADDR_SAME (&onlypeer
->remote_id
, &riattr
->extra
->originator_id
)))
1297 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1298 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1300 onlypeer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1304 /* ORF prefix-list filter check */
1305 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1306 && (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1307 || CHECK_FLAG (peer
->af_cap
[afi
][safi
],
1308 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1309 if (peer
->orf_plist
[afi
][safi
])
1311 if (prefix_list_apply (peer
->orf_plist
[afi
][safi
], p
) == PREFIX_DENY
)
1313 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1314 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1315 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1320 /* Output filter check. */
1321 if (bgp_output_filter (peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
)
1323 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1324 zlog_debug ("%s [Update:SEND] %s is filtered",
1325 peer
->host
, prefix2str (p
, buf
, sizeof (buf
)));
1329 #ifdef BGP_SEND_ASPATH_CHECK
1330 /* AS path loop check. */
1331 if (onlypeer
&& aspath_loop_check (riattr
->aspath
, onlypeer
->as
))
1333 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1334 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1335 "that is part of AS path.",
1336 onlypeer
->host
, onlypeer
->as
);
1339 #endif /* BGP_SEND_ASPATH_CHECK */
1341 /* If we're a CONFED we need to loop check the CONFED ID too */
1342 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
1344 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
))
1346 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1347 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1355 /* Route-Reflect check. */
1356 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1361 /* IBGP reflection check. */
1362 if (reflect
&& !samepeer_safe
)
1364 /* A route from a Client peer. */
1365 if (CHECK_FLAG (from
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
1367 /* Reflect to all the Non-Client peers and also to the
1368 Client peers other than the originator. Originator check
1369 is already done. So there is noting to do. */
1370 /* no bgp client-to-client reflection check. */
1371 if (bgp_flag_check (bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1372 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1373 PEER_FLAG_REFLECTOR_CLIENT
))
1378 /* A route from a Non-client peer. Reflect to all other
1380 if (! CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1381 PEER_FLAG_REFLECTOR_CLIENT
))
1386 /* For modify attribute, copy it to temporary structure. */
1387 bgp_attr_dup (attr
, riattr
);
1389 /* If local-preference is not set. */
1390 if ((peer
->sort
== BGP_PEER_IBGP
1391 || peer
->sort
== BGP_PEER_CONFED
)
1392 && (! (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))))
1394 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1395 attr
->local_pref
= bgp
->default_local_pref
;
1398 /* If originator-id is not set and the route is to be reflected,
1399 set the originator id */
1400 if (reflect
&& (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))))
1402 attr
->extra
= bgp_attr_extra_get(attr
);
1403 IPV4_ADDR_COPY(&(attr
->extra
->originator_id
), &(from
->remote_id
));
1404 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1407 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1408 if (peer
->sort
== BGP_PEER_EBGP
1409 && attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1411 if (from
!= bgp
->peer_self
&& ! transparent
1412 && ! CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MED_UNCHANGED
))
1413 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
));
1416 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1417 * in announce check, only certain flags and length (or number of nexthops
1418 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1419 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1420 * Typically, the source nexthop in the attribute is preserved but in the
1421 * scenarios where we know it will always be overwritten, we reset the
1422 * nexthop to "0" in an attempt to achieve better Update packing. An
1423 * example of this is when a prefix from each of 2 IBGP peers needs to be
1424 * announced to an EBGP peer (and they have the same attributes barring
1428 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1430 #define NEXTHOP_IS_V6 (\
1431 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1432 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1433 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1434 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1436 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1437 * the peer (group) is configured to receive link-local nexthop unchanged
1438 * and it is available in the prefix OR we're not reflecting the route and
1439 * the peer (group) to whom we're going to announce is on a shared network
1440 * and this is either a self-originated route or the peer is EBGP.
1444 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1445 if ((CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1446 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
) &&
1447 IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_local
)) ||
1448 (!reflect
&& peer
->shared_network
&&
1449 (from
== bgp
->peer_self
|| peer
->sort
== BGP_PEER_EBGP
)))
1451 attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1454 /* Clear off link-local nexthop in source, whenever it is not needed to
1455 * ensure more prefixes share the same attribute for announcement.
1457 if (!(CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1458 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1459 memset (&attr
->extra
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1462 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1463 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1465 /* Route map & unsuppress-map apply. */
1466 if (ROUTE_MAP_OUT_NAME (filter
)
1467 || (ri
->extra
&& ri
->extra
->suppress
) )
1469 struct bgp_info info
;
1470 struct attr dummy_attr
;
1471 struct attr_extra dummy_extra
;
1473 dummy_attr
.extra
= &dummy_extra
;
1477 /* don't confuse inbound and outbound setting */
1478 RESET_FLAG(attr
->rmap_change_flags
);
1481 * The route reflector is not allowed to modify the attributes
1482 * of the reflected IBGP routes unless explicitly allowed.
1484 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1485 && !bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
))
1487 bgp_attr_dup (&dummy_attr
, attr
);
1488 info
.attr
= &dummy_attr
;
1491 SET_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1493 if (ri
->extra
&& ri
->extra
->suppress
)
1494 ret
= route_map_apply (UNSUPPRESS_MAP (filter
), p
, RMAP_BGP
, &info
);
1496 ret
= route_map_apply (ROUTE_MAP_OUT (filter
), p
, RMAP_BGP
, &info
);
1498 peer
->rmap_type
= 0;
1500 if (ret
== RMAP_DENYMATCH
)
1502 bgp_attr_flush (attr
);
1507 /* After route-map has been applied, we check to see if the nexthop to
1508 * be carried in the attribute (that is used for the announcement) can
1509 * be cleared off or not. We do this in all cases where we would be
1510 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1511 * the global nexthop here; the link-local nexthop would have been cleared
1512 * already, and if not, it is required by the update formation code.
1513 * Also see earlier comments in this function.
1516 * If route-map has performed some operation on the nexthop or the peer
1517 * configuration says to pass it unchanged, we cannot reset the nexthop
1518 * here, so only attempt to do it if these aren't true. Note that the
1519 * route-map handler itself might have cleared the nexthop, if for example,
1520 * it is configured as 'peer-address'.
1522 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1523 riattr
->rmap_change_flags
) &&
1525 !CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_UNCHANGED
))
1527 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1528 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_NEXTHOP_SELF
) ||
1529 CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_FORCE_NEXTHOP_SELF
))
1532 CHECK_FLAG (peer
->af_flags
[afi
][safi
],
1533 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1534 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ?
1535 AF_INET6
: p
->family
), attr
);
1537 else if (peer
->sort
== BGP_PEER_EBGP
)
1539 /* Can also reset the nexthop if announcing to EBGP, but only if
1540 * no peer in the subgroup is on a shared subnet.
1541 * Note: 3rd party nexthop currently implemented for IPv4 only.
1543 SUBGRP_FOREACH_PEER (subgrp
, paf
)
1545 if (bgp_multiaccess_check_v4 (riattr
->nexthop
, paf
->peer
))
1549 subgroup_announce_reset_nhop ((peer_cap_enhe(peer
) ? AF_INET6
: p
->family
), attr
);
1551 /* If IPv6/MP and nexthop does not have any override and happens to
1552 * be a link-local address, reset it so that we don't pass along the
1553 * source's link-local IPv6 address to recipients who may not be on
1554 * the same interface.
1556 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
))
1558 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
1559 subgroup_announce_reset_nhop (AF_INET6
, attr
);
1566 struct bgp_info_pair
1568 struct bgp_info
*old
;
1569 struct bgp_info
*new;
1573 bgp_best_selection (struct bgp
*bgp
, struct bgp_node
*rn
,
1574 struct bgp_maxpaths_cfg
*mpath_cfg
,
1575 struct bgp_info_pair
*result
)
1577 struct bgp_info
*new_select
;
1578 struct bgp_info
*old_select
;
1579 struct bgp_info
*ri
;
1580 struct bgp_info
*ri1
;
1581 struct bgp_info
*ri2
;
1582 struct bgp_info
*nextri
= NULL
;
1583 int paths_eq
, do_mpath
, debug
;
1584 struct list mp_list
;
1585 char pfx_buf
[PREFIX2STR_BUFFER
];
1586 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1588 bgp_mp_list_init (&mp_list
);
1589 do_mpath
= (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1591 debug
= bgp_debug_bestpath(&rn
->p
);
1594 prefix2str (&rn
->p
, pfx_buf
, sizeof (pfx_buf
));
1596 /* bgp deterministic-med */
1598 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
))
1601 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1602 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1603 bgp_info_unset_flag (rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1605 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1607 if (CHECK_FLAG (ri1
->flags
, BGP_INFO_DMED_CHECK
))
1609 if (BGP_INFO_HOLDDOWN (ri1
))
1611 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1612 if (ri1
->peer
->status
!= Established
)
1618 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
)
1620 if (CHECK_FLAG (ri2
->flags
, BGP_INFO_DMED_CHECK
))
1622 if (BGP_INFO_HOLDDOWN (ri2
))
1625 ri2
->peer
!= bgp
->peer_self
&&
1626 !CHECK_FLAG (ri2
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1627 if (ri2
->peer
->status
!= Established
)
1630 if (aspath_cmp_left (ri1
->attr
->aspath
, ri2
->attr
->aspath
)
1631 || aspath_cmp_left_confed (ri1
->attr
->aspath
,
1634 if (bgp_info_cmp (bgp
, ri2
, new_select
, &paths_eq
,
1635 mpath_cfg
, debug
, pfx_buf
))
1637 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1641 bgp_info_set_flag (rn
, ri2
, BGP_INFO_DMED_CHECK
);
1645 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_CHECK
);
1646 bgp_info_set_flag (rn
, new_select
, BGP_INFO_DMED_SELECTED
);
1650 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1651 zlog_debug("%s: %s is the bestpath from AS %d",
1652 pfx_buf
, path_buf
, aspath_get_first_as(new_select
->attr
->aspath
));
1657 /* Check old selected route and new selected route. */
1660 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1662 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
1665 if (BGP_INFO_HOLDDOWN (ri
))
1667 /* reap REMOVED routes, if needs be
1668 * selected route must stay for a while longer though
1670 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
1671 && (ri
!= old_select
))
1672 bgp_info_reap (rn
, ri
);
1678 ri
->peer
!= bgp
->peer_self
&&
1679 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1680 if (ri
->peer
->status
!= Established
)
1683 if (bgp_flag_check (bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1684 && (! CHECK_FLAG (ri
->flags
, BGP_INFO_DMED_SELECTED
)))
1686 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1690 bgp_info_unset_flag (rn
, ri
, BGP_INFO_DMED_CHECK
);
1692 if (bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
))
1698 /* Now that we know which path is the bestpath see if any of the other paths
1699 * qualify as multipaths
1704 bgp_info_path_with_addpath_rx_str (new_select
, path_buf
);
1706 sprintf (path_buf
, "NONE");
1707 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1709 old_select
? old_select
->peer
->host
: "NONE");
1712 if (do_mpath
&& new_select
)
1714 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1); ri
= nextri
)
1718 bgp_info_path_with_addpath_rx_str (ri
, path_buf
);
1720 if (ri
== new_select
)
1723 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1725 bgp_mp_list_add (&mp_list
, ri
);
1729 if (BGP_INFO_HOLDDOWN (ri
))
1733 ri
->peer
!= bgp
->peer_self
&&
1734 !CHECK_FLAG (ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1735 if (ri
->peer
->status
!= Established
)
1738 if (!bgp_info_nexthop_cmp (ri
, new_select
))
1741 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1746 bgp_info_cmp (bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
, debug
, pfx_buf
);
1751 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1753 bgp_mp_list_add (&mp_list
, ri
);
1758 bgp_info_mpath_update (rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1759 bgp_info_mpath_aggregate_update (new_select
, old_select
);
1760 bgp_mp_list_clear (&mp_list
);
1762 result
->old
= old_select
;
1763 result
->new = new_select
;
1769 * A new route/change in bestpath of an existing route. Evaluate the path
1770 * for advertisement to the subgroup.
1773 subgroup_process_announce_selected (struct update_subgroup
*subgrp
,
1774 struct bgp_info
*selected
,
1775 struct bgp_node
*rn
,
1776 u_int32_t addpath_tx_id
)
1779 struct peer
*onlypeer
;
1781 struct attr_extra extra
;
1786 afi
= SUBGRP_AFI(subgrp
);
1787 safi
= SUBGRP_SAFI(subgrp
);
1788 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ?
1789 (SUBGRP_PFIRST(subgrp
))->peer
: NULL
);
1791 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1792 if (onlypeer
&& CHECK_FLAG (onlypeer
->af_sflags
[afi
][safi
],
1793 PEER_STATUS_ORF_WAIT_REFRESH
))
1796 memset(&extra
, 0, sizeof(struct attr_extra
));
1797 /* It's initialized in bgp_announce_check() */
1798 attr
.extra
= &extra
;
1800 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1803 if (subgroup_announce_check(selected
, subgrp
, p
, &attr
))
1804 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1806 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, selected
->addpath_tx_id
);
1809 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1812 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1819 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1820 * This is called at the end of route processing.
1823 bgp_zebra_clear_route_change_flags (struct bgp_node
*rn
)
1825 struct bgp_info
*ri
;
1827 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1829 if (BGP_INFO_HOLDDOWN (ri
))
1831 UNSET_FLAG (ri
->flags
, BGP_INFO_IGP_CHANGED
);
1832 UNSET_FLAG (ri
->flags
, BGP_INFO_ATTR_CHANGED
);
1837 * Has the route changed from the RIB's perspective? This is invoked only
1838 * if the route selection returns the same best route as earlier - to
1839 * determine if we need to update zebra or not.
1842 bgp_zebra_has_route_changed (struct bgp_node
*rn
, struct bgp_info
*selected
)
1844 struct bgp_info
*mpinfo
;
1846 /* If this is multipath, check all selected paths for any nexthop change or
1847 * attribute change. Some attribute changes (e.g., community) aren't of
1848 * relevance to the RIB, but we'll update zebra to ensure we handle the
1849 * case of BGP nexthop change. This is the behavior when the best path has
1850 * an attribute change anyway.
1852 if (CHECK_FLAG (selected
->flags
, BGP_INFO_IGP_CHANGED
) ||
1853 CHECK_FLAG (selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
1856 /* If this is multipath, check all selected paths for any nexthop change */
1857 for (mpinfo
= bgp_info_mpath_first (selected
); mpinfo
;
1858 mpinfo
= bgp_info_mpath_next (mpinfo
))
1860 if (CHECK_FLAG (mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
1861 || CHECK_FLAG (mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
1865 /* Nothing has changed from the RIB's perspective. */
1869 struct bgp_process_queue
1872 struct bgp_node
*rn
;
1877 static wq_item_status
1878 bgp_process_main (struct work_queue
*wq
, void *data
)
1880 struct bgp_process_queue
*pq
= data
;
1881 struct bgp
*bgp
= pq
->bgp
;
1882 struct bgp_node
*rn
= pq
->rn
;
1883 afi_t afi
= pq
->afi
;
1884 safi_t safi
= pq
->safi
;
1885 struct prefix
*p
= &rn
->p
;
1886 struct bgp_info
*new_select
;
1887 struct bgp_info
*old_select
;
1888 struct bgp_info_pair old_and_new
;
1890 /* Is it end of initial update? (after startup) */
1893 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
1894 sizeof(bgp
->update_delay_zebra_resume_time
));
1896 bgp
->main_zebra_update_hold
= 0;
1897 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1898 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1900 bgp_zebra_announce_table(bgp
, afi
, safi
);
1902 bgp
->main_peers_update_hold
= 0;
1904 bgp_start_routeadv(bgp
);
1908 /* Best path selection. */
1909 bgp_best_selection (bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
);
1910 old_select
= old_and_new
.old
;
1911 new_select
= old_and_new
.new;
1913 /* Nothing to do. */
1914 if (old_select
&& old_select
== new_select
&&
1915 !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
) &&
1916 !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
) &&
1917 !bgp
->addpath_tx_used
[afi
][safi
])
1919 if (bgp_zebra_has_route_changed (rn
, old_select
))
1922 vnc_import_bgp_add_route(bgp
, p
, old_select
);
1923 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
1925 bgp_zebra_announce (p
, old_select
, bgp
, afi
, safi
);
1927 UNSET_FLAG (old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1928 bgp_zebra_clear_route_change_flags (rn
);
1929 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
1933 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
1934 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1936 /* bestpath has changed; bump version */
1937 if (old_select
|| new_select
)
1939 bgp_bump_version(rn
);
1941 if (!bgp
->t_rmap_def_originate_eval
)
1944 THREAD_TIMER_ON(bm
->master
, bgp
->t_rmap_def_originate_eval
,
1945 update_group_refresh_default_originate_route_map
,
1946 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
);
1951 bgp_info_unset_flag (rn
, old_select
, BGP_INFO_SELECTED
);
1954 bgp_info_set_flag (rn
, new_select
, BGP_INFO_SELECTED
);
1955 bgp_info_unset_flag (rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
1956 UNSET_FLAG (new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
1960 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
1961 if (old_select
!= new_select
) {
1963 vnc_import_bgp_exterior_del_route(bgp
, p
, old_select
);
1964 vnc_import_bgp_del_route(bgp
, p
, old_select
);
1967 vnc_import_bgp_exterior_add_route(bgp
, p
, new_select
);
1968 vnc_import_bgp_add_route(bgp
, p
, new_select
);
1974 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
1977 if ((safi
== SAFI_UNICAST
|| safi
== SAFI_MULTICAST
) &&
1978 (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
) &&
1979 !bgp_option_check (BGP_OPT_NO_FIB
))
1982 && new_select
->type
== ZEBRA_ROUTE_BGP
1983 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
||
1984 new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1985 bgp_zebra_announce (p
, new_select
, bgp
, afi
, safi
);
1988 /* Withdraw the route from the kernel. */
1990 && old_select
->type
== ZEBRA_ROUTE_BGP
1991 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
||
1992 old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
1993 bgp_zebra_withdraw (p
, old_select
, safi
);
1997 /* Clear any route change flags. */
1998 bgp_zebra_clear_route_change_flags (rn
);
2000 /* Reap old select bgp_info, if it has been removed */
2001 if (old_select
&& CHECK_FLAG (old_select
->flags
, BGP_INFO_REMOVED
))
2002 bgp_info_reap (rn
, old_select
);
2004 UNSET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2009 bgp_processq_del (struct work_queue
*wq
, void *data
)
2011 struct bgp_process_queue
*pq
= data
;
2012 struct bgp_table
*table
;
2014 bgp_unlock (pq
->bgp
);
2017 table
= bgp_node_table (pq
->rn
);
2018 bgp_unlock_node (pq
->rn
);
2019 bgp_table_unlock (table
);
2021 XFREE (MTYPE_BGP_PROCESS_QUEUE
, pq
);
2025 bgp_process_queue_init (void)
2027 if (!bm
->process_main_queue
)
2029 bm
->process_main_queue
2030 = work_queue_new (bm
->master
, "process_main_queue");
2032 if ( !bm
->process_main_queue
)
2034 zlog_err ("%s: Failed to allocate work queue", __func__
);
2039 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_main
;
2040 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2041 bm
->process_main_queue
->spec
.max_retries
= 0;
2042 bm
->process_main_queue
->spec
.hold
= 50;
2043 /* Use a higher yield value of 50ms for main queue processing */
2044 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2048 bgp_process (struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2050 struct bgp_process_queue
*pqnode
;
2052 /* already scheduled for processing? */
2053 if (CHECK_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2056 if (bm
->process_main_queue
== NULL
)
2057 bgp_process_queue_init ();
2059 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2060 sizeof (struct bgp_process_queue
));
2064 /* all unlocked in bgp_processq_del */
2065 bgp_table_lock (bgp_node_table (rn
));
2066 pqnode
->rn
= bgp_lock_node (rn
);
2070 pqnode
->safi
= safi
;
2071 work_queue_add (bm
->process_main_queue
, pqnode
);
2072 SET_FLAG (rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2077 bgp_add_eoiu_mark (struct bgp
*bgp
)
2079 struct bgp_process_queue
*pqnode
;
2081 if (bm
->process_main_queue
== NULL
)
2082 bgp_process_queue_init ();
2084 pqnode
= XCALLOC (MTYPE_BGP_PROCESS_QUEUE
,
2085 sizeof (struct bgp_process_queue
));
2092 work_queue_add (bm
->process_main_queue
, pqnode
);
2096 bgp_maximum_prefix_restart_timer (struct thread
*thread
)
2100 peer
= THREAD_ARG (thread
);
2101 peer
->t_pmax_restart
= NULL
;
2103 if (bgp_debug_neighbor_events(peer
))
2104 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2107 peer_clear (peer
, NULL
);
2113 bgp_maximum_prefix_overflow (struct peer
*peer
, afi_t afi
,
2114 safi_t safi
, int always
)
2119 if (!CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2122 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
])
2124 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
)
2128 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2129 "limit %ld", afi_safi_print (afi
, safi
), peer
->host
,
2130 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2131 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2133 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
))
2136 /* Convert AFI, SAFI to values for packet. */
2137 pkt_afi
= afi_int2iana (afi
);
2138 pkt_safi
= safi_int2iana (safi
);
2142 ndata
[0] = (pkt_afi
>> 8);
2144 ndata
[2] = pkt_safi
;
2145 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2146 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2147 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2148 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2150 SET_FLAG (peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2151 bgp_notify_send_with_data (peer
, BGP_NOTIFY_CEASE
,
2152 BGP_NOTIFY_CEASE_MAX_PREFIX
, ndata
, 7);
2155 /* Dynamic peers will just close their connection. */
2156 if (peer_dynamic_neighbor (peer
))
2159 /* restart timer start */
2160 if (peer
->pmax_restart
[afi
][safi
])
2162 peer
->v_pmax_restart
= peer
->pmax_restart
[afi
][safi
] * 60;
2164 if (bgp_debug_neighbor_events(peer
))
2165 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2166 peer
->host
, peer
->v_pmax_restart
);
2168 BGP_TIMER_ON (peer
->t_pmax_restart
, bgp_maximum_prefix_restart_timer
,
2169 peer
->v_pmax_restart
);
2175 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2177 if (peer
->pcount
[afi
][safi
] > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100))
2179 if (CHECK_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
)
2183 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2184 afi_safi_print (afi
, safi
), peer
->host
, peer
->pcount
[afi
][safi
],
2185 peer
->pmax
[afi
][safi
]);
2186 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2189 UNSET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_THRESHOLD
);
2193 /* Unconditionally remove the route from the RIB, without taking
2194 * damping into consideration (eg, because the session went down)
2197 bgp_rib_remove (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2198 afi_t afi
, safi_t safi
)
2200 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2202 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2203 bgp_info_delete (rn
, ri
); /* keep historical info */
2205 bgp_process (peer
->bgp
, rn
, afi
, safi
);
2209 bgp_rib_withdraw (struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2210 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
)
2212 int status
= BGP_DAMP_NONE
;
2214 /* apply dampening, if result is suppressed, we'll be retaining
2215 * the bgp_info in the RIB for historical reference.
2217 if (CHECK_FLAG (peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2218 && peer
->sort
== BGP_PEER_EBGP
)
2219 if ( (status
= bgp_damp_withdraw (ri
, rn
, afi
, safi
, 0))
2220 == BGP_DAMP_SUPPRESSED
)
2222 bgp_aggregate_decrement (peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2227 if (safi
== SAFI_MPLS_VPN
) {
2228 struct bgp_node
*prn
= NULL
;
2229 struct bgp_table
*table
= NULL
;
2231 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2233 table
= (struct bgp_table
*)(prn
->info
);
2235 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2242 bgp_unlock_node(prn
);
2244 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2245 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2247 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2248 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
, ri
);
2252 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2255 static struct bgp_info
*
2256 info_make (int type
, int sub_type
, u_short instance
, struct peer
*peer
, struct attr
*attr
,
2257 struct bgp_node
*rn
)
2259 struct bgp_info
*new;
2261 /* Make new BGP info. */
2262 new = XCALLOC (MTYPE_BGP_ROUTE
, sizeof (struct bgp_info
));
2264 new->instance
= instance
;
2265 new->sub_type
= sub_type
;
2268 new->uptime
= bgp_clock ();
2270 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2275 overlay_index_update(struct attr
*attr
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2277 struct attr_extra
*extra
;
2281 extra
= bgp_attr_extra_get(attr
);
2283 if(eth_s_id
== NULL
)
2285 memset(&(extra
->evpn_overlay
.eth_s_id
),0, sizeof(struct eth_segment_id
));
2289 memcpy(&(extra
->evpn_overlay
.eth_s_id
), eth_s_id
, sizeof(struct eth_segment_id
));
2293 memset(&(extra
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2297 memcpy(&(extra
->evpn_overlay
.gw_ip
),gw_ip
, sizeof(union gw_addr
));
2302 overlay_index_equal(afi_t afi
, struct bgp_info
*info
, struct eth_segment_id
*eth_s_id
, union gw_addr
*gw_ip
)
2304 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2305 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2308 if(afi
!= AFI_L2VPN
)
2310 if (!info
->attr
|| !info
->attr
->extra
)
2312 memset(&temp
, 0, 16);
2313 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2314 info_gw_ip
= (union gw_addr
*)&temp
;
2315 if(eth_s_id
== NULL
&& gw_ip
== NULL
)
2320 info_eth_s_id
= &(info
->attr
->extra
->evpn_overlay
.eth_s_id
);
2321 info_gw_ip
= &(info
->attr
->extra
->evpn_overlay
.gw_ip
);
2324 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2326 info_gw_ip_remote
= gw_ip
;
2327 if(eth_s_id
== NULL
)
2328 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2330 info_eth_s_id_remote
= eth_s_id
;
2331 if(!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2333 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
, sizeof(struct eth_segment_id
));
2336 /* Check if received nexthop is valid or not. */
2338 bgp_update_martian_nexthop (struct bgp
*bgp
, afi_t afi
, safi_t safi
, struct attr
*attr
)
2340 struct attr_extra
*attre
= attr
->extra
;
2343 /* Only validated for unicast and multicast currently. */
2344 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
)
2347 /* If NEXT_HOP is present, validate it. */
2348 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
))
2350 if (attr
->nexthop
.s_addr
== 0 ||
2351 IPV4_CLASS_DE (ntohl (attr
->nexthop
.s_addr
)) ||
2352 bgp_nexthop_self (bgp
, attr
))
2356 /* If MP_NEXTHOP is present, validate it. */
2357 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2358 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2359 * it is not an IPv6 link-local address.
2361 if (attre
&& attre
->mp_nexthop_len
)
2363 switch (attre
->mp_nexthop_len
)
2365 case BGP_ATTR_NHLEN_IPV4
:
2366 case BGP_ATTR_NHLEN_VPNV4
:
2367 ret
= (attre
->mp_nexthop_global_in
.s_addr
== 0 ||
2368 IPV4_CLASS_DE (ntohl (attre
->mp_nexthop_global_in
.s_addr
)));
2371 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2372 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2373 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2374 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attre
->mp_nexthop_global
) ||
2375 IN6_IS_ADDR_LOOPBACK(&attre
->mp_nexthop_global
) ||
2376 IN6_IS_ADDR_MULTICAST(&attre
->mp_nexthop_global
));
2389 bgp_update (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2390 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2391 int sub_type
, struct prefix_rd
*prd
, u_char
*tag
,
2392 int soft_reconfig
, struct bgp_route_evpn
* evpn
)
2395 int aspath_loop_count
= 0;
2396 struct bgp_node
*rn
;
2398 struct attr new_attr
;
2399 struct attr_extra new_extra
;
2400 struct attr
*attr_new
;
2401 struct bgp_info
*ri
;
2402 struct bgp_info
*new;
2404 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2406 int do_loop_check
= 1;
2408 int vnc_implicit_withdraw
= 0;
2411 memset (&new_attr
, 0, sizeof(struct attr
));
2412 memset (&new_extra
, 0, sizeof(struct attr_extra
));
2415 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2417 /* When peer's soft reconfiguration enabled. Record input packet in
2419 if (! soft_reconfig
&& CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2420 && peer
!= bgp
->peer_self
)
2421 bgp_adj_in_set (rn
, peer
, attr
, addpath_id
);
2423 /* Check previously received route. */
2424 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2425 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2426 ri
->addpath_rx_id
== addpath_id
)
2429 /* AS path local-as loop check. */
2430 if (peer
->change_local_as
)
2432 if (! CHECK_FLAG (peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2433 aspath_loop_count
= 1;
2435 if (aspath_loop_check (attr
->aspath
, peer
->change_local_as
) > aspath_loop_count
)
2437 reason
= "as-path contains our own AS;";
2442 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2443 * as-path is our ASN then we do not need to call aspath_loop_check
2445 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2446 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2449 /* AS path loop check. */
2452 if (aspath_loop_check (attr
->aspath
, bgp
->as
) > peer
->allowas_in
[afi
][safi
]
2453 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2454 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
) > peer
->allowas_in
[afi
][safi
]))
2456 reason
= "as-path contains our own AS;";
2461 /* Route reflector originator ID check. */
2462 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
)
2463 && IPV4_ADDR_SAME (&bgp
->router_id
, &attr
->extra
->originator_id
))
2465 reason
= "originator is us;";
2469 /* Route reflector cluster ID check. */
2470 if (bgp_cluster_filter (peer
, attr
))
2472 reason
= "reflected from the same cluster;";
2476 /* Apply incoming filter. */
2477 if (bgp_input_filter (peer
, p
, attr
, afi
, safi
) == FILTER_DENY
)
2483 new_attr
.extra
= &new_extra
;
2484 bgp_attr_dup (&new_attr
, attr
);
2486 /* Apply incoming route-map.
2487 * NB: new_attr may now contain newly allocated values from route-map "set"
2488 * commands, so we need bgp_attr_flush in the error paths, until we intern
2489 * the attr (which takes over the memory references) */
2490 if (bgp_input_modifier (peer
, p
, &new_attr
, afi
, safi
, NULL
) == RMAP_DENY
)
2492 reason
= "route-map;";
2493 bgp_attr_flush (&new_attr
);
2497 /* next hop check. */
2498 if (bgp_update_martian_nexthop (bgp
, afi
, safi
, &new_attr
))
2500 reason
= "martian or self next-hop;";
2501 bgp_attr_flush (&new_attr
);
2505 attr_new
= bgp_attr_intern (&new_attr
);
2507 /* If the update is implicit withdraw. */
2510 ri
->uptime
= bgp_clock ();
2512 /* Same attribute comes in. */
2513 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
)
2514 && attrhash_cmp (ri
->attr
, attr_new
)
2515 && (overlay_index_equal(afi
, ri
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2516 evpn
==NULL
?NULL
:&evpn
->gw_ip
)))
2518 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2519 && peer
->sort
== BGP_PEER_EBGP
2520 && CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2522 if (bgp_debug_update(peer
, p
, NULL
, 1))
2523 zlog_debug ("%s rcvd %s", peer
->host
,
2524 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2525 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2527 if (bgp_damp_update (ri
, rn
, afi
, safi
) != BGP_DAMP_SUPPRESSED
)
2529 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2530 bgp_process (bgp
, rn
, afi
, safi
);
2533 else /* Duplicate - odd */
2535 if (bgp_debug_update(peer
, p
, NULL
, 1))
2537 if (!peer
->rcvd_attr_printed
)
2539 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2540 peer
->rcvd_attr_printed
= 1;
2543 zlog_debug ("%s rcvd %s...duplicate ignored",
2545 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
?
2546 1 : 0, addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2549 /* graceful restart STALE flag unset. */
2550 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2552 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2553 bgp_process (bgp
, rn
, afi
, safi
);
2557 bgp_unlock_node (rn
);
2558 bgp_attr_unintern (&attr_new
);
2563 /* Withdraw/Announce before we fully processed the withdraw */
2564 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
2566 if (bgp_debug_update(peer
, p
, NULL
, 1))
2567 zlog_debug ("%s rcvd %s, flapped quicker than processing",
2569 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2570 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2571 bgp_info_restore (rn
, ri
);
2574 /* Received Logging. */
2575 if (bgp_debug_update(peer
, p
, NULL
, 1))
2576 zlog_debug ("%s rcvd %s", peer
->host
,
2577 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2578 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2580 /* graceful restart STALE flag unset. */
2581 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
2582 bgp_info_unset_flag (rn
, ri
, BGP_INFO_STALE
);
2584 /* The attribute is changed. */
2585 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2587 /* implicit withdraw, decrement aggregate and pcount here.
2588 * only if update is accepted, they'll increment below.
2590 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
2592 /* Update bgp route dampening information. */
2593 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2594 && peer
->sort
== BGP_PEER_EBGP
)
2596 /* This is implicit withdraw so we should update dampening
2598 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2599 bgp_damp_withdraw (ri
, rn
, afi
, safi
, 1);
2602 if (safi
== SAFI_MPLS_VPN
) {
2603 struct bgp_node
*prn
= NULL
;
2604 struct bgp_table
*table
= NULL
;
2606 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2608 table
= (struct bgp_table
*)(prn
->info
);
2610 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2617 bgp_unlock_node(prn
);
2619 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2620 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) {
2622 * Implicit withdraw case.
2624 ++vnc_implicit_withdraw
;
2625 vnc_import_bgp_del_route(bgp
, p
, ri
);
2626 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2631 /* Update to new attribute. */
2632 bgp_attr_unintern (&ri
->attr
);
2633 ri
->attr
= attr_new
;
2635 /* Update MPLS tag. */
2636 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2637 memcpy ((bgp_info_extra_get (ri
))->tag
, tag
, 3);
2640 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
2642 if (vnc_implicit_withdraw
)
2645 * Add back the route with its new attributes (e.g., nexthop).
2646 * The route is still selected, until the route selection
2647 * queued by bgp_process actually runs. We have to make this
2648 * update to the VNC side immediately to avoid racing against
2649 * configuration changes (e.g., route-map changes) which
2650 * trigger re-importation of the entire RIB.
2652 vnc_import_bgp_add_route(bgp
, p
, ri
);
2653 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
2657 /* Update Overlay Index */
2658 if(afi
== AFI_L2VPN
)
2660 overlay_index_update(ri
->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2661 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2664 /* Update bgp route dampening information. */
2665 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2666 && peer
->sort
== BGP_PEER_EBGP
)
2668 /* Now we do normal update dampening. */
2669 ret
= bgp_damp_update (ri
, rn
, afi
, safi
);
2670 if (ret
== BGP_DAMP_SUPPRESSED
)
2672 bgp_unlock_node (rn
);
2677 /* Nexthop reachability check. */
2678 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2680 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2681 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2682 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2687 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, connected
))
2688 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2691 if (BGP_DEBUG(nht
, NHT
))
2693 char buf1
[INET6_ADDRSTRLEN
];
2694 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2695 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2697 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
2701 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
2704 if (safi
== SAFI_MPLS_VPN
)
2706 struct bgp_node
*prn
= NULL
;
2707 struct bgp_table
*table
= NULL
;
2709 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2712 table
= (struct bgp_table
*)(prn
->info
);
2714 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2721 bgp_unlock_node(prn
);
2725 /* Process change. */
2726 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
2728 bgp_process (bgp
, rn
, afi
, safi
);
2729 bgp_unlock_node (rn
);
2732 if (SAFI_MPLS_VPN
== safi
)
2734 uint32_t label
= decode_label(tag
);
2736 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2739 if (SAFI_ENCAP
== safi
)
2741 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2747 } // End of implicit withdraw
2749 /* Received Logging. */
2750 if (bgp_debug_update(peer
, p
, NULL
, 1))
2752 if (!peer
->rcvd_attr_printed
)
2754 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2755 peer
->rcvd_attr_printed
= 1;
2758 zlog_debug ("%s rcvd %s", peer
->host
,
2759 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2760 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2763 /* Make new BGP info. */
2764 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
2766 /* Update MPLS tag. */
2767 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_EVPN
)
2768 memcpy ((bgp_info_extra_get (new))->tag
, tag
, 3);
2770 /* Update Overlay Index */
2771 if(afi
== AFI_L2VPN
)
2773 overlay_index_update(new->attr
, evpn
==NULL
?NULL
:&evpn
->eth_s_id
,
2774 evpn
==NULL
?NULL
:&evpn
->gw_ip
);
2776 /* Nexthop reachability check. */
2777 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && safi
== SAFI_UNICAST
)
2779 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1 &&
2780 ! CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
2781 && ! bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
2786 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, connected
))
2787 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2790 if (BGP_DEBUG(nht
, NHT
))
2792 char buf1
[INET6_ADDRSTRLEN
];
2793 inet_ntop(AF_INET
, (const void *)&attr_new
->nexthop
, buf1
, INET6_ADDRSTRLEN
);
2794 zlog_debug("%s(%s): NH unresolved", __FUNCTION__
, buf1
);
2796 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
2800 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
2803 new->addpath_rx_id
= addpath_id
;
2805 /* Increment prefix */
2806 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
2808 /* Register new BGP information. */
2809 bgp_info_add (rn
, new);
2811 /* route_node_get lock */
2812 bgp_unlock_node (rn
);
2815 if (safi
== SAFI_MPLS_VPN
)
2817 struct bgp_node
*prn
= NULL
;
2818 struct bgp_table
*table
= NULL
;
2820 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*) prd
);
2823 table
= (struct bgp_table
*)(prn
->info
);
2825 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2832 bgp_unlock_node(prn
);
2836 /* If maximum prefix count is configured and current prefix
2838 if (bgp_maximum_prefix_overflow (peer
, afi
, safi
, 0))
2841 /* Process change. */
2842 bgp_process (bgp
, rn
, afi
, safi
);
2845 if (SAFI_MPLS_VPN
== safi
)
2847 uint32_t label
= decode_label(tag
);
2849 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2852 if (SAFI_ENCAP
== safi
)
2854 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
, sub_type
,
2861 /* This BGP update is filtered. Log the reason then update BGP
2864 if (bgp_debug_update(peer
, p
, NULL
, 1))
2866 if (!peer
->rcvd_attr_printed
)
2868 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer
->host
, peer
->rcvd_attr_str
);
2869 peer
->rcvd_attr_printed
= 1;
2872 zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
2874 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2875 addpath_id
, pfx_buf
, sizeof (pfx_buf
)), reason
);
2879 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
2881 bgp_unlock_node (rn
);
2885 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2886 * a few lines above)
2888 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2890 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2898 bgp_withdraw (struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2899 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
, int sub_type
,
2900 struct prefix_rd
*prd
, u_char
*tag
, struct bgp_route_evpn
*evpn
)
2903 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2904 struct bgp_node
*rn
;
2905 struct bgp_info
*ri
;
2908 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
))
2910 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
, 0);
2917 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2919 /* If peer is soft reconfiguration enabled. Record input packet for
2920 * further calculation.
2922 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
2923 * routes that are filtered. This tanks out Quagga RS pretty badly due to
2924 * the iteration over all RS clients.
2925 * Since we need to remove the entry from adj_in anyway, do that first and
2926 * if there was no entry, we don't need to do anything more.
2928 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2929 && peer
!= bgp
->peer_self
)
2930 if (!bgp_adj_in_unset (rn
, peer
, addpath_id
))
2932 if (bgp_debug_update (peer
, p
, NULL
, 1))
2933 zlog_debug ("%s withdrawing route %s not in adj-in",
2935 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2936 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2937 bgp_unlock_node (rn
);
2941 /* Lookup withdrawn route. */
2942 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2943 if (ri
->peer
== peer
&& ri
->type
== type
&& ri
->sub_type
== sub_type
&&
2944 ri
->addpath_rx_id
== addpath_id
)
2948 if (bgp_debug_update(peer
, p
, NULL
, 1))
2950 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
2952 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2953 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2956 /* Withdraw specified route from routing table. */
2957 if (ri
&& ! CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
2958 bgp_rib_withdraw (rn
, ri
, peer
, afi
, safi
, prd
);
2959 else if (bgp_debug_update(peer
, p
, NULL
, 1))
2960 zlog_debug ("%s Can't find the route %s",
2962 bgp_debug_rdpfxpath2str (prd
, p
, addpath_id
? 1 : 0,
2963 addpath_id
, pfx_buf
, sizeof (pfx_buf
)));
2965 /* Unlock bgp_node_get() lock. */
2966 bgp_unlock_node (rn
);
2972 bgp_default_originate (struct peer
*peer
, afi_t afi
, safi_t safi
, int withdraw
)
2974 struct update_subgroup
*subgrp
;
2975 subgrp
= peer_subgroup(peer
, afi
, safi
);
2976 subgroup_default_originate(subgrp
, withdraw
);
2981 * bgp_stop_announce_route_timer
2984 bgp_stop_announce_route_timer (struct peer_af
*paf
)
2986 if (!paf
->t_announce_route
)
2989 THREAD_TIMER_OFF (paf
->t_announce_route
);
2993 * bgp_announce_route_timer_expired
2995 * Callback that is invoked when the route announcement timer for a
2999 bgp_announce_route_timer_expired (struct thread
*t
)
3001 struct peer_af
*paf
;
3004 paf
= THREAD_ARG (t
);
3007 assert (paf
->t_announce_route
);
3008 paf
->t_announce_route
= NULL
;
3010 if (peer
->status
!= Established
)
3013 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3016 peer_af_announce_route (paf
, 1);
3021 * bgp_announce_route
3023 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3026 bgp_announce_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3028 struct peer_af
*paf
;
3029 struct update_subgroup
*subgrp
;
3031 paf
= peer_af_find (peer
, afi
, safi
);
3034 subgrp
= PAF_SUBGRP(paf
);
3037 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3038 * or a refresh has already been triggered.
3040 if (!subgrp
|| paf
->t_announce_route
)
3044 * Start a timer to stagger/delay the announce. This serves
3045 * two purposes - announcement can potentially be combined for
3046 * multiple peers and the announcement doesn't happen in the
3049 THREAD_TIMER_MSEC_ON (bm
->master
, paf
->t_announce_route
,
3050 bgp_announce_route_timer_expired
, paf
,
3051 (subgrp
->peer_count
== 1) ?
3052 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
:
3053 BGP_ANNOUNCE_ROUTE_DELAY_MS
);
3057 * Announce routes from all AF tables to a peer.
3059 * This should ONLY be called when there is a need to refresh the
3060 * routes to the peer based on a policy change for this peer alone
3061 * or a route refresh request received from the peer.
3062 * The operation will result in splitting the peer from its existing
3063 * subgroups and putting it in new subgroups.
3066 bgp_announce_route_all (struct peer
*peer
)
3071 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3072 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3073 bgp_announce_route (peer
, afi
, safi
);
3077 bgp_soft_reconfig_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3078 struct bgp_table
*table
, struct prefix_rd
*prd
)
3081 struct bgp_node
*rn
;
3082 struct bgp_adj_in
*ain
;
3085 table
= peer
->bgp
->rib
[afi
][safi
];
3087 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3088 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
3090 if (ain
->peer
== peer
)
3092 struct bgp_info
*ri
= rn
->info
;
3093 u_char
*tag
= (ri
&& ri
->extra
) ? ri
->extra
->tag
: NULL
;
3095 ret
= bgp_update (peer
, &rn
->p
, ain
->addpath_rx_id
, ain
->attr
,
3096 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3101 bgp_unlock_node (rn
);
3109 bgp_soft_reconfig_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3111 struct bgp_node
*rn
;
3112 struct bgp_table
*table
;
3114 if (peer
->status
!= Established
)
3117 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
) && (safi
!= SAFI_EVPN
))
3118 bgp_soft_reconfig_table (peer
, afi
, safi
, NULL
, NULL
);
3120 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3121 rn
= bgp_route_next (rn
))
3122 if ((table
= rn
->info
) != NULL
)
3124 struct prefix_rd prd
;
3125 prd
.family
= AF_UNSPEC
;
3127 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3129 bgp_soft_reconfig_table (peer
, afi
, safi
, table
, &prd
);
3134 struct bgp_clear_node_queue
3136 struct bgp_node
*rn
;
3139 static wq_item_status
3140 bgp_clear_route_node (struct work_queue
*wq
, void *data
)
3142 struct bgp_clear_node_queue
*cnq
= data
;
3143 struct bgp_node
*rn
= cnq
->rn
;
3144 struct peer
*peer
= wq
->spec
.data
;
3145 struct bgp_info
*ri
;
3146 afi_t afi
= bgp_node_table (rn
)->afi
;
3147 safi_t safi
= bgp_node_table (rn
)->safi
;
3149 assert (rn
&& peer
);
3151 /* It is possible that we have multiple paths for a prefix from a peer
3152 * if that peer is using AddPath.
3154 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3155 if (ri
->peer
== peer
)
3157 /* graceful restart STALE flag set. */
3158 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3159 && peer
->nsf
[afi
][safi
]
3160 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
)
3161 && ! CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
3162 bgp_info_set_flag (rn
, ri
, BGP_INFO_STALE
);
3164 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3170 bgp_clear_node_queue_del (struct work_queue
*wq
, void *data
)
3172 struct bgp_clear_node_queue
*cnq
= data
;
3173 struct bgp_node
*rn
= cnq
->rn
;
3174 struct bgp_table
*table
= bgp_node_table (rn
);
3176 bgp_unlock_node (rn
);
3177 bgp_table_unlock (table
);
3178 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3182 bgp_clear_node_complete (struct work_queue
*wq
)
3184 struct peer
*peer
= wq
->spec
.data
;
3186 /* Tickle FSM to start moving again */
3187 BGP_EVENT_ADD (peer
, Clearing_Completed
);
3189 peer_unlock (peer
); /* bgp_clear_route */
3193 bgp_clear_node_queue_init (struct peer
*peer
)
3195 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3197 snprintf (wname
, sizeof(wname
), "clear %s", peer
->host
);
3198 #undef CLEAR_QUEUE_NAME_LEN
3200 if ( (peer
->clear_node_queue
= work_queue_new (bm
->master
, wname
)) == NULL
)
3202 zlog_err ("%s: Failed to allocate work queue", __func__
);
3205 peer
->clear_node_queue
->spec
.hold
= 10;
3206 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3207 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3208 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3209 peer
->clear_node_queue
->spec
.max_retries
= 0;
3211 /* we only 'lock' this peer reference when the queue is actually active */
3212 peer
->clear_node_queue
->spec
.data
= peer
;
3216 bgp_clear_route_table (struct peer
*peer
, afi_t afi
, safi_t safi
,
3217 struct bgp_table
*table
)
3219 struct bgp_node
*rn
;
3220 int force
= bm
->process_main_queue
? 0 : 1;
3223 table
= peer
->bgp
->rib
[afi
][safi
];
3225 /* If still no table => afi/safi isn't configured at all or smth. */
3229 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3231 struct bgp_info
*ri
, *next
;
3232 struct bgp_adj_in
*ain
;
3233 struct bgp_adj_in
*ain_next
;
3235 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3236 * queued for every clearing peer, regardless of whether it is
3237 * relevant to the peer at hand.
3239 * Overview: There are 3 different indices which need to be
3240 * scrubbed, potentially, when a peer is removed:
3242 * 1 peer's routes visible via the RIB (ie accepted routes)
3243 * 2 peer's routes visible by the (optional) peer's adj-in index
3244 * 3 other routes visible by the peer's adj-out index
3246 * 3 there is no hurry in scrubbing, once the struct peer is
3247 * removed from bgp->peer, we could just GC such deleted peer's
3248 * adj-outs at our leisure.
3250 * 1 and 2 must be 'scrubbed' in some way, at least made
3251 * invisible via RIB index before peer session is allowed to be
3252 * brought back up. So one needs to know when such a 'search' is
3257 * - there'd be a single global queue or a single RIB walker
3258 * - rather than tracking which route_nodes still need to be
3259 * examined on a peer basis, we'd track which peers still
3262 * Given that our per-peer prefix-counts now should be reliable,
3263 * this may actually be achievable. It doesn't seem to be a huge
3264 * problem at this time,
3266 * It is possible that we have multiple paths for a prefix from a peer
3267 * if that peer is using AddPath.
3272 ain_next
= ain
->next
;
3274 if (ain
->peer
== peer
)
3276 bgp_adj_in_remove (rn
, ain
);
3277 bgp_unlock_node (rn
);
3283 for (ri
= rn
->info
; ri
; ri
= next
)
3286 if (ri
->peer
!= peer
)
3290 bgp_info_reap (rn
, ri
);
3293 struct bgp_clear_node_queue
*cnq
;
3295 /* both unlocked in bgp_clear_node_queue_del */
3296 bgp_table_lock (bgp_node_table (rn
));
3298 cnq
= XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE
,
3299 sizeof (struct bgp_clear_node_queue
));
3301 work_queue_add (peer
->clear_node_queue
, cnq
);
3310 bgp_clear_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3312 struct bgp_node
*rn
;
3313 struct bgp_table
*table
;
3315 if (peer
->clear_node_queue
== NULL
)
3316 bgp_clear_node_queue_init (peer
);
3318 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3319 * Idle until it receives a Clearing_Completed event. This protects
3320 * against peers which flap faster than we can we clear, which could
3323 * a) race with routes from the new session being installed before
3324 * clear_route_node visits the node (to delete the route of that
3326 * b) resource exhaustion, clear_route_node likely leads to an entry
3327 * on the process_main queue. Fast-flapping could cause that queue
3331 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3332 * the unlock will happen upon work-queue completion; other wise, the
3333 * unlock happens at the end of this function.
3335 if (!peer
->clear_node_queue
->thread
)
3338 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3339 bgp_clear_route_table (peer
, afi
, safi
, NULL
);
3341 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
;
3342 rn
= bgp_route_next (rn
))
3343 if ((table
= rn
->info
) != NULL
)
3344 bgp_clear_route_table (peer
, afi
, safi
, table
);
3346 /* unlock if no nodes got added to the clear-node-queue. */
3347 if (!peer
->clear_node_queue
->thread
)
3353 bgp_clear_route_all (struct peer
*peer
)
3358 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3359 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3360 bgp_clear_route (peer
, afi
, safi
);
3363 rfapiProcessPeerDown(peer
);
3368 bgp_clear_adj_in (struct peer
*peer
, afi_t afi
, safi_t safi
)
3370 struct bgp_table
*table
;
3371 struct bgp_node
*rn
;
3372 struct bgp_adj_in
*ain
;
3373 struct bgp_adj_in
*ain_next
;
3375 table
= peer
->bgp
->rib
[afi
][safi
];
3377 /* It is possible that we have multiple paths for a prefix from a peer
3378 * if that peer is using AddPath.
3380 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3386 ain_next
= ain
->next
;
3388 if (ain
->peer
== peer
)
3390 bgp_adj_in_remove (rn
, ain
);
3391 bgp_unlock_node (rn
);
3400 bgp_clear_stale_route (struct peer
*peer
, afi_t afi
, safi_t safi
)
3402 struct bgp_node
*rn
;
3403 struct bgp_info
*ri
;
3404 struct bgp_table
*table
;
3406 if ( safi
== SAFI_MPLS_VPN
)
3408 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3410 struct bgp_node
*rm
;
3411 struct bgp_info
*ri
;
3413 /* look for neighbor in tables */
3414 if ((table
= rn
->info
) != NULL
)
3416 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
3417 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3418 if (ri
->peer
== peer
)
3420 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3421 bgp_rib_remove (rm
, ri
, peer
, afi
, safi
);
3429 for (rn
= bgp_table_top (peer
->bgp
->rib
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
3430 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3431 if (ri
->peer
== peer
)
3433 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
3434 bgp_rib_remove (rn
, ri
, peer
, afi
, safi
);
3441 bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3443 struct bgp_node
*rn
;
3444 struct bgp_info
*ri
;
3445 struct bgp_info
*next
;
3447 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
3448 for (ri
= rn
->info
; ri
; ri
= next
)
3451 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
3452 && ri
->type
== ZEBRA_ROUTE_BGP
3453 && (ri
->sub_type
== BGP_ROUTE_NORMAL
||
3454 ri
->sub_type
== BGP_ROUTE_AGGREGATE
))
3457 if (table
->owner
&& table
->owner
->bgp
)
3458 vnc_import_bgp_del_route(table
->owner
->bgp
, &rn
->p
, ri
);
3460 bgp_zebra_withdraw (&rn
->p
, ri
, safi
);
3461 bgp_info_reap (rn
, ri
);
3466 /* Delete all kernel routes. */
3468 bgp_cleanup_routes (struct bgp
*bgp
)
3471 struct bgp_node
*rn
;
3473 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
)
3475 if (afi
== AFI_L2VPN
)
3477 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3479 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3481 if (afi
!= AFI_L2VPN
)
3484 safi
= SAFI_MPLS_VPN
;
3485 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3486 rn
= bgp_route_next (rn
))
3490 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3491 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3493 bgp_unlock_node(rn
);
3497 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3498 rn
= bgp_route_next (rn
))
3502 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), safi
);
3503 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3505 bgp_unlock_node(rn
);
3510 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3511 rn
= bgp_route_next (rn
))
3515 bgp_cleanup_table((struct bgp_table
*)(rn
->info
), SAFI_EVPN
);
3516 bgp_table_finish ((struct bgp_table
**)&(rn
->info
));
3518 bgp_unlock_node(rn
);
3527 bgp_zclient_reset ();
3528 access_list_reset ();
3529 prefix_list_reset ();
3533 bgp_addpath_encode_rx (struct peer
*peer
, afi_t afi
, safi_t safi
)
3535 return (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
3536 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
3539 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3542 bgp_nlri_parse_ip (struct peer
*peer
, struct attr
*attr
,
3543 struct bgp_nlri
*packet
)
3552 int addpath_encoded
;
3553 u_int32_t addpath_id
;
3555 /* Check peer status. */
3556 if (peer
->status
!= Established
)
3560 lim
= pnt
+ packet
->length
;
3562 safi
= packet
->safi
;
3564 addpath_encoded
= bgp_addpath_encode_rx (peer
, afi
, safi
);
3566 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3567 syntactic validity. If the field is syntactically incorrect,
3568 then the Error Subcode is set to Invalid Network Field. */
3569 for (; pnt
< lim
; pnt
+= psize
)
3571 /* Clear prefix structure. */
3572 memset (&p
, 0, sizeof (struct prefix
));
3574 if (addpath_encoded
)
3577 /* When packet overflow occurs return immediately. */
3578 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3581 addpath_id
= ntohl(*((uint32_t*) pnt
));
3582 pnt
+= BGP_ADDPATH_ID_LEN
;
3585 /* Fetch prefix length. */
3586 p
.prefixlen
= *pnt
++;
3587 /* afi/safi validity already verified by caller, bgp_update_receive */
3588 p
.family
= afi2family (afi
);
3590 /* Prefix length check. */
3591 if (p
.prefixlen
> prefix_blen (&p
) * 8)
3593 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3594 peer
->host
, p
.prefixlen
, packet
->afi
);
3598 /* Packet size overflow check. */
3599 psize
= PSIZE (p
.prefixlen
);
3601 /* When packet overflow occur return immediately. */
3602 if (pnt
+ psize
> lim
)
3604 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3605 peer
->host
, p
.prefixlen
);
3609 /* Defensive coding, double-check the psize fits in a struct prefix */
3610 if (psize
> (ssize_t
) sizeof(p
.u
))
3612 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3613 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3617 /* Fetch prefix from NLRI packet. */
3618 memcpy (&p
.u
.prefix
, pnt
, psize
);
3620 /* Check address. */
3621 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
3623 if (IN_CLASSD (ntohl (p
.u
.prefix4
.s_addr
)))
3625 /* From RFC4271 Section 6.3:
3627 * If a prefix in the NLRI field is semantically incorrect
3628 * (e.g., an unexpected multicast IP address), an error SHOULD
3629 * be logged locally, and the prefix SHOULD be ignored.
3631 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3632 peer
->host
, inet_ntoa (p
.u
.prefix4
));
3637 /* Check address. */
3638 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
3640 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
3644 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3645 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3649 if (IN6_IS_ADDR_MULTICAST (&p
.u
.prefix6
))
3653 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3654 peer
->host
, inet_ntop (AF_INET6
, &p
.u
.prefix6
, buf
, BUFSIZ
));
3660 /* Normal process. */
3662 ret
= bgp_update (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3663 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, 0, NULL
);
3665 ret
= bgp_withdraw (peer
, &p
, addpath_id
, attr
, afi
, safi
,
3666 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
3668 /* Address family configuration mismatch or maximum-prefix count
3674 /* Packet length consistency check. */
3677 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3685 static struct bgp_static
*
3686 bgp_static_new (void)
3688 return XCALLOC (MTYPE_BGP_STATIC
, sizeof (struct bgp_static
));
3692 bgp_static_free (struct bgp_static
*bgp_static
)
3694 if (bgp_static
->rmap
.name
)
3695 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
3696 if(bgp_static
->eth_s_id
)
3697 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
3698 XFREE (MTYPE_BGP_STATIC
, bgp_static
);
3702 bgp_static_update_main (struct bgp
*bgp
, struct prefix
*p
,
3703 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3705 struct bgp_node
*rn
;
3706 struct bgp_info
*ri
;
3707 struct bgp_info
*new;
3708 struct bgp_info info
;
3710 struct attr
*attr_new
;
3713 int vnc_implicit_withdraw
= 0;
3716 assert (bgp_static
);
3720 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3722 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
3724 attr
.nexthop
= bgp_static
->igpnexthop
;
3725 attr
.med
= bgp_static
->igpmetric
;
3726 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
3728 if (bgp_static
->atomic
)
3729 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
3731 /* Apply route-map. */
3732 if (bgp_static
->rmap
.name
)
3734 struct attr attr_tmp
= attr
;
3735 info
.peer
= bgp
->peer_self
;
3736 info
.attr
= &attr_tmp
;
3738 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
3740 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
3742 bgp
->peer_self
->rmap_type
= 0;
3744 if (ret
== RMAP_DENYMATCH
)
3746 /* Free uninterned attribute. */
3747 bgp_attr_flush (&attr_tmp
);
3749 /* Unintern original. */
3750 aspath_unintern (&attr
.aspath
);
3751 bgp_attr_extra_free (&attr
);
3752 bgp_static_withdraw (bgp
, p
, afi
, safi
);
3755 attr_new
= bgp_attr_intern (&attr_tmp
);
3758 attr_new
= bgp_attr_intern (&attr
);
3760 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3761 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
3762 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3767 if (attrhash_cmp (ri
->attr
, attr_new
) &&
3768 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
) &&
3769 !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
))
3771 bgp_unlock_node (rn
);
3772 bgp_attr_unintern (&attr_new
);
3773 aspath_unintern (&attr
.aspath
);
3774 bgp_attr_extra_free (&attr
);
3779 /* The attribute is changed. */
3780 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3782 /* Rewrite BGP route information. */
3783 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
3784 bgp_info_restore(rn
, ri
);
3786 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3788 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3790 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
3793 * Implicit withdraw case.
3794 * We have to do this before ri is changed
3796 ++vnc_implicit_withdraw
;
3797 vnc_import_bgp_del_route(bgp
, p
, ri
);
3798 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3802 bgp_attr_unintern (&ri
->attr
);
3803 ri
->attr
= attr_new
;
3804 ri
->uptime
= bgp_clock ();
3806 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
))
3808 if (vnc_implicit_withdraw
)
3810 vnc_import_bgp_add_route(bgp
, p
, ri
);
3811 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3816 /* Nexthop reachability check. */
3817 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3819 if (bgp_find_or_add_nexthop (bgp
, afi
, ri
, NULL
, 0))
3820 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3823 if (BGP_DEBUG(nht
, NHT
))
3825 char buf1
[INET6_ADDRSTRLEN
];
3826 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3828 zlog_debug("%s(%s): Route not in table, not advertising",
3829 __FUNCTION__
, buf1
);
3831 bgp_info_unset_flag (rn
, ri
, BGP_INFO_VALID
);
3836 /* Delete the NHT structure if any, if we're toggling between
3837 * enabling/disabling import check. We deregister the route
3838 * from NHT to avoid overloading NHT and the process interaction
3840 bgp_unlink_nexthop(ri
);
3841 bgp_info_set_flag (rn
, ri
, BGP_INFO_VALID
);
3843 /* Process change. */
3844 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
3845 bgp_process (bgp
, rn
, afi
, safi
);
3846 bgp_unlock_node (rn
);
3847 aspath_unintern (&attr
.aspath
);
3848 bgp_attr_extra_free (&attr
);
3853 /* Make new BGP info. */
3854 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
3856 /* Nexthop reachability check. */
3857 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
))
3859 if (bgp_find_or_add_nexthop (bgp
, afi
, new, NULL
, 0))
3860 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3863 if (BGP_DEBUG(nht
, NHT
))
3865 char buf1
[INET6_ADDRSTRLEN
];
3866 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
3868 zlog_debug("%s(%s): Route not in table, not advertising",
3869 __FUNCTION__
, buf1
);
3871 bgp_info_unset_flag (rn
, new, BGP_INFO_VALID
);
3876 /* Delete the NHT structure if any, if we're toggling between
3877 * enabling/disabling import check. We deregister the route
3878 * from NHT to avoid overloading NHT and the process interaction
3880 bgp_unlink_nexthop(new);
3882 bgp_info_set_flag (rn
, new, BGP_INFO_VALID
);
3885 /* Aggregate address increment. */
3886 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
3888 /* Register new BGP information. */
3889 bgp_info_add (rn
, new);
3891 /* route_node_get lock */
3892 bgp_unlock_node (rn
);
3894 /* Process change. */
3895 bgp_process (bgp
, rn
, afi
, safi
);
3897 /* Unintern original. */
3898 aspath_unintern (&attr
.aspath
);
3899 bgp_attr_extra_free (&attr
);
3903 bgp_static_update (struct bgp
*bgp
, struct prefix
*p
,
3904 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3906 bgp_static_update_main (bgp
, p
, bgp_static
, afi
, safi
);
3910 bgp_static_withdraw (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3913 struct bgp_node
*rn
;
3914 struct bgp_info
*ri
;
3916 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
3918 /* Check selected route and self inserted route. */
3919 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3920 if (ri
->peer
== bgp
->peer_self
3921 && ri
->type
== ZEBRA_ROUTE_BGP
3922 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3925 /* Withdraw static BGP route from routing table. */
3928 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3929 bgp_unlink_nexthop(ri
);
3930 bgp_info_delete (rn
, ri
);
3931 bgp_process (bgp
, rn
, afi
, safi
);
3934 /* Unlock bgp_node_lookup. */
3935 bgp_unlock_node (rn
);
3939 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
3942 bgp_static_withdraw_safi (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
3943 safi_t safi
, struct prefix_rd
*prd
, u_char
*tag
)
3945 struct bgp_node
*rn
;
3946 struct bgp_info
*ri
;
3948 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3950 /* Check selected route and self inserted route. */
3951 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3952 if (ri
->peer
== bgp
->peer_self
3953 && ri
->type
== ZEBRA_ROUTE_BGP
3954 && ri
->sub_type
== BGP_ROUTE_STATIC
)
3957 /* Withdraw static BGP route from routing table. */
3961 rfapiProcessWithdraw(
3970 1); /* Kill, since it is an administrative change */
3972 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
3973 bgp_info_delete (rn
, ri
);
3974 bgp_process (bgp
, rn
, afi
, safi
);
3977 /* Unlock bgp_node_lookup. */
3978 bgp_unlock_node (rn
);
3982 bgp_static_update_safi (struct bgp
*bgp
, struct prefix
*p
,
3983 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
3985 struct bgp_node
*rn
;
3986 struct bgp_info
*new;
3987 struct attr
*attr_new
;
3988 struct attr attr
= { 0 };
3989 struct bgp_info
*ri
;
3991 u_int32_t label
= 0;
3994 assert (bgp_static
);
3996 rn
= bgp_afi_node_get (bgp
->rib
[afi
][safi
], afi
, safi
, p
, &bgp_static
->prd
);
3998 bgp_attr_default_set (&attr
, BGP_ORIGIN_IGP
);
4000 attr
.nexthop
= bgp_static
->igpnexthop
;
4001 attr
.med
= bgp_static
->igpmetric
;
4002 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
4004 if(afi
== AFI_L2VPN
)
4005 overlay_index_update(&attr
, bgp_static
->eth_s_id
, NULL
);
4006 /* Apply route-map. */
4007 if (bgp_static
->rmap
.name
)
4009 struct attr attr_tmp
= attr
;
4010 struct bgp_info info
;
4013 info
.peer
= bgp
->peer_self
;
4014 info
.attr
= &attr_tmp
;
4016 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4018 ret
= route_map_apply (bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4020 bgp
->peer_self
->rmap_type
= 0;
4022 if (ret
== RMAP_DENYMATCH
)
4024 /* Free uninterned attribute. */
4025 bgp_attr_flush (&attr_tmp
);
4027 /* Unintern original. */
4028 aspath_unintern (&attr
.aspath
);
4029 bgp_attr_extra_free (&attr
);
4030 bgp_static_withdraw_safi (bgp
, p
, afi
, safi
, &bgp_static
->prd
,
4035 attr_new
= bgp_attr_intern (&attr_tmp
);
4039 attr_new
= bgp_attr_intern (&attr
);
4042 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4043 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4044 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4050 memset(&add
, 0, sizeof(union gw_addr
));
4051 if (attrhash_cmp (ri
->attr
, attr_new
) &&
4052 overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
) &&
4053 !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4055 bgp_unlock_node (rn
);
4056 bgp_attr_unintern (&attr_new
);
4057 aspath_unintern (&attr
.aspath
);
4058 bgp_attr_extra_free (&attr
);
4063 /* The attribute is changed. */
4064 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4066 /* Rewrite BGP route information. */
4067 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4068 bgp_info_restore(rn
, ri
);
4070 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, safi
);
4071 bgp_attr_unintern (&ri
->attr
);
4072 ri
->attr
= attr_new
;
4073 ri
->uptime
= bgp_clock ();
4076 label
= decode_label (ri
->extra
->tag
);
4079 /* Process change. */
4080 bgp_aggregate_increment (bgp
, p
, ri
, afi
, safi
);
4081 bgp_process (bgp
, rn
, afi
, safi
);
4083 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4084 ri
->attr
, afi
, safi
,
4085 ri
->type
, ri
->sub_type
, &label
);
4087 bgp_unlock_node (rn
);
4088 aspath_unintern (&attr
.aspath
);
4089 bgp_attr_extra_free (&attr
);
4095 /* Make new BGP info. */
4096 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
, attr_new
,
4098 SET_FLAG (new->flags
, BGP_INFO_VALID
);
4099 new->extra
= bgp_info_extra_new();
4100 memcpy (new->extra
->tag
, bgp_static
->tag
, 3);
4102 label
= decode_label (bgp_static
->tag
);
4105 /* Aggregate address increment. */
4106 bgp_aggregate_increment (bgp
, p
, new, afi
, safi
);
4108 /* Register new BGP information. */
4109 bgp_info_add (rn
, new);
4111 /* route_node_get lock */
4112 bgp_unlock_node (rn
);
4114 /* Process change. */
4115 bgp_process (bgp
, rn
, afi
, safi
);
4118 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
,
4119 new->attr
, afi
, safi
,
4120 new->type
, new->sub_type
, &label
);
4123 /* Unintern original. */
4124 aspath_unintern (&attr
.aspath
);
4125 bgp_attr_extra_free (&attr
);
4128 /* Configure static BGP network. When user don't run zebra, static
4129 route should be installed as valid. */
4131 bgp_static_set (struct vty
*vty
, const char *ip_str
,
4132 afi_t afi
, safi_t safi
, const char *rmap
, int backdoor
)
4134 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4137 struct bgp_static
*bgp_static
;
4138 struct bgp_node
*rn
;
4139 u_char need_update
= 0;
4141 /* Convert IP prefix string to struct prefix. */
4142 ret
= str2prefix (ip_str
, &p
);
4145 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4148 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4150 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4157 /* Set BGP static route configuration. */
4158 rn
= bgp_node_get (bgp
->route
[afi
][safi
], &p
);
4162 /* Configuration change. */
4163 bgp_static
= rn
->info
;
4165 /* Check previous routes are installed into BGP. */
4166 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4169 bgp_static
->backdoor
= backdoor
;
4173 if (bgp_static
->rmap
.name
)
4174 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4175 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4176 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4180 if (bgp_static
->rmap
.name
)
4181 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4182 bgp_static
->rmap
.name
= NULL
;
4183 bgp_static
->rmap
.map
= NULL
;
4184 bgp_static
->valid
= 0;
4186 bgp_unlock_node (rn
);
4190 /* New configuration. */
4191 bgp_static
= bgp_static_new ();
4192 bgp_static
->backdoor
= backdoor
;
4193 bgp_static
->valid
= 0;
4194 bgp_static
->igpmetric
= 0;
4195 bgp_static
->igpnexthop
.s_addr
= 0;
4199 if (bgp_static
->rmap
.name
)
4200 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4201 bgp_static
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4202 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap
);
4204 rn
->info
= bgp_static
;
4207 bgp_static
->valid
= 1;
4209 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4211 if (! bgp_static
->backdoor
)
4212 bgp_static_update (bgp
, &p
, bgp_static
, afi
, safi
);
4217 /* Configure static BGP network. */
4219 bgp_static_unset (struct vty
*vty
, const char *ip_str
,
4220 afi_t afi
, safi_t safi
)
4222 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4225 struct bgp_static
*bgp_static
;
4226 struct bgp_node
*rn
;
4228 /* Convert IP prefix string to struct prefix. */
4229 ret
= str2prefix (ip_str
, &p
);
4232 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4235 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
4237 vty_out (vty
, "%% Malformed prefix (link-local address)%s",
4244 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], &p
);
4247 vty_out (vty
, "%% Can't find specified static route configuration.%s",
4252 bgp_static
= rn
->info
;
4254 /* Update BGP RIB. */
4255 if (! bgp_static
->backdoor
)
4256 bgp_static_withdraw (bgp
, &p
, afi
, safi
);
4258 /* Clear configuration. */
4259 bgp_static_free (bgp_static
);
4261 bgp_unlock_node (rn
);
4262 bgp_unlock_node (rn
);
4268 bgp_static_add (struct bgp
*bgp
)
4272 struct bgp_node
*rn
;
4273 struct bgp_node
*rm
;
4274 struct bgp_table
*table
;
4275 struct bgp_static
*bgp_static
;
4277 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4278 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4279 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4280 if (rn
->info
!= NULL
)
4282 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4286 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4288 bgp_static
= rn
->info
;
4289 bgp_static_update_safi (bgp
, &rm
->p
, bgp_static
, afi
, safi
);
4294 bgp_static_update (bgp
, &rn
->p
, rn
->info
, afi
, safi
);
4299 /* Called from bgp_delete(). Delete all static routes from the BGP
4302 bgp_static_delete (struct bgp
*bgp
)
4306 struct bgp_node
*rn
;
4307 struct bgp_node
*rm
;
4308 struct bgp_table
*table
;
4309 struct bgp_static
*bgp_static
;
4311 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4312 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4313 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4314 if (rn
->info
!= NULL
)
4316 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
4320 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
4322 bgp_static
= rn
->info
;
4323 bgp_static_withdraw_safi (bgp
, &rm
->p
,
4325 (struct prefix_rd
*)&rn
->p
,
4327 bgp_static_free (bgp_static
);
4329 bgp_unlock_node (rn
);
4334 bgp_static
= rn
->info
;
4335 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
4336 bgp_static_free (bgp_static
);
4338 bgp_unlock_node (rn
);
4344 bgp_static_redo_import_check (struct bgp
*bgp
)
4348 struct bgp_node
*rn
;
4349 struct bgp_static
*bgp_static
;
4351 /* Use this flag to force reprocessing of the route */
4352 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4353 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4354 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4355 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
4356 if (rn
->info
!= NULL
)
4358 bgp_static
= rn
->info
;
4359 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
4361 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4365 bgp_purge_af_static_redist_routes (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
4367 struct bgp_table
*table
;
4368 struct bgp_node
*rn
;
4369 struct bgp_info
*ri
;
4371 table
= bgp
->rib
[afi
][safi
];
4372 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
4374 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4376 if (ri
->peer
== bgp
->peer_self
&&
4377 ((ri
->type
== ZEBRA_ROUTE_BGP
&&
4378 ri
->sub_type
== BGP_ROUTE_STATIC
) ||
4379 (ri
->type
!= ZEBRA_ROUTE_BGP
&&
4380 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)))
4382 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, safi
);
4383 bgp_unlink_nexthop(ri
);
4384 bgp_info_delete (rn
, ri
);
4385 bgp_process (bgp
, rn
, afi
, safi
);
4392 * Purge all networks and redistributed routes from routing table.
4393 * Invoked upon the instance going down.
4396 bgp_purge_static_redist_routes (struct bgp
*bgp
)
4401 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4402 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4403 bgp_purge_af_static_redist_routes (bgp
, afi
, safi
);
4408 * Currently this is used to set static routes for VPN and ENCAP.
4409 * I think it can probably be factored with bgp_static_set.
4412 bgp_static_set_safi (safi_t safi
, struct vty
*vty
, const char *ip_str
,
4413 const char *rd_str
, const char *tag_str
,
4414 const char *rmap_str
)
4416 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4419 struct prefix_rd prd
;
4420 struct bgp_node
*prn
;
4421 struct bgp_node
*rn
;
4422 struct bgp_table
*table
;
4423 struct bgp_static
*bgp_static
;
4427 ret
= str2prefix (ip_str
, &p
);
4430 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4435 ret
= str2prefix_rd (rd_str
, &prd
);
4438 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4442 ret
= str2tag (tag_str
, tag
);
4445 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4448 if (p
.family
== AF_INET
)
4450 else if (p
.family
== AF_INET6
)
4454 vty_out (vty
, "%% Non Supported prefix%s", VTY_NEWLINE
);
4457 prn
= bgp_node_get (bgp
->route
[afi
][safi
],
4458 (struct prefix
*)&prd
);
4459 if (prn
->info
== NULL
)
4460 prn
->info
= bgp_table_init (afi
, safi
);
4462 bgp_unlock_node (prn
);
4465 rn
= bgp_node_get (table
, &p
);
4469 vty_out (vty
, "%% Same network configuration exists%s", VTY_NEWLINE
);
4470 bgp_unlock_node (rn
);
4474 /* New configuration. */
4475 bgp_static
= bgp_static_new ();
4476 bgp_static
->backdoor
= 0;
4477 bgp_static
->valid
= 0;
4478 bgp_static
->igpmetric
= 0;
4479 bgp_static
->igpnexthop
.s_addr
= 0;
4480 memcpy(bgp_static
->tag
, tag
, 3);
4481 bgp_static
->prd
= prd
;
4485 if (bgp_static
->rmap
.name
)
4486 free (bgp_static
->rmap
.name
);
4487 bgp_static
->rmap
.name
= strdup (rmap_str
);
4488 bgp_static
->rmap
.map
= route_map_lookup_by_name (rmap_str
);
4490 rn
->info
= bgp_static
;
4492 bgp_static
->valid
= 1;
4493 bgp_static_update_safi (bgp
, &p
, bgp_static
, afi
, safi
);
4499 /* Configure static BGP network. */
4501 bgp_static_unset_safi(safi_t safi
, struct vty
*vty
, const char *ip_str
,
4502 const char *rd_str
, const char *tag_str
)
4504 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4507 struct prefix_rd prd
;
4508 struct bgp_node
*prn
;
4509 struct bgp_node
*rn
;
4510 struct bgp_table
*table
;
4511 struct bgp_static
*bgp_static
;
4514 /* Convert IP prefix string to struct prefix. */
4515 ret
= str2prefix (ip_str
, &p
);
4518 vty_out (vty
, "%% Malformed prefix%s", VTY_NEWLINE
);
4523 ret
= str2prefix_rd (rd_str
, &prd
);
4526 vty_out (vty
, "%% Malformed rd%s", VTY_NEWLINE
);
4530 ret
= str2tag (tag_str
, tag
);
4533 vty_out (vty
, "%% Malformed tag%s", VTY_NEWLINE
);
4537 prn
= bgp_node_get (bgp
->route
[AFI_IP
][safi
],
4538 (struct prefix
*)&prd
);
4539 if (prn
->info
== NULL
)
4540 prn
->info
= bgp_table_init (AFI_IP
, safi
);
4542 bgp_unlock_node (prn
);
4545 rn
= bgp_node_lookup (table
, &p
);
4549 bgp_static_withdraw_safi (bgp
, &p
, AFI_IP
, safi
, &prd
, tag
);
4551 bgp_static
= rn
->info
;
4552 bgp_static_free (bgp_static
);
4554 bgp_unlock_node (rn
);
4555 bgp_unlock_node (rn
);
4558 vty_out (vty
, "%% Can't find the route%s", VTY_NEWLINE
);
4564 bgp_table_map_set (struct vty
*vty
, afi_t afi
, safi_t safi
,
4565 const char *rmap_name
)
4567 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4568 struct bgp_rmap
*rmap
;
4570 rmap
= &bgp
->table_map
[afi
][safi
];
4574 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4575 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4576 rmap
->map
= route_map_lookup_by_name (rmap_name
);
4581 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4586 bgp_zebra_announce_table(bgp
, afi
, safi
);
4592 bgp_table_map_unset (struct vty
*vty
, afi_t afi
, safi_t safi
,
4593 const char *rmap_name
)
4595 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4596 struct bgp_rmap
*rmap
;
4598 rmap
= &bgp
->table_map
[afi
][safi
];
4600 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4604 bgp_zebra_announce_table(bgp
, afi
, safi
);
4610 bgp_config_write_table_map (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4611 safi_t safi
, int *write
)
4613 if (bgp
->table_map
[afi
][safi
].name
)
4615 bgp_config_write_family_header (vty
, afi
, safi
, write
);
4616 vty_out (vty
, " table-map %s%s",
4617 bgp
->table_map
[afi
][safi
].name
, VTY_NEWLINE
);
4623 DEFUN (bgp_table_map
,
4626 "BGP table to RIB route download filter\n"
4627 "Name of the route map\n")
4630 return bgp_table_map_set (vty
,
4631 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4633 DEFUN (no_bgp_table_map
,
4634 no_bgp_table_map_cmd
,
4635 "no table-map WORD",
4637 "BGP table to RIB route download filter\n"
4638 "Name of the route map\n")
4641 return bgp_table_map_unset (vty
,
4642 bgp_node_afi (vty
), bgp_node_safi (vty
), argv
[idx_word
]->arg
);
4647 "network A.B.C.D/M",
4648 "Specify a network to announce via BGP\n"
4651 int idx_ipv4_prefixlen
= 1;
4652 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4653 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4656 DEFUN (bgp_network_route_map
,
4657 bgp_network_route_map_cmd
,
4658 "network A.B.C.D/M route-map WORD",
4659 "Specify a network to announce via BGP\n"
4661 "Route-map to modify the attributes\n"
4662 "Name of the route map\n")
4664 int idx_ipv4_prefixlen
= 1;
4666 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
,
4667 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4670 DEFUN (bgp_network_backdoor
,
4671 bgp_network_backdoor_cmd
,
4672 "network A.B.C.D/M backdoor",
4673 "Specify a network to announce via BGP\n"
4675 "Specify a BGP backdoor route\n")
4677 int idx_ipv4_prefixlen
= 1;
4678 return bgp_static_set (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
, SAFI_UNICAST
,
4682 DEFUN (bgp_network_mask
,
4683 bgp_network_mask_cmd
,
4684 "network A.B.C.D mask A.B.C.D",
4685 "Specify a network to announce via BGP\n"
4693 char prefix_str
[BUFSIZ
];
4695 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4698 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4702 return bgp_static_set (vty
, prefix_str
,
4703 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4706 DEFUN (bgp_network_mask_route_map
,
4707 bgp_network_mask_route_map_cmd
,
4708 "network A.B.C.D mask A.B.C.D route-map WORD",
4709 "Specify a network to announce via BGP\n"
4713 "Route-map to modify the attributes\n"
4714 "Name of the route map\n")
4720 char prefix_str
[BUFSIZ
];
4722 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4725 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4729 return bgp_static_set (vty
, prefix_str
,
4730 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4733 DEFUN (bgp_network_mask_backdoor
,
4734 bgp_network_mask_backdoor_cmd
,
4735 "network A.B.C.D mask A.B.C.D backdoor",
4736 "Specify a network to announce via BGP\n"
4740 "Specify a BGP backdoor route\n")
4745 char prefix_str
[BUFSIZ
];
4747 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4750 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4754 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4758 DEFUN (bgp_network_mask_natural
,
4759 bgp_network_mask_natural_cmd
,
4761 "Specify a network to announce via BGP\n"
4766 char prefix_str
[BUFSIZ
];
4768 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4771 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4775 return bgp_static_set (vty
, prefix_str
,
4776 AFI_IP
, bgp_node_safi (vty
), NULL
, 0);
4779 DEFUN (bgp_network_mask_natural_route_map
,
4780 bgp_network_mask_natural_route_map_cmd
,
4781 "network A.B.C.D route-map WORD",
4782 "Specify a network to announce via BGP\n"
4784 "Route-map to modify the attributes\n"
4785 "Name of the route map\n")
4790 char prefix_str
[BUFSIZ
];
4792 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4795 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4799 return bgp_static_set (vty
, prefix_str
,
4800 AFI_IP
, bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4803 DEFUN (bgp_network_mask_natural_backdoor
,
4804 bgp_network_mask_natural_backdoor_cmd
,
4805 "network A.B.C.D backdoor",
4806 "Specify a network to announce via BGP\n"
4808 "Specify a BGP backdoor route\n")
4812 char prefix_str
[BUFSIZ
];
4814 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4817 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4821 return bgp_static_set (vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
4825 DEFUN (no_bgp_network
,
4827 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4829 "Specify a network to announce via BGP\n"
4831 "Specify a BGP backdoor route\n"
4832 "Route-map to modify the attributes\n"
4833 "Name of the route map\n")
4835 int idx_ipv4_prefixlen
= 2;
4836 return bgp_static_unset (vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
4837 bgp_node_safi (vty
));
4840 DEFUN (no_bgp_network_mask
,
4841 no_bgp_network_mask_cmd
,
4842 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4844 "Specify a network to announce via BGP\n"
4848 "Specify a BGP backdoor route\n"
4849 "Route-map to modify the attributes\n"
4850 "Name of the route map\n")
4855 char prefix_str
[BUFSIZ
];
4857 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
4860 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4864 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4865 bgp_node_safi (vty
));
4868 DEFUN (no_bgp_network_mask_natural
,
4869 no_bgp_network_mask_natural_cmd
,
4870 "no network A.B.C.D [<backdoor|route-map WORD>]",
4872 "Specify a network to announce via BGP\n"
4874 "Specify a BGP backdoor route\n"
4875 "Route-map to modify the attributes\n"
4876 "Name of the route map\n")
4880 char prefix_str
[BUFSIZ
];
4882 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
4885 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
4889 return bgp_static_unset (vty
, prefix_str
, AFI_IP
,
4890 bgp_node_safi (vty
));
4893 DEFUN (ipv6_bgp_network
,
4894 ipv6_bgp_network_cmd
,
4895 "network X:X::X:X/M",
4896 "Specify a network to announce via BGP\n"
4899 int idx_ipv6_prefixlen
= 1;
4900 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
),
4904 DEFUN (ipv6_bgp_network_route_map
,
4905 ipv6_bgp_network_route_map_cmd
,
4906 "network X:X::X:X/M route-map WORD",
4907 "Specify a network to announce via BGP\n"
4909 "Route-map to modify the attributes\n"
4910 "Name of the route map\n")
4912 int idx_ipv6_prefixlen
= 1;
4914 return bgp_static_set (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
4915 bgp_node_safi (vty
), argv
[idx_word
]->arg
, 0);
4918 DEFUN (no_ipv6_bgp_network
,
4919 no_ipv6_bgp_network_cmd
,
4920 "no network X:X::X:X/M [route-map WORD]",
4922 "Specify a network to announce via BGP\n"
4924 "Route-map to modify the attributes\n"
4925 "Name of the route map\n")
4927 int idx_ipv6_prefixlen
= 2;
4928 return bgp_static_unset (vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
, bgp_node_safi(vty
));
4931 /* Aggreagete address:
4933 advertise-map Set condition to advertise attribute
4934 as-set Generate AS set path information
4935 attribute-map Set attributes of aggregate
4936 route-map Set parameters of aggregate
4937 summary-only Filter more specific routes from updates
4938 suppress-map Conditionally filter more specific routes from updates
4941 struct bgp_aggregate
4943 /* Summary-only flag. */
4944 u_char summary_only
;
4946 /* AS set generation. */
4949 /* Route-map for aggregated route. */
4950 struct route_map
*map
;
4952 /* Suppress-count. */
4953 unsigned long count
;
4955 /* SAFI configuration. */
4959 static struct bgp_aggregate
*
4960 bgp_aggregate_new (void)
4962 return XCALLOC (MTYPE_BGP_AGGREGATE
, sizeof (struct bgp_aggregate
));
4966 bgp_aggregate_free (struct bgp_aggregate
*aggregate
)
4968 XFREE (MTYPE_BGP_AGGREGATE
, aggregate
);
4971 /* Update an aggregate as routes are added/removed from the BGP table */
4973 bgp_aggregate_route (struct bgp
*bgp
, struct prefix
*p
, struct bgp_info
*rinew
,
4974 afi_t afi
, safi_t safi
, struct bgp_info
*del
,
4975 struct bgp_aggregate
*aggregate
)
4977 struct bgp_table
*table
;
4978 struct bgp_node
*top
;
4979 struct bgp_node
*rn
;
4981 struct aspath
*aspath
= NULL
;
4982 struct aspath
*asmerge
= NULL
;
4983 struct community
*community
= NULL
;
4984 struct community
*commerge
= NULL
;
4985 #if defined(AGGREGATE_NEXTHOP_CHECK)
4986 struct in_addr nexthop
;
4989 struct bgp_info
*ri
;
4990 struct bgp_info
*new;
4992 unsigned long match
= 0;
4993 u_char atomic_aggregate
= 0;
4995 /* Record adding route's nexthop and med. */
4998 #if defined(AGGREGATE_NEXTHOP_CHECK)
4999 nexthop
= rinew
->attr
->nexthop
;
5000 med
= rinew
->attr
->med
;
5004 /* ORIGIN attribute: If at least one route among routes that are
5005 aggregated has ORIGIN with the value INCOMPLETE, then the
5006 aggregated route must have the ORIGIN attribute with the value
5007 INCOMPLETE. Otherwise, if at least one route among routes that
5008 are aggregated has ORIGIN with the value EGP, then the aggregated
5009 route must have the origin attribute with the value EGP. In all
5010 other case the value of the ORIGIN attribute of the aggregated
5011 route is INTERNAL. */
5012 origin
= BGP_ORIGIN_IGP
;
5014 table
= bgp
->rib
[afi
][safi
];
5016 top
= bgp_node_get (table
, p
);
5017 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5018 if (rn
->p
.prefixlen
> p
->prefixlen
)
5022 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5024 if (BGP_INFO_HOLDDOWN (ri
))
5027 if (del
&& ri
== del
)
5030 if (! rinew
&& first
)
5032 #if defined(AGGREGATE_NEXTHOP_CHECK)
5033 nexthop
= ri
->attr
->nexthop
;
5034 med
= ri
->attr
->med
;
5039 #ifdef AGGREGATE_NEXTHOP_CHECK
5040 if (! IPV4_ADDR_SAME (&ri
->attr
->nexthop
, &nexthop
)
5041 || ri
->attr
->med
!= med
)
5044 aspath_free (aspath
);
5046 community_free (community
);
5047 bgp_unlock_node (rn
);
5048 bgp_unlock_node (top
);
5051 #endif /* AGGREGATE_NEXTHOP_CHECK */
5053 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5054 atomic_aggregate
= 1;
5056 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5058 if (aggregate
->summary_only
)
5060 (bgp_info_extra_get (ri
))->suppress
++;
5061 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5067 if (origin
< ri
->attr
->origin
)
5068 origin
= ri
->attr
->origin
;
5070 if (aggregate
->as_set
)
5074 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5075 aspath_free (aspath
);
5079 aspath
= aspath_dup (ri
->attr
->aspath
);
5081 if (ri
->attr
->community
)
5085 commerge
= community_merge (community
,
5086 ri
->attr
->community
);
5087 community
= community_uniq_sort (commerge
);
5088 community_free (commerge
);
5091 community
= community_dup (ri
->attr
->community
);
5097 bgp_process (bgp
, rn
, afi
, safi
);
5099 bgp_unlock_node (top
);
5105 if (aggregate
->summary_only
)
5106 (bgp_info_extra_get (rinew
))->suppress
++;
5108 if (origin
< rinew
->attr
->origin
)
5109 origin
= rinew
->attr
->origin
;
5111 if (aggregate
->as_set
)
5115 asmerge
= aspath_aggregate (aspath
, rinew
->attr
->aspath
);
5116 aspath_free (aspath
);
5120 aspath
= aspath_dup (rinew
->attr
->aspath
);
5122 if (rinew
->attr
->community
)
5126 commerge
= community_merge (community
,
5127 rinew
->attr
->community
);
5128 community
= community_uniq_sort (commerge
);
5129 community_free (commerge
);
5132 community
= community_dup (rinew
->attr
->community
);
5137 if (aggregate
->count
> 0)
5139 rn
= bgp_node_get (table
, p
);
5140 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5141 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5143 atomic_aggregate
), rn
);
5144 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5146 bgp_info_add (rn
, new);
5147 bgp_unlock_node (rn
);
5148 bgp_process (bgp
, rn
, afi
, safi
);
5153 aspath_free (aspath
);
5155 community_free (community
);
5159 void bgp_aggregate_delete (struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5160 struct bgp_aggregate
*);
5163 bgp_aggregate_increment (struct bgp
*bgp
, struct prefix
*p
,
5164 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5166 struct bgp_node
*child
;
5167 struct bgp_node
*rn
;
5168 struct bgp_aggregate
*aggregate
;
5169 struct bgp_table
*table
;
5171 /* MPLS-VPN aggregation is not yet supported. */
5172 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
= SAFI_EVPN
))
5175 table
= bgp
->aggregate
[afi
][safi
];
5177 /* No aggregates configured. */
5178 if (bgp_table_top_nolock (table
) == NULL
)
5181 if (p
->prefixlen
== 0)
5184 if (BGP_INFO_HOLDDOWN (ri
))
5187 child
= bgp_node_get (table
, p
);
5189 /* Aggregate address configuration check. */
5190 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5191 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5193 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5194 bgp_aggregate_route (bgp
, &rn
->p
, ri
, afi
, safi
, NULL
, aggregate
);
5196 bgp_unlock_node (child
);
5200 bgp_aggregate_decrement (struct bgp
*bgp
, struct prefix
*p
,
5201 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5203 struct bgp_node
*child
;
5204 struct bgp_node
*rn
;
5205 struct bgp_aggregate
*aggregate
;
5206 struct bgp_table
*table
;
5208 /* MPLS-VPN aggregation is not yet supported. */
5209 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
= SAFI_EVPN
))
5212 table
= bgp
->aggregate
[afi
][safi
];
5214 /* No aggregates configured. */
5215 if (bgp_table_top_nolock (table
) == NULL
)
5218 if (p
->prefixlen
== 0)
5221 child
= bgp_node_get (table
, p
);
5223 /* Aggregate address configuration check. */
5224 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock (rn
))
5225 if ((aggregate
= rn
->info
) != NULL
&& rn
->p
.prefixlen
< p
->prefixlen
)
5227 bgp_aggregate_delete (bgp
, &rn
->p
, afi
, safi
, aggregate
);
5228 bgp_aggregate_route (bgp
, &rn
->p
, NULL
, afi
, safi
, del
, aggregate
);
5230 bgp_unlock_node (child
);
5233 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5235 bgp_aggregate_add (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
, safi_t safi
,
5236 struct bgp_aggregate
*aggregate
)
5238 struct bgp_table
*table
;
5239 struct bgp_node
*top
;
5240 struct bgp_node
*rn
;
5241 struct bgp_info
*new;
5242 struct bgp_info
*ri
;
5243 unsigned long match
;
5244 u_char origin
= BGP_ORIGIN_IGP
;
5245 struct aspath
*aspath
= NULL
;
5246 struct aspath
*asmerge
= NULL
;
5247 struct community
*community
= NULL
;
5248 struct community
*commerge
= NULL
;
5249 u_char atomic_aggregate
= 0;
5251 table
= bgp
->rib
[afi
][safi
];
5254 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5256 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5259 /* If routes exists below this node, generate aggregate routes. */
5260 top
= bgp_node_get (table
, p
);
5261 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5262 if (rn
->p
.prefixlen
> p
->prefixlen
)
5266 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5268 if (BGP_INFO_HOLDDOWN (ri
))
5271 if (ri
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5272 atomic_aggregate
= 1;
5274 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5276 /* summary-only aggregate route suppress aggregated
5277 route announcement. */
5278 if (aggregate
->summary_only
)
5280 (bgp_info_extra_get (ri
))->suppress
++;
5281 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5285 /* If at least one route among routes that are aggregated has
5286 * ORIGIN with the value INCOMPLETE, then the aggregated route
5287 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5288 * Otherwise, if at least one route among routes that are
5289 * aggregated has ORIGIN with the value EGP, then the aggregated
5290 * route MUST have the ORIGIN attribute with the value EGP.
5292 if (origin
< ri
->attr
->origin
)
5293 origin
= ri
->attr
->origin
;
5295 /* as-set aggregate route generate origin, as path,
5296 community aggregation. */
5297 if (aggregate
->as_set
)
5301 asmerge
= aspath_aggregate (aspath
, ri
->attr
->aspath
);
5302 aspath_free (aspath
);
5306 aspath
= aspath_dup (ri
->attr
->aspath
);
5308 if (ri
->attr
->community
)
5312 commerge
= community_merge (community
,
5313 ri
->attr
->community
);
5314 community
= community_uniq_sort (commerge
);
5315 community_free (commerge
);
5318 community
= community_dup (ri
->attr
->community
);
5325 /* If this node is suppressed, process the change. */
5327 bgp_process (bgp
, rn
, afi
, safi
);
5329 bgp_unlock_node (top
);
5331 /* Add aggregate route to BGP table. */
5332 if (aggregate
->count
)
5334 rn
= bgp_node_get (table
, p
);
5335 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5336 bgp_attr_aggregate_intern(bgp
, origin
, aspath
, community
,
5338 atomic_aggregate
), rn
);
5339 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5341 bgp_info_add (rn
, new);
5342 bgp_unlock_node (rn
);
5344 /* Process change. */
5345 bgp_process (bgp
, rn
, afi
, safi
);
5350 aspath_free (aspath
);
5352 community_free (community
);
5357 bgp_aggregate_delete (struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5358 safi_t safi
, struct bgp_aggregate
*aggregate
)
5360 struct bgp_table
*table
;
5361 struct bgp_node
*top
;
5362 struct bgp_node
*rn
;
5363 struct bgp_info
*ri
;
5364 unsigned long match
;
5366 table
= bgp
->rib
[afi
][safi
];
5368 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5370 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5373 /* If routes exists below this node, generate aggregate routes. */
5374 top
= bgp_node_get (table
, p
);
5375 for (rn
= bgp_node_get (table
, p
); rn
; rn
= bgp_route_next_until (rn
, top
))
5376 if (rn
->p
.prefixlen
> p
->prefixlen
)
5380 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5382 if (BGP_INFO_HOLDDOWN (ri
))
5385 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
)
5387 if (aggregate
->summary_only
&& ri
->extra
)
5389 ri
->extra
->suppress
--;
5391 if (ri
->extra
->suppress
== 0)
5393 bgp_info_set_flag (rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5401 /* If this node was suppressed, process the change. */
5403 bgp_process (bgp
, rn
, afi
, safi
);
5405 bgp_unlock_node (top
);
5407 /* Delete aggregate route from BGP table. */
5408 rn
= bgp_node_get (table
, p
);
5410 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5411 if (ri
->peer
== bgp
->peer_self
5412 && ri
->type
== ZEBRA_ROUTE_BGP
5413 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5416 /* Withdraw static BGP route from routing table. */
5419 bgp_info_delete (rn
, ri
);
5420 bgp_process (bgp
, rn
, afi
, safi
);
5423 /* Unlock bgp_node_lookup. */
5424 bgp_unlock_node (rn
);
5427 /* Aggregate route attribute. */
5428 #define AGGREGATE_SUMMARY_ONLY 1
5429 #define AGGREGATE_AS_SET 1
5432 bgp_aggregate_unset (struct vty
*vty
, const char *prefix_str
,
5433 afi_t afi
, safi_t safi
)
5435 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5438 struct bgp_node
*rn
;
5439 struct bgp_aggregate
*aggregate
;
5441 /* Convert string to prefix structure. */
5442 ret
= str2prefix (prefix_str
, &p
);
5445 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5450 /* Old configuration check. */
5451 rn
= bgp_node_lookup (bgp
->aggregate
[afi
][safi
], &p
);
5454 vty_out (vty
, "%% There is no aggregate-address configuration.%s",
5459 aggregate
= rn
->info
;
5460 if (aggregate
->safi
& SAFI_UNICAST
)
5461 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5462 if (aggregate
->safi
& SAFI_MULTICAST
)
5463 bgp_aggregate_delete (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5465 /* Unlock aggregate address configuration. */
5467 bgp_aggregate_free (aggregate
);
5468 bgp_unlock_node (rn
);
5469 bgp_unlock_node (rn
);
5475 bgp_aggregate_set (struct vty
*vty
, const char *prefix_str
,
5476 afi_t afi
, safi_t safi
,
5477 u_char summary_only
, u_char as_set
)
5479 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5482 struct bgp_node
*rn
;
5483 struct bgp_aggregate
*aggregate
;
5485 /* Convert string to prefix structure. */
5486 ret
= str2prefix (prefix_str
, &p
);
5489 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
5494 /* Old configuration check. */
5495 rn
= bgp_node_get (bgp
->aggregate
[afi
][safi
], &p
);
5499 vty_out (vty
, "There is already same aggregate network.%s", VTY_NEWLINE
);
5500 /* try to remove the old entry */
5501 ret
= bgp_aggregate_unset (vty
, prefix_str
, afi
, safi
);
5504 vty_out (vty
, "Error deleting aggregate.%s", VTY_NEWLINE
);
5505 bgp_unlock_node (rn
);
5510 /* Make aggregate address structure. */
5511 aggregate
= bgp_aggregate_new ();
5512 aggregate
->summary_only
= summary_only
;
5513 aggregate
->as_set
= as_set
;
5514 aggregate
->safi
= safi
;
5515 rn
->info
= aggregate
;
5517 /* Aggregate address insert into BGP routing table. */
5518 if (safi
& SAFI_UNICAST
)
5519 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5520 if (safi
& SAFI_MULTICAST
)
5521 bgp_aggregate_add (bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5526 DEFUN (aggregate_address
,
5527 aggregate_address_cmd
,
5528 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5529 "Configure BGP aggregate entries\n"
5530 "Aggregate prefix\n"
5531 "Generate AS set path information\n"
5532 "Filter more specific routes from updates\n"
5533 "Filter more specific routes from updates\n"
5534 "Generate AS set path information\n")
5537 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5538 char *prefix
= argv
[idx
]->arg
;
5539 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5541 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5543 return bgp_aggregate_set (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5546 DEFUN (aggregate_address_mask
,
5547 aggregate_address_mask_cmd
,
5548 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5549 "Configure BGP aggregate entries\n"
5550 "Aggregate address\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", &idx
);
5559 char *prefix
= argv
[idx
++]->arg
;
5560 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5561 char *mask
= argv
[idx
]->arg
;
5562 int as_set
= argv_find (argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5564 int summary_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5566 char prefix_str
[BUFSIZ
];
5567 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5571 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5575 return bgp_aggregate_set (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
), summary_only
, as_set
);
5578 DEFUN (no_aggregate_address
,
5579 no_aggregate_address_cmd
,
5580 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5582 "Configure BGP aggregate entries\n"
5583 "Aggregate prefix\n"
5584 "Generate AS set path information\n"
5585 "Filter more specific routes from updates\n"
5586 "Filter more specific routes from updates\n"
5587 "Generate AS set path information\n")
5590 argv_find (argv
, argc
, "A.B.C.D/M", &idx
);
5591 char *prefix
= argv
[idx
]->arg
;
5592 return bgp_aggregate_unset (vty
, prefix
, AFI_IP
, bgp_node_safi (vty
));
5595 DEFUN (no_aggregate_address_mask
,
5596 no_aggregate_address_mask_cmd
,
5597 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5599 "Configure BGP aggregate entries\n"
5600 "Aggregate address\n"
5602 "Generate AS set path information\n"
5603 "Filter more specific routes from updates\n"
5604 "Filter more specific routes from updates\n"
5605 "Generate AS set path information\n")
5608 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5609 char *prefix
= argv
[idx
++]->arg
;
5610 argv_find (argv
, argc
, "A.B.C.D", &idx
);
5611 char *mask
= argv
[idx
]->arg
;
5613 char prefix_str
[BUFSIZ
];
5614 int ret
= netmask_str2prefix_str (prefix
, mask
, prefix_str
);
5618 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
5622 return bgp_aggregate_unset (vty
, prefix_str
, AFI_IP
, bgp_node_safi (vty
));
5625 DEFUN (ipv6_aggregate_address
,
5626 ipv6_aggregate_address_cmd
,
5627 "aggregate-address X:X::X:X/M [summary-only]",
5628 "Configure BGP aggregate entries\n"
5629 "Aggregate prefix\n"
5630 "Filter more specific routes from updates\n")
5633 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5634 char *prefix
= argv
[idx
]->arg
;
5635 int sum_only
= argv_find (argv
, argc
, "summary-only", &idx
) ? AGGREGATE_SUMMARY_ONLY
: 0;
5636 return bgp_aggregate_set (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
, 0);
5639 DEFUN (no_ipv6_aggregate_address
,
5640 no_ipv6_aggregate_address_cmd
,
5641 "no aggregate-address X:X::X:X/M [summary-only]",
5643 "Configure BGP aggregate entries\n"
5644 "Aggregate prefix\n"
5645 "Filter more specific routes from updates\n")
5648 argv_find (argv
, argc
, "X:X::X:X/M", &idx
);
5649 char *prefix
= argv
[idx
]->arg
;
5650 return bgp_aggregate_unset (vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
5653 /* Redistribute route treatment. */
5655 bgp_redistribute_add (struct bgp
*bgp
, struct prefix
*p
, const struct in_addr
*nexthop
,
5656 const struct in6_addr
*nexthop6
, unsigned int ifindex
,
5657 u_int32_t metric
, u_char type
, u_short instance
, route_tag_t tag
)
5659 struct bgp_info
*new;
5660 struct bgp_info
*bi
;
5661 struct bgp_info info
;
5662 struct bgp_node
*bn
;
5664 struct attr
*new_attr
;
5667 struct bgp_redist
*red
;
5669 /* Make default attribute. */
5670 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
5672 attr
.nexthop
= *nexthop
;
5673 attr
.nh_ifindex
= ifindex
;
5677 struct attr_extra
*extra
= bgp_attr_extra_get(&attr
);
5678 extra
->mp_nexthop_global
= *nexthop6
;
5679 extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
5683 attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
5684 attr
.extra
->tag
= tag
;
5686 afi
= family2afi (p
->family
);
5688 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5691 struct attr attr_new
;
5692 struct attr_extra extra_new
;
5694 /* Copy attribute for modification. */
5695 attr_new
.extra
= &extra_new
;
5696 bgp_attr_dup (&attr_new
, &attr
);
5698 if (red
->redist_metric_flag
)
5699 attr_new
.med
= red
->redist_metric
;
5701 /* Apply route-map. */
5704 info
.peer
= bgp
->peer_self
;
5705 info
.attr
= &attr_new
;
5707 SET_FLAG (bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
);
5709 ret
= route_map_apply (red
->rmap
.map
, p
, RMAP_BGP
, &info
);
5711 bgp
->peer_self
->rmap_type
= 0;
5713 if (ret
== RMAP_DENYMATCH
)
5715 /* Free uninterned attribute. */
5716 bgp_attr_flush (&attr_new
);
5718 /* Unintern original. */
5719 aspath_unintern (&attr
.aspath
);
5720 bgp_attr_extra_free (&attr
);
5721 bgp_redistribute_delete (bgp
, p
, type
, instance
);
5726 bn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
],
5727 afi
, SAFI_UNICAST
, p
, NULL
);
5729 new_attr
= bgp_attr_intern (&attr_new
);
5731 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
5732 if (bi
->peer
== bgp
->peer_self
5733 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
5738 /* Ensure the (source route) type is updated. */
5740 if (attrhash_cmp (bi
->attr
, new_attr
) &&
5741 !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5743 bgp_attr_unintern (&new_attr
);
5744 aspath_unintern (&attr
.aspath
);
5745 bgp_attr_extra_free (&attr
);
5746 bgp_unlock_node (bn
);
5751 /* The attribute is changed. */
5752 bgp_info_set_flag (bn
, bi
, BGP_INFO_ATTR_CHANGED
);
5754 /* Rewrite BGP route information. */
5755 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
5756 bgp_info_restore(bn
, bi
);
5758 bgp_aggregate_decrement (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5759 bgp_attr_unintern (&bi
->attr
);
5760 bi
->attr
= new_attr
;
5761 bi
->uptime
= bgp_clock ();
5763 /* Process change. */
5764 bgp_aggregate_increment (bgp
, p
, bi
, afi
, SAFI_UNICAST
);
5765 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5766 bgp_unlock_node (bn
);
5767 aspath_unintern (&attr
.aspath
);
5768 bgp_attr_extra_free (&attr
);
5773 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
, bgp
->peer_self
,
5775 SET_FLAG (new->flags
, BGP_INFO_VALID
);
5777 bgp_aggregate_increment (bgp
, p
, new, afi
, SAFI_UNICAST
);
5778 bgp_info_add (bn
, new);
5779 bgp_unlock_node (bn
);
5780 bgp_process (bgp
, bn
, afi
, SAFI_UNICAST
);
5783 /* Unintern original. */
5784 aspath_unintern (&attr
.aspath
);
5785 bgp_attr_extra_free (&attr
);
5789 bgp_redistribute_delete (struct bgp
*bgp
, struct prefix
*p
, u_char type
, u_short instance
)
5792 struct bgp_node
*rn
;
5793 struct bgp_info
*ri
;
5794 struct bgp_redist
*red
;
5796 afi
= family2afi (p
->family
);
5798 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
5801 rn
= bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, p
, NULL
);
5803 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5804 if (ri
->peer
== bgp
->peer_self
5805 && ri
->type
== type
)
5810 bgp_aggregate_decrement (bgp
, p
, ri
, afi
, SAFI_UNICAST
);
5811 bgp_info_delete (rn
, ri
);
5812 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5814 bgp_unlock_node (rn
);
5818 /* Withdraw specified route type's route. */
5820 bgp_redistribute_withdraw (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
5822 struct bgp_node
*rn
;
5823 struct bgp_info
*ri
;
5824 struct bgp_table
*table
;
5826 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
5828 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
5830 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5831 if (ri
->peer
== bgp
->peer_self
5833 && ri
->instance
== instance
)
5838 bgp_aggregate_decrement (bgp
, &rn
->p
, ri
, afi
, SAFI_UNICAST
);
5839 bgp_info_delete (rn
, ri
);
5840 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
5845 /* Static function to display route. */
5847 route_vty_out_route (struct prefix
*p
, struct vty
*vty
)
5850 u_int32_t destination
;
5853 if (p
->family
== AF_INET
)
5855 len
= vty_out (vty
, "%s", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
5856 destination
= ntohl (p
->u
.prefix4
.s_addr
);
5858 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
5859 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
5860 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
5861 || p
->u
.prefix4
.s_addr
== 0)
5863 /* When mask is natural, mask is not displayed. */
5866 len
+= vty_out (vty
, "/%d", p
->prefixlen
);
5869 len
= vty_out (vty
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
5874 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 20, " ");
5876 vty_out (vty
, "%*s", len
, " ");
5879 enum bgp_display_type
5884 /* Print the short form route status for a bgp_info */
5886 route_vty_short_status_out (struct vty
*vty
, struct bgp_info
*binfo
,
5887 json_object
*json_path
)
5892 /* Route status display. */
5893 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5894 json_object_boolean_true_add(json_path
, "removed");
5896 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5897 json_object_boolean_true_add(json_path
, "stale");
5899 if (binfo
->extra
&& binfo
->extra
->suppress
)
5900 json_object_boolean_true_add(json_path
, "suppressed");
5902 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5903 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5904 json_object_boolean_true_add(json_path
, "valid");
5907 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5908 json_object_boolean_true_add(json_path
, "history");
5910 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5911 json_object_boolean_true_add(json_path
, "damped");
5913 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5914 json_object_boolean_true_add(json_path
, "bestpath");
5916 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5917 json_object_boolean_true_add(json_path
, "multipath");
5919 /* Internal route. */
5920 if ((binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5921 json_object_string_add(json_path
, "pathFrom", "internal");
5923 json_object_string_add(json_path
, "pathFrom", "external");
5928 /* Route status display. */
5929 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
5931 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
5933 else if (binfo
->extra
&& binfo
->extra
->suppress
)
5935 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
) &&
5936 ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5942 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
5944 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
5946 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
5948 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
))
5953 /* Internal route. */
5955 (binfo
->peer
->as
) && (binfo
->peer
->as
== binfo
->peer
->local_as
))
5961 /* called from terminal list command */
5963 route_vty_out (struct vty
*vty
, struct prefix
*p
,
5964 struct bgp_info
*binfo
, int display
, safi_t safi
,
5965 json_object
*json_paths
)
5968 json_object
*json_path
= NULL
;
5969 json_object
*json_nexthops
= NULL
;
5970 json_object
*json_nexthop_global
= NULL
;
5971 json_object
*json_nexthop_ll
= NULL
;
5974 json_path
= json_object_new_object();
5976 /* short status lead text */
5977 route_vty_short_status_out (vty
, binfo
, json_path
);
5981 /* print prefix and mask */
5983 route_vty_out_route (p
, vty
);
5985 vty_out (vty
, "%*s", 17, " ");
5988 /* Print attribute */
5993 * For ENCAP routes, nexthop address family is not
5994 * neccessarily the same as the prefix address family.
5995 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
5997 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6002 int af
= NEXTHOP_FAMILY(attr
->extra
->mp_nexthop_len
);
6007 vty_out (vty
, "%s", inet_ntop(af
,
6008 &attr
->extra
->mp_nexthop_global_in
, buf
, BUFSIZ
));
6011 vty_out (vty
, "%s", inet_ntop(af
,
6012 &attr
->extra
->mp_nexthop_global
, buf
, BUFSIZ
));
6023 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6027 json_nexthop_global
= json_object_new_object();
6029 if ((safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6030 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6032 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6034 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6035 json_object_boolean_true_add(json_nexthop_global
, "used");
6039 if ((safi
== SAFI_MPLS_VPN
) || (safi
= SAFI_EVPN
))
6040 vty_out (vty
, "%-16s",
6041 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6043 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6048 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6055 json_nexthop_global
= json_object_new_object();
6056 json_object_string_add(json_nexthop_global
, "ip",
6057 inet_ntop (AF_INET6
,
6058 &attr
->extra
->mp_nexthop_global
,
6060 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6061 json_object_string_add(json_nexthop_global
, "scope", "global");
6063 /* We display both LL & GL if both have been received */
6064 if ((attr
->extra
->mp_nexthop_len
== 32) || (binfo
->peer
->conf_if
))
6066 json_nexthop_ll
= json_object_new_object();
6067 json_object_string_add(json_nexthop_ll
, "ip",
6068 inet_ntop (AF_INET6
,
6069 &attr
->extra
->mp_nexthop_local
,
6071 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6072 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6074 if ((IPV6_ADDR_CMP (&attr
->extra
->mp_nexthop_global
,
6075 &attr
->extra
->mp_nexthop_local
) != 0) &&
6076 !attr
->extra
->mp_nexthop_prefer_global
)
6077 json_object_boolean_true_add(json_nexthop_ll
, "used");
6079 json_object_boolean_true_add(json_nexthop_global
, "used");
6082 json_object_boolean_true_add(json_nexthop_global
, "used");
6086 /* Display LL if LL/Global both in table unless prefer-global is set */
6087 if (((attr
->extra
->mp_nexthop_len
== 32) &&
6088 !attr
->extra
->mp_nexthop_prefer_global
) ||
6089 (binfo
->peer
->conf_if
))
6091 if (binfo
->peer
->conf_if
)
6093 len
= vty_out (vty
, "%s",
6094 binfo
->peer
->conf_if
);
6095 len
= 7 - len
; /* len of IPv6 addr + max len of def ifname */
6098 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 45, " ");
6100 vty_out (vty
, "%*s", len
, " ");
6104 len
= vty_out (vty
, "%s",
6105 inet_ntop (AF_INET6
,
6106 &attr
->extra
->mp_nexthop_local
,
6111 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6113 vty_out (vty
, "%*s", len
, " ");
6118 len
= vty_out (vty
, "%s",
6119 inet_ntop (AF_INET6
,
6120 &attr
->extra
->mp_nexthop_global
,
6125 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6127 vty_out (vty
, "%*s", len
, " ");
6133 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6135 json_object_int_add(json_path
, "med", attr
->med
);
6137 vty_out (vty
, "%10u", attr
->med
);
6143 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6145 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6147 vty_out (vty
, "%7u", attr
->local_pref
);
6155 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
6157 json_object_int_add(json_path
, "weight", 0);
6160 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6164 json_object_string_add(json_path
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6171 json_object_string_add(json_path
, "aspath", attr
->aspath
->str
);
6173 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6178 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6180 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6185 json_object_string_add(json_path
, "alert", "No attributes");
6187 vty_out (vty
, "No attributes to print%s", VTY_NEWLINE
);
6192 if (json_nexthop_global
|| json_nexthop_ll
)
6194 json_nexthops
= json_object_new_array();
6196 if (json_nexthop_global
)
6197 json_object_array_add(json_nexthops
, json_nexthop_global
);
6199 if (json_nexthop_ll
)
6200 json_object_array_add(json_nexthops
, json_nexthop_ll
);
6202 json_object_object_add(json_path
, "nexthops", json_nexthops
);
6205 json_object_array_add(json_paths
, json_path
);
6209 vty_out (vty
, "%s", VTY_NEWLINE
);
6211 /* prints an additional line, indented, with VNC info, if present */
6212 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6213 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6218 /* called from terminal list command */
6220 route_vty_out_tmp (struct vty
*vty
, struct prefix
*p
, struct attr
*attr
, safi_t safi
,
6221 u_char use_json
, json_object
*json_ar
)
6223 json_object
*json_status
= NULL
;
6224 json_object
*json_net
= NULL
;
6226 /* Route status display. */
6229 json_status
= json_object_new_object();
6230 json_net
= json_object_new_object();
6239 /* print prefix and mask */
6241 json_object_string_add(json_net
, "addrPrefix", inet_ntop (p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6243 route_vty_out_route (p
, vty
);
6245 /* Print attribute */
6250 if (p
->family
== AF_INET
&&
6251 (safi
== SAFI_MPLS_VPN
||
6252 safi
== SAFI_ENCAP
||
6253 safi
== SAFI_EVPN
||
6254 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6256 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6257 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6259 json_object_string_add(json_net
, "nextHop", inet_ntoa (attr
->nexthop
));
6261 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6265 json_object_string_add(json_net
, "netHopGloabal", inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6269 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6270 json_object_int_add(json_net
, "metric", attr
->med
);
6272 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6273 json_object_int_add(json_net
, "localPref", attr
->local_pref
);
6276 json_object_int_add(json_net
, "weight", attr
->extra
->weight
);
6278 json_object_int_add(json_net
, "weight", 0);
6282 json_object_string_add(json_net
, "asPath", attr
->aspath
->str
);
6285 json_object_string_add(json_net
, "bgpOriginCode", bgp_origin_str
[attr
->origin
]);
6289 if (p
->family
== AF_INET
&&
6290 (safi
== SAFI_MPLS_VPN
||
6291 safi
== SAFI_ENCAP
||
6292 safi
== SAFI_EVPN
||
6293 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6295 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6296 vty_out (vty
, "%-16s",
6297 inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6299 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6301 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6306 assert (attr
->extra
);
6308 len
= vty_out (vty
, "%s",
6309 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6313 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 36, " ");
6315 vty_out (vty
, "%*s", len
, " ");
6317 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
6318 vty_out (vty
, "%10u", attr
->med
);
6322 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
6323 vty_out (vty
, "%7u", attr
->local_pref
);
6327 vty_out (vty
, "%7u ", (attr
->extra
? attr
->extra
->weight
: 0));
6331 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6334 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6339 json_object_boolean_true_add(json_status
, "*");
6340 json_object_boolean_true_add(json_status
, ">");
6341 json_object_object_add(json_net
, "appliedStatusSymbols", json_status
);
6342 char buf_cut
[BUFSIZ
];
6343 json_object_object_add(json_ar
, inet_ntop (p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
), json_net
);
6346 vty_out (vty
, "%s", VTY_NEWLINE
);
6350 route_vty_out_tag (struct vty
*vty
, struct prefix
*p
,
6351 struct bgp_info
*binfo
, int display
, safi_t safi
, json_object
*json
)
6353 json_object
*json_out
= NULL
;
6355 u_int32_t label
= 0;
6361 json_out
= json_object_new_object();
6363 /* short status lead text */
6364 route_vty_short_status_out (vty
, binfo
, json_out
);
6366 /* print prefix and mask */
6370 route_vty_out_route (p
, vty
);
6372 vty_out (vty
, "%*s", 17, " ");
6375 /* Print attribute */
6379 if (p
->family
== AF_INET
6380 && (safi
== SAFI_MPLS_VPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6382 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6385 json_object_string_add(json_out
, "mpNexthopGlobalIn", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6387 vty_out (vty
, "%-16s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6392 json_object_string_add(json_out
, "nexthop", inet_ntoa (attr
->nexthop
));
6394 vty_out (vty
, "%-16s", inet_ntoa (attr
->nexthop
));
6397 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6399 assert (attr
->extra
);
6403 if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
6406 json_object_string_add(json_out
, "mpNexthopGlobalIn",
6407 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
, buf_a
, BUFSIZ
));
6410 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6413 else if (attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6417 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6419 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6421 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6422 json_object_string_add(json_out
, "mpNexthopGlobalLocal", buf_c
);
6425 vty_out (vty
, "%s(%s)",
6426 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6428 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6435 label
= decode_label (binfo
->extra
->tag
);
6440 json_object_int_add(json_out
, "notag", label
);
6441 json_object_array_add(json
, json_out
);
6445 vty_out (vty
, "notag/%d", label
);
6446 vty_out (vty
, "%s", VTY_NEWLINE
);
6450 /* dampening route */
6452 damp_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6453 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6457 char timebuf
[BGP_UPTIME_LEN
];
6459 /* short status lead text */
6460 route_vty_short_status_out (vty
, binfo
, json
);
6462 /* print prefix and mask */
6466 route_vty_out_route (p
, vty
);
6468 vty_out (vty
, "%*s", 17, " ");
6471 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6476 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 34, " ");
6481 json_object_int_add(json
, "peerHost", len
);
6483 vty_out (vty
, "%*s", len
, " ");
6487 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6489 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6491 /* Print attribute */
6499 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6501 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6506 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6508 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6511 vty_out (vty
, "%s", VTY_NEWLINE
);
6516 flap_route_vty_out (struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6517 int display
, safi_t safi
, u_char use_json
, json_object
*json
)
6520 struct bgp_damp_info
*bdi
;
6521 char timebuf
[BGP_UPTIME_LEN
];
6527 bdi
= binfo
->extra
->damp_info
;
6529 /* short status lead text */
6530 route_vty_short_status_out (vty
, binfo
, json
);
6532 /* print prefix and mask */
6536 route_vty_out_route (p
, vty
);
6538 vty_out (vty
, "%*s", 17, " ");
6541 len
= vty_out (vty
, "%s", binfo
->peer
->host
);
6546 vty_out (vty
, "%s%*s", VTY_NEWLINE
, 33, " ");
6551 json_object_int_add(json
, "peerHost", len
);
6553 vty_out (vty
, "%*s", len
, " ");
6556 len
= vty_out (vty
, "%d", bdi
->flap
);
6566 json_object_int_add(json
, "bdiFlap", len
);
6568 vty_out (vty
, "%*s", len
, " ");
6572 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6574 vty_out (vty
, "%s ", peer_uptime (bdi
->start_time
,
6575 timebuf
, BGP_UPTIME_LEN
, 0, NULL
));
6577 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
6578 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6581 bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
);
6583 vty_out (vty
, "%s ", bgp_damp_reuse_time_vty (vty
, binfo
, timebuf
, BGP_UPTIME_LEN
, use_json
, json
));
6588 vty_out (vty
, "%*s ", 8, " ");
6591 /* Print attribute */
6599 json_object_string_add(json
, "asPath", attr
->aspath
->str
);
6601 aspath_print_vty (vty
, "%s", attr
->aspath
, " ");
6606 json_object_string_add(json
, "origin", bgp_origin_str
[attr
->origin
]);
6608 vty_out (vty
, "%s", bgp_origin_str
[attr
->origin
]);
6611 vty_out (vty
, "%s", VTY_NEWLINE
);
6615 route_vty_out_advertised_to (struct vty
*vty
, struct peer
*peer
, int *first
,
6616 const char *header
, json_object
*json_adv_to
)
6618 char buf1
[INET6_ADDRSTRLEN
];
6619 json_object
*json_peer
= NULL
;
6623 /* 'advertised-to' is a dictionary of peers we have advertised this
6624 * prefix too. The key is the peer's IP or swpX, the value is the
6625 * hostname if we know it and "" if not.
6627 json_peer
= json_object_new_object();
6630 json_object_string_add(json_peer
, "hostname", peer
->hostname
);
6633 json_object_object_add(json_adv_to
, peer
->conf_if
, json_peer
);
6635 json_object_object_add(json_adv_to
,
6636 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
),
6643 vty_out (vty
, "%s", header
);
6647 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6650 vty_out (vty
, " %s(%s)", peer
->hostname
, peer
->conf_if
);
6652 vty_out (vty
, " %s(%s)", peer
->hostname
,
6653 sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6658 vty_out (vty
, " %s", peer
->conf_if
);
6660 vty_out (vty
, " %s", sockunion2str (&peer
->su
, buf1
, SU_ADDRSTRLEN
));
6666 route_vty_out_detail (struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
6667 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
6668 json_object
*json_paths
)
6670 char buf
[INET6_ADDRSTRLEN
];
6673 int sockunion_vty_out (struct vty
*, union sockunion
*);
6675 json_object
*json_bestpath
= NULL
;
6676 json_object
*json_cluster_list
= NULL
;
6677 json_object
*json_cluster_list_list
= NULL
;
6678 json_object
*json_ext_community
= NULL
;
6679 json_object
*json_last_update
= NULL
;
6680 json_object
*json_nexthop_global
= NULL
;
6681 json_object
*json_nexthop_ll
= NULL
;
6682 json_object
*json_nexthops
= NULL
;
6683 json_object
*json_path
= NULL
;
6684 json_object
*json_peer
= NULL
;
6685 json_object
*json_string
= NULL
;
6686 json_object
*json_adv_to
= NULL
;
6688 struct listnode
*node
, *nnode
;
6690 int addpath_capable
;
6692 unsigned int first_as
;
6696 json_path
= json_object_new_object();
6697 json_peer
= json_object_new_object();
6698 json_nexthop_global
= json_object_new_object();
6705 /* Line1 display AS-path, Aggregator */
6710 json_object_lock(attr
->aspath
->json
);
6711 json_object_object_add(json_path
, "aspath", attr
->aspath
->json
);
6715 if (attr
->aspath
->segments
)
6716 aspath_print_vty (vty
, " %s", attr
->aspath
, "");
6718 vty_out (vty
, " Local");
6722 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_REMOVED
))
6725 json_object_boolean_true_add(json_path
, "removed");
6727 vty_out (vty
, ", (removed)");
6730 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_STALE
))
6733 json_object_boolean_true_add(json_path
, "stale");
6735 vty_out (vty
, ", (stale)");
6738 if (CHECK_FLAG (attr
->flag
, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
)))
6742 json_object_int_add(json_path
, "aggregatorAs", attr
->extra
->aggregator_as
);
6743 json_object_string_add(json_path
, "aggregatorId", inet_ntoa (attr
->extra
->aggregator_addr
));
6747 vty_out (vty
, ", (aggregated by %u %s)",
6748 attr
->extra
->aggregator_as
,
6749 inet_ntoa (attr
->extra
->aggregator_addr
));
6753 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_REFLECTOR_CLIENT
))
6756 json_object_boolean_true_add(json_path
, "rxedFromRrClient");
6758 vty_out (vty
, ", (Received from a RR-client)");
6761 if (CHECK_FLAG (binfo
->peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
6764 json_object_boolean_true_add(json_path
, "rxedFromRsClient");
6766 vty_out (vty
, ", (Received from a RS-client)");
6769 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
6772 json_object_boolean_true_add(json_path
, "dampeningHistoryEntry");
6774 vty_out (vty
, ", (history entry)");
6776 else if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
6779 json_object_boolean_true_add(json_path
, "dampeningSuppressed");
6781 vty_out (vty
, ", (suppressed due to dampening)");
6785 vty_out (vty
, "%s", VTY_NEWLINE
);
6787 /* Line2 display Next-hop, Neighbor, Router-id */
6788 /* Display the nexthop */
6789 if (p
->family
== AF_INET
&&
6790 (safi
== SAFI_MPLS_VPN
||
6791 safi
== SAFI_ENCAP
||
6792 safi
== SAFI_EVPN
||
6793 !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)))
6795 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
6798 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6800 vty_out (vty
, " %s", inet_ntoa (attr
->extra
->mp_nexthop_global_in
));
6805 json_object_string_add(json_nexthop_global
, "ip", inet_ntoa (attr
->nexthop
));
6807 vty_out (vty
, " %s", inet_ntoa (attr
->nexthop
));
6811 json_object_string_add(json_nexthop_global
, "afi", "ipv4");
6815 assert (attr
->extra
);
6818 json_object_string_add(json_nexthop_global
, "ip",
6819 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6820 buf
, INET6_ADDRSTRLEN
));
6821 json_object_string_add(json_nexthop_global
, "afi", "ipv6");
6822 json_object_string_add(json_nexthop_global
, "scope", "global");
6826 vty_out (vty
, " %s",
6827 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_global
,
6828 buf
, INET6_ADDRSTRLEN
));
6832 /* Display the IGP cost or 'inaccessible' */
6833 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
6836 json_object_boolean_false_add(json_nexthop_global
, "accessible");
6838 vty_out (vty
, " (inaccessible)");
6842 if (binfo
->extra
&& binfo
->extra
->igpmetric
)
6845 json_object_int_add(json_nexthop_global
, "metric", binfo
->extra
->igpmetric
);
6847 vty_out (vty
, " (metric %u)", binfo
->extra
->igpmetric
);
6850 /* IGP cost is 0, display this only for json */
6854 json_object_int_add(json_nexthop_global
, "metric", 0);
6858 json_object_boolean_true_add(json_nexthop_global
, "accessible");
6861 /* Display peer "from" output */
6862 /* This path was originated locally */
6863 if (binfo
->peer
== bgp
->peer_self
)
6866 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6869 json_object_string_add(json_peer
, "peerId", "0.0.0.0");
6871 vty_out (vty
, " from 0.0.0.0 ");
6876 json_object_string_add(json_peer
, "peerId", "::");
6878 vty_out (vty
, " from :: ");
6882 json_object_string_add(json_peer
, "routerId", inet_ntoa(bgp
->router_id
));
6884 vty_out (vty
, "(%s)", inet_ntoa(bgp
->router_id
));
6887 /* We RXed this path from one of our peers */
6893 json_object_string_add(json_peer
, "peerId", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6894 json_object_string_add(json_peer
, "routerId", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6896 if (binfo
->peer
->hostname
)
6897 json_object_string_add(json_peer
, "hostname", binfo
->peer
->hostname
);
6899 if (binfo
->peer
->domainname
)
6900 json_object_string_add(json_peer
, "domainname", binfo
->peer
->domainname
);
6902 if (binfo
->peer
->conf_if
)
6903 json_object_string_add(json_peer
, "interface", binfo
->peer
->conf_if
);
6907 if (binfo
->peer
->conf_if
)
6909 if (binfo
->peer
->hostname
&&
6910 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6911 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6912 binfo
->peer
->conf_if
);
6914 vty_out (vty
, " from %s", binfo
->peer
->conf_if
);
6918 if (binfo
->peer
->hostname
&&
6919 bgp_flag_check(binfo
->peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6920 vty_out (vty
, " from %s(%s)", binfo
->peer
->hostname
,
6923 vty_out (vty
, " from %s", sockunion2str (&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6926 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
6927 vty_out (vty
, " (%s)", inet_ntoa (attr
->extra
->originator_id
));
6929 vty_out (vty
, " (%s)", inet_ntop (AF_INET
, &binfo
->peer
->remote_id
, buf1
, BUFSIZ
));
6934 vty_out (vty
, "%s", VTY_NEWLINE
);
6936 /* display the link-local nexthop */
6937 if (attr
->extra
&& attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
6941 json_nexthop_ll
= json_object_new_object();
6942 json_object_string_add(json_nexthop_ll
, "ip",
6943 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6944 buf
, INET6_ADDRSTRLEN
));
6945 json_object_string_add(json_nexthop_ll
, "afi", "ipv6");
6946 json_object_string_add(json_nexthop_ll
, "scope", "link-local");
6948 json_object_boolean_true_add(json_nexthop_ll
, "accessible");
6950 if (!attr
->extra
->mp_nexthop_prefer_global
)
6951 json_object_boolean_true_add(json_nexthop_ll
, "used");
6953 json_object_boolean_true_add(json_nexthop_global
, "used");
6957 vty_out (vty
, " (%s) %s%s",
6958 inet_ntop (AF_INET6
, &attr
->extra
->mp_nexthop_local
,
6959 buf
, INET6_ADDRSTRLEN
),
6960 attr
->extra
->mp_nexthop_prefer_global
?
6961 "(prefer-global)" : "(used)",
6965 /* If we do not have a link-local nexthop then we must flag the global as "used" */
6969 json_object_boolean_true_add(json_nexthop_global
, "used");
6972 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
6974 json_object_string_add(json_path
, "origin", bgp_origin_long_str
[attr
->origin
]);
6976 vty_out (vty
, " Origin %s", bgp_origin_long_str
[attr
->origin
]);
6978 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6981 json_object_int_add(json_path
, "med", attr
->med
);
6983 vty_out (vty
, ", metric %u", attr
->med
);
6986 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6989 json_object_int_add(json_path
, "localpref", attr
->local_pref
);
6991 vty_out (vty
, ", localpref %u", attr
->local_pref
);
6996 json_object_int_add(json_path
, "localpref", bgp
->default_local_pref
);
6998 vty_out (vty
, ", localpref %u", bgp
->default_local_pref
);
7001 if (attr
->extra
&& attr
->extra
->weight
!= 0)
7004 json_object_int_add(json_path
, "weight", attr
->extra
->weight
);
7006 vty_out (vty
, ", weight %u", attr
->extra
->weight
);
7009 if (attr
->extra
&& attr
->extra
->tag
!= 0)
7012 json_object_int_add(json_path
, "tag", attr
->extra
->tag
);
7014 vty_out (vty
, ", tag %"ROUTE_TAG_PRI
, attr
->extra
->tag
);
7017 if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_VALID
))
7020 json_object_boolean_false_add(json_path
, "valid");
7022 vty_out (vty
, ", invalid");
7024 else if (! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
7027 json_object_boolean_true_add(json_path
, "valid");
7029 vty_out (vty
, ", valid");
7032 if (binfo
->peer
!= bgp
->peer_self
)
7034 if (binfo
->peer
->as
== binfo
->peer
->local_as
)
7036 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7039 json_object_string_add(json_peer
, "type", "confed-internal");
7041 vty_out (vty
, ", confed-internal");
7046 json_object_string_add(json_peer
, "type", "internal");
7048 vty_out (vty
, ", internal");
7053 if (bgp_confederation_peers_check(bgp
, binfo
->peer
->as
))
7056 json_object_string_add(json_peer
, "type", "confed-external");
7058 vty_out (vty
, ", confed-external");
7063 json_object_string_add(json_peer
, "type", "external");
7065 vty_out (vty
, ", external");
7069 else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
)
7073 json_object_boolean_true_add(json_path
, "aggregated");
7074 json_object_boolean_true_add(json_path
, "local");
7078 vty_out (vty
, ", aggregated, local");
7081 else if (binfo
->type
!= ZEBRA_ROUTE_BGP
)
7084 json_object_boolean_true_add(json_path
, "sourced");
7086 vty_out (vty
, ", sourced");
7092 json_object_boolean_true_add(json_path
, "sourced");
7093 json_object_boolean_true_add(json_path
, "local");
7097 vty_out (vty
, ", sourced, local");
7101 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
7104 json_object_boolean_true_add(json_path
, "atomicAggregate");
7106 vty_out (vty
, ", atomic-aggregate");
7109 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_MULTIPATH
) ||
7110 (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
) &&
7111 bgp_info_mpath_count (binfo
)))
7114 json_object_boolean_true_add(json_path
, "multipath");
7116 vty_out (vty
, ", multipath");
7119 // Mark the bestpath(s)
7120 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DMED_SELECTED
))
7122 first_as
= aspath_get_first_as(attr
->aspath
);
7127 json_bestpath
= json_object_new_object();
7128 json_object_int_add(json_bestpath
, "bestpathFromAs", first_as
);
7133 vty_out (vty
, ", bestpath-from-AS %d", first_as
);
7135 vty_out (vty
, ", bestpath-from-AS Local");
7139 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
))
7144 json_bestpath
= json_object_new_object();
7145 json_object_boolean_true_add(json_bestpath
, "overall");
7148 vty_out (vty
, ", best");
7152 json_object_object_add(json_path
, "bestpath", json_bestpath
);
7155 vty_out (vty
, "%s", VTY_NEWLINE
);
7157 /* Line 4 display Community */
7158 if (attr
->community
)
7162 json_object_lock(attr
->community
->json
);
7163 json_object_object_add(json_path
, "community", attr
->community
->json
);
7167 vty_out (vty
, " Community: %s%s", attr
->community
->str
,
7172 /* Line 5 display Extended-community */
7173 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
7177 json_ext_community
= json_object_new_object();
7178 json_object_string_add(json_ext_community
, "string", attr
->extra
->ecommunity
->str
);
7179 json_object_object_add(json_path
, "extendedCommunity", json_ext_community
);
7183 vty_out (vty
, " Extended Community: %s%s",
7184 attr
->extra
->ecommunity
->str
, VTY_NEWLINE
);
7188 /* Line 6 display Large community */
7189 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7190 vty_out (vty
, " Large Community: %s%s",
7191 attr
->extra
->lcommunity
->str
, VTY_NEWLINE
);
7193 /* Line 7 display Originator, Cluster-id */
7194 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) ||
7195 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)))
7197 assert (attr
->extra
);
7198 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7201 json_object_string_add(json_path
, "originatorId", inet_ntoa (attr
->extra
->originator_id
));
7203 vty_out (vty
, " Originator: %s",
7204 inet_ntoa (attr
->extra
->originator_id
));
7207 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))
7213 json_cluster_list
= json_object_new_object();
7214 json_cluster_list_list
= json_object_new_array();
7216 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7218 json_string
= json_object_new_string(inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7219 json_object_array_add(json_cluster_list_list
, json_string
);
7222 /* struct cluster_list does not have "str" variable like
7223 * aspath and community do. Add this someday if someone
7225 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7227 json_object_object_add(json_cluster_list
, "list", json_cluster_list_list
);
7228 json_object_object_add(json_path
, "clusterList", json_cluster_list
);
7232 vty_out (vty
, ", Cluster list: ");
7234 for (i
= 0; i
< attr
->extra
->cluster
->length
/ 4; i
++)
7236 vty_out (vty
, "%s ",
7237 inet_ntoa (attr
->extra
->cluster
->list
[i
]));
7243 vty_out (vty
, "%s", VTY_NEWLINE
);
7246 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7247 bgp_damp_info_vty (vty
, binfo
, json_path
);
7249 /* Line 8 display Addpath IDs */
7250 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
)
7254 json_object_int_add(json_path
, "addpathRxId", binfo
->addpath_rx_id
);
7255 json_object_int_add(json_path
, "addpathTxId", binfo
->addpath_tx_id
);
7259 vty_out (vty
, " AddPath ID: RX %u, TX %u%s",
7260 binfo
->addpath_rx_id
, binfo
->addpath_tx_id
,
7265 /* If we used addpath to TX a non-bestpath we need to display
7266 * "Advertised to" on a path-by-path basis */
7267 if (bgp
->addpath_tx_used
[afi
][safi
])
7271 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7273 addpath_capable
= bgp_addpath_encode_tx (peer
, afi
, safi
);
7274 has_adj
= bgp_adj_out_lookup (peer
, binfo
->net
, binfo
->addpath_tx_id
);
7276 if ((addpath_capable
&& has_adj
) ||
7277 (!addpath_capable
&& has_adj
&& CHECK_FLAG (binfo
->flags
, BGP_INFO_SELECTED
)))
7279 if (json_path
&& !json_adv_to
)
7280 json_adv_to
= json_object_new_object();
7282 route_vty_out_advertised_to(vty
, peer
, &first
,
7292 json_object_object_add(json_path
, "advertisedTo", json_adv_to
);
7299 vty_out (vty
, "%s", VTY_NEWLINE
);
7304 /* Line 9 display Uptime */
7305 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7308 json_last_update
= json_object_new_object();
7309 json_object_int_add(json_last_update
, "epoch", tbuf
);
7310 json_object_string_add(json_last_update
, "string", ctime(&tbuf
));
7311 json_object_object_add(json_path
, "lastUpdate", json_last_update
);
7314 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
7317 /* We've constructed the json object for this path, add it to the json
7322 if (json_nexthop_global
|| json_nexthop_ll
)
7324 json_nexthops
= json_object_new_array();
7326 if (json_nexthop_global
)
7327 json_object_array_add(json_nexthops
, json_nexthop_global
);
7329 if (json_nexthop_ll
)
7330 json_object_array_add(json_nexthops
, json_nexthop_ll
);
7332 json_object_object_add(json_path
, "nexthops", json_nexthops
);
7335 json_object_object_add(json_path
, "peer", json_peer
);
7336 json_object_array_add(json_paths
, json_path
);
7339 vty_out (vty
, "%s", VTY_NEWLINE
);
7342 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7343 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7344 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7347 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
7348 const char *prefix_list_str
, afi_t afi
,
7349 safi_t safi
, enum bgp_show_type type
);
7351 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
7352 const char *filter
, afi_t afi
,
7353 safi_t safi
, enum bgp_show_type type
);
7355 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
7356 const char *rmap_str
, afi_t afi
,
7357 safi_t safi
, enum bgp_show_type type
);
7359 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
7360 const char *com
, int exact
,
7361 afi_t afi
, safi_t safi
);
7363 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
7364 const char *prefix
, afi_t afi
,
7365 safi_t safi
, enum bgp_show_type type
);
7367 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
7368 safi_t safi
, enum bgp_show_type type
);
7370 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7371 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
);
7374 bgp_show_table (struct vty
*vty
, struct bgp
*bgp
, struct bgp_table
*table
,
7375 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7377 struct bgp_info
*ri
;
7378 struct bgp_node
*rn
;
7381 unsigned long output_count
;
7382 unsigned long total_count
;
7386 json_object
*json_paths
= NULL
;
7391 vty_out (vty
, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
7392 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
7393 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default" : bgp
->name
,
7394 table
->version
, inet_ntoa (bgp
->router_id
));
7395 json_paths
= json_object_new_object();
7398 /* This is first entry point, so reset total line. */
7402 /* Start processing of routes. */
7403 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
7404 if (rn
->info
!= NULL
)
7407 if (!first
&& use_json
)
7412 json_paths
= json_object_new_array();
7416 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7419 if (type
== bgp_show_type_flap_statistics
7420 || type
== bgp_show_type_flap_neighbor
7421 || type
== bgp_show_type_dampend_paths
7422 || type
== bgp_show_type_damp_neighbor
)
7424 if (!(ri
->extra
&& ri
->extra
->damp_info
))
7427 if (type
== bgp_show_type_regexp
)
7429 regex_t
*regex
= output_arg
;
7431 if (bgp_regexec (regex
, ri
->attr
->aspath
) == REG_NOMATCH
)
7434 if (type
== bgp_show_type_prefix_list
)
7436 struct prefix_list
*plist
= output_arg
;
7438 if (prefix_list_apply (plist
, &rn
->p
) != PREFIX_PERMIT
)
7441 if (type
== bgp_show_type_filter_list
)
7443 struct as_list
*as_list
= output_arg
;
7445 if (as_list_apply (as_list
, ri
->attr
->aspath
) != AS_FILTER_PERMIT
)
7448 if (type
== bgp_show_type_route_map
)
7450 struct route_map
*rmap
= output_arg
;
7451 struct bgp_info binfo
;
7452 struct attr dummy_attr
;
7453 struct attr_extra dummy_extra
;
7456 dummy_attr
.extra
= &dummy_extra
;
7457 bgp_attr_dup (&dummy_attr
, ri
->attr
);
7459 binfo
.peer
= ri
->peer
;
7460 binfo
.attr
= &dummy_attr
;
7462 ret
= route_map_apply (rmap
, &rn
->p
, RMAP_BGP
, &binfo
);
7463 if (ret
== RMAP_DENYMATCH
)
7466 if (type
== bgp_show_type_neighbor
7467 || type
== bgp_show_type_flap_neighbor
7468 || type
== bgp_show_type_damp_neighbor
)
7470 union sockunion
*su
= output_arg
;
7472 if (ri
->peer
== NULL
||
7473 ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
7476 if (type
== bgp_show_type_cidr_only
)
7478 u_int32_t destination
;
7480 destination
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
7481 if (IN_CLASSC (destination
) && rn
->p
.prefixlen
== 24)
7483 if (IN_CLASSB (destination
) && rn
->p
.prefixlen
== 16)
7485 if (IN_CLASSA (destination
) && rn
->p
.prefixlen
== 8)
7488 if (type
== bgp_show_type_prefix_longer
)
7490 struct prefix
*p
= output_arg
;
7492 if (! prefix_match (p
, &rn
->p
))
7495 if (type
== bgp_show_type_community_all
)
7497 if (! ri
->attr
->community
)
7500 if (type
== bgp_show_type_community
)
7502 struct community
*com
= output_arg
;
7504 if (! ri
->attr
->community
||
7505 ! community_match (ri
->attr
->community
, com
))
7508 if (type
== bgp_show_type_community_exact
)
7510 struct community
*com
= output_arg
;
7512 if (! ri
->attr
->community
||
7513 ! community_cmp (ri
->attr
->community
, com
))
7516 if (type
== bgp_show_type_community_list
)
7518 struct community_list
*list
= output_arg
;
7520 if (! community_list_match (ri
->attr
->community
, list
))
7523 if (type
== bgp_show_type_community_list_exact
)
7525 struct community_list
*list
= output_arg
;
7527 if (! community_list_exact_match (ri
->attr
->community
, list
))
7530 if (type
== bgp_show_type_lcommunity
)
7532 struct lcommunity
*lcom
= output_arg
;
7534 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
||
7535 ! lcommunity_match (ri
->attr
->extra
->lcommunity
, lcom
))
7538 if (type
== bgp_show_type_lcommunity_list
)
7540 struct community_list
*list
= output_arg
;
7542 if (! ri
->attr
->extra
||
7543 ! lcommunity_list_match (ri
->attr
->extra
->lcommunity
, list
))
7546 if (type
== bgp_show_type_lcommunity_all
)
7548 if (! ri
->attr
->extra
|| ! ri
->attr
->extra
->lcommunity
)
7551 if (type
== bgp_show_type_dampend_paths
7552 || type
== bgp_show_type_damp_neighbor
)
7554 if (! CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
)
7555 || CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
7559 if (!use_json
&& header
)
7561 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
7562 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7563 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
7564 if (type
== bgp_show_type_dampend_paths
7565 || type
== bgp_show_type_damp_neighbor
)
7566 vty_out (vty
, BGP_SHOW_DAMP_HEADER
, VTY_NEWLINE
);
7567 else if (type
== bgp_show_type_flap_statistics
7568 || type
== bgp_show_type_flap_neighbor
)
7569 vty_out (vty
, BGP_SHOW_FLAP_HEADER
, VTY_NEWLINE
);
7571 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
7575 if (type
== bgp_show_type_dampend_paths
7576 || type
== bgp_show_type_damp_neighbor
)
7577 damp_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7578 else if (type
== bgp_show_type_flap_statistics
7579 || type
== bgp_show_type_flap_neighbor
)
7580 flap_route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, use_json
, json_paths
);
7582 route_vty_out (vty
, &rn
->p
, ri
, display
, SAFI_UNICAST
, json_paths
);
7592 sprintf(buf2
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
), p
->prefixlen
);
7593 vty_out (vty
, "\"%s\": ", buf2
);
7594 vty_out (vty
, "%s", json_object_to_json_string (json_paths
));
7595 json_object_free (json_paths
);
7604 json_object_free (json_paths
);
7605 vty_out (vty
, " } }%s", VTY_NEWLINE
);
7609 /* No route is displayed */
7610 if (output_count
== 0)
7612 if (type
== bgp_show_type_normal
)
7613 vty_out (vty
, "No BGP prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
7616 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
7617 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
7624 bgp_show (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
7625 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
7627 struct bgp_table
*table
;
7631 bgp
= bgp_get_default ();
7637 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
7640 /* use MPLS and ENCAP specific shows until they are merged */
7641 if (safi
== SAFI_MPLS_VPN
)
7643 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
,
7646 if (safi
== SAFI_ENCAP
)
7648 return bgp_show_encap(vty
, afi
, NULL
, type
, output_arg
,
7653 table
= bgp
->rib
[afi
][safi
];
7655 return bgp_show_table (vty
, bgp
, table
, type
, output_arg
,
7660 bgp_show_all_instances_routes_vty (struct vty
*vty
, afi_t afi
, safi_t safi
,
7663 struct listnode
*node
, *nnode
;
7665 struct bgp_table
*table
;
7669 vty_out (vty
, "{%s", VTY_NEWLINE
);
7671 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
7676 vty_out (vty
, ",%s", VTY_NEWLINE
);
7680 vty_out(vty
, "\"%s\":", (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7681 ? "Default" : bgp
->name
);
7685 vty_out (vty
, "%sInstance %s:%s",
7687 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7688 ? "Default" : bgp
->name
,
7691 table
= bgp
->rib
[afi
][safi
];
7692 bgp_show_table (vty
, bgp
, table
,
7693 bgp_show_type_normal
, NULL
, use_json
);
7698 vty_out (vty
, "}%s", VTY_NEWLINE
);
7701 /* Header of detailed BGP route information */
7703 route_vty_out_detail_header (struct vty
*vty
, struct bgp
*bgp
,
7704 struct bgp_node
*rn
,
7705 struct prefix_rd
*prd
, afi_t afi
, safi_t safi
,
7708 struct bgp_info
*ri
;
7711 struct listnode
*node
, *nnode
;
7712 char buf1
[INET6_ADDRSTRLEN
];
7713 char buf2
[INET6_ADDRSTRLEN
];
7718 int no_advertise
= 0;
7721 json_object
*json_adv_to
= NULL
;
7727 json_object_string_add(json
, "prefix", inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
));
7728 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
7732 vty_out (vty
, "BGP routing table entry for %s%s%s/%d%s",
7733 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) ?
7734 prefix_rd2str (prd
, buf1
, RD_ADDRSTRLEN
) : ""),
7735 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":" : "",
7736 inet_ntop (p
->family
, &p
->u
.prefix
, buf2
, INET6_ADDRSTRLEN
),
7737 p
->prefixlen
, VTY_NEWLINE
);
7740 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7743 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))
7746 if (ri
->extra
&& ri
->extra
->suppress
)
7748 if (ri
->attr
->community
!= NULL
)
7750 if (community_include (ri
->attr
->community
, COMMUNITY_NO_ADVERTISE
))
7752 if (community_include (ri
->attr
->community
, COMMUNITY_NO_EXPORT
))
7754 if (community_include (ri
->attr
->community
, COMMUNITY_LOCAL_AS
))
7762 vty_out (vty
, "Paths: (%d available", count
);
7765 vty_out (vty
, ", best #%d", best
);
7766 if (safi
== SAFI_UNICAST
)
7767 vty_out (vty
, ", table %s",
7768 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
7769 ? "Default-IP-Routing-Table" : bgp
->name
);
7772 vty_out (vty
, ", no best path");
7775 vty_out (vty
, ", not advertised to any peer");
7777 vty_out (vty
, ", not advertised to EBGP peer");
7779 vty_out (vty
, ", not advertised outside local AS");
7782 vty_out (vty
, ", Advertisements suppressed by an aggregate.");
7783 vty_out (vty
, ")%s", VTY_NEWLINE
);
7786 /* If we are not using addpath then we can display Advertised to and that will
7787 * show what peers we advertised the bestpath to. If we are using addpath
7788 * though then we must display Advertised to on a path-by-path basis. */
7789 if (!bgp
->addpath_tx_used
[afi
][safi
])
7791 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
7793 if (bgp_adj_out_lookup (peer
, rn
, 0))
7795 if (json
&& !json_adv_to
)
7796 json_adv_to
= json_object_new_object();
7798 route_vty_out_advertised_to(vty
, peer
, &first
,
7799 " Advertised to non peer-group peers:\n ",
7808 json_object_object_add(json
, "advertisedTo", json_adv_to
);
7814 vty_out (vty
, " Not advertised to any peer");
7815 vty_out (vty
, "%s", VTY_NEWLINE
);
7820 /* Display specified route of BGP table. */
7822 bgp_show_route_in_table (struct vty
*vty
, struct bgp
*bgp
,
7823 struct bgp_table
*rib
, const char *ip_str
,
7824 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7825 int prefix_check
, enum bgp_path_type pathtype
,
7831 struct prefix match
;
7832 struct bgp_node
*rn
;
7833 struct bgp_node
*rm
;
7834 struct bgp_info
*ri
;
7835 struct bgp_table
*table
;
7836 json_object
*json
= NULL
;
7837 json_object
*json_paths
= NULL
;
7839 /* Check IP address argument. */
7840 ret
= str2prefix (ip_str
, &match
);
7843 vty_out (vty
, "address is malformed%s", VTY_NEWLINE
);
7847 match
.family
= afi2family (afi
);
7851 json
= json_object_new_object();
7852 json_paths
= json_object_new_array();
7855 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
)
7857 for (rn
= bgp_table_top (rib
); rn
; rn
= bgp_route_next (rn
))
7859 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
7862 if ((table
= rn
->info
) != NULL
)
7866 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
7868 if (prefix_check
&& rm
->p
.prefixlen
!= match
.prefixlen
)
7870 bgp_unlock_node (rm
);
7874 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
7878 route_vty_out_detail_header (vty
, bgp
, rm
, (struct prefix_rd
*)&rn
->p
,
7879 AFI_IP
, safi
, json
);
7884 if (pathtype
== BGP_PATH_ALL
||
7885 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7886 (pathtype
== BGP_PATH_MULTIPATH
&&
7887 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7888 route_vty_out_detail (vty
, bgp
, &rm
->p
, ri
, AFI_IP
, safi
, json_paths
);
7891 bgp_unlock_node (rm
);
7900 if ((rn
= bgp_node_match (rib
, &match
)) != NULL
)
7902 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
7904 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
7908 route_vty_out_detail_header (vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
7913 if (pathtype
== BGP_PATH_ALL
||
7914 (pathtype
== BGP_PATH_BESTPATH
&& CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)) ||
7915 (pathtype
== BGP_PATH_MULTIPATH
&&
7916 (CHECK_FLAG (ri
->flags
, BGP_INFO_MULTIPATH
) || CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
))))
7917 route_vty_out_detail (vty
, bgp
, &rn
->p
, ri
, afi
, safi
, json_paths
);
7921 bgp_unlock_node (rn
);
7928 json_object_object_add(json
, "paths", json_paths
);
7930 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
7931 json_object_free(json
);
7937 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
7945 /* Display specified route of Main RIB */
7947 bgp_show_route (struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
7948 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
7949 int prefix_check
, enum bgp_path_type pathtype
,
7953 bgp
= bgp_get_default ();
7955 return bgp_show_route_in_table (vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
7956 afi
, safi
, prd
, prefix_check
, pathtype
,
7961 bgp_show_lcommunity (struct vty
*vty
, struct bgp
*bgp
, int argc
,
7962 struct cmd_token
**argv
, afi_t afi
, safi_t safi
, u_char uj
)
7964 struct lcommunity
*lcom
;
7970 b
= buffer_new (1024);
7971 for (i
= 0; i
< argc
; i
++)
7974 buffer_putc (b
, ' ');
7977 if (strmatch (argv
[i
]->text
, "<AA:BB:CC>"))
7980 buffer_putstr (b
, argv
[i
]->arg
);
7984 buffer_putc (b
, '\0');
7986 str
= buffer_getstr (b
);
7989 lcom
= lcommunity_str2com (str
);
7990 XFREE (MTYPE_TMP
, str
);
7993 vty_out (vty
, "%% Large-community malformed: %s", VTY_NEWLINE
);
7997 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
, uj
);
8001 bgp_show_lcommunity_list (struct vty
*vty
, struct bgp
*bgp
, const char *lcom
,
8002 afi_t afi
, safi_t safi
, u_char uj
)
8004 struct community_list
*list
;
8006 list
= community_list_lookup (bgp_clist
, lcom
, LARGE_COMMUNITY_LIST_MASTER
);
8009 vty_out (vty
, "%% %s is not a valid large-community-list name%s", lcom
,
8014 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
, list
, uj
);
8017 DEFUN (show_ip_bgp_large_community_list
,
8018 show_ip_bgp_large_community_list_cmd
,
8019 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
8023 BGP_INSTANCE_HELP_STR
8026 "Address Family modifier\n"
8027 "Address Family modifier\n"
8028 "Address Family modifier\n"
8029 "Address Family modifier\n"
8030 "Display routes matching the large-community-list\n"
8031 "large-community-list number\n"
8032 "large-community-list name\n"
8036 afi_t afi
= AFI_IP6
;
8037 safi_t safi
= SAFI_UNICAST
;
8040 if (argv_find (argv
, argc
, "ip", &idx
))
8042 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8043 vrf
= argv
[++idx
]->arg
;
8044 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8046 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8047 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8048 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8051 int uj
= use_json (argc
, argv
);
8053 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8056 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8060 argv_find (argv
, argc
, "large-community-list", &idx
);
8061 return bgp_show_lcommunity_list (vty
, bgp
, argv
[idx
+1]->arg
, afi
, safi
, uj
);
8063 DEFUN (show_ip_bgp_large_community
,
8064 show_ip_bgp_large_community_cmd
,
8065 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
8069 BGP_INSTANCE_HELP_STR
8072 "Address Family modifier\n"
8073 "Address Family modifier\n"
8074 "Address Family modifier\n"
8075 "Address Family modifier\n"
8076 "Display routes matching the large-communities\n"
8077 "List of large-community numbers\n"
8081 afi_t afi
= AFI_IP6
;
8082 safi_t safi
= SAFI_UNICAST
;
8085 if (argv_find (argv
, argc
, "ip", &idx
))
8087 if (argv_find (argv
, argc
, "view", &idx
) || argv_find (argv
, argc
, "vrf", &idx
))
8088 vrf
= argv
[++idx
]->arg
;
8089 if (argv_find (argv
, argc
, "ipv4", &idx
) || argv_find (argv
, argc
, "ipv6", &idx
))
8091 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8092 if (argv_find (argv
, argc
, "unicast", &idx
) || argv_find (argv
, argc
, "multicast", &idx
))
8093 safi
= bgp_vty_safi_from_arg (argv
[idx
]->text
);
8096 int uj
= use_json (argc
, argv
);
8098 struct bgp
*bgp
= bgp_lookup_by_name (vrf
);
8101 vty_out (vty
, "Can't find BGP instance %s%s", vrf
, VTY_NEWLINE
);
8105 argv_find (argv
, argc
, "large-community", &idx
);
8106 if (strmatch(argv
[idx
+1]->text
, "AA:BB:CC"))
8107 return bgp_show_lcommunity (vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8109 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_all
, NULL
, uj
);
8112 static int bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
);
8114 /* BGP route print out function. */
8117 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]\
8120 |dampening <flap-statistics|dampened-paths|parameters>\
8125 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8126 |community-list <(1-500)|WORD> [exact-match]\
8127 |A.B.C.D/M longer-prefixes\
8128 |X:X::X:X/M longer-prefixes>\
8133 BGP_INSTANCE_HELP_STR
8136 "Display only routes with non-natural netmasks\n"
8137 "Display detailed information about dampening\n"
8138 "Display flap statistics of routes\n"
8139 "Display paths suppressed due to dampening\n"
8140 "Display detail of configured dampening parameters\n"
8141 "Display routes matching the route-map\n"
8142 "A route-map to match on\n"
8143 "Display routes conforming to the prefix-list\n"
8144 "Prefix-list name\n"
8145 "Display routes conforming to the filter-list\n"
8146 "Regular expression access list name\n"
8147 "BGP RIB advertisement statistics\n"
8148 "Display routes matching the communities\n"
8150 "Do not send outside local AS (well-known community)\n"
8151 "Do not advertise to any peer (well-known community)\n"
8152 "Do not export to next AS (well-known community)\n"
8153 "Exact match of the communities\n"
8154 "Display routes matching the community-list\n"
8155 "community-list number\n"
8156 "community-list name\n"
8157 "Exact match of the communities\n"
8159 "Display route and more specific routes\n"
8161 "Display route and more specific routes\n"
8164 vrf_id_t vrf
= VRF_DEFAULT
;
8165 afi_t afi
= AFI_IP6
;
8166 safi_t safi
= SAFI_UNICAST
;
8167 int exact_match
= 0;
8168 enum bgp_show_type sh_type
= bgp_show_type_normal
;
8169 struct bgp
*bgp
= NULL
;
8172 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8176 int uj
= use_json (argc
, argv
);
8179 bgp
= bgp_lookup_by_vrf_id (vrf
);
8182 if (vrf
== VRF_DEFAULT
)
8183 vty_out (vty
, "Can't find BGP instance (default)%s", VTY_NEWLINE
);
8185 vty_out (vty
, "Can't find BGP instance %d%s", vrf
, VTY_NEWLINE
);
8189 if (argv_find(argv
, argc
, "cidr-only", &idx
))
8190 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
, NULL
, uj
);
8192 if (argv_find(argv
, argc
, "dampening", &idx
))
8194 if (argv_find (argv
, argc
, "dampened-paths", &idx
))
8195 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_dampend_paths
, NULL
, uj
);
8196 else if (argv_find (argv
, argc
, "flap-statistics", &idx
))
8197 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_flap_statistics
, NULL
, uj
);
8198 else if (argv_find (argv
, argc
, "parameters", &idx
))
8199 return bgp_show_dampening_parameters (vty
, afi
, safi
);
8202 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8203 return bgp_show_prefix_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_list
);
8205 if (argv_find(argv
, argc
, "filter-list", &idx
))
8206 return bgp_show_filter_list (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_filter_list
);
8208 if (argv_find(argv
, argc
, "statistics", &idx
))
8209 return bgp_table_stats (vty
, bgp
, afi
, safi
);
8211 if (argv_find(argv
, argc
, "route-map", &idx
))
8212 return bgp_show_route_map (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_route_map
);
8214 if (argv_find(argv
, argc
, "community", &idx
))
8216 /* show a specific community */
8217 if (argv_find (argv
, argc
, "local-AS", &idx
) ||
8218 argv_find (argv
, argc
, "no-advertise", &idx
) ||
8219 argv_find (argv
, argc
, "no-export", &idx
))
8221 if (argv_find (argv
, argc
, "exact_match", &idx
))
8223 return bgp_show_community (vty
, bgp
, argc
, argv
, exact_match
, afi
, safi
);
8225 /* show all communities */
8227 return bgp_show (vty
, bgp
, afi
, safi
, bgp_show_type_community_all
, NULL
, uj
);
8230 if (argv_find(argv
, argc
, "community-list", &idx
))
8232 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8233 if (++idx
< argc
&& strmatch (argv
[idx
]->text
, "exact-match"))
8235 return bgp_show_community_list (vty
, bgp
, clist_number_or_name
, exact_match
, afi
, safi
);
8238 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
) || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
8239 return bgp_show_prefix_longer (vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
, bgp_show_type_prefix_longer
);
8241 if (safi
== SAFI_MPLS_VPN
)
8242 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, uj
);
8243 else if (safi
== SAFI_ENCAP
)
8244 return bgp_show_encap (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0);
8246 return bgp_show (vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
8249 DEFUN (show_ip_bgp_route
,
8250 show_ip_bgp_route_cmd
,
8251 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]]"
8252 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8256 BGP_INSTANCE_HELP_STR
8259 "Network in the BGP routing table to display\n"
8261 "Network in the BGP routing table to display\n"
8263 "Display only the bestpath\n"
8264 "Display only multipaths\n"
8267 int prefix_check
= 0;
8269 afi_t afi
= AFI_IP6
;
8270 safi_t safi
= SAFI_UNICAST
;
8271 vrf_id_t vrf
= VRF_DEFAULT
;;
8272 char *prefix
= NULL
;
8273 struct bgp
*bgp
= NULL
;
8274 enum bgp_path_type path_type
;
8275 u_char uj
= use_json(argc
, argv
);
8279 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8285 bgp
= bgp_lookup_by_vrf_id (vrf
);
8288 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
8294 vty_out (vty
, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE
);
8298 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8299 if (argv_find (argv
, argc
, "A.B.C.D", &idx
) || argv_find (argv
, argc
, "X:X::X:X", &idx
))
8301 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
) || argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
8304 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
) && afi
!= AFI_IP6
)
8306 vty_out (vty
, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE
);
8309 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
) && afi
!= AFI_IP
)
8311 vty_out (vty
, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE
);
8315 prefix
= argv
[idx
]->arg
;
8317 /* [<bestpath|multipath>] */
8318 if (argv_find (argv
, argc
, "bestpath", &idx
))
8319 path_type
= BGP_PATH_BESTPATH
;
8320 else if (argv_find (argv
, argc
, "multipath", &idx
))
8321 path_type
= BGP_PATH_MULTIPATH
;
8323 path_type
= BGP_PATH_ALL
;
8325 return bgp_show_route (vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
, path_type
, uj
);
8328 DEFUN (show_ip_bgp_regexp
,
8329 show_ip_bgp_regexp_cmd
,
8330 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] regexp REGEX...",
8334 BGP_INSTANCE_HELP_STR
8337 "Display routes matching the AS path regular expression\n"
8338 "A regular-expression to match the BGP AS paths\n")
8340 vrf_id_t vrf
= VRF_DEFAULT
;
8341 afi_t afi
= AFI_IP6
;
8342 safi_t safi
= SAFI_UNICAST
;
8345 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8349 // get index of regex
8350 argv_find (argv
, argc
, "regexp", &idx
);
8353 char *regstr
= argv_concat (argv
, argc
, idx
);
8354 int rc
= bgp_show_regexp (vty
, (const char *) regstr
, afi
, safi
, bgp_show_type_regexp
);
8355 XFREE (MTYPE_TMP
, regstr
);
8359 DEFUN (show_ip_bgp_instance_all
,
8360 show_ip_bgp_instance_all_cmd
,
8361 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] [json]",
8365 BGP_INSTANCE_ALL_HELP_STR
8370 vrf_id_t vrf
= VRF_DEFAULT
;
8372 safi_t safi
= SAFI_UNICAST
;
8375 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
8379 int uj
= use_json (argc
, argv
);
8382 bgp_show_all_instances_routes_vty (vty
, afi
, safi
, uj
);
8387 bgp_show_regexp (struct vty
*vty
, const char *regstr
, afi_t afi
,
8388 safi_t safi
, enum bgp_show_type type
)
8395 regex
= bgp_regcomp (regstr
);
8398 vty_out (vty
, "Can't compile regexp %s%s", regstr
, VTY_NEWLINE
);
8402 rc
= bgp_show (vty
, NULL
, afi
, safi
, type
, regex
, 0);
8403 bgp_regex_free (regex
);
8408 bgp_show_prefix_list (struct vty
*vty
, struct bgp
*bgp
,
8409 const char *prefix_list_str
, afi_t afi
,
8410 safi_t safi
, enum bgp_show_type type
)
8412 struct prefix_list
*plist
;
8414 plist
= prefix_list_lookup (afi
, prefix_list_str
);
8417 vty_out (vty
, "%% %s is not a valid prefix-list name%s",
8418 prefix_list_str
, VTY_NEWLINE
);
8422 return bgp_show (vty
, bgp
, afi
, safi
, type
, plist
, 0);
8426 bgp_show_filter_list (struct vty
*vty
, struct bgp
*bgp
,
8427 const char *filter
, afi_t afi
,
8428 safi_t safi
, enum bgp_show_type type
)
8430 struct as_list
*as_list
;
8432 as_list
= as_list_lookup (filter
);
8433 if (as_list
== NULL
)
8435 vty_out (vty
, "%% %s is not a valid AS-path access-list name%s", filter
, VTY_NEWLINE
);
8439 return bgp_show (vty
, bgp
, afi
, safi
, type
, as_list
, 0);
8443 bgp_show_route_map (struct vty
*vty
, struct bgp
*bgp
,
8444 const char *rmap_str
, afi_t afi
,
8445 safi_t safi
, enum bgp_show_type type
)
8447 struct route_map
*rmap
;
8449 rmap
= route_map_lookup_by_name (rmap_str
);
8452 vty_out (vty
, "%% %s is not a valid route-map name%s",
8453 rmap_str
, VTY_NEWLINE
);
8457 return bgp_show (vty
, bgp
, afi
, safi
, type
, rmap
, 0);
8461 bgp_show_community (struct vty
*vty
, struct bgp
*bgp
, int argc
,
8462 struct cmd_token
**argv
, int exact
, afi_t afi
, safi_t safi
)
8464 struct community
*com
;
8470 b
= buffer_new (1024);
8471 for (i
= 0; i
< argc
; i
++)
8474 buffer_putc (b
, ' ');
8477 if ((strcmp (argv
[i
]->arg
, "unicast") == 0) || (strcmp (argv
[i
]->arg
, "multicast") == 0))
8482 buffer_putstr (b
, argv
[i
]->arg
);
8484 buffer_putc (b
, '\0');
8486 str
= buffer_getstr (b
);
8489 com
= community_str2com (str
);
8490 XFREE (MTYPE_TMP
, str
);
8493 vty_out (vty
, "%% Community malformed: %s", VTY_NEWLINE
);
8497 return bgp_show (vty
, bgp
, afi
, safi
,
8498 (exact
? bgp_show_type_community_exact
:
8499 bgp_show_type_community
), com
, 0);
8503 bgp_show_community_list (struct vty
*vty
, struct bgp
*bgp
,
8504 const char *com
, int exact
,
8505 afi_t afi
, safi_t safi
)
8507 struct community_list
*list
;
8509 list
= community_list_lookup (bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
8512 vty_out (vty
, "%% %s is not a valid community-list name%s", com
,
8517 return bgp_show (vty
, bgp
, afi
, safi
,
8518 (exact
? bgp_show_type_community_list_exact
:
8519 bgp_show_type_community_list
), list
, 0);
8523 bgp_show_prefix_longer (struct vty
*vty
, struct bgp
*bgp
,
8524 const char *prefix
, afi_t afi
,
8525 safi_t safi
, enum bgp_show_type type
)
8532 ret
= str2prefix (prefix
, p
);
8535 vty_out (vty
, "%% Malformed Prefix%s", VTY_NEWLINE
);
8539 ret
= bgp_show (vty
, bgp
, afi
, safi
, type
, p
, 0);
8544 static struct peer
*
8545 peer_lookup_in_view (struct vty
*vty
, struct bgp
*bgp
,
8546 const char *ip_str
, u_char use_json
)
8552 /* Get peer sockunion. */
8553 ret
= str2sockunion (ip_str
, &su
);
8556 peer
= peer_lookup_by_conf_if (bgp
, ip_str
);
8559 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8565 json_object
*json_no
= NULL
;
8566 json_no
= json_object_new_object();
8567 json_object_string_add(json_no
, "malformedAddressOrName", ip_str
);
8568 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8569 json_object_free(json_no
);
8572 vty_out (vty
, "%% Malformed address or name: %s%s", ip_str
, VTY_NEWLINE
);
8579 /* Peer structure lookup. */
8580 peer
= peer_lookup (bgp
, &su
);
8585 json_object
*json_no
= NULL
;
8586 json_no
= json_object_new_object();
8587 json_object_string_add(json_no
, "warning","No such neighbor");
8588 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
8589 json_object_free(json_no
);
8592 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
8601 BGP_STATS_MAXBITLEN
= 0,
8605 BGP_STATS_UNAGGREGATEABLE
,
8606 BGP_STATS_MAX_AGGREGATEABLE
,
8607 BGP_STATS_AGGREGATES
,
8609 BGP_STATS_ASPATH_COUNT
,
8610 BGP_STATS_ASPATH_MAXHOPS
,
8611 BGP_STATS_ASPATH_TOTHOPS
,
8612 BGP_STATS_ASPATH_MAXSIZE
,
8613 BGP_STATS_ASPATH_TOTSIZE
,
8614 BGP_STATS_ASN_HIGHEST
,
8618 static const char *table_stats_strs
[] =
8620 [BGP_STATS_PREFIXES
] = "Total Prefixes",
8621 [BGP_STATS_TOTPLEN
] = "Average prefix length",
8622 [BGP_STATS_RIB
] = "Total Advertisements",
8623 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
8624 [BGP_STATS_MAX_AGGREGATEABLE
] = "Maximum aggregateable prefixes",
8625 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
8626 [BGP_STATS_SPACE
] = "Address space advertised",
8627 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
8628 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
8629 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
8630 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
8631 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
8632 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
8633 [BGP_STATS_MAX
] = NULL
,
8636 struct bgp_table_stats
8638 struct bgp_table
*table
;
8639 unsigned long long counts
[BGP_STATS_MAX
];
8643 #define TALLY_SIGFIG 100000
8644 static unsigned long
8645 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
8647 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
8648 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
8649 unsigned long ret
= newtot
/ count
;
8651 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
8659 bgp_table_stats_walker (struct thread
*t
)
8661 struct bgp_node
*rn
;
8662 struct bgp_node
*top
;
8663 struct bgp_table_stats
*ts
= THREAD_ARG (t
);
8664 unsigned int space
= 0;
8666 if (!(top
= bgp_table_top (ts
->table
)))
8669 switch (top
->p
.family
)
8672 space
= IPV4_MAX_BITLEN
;
8675 space
= IPV6_MAX_BITLEN
;
8679 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
8681 for (rn
= top
; rn
; rn
= bgp_route_next (rn
))
8683 struct bgp_info
*ri
;
8684 struct bgp_node
*prn
= bgp_node_parent_nolock (rn
);
8685 unsigned int rinum
= 0;
8693 ts
->counts
[BGP_STATS_PREFIXES
]++;
8694 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
8697 ts
->counts
[BGP_STATS_AVGPLEN
]
8698 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
8699 ts
->counts
[BGP_STATS_AVGPLEN
],
8703 /* check if the prefix is included by any other announcements */
8704 while (prn
&& !prn
->info
)
8705 prn
= bgp_node_parent_nolock (prn
);
8707 if (prn
== NULL
|| prn
== top
)
8709 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
8710 /* announced address space */
8712 ts
->counts
[BGP_STATS_SPACE
] += 1 << (space
- rn
->p
.prefixlen
);
8715 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
8717 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8720 ts
->counts
[BGP_STATS_RIB
]++;
8723 (CHECK_FLAG (ri
->attr
->flag
,
8724 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
))))
8725 ts
->counts
[BGP_STATS_AGGREGATES
]++;
8728 if (ri
->attr
&& ri
->attr
->aspath
)
8730 unsigned int hops
= aspath_count_hops (ri
->attr
->aspath
);
8731 unsigned int size
= aspath_size (ri
->attr
->aspath
);
8732 as_t highest
= aspath_highest (ri
->attr
->aspath
);
8734 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
8736 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
8737 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
8739 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
8740 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
8742 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
8743 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
8745 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
8746 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8747 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
8749 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
8750 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
8751 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
8754 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
8755 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
8763 bgp_table_stats (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
)
8765 struct bgp_table_stats ts
;
8768 if (!bgp
->rib
[afi
][safi
])
8770 vty_out (vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8771 afi
, safi
, VTY_NEWLINE
);
8775 memset (&ts
, 0, sizeof (ts
));
8776 ts
.table
= bgp
->rib
[afi
][safi
];
8777 thread_execute (bm
->master
, bgp_table_stats_walker
, &ts
, 0);
8779 vty_out (vty
, "BGP %s RIB statistics%s%s",
8780 afi_safi_print (afi
, safi
), VTY_NEWLINE
, VTY_NEWLINE
);
8782 for (i
= 0; i
< BGP_STATS_MAX
; i
++)
8784 if (!table_stats_strs
[i
])
8790 case BGP_STATS_ASPATH_AVGHOPS
:
8791 case BGP_STATS_ASPATH_AVGSIZE
:
8792 case BGP_STATS_AVGPLEN
:
8793 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8794 vty_out (vty
, "%12.2f",
8795 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
8798 case BGP_STATS_ASPATH_TOTHOPS
:
8799 case BGP_STATS_ASPATH_TOTSIZE
:
8800 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8801 vty_out (vty
, "%12.2f",
8803 (float)ts
.counts
[i
] /
8804 (float)ts
.counts
[BGP_STATS_ASPATH_COUNT
]
8807 case BGP_STATS_TOTPLEN
:
8808 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8809 vty_out (vty
, "%12.2f",
8811 (float)ts
.counts
[i
] /
8812 (float)ts
.counts
[BGP_STATS_PREFIXES
]
8815 case BGP_STATS_SPACE
:
8816 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8817 vty_out (vty
, "%12llu%s", ts
.counts
[i
], VTY_NEWLINE
);
8818 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 9)
8820 vty_out (vty
, "%30s: ", "%% announced ");
8821 vty_out (vty
, "%12.2f%s",
8822 100 * (float)ts
.counts
[BGP_STATS_SPACE
] /
8823 (float)((uint64_t)1UL << ts
.counts
[BGP_STATS_MAXBITLEN
]),
8825 vty_out (vty
, "%30s: ", "/8 equivalent ");
8826 vty_out (vty
, "%12.2f%s",
8827 (float)ts
.counts
[BGP_STATS_SPACE
] /
8828 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 8)),
8830 if (ts
.counts
[BGP_STATS_MAXBITLEN
] < 25)
8832 vty_out (vty
, "%30s: ", "/24 equivalent ");
8833 vty_out (vty
, "%12.2f",
8834 (float)ts
.counts
[BGP_STATS_SPACE
] /
8835 (float)(1UL << (ts
.counts
[BGP_STATS_MAXBITLEN
] - 24)));
8838 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
8839 vty_out (vty
, "%12llu", ts
.counts
[i
]);
8842 vty_out (vty
, "%s", VTY_NEWLINE
);
8857 PCOUNT_PFCNT
, /* the figure we display to users */
8861 static const char *pcount_strs
[] =
8863 [PCOUNT_ADJ_IN
] = "Adj-in",
8864 [PCOUNT_DAMPED
] = "Damped",
8865 [PCOUNT_REMOVED
] = "Removed",
8866 [PCOUNT_HISTORY
] = "History",
8867 [PCOUNT_STALE
] = "Stale",
8868 [PCOUNT_VALID
] = "Valid",
8869 [PCOUNT_ALL
] = "All RIB",
8870 [PCOUNT_COUNTED
] = "PfxCt counted",
8871 [PCOUNT_PFCNT
] = "Useable",
8872 [PCOUNT_MAX
] = NULL
,
8877 unsigned int count
[PCOUNT_MAX
];
8878 const struct peer
*peer
;
8879 const struct bgp_table
*table
;
8883 bgp_peer_count_walker (struct thread
*t
)
8885 struct bgp_node
*rn
;
8886 struct peer_pcounts
*pc
= THREAD_ARG (t
);
8887 const struct peer
*peer
= pc
->peer
;
8889 for (rn
= bgp_table_top (pc
->table
); rn
; rn
= bgp_route_next (rn
))
8891 struct bgp_adj_in
*ain
;
8892 struct bgp_info
*ri
;
8894 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
8895 if (ain
->peer
== peer
)
8896 pc
->count
[PCOUNT_ADJ_IN
]++;
8898 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
8900 char buf
[SU_ADDRSTRLEN
];
8902 if (ri
->peer
!= peer
)
8905 pc
->count
[PCOUNT_ALL
]++;
8907 if (CHECK_FLAG (ri
->flags
, BGP_INFO_DAMPED
))
8908 pc
->count
[PCOUNT_DAMPED
]++;
8909 if (CHECK_FLAG (ri
->flags
, BGP_INFO_HISTORY
))
8910 pc
->count
[PCOUNT_HISTORY
]++;
8911 if (CHECK_FLAG (ri
->flags
, BGP_INFO_REMOVED
))
8912 pc
->count
[PCOUNT_REMOVED
]++;
8913 if (CHECK_FLAG (ri
->flags
, BGP_INFO_STALE
))
8914 pc
->count
[PCOUNT_STALE
]++;
8915 if (CHECK_FLAG (ri
->flags
, BGP_INFO_VALID
))
8916 pc
->count
[PCOUNT_VALID
]++;
8917 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8918 pc
->count
[PCOUNT_PFCNT
]++;
8920 if (CHECK_FLAG (ri
->flags
, BGP_INFO_COUNTED
))
8922 pc
->count
[PCOUNT_COUNTED
]++;
8923 if (CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8924 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
8926 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8927 buf
, SU_ADDRSTRLEN
),
8933 if (!CHECK_FLAG (ri
->flags
, BGP_INFO_UNUSEABLE
))
8934 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
8936 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
,
8937 buf
, SU_ADDRSTRLEN
),
8947 bgp_peer_counts (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
, u_char use_json
)
8949 struct peer_pcounts pcounts
= { .peer
= peer
};
8951 json_object
*json
= NULL
;
8952 json_object
*json_loop
= NULL
;
8956 json
= json_object_new_object();
8957 json_loop
= json_object_new_object();
8960 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
8961 || !peer
->bgp
->rib
[afi
][safi
])
8965 json_object_string_add(json
, "warning", "No such neighbor or address family");
8966 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
8967 json_object_free(json
);
8970 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
8975 memset (&pcounts
, 0, sizeof(pcounts
));
8976 pcounts
.peer
= peer
;
8977 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
8979 /* in-place call via thread subsystem so as to record execution time
8980 * * stats for the thread-walk (i.e. ensure this can't be blamed on
8981 * * on just vty_read()).
8983 thread_execute (bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
8987 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
8988 json_object_string_add(json
, "multiProtocol", afi_safi_print (afi
, safi
));
8989 json_object_int_add(json
, "pfxCounter", peer
->pcount
[afi
][safi
]);
8991 for (i
= 0; i
< PCOUNT_MAX
; i
++)
8992 json_object_int_add(json_loop
, pcount_strs
[i
], pcounts
.count
[i
]);
8994 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
8996 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
8998 json_object_string_add(json
, "pfxctDriftFor", peer
->host
);
8999 json_object_string_add(json
, "recommended", "Please report this bug, with the above command output");
9001 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9002 json_object_free(json
);
9007 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
9009 vty_out (vty
, "Prefix counts for %s/%s, %s%s",
9010 peer
->hostname
, peer
->host
, afi_safi_print (afi
, safi
),
9015 vty_out (vty
, "Prefix counts for %s, %s%s",
9016 peer
->host
, afi_safi_print (afi
, safi
), VTY_NEWLINE
);
9019 vty_out (vty
, "PfxCt: %ld%s", peer
->pcount
[afi
][safi
], VTY_NEWLINE
);
9020 vty_out (vty
, "%sCounts from RIB table walk:%s%s",
9021 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
9023 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9024 vty_out (vty
, "%20s: %-10d%s", pcount_strs
[i
], pcounts
.count
[i
], VTY_NEWLINE
);
9026 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
])
9028 vty_out (vty
, "%s [pcount] PfxCt drift!%s",
9029 peer
->host
, VTY_NEWLINE
);
9030 vty_out (vty
, "Please report this bug, with the above command output%s",
9038 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9039 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9040 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
9041 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9045 BGP_INSTANCE_HELP_STR
9048 "Address Family modifier\n"
9049 "Address Family modifier\n"
9050 "Address Family modifier\n"
9051 "Address Family modifier\n"
9052 "Detailed information on TCP and BGP neighbor connections\n"
9053 "Neighbor to display information about\n"
9054 "Neighbor to display information about\n"
9055 "Neighbor on BGP configured interface\n"
9056 "Display detailed prefix count information\n"
9059 vrf_id_t vrf
= VRF_DEFAULT
;
9060 afi_t afi
= AFI_IP6
;
9061 safi_t safi
= SAFI_UNICAST
;
9064 struct bgp
*bgp
= NULL
;
9066 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9070 int uj
= use_json (argc
, argv
);
9075 bgp
= bgp_lookup_by_vrf_id (vrf
);
9080 json_object
*json_no
= NULL
;
9081 json_no
= json_object_new_object();
9082 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9083 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9084 json_object_free(json_no
);
9087 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9094 argv_find (argv
, argc
, "neighbors", &idx
);
9095 peer
= peer_lookup_in_view (vty
, bgp
, argv
[idx
+1]->arg
, uj
);
9099 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9102 #ifdef KEEP_OLD_VPN_COMMANDS
9103 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9104 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9105 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9110 "Display information about all VPNv4 NLRIs\n"
9111 "Detailed information on TCP and BGP neighbor connections\n"
9112 "Neighbor to display information about\n"
9113 "Neighbor to display information about\n"
9114 "Neighbor on BGP configured interface\n"
9115 "Display detailed prefix count information\n"
9120 u_char uj
= use_json(argc
, argv
);
9122 peer
= peer_lookup_in_view (vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9126 return bgp_peer_counts (vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9129 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9130 show_ip_bgp_vpn_all_route_prefix_cmd
,
9131 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9136 "Display information about all VPNv4 NLRIs\n"
9137 "Network in the BGP routing table to display\n"
9138 "Network in the BGP routing table to display\n"
9142 char *network
= NULL
;
9143 struct bgp
*bgp
= bgp_get_default();
9146 vty_out (vty
, "Can't find default instance%s", VTY_NEWLINE
);
9149 network
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
9150 network
= argv_find (argv
, argc
, "A.B.C.D/M", &idx
) ? argv
[idx
]->arg
: NULL
;
9151 return bgp_show_route (vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0, BGP_PATH_ALL
, use_json(argc
, argv
));
9153 #endif /* KEEP_OLD_VPN_COMMANDS */
9156 show_adj_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9157 int in
, const char *rmap_name
, u_char use_json
, json_object
*json
)
9159 struct bgp_table
*table
;
9160 struct bgp_adj_in
*ain
;
9161 struct bgp_adj_out
*adj
;
9162 unsigned long output_count
;
9163 unsigned long filtered_count
;
9164 struct bgp_node
*rn
;
9169 struct attr_extra extra
;
9171 struct update_subgroup
*subgrp
;
9172 json_object
*json_scode
= NULL
;
9173 json_object
*json_ocode
= NULL
;
9174 json_object
*json_ar
= NULL
;
9175 struct peer_af
*paf
;
9179 json_scode
= json_object_new_object();
9180 json_ocode
= json_object_new_object();
9181 json_ar
= json_object_new_object();
9183 json_object_string_add(json_scode
, "suppressed", "s");
9184 json_object_string_add(json_scode
, "damped", "d");
9185 json_object_string_add(json_scode
, "history", "h");
9186 json_object_string_add(json_scode
, "valid", "*");
9187 json_object_string_add(json_scode
, "best", ">");
9188 json_object_string_add(json_scode
, "multipath", "=");
9189 json_object_string_add(json_scode
, "internal", "i");
9190 json_object_string_add(json_scode
, "ribFailure", "r");
9191 json_object_string_add(json_scode
, "stale", "S");
9192 json_object_string_add(json_scode
, "removed", "R");
9194 json_object_string_add(json_ocode
, "igp", "i");
9195 json_object_string_add(json_ocode
, "egp", "e");
9196 json_object_string_add(json_ocode
, "incomplete", "?");
9205 json_object_string_add(json
, "alert", "no BGP");
9206 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9207 json_object_free(json
);
9210 vty_out (vty
, "%% No bgp%s", VTY_NEWLINE
);
9214 table
= bgp
->rib
[afi
][safi
];
9216 output_count
= filtered_count
= 0;
9217 subgrp
= peer_subgroup(peer
, afi
, safi
);
9219 if (!in
&& subgrp
&& CHECK_FLAG (subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
))
9223 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9224 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9225 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9226 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9227 json_object_string_add(json
, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9231 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
, inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9232 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9233 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9235 vty_out (vty
, "Originating default network 0.0.0.0%s%s",
9236 VTY_NEWLINE
, VTY_NEWLINE
);
9241 attr
.extra
= &extra
;
9242 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
9246 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9248 if (ain
->peer
== peer
)
9254 json_object_int_add(json
, "bgpTableVersion", 0);
9255 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9256 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9257 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9261 vty_out (vty
, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9262 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9263 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9270 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9275 bgp_attr_dup(&attr
, ain
->attr
);
9276 if (bgp_input_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
) != RMAP_DENY
)
9278 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9289 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
9290 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
9291 if (paf
->peer
== peer
)
9297 json_object_int_add(json
, "bgpTableVersion", table
->version
);
9298 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
9299 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
9300 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
9304 vty_out (vty
, "BGP table version is %" PRIu64
", local router ID is %s%s", table
->version
,
9305 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
9306 vty_out (vty
, BGP_SHOW_SCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9307 vty_out (vty
, BGP_SHOW_OCODE_HEADER
, VTY_NEWLINE
, VTY_NEWLINE
);
9315 vty_out (vty
, BGP_SHOW_HEADER
, VTY_NEWLINE
);
9321 bgp_attr_dup(&attr
, adj
->attr
);
9322 ret
= bgp_output_modifier(peer
, &rn
->p
, &attr
, afi
, safi
, rmap_name
);
9323 if (ret
!= RMAP_DENY
)
9325 route_vty_out_tmp (vty
, &rn
->p
, &attr
, safi
, use_json
, json_ar
);
9335 json_object_object_add(json
, "advertisedRoutes", json_ar
);
9337 if (output_count
!= 0)
9340 json_object_int_add(json
, "totalPrefixCounter", output_count
);
9342 vty_out (vty
, "%sTotal number of prefixes %ld%s",
9343 VTY_NEWLINE
, output_count
, VTY_NEWLINE
);
9347 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9348 json_object_free(json
);
9354 peer_adj_routes (struct vty
*vty
, struct peer
*peer
, afi_t afi
, safi_t safi
,
9355 int in
, const char *rmap_name
, u_char use_json
)
9357 json_object
*json
= NULL
;
9360 json
= json_object_new_object();
9362 if (!peer
|| !peer
->afc
[afi
][safi
])
9366 json_object_string_add(json
, "warning", "No such neighbor or address family");
9367 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9368 json_object_free(json
);
9371 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9376 if (in
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
))
9380 json_object_string_add(json
, "warning", "Inbound soft reconfiguration not enabled");
9381 vty_out (vty
, "%s%s", json_object_to_json_string(json
), VTY_NEWLINE
);
9382 json_object_free(json
);
9385 vty_out (vty
, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE
);
9390 show_adj_route (vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
9395 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
9396 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
9397 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9398 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9402 BGP_INSTANCE_HELP_STR
9405 "Detailed information on TCP and BGP neighbor connections\n"
9406 "Neighbor to display information about\n"
9407 "Neighbor to display information about\n"
9408 "Neighbor on BGP configured interface\n"
9409 "Display the received routes from neighbor\n"
9410 "Display the routes advertised to a BGP neighbor\n"
9411 "Route-map to modify the attributes\n"
9412 "Name of the route map\n"
9415 vrf_id_t vrf
= VRF_DEFAULT
;
9416 afi_t afi
= AFI_IP6
;
9417 safi_t safi
= SAFI_UNICAST
;
9418 char *rmap_name
= NULL
;
9419 char *peerstr
= NULL
;
9421 struct bgp
*bgp
= NULL
;
9426 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9430 int uj
= use_json (argc
, argv
);
9433 bgp
= bgp_lookup_by_vrf_id (vrf
);
9438 json_object
*json_no
= NULL
;
9439 json_no
= json_object_new_object();
9440 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9441 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9442 json_object_free(json_no
);
9445 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9449 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9450 argv_find (argv
, argc
, "neighbors", &idx
);
9451 peerstr
= argv
[++idx
]->arg
;
9453 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9457 if (argv_find (argv
, argc
, "received-routes", &idx
))
9459 if (argv_find (argv
, argc
, "advertised-routes", &idx
))
9461 if (argv_find (argv
, argc
, "route-map", &idx
))
9462 rmap_name
= argv
[++idx
]->arg
;
9464 return peer_adj_routes (vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
9467 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
9468 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
9469 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9475 "Address Family modifier\n"
9476 "Detailed information on TCP and BGP neighbor connections\n"
9477 "Neighbor to display information about\n"
9478 "Neighbor to display information about\n"
9479 "Neighbor on BGP configured interface\n"
9480 "Display information received from a BGP neighbor\n"
9481 "Display the prefixlist filter\n"
9484 afi_t afi
= AFI_IP6
;
9485 safi_t safi
= SAFI_UNICAST
;
9486 char *peerstr
= NULL
;
9496 if (argv_find (argv
, argc
, "ip", &idx
))
9498 /* [<ipv4|ipv6> [unicast]] */
9499 if (argv_find (argv
, argc
, "ipv4", &idx
))
9501 if (argv_find (argv
, argc
, "ipv6", &idx
))
9503 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9504 argv_find (argv
, argc
, "neighbors", &idx
);
9505 peerstr
= argv
[++idx
]->arg
;
9507 u_char uj
= use_json(argc
, argv
);
9509 ret
= str2sockunion (peerstr
, &su
);
9512 peer
= peer_lookup_by_conf_if (NULL
, peerstr
);
9516 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9518 vty_out (vty
, "%% Malformed address or name: %s%s", peerstr
, VTY_NEWLINE
);
9524 peer
= peer_lookup (NULL
, &su
);
9528 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9530 vty_out (vty
, "No peer%s", VTY_NEWLINE
);
9535 sprintf (name
, "%s.%d.%d", peer
->host
, afi
, safi
);
9536 count
= prefix_bgp_show_prefix_list (NULL
, afi
, name
, uj
);
9540 vty_out (vty
, "Address Family: %s%s", afi_safi_print(afi
, safi
), VTY_NEWLINE
);
9541 prefix_bgp_show_prefix_list (vty
, afi
, name
, uj
);
9546 vty_out (vty
, "{}%s", VTY_NEWLINE
);
9548 vty_out (vty
, "No functional output%s", VTY_NEWLINE
);
9555 bgp_show_neighbor_route (struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9556 safi_t safi
, enum bgp_show_type type
, u_char use_json
)
9558 if (! peer
|| ! peer
->afc
[afi
][safi
])
9562 json_object
*json_no
= NULL
;
9563 json_no
= json_object_new_object();
9564 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
9565 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9566 json_object_free(json_no
);
9569 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
9573 return bgp_show (vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
9576 DEFUN (show_ip_bgp_neighbor_routes
,
9577 show_ip_bgp_neighbor_routes_cmd
,
9578 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9579 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9583 BGP_INSTANCE_HELP_STR
9586 "Detailed information on TCP and BGP neighbor connections\n"
9587 "Neighbor to display information about\n"
9588 "Neighbor to display information about\n"
9589 "Neighbor on BGP configured interface\n"
9590 "Display flap statistics of the routes learned from neighbor\n"
9591 "Display the dampened routes received from neighbor\n"
9592 "Display routes learned from neighbor\n"
9595 vrf_id_t vrf
= VRF_DEFAULT
;
9596 char *peerstr
= NULL
;
9597 struct bgp
*bgp
= NULL
;
9598 afi_t afi
= AFI_IP6
;
9599 safi_t safi
= SAFI_UNICAST
;
9601 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
9605 bgp_vty_find_and_parse_afi_safi_vrf (vty
, argv
, argc
, &idx
, &afi
, &safi
, &vrf
);
9609 int uj
= use_json (argc
, argv
);
9614 bgp
= bgp_lookup_by_vrf_id (vrf
);
9619 json_object
*json_no
= NULL
;
9620 json_no
= json_object_new_object();
9621 json_object_string_add(json_no
, "warning", "Can't find BGP view");
9622 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
9623 json_object_free(json_no
);
9626 vty_out (vty
, "Can't find BGP instance %s%s", argv
[5]->arg
, VTY_NEWLINE
);
9633 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9634 argv_find (argv
, argc
, "neighbors", &idx
);
9635 peerstr
= argv
[++idx
]->arg
;
9637 peer
= peer_lookup_in_view (vty
, bgp
, peerstr
, uj
);
9640 vty_out (vty
, "No such neighbor%s", VTY_NEWLINE
);
9644 if (argv_find (argv
, argc
, "flap-statistics", &idx
))
9645 sh_type
= bgp_show_type_flap_neighbor
;
9646 else if (argv_find (argv
, argc
, "dampened-routes", &idx
))
9647 sh_type
= bgp_show_type_damp_neighbor
;
9648 else if (argv_find (argv
, argc
, "routes", &idx
))
9649 sh_type
= bgp_show_type_neighbor
;
9651 return bgp_show_neighbor_route (vty
, peer
, afi
, safi
, sh_type
, uj
);
9654 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
9658 /* Distance value for the IP source prefix. */
9661 /* Name of the access-list to be matched. */
9665 DEFUN (show_bgp_afi_vpn_rd_route
,
9666 show_bgp_afi_vpn_rd_route_cmd
,
9667 "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]",
9671 "Address Family modifier\n"
9672 "Display information for a route distinguisher\n"
9673 "Route Distinguisher\n"
9674 "Network in the BGP routing table to display\n"
9675 "Network in the BGP routing table to display\n"
9679 struct prefix_rd prd
;
9680 afi_t afi
= AFI_MAX
;
9683 argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
);
9684 ret
= str2prefix_rd (argv
[5]->arg
, &prd
);
9687 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
9690 return bgp_show_route (vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
, 0, BGP_PATH_ALL
, use_json (argc
, argv
));
9693 static struct bgp_distance
*
9694 bgp_distance_new (void)
9696 return XCALLOC (MTYPE_BGP_DISTANCE
, sizeof (struct bgp_distance
));
9700 bgp_distance_free (struct bgp_distance
*bdistance
)
9702 XFREE (MTYPE_BGP_DISTANCE
, bdistance
);
9706 bgp_distance_set (struct vty
*vty
, const char *distance_str
,
9707 const char *ip_str
, const char *access_list_str
)
9714 struct bgp_node
*rn
;
9715 struct bgp_distance
*bdistance
;
9717 afi
= bgp_node_afi (vty
);
9718 safi
= bgp_node_safi (vty
);
9720 ret
= str2prefix (ip_str
, &p
);
9723 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9727 distance
= atoi (distance_str
);
9729 /* Get BGP distance node. */
9730 rn
= bgp_node_get (bgp_distance_table
[afi
][safi
], (struct prefix
*) &p
);
9733 bdistance
= rn
->info
;
9734 bgp_unlock_node (rn
);
9738 bdistance
= bgp_distance_new ();
9739 rn
->info
= bdistance
;
9742 /* Set distance value. */
9743 bdistance
->distance
= distance
;
9745 /* Reset access-list configuration. */
9746 if (bdistance
->access_list
)
9748 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9749 bdistance
->access_list
= NULL
;
9751 if (access_list_str
)
9752 bdistance
->access_list
= XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
9758 bgp_distance_unset (struct vty
*vty
, const char *distance_str
,
9759 const char *ip_str
, const char *access_list_str
)
9766 struct bgp_node
*rn
;
9767 struct bgp_distance
*bdistance
;
9769 afi
= bgp_node_afi (vty
);
9770 safi
= bgp_node_safi (vty
);
9772 ret
= str2prefix (ip_str
, &p
);
9775 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
9779 rn
= bgp_node_lookup (bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
9782 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
9786 bdistance
= rn
->info
;
9787 distance
= atoi(distance_str
);
9789 if (bdistance
->distance
!= distance
)
9791 vty_out (vty
, "Distance does not match configured%s", VTY_NEWLINE
);
9795 if (bdistance
->access_list
)
9796 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
9797 bgp_distance_free (bdistance
);
9800 bgp_unlock_node (rn
);
9801 bgp_unlock_node (rn
);
9806 /* Apply BGP information to distance method. */
9808 bgp_distance_apply (struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
9809 safi_t safi
, struct bgp
*bgp
)
9811 struct bgp_node
*rn
;
9814 struct bgp_distance
*bdistance
;
9815 struct access_list
*alist
;
9816 struct bgp_static
*bgp_static
;
9823 /* Check source address. */
9824 sockunion2hostprefix (&peer
->su
, &q
);
9825 rn
= bgp_node_match (bgp_distance_table
[afi
][safi
], &q
);
9828 bdistance
= rn
->info
;
9829 bgp_unlock_node (rn
);
9831 if (bdistance
->access_list
)
9833 alist
= access_list_lookup (afi
, bdistance
->access_list
);
9834 if (alist
&& access_list_apply (alist
, p
) == FILTER_PERMIT
)
9835 return bdistance
->distance
;
9838 return bdistance
->distance
;
9841 /* Backdoor check. */
9842 rn
= bgp_node_lookup (bgp
->route
[afi
][safi
], p
);
9845 bgp_static
= rn
->info
;
9846 bgp_unlock_node (rn
);
9848 if (bgp_static
->backdoor
)
9850 if (bgp
->distance_local
[afi
][safi
])
9851 return bgp
->distance_local
[afi
][safi
];
9853 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9857 if (peer
->sort
== BGP_PEER_EBGP
)
9859 if (bgp
->distance_ebgp
[afi
][safi
])
9860 return bgp
->distance_ebgp
[afi
][safi
];
9861 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
9865 if (bgp
->distance_ibgp
[afi
][safi
])
9866 return bgp
->distance_ibgp
[afi
][safi
];
9867 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
9871 DEFUN (bgp_distance
,
9873 "distance bgp (1-255) (1-255) (1-255)",
9874 "Define an administrative distance\n"
9876 "Distance for routes external to the AS\n"
9877 "Distance for routes internal to the AS\n"
9878 "Distance for local routes\n")
9880 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9882 int idx_number_2
= 3;
9883 int idx_number_3
= 4;
9887 afi
= bgp_node_afi (vty
);
9888 safi
= bgp_node_safi (vty
);
9890 bgp
->distance_ebgp
[afi
][safi
] = atoi (argv
[idx_number
]->arg
);
9891 bgp
->distance_ibgp
[afi
][safi
] = atoi (argv
[idx_number_2
]->arg
);
9892 bgp
->distance_local
[afi
][safi
] = atoi (argv
[idx_number_3
]->arg
);
9896 DEFUN (no_bgp_distance
,
9897 no_bgp_distance_cmd
,
9898 "no distance bgp [(1-255) (1-255) (1-255)]",
9900 "Define an administrative distance\n"
9902 "Distance for routes external to the AS\n"
9903 "Distance for routes internal to the AS\n"
9904 "Distance for local routes\n")
9906 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
9910 afi
= bgp_node_afi (vty
);
9911 safi
= bgp_node_safi (vty
);
9913 bgp
->distance_ebgp
[afi
][safi
] = 0;
9914 bgp
->distance_ibgp
[afi
][safi
] = 0;
9915 bgp
->distance_local
[afi
][safi
] = 0;
9920 DEFUN (bgp_distance_source
,
9921 bgp_distance_source_cmd
,
9922 "distance (1-255) A.B.C.D/M",
9923 "Define an administrative distance\n"
9924 "Administrative distance\n"
9925 "IP source prefix\n")
9928 int idx_ipv4_prefixlen
= 2;
9929 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9933 DEFUN (no_bgp_distance_source
,
9934 no_bgp_distance_source_cmd
,
9935 "no distance (1-255) A.B.C.D/M",
9937 "Define an administrative distance\n"
9938 "Administrative distance\n"
9939 "IP source prefix\n")
9942 int idx_ipv4_prefixlen
= 3;
9943 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
9947 DEFUN (bgp_distance_source_access_list
,
9948 bgp_distance_source_access_list_cmd
,
9949 "distance (1-255) A.B.C.D/M WORD",
9950 "Define an administrative distance\n"
9951 "Administrative distance\n"
9952 "IP source prefix\n"
9953 "Access list name\n")
9956 int idx_ipv4_prefixlen
= 2;
9958 bgp_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9962 DEFUN (no_bgp_distance_source_access_list
,
9963 no_bgp_distance_source_access_list_cmd
,
9964 "no distance (1-255) A.B.C.D/M WORD",
9966 "Define an administrative distance\n"
9967 "Administrative distance\n"
9968 "IP source prefix\n"
9969 "Access list name\n")
9972 int idx_ipv4_prefixlen
= 3;
9974 bgp_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
9978 DEFUN (ipv6_bgp_distance_source
,
9979 ipv6_bgp_distance_source_cmd
,
9980 "distance (1-255) X:X::X:X/M",
9981 "Define an administrative distance\n"
9982 "Administrative distance\n"
9983 "IP source prefix\n")
9985 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
9989 DEFUN (no_ipv6_bgp_distance_source
,
9990 no_ipv6_bgp_distance_source_cmd
,
9991 "no distance (1-255) X:X::X:X/M",
9993 "Define an administrative distance\n"
9994 "Administrative distance\n"
9995 "IP source prefix\n")
9997 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10001 DEFUN (ipv6_bgp_distance_source_access_list
,
10002 ipv6_bgp_distance_source_access_list_cmd
,
10003 "distance (1-255) X:X::X:X/M WORD",
10004 "Define an administrative distance\n"
10005 "Administrative distance\n"
10006 "IP source prefix\n"
10007 "Access list name\n")
10009 bgp_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10010 return CMD_SUCCESS
;
10013 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10014 no_ipv6_bgp_distance_source_access_list_cmd
,
10015 "no distance (1-255) X:X::X:X/M WORD",
10017 "Define an administrative distance\n"
10018 "Administrative distance\n"
10019 "IP source prefix\n"
10020 "Access list name\n")
10022 bgp_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10023 return CMD_SUCCESS
;
10026 DEFUN (bgp_damp_set
,
10028 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10029 "BGP Specific commands\n"
10030 "Enable route-flap dampening\n"
10031 "Half-life time for the penalty\n"
10032 "Value to start reusing a route\n"
10033 "Value to start suppressing a route\n"
10034 "Maximum duration to suppress a stable route\n")
10036 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10037 int idx_half_life
= 2;
10039 int idx_suppress
= 4;
10040 int idx_max_suppress
= 5;
10041 int half
= DEFAULT_HALF_LIFE
* 60;
10042 int reuse
= DEFAULT_REUSE
;
10043 int suppress
= DEFAULT_SUPPRESS
;
10044 int max
= 4 * half
;
10048 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10049 reuse
= atoi (argv
[idx_reuse
]->arg
);
10050 suppress
= atoi (argv
[idx_suppress
]->arg
);
10051 max
= atoi (argv
[idx_max_suppress
]->arg
) * 60;
10053 else if (argc
== 3)
10055 half
= atoi (argv
[idx_half_life
]->arg
) * 60;
10059 if (suppress
< reuse
)
10061 vty_out (vty
, "Suppress value cannot be less than reuse value %s",
10066 return bgp_damp_enable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
),
10067 half
, reuse
, suppress
, max
);
10070 DEFUN (bgp_damp_unset
,
10071 bgp_damp_unset_cmd
,
10072 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10074 "BGP Specific commands\n"
10075 "Enable route-flap dampening\n"
10076 "Half-life time for the penalty\n"
10077 "Value to start reusing a route\n"
10078 "Value to start suppressing a route\n"
10079 "Maximum duration to suppress a stable route\n")
10081 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10082 return bgp_damp_disable (bgp
, bgp_node_afi (vty
), bgp_node_safi (vty
));
10085 /* Display specified route of BGP table. */
10087 bgp_clear_damp_route (struct vty
*vty
, const char *view_name
,
10088 const char *ip_str
, afi_t afi
, safi_t safi
,
10089 struct prefix_rd
*prd
, int prefix_check
)
10092 struct prefix match
;
10093 struct bgp_node
*rn
;
10094 struct bgp_node
*rm
;
10095 struct bgp_info
*ri
;
10096 struct bgp_info
*ri_temp
;
10098 struct bgp_table
*table
;
10100 /* BGP structure lookup. */
10103 bgp
= bgp_lookup_by_name (view_name
);
10106 vty_out (vty
, "%% Can't find BGP instance %s%s", view_name
, VTY_NEWLINE
);
10107 return CMD_WARNING
;
10112 bgp
= bgp_get_default ();
10115 vty_out (vty
, "%% No BGP process is configured%s", VTY_NEWLINE
);
10116 return CMD_WARNING
;
10120 /* Check IP address argument. */
10121 ret
= str2prefix (ip_str
, &match
);
10124 vty_out (vty
, "%% address is malformed%s", VTY_NEWLINE
);
10125 return CMD_WARNING
;
10128 match
.family
= afi2family (afi
);
10130 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
) || (safi
== SAFI_EVPN
))
10132 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][safi
]); rn
; rn
= bgp_route_next (rn
))
10134 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
10137 if ((table
= rn
->info
) != NULL
)
10138 if ((rm
= bgp_node_match (table
, &match
)) != NULL
)
10140 if (! prefix_check
|| rm
->p
.prefixlen
== match
.prefixlen
)
10145 if (ri
->extra
&& ri
->extra
->damp_info
)
10147 ri_temp
= ri
->next
;
10148 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10156 bgp_unlock_node (rm
);
10162 if ((rn
= bgp_node_match (bgp
->rib
[afi
][safi
], &match
)) != NULL
)
10164 if (! prefix_check
|| rn
->p
.prefixlen
== match
.prefixlen
)
10169 if (ri
->extra
&& ri
->extra
->damp_info
)
10171 ri_temp
= ri
->next
;
10172 bgp_damp_info_free (ri
->extra
->damp_info
, 1);
10180 bgp_unlock_node (rn
);
10184 return CMD_SUCCESS
;
10187 DEFUN (clear_ip_bgp_dampening
,
10188 clear_ip_bgp_dampening_cmd
,
10189 "clear ip bgp dampening",
10193 "Clear route flap dampening information\n")
10195 bgp_damp_info_clean ();
10196 return CMD_SUCCESS
;
10199 DEFUN (clear_ip_bgp_dampening_prefix
,
10200 clear_ip_bgp_dampening_prefix_cmd
,
10201 "clear ip bgp dampening A.B.C.D/M",
10205 "Clear route flap dampening information\n"
10208 int idx_ipv4_prefixlen
= 4;
10209 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
10210 SAFI_UNICAST
, NULL
, 1);
10213 DEFUN (clear_ip_bgp_dampening_address
,
10214 clear_ip_bgp_dampening_address_cmd
,
10215 "clear ip bgp dampening A.B.C.D",
10219 "Clear route flap dampening information\n"
10220 "Network to clear damping information\n")
10223 return bgp_clear_damp_route (vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10224 SAFI_UNICAST
, NULL
, 0);
10227 DEFUN (clear_ip_bgp_dampening_address_mask
,
10228 clear_ip_bgp_dampening_address_mask_cmd
,
10229 "clear ip bgp dampening A.B.C.D A.B.C.D",
10233 "Clear route flap dampening information\n"
10234 "Network to clear damping information\n"
10238 int idx_ipv4_2
= 5;
10240 char prefix_str
[BUFSIZ
];
10242 ret
= netmask_str2prefix_str (argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
, prefix_str
);
10245 vty_out (vty
, "%% Inconsistent address and mask%s", VTY_NEWLINE
);
10246 return CMD_WARNING
;
10249 return bgp_clear_damp_route (vty
, NULL
, prefix_str
, AFI_IP
,
10250 SAFI_UNICAST
, NULL
, 0);
10253 /* also used for encap safi */
10255 bgp_config_write_network_vpn (struct vty
*vty
, struct bgp
*bgp
,
10256 afi_t afi
, safi_t safi
, int *write
)
10258 struct bgp_node
*prn
;
10259 struct bgp_node
*rn
;
10260 struct bgp_table
*table
;
10262 struct prefix_rd
*prd
;
10263 struct bgp_static
*bgp_static
;
10265 char buf
[SU_ADDRSTRLEN
];
10266 char rdbuf
[RD_ADDRSTRLEN
];
10268 /* Network configuration. */
10269 for (prn
= bgp_table_top (bgp
->route
[afi
][safi
]); prn
; prn
= bgp_route_next (prn
))
10270 if ((table
= prn
->info
) != NULL
)
10271 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
10272 if ((bgp_static
= rn
->info
) != NULL
)
10275 prd
= (struct prefix_rd
*) &prn
->p
;
10277 /* "address-family" display. */
10278 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10280 /* "network" configuration display. */
10281 prefix_rd2str (prd
, rdbuf
, RD_ADDRSTRLEN
);
10282 label
= decode_label (bgp_static
->tag
);
10284 vty_out (vty
, " network %s/%d rd %s tag %d",
10285 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10288 vty_out (vty
, "%s", VTY_NEWLINE
);
10293 /* Configuration of static route announcement and aggregate
10296 bgp_config_write_network (struct vty
*vty
, struct bgp
*bgp
,
10297 afi_t afi
, safi_t safi
, int *write
)
10299 struct bgp_node
*rn
;
10301 struct bgp_static
*bgp_static
;
10302 struct bgp_aggregate
*bgp_aggregate
;
10303 char buf
[SU_ADDRSTRLEN
];
10305 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
10306 return bgp_config_write_network_vpn (vty
, bgp
, afi
, safi
, write
);
10308 /* Network configuration. */
10309 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10310 if ((bgp_static
= rn
->info
) != NULL
)
10314 /* "address-family" display. */
10315 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10317 /* "network" configuration display. */
10318 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10320 u_int32_t destination
;
10321 struct in_addr netmask
;
10323 destination
= ntohl (p
->u
.prefix4
.s_addr
);
10324 masklen2ip (p
->prefixlen
, &netmask
);
10325 vty_out (vty
, " network %s",
10326 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
));
10328 if ((IN_CLASSC (destination
) && p
->prefixlen
== 24)
10329 || (IN_CLASSB (destination
) && p
->prefixlen
== 16)
10330 || (IN_CLASSA (destination
) && p
->prefixlen
== 8)
10331 || p
->u
.prefix4
.s_addr
== 0)
10333 /* Natural mask is not display. */
10336 vty_out (vty
, " mask %s", inet_ntoa (netmask
));
10340 vty_out (vty
, " network %s/%d",
10341 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10345 if (bgp_static
->rmap
.name
)
10346 vty_out (vty
, " route-map %s", bgp_static
->rmap
.name
);
10349 if (bgp_static
->backdoor
)
10350 vty_out (vty
, " backdoor");
10353 vty_out (vty
, "%s", VTY_NEWLINE
);
10356 /* Aggregate-address configuration. */
10357 for (rn
= bgp_table_top (bgp
->aggregate
[afi
][safi
]); rn
; rn
= bgp_route_next (rn
))
10358 if ((bgp_aggregate
= rn
->info
) != NULL
)
10362 /* "address-family" display. */
10363 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10365 if (bgp_option_check (BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
)
10367 struct in_addr netmask
;
10369 masklen2ip (p
->prefixlen
, &netmask
);
10370 vty_out (vty
, " aggregate-address %s %s",
10371 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10372 inet_ntoa (netmask
));
10376 vty_out (vty
, " aggregate-address %s/%d",
10377 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
10381 if (bgp_aggregate
->as_set
)
10382 vty_out (vty
, " as-set");
10384 if (bgp_aggregate
->summary_only
)
10385 vty_out (vty
, " summary-only");
10387 vty_out (vty
, "%s", VTY_NEWLINE
);
10394 bgp_config_write_distance (struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10395 safi_t safi
, int *write
)
10397 struct bgp_node
*rn
;
10398 struct bgp_distance
*bdistance
;
10400 /* Distance configuration. */
10401 if (bgp
->distance_ebgp
[afi
][safi
]
10402 && bgp
->distance_ibgp
[afi
][safi
]
10403 && bgp
->distance_local
[afi
][safi
]
10404 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
10405 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
10406 || bgp
->distance_local
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
))
10408 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10409 vty_out (vty
, " distance bgp %d %d %d%s",
10410 bgp
->distance_ebgp
[afi
][safi
], bgp
->distance_ibgp
[afi
][safi
],
10411 bgp
->distance_local
[afi
][safi
], VTY_NEWLINE
);
10414 for (rn
= bgp_table_top (bgp_distance_table
[afi
][safi
]); rn
;
10415 rn
= bgp_route_next (rn
))
10416 if ((bdistance
= rn
->info
) != NULL
)
10418 char buf
[PREFIX_STRLEN
];
10420 bgp_config_write_family_header (vty
, afi
, safi
, write
);
10421 vty_out (vty
, " distance %d %s %s%s", bdistance
->distance
,
10422 prefix2str (&rn
->p
, buf
, sizeof (buf
)),
10423 bdistance
->access_list
? bdistance
->access_list
: "",
10430 /* Allocate routing table structure and install commands. */
10432 bgp_route_init (void)
10437 /* Init BGP distance table. */
10438 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10439 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10440 bgp_distance_table
[afi
][safi
] = bgp_table_init (afi
, safi
);
10442 /* IPv4 BGP commands. */
10443 install_element (BGP_NODE
, &bgp_table_map_cmd
);
10444 install_element (BGP_NODE
, &bgp_network_cmd
);
10445 install_element (BGP_NODE
, &bgp_network_mask_cmd
);
10446 install_element (BGP_NODE
, &bgp_network_mask_natural_cmd
);
10447 install_element (BGP_NODE
, &bgp_network_route_map_cmd
);
10448 install_element (BGP_NODE
, &bgp_network_mask_route_map_cmd
);
10449 install_element (BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10450 install_element (BGP_NODE
, &bgp_network_backdoor_cmd
);
10451 install_element (BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
10452 install_element (BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
10453 install_element (BGP_NODE
, &no_bgp_table_map_cmd
);
10454 install_element (BGP_NODE
, &no_bgp_network_cmd
);
10455 install_element (BGP_NODE
, &no_bgp_network_mask_cmd
);
10456 install_element (BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
10458 install_element (BGP_NODE
, &aggregate_address_cmd
);
10459 install_element (BGP_NODE
, &aggregate_address_mask_cmd
);
10460 install_element (BGP_NODE
, &no_aggregate_address_cmd
);
10461 install_element (BGP_NODE
, &no_aggregate_address_mask_cmd
);
10463 /* IPv4 unicast configuration. */
10464 install_element (BGP_IPV4_NODE
, &bgp_table_map_cmd
);
10465 install_element (BGP_IPV4_NODE
, &bgp_network_cmd
);
10466 install_element (BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
10467 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
10468 install_element (BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
10469 install_element (BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
10470 install_element (BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10471 install_element (BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
10472 install_element (BGP_IPV4_NODE
, &no_bgp_network_cmd
);
10473 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
10474 install_element (BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
10476 install_element (BGP_IPV4_NODE
, &aggregate_address_cmd
);
10477 install_element (BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
10478 install_element (BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
10479 install_element (BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
10481 /* IPv4 multicast configuration. */
10482 install_element (BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
10483 install_element (BGP_IPV4M_NODE
, &bgp_network_cmd
);
10484 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
10485 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
10486 install_element (BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
10487 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
10488 install_element (BGP_IPV4M_NODE
, &bgp_network_mask_natural_route_map_cmd
);
10489 install_element (BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
10490 install_element (BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
10491 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
10492 install_element (BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
10493 install_element (BGP_IPV4M_NODE
, &aggregate_address_cmd
);
10494 install_element (BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
10495 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
10496 install_element (BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
10498 install_element (VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
10499 install_element (VIEW_NODE
, &show_ip_bgp_cmd
);
10500 install_element (VIEW_NODE
, &show_ip_bgp_route_cmd
);
10501 install_element (VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
10503 install_element (VIEW_NODE
, &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
10504 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
10505 install_element (VIEW_NODE
, &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
10506 #ifdef KEEP_OLD_VPN_COMMANDS
10507 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
10508 #endif /* KEEP_OLD_VPN_COMMANDS */
10509 install_element (VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
10511 /* BGP dampening clear commands */
10512 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
10513 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
10515 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
10516 install_element (ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
10519 install_element (ENABLE_NODE
, &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
10520 #ifdef KEEP_OLD_VPN_COMMANDS
10521 install_element (ENABLE_NODE
, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
10522 #endif /* KEEP_OLD_VPN_COMMANDS */
10524 /* New config IPv6 BGP commands. */
10525 install_element (BGP_IPV6_NODE
, &bgp_table_map_cmd
);
10526 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
10527 install_element (BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
10528 install_element (BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
10529 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
10531 install_element (BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
10532 install_element (BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
10534 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
10535 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
10537 install_element (BGP_NODE
, &bgp_distance_cmd
);
10538 install_element (BGP_NODE
, &no_bgp_distance_cmd
);
10539 install_element (BGP_NODE
, &bgp_distance_source_cmd
);
10540 install_element (BGP_NODE
, &no_bgp_distance_source_cmd
);
10541 install_element (BGP_NODE
, &bgp_distance_source_access_list_cmd
);
10542 install_element (BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
10543 install_element (BGP_IPV4_NODE
, &bgp_distance_cmd
);
10544 install_element (BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
10545 install_element (BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
10546 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
10547 install_element (BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
10548 install_element (BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
10549 install_element (BGP_IPV4M_NODE
, &bgp_distance_cmd
);
10550 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
10551 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
10552 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
10553 install_element (BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
10554 install_element (BGP_IPV4M_NODE
, &no_bgp_distance_source_access_list_cmd
);
10555 install_element (BGP_IPV6_NODE
, &bgp_distance_cmd
);
10556 install_element (BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
10557 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
10558 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10559 install_element (BGP_IPV6_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10560 install_element (BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10561 install_element (BGP_IPV6M_NODE
, &bgp_distance_cmd
);
10562 install_element (BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
10563 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
10564 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
10565 install_element (BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_access_list_cmd
);
10566 install_element (BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_access_list_cmd
);
10568 install_element (BGP_NODE
, &bgp_damp_set_cmd
);
10569 install_element (BGP_NODE
, &bgp_damp_unset_cmd
);
10570 install_element (BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
10571 install_element (BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
10573 /* IPv4 Multicast Mode */
10574 install_element (BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
10575 install_element (BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
10577 /* Large Communities */
10578 install_element (VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
10579 install_element (VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
10583 bgp_route_finish (void)
10588 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
10589 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
10591 bgp_table_unlock (bgp_distance_table
[afi
][safi
]);
10592 bgp_distance_table
[afi
][safi
] = NULL
;