1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_community.h"
56 #include "bgpd/bgp_attr.h"
57 #include "bgpd/bgp_regex.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_packet.h"
61 #include "bgpd/bgp_zebra.h"
62 #include "bgpd/bgp_open.h"
63 #include "bgpd/bgp_filter.h"
64 #include "bgpd/bgp_nexthop.h"
65 #include "bgpd/bgp_damp.h"
66 #include "bgpd/bgp_mplsvpn.h"
68 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
69 #include "bgpd/rfapi/rfapi_backend.h"
71 #include "bgpd/bgp_evpn.h"
72 #include "bgpd/bgp_advertise.h"
73 #include "bgpd/bgp_network.h"
74 #include "bgpd/bgp_vty.h"
75 #include "bgpd/bgp_mpath.h"
76 #include "bgpd/bgp_nht.h"
77 #include "bgpd/bgp_updgrp.h"
78 #include "bgpd/bgp_bfd.h"
79 #include "bgpd/bgp_memory.h"
80 #include "bgpd/bgp_evpn_vty.h"
81 #include "bgpd/bgp_keepalives.h"
82 #include "bgpd/bgp_io.h"
83 #include "bgpd/bgp_ecommunity.h"
84 #include "bgpd/bgp_flowspec.h"
85 #include "bgpd/bgp_labelpool.h"
87 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
88 DEFINE_QOBJ_TYPE(bgp_master
)
90 DEFINE_QOBJ_TYPE(peer
)
92 /* BGP process wide configuration. */
93 static struct bgp_master bgp_master
;
95 /* BGP process wide configuration pointer to export. */
96 struct bgp_master
*bm
;
98 /* BGP community-list. */
99 struct community_list_handler
*bgp_clist
;
101 unsigned int multipath_num
= MULTIPATH_NUM
;
103 static void bgp_if_finish(struct bgp
*bgp
);
105 extern struct zclient
*zclient
;
107 /* handle main socket creation or deletion */
108 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
110 static int bgp_server_main_created
;
111 struct listnode
*bgpnode
, *nbgpnode
;
112 struct bgp
*bgp_temp
;
114 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&&
115 vrf_is_mapped_on_netns(bgp
->vrf_id
))
117 if (create
== true) {
118 if (bgp_server_main_created
)
120 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
121 return BGP_ERR_INVALID_VALUE
;
122 bgp_server_main_created
= 1;
125 if (!bgp_server_main_created
)
127 /* only delete socket on some cases */
128 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp_temp
)) {
129 /* do not count with current bgp */
132 /* if other instance non VRF, do not delete socket */
133 if (bgp_temp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
135 /* vrf lite, do not delete socket */
136 if (!vrf_is_mapped_on_netns(bgp_temp
->vrf_id
))
140 bgp_server_main_created
= 0;
144 void bgp_session_reset(struct peer
*peer
)
146 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
147 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
148 peer_delete(peer
->doppelganger
);
150 BGP_EVENT_ADD(peer
, BGP_Stop
);
154 * During session reset, we may delete the doppelganger peer, which would
155 * be the next node to the current node. If the session reset was invoked
156 * during walk of peer list, we would end up accessing the freed next
157 * node. This function moves the next node along.
159 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
164 n
= (nnode
) ? *nnode
: NULL
;
165 npeer
= (n
) ? listgetdata(n
) : NULL
;
167 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
168 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
169 PEER_FLAG_CONFIG_NODE
))) {
170 if (peer
->doppelganger
== npeer
)
171 /* nnode and *nnode are confirmed to be non-NULL here */
172 *nnode
= (*nnode
)->next
;
173 peer_delete(peer
->doppelganger
);
176 BGP_EVENT_ADD(peer
, BGP_Stop
);
179 /* BGP global flag manipulation. */
180 int bgp_option_set(int flag
)
184 case BGP_OPT_MULTIPLE_INSTANCE
:
185 case BGP_OPT_CONFIG_CISCO
:
186 case BGP_OPT_NO_LISTEN
:
187 SET_FLAG(bm
->options
, flag
);
190 return BGP_ERR_INVALID_FLAG
;
195 int bgp_option_unset(int flag
)
198 case BGP_OPT_MULTIPLE_INSTANCE
:
199 if (listcount(bm
->bgp
) > 1)
200 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
203 case BGP_OPT_CONFIG_CISCO
:
204 UNSET_FLAG(bm
->options
, flag
);
207 return BGP_ERR_INVALID_FLAG
;
212 int bgp_option_check(int flag
)
214 return CHECK_FLAG(bm
->options
, flag
);
217 /* BGP flag manipulation. */
218 int bgp_flag_set(struct bgp
*bgp
, int flag
)
220 SET_FLAG(bgp
->flags
, flag
);
224 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
226 UNSET_FLAG(bgp
->flags
, flag
);
230 int bgp_flag_check(struct bgp
*bgp
, int flag
)
232 return CHECK_FLAG(bgp
->flags
, flag
);
235 /* Internal function to set BGP structure configureation flag. */
236 static void bgp_config_set(struct bgp
*bgp
, int config
)
238 SET_FLAG(bgp
->config
, config
);
241 static void bgp_config_unset(struct bgp
*bgp
, int config
)
243 UNSET_FLAG(bgp
->config
, config
);
246 static int bgp_config_check(struct bgp
*bgp
, int config
)
248 return CHECK_FLAG(bgp
->config
, config
);
251 /* Set BGP router identifier. */
252 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
255 struct listnode
*node
, *nnode
;
257 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
260 /* EVPN uses router id in RD, withdraw them */
261 if (is_evpn_enabled())
262 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
264 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
266 /* Set all peer's local identifier with this value. */
267 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
268 IPV4_ADDR_COPY(&peer
->local_id
, id
);
270 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
271 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
272 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
273 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
277 /* EVPN uses router id in RD, update them */
278 if (is_evpn_enabled())
279 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
284 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
286 struct listnode
*node
, *nnode
;
289 if (vrf_id
== VRF_DEFAULT
) {
290 /* Router-id change for default VRF has to also update all
292 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
293 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
296 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
297 if (!bgp
->router_id_static
.s_addr
)
298 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
301 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
303 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
305 if (!bgp
->router_id_static
.s_addr
)
306 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
311 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
313 bgp
->router_id_static
= id
;
314 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
318 /* BGP's cluster-id control. */
319 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
322 struct listnode
*node
, *nnode
;
324 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
325 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
328 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
329 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
331 /* Clear all IBGP peer. */
332 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
333 if (peer
->sort
!= BGP_PEER_IBGP
)
336 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
337 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
338 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
339 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
345 int bgp_cluster_id_unset(struct bgp
*bgp
)
348 struct listnode
*node
, *nnode
;
350 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
353 bgp
->cluster_id
.s_addr
= 0;
354 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
356 /* Clear all IBGP peer. */
357 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
358 if (peer
->sort
!= BGP_PEER_IBGP
)
361 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
362 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
363 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
364 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
370 /* time_t value that is monotonicly increasing
371 * and uneffected by adjustments to system clock
373 time_t bgp_clock(void)
381 /* BGP timer configuration. */
382 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
384 bgp
->default_keepalive
=
385 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
386 bgp
->default_holdtime
= holdtime
;
391 int bgp_timers_unset(struct bgp
*bgp
)
393 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
394 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
399 /* BGP confederation configuration. */
400 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
403 struct listnode
*node
, *nnode
;
407 return BGP_ERR_INVALID_AS
;
409 /* Remember - were we doing confederation before? */
410 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
412 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
414 /* If we were doing confederation already, this is just an external
415 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
416 were not doing confederation before, reset all EBGP sessions. */
417 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
418 /* We're looking for peers who's AS is not local or part of our
420 if (already_confed
) {
421 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
423 if (BGP_IS_VALID_STATE_FOR_NOTIF(
426 PEER_DOWN_CONFED_ID_CHANGE
;
428 peer
, BGP_NOTIFY_CEASE
,
429 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
431 bgp_session_reset_safe(peer
, &nnode
);
434 /* Not doign confederation before, so reset every
437 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
438 /* Reset the local_as to be our EBGP one */
439 if (peer_sort(peer
) == BGP_PEER_EBGP
)
441 if (BGP_IS_VALID_STATE_FOR_NOTIF(
444 PEER_DOWN_CONFED_ID_CHANGE
;
446 peer
, BGP_NOTIFY_CEASE
,
447 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
449 bgp_session_reset_safe(peer
, &nnode
);
456 int bgp_confederation_id_unset(struct bgp
*bgp
)
459 struct listnode
*node
, *nnode
;
462 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
464 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
465 /* We're looking for peers who's AS is not local */
466 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
467 peer
->local_as
= bgp
->as
;
468 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
469 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
470 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
471 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
475 bgp_session_reset_safe(peer
, &nnode
);
481 /* Is an AS part of the confed or not? */
482 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
489 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
490 if (bgp
->confed_peers
[i
] == as
)
496 /* Add an AS to the confederation set. */
497 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
500 struct listnode
*node
, *nnode
;
503 return BGP_ERR_INVALID_BGP
;
506 return BGP_ERR_INVALID_AS
;
508 if (bgp_confederation_peers_check(bgp
, as
))
511 if (bgp
->confed_peers
)
513 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
514 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
517 XMALLOC(MTYPE_BGP_CONFED_LIST
,
518 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
520 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
521 bgp
->confed_peers_cnt
++;
523 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
524 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
525 if (peer
->as
== as
) {
526 peer
->local_as
= bgp
->as
;
527 if (BGP_IS_VALID_STATE_FOR_NOTIF(
530 PEER_DOWN_CONFED_PEER_CHANGE
;
532 peer
, BGP_NOTIFY_CEASE
,
533 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
535 bgp_session_reset_safe(peer
, &nnode
);
542 /* Delete an AS from the confederation set. */
543 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
548 struct listnode
*node
, *nnode
;
553 if (!bgp_confederation_peers_check(bgp
, as
))
556 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
557 if (bgp
->confed_peers
[i
] == as
)
558 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
559 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
561 bgp
->confed_peers_cnt
--;
563 if (bgp
->confed_peers_cnt
== 0) {
564 if (bgp
->confed_peers
)
565 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
566 bgp
->confed_peers
= NULL
;
569 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
570 bgp
->confed_peers_cnt
* sizeof(as_t
));
572 /* Now reset any peer who's remote AS has just been removed from the
574 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
575 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
576 if (peer
->as
== as
) {
577 peer
->local_as
= bgp
->confed_id
;
578 if (BGP_IS_VALID_STATE_FOR_NOTIF(
581 PEER_DOWN_CONFED_PEER_CHANGE
;
583 peer
, BGP_NOTIFY_CEASE
,
584 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
586 bgp_session_reset_safe(peer
, &nnode
);
594 /* Local preference configuration. */
595 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
600 bgp
->default_local_pref
= local_pref
;
605 int bgp_default_local_preference_unset(struct bgp
*bgp
)
610 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
615 /* Local preference configuration. */
616 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
621 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
626 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
630 bgp
->default_subgroup_pkt_queue_max
=
631 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
636 /* Listen limit configuration. */
637 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
642 bgp
->dynamic_neighbors_limit
= listen_limit
;
647 int bgp_listen_limit_unset(struct bgp
*bgp
)
652 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
657 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
658 afi_t
*afi
, safi_t
*safi
)
660 /* Map from IANA values to internal values, return error if
661 * values are unrecognized.
663 *afi
= afi_iana2int(pkt_afi
);
664 *safi
= safi_iana2int(pkt_safi
);
665 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
671 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
672 iana_safi_t
*pkt_safi
)
674 /* Map from internal values to IANA values, return error if
675 * internal values are bad (unexpected).
677 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
679 *pkt_afi
= afi_int2iana(afi
);
680 *pkt_safi
= safi_int2iana(safi
);
684 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
692 afid
= afindex(afi
, safi
);
693 if (afid
>= BGP_AF_MAX
)
696 assert(peer
->peer_af_array
[afid
] == NULL
);
698 /* Allocate new peer af */
699 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
702 zlog_err("Could not create af structure for peer %s",
707 peer
->peer_af_array
[afid
] = af
;
716 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
723 afid
= afindex(afi
, safi
);
724 if (afid
>= BGP_AF_MAX
)
727 return peer
->peer_af_array
[afid
];
730 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
738 afid
= afindex(afi
, safi
);
739 if (afid
>= BGP_AF_MAX
)
742 af
= peer
->peer_af_array
[afid
];
746 bgp_stop_announce_route_timer(af
);
748 if (PAF_SUBGRP(af
)) {
749 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
750 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
751 af
->subgroup
->update_group
->id
,
752 af
->subgroup
->id
, peer
->host
);
755 update_subgroup_remove_peer(af
->subgroup
, af
);
757 peer
->peer_af_array
[afid
] = NULL
;
758 XFREE(MTYPE_BGP_PEER_AF
, af
);
762 /* Peer comparison function for sorting. */
763 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
765 if (p1
->group
&& !p2
->group
)
768 if (!p1
->group
&& p2
->group
)
771 if (p1
->group
== p2
->group
) {
772 if (p1
->conf_if
&& !p2
->conf_if
)
775 if (!p1
->conf_if
&& p2
->conf_if
)
778 if (p1
->conf_if
&& p2
->conf_if
)
779 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
781 return strcmp(p1
->group
->name
, p2
->group
->name
);
783 return sockunion_cmp(&p1
->su
, &p2
->su
);
786 static unsigned int peer_hash_key_make(void *p
)
788 struct peer
*peer
= p
;
789 return sockunion_hash(&peer
->su
);
792 static int peer_hash_same(const void *p1
, const void *p2
)
794 const struct peer
*peer1
= p1
;
795 const struct peer
*peer2
= p2
;
796 return (sockunion_same(&peer1
->su
, &peer2
->su
)
797 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
798 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
801 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
803 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
806 /* Return true if flag is set for the peer but not the peer-group */
807 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
810 struct peer
*g_peer
= NULL
;
812 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
813 if (peer_group_active(peer
)) {
814 g_peer
= peer
->group
->conf
;
816 /* If this flag is not set for the peer's peer-group
817 * then return true */
818 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
823 /* peer is not in a peer-group but the flag is set to return
833 /* Reset all address family specific configuration. */
834 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
837 struct bgp_filter
*filter
;
838 char orf_name
[BUFSIZ
];
840 filter
= &peer
->filter
[afi
][safi
];
842 /* Clear neighbor filter and route-map */
843 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
844 if (filter
->dlist
[i
].name
) {
845 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
846 filter
->dlist
[i
].name
= NULL
;
848 if (filter
->plist
[i
].name
) {
849 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
850 filter
->plist
[i
].name
= NULL
;
852 if (filter
->aslist
[i
].name
) {
853 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
854 filter
->aslist
[i
].name
= NULL
;
857 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
858 if (filter
->map
[i
].name
) {
859 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
860 filter
->map
[i
].name
= NULL
;
864 /* Clear unsuppress map. */
865 if (filter
->usmap
.name
)
866 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
867 filter
->usmap
.name
= NULL
;
868 filter
->usmap
.map
= NULL
;
870 /* Clear neighbor's all address family flags. */
871 peer
->af_flags
[afi
][safi
] = 0;
873 /* Clear neighbor's all address family sflags. */
874 peer
->af_sflags
[afi
][safi
] = 0;
876 /* Clear neighbor's all address family capabilities. */
877 peer
->af_cap
[afi
][safi
] = 0;
880 peer
->orf_plist
[afi
][safi
] = NULL
;
881 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
882 prefix_bgp_orf_remove_all(afi
, orf_name
);
884 /* Set default neighbor send-community. */
885 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
886 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
887 SET_FLAG(peer
->af_flags
[afi
][safi
],
888 PEER_FLAG_SEND_EXT_COMMUNITY
);
889 SET_FLAG(peer
->af_flags
[afi
][safi
],
890 PEER_FLAG_SEND_LARGE_COMMUNITY
);
893 /* Clear neighbor default_originate_rmap */
894 if (peer
->default_rmap
[afi
][safi
].name
)
895 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
896 peer
->default_rmap
[afi
][safi
].name
= NULL
;
897 peer
->default_rmap
[afi
][safi
].map
= NULL
;
899 /* Clear neighbor maximum-prefix */
900 peer
->pmax
[afi
][safi
] = 0;
901 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
904 /* peer global config reset */
905 static void peer_global_config_reset(struct peer
*peer
)
909 peer
->change_local_as
= 0;
910 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
911 if (peer
->update_source
) {
912 sockunion_free(peer
->update_source
);
913 peer
->update_source
= NULL
;
915 if (peer
->update_if
) {
916 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
917 peer
->update_if
= NULL
;
920 if (peer_sort(peer
) == BGP_PEER_IBGP
)
921 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
923 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
925 /* These are per-peer specific flags and so we must preserve them */
926 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
927 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
929 SET_FLAG(peer
->flags
, saved_flags
);
935 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
937 /* Reset some other configs back to defaults. */
938 peer
->v_start
= BGP_INIT_START_TIMER
;
939 peer
->password
= NULL
;
940 peer
->local_id
= peer
->bgp
->router_id
;
941 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
942 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
944 bfd_info_free(&(peer
->bfd_info
));
946 /* Set back the CONFIG_NODE flag. */
947 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
950 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
951 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
958 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
959 if (peer
->as_type
== AS_INTERNAL
)
960 return BGP_PEER_IBGP
;
962 else if (peer
->as_type
== AS_EXTERNAL
)
963 return BGP_PEER_EBGP
;
965 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
966 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
971 peer1
= listnode_head(peer
->group
->peer
);
976 return BGP_PEER_INTERNAL
;
980 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
981 if (peer
->local_as
== 0)
982 return BGP_PEER_INTERNAL
;
984 if (peer
->local_as
== peer
->as
) {
985 if (bgp
->as
== bgp
->confed_id
) {
986 if (peer
->local_as
== bgp
->as
)
987 return BGP_PEER_IBGP
;
989 return BGP_PEER_EBGP
;
991 if (peer
->local_as
== bgp
->confed_id
)
992 return BGP_PEER_EBGP
;
994 return BGP_PEER_IBGP
;
998 if (bgp_confederation_peers_check(bgp
, peer
->as
))
999 return BGP_PEER_CONFED
;
1001 return BGP_PEER_EBGP
;
1003 if (peer
->as_type
!= AS_SPECIFIED
)
1004 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1007 return (peer
->local_as
== 0
1009 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1014 /* Calculate and cache the peer "sort" */
1015 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1017 peer
->sort
= peer_calc_sort(peer
);
1021 static void peer_free(struct peer
*peer
)
1023 assert(peer
->status
== Deleted
);
1027 /* this /ought/ to have been done already through bgp_stop earlier,
1028 * but just to be sure..
1030 bgp_timer_set(peer
);
1031 bgp_reads_off(peer
);
1032 bgp_writes_off(peer
);
1033 assert(!peer
->t_write
);
1034 assert(!peer
->t_read
);
1035 BGP_EVENT_FLUSH(peer
);
1037 pthread_mutex_destroy(&peer
->io_mtx
);
1039 /* Free connected nexthop, if present */
1040 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1041 && !peer_dynamic_neighbor(peer
))
1042 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1045 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1048 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1052 /* Free allocated host character. */
1054 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1058 if (peer
->domainname
) {
1059 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1060 peer
->domainname
= NULL
;
1064 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1065 peer
->ifname
= NULL
;
1068 /* Update source configuration. */
1069 if (peer
->update_source
) {
1070 sockunion_free(peer
->update_source
);
1071 peer
->update_source
= NULL
;
1074 if (peer
->update_if
) {
1075 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1076 peer
->update_if
= NULL
;
1079 if (peer
->notify
.data
)
1080 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1081 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1083 if (peer
->clear_node_queue
)
1084 work_queue_free_and_null(&peer
->clear_node_queue
);
1086 bgp_sync_delete(peer
);
1088 if (peer
->conf_if
) {
1089 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1090 peer
->conf_if
= NULL
;
1093 bfd_info_free(&(peer
->bfd_info
));
1095 bgp_unlock(peer
->bgp
);
1097 memset(peer
, 0, sizeof(struct peer
));
1099 XFREE(MTYPE_BGP_PEER
, peer
);
1102 /* increase reference count on a struct peer */
1103 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1105 assert(peer
&& (peer
->lock
>= 0));
1108 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1116 /* decrease reference count on a struct peer
1117 * struct peer is freed and NULL returned if last reference
1119 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1121 assert(peer
&& (peer
->lock
> 0));
1124 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1129 if (peer
->lock
== 0) {
1137 /* Allocate new peer object, implicitely locked. */
1138 struct peer
*peer_new(struct bgp
*bgp
)
1145 /* bgp argument is absolutely required */
1150 /* Allocate new peer. */
1151 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1153 /* Set default value. */
1155 peer
->v_start
= BGP_INIT_START_TIMER
;
1156 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1157 peer
->status
= Idle
;
1158 peer
->ostatus
= Idle
;
1159 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1160 peer
->bgp
= bgp_lock(bgp
);
1161 peer
= peer_lock(peer
); /* initial reference */
1162 peer
->password
= NULL
;
1164 /* Set default flags. */
1165 FOREACH_AFI_SAFI (afi
, safi
) {
1166 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1167 SET_FLAG(peer
->af_flags
[afi
][safi
],
1168 PEER_FLAG_SEND_COMMUNITY
);
1169 SET_FLAG(peer
->af_flags
[afi
][safi
],
1170 PEER_FLAG_SEND_EXT_COMMUNITY
);
1171 SET_FLAG(peer
->af_flags
[afi
][safi
],
1172 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1174 peer
->orf_plist
[afi
][safi
] = NULL
;
1176 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1178 /* Create buffers. */
1179 peer
->ibuf
= stream_fifo_new();
1180 peer
->obuf
= stream_fifo_new();
1181 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1183 /* We use a larger buffer for peer->obuf_work in the event that:
1184 * - We RX a BGP_UPDATE where the attributes alone are just
1185 * under BGP_MAX_PACKET_SIZE
1186 * - The user configures an outbound route-map that does many as-path
1187 * prepends or adds many communities. At most they can have
1188 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1189 * large they can make the attributes.
1191 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1192 * bounds checking for every single attribute as we construct an
1196 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1198 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1200 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1202 bgp_sync_init(peer
);
1204 /* Get service port number. */
1205 sp
= getservbyname("bgp", "tcp");
1206 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1208 QOBJ_REG(peer
, peer
);
1213 * This function is invoked when a duplicate peer structure associated with
1214 * a neighbor is being deleted. If this about-to-be-deleted structure is
1215 * the one with all the config, then we have to copy over the info.
1217 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1219 struct peer_af
*paf
;
1227 /* The following function is used by both peer group config copy to
1228 * individual peer and when we transfer config
1230 if (peer_src
->change_local_as
)
1231 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1233 /* peer flags apply */
1234 peer_dst
->flags
= peer_src
->flags
;
1235 peer_dst
->cap
= peer_src
->cap
;
1236 peer_dst
->config
= peer_src
->config
;
1238 peer_dst
->local_as
= peer_src
->local_as
;
1239 peer_dst
->port
= peer_src
->port
;
1240 (void)peer_sort(peer_dst
);
1241 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1244 peer_dst
->holdtime
= peer_src
->holdtime
;
1245 peer_dst
->keepalive
= peer_src
->keepalive
;
1246 peer_dst
->connect
= peer_src
->connect
;
1247 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1248 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1249 peer_dst
->routeadv
= peer_src
->routeadv
;
1250 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1252 /* password apply */
1253 if (peer_src
->password
&& !peer_dst
->password
)
1254 peer_dst
->password
=
1255 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1257 FOREACH_AFI_SAFI (afi
, safi
) {
1258 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1259 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1260 peer_dst
->allowas_in
[afi
][safi
] =
1261 peer_src
->allowas_in
[afi
][safi
];
1262 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1265 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1266 paf
= peer_src
->peer_af_array
[afidx
];
1268 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1271 /* update-source apply */
1272 if (peer_src
->update_source
) {
1273 if (peer_dst
->update_source
)
1274 sockunion_free(peer_dst
->update_source
);
1275 if (peer_dst
->update_if
) {
1276 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1277 peer_dst
->update_if
= NULL
;
1279 peer_dst
->update_source
=
1280 sockunion_dup(peer_src
->update_source
);
1281 } else if (peer_src
->update_if
) {
1282 if (peer_dst
->update_if
)
1283 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1284 if (peer_dst
->update_source
) {
1285 sockunion_free(peer_dst
->update_source
);
1286 peer_dst
->update_source
= NULL
;
1288 peer_dst
->update_if
=
1289 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1292 if (peer_src
->ifname
) {
1293 if (peer_dst
->ifname
)
1294 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1297 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1301 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1302 struct interface
*ifp
)
1304 struct connected
*ifc
;
1307 struct listnode
*node
;
1309 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1310 * IPv4 address of the other end.
1312 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1313 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1314 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1315 if (p
.prefixlen
== 30) {
1316 peer
->su
.sa
.sa_family
= AF_INET
;
1317 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1319 peer
->su
.sin
.sin_addr
.s_addr
=
1321 else if (addr
% 4 == 2)
1322 peer
->su
.sin
.sin_addr
.s_addr
=
1324 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1325 peer
->su
.sin
.sin_len
=
1326 sizeof(struct sockaddr_in
);
1327 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1329 } else if (p
.prefixlen
== 31) {
1330 peer
->su
.sa
.sa_family
= AF_INET
;
1331 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1333 peer
->su
.sin
.sin_addr
.s_addr
=
1336 peer
->su
.sin
.sin_addr
.s_addr
=
1338 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1339 peer
->su
.sin
.sin_len
=
1340 sizeof(struct sockaddr_in
);
1341 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1343 } else if (bgp_debug_neighbor_events(peer
))
1345 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1353 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1354 struct interface
*ifp
)
1356 struct nbr_connected
*ifc_nbr
;
1358 /* Have we learnt the peer's IPv6 link-local address? */
1359 if (ifp
->nbr_connected
1360 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1361 peer
->su
.sa
.sa_family
= AF_INET6
;
1362 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1363 sizeof(struct in6_addr
));
1365 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1367 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1375 * Set or reset the peer address socketunion structure based on the
1376 * learnt/derived peer address. If the address has changed, update the
1377 * password on the listen socket, if needed.
1379 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1381 struct interface
*ifp
;
1383 int peer_addr_updated
= 0;
1388 prev_family
= peer
->su
.sa
.sa_family
;
1389 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1391 /* If BGP unnumbered is not "v6only", we first see if we can
1393 * peer's IPv4 address.
1395 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1397 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1399 /* If "v6only" or we can't derive peer's IPv4 address, see if
1401 * learnt the peer's IPv6 link-local address. This is from the
1403 * IPv6 address in router advertisement.
1405 if (!peer_addr_updated
)
1407 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1409 /* If we could derive the peer address, we may need to install the
1411 * configured for the peer, if any, on the listen socket. Otherwise,
1413 * that peer's address is not available and uninstall the password, if
1416 if (peer_addr_updated
) {
1417 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1420 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1421 bgp_md5_unset(peer
);
1422 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1423 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1426 /* Since our su changed we need to del/add peer to the peerhash */
1427 hash_release(peer
->bgp
->peerhash
, peer
);
1428 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1431 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1434 struct bgp_node
*rn
, *nrn
;
1436 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1437 rn
= bgp_route_next(rn
)) {
1438 if (rn
->info
!= NULL
) {
1439 /* Special handling for 2-level routing
1441 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1442 || safi
== SAFI_EVPN
) {
1443 for (nrn
= bgp_table_top(
1444 (struct bgp_table
*)(rn
->info
));
1445 nrn
; nrn
= bgp_route_next(nrn
))
1446 bgp_process(bgp
, nrn
, afi
, safi
);
1448 bgp_process(bgp
, rn
, afi
, safi
);
1453 /* Force a bestpath recalculation for all prefixes. This is used
1454 * when 'bgp bestpath' commands are entered.
1456 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1461 FOREACH_AFI_SAFI (afi
, safi
) {
1462 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1466 /* Create new BGP peer. */
1467 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1468 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1469 int as_type
, afi_t afi
, safi_t safi
,
1470 struct peer_group
*group
)
1474 char buf
[SU_ADDRSTRLEN
];
1476 peer
= peer_new(bgp
);
1478 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1479 bgp_peer_conf_if_to_su_update(peer
);
1481 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1482 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1485 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1487 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1488 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1490 peer
->local_as
= local_as
;
1491 peer
->as
= remote_as
;
1492 peer
->as_type
= as_type
;
1493 peer
->local_id
= bgp
->router_id
;
1494 peer
->v_holdtime
= bgp
->default_holdtime
;
1495 peer
->v_keepalive
= bgp
->default_keepalive
;
1496 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1497 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1499 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1501 peer
= peer_lock(peer
); /* bgp peer list reference */
1502 peer
->group
= group
;
1503 listnode_add_sort(bgp
->peer
, peer
);
1504 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1506 /* Adjust update-group coalesce timer heuristics for # peers. */
1507 if (bgp
->heuristic_coalesce
) {
1508 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1510 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1511 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1514 active
= peer_active(peer
);
1516 /* Last read and reset time set */
1517 peer
->readtime
= peer
->resettime
= bgp_clock();
1519 /* Default TTL set. */
1520 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1522 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1525 peer
->afc
[afi
][safi
] = 1;
1526 peer_af_create(peer
, afi
, safi
);
1529 /* auto shutdown if configured */
1530 if (bgp
->autoshutdown
)
1531 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1532 /* Set up peer's events and timers. */
1533 else if (!active
&& peer_active(peer
))
1534 bgp_timer_set(peer
);
1539 /* Make accept BGP peer. This function is only called from the test code */
1540 struct peer
*peer_create_accept(struct bgp
*bgp
)
1544 peer
= peer_new(bgp
);
1546 peer
= peer_lock(peer
); /* bgp peer list reference */
1547 listnode_add_sort(bgp
->peer
, peer
);
1553 * Return true if we have a peer configured to use this afi/safi
1555 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1557 struct listnode
*node
;
1560 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1561 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1564 if (peer
->afc
[afi
][safi
])
1571 /* Change peer's AS number. */
1572 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1574 bgp_peer_sort_t type
;
1578 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1579 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1580 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1581 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1582 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1584 bgp_session_reset(peer
);
1586 type
= peer_sort(peer
);
1588 peer
->as_type
= as_specified
;
1590 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1591 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1592 && peer
->bgp
->as
!= as
)
1593 peer
->local_as
= peer
->bgp
->confed_id
;
1595 peer
->local_as
= peer
->bgp
->as
;
1597 /* Advertisement-interval reset */
1600 conf
= peer
->group
->conf
;
1602 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1603 peer
->v_routeadv
= conf
->routeadv
;
1605 /* Only go back to the default advertisement-interval if the user had
1607 * already configured it */
1608 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1609 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1610 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1612 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1615 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1617 else if (type
== BGP_PEER_IBGP
)
1620 /* reflector-client reset */
1621 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1622 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1623 PEER_FLAG_REFLECTOR_CLIENT
);
1624 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1625 PEER_FLAG_REFLECTOR_CLIENT
);
1626 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1627 PEER_FLAG_REFLECTOR_CLIENT
);
1628 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1629 PEER_FLAG_REFLECTOR_CLIENT
);
1630 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1631 PEER_FLAG_REFLECTOR_CLIENT
);
1632 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1633 PEER_FLAG_REFLECTOR_CLIENT
);
1634 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1635 PEER_FLAG_REFLECTOR_CLIENT
);
1636 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1637 PEER_FLAG_REFLECTOR_CLIENT
);
1638 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1639 PEER_FLAG_REFLECTOR_CLIENT
);
1640 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1641 PEER_FLAG_REFLECTOR_CLIENT
);
1642 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1643 PEER_FLAG_REFLECTOR_CLIENT
);
1644 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1645 PEER_FLAG_REFLECTOR_CLIENT
);
1646 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1647 PEER_FLAG_REFLECTOR_CLIENT
);
1650 /* local-as reset */
1651 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1652 peer
->change_local_as
= 0;
1653 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1654 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1658 /* If peer does not exist, create new one. If peer already exists,
1659 set AS number to the peer. */
1660 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1661 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1667 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1669 peer
= peer_lookup(bgp
, su
);
1672 /* Not allowed for a dynamic peer. */
1673 if (peer_dynamic_neighbor(peer
)) {
1675 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1678 /* When this peer is a member of peer-group. */
1680 if (peer
->group
->conf
->as
) {
1681 /* Return peer group's AS number. */
1682 *as
= peer
->group
->conf
->as
;
1683 return BGP_ERR_PEER_GROUP_MEMBER
;
1685 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1686 if ((as_type
!= AS_INTERNAL
)
1687 && (bgp
->as
!= *as
)) {
1689 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1692 if ((as_type
!= AS_EXTERNAL
)
1693 && (bgp
->as
== *as
)) {
1695 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1700 /* Existing peer's AS number change. */
1701 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1702 || (peer
->as_type
!= as_type
))
1703 peer_as_change(peer
, *as
, as_type
);
1706 return BGP_ERR_NO_INTERFACE_CONFIG
;
1708 /* If the peer is not part of our confederation, and its not an
1709 iBGP peer then spoof the source AS */
1710 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1711 && !bgp_confederation_peers_check(bgp
, *as
)
1713 local_as
= bgp
->confed_id
;
1717 /* If this is IPv4 unicast configuration and "no bgp default
1718 ipv4-unicast" is specified. */
1720 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1721 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1722 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1725 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1732 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1733 struct peer
*peer
, afi_t afi
,
1737 int out
= FILTER_OUT
;
1739 struct bgp_filter
*pfilter
;
1740 struct bgp_filter
*gfilter
;
1743 pfilter
= &peer
->filter
[afi
][safi
];
1744 gfilter
= &conf
->filter
[afi
][safi
];
1746 /* peer af_flags apply */
1747 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1749 /* maximum-prefix */
1750 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1751 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1752 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1755 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1758 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1760 /* default-originate route-map */
1761 if (conf
->default_rmap
[afi
][safi
].name
) {
1762 if (peer
->default_rmap
[afi
][safi
].name
)
1763 XFREE(MTYPE_BGP_FILTER_NAME
,
1764 peer
->default_rmap
[afi
][safi
].name
);
1765 peer
->default_rmap
[afi
][safi
].name
=
1766 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1767 conf
->default_rmap
[afi
][safi
].name
);
1768 peer
->default_rmap
[afi
][safi
].map
=
1769 conf
->default_rmap
[afi
][safi
].map
;
1772 /* inbound filter apply */
1773 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1774 if (pfilter
->dlist
[in
].name
)
1775 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1776 pfilter
->dlist
[in
].name
=
1777 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1778 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1781 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1782 if (pfilter
->plist
[in
].name
)
1783 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1784 pfilter
->plist
[in
].name
=
1785 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1786 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1789 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1790 if (pfilter
->aslist
[in
].name
)
1791 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1792 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1793 gfilter
->aslist
[in
].name
);
1794 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1797 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1798 if (pfilter
->map
[RMAP_IN
].name
)
1799 XFREE(MTYPE_BGP_FILTER_NAME
,
1800 pfilter
->map
[RMAP_IN
].name
);
1801 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1802 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1803 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1806 /* outbound filter apply */
1807 if (gfilter
->dlist
[out
].name
) {
1808 if (pfilter
->dlist
[out
].name
)
1809 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1810 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1811 gfilter
->dlist
[out
].name
);
1812 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1814 if (pfilter
->dlist
[out
].name
)
1815 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1816 pfilter
->dlist
[out
].name
= NULL
;
1817 pfilter
->dlist
[out
].alist
= NULL
;
1820 if (gfilter
->plist
[out
].name
) {
1821 if (pfilter
->plist
[out
].name
)
1822 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1823 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1824 gfilter
->plist
[out
].name
);
1825 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1827 if (pfilter
->plist
[out
].name
)
1828 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1829 pfilter
->plist
[out
].name
= NULL
;
1830 pfilter
->plist
[out
].plist
= NULL
;
1833 if (gfilter
->aslist
[out
].name
) {
1834 if (pfilter
->aslist
[out
].name
)
1835 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1836 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1837 gfilter
->aslist
[out
].name
);
1838 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1840 if (pfilter
->aslist
[out
].name
)
1841 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1842 pfilter
->aslist
[out
].name
= NULL
;
1843 pfilter
->aslist
[out
].aslist
= NULL
;
1846 if (gfilter
->map
[RMAP_OUT
].name
) {
1847 if (pfilter
->map
[RMAP_OUT
].name
)
1848 XFREE(MTYPE_BGP_FILTER_NAME
,
1849 pfilter
->map
[RMAP_OUT
].name
);
1850 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1851 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1852 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1854 if (pfilter
->map
[RMAP_OUT
].name
)
1855 XFREE(MTYPE_BGP_FILTER_NAME
,
1856 pfilter
->map
[RMAP_OUT
].name
);
1857 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1858 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1861 if (gfilter
->usmap
.name
) {
1862 if (pfilter
->usmap
.name
)
1863 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1864 pfilter
->usmap
.name
=
1865 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1866 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1868 if (pfilter
->usmap
.name
)
1869 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1870 pfilter
->usmap
.name
= NULL
;
1871 pfilter
->usmap
.map
= NULL
;
1875 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1879 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1880 zlog_err("%s was called for peer-group %s", __func__
,
1885 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1887 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1888 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1889 return BGP_ERR_PEER_SAFI_CONFLICT
;
1891 /* Nothing to do if we've already activated this peer */
1892 if (peer
->afc
[afi
][safi
])
1895 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1898 active
= peer_active(peer
);
1899 peer
->afc
[afi
][safi
] = 1;
1902 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1904 if (!active
&& peer_active(peer
)) {
1905 bgp_timer_set(peer
);
1907 if (peer
->status
== Established
) {
1908 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1909 peer
->afc_adv
[afi
][safi
] = 1;
1910 bgp_capability_send(peer
, afi
, safi
,
1912 CAPABILITY_ACTION_SET
);
1913 if (peer
->afc_recv
[afi
][safi
]) {
1914 peer
->afc_nego
[afi
][safi
] = 1;
1915 bgp_announce_route(peer
, afi
, safi
);
1918 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1919 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1920 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1923 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1924 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1925 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1926 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1933 /* Activate the peer or peer group for specified AFI and SAFI. */
1934 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1937 struct peer_group
*group
;
1938 struct listnode
*node
, *nnode
;
1939 struct peer
*tmp_peer
;
1942 /* Nothing to do if we've already activated this peer */
1943 if (peer
->afc
[afi
][safi
])
1948 /* This is a peer-group so activate all of the members of the
1949 * peer-group as well */
1950 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1952 /* Do not activate a peer for both SAFI_UNICAST and
1953 * SAFI_LABELED_UNICAST */
1954 if ((safi
== SAFI_UNICAST
1955 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1956 || (safi
== SAFI_LABELED_UNICAST
1957 && peer
->afc
[afi
][SAFI_UNICAST
]))
1958 return BGP_ERR_PEER_SAFI_CONFLICT
;
1960 peer
->afc
[afi
][safi
] = 1;
1961 group
= peer
->group
;
1963 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1964 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1967 ret
|= peer_activate_af(peer
, afi
, safi
);
1970 /* If this is the first peer to be activated for this
1971 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1972 if (safi
== SAFI_LABELED_UNICAST
1973 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1975 if (BGP_DEBUG(zebra
, ZEBRA
))
1977 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1979 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1980 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1983 if (safi
== SAFI_FLOWSPEC
) {
1984 /* connect to table manager */
1985 bgp_zebra_init_tm_connect();
1990 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1993 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1994 zlog_err("%s was called for peer-group %s", __func__
,
1999 /* Nothing to do if we've already deactivated this peer */
2000 if (!peer
->afc
[afi
][safi
])
2003 /* De-activate the address family configuration. */
2004 peer
->afc
[afi
][safi
] = 0;
2006 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2007 zlog_err("couldn't delete af structure for peer %s",
2012 if (peer
->status
== Established
) {
2013 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2014 peer
->afc_adv
[afi
][safi
] = 0;
2015 peer
->afc_nego
[afi
][safi
] = 0;
2017 if (peer_active_nego(peer
)) {
2018 bgp_capability_send(peer
, afi
, safi
,
2020 CAPABILITY_ACTION_UNSET
);
2021 bgp_clear_route(peer
, afi
, safi
);
2022 peer
->pcount
[afi
][safi
] = 0;
2024 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2025 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2026 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2029 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2030 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2031 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2038 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2041 struct peer_group
*group
;
2042 struct peer
*tmp_peer
;
2043 struct listnode
*node
, *nnode
;
2046 /* Nothing to do if we've already de-activated this peer */
2047 if (!peer
->afc
[afi
][safi
])
2050 /* This is a peer-group so de-activate all of the members of the
2051 * peer-group as well */
2052 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2053 peer
->afc
[afi
][safi
] = 0;
2054 group
= peer
->group
;
2056 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2057 zlog_err("couldn't delete af structure for peer %s",
2061 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2062 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2065 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2070 /* If this is the last peer to be deactivated for this
2071 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2072 if (safi
== SAFI_LABELED_UNICAST
2073 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2074 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2076 if (BGP_DEBUG(zebra
, ZEBRA
))
2078 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2080 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2081 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2086 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2089 return peer_activate(peer
, afi
, safi
);
2091 return peer_deactivate(peer
, afi
, safi
);
2094 static void peer_nsf_stop(struct peer
*peer
)
2099 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2100 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2102 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2103 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2104 peer
->nsf
[afi
][safi
] = 0;
2106 if (peer
->t_gr_restart
) {
2107 BGP_TIMER_OFF(peer
->t_gr_restart
);
2108 if (bgp_debug_neighbor_events(peer
))
2109 zlog_debug("%s graceful restart timer stopped",
2112 if (peer
->t_gr_stale
) {
2113 BGP_TIMER_OFF(peer
->t_gr_stale
);
2114 if (bgp_debug_neighbor_events(peer
))
2116 "%s graceful restart stalepath timer stopped",
2119 bgp_clear_route_all(peer
);
2122 /* Delete peer from confguration.
2124 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2125 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2127 * This function /should/ take care to be idempotent, to guard against
2128 * it being called multiple times through stray events that come in
2129 * that happen to result in this function being called again. That
2130 * said, getting here for a "Deleted" peer is a bug in the neighbour
2133 int peer_delete(struct peer
*peer
)
2139 struct bgp_filter
*filter
;
2140 struct listnode
*pn
;
2143 assert(peer
->status
!= Deleted
);
2146 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2148 bgp_reads_off(peer
);
2149 bgp_writes_off(peer
);
2150 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2151 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2153 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2154 peer_nsf_stop(peer
);
2156 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2158 /* If this peer belongs to peer group, clear up the
2161 if (peer_dynamic_neighbor(peer
))
2162 peer_drop_dynamic_neighbor(peer
);
2164 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2166 peer
); /* group->peer list reference */
2167 list_delete_node(peer
->group
->peer
, pn
);
2172 /* Withdraw all information from routing table. We can not use
2173 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2174 * executed after peer structure is deleted.
2176 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2178 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2180 if (peer
->doppelganger
) {
2181 peer
->doppelganger
->doppelganger
= NULL
;
2182 peer
->doppelganger
= NULL
;
2185 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2186 bgp_fsm_change_status(peer
, Deleted
);
2188 /* Remove from NHT */
2189 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2190 bgp_unlink_nexthop_by_peer(peer
);
2192 /* Password configuration */
2193 if (peer
->password
) {
2194 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2195 peer
->password
= NULL
;
2197 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2198 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2199 bgp_md5_unset(peer
);
2202 bgp_timer_set(peer
); /* stops all timers for Deleted */
2204 /* Delete from all peer list. */
2205 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2206 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2207 peer_unlock(peer
); /* bgp peer list reference */
2208 list_delete_node(bgp
->peer
, pn
);
2209 hash_release(bgp
->peerhash
, peer
);
2214 stream_fifo_free(peer
->ibuf
);
2219 stream_fifo_free(peer
->obuf
);
2223 if (peer
->ibuf_work
) {
2224 ringbuf_del(peer
->ibuf_work
);
2225 peer
->ibuf_work
= NULL
;
2228 if (peer
->obuf_work
) {
2229 stream_free(peer
->obuf_work
);
2230 peer
->obuf_work
= NULL
;
2233 if (peer
->scratch
) {
2234 stream_free(peer
->scratch
);
2235 peer
->scratch
= NULL
;
2238 /* Local and remote addresses. */
2239 if (peer
->su_local
) {
2240 sockunion_free(peer
->su_local
);
2241 peer
->su_local
= NULL
;
2244 if (peer
->su_remote
) {
2245 sockunion_free(peer
->su_remote
);
2246 peer
->su_remote
= NULL
;
2249 /* Free filter related memory. */
2250 FOREACH_AFI_SAFI (afi
, safi
) {
2251 filter
= &peer
->filter
[afi
][safi
];
2253 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2254 if (filter
->dlist
[i
].name
) {
2255 XFREE(MTYPE_BGP_FILTER_NAME
,
2256 filter
->dlist
[i
].name
);
2257 filter
->dlist
[i
].name
= NULL
;
2260 if (filter
->plist
[i
].name
) {
2261 XFREE(MTYPE_BGP_FILTER_NAME
,
2262 filter
->plist
[i
].name
);
2263 filter
->plist
[i
].name
= NULL
;
2266 if (filter
->aslist
[i
].name
) {
2267 XFREE(MTYPE_BGP_FILTER_NAME
,
2268 filter
->aslist
[i
].name
);
2269 filter
->aslist
[i
].name
= NULL
;
2273 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2274 if (filter
->map
[i
].name
) {
2275 XFREE(MTYPE_BGP_FILTER_NAME
,
2276 filter
->map
[i
].name
);
2277 filter
->map
[i
].name
= NULL
;
2281 if (filter
->usmap
.name
) {
2282 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2283 filter
->usmap
.name
= NULL
;
2286 if (peer
->default_rmap
[afi
][safi
].name
) {
2287 XFREE(MTYPE_ROUTE_MAP_NAME
,
2288 peer
->default_rmap
[afi
][safi
].name
);
2289 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2293 FOREACH_AFI_SAFI (afi
, safi
)
2294 peer_af_delete(peer
, afi
, safi
);
2296 if (peer
->hostname
) {
2297 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2298 peer
->hostname
= NULL
;
2301 if (peer
->domainname
) {
2302 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2303 peer
->domainname
= NULL
;
2306 peer_unlock(peer
); /* initial reference */
2311 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2313 return strcmp(g1
->name
, g2
->name
);
2316 /* Peer group cofiguration. */
2317 static struct peer_group
*peer_group_new(void)
2319 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2320 sizeof(struct peer_group
));
2323 static void peer_group_free(struct peer_group
*group
)
2325 XFREE(MTYPE_PEER_GROUP
, group
);
2328 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2330 struct peer_group
*group
;
2331 struct listnode
*node
, *nnode
;
2333 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2334 if (strcmp(group
->name
, name
) == 0)
2340 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2342 struct peer_group
*group
;
2345 group
= peer_group_lookup(bgp
, name
);
2349 group
= peer_group_new();
2352 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2353 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2354 group
->peer
= list_new();
2355 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2356 group
->listen_range
[afi
] = list_new();
2357 group
->conf
= peer_new(bgp
);
2358 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2359 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2360 if (group
->conf
->host
)
2361 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2362 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2363 group
->conf
->group
= group
;
2364 group
->conf
->as
= 0;
2365 group
->conf
->ttl
= 1;
2366 group
->conf
->gtsm_hops
= 0;
2367 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2368 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2369 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2370 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2371 group
->conf
->keepalive
= 0;
2372 group
->conf
->holdtime
= 0;
2373 group
->conf
->connect
= 0;
2374 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2375 listnode_add_sort(bgp
->group
, group
);
2380 static void peer_group2peer_config_copy(struct peer_group
*group
,
2384 int saved_flags
= 0;
2390 peer
->as
= conf
->as
;
2393 if (conf
->change_local_as
)
2394 peer
->change_local_as
= conf
->change_local_as
;
2397 peer
->ttl
= conf
->ttl
;
2400 peer
->gtsm_hops
= conf
->gtsm_hops
;
2402 /* These are per-peer specific flags and so we must preserve them */
2403 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2404 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
2405 peer
->flags
= conf
->flags
;
2406 SET_FLAG(peer
->flags
, saved_flags
);
2408 /* peer config apply */
2409 peer
->config
= conf
->config
;
2411 /* peer timers apply */
2412 peer
->holdtime
= conf
->holdtime
;
2413 peer
->keepalive
= conf
->keepalive
;
2414 peer
->connect
= conf
->connect
;
2415 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2416 peer
->v_connect
= conf
->connect
;
2418 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2420 /* advertisement-interval reset */
2421 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2422 peer
->v_routeadv
= conf
->routeadv
;
2423 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2424 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2426 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2428 /* password apply */
2429 if (conf
->password
&& !peer
->password
)
2430 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2432 if (!BGP_PEER_SU_UNSPEC(peer
))
2435 /* update-source apply */
2436 if (conf
->update_source
) {
2437 if (peer
->update_source
)
2438 sockunion_free(peer
->update_source
);
2439 if (peer
->update_if
) {
2440 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2441 peer
->update_if
= NULL
;
2443 peer
->update_source
= sockunion_dup(conf
->update_source
);
2444 } else if (conf
->update_if
) {
2445 if (peer
->update_if
)
2446 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2447 if (peer
->update_source
) {
2448 sockunion_free(peer
->update_source
);
2449 peer
->update_source
= NULL
;
2452 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2455 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2458 /* Peer group's remote AS configuration. */
2459 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2462 struct peer_group
*group
;
2464 struct listnode
*node
, *nnode
;
2466 group
= peer_group_lookup(bgp
, group_name
);
2470 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2474 /* When we setup peer-group AS number all peer group member's AS
2475 number must be updated to same number. */
2476 peer_as_change(group
->conf
, *as
, as_type
);
2478 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2479 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2480 || (peer
->as_type
!= as_type
))
2481 peer_as_change(peer
, *as
, as_type
);
2487 int peer_group_delete(struct peer_group
*group
)
2491 struct prefix
*prefix
;
2493 struct listnode
*node
, *nnode
;
2498 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2499 other
= peer
->doppelganger
;
2501 if (other
&& other
->status
!= Deleted
) {
2502 other
->group
= NULL
;
2506 list_delete_and_null(&group
->peer
);
2508 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2509 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2511 prefix_free(prefix
);
2513 list_delete_and_null(&group
->listen_range
[afi
]);
2516 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2519 bfd_info_free(&(group
->conf
->bfd_info
));
2521 group
->conf
->group
= NULL
;
2522 peer_delete(group
->conf
);
2524 /* Delete from all peer_group list. */
2525 listnode_delete(bgp
->group
, group
);
2527 peer_group_free(group
);
2532 int peer_group_remote_as_delete(struct peer_group
*group
)
2534 struct peer
*peer
, *other
;
2535 struct listnode
*node
, *nnode
;
2537 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2538 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2541 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2542 other
= peer
->doppelganger
;
2546 if (other
&& other
->status
!= Deleted
) {
2547 other
->group
= NULL
;
2551 list_delete_all_node(group
->peer
);
2553 group
->conf
->as
= 0;
2554 group
->conf
->as_type
= AS_UNSPECIFIED
;
2559 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2561 struct prefix
*prefix
;
2562 struct listnode
*node
, *nnode
;
2565 afi
= family2afi(range
->family
);
2567 /* Group needs remote AS configured. */
2568 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2569 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2571 /* Ensure no duplicates. Currently we don't care about overlaps. */
2572 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2573 if (prefix_same(range
, prefix
))
2577 prefix
= prefix_new();
2578 prefix_copy(prefix
, range
);
2579 listnode_add(group
->listen_range
[afi
], prefix
);
2583 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2585 struct prefix
*prefix
, prefix2
;
2586 struct listnode
*node
, *nnode
;
2589 char buf
[PREFIX2STR_BUFFER
];
2591 afi
= family2afi(range
->family
);
2593 /* Identify the listen range. */
2594 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2595 if (prefix_same(range
, prefix
))
2600 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2602 prefix2str(prefix
, buf
, sizeof(buf
));
2604 /* Dispose off any dynamic neighbors that exist due to this listen range
2606 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2607 if (!peer_dynamic_neighbor(peer
))
2610 sockunion2hostprefix(&peer
->su
, &prefix2
);
2611 if (prefix_match(prefix
, &prefix2
)) {
2612 if (bgp_debug_neighbor_events(peer
))
2614 "Deleting dynamic neighbor %s group %s upon "
2615 "delete of listen range %s",
2616 peer
->host
, group
->name
, buf
);
2621 /* Get rid of the listen range */
2622 listnode_delete(group
->listen_range
[afi
], prefix
);
2627 /* Bind specified peer to peer group. */
2628 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2629 struct peer_group
*group
, as_t
*as
)
2631 int first_member
= 0;
2634 int cap_enhe_preset
= 0;
2636 /* Lookup the peer. */
2638 peer
= peer_lookup(bgp
, su
);
2640 /* The peer exist, bind it to the peer-group */
2642 /* When the peer already belongs to a peer-group, check the
2644 if (peer_group_active(peer
)) {
2646 /* The peer is already bound to the peer-group,
2649 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2652 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2655 /* The peer has not specified a remote-as, inherit it from the
2657 if (peer
->as_type
== AS_UNSPECIFIED
) {
2658 peer
->as_type
= group
->conf
->as_type
;
2659 peer
->as
= group
->conf
->as
;
2662 if (!group
->conf
->as
) {
2663 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2664 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2667 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2670 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2674 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2675 cap_enhe_preset
= 1;
2677 peer_group2peer_config_copy(group
, peer
);
2680 * Capability extended-nexthop is enabled for an interface
2682 * default. So, fix that up here.
2684 if (peer
->conf_if
&& cap_enhe_preset
)
2685 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2687 FOREACH_AFI_SAFI (afi
, safi
) {
2688 if (group
->conf
->afc
[afi
][safi
]) {
2689 peer
->afc
[afi
][safi
] = 1;
2691 if (peer_af_find(peer
, afi
, safi
)
2692 || peer_af_create(peer
, afi
, safi
)) {
2693 peer_group2peer_config_copy_af(
2694 group
, peer
, afi
, safi
);
2696 } else if (peer
->afc
[afi
][safi
])
2697 peer_deactivate(peer
, afi
, safi
);
2701 assert(group
&& peer
->group
== group
);
2703 struct listnode
*pn
;
2704 pn
= listnode_lookup(bgp
->peer
, peer
);
2705 list_delete_node(bgp
->peer
, pn
);
2706 peer
->group
= group
;
2707 listnode_add_sort(bgp
->peer
, peer
);
2709 peer
= peer_lock(peer
); /* group->peer list reference */
2710 listnode_add(group
->peer
, peer
);
2714 /* Advertisement-interval reset */
2715 if (!CHECK_FLAG(group
->conf
->config
,
2716 PEER_CONFIG_ROUTEADV
)) {
2717 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2718 group
->conf
->v_routeadv
=
2719 BGP_DEFAULT_IBGP_ROUTEADV
;
2721 group
->conf
->v_routeadv
=
2722 BGP_DEFAULT_EBGP_ROUTEADV
;
2725 /* ebgp-multihop reset */
2726 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2727 group
->conf
->ttl
= MAXTTL
;
2729 /* local-as reset */
2730 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2731 group
->conf
->change_local_as
= 0;
2732 UNSET_FLAG(peer
->flags
,
2733 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2734 UNSET_FLAG(peer
->flags
,
2735 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2739 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2741 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2742 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2743 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2744 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2746 bgp_session_reset(peer
);
2750 /* Create a new peer. */
2752 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2753 && (!group
->conf
->as
)) {
2754 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2757 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2758 group
->conf
->as_type
, 0, 0, group
);
2760 peer
= peer_lock(peer
); /* group->peer list reference */
2761 listnode_add(group
->peer
, peer
);
2763 peer_group2peer_config_copy(group
, peer
);
2765 /* If the peer-group is active for this afi/safi then activate
2767 FOREACH_AFI_SAFI (afi
, safi
) {
2768 if (group
->conf
->afc
[afi
][safi
]) {
2769 peer
->afc
[afi
][safi
] = 1;
2770 peer_af_create(peer
, afi
, safi
);
2771 peer_group2peer_config_copy_af(group
, peer
, afi
,
2773 } else if (peer
->afc
[afi
][safi
])
2774 peer_deactivate(peer
, afi
, safi
);
2777 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2779 /* Set up peer's events and timers. */
2780 if (peer_active(peer
))
2781 bgp_timer_set(peer
);
2787 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2788 struct peer_group
*group
)
2794 if (group
!= peer
->group
)
2795 return BGP_ERR_PEER_GROUP_MISMATCH
;
2797 FOREACH_AFI_SAFI (afi
, safi
) {
2798 if (peer
->afc
[afi
][safi
]) {
2799 peer
->afc
[afi
][safi
] = 0;
2800 peer_af_flag_reset(peer
, afi
, safi
);
2802 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2804 "couldn't delete af structure for peer %s",
2810 assert(listnode_lookup(group
->peer
, peer
));
2811 peer_unlock(peer
); /* peer group list reference */
2812 listnode_delete(group
->peer
, peer
);
2814 other
= peer
->doppelganger
;
2816 if (group
->conf
->as
) {
2818 if (other
&& other
->status
!= Deleted
) {
2821 listnode_delete(group
->peer
, other
);
2823 other
->group
= NULL
;
2829 bgp_bfd_deregister_peer(peer
);
2830 peer_global_config_reset(peer
);
2832 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2833 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2834 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2835 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2837 bgp_session_reset(peer
);
2842 static int bgp_startup_timer_expire(struct thread
*thread
)
2846 bgp
= THREAD_ARG(thread
);
2847 bgp
->t_startup
= NULL
;
2852 /* BGP instance creation by `router bgp' commands. */
2853 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2854 enum bgp_instance_type inst_type
)
2860 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2863 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2864 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2865 zlog_debug("Creating Default VRF, AS %u", *as
);
2867 zlog_debug("Creating %s %s, AS %u",
2868 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2875 bgp
->heuristic_coalesce
= true;
2876 bgp
->inst_type
= inst_type
;
2877 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2879 bgp
->peer_self
= peer_new(bgp
);
2880 if (bgp
->peer_self
->host
)
2881 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2882 bgp
->peer_self
->host
=
2883 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2884 if (bgp
->peer_self
->hostname
!= NULL
) {
2885 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2886 bgp
->peer_self
->hostname
= NULL
;
2888 if (cmd_hostname_get())
2889 bgp
->peer_self
->hostname
=
2890 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2892 if (bgp
->peer_self
->domainname
!= NULL
) {
2893 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2894 bgp
->peer_self
->domainname
= NULL
;
2896 if (cmd_domainname_get())
2897 bgp
->peer_self
->domainname
=
2898 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2899 bgp
->peer
= list_new();
2900 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2901 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2903 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2905 bgp
->group
= list_new();
2906 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2908 FOREACH_AFI_SAFI (afi
, safi
) {
2909 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2910 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2911 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2913 /* Enable maximum-paths */
2914 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2916 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2920 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2921 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2922 bgp
->default_subgroup_pkt_queue_max
=
2923 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2924 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2925 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2926 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2927 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2928 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2929 bgp
->dynamic_neighbors_count
= 0;
2930 #if DFLT_BGP_IMPORT_CHECK
2931 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2933 #if DFLT_BGP_SHOW_HOSTNAME
2934 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2936 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2937 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2939 #if DFLT_BGP_DETERMINISTIC_MED
2940 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2942 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2947 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2948 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2950 assert(bgp
->rfapi_cfg
);
2952 #endif /* ENABLE_BGP_VNC */
2954 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2955 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2956 bgp
->vpn_policy
[afi
].afi
= afi
;
2957 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2958 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2961 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2962 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2965 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2967 /* TODO - The startup timer needs to be run for the whole of BGP
2969 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2970 bgp
->restart_time
, &bgp
->t_startup
);
2973 /* printable name we can use in debug messages */
2974 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2975 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2985 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2987 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2988 snprintf(bgp
->name_pretty
, len
, "%s %s",
2989 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2995 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2996 memory_order_relaxed
);
2997 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2998 memory_order_relaxed
);
2999 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3003 update_bgp_group_init(bgp
);
3005 /* assign a unique rd id for auto derivation of vrf's RD */
3006 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3012 /* Return the "default VRF" instance of BGP. */
3013 struct bgp
*bgp_get_default(void)
3016 struct listnode
*node
, *nnode
;
3018 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3019 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3024 /* Lookup BGP entry. */
3025 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3028 struct listnode
*node
, *nnode
;
3030 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3032 && ((bgp
->name
== NULL
&& name
== NULL
)
3033 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3038 /* Lookup BGP structure by view name. */
3039 struct bgp
*bgp_lookup_by_name(const char *name
)
3042 struct listnode
*node
, *nnode
;
3044 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3045 if ((bgp
->name
== NULL
&& name
== NULL
)
3046 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3051 /* Lookup BGP instance based on VRF id. */
3052 /* Note: Only to be used for incoming messages from Zebra. */
3053 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3057 /* Lookup VRF (in tree) and follow link. */
3058 vrf
= vrf_lookup_by_id(vrf_id
);
3061 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3064 /* handle socket creation or deletion, if necessary
3065 * this is called for all new BGP instances
3067 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3072 /* Create BGP server socket, if listen mode not disabled */
3073 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3075 if (bgp
->name
&& bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&& vrf
) {
3077 * suppress vrf socket
3079 if (create
== FALSE
) {
3080 if (vrf_is_mapped_on_netns(vrf
->vrf_id
))
3081 bgp_close_vrf_socket(bgp
);
3083 ret
= bgp_check_main_socket(create
, bgp
);
3087 * if vrf_id did not change
3089 if (vrf
->vrf_id
== old_vrf_id
)
3091 if (old_vrf_id
!= VRF_UNKNOWN
) {
3092 /* look for old socket. close it. */
3093 bgp_close_vrf_socket(bgp
);
3095 /* if backend is not yet identified ( VRF_UNKNOWN) then
3096 * creation will be done later
3098 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3100 /* if BGP VRF instance requested
3101 * if backend is NETNS, create BGP server socket in the NETNS
3103 if (vrf_is_mapped_on_netns(bgp
->vrf_id
)) {
3104 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3106 return BGP_ERR_INVALID_VALUE
;
3110 /* if BGP VRF instance requested or VRF lite backend
3111 * if BGP non VRF instance, create it
3112 * if not already done
3114 return bgp_check_main_socket(create
, bgp
);
3117 /* Called from VTY commands. */
3118 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3119 enum bgp_instance_type inst_type
)
3122 struct vrf
*vrf
= NULL
;
3124 /* Multiple instance check. */
3125 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3127 bgp
= bgp_lookup_by_name(name
);
3129 bgp
= bgp_get_default();
3131 /* Already exists. */
3133 if (bgp
->as
!= *as
) {
3135 return BGP_ERR_INSTANCE_MISMATCH
;
3137 if (bgp
->inst_type
!= inst_type
)
3138 return BGP_ERR_INSTANCE_MISMATCH
;
3143 /* BGP instance name can not be specified for single instance.
3146 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3148 /* Get default BGP structure if exists. */
3149 bgp
= bgp_get_default();
3152 if (bgp
->as
!= *as
) {
3154 return BGP_ERR_AS_MISMATCH
;
3161 bgp
= bgp_create(as
, name
, inst_type
);
3162 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3163 bgp_address_init(bgp
);
3164 bgp_tip_hash_init(bgp
);
3168 bgp
->t_rmap_def_originate_eval
= NULL
;
3170 /* If Default instance or VRF, link to the VRF structure, if present. */
3171 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3172 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3173 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3175 bgp_vrf_link(bgp
, vrf
);
3177 /* BGP server socket already processed if BGP instance
3178 * already part of the list
3180 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3181 listnode_add(bm
->bgp
, bgp
);
3183 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3184 bgp_zebra_instance_register(bgp
);
3191 * Make BGP instance "up". Applies only to VRFs (non-default) and
3192 * implies the VRF has been learnt from Zebra.
3194 void bgp_instance_up(struct bgp
*bgp
)
3197 struct listnode
*node
, *next
;
3199 /* Register with zebra. */
3200 bgp_zebra_instance_register(bgp
);
3202 /* Kick off any peers that may have been configured. */
3203 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3204 if (!BGP_PEER_START_SUPPRESSED(peer
))
3205 BGP_EVENT_ADD(peer
, BGP_Start
);
3208 /* Process any networks that have been configured. */
3209 bgp_static_add(bgp
);
3213 * Make BGP instance "down". Applies only to VRFs (non-default) and
3214 * implies the VRF has been deleted by Zebra.
3216 void bgp_instance_down(struct bgp
*bgp
)
3219 struct listnode
*node
;
3220 struct listnode
*next
;
3223 if (bgp
->t_rmap_def_originate_eval
) {
3224 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3225 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3229 /* Bring down peers, so corresponding routes are purged. */
3230 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3231 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3233 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3235 bgp_session_reset(peer
);
3238 /* Purge network and redistributed routes. */
3239 bgp_purge_static_redist_routes(bgp
);
3241 /* Cleanup registered nexthops (flags) */
3242 bgp_cleanup_nexthops(bgp
);
3245 /* Delete BGP instance. */
3246 int bgp_delete(struct bgp
*bgp
)
3249 struct peer_group
*group
;
3250 struct listnode
*node
, *next
;
3255 THREAD_OFF(bgp
->t_startup
);
3257 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3258 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3259 zlog_debug("Deleting Default VRF");
3261 zlog_debug("Deleting %s %s",
3262 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3268 /* unmap from RT list */
3269 bgp_evpn_vrf_delete(bgp
);
3272 if (bgp
->t_rmap_def_originate_eval
) {
3273 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3274 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3278 /* Inform peers we're going down. */
3279 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3280 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3281 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3282 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3285 /* Delete static routes (networks). */
3286 bgp_static_delete(bgp
);
3288 /* Unset redistribution. */
3289 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3290 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3291 if (i
!= ZEBRA_ROUTE_BGP
)
3292 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3294 /* Free peers and peer-groups. */
3295 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3296 peer_group_delete(group
);
3298 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3301 if (bgp
->peer_self
) {
3302 peer_delete(bgp
->peer_self
);
3303 bgp
->peer_self
= NULL
;
3306 update_bgp_group_free(bgp
);
3308 /* TODO - Other memory may need to be freed - e.g., NHT */
3313 bgp_cleanup_routes(bgp
);
3315 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3316 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3319 &bgp
->vpn_policy
[afi
]
3320 .import_redirect_rtlist
);
3321 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3323 /* Remove visibility via the master list - there may however still be
3324 * routes to be processed still referencing the struct bgp.
3326 listnode_delete(bm
->bgp
, bgp
);
3328 /* Deregister from Zebra, if needed */
3329 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3330 bgp_zebra_instance_deregister(bgp
);
3332 /* Free interfaces in this instance. */
3335 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3336 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3338 bgp_vrf_unlink(bgp
, vrf
);
3340 thread_master_free_unused(bm
->master
);
3341 bgp_unlock(bgp
); /* initial reference */
3346 void bgp_free(struct bgp
*bgp
)
3350 struct bgp_table
*table
;
3351 struct bgp_node
*rn
;
3352 struct bgp_rmap
*rmap
;
3356 list_delete_and_null(&bgp
->group
);
3357 list_delete_and_null(&bgp
->peer
);
3359 if (bgp
->peerhash
) {
3360 hash_free(bgp
->peerhash
);
3361 bgp
->peerhash
= NULL
;
3364 FOREACH_AFI_SAFI (afi
, safi
) {
3365 /* Special handling for 2-level routing tables. */
3366 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3367 || safi
== SAFI_EVPN
) {
3368 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3369 rn
= bgp_route_next(rn
)) {
3370 table
= (struct bgp_table
*)rn
->info
;
3371 bgp_table_finish(&table
);
3374 if (bgp
->route
[afi
][safi
])
3375 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3376 if (bgp
->aggregate
[afi
][safi
])
3377 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3378 if (bgp
->rib
[afi
][safi
])
3379 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3380 rmap
= &bgp
->table_map
[afi
][safi
];
3382 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3385 * Yes this is per AFI, but
3386 * the list_delete_and_null nulls the pointer
3387 * and we'll not leak anything on going down
3388 * and the if test will fail on the second safi.
3390 if (bgp
->vpn_policy
[afi
].import_vrf
)
3391 list_delete_and_null(&bgp
->vpn_policy
[afi
].import_vrf
);
3392 if (bgp
->vpn_policy
[afi
].export_vrf
)
3393 list_delete_and_null(&bgp
->vpn_policy
[afi
].export_vrf
);
3396 bgp_scan_finish(bgp
);
3397 bgp_address_destroy(bgp
);
3398 bgp_tip_hash_destroy(bgp
);
3400 /* release the auto RD id */
3401 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3403 bgp_evpn_cleanup(bgp
);
3406 XFREE(MTYPE_BGP
, bgp
->name
);
3407 if (bgp
->name_pretty
)
3408 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3410 XFREE(MTYPE_BGP
, bgp
);
3413 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3416 struct listnode
*node
, *nnode
;
3422 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3423 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3424 && !CHECK_FLAG(peer
->sflags
,
3425 PEER_STATUS_ACCEPT_PEER
))
3427 } else if (bm
->bgp
!= NULL
) {
3428 struct listnode
*bgpnode
, *nbgpnode
;
3430 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3431 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3433 && !strcmp(peer
->conf_if
, conf_if
)
3434 && !CHECK_FLAG(peer
->sflags
,
3435 PEER_STATUS_ACCEPT_PEER
))
3441 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3444 struct listnode
*node
, *nnode
;
3450 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3451 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3452 && !CHECK_FLAG(peer
->sflags
,
3453 PEER_STATUS_ACCEPT_PEER
))
3455 } else if (bm
->bgp
!= NULL
) {
3456 struct listnode
*bgpnode
, *nbgpnode
;
3458 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3459 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3461 && !strcmp(peer
->hostname
, hostname
)
3462 && !CHECK_FLAG(peer
->sflags
,
3463 PEER_STATUS_ACCEPT_PEER
))
3469 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3471 struct peer
*peer
= NULL
;
3472 struct peer tmp_peer
;
3474 memset(&tmp_peer
, 0, sizeof(struct peer
));
3477 * We do not want to find the doppelganger peer so search for the peer
3479 * the hash that has PEER_FLAG_CONFIG_NODE
3481 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3486 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3487 } else if (bm
->bgp
!= NULL
) {
3488 struct listnode
*bgpnode
, *nbgpnode
;
3490 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3491 /* Skip VRFs Lite only, this function will not be
3492 * invoked without an instance
3493 * when examining VRFs.
3495 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3496 && !vrf_is_mapped_on_netns(bgp
->vrf_id
))
3499 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3509 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3510 union sockunion
*su
,
3511 struct peer_group
*group
)
3517 /* Create peer first; we've already checked group config is valid. */
3518 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3519 group
->conf
->as_type
, 0, 0, group
);
3524 peer
= peer_lock(peer
);
3525 listnode_add(group
->peer
, peer
);
3527 peer_group2peer_config_copy(group
, peer
);
3530 * Bind peer for all AFs configured for the group. We don't call
3531 * peer_group_bind as that is sub-optimal and does some stuff we don't
3534 FOREACH_AFI_SAFI (afi
, safi
) {
3535 if (!group
->conf
->afc
[afi
][safi
])
3537 peer
->afc
[afi
][safi
] = 1;
3539 if (!peer_af_find(peer
, afi
, safi
))
3540 peer_af_create(peer
, afi
, safi
);
3542 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3545 /* Mark as dynamic, but also as a "config node" for other things to
3547 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3548 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3554 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3555 struct prefix
*prefix
)
3557 struct listnode
*node
, *nnode
;
3558 struct prefix
*range
;
3561 afi
= family2afi(prefix
->family
);
3563 if (group
->listen_range
[afi
])
3564 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3566 if (prefix_match(range
, prefix
))
3573 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3574 struct prefix
**listen_range
)
3576 struct prefix
*range
= NULL
;
3577 struct peer_group
*group
= NULL
;
3578 struct listnode
*node
, *nnode
;
3580 *listen_range
= NULL
;
3582 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3583 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3586 } else if (bm
->bgp
!= NULL
) {
3587 struct listnode
*bgpnode
, *nbgpnode
;
3589 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3590 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3591 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3597 *listen_range
= range
;
3598 return (group
&& range
) ? group
: NULL
;
3601 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3603 struct peer_group
*group
;
3606 struct prefix prefix
;
3607 struct prefix
*listen_range
;
3609 char buf
[PREFIX2STR_BUFFER
];
3610 char buf1
[PREFIX2STR_BUFFER
];
3612 sockunion2hostprefix(su
, &prefix
);
3614 /* See if incoming connection matches a configured listen range. */
3615 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3626 prefix2str(&prefix
, buf
, sizeof(buf
));
3627 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3629 if (bgp_debug_neighbor_events(NULL
))
3631 "Dynamic Neighbor %s matches group %s listen range %s",
3632 buf
, group
->name
, buf1
);
3634 /* Are we within the listen limit? */
3635 dncount
= gbgp
->dynamic_neighbors_count
;
3637 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3638 if (bgp_debug_neighbor_events(NULL
))
3639 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3640 inet_sutop(su
, buf
),
3641 gbgp
->dynamic_neighbors_limit
);
3645 /* Ensure group is not disabled. */
3646 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3647 if (bgp_debug_neighbor_events(NULL
))
3649 "Dynamic Neighbor %s rejected - group %s disabled",
3654 /* Check that at least one AF is activated for the group. */
3655 if (!peer_group_af_configured(group
)) {
3656 if (bgp_debug_neighbor_events(NULL
))
3658 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3663 /* Create dynamic peer and bind to associated group. */
3664 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3667 gbgp
->dynamic_neighbors_count
= ++dncount
;
3669 if (bgp_debug_neighbor_events(peer
))
3670 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3671 peer
->host
, group
->name
, dncount
);
3676 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3679 if (peer
->group
&& peer
->group
->bgp
) {
3680 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3682 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3684 if (bgp_debug_neighbor_events(peer
))
3685 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3686 peer
->group
->name
, dncount
);
3690 /* If peer is configured at least one address family return 1. */
3691 int peer_active(struct peer
*peer
)
3693 if (BGP_PEER_SU_UNSPEC(peer
))
3695 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3696 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3697 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3698 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3699 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3700 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3701 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3702 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3703 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3704 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3705 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3710 /* If peer is negotiated at least one address family return 1. */
3711 int peer_active_nego(struct peer
*peer
)
3713 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3714 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3715 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3716 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3717 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3718 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3719 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3720 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3721 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3722 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3723 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3724 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3725 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3730 /* peer_flag_change_type. */
3731 enum peer_change_type
{
3734 peer_change_reset_in
,
3735 peer_change_reset_out
,
3738 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3739 enum peer_change_type type
)
3741 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3744 if (peer
->status
!= Established
)
3747 if (type
== peer_change_reset
) {
3748 /* If we're resetting session, we've to delete both peer struct
3750 if ((peer
->doppelganger
)
3751 && (peer
->doppelganger
->status
!= Deleted
)
3752 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3753 PEER_FLAG_CONFIG_NODE
)))
3754 peer_delete(peer
->doppelganger
);
3756 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3757 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3758 } else if (type
== peer_change_reset_in
) {
3759 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3760 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3761 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3763 if ((peer
->doppelganger
)
3764 && (peer
->doppelganger
->status
!= Deleted
)
3765 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3766 PEER_FLAG_CONFIG_NODE
)))
3767 peer_delete(peer
->doppelganger
);
3769 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3770 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3772 } else if (type
== peer_change_reset_out
) {
3773 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3774 bgp_announce_route(peer
, afi
, safi
);
3778 struct peer_flag_action
{
3782 /* This flag can be set for peer-group member. */
3783 uint8_t not_for_member
;
3785 /* Action when the flag is changed. */
3786 enum peer_change_type type
;
3788 /* Peer down cause */
3792 static const struct peer_flag_action peer_flag_action_list
[] = {
3793 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3794 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3795 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3796 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3797 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3798 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3799 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3800 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3803 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3804 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3805 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3806 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3807 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3808 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3809 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3810 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3811 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3812 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3813 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3814 // PEER_FLAG_DEFAULT_ORIGINATE
3815 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3816 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3817 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3818 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3819 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3820 // PEER_FLAG_MAX_PREFIX
3821 // PEER_FLAG_MAX_PREFIX_WARNING
3822 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3823 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3824 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3825 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3826 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3827 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3828 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3829 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3830 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3833 /* Proper action set. */
3834 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3835 int size
, struct peer_flag_action
*action
,
3842 const struct peer_flag_action
*match
= NULL
;
3844 /* Check peer's frag action. */
3845 for (i
= 0; i
< size
; i
++) {
3846 match
= &action_list
[i
];
3848 if (match
->flag
== 0)
3851 if (match
->flag
& flag
) {
3854 if (match
->type
== peer_change_reset_in
)
3856 if (match
->type
== peer_change_reset_out
)
3858 if (match
->type
== peer_change_reset
) {
3862 if (match
->not_for_member
)
3863 action
->not_for_member
= 1;
3867 /* Set peer clear type. */
3868 if (reset_in
&& reset_out
)
3869 action
->type
= peer_change_reset
;
3871 action
->type
= peer_change_reset_in
;
3873 action
->type
= peer_change_reset_out
;
3875 action
->type
= peer_change_none
;
3880 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3882 if (flag
== PEER_FLAG_SHUTDOWN
) {
3883 if (CHECK_FLAG(peer
->flags
, flag
)) {
3884 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3885 peer_nsf_stop(peer
);
3887 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3888 if (peer
->t_pmax_restart
) {
3889 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3890 if (bgp_debug_neighbor_events(peer
))
3892 "%s Maximum-prefix restart timer canceled",
3896 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3897 peer_nsf_stop(peer
);
3899 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3900 char *msg
= peer
->tx_shutdown_message
;
3903 if (!msg
&& peer_group_active(peer
))
3904 msg
= peer
->group
->conf
3905 ->tx_shutdown_message
;
3906 msglen
= msg
? strlen(msg
) : 0;
3911 uint8_t msgbuf
[129];
3914 memcpy(msgbuf
+ 1, msg
, msglen
);
3916 bgp_notify_send_with_data(
3917 peer
, BGP_NOTIFY_CEASE
,
3918 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3919 msgbuf
, msglen
+ 1);
3922 peer
, BGP_NOTIFY_CEASE
,
3923 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3925 bgp_session_reset(peer
);
3927 peer
->v_start
= BGP_INIT_START_TIMER
;
3928 BGP_EVENT_ADD(peer
, BGP_Stop
);
3930 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3931 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3932 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3933 else if (flag
== PEER_FLAG_PASSIVE
)
3934 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3935 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3936 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3938 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3939 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3941 bgp_session_reset(peer
);
3944 /* Change specified peer flag. */
3945 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3949 struct peer_group
*group
;
3950 struct peer
*tmp_peer
;
3951 struct listnode
*node
, *nnode
;
3952 struct peer_flag_action action
;
3954 memset(&action
, 0, sizeof(struct peer_flag_action
));
3955 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3957 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3960 /* No flag action is found. */
3962 return BGP_ERR_INVALID_FLAG
;
3964 /* When unset the peer-group member's flag we have to check
3965 peer-group configuration. */
3966 if (!set
&& peer_group_active(peer
))
3967 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3968 if (flag
== PEER_FLAG_SHUTDOWN
)
3969 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3972 /* Flag conflict check. */
3973 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3974 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3975 return BGP_ERR_PEER_FLAG_CONFLICT
;
3977 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3978 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3980 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3985 SET_FLAG(peer
->flags
, flag
);
3987 UNSET_FLAG(peer
->flags
, flag
);
3989 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3990 if (action
.type
== peer_change_reset
)
3991 peer_flag_modify_action(peer
, flag
);
3996 /* peer-group member updates. */
3997 group
= peer
->group
;
3999 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4001 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
4004 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
4008 SET_FLAG(tmp_peer
->flags
, flag
);
4010 UNSET_FLAG(tmp_peer
->flags
, flag
);
4012 if (action
.type
== peer_change_reset
)
4013 peer_flag_modify_action(tmp_peer
, flag
);
4018 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4020 return peer_flag_modify(peer
, flag
, 1);
4023 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4025 return peer_flag_modify(peer
, flag
, 0);
4028 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4029 uint32_t flag
, int set
)
4033 struct listnode
*node
, *nnode
;
4034 struct peer_group
*group
;
4035 struct peer_flag_action action
;
4036 struct peer
*tmp_peer
;
4038 int addpath_tx_used
;
4040 memset(&action
, 0, sizeof(struct peer_flag_action
));
4041 size
= sizeof peer_af_flag_action_list
4042 / sizeof(struct peer_flag_action
);
4044 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4047 /* No flag action is found. */
4049 return BGP_ERR_INVALID_FLAG
;
4051 /* Special check for reflector client. */
4052 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4053 && peer_sort(peer
) != BGP_PEER_IBGP
)
4054 return BGP_ERR_NOT_INTERNAL_PEER
;
4056 /* Special check for remove-private-AS. */
4057 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4058 && peer_sort(peer
) == BGP_PEER_IBGP
)
4059 return BGP_ERR_REMOVE_PRIVATE_AS
;
4061 /* as-override is not allowed for IBGP peers */
4062 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4063 return BGP_ERR_AS_OVERRIDE
;
4065 /* When current flag configuration is same as requested one. */
4066 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4067 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
4069 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
4074 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4076 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4078 /* Execute action when peer is established. */
4079 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4080 && peer
->status
== Established
) {
4081 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4082 bgp_clear_adj_in(peer
, afi
, safi
);
4084 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4085 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4086 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4087 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4088 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4089 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4090 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4091 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4093 peer_change_action(peer
, afi
, safi
, action
.type
);
4097 /* Peer group member updates. */
4098 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4099 group
= peer
->group
;
4101 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4103 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
4108 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
4112 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4114 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4116 if (tmp_peer
->status
== Established
) {
4117 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4118 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
4120 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4121 tmp_peer
->last_reset
=
4122 PEER_DOWN_RR_CLIENT_CHANGE
;
4124 == PEER_FLAG_RSERVER_CLIENT
)
4125 tmp_peer
->last_reset
=
4126 PEER_DOWN_RS_CLIENT_CHANGE
;
4128 == PEER_FLAG_ORF_PREFIX_SM
)
4129 tmp_peer
->last_reset
=
4130 PEER_DOWN_CAPABILITY_CHANGE
;
4132 == PEER_FLAG_ORF_PREFIX_RM
)
4133 tmp_peer
->last_reset
=
4134 PEER_DOWN_CAPABILITY_CHANGE
;
4136 peer_change_action(tmp_peer
, afi
, safi
,
4143 /* Track if addpath TX is in use */
4144 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4145 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4147 addpath_tx_used
= 0;
4150 addpath_tx_used
= 1;
4152 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4153 if (!bgp_flag_check(
4154 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4156 "%s: enabling bgp deterministic-med, this is required"
4157 " for addpath-tx-bestpath-per-AS",
4161 BGP_FLAG_DETERMINISTIC_MED
);
4162 bgp_recalculate_all_bestpaths(bgp
);
4166 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4168 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4169 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4171 tmp_peer
->af_flags
[afi
][safi
],
4172 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4173 addpath_tx_used
= 1;
4179 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4185 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4187 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4190 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4192 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4196 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4198 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4199 peer
->tx_shutdown_message
=
4200 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4204 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4206 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4211 /* EBGP multihop configuration. */
4212 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4214 struct peer_group
*group
;
4215 struct listnode
*node
, *nnode
;
4218 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4221 /* see comment in peer_ttl_security_hops_set() */
4222 if (ttl
!= MAXTTL
) {
4223 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4224 group
= peer
->group
;
4225 if (group
->conf
->gtsm_hops
!= 0)
4226 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4228 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4230 if (peer1
->sort
== BGP_PEER_IBGP
)
4233 if (peer1
->gtsm_hops
!= 0)
4234 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4237 if (peer
->gtsm_hops
!= 0)
4238 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4244 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4245 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4246 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4247 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4248 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4250 bgp_session_reset(peer
);
4253 group
= peer
->group
;
4254 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4255 if (peer
->sort
== BGP_PEER_IBGP
)
4258 peer
->ttl
= group
->conf
->ttl
;
4260 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4261 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4262 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4264 bgp_session_reset(peer
);
4270 int peer_ebgp_multihop_unset(struct peer
*peer
)
4272 struct peer_group
*group
;
4273 struct listnode
*node
, *nnode
;
4275 if (peer
->sort
== BGP_PEER_IBGP
)
4278 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4279 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4281 if (peer_group_active(peer
))
4282 peer
->ttl
= peer
->group
->conf
->ttl
;
4286 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4287 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4288 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4289 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4291 bgp_session_reset(peer
);
4293 group
= peer
->group
;
4294 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4295 if (peer
->sort
== BGP_PEER_IBGP
)
4300 if (peer
->fd
>= 0) {
4301 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4303 peer
, BGP_NOTIFY_CEASE
,
4304 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4306 bgp_session_reset(peer
);
4313 /* Neighbor description. */
4314 int peer_description_set(struct peer
*peer
, const char *desc
)
4317 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4319 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4324 int peer_description_unset(struct peer
*peer
)
4327 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4334 /* Neighbor update-source. */
4335 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4337 struct peer_group
*group
;
4338 struct listnode
*node
, *nnode
;
4340 if (peer
->update_if
) {
4341 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4342 && strcmp(peer
->update_if
, ifname
) == 0)
4345 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4346 peer
->update_if
= NULL
;
4349 if (peer
->update_source
) {
4350 sockunion_free(peer
->update_source
);
4351 peer
->update_source
= NULL
;
4354 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4356 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4357 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4358 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4362 bgp_session_reset(peer
);
4366 /* peer-group member updates. */
4367 group
= peer
->group
;
4368 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4369 if (peer
->update_if
) {
4370 if (strcmp(peer
->update_if
, ifname
) == 0)
4373 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4374 peer
->update_if
= NULL
;
4377 if (peer
->update_source
) {
4378 sockunion_free(peer
->update_source
);
4379 peer
->update_source
= NULL
;
4382 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4384 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4385 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4386 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4387 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4389 bgp_session_reset(peer
);
4394 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4396 struct peer_group
*group
;
4397 struct listnode
*node
, *nnode
;
4399 if (peer
->update_source
) {
4400 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4401 && sockunion_cmp(peer
->update_source
, su
) == 0)
4403 sockunion_free(peer
->update_source
);
4404 peer
->update_source
= NULL
;
4407 if (peer
->update_if
) {
4408 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4409 peer
->update_if
= NULL
;
4412 peer
->update_source
= sockunion_dup(su
);
4414 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4415 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4416 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4417 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4418 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4420 bgp_session_reset(peer
);
4424 /* peer-group member updates. */
4425 group
= peer
->group
;
4426 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4427 if (peer
->update_source
) {
4428 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4430 sockunion_free(peer
->update_source
);
4431 peer
->update_source
= NULL
;
4434 if (peer
->update_if
) {
4435 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4436 peer
->update_if
= NULL
;
4439 peer
->update_source
= sockunion_dup(su
);
4441 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4442 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4443 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4444 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4446 bgp_session_reset(peer
);
4451 int peer_update_source_unset(struct peer
*peer
)
4453 union sockunion
*su
;
4454 struct peer_group
*group
;
4455 struct listnode
*node
, *nnode
;
4457 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4458 && !peer
->update_if
)
4461 if (peer
->update_source
) {
4462 sockunion_free(peer
->update_source
);
4463 peer
->update_source
= NULL
;
4465 if (peer
->update_if
) {
4466 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4467 peer
->update_if
= NULL
;
4470 if (peer_group_active(peer
)) {
4471 group
= peer
->group
;
4473 if (group
->conf
->update_source
) {
4474 su
= sockunion_dup(group
->conf
->update_source
);
4475 peer
->update_source
= su
;
4476 } else if (group
->conf
->update_if
)
4477 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4478 group
->conf
->update_if
);
4481 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4482 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4483 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4484 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4485 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4487 bgp_session_reset(peer
);
4491 /* peer-group member updates. */
4492 group
= peer
->group
;
4493 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4494 if (!peer
->update_source
&& !peer
->update_if
)
4497 if (peer
->update_source
) {
4498 sockunion_free(peer
->update_source
);
4499 peer
->update_source
= NULL
;
4502 if (peer
->update_if
) {
4503 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4504 peer
->update_if
= NULL
;
4507 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4508 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4509 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4510 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4512 bgp_session_reset(peer
);
4517 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4520 struct peer_group
*group
;
4521 struct listnode
*node
, *nnode
;
4523 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4524 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4526 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4527 SET_FLAG(peer
->af_flags
[afi
][safi
],
4528 PEER_FLAG_DEFAULT_ORIGINATE
);
4531 if (peer
->default_rmap
[afi
][safi
].name
)
4532 XFREE(MTYPE_ROUTE_MAP_NAME
,
4533 peer
->default_rmap
[afi
][safi
].name
);
4534 peer
->default_rmap
[afi
][safi
].name
=
4535 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4536 peer
->default_rmap
[afi
][safi
].map
=
4537 route_map_lookup_by_name(rmap
);
4541 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4542 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4543 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4544 bgp_default_originate(peer
, afi
, safi
, 0);
4545 bgp_announce_route(peer
, afi
, safi
);
4550 /* peer-group member updates. */
4551 group
= peer
->group
;
4552 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4553 SET_FLAG(peer
->af_flags
[afi
][safi
],
4554 PEER_FLAG_DEFAULT_ORIGINATE
);
4557 if (peer
->default_rmap
[afi
][safi
].name
)
4558 XFREE(MTYPE_ROUTE_MAP_NAME
,
4559 peer
->default_rmap
[afi
][safi
].name
);
4560 peer
->default_rmap
[afi
][safi
].name
=
4561 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4562 peer
->default_rmap
[afi
][safi
].map
=
4563 route_map_lookup_by_name(rmap
);
4566 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4567 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4568 bgp_default_originate(peer
, afi
, safi
, 0);
4569 bgp_announce_route(peer
, afi
, safi
);
4575 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4577 struct peer_group
*group
;
4578 struct listnode
*node
, *nnode
;
4580 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4581 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4582 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4583 PEER_FLAG_DEFAULT_ORIGINATE
);
4585 if (peer
->default_rmap
[afi
][safi
].name
)
4586 XFREE(MTYPE_ROUTE_MAP_NAME
,
4587 peer
->default_rmap
[afi
][safi
].name
);
4588 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4589 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4592 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4593 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4594 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4595 bgp_default_originate(peer
, afi
, safi
, 1);
4596 bgp_announce_route(peer
, afi
, safi
);
4601 /* peer-group member updates. */
4602 group
= peer
->group
;
4603 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4604 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4605 PEER_FLAG_DEFAULT_ORIGINATE
);
4607 if (peer
->default_rmap
[afi
][safi
].name
)
4608 XFREE(MTYPE_ROUTE_MAP_NAME
,
4609 peer
->default_rmap
[afi
][safi
].name
);
4610 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4611 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4613 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4614 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4615 bgp_default_originate(peer
, afi
, safi
, 1);
4616 bgp_announce_route(peer
, afi
, safi
);
4622 int peer_port_set(struct peer
*peer
, uint16_t port
)
4628 int peer_port_unset(struct peer
*peer
)
4630 peer
->port
= BGP_PORT_DEFAULT
;
4635 * Helper function that is called after the name of the policy
4636 * being used by a peer has changed (AF specific). Automatically
4637 * initiates inbound or outbound processing as needed.
4639 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4643 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4644 if (peer
->status
== Established
)
4645 bgp_announce_route(peer
, afi
, safi
);
4647 if (peer
->status
!= Established
)
4650 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4651 PEER_FLAG_SOFT_RECONFIG
))
4652 bgp_soft_reconfig_in(peer
, afi
, safi
);
4653 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4654 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4655 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4660 /* neighbor weight. */
4661 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4663 struct peer_group
*group
;
4664 struct listnode
*node
, *nnode
;
4666 if (peer
->weight
[afi
][safi
] != weight
) {
4667 peer
->weight
[afi
][safi
] = weight
;
4668 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4669 peer_on_policy_change(peer
, afi
, safi
, 0);
4672 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4675 /* peer-group member updates. */
4676 group
= peer
->group
;
4677 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4678 if (peer
->weight
[afi
][safi
] != weight
) {
4679 peer
->weight
[afi
][safi
] = weight
;
4680 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4681 peer_on_policy_change(peer
, afi
, safi
, 0);
4687 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4689 struct peer_group
*group
;
4690 struct listnode
*node
, *nnode
;
4692 /* not the peer-group itself but a peer in a peer-group */
4693 if (peer_group_active(peer
)) {
4694 group
= peer
->group
;
4696 /* inherit weight from the peer-group */
4697 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4698 PEER_FLAG_WEIGHT
)) {
4699 peer
->weight
[afi
][safi
] =
4700 group
->conf
->weight
[afi
][safi
];
4701 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4702 peer_on_policy_change(peer
, afi
, safi
, 0);
4704 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4705 PEER_FLAG_WEIGHT
)) {
4706 peer
->weight
[afi
][safi
] = 0;
4707 peer_af_flag_unset(peer
, afi
, safi
,
4709 peer_on_policy_change(peer
, afi
, safi
, 0);
4715 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4716 peer
->weight
[afi
][safi
] = 0;
4717 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4718 peer_on_policy_change(peer
, afi
, safi
, 0);
4721 /* peer-group member updates. */
4722 group
= peer
->group
;
4725 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4727 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4728 PEER_FLAG_WEIGHT
)) {
4729 peer
->weight
[afi
][safi
] = 0;
4730 peer_af_flag_unset(peer
, afi
, safi
,
4732 peer_on_policy_change(peer
, afi
, safi
,
4741 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4743 struct peer_group
*group
;
4744 struct listnode
*node
, *nnode
;
4746 /* keepalive value check. */
4747 if (keepalive
> 65535)
4748 return BGP_ERR_INVALID_VALUE
;
4750 /* Holdtime value check. */
4751 if (holdtime
> 65535)
4752 return BGP_ERR_INVALID_VALUE
;
4754 /* Holdtime value must be either 0 or greater than 3. */
4755 if (holdtime
< 3 && holdtime
!= 0)
4756 return BGP_ERR_INVALID_VALUE
;
4758 /* Set value to the configuration. */
4759 peer
->holdtime
= holdtime
;
4760 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4762 /* First work on real peers with timers */
4763 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4764 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4765 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4767 /* Now work on the peer-group timers */
4768 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4770 /* peer-group member updates. */
4771 group
= peer
->group
;
4772 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4773 /* Skip peers that have their own timers */
4774 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4777 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4778 peer
->holdtime
= group
->conf
->holdtime
;
4779 peer
->keepalive
= group
->conf
->keepalive
;
4786 int peer_timers_unset(struct peer
*peer
)
4788 struct peer_group
*group
;
4789 struct listnode
*node
, *nnode
;
4791 /* First work on real peers vs the peer-group */
4792 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4793 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4794 peer
->keepalive
= 0;
4797 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4798 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4799 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4800 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4803 /* peer-group member updates. */
4804 group
= peer
->group
;
4805 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4806 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4807 UNSET_FLAG(peer
->config
,
4808 PEER_GROUP_CONFIG_TIMER
);
4810 peer
->keepalive
= 0;
4814 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4815 group
->conf
->holdtime
= 0;
4816 group
->conf
->keepalive
= 0;
4822 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4824 struct peer_group
*group
;
4825 struct listnode
*node
, *nnode
;
4827 if (connect
> 65535)
4828 return BGP_ERR_INVALID_VALUE
;
4830 /* Set value to the configuration. */
4831 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4832 peer
->connect
= connect
;
4834 /* Set value to timer setting. */
4835 peer
->v_connect
= connect
;
4837 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4840 /* peer-group member updates. */
4841 group
= peer
->group
;
4842 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4843 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4844 peer
->connect
= connect
;
4845 peer
->v_connect
= connect
;
4850 int peer_timers_connect_unset(struct peer
*peer
)
4852 struct peer_group
*group
;
4853 struct listnode
*node
, *nnode
;
4855 /* Clear configuration. */
4856 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4859 /* Set timer setting to default value. */
4860 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4862 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4865 /* peer-group member updates. */
4866 group
= peer
->group
;
4867 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4868 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4870 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4875 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4877 struct peer_group
*group
;
4878 struct listnode
*node
, *nnode
;
4881 return BGP_ERR_INVALID_VALUE
;
4883 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4884 peer
->routeadv
= routeadv
;
4885 peer
->v_routeadv
= routeadv
;
4887 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4888 update_group_adjust_peer_afs(peer
);
4889 if (peer
->status
== Established
)
4890 bgp_announce_route_all(peer
);
4894 /* peer-group member updates. */
4895 group
= peer
->group
;
4896 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4897 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4898 peer
->routeadv
= routeadv
;
4899 peer
->v_routeadv
= routeadv
;
4900 update_group_adjust_peer_afs(peer
);
4901 if (peer
->status
== Established
)
4902 bgp_announce_route_all(peer
);
4908 int peer_advertise_interval_unset(struct peer
*peer
)
4910 struct peer_group
*group
;
4911 struct listnode
*node
, *nnode
;
4913 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4916 if (peer
->sort
== BGP_PEER_IBGP
)
4917 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4919 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4921 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4922 update_group_adjust_peer_afs(peer
);
4923 if (peer
->status
== Established
)
4924 bgp_announce_route_all(peer
);
4928 /* peer-group member updates. */
4929 group
= peer
->group
;
4930 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4931 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4934 if (peer
->sort
== BGP_PEER_IBGP
)
4935 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4937 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4939 update_group_adjust_peer_afs(peer
);
4940 if (peer
->status
== Established
)
4941 bgp_announce_route_all(peer
);
4947 /* neighbor interface */
4948 void peer_interface_set(struct peer
*peer
, const char *str
)
4951 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4952 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4955 void peer_interface_unset(struct peer
*peer
)
4958 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4959 peer
->ifname
= NULL
;
4963 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4964 int allow_num
, int origin
)
4966 struct peer_group
*group
;
4967 struct listnode
*node
, *nnode
;
4970 if (peer
->allowas_in
[afi
][safi
]
4971 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4972 PEER_FLAG_ALLOWAS_IN
)
4973 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4974 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4975 peer
->allowas_in
[afi
][safi
] = 0;
4976 peer_af_flag_unset(peer
, afi
, safi
,
4977 PEER_FLAG_ALLOWAS_IN
);
4978 peer_af_flag_set(peer
, afi
, safi
,
4979 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4980 peer_on_policy_change(peer
, afi
, safi
, 0);
4983 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4986 group
= peer
->group
;
4987 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4988 if (peer
->allowas_in
[afi
][safi
]
4989 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4990 PEER_FLAG_ALLOWAS_IN
)
4991 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4992 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4993 peer
->allowas_in
[afi
][safi
] = 0;
4994 peer_af_flag_unset(peer
, afi
, safi
,
4995 PEER_FLAG_ALLOWAS_IN
);
4996 peer_af_flag_set(peer
, afi
, safi
,
4997 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4998 peer_on_policy_change(peer
, afi
, safi
, 0);
5002 if (allow_num
< 1 || allow_num
> 10)
5003 return BGP_ERR_INVALID_VALUE
;
5005 if (peer
->allowas_in
[afi
][safi
] != allow_num
5006 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5007 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5008 peer
->allowas_in
[afi
][safi
] = allow_num
;
5009 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5010 peer_af_flag_unset(peer
, afi
, safi
,
5011 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5012 peer_on_policy_change(peer
, afi
, safi
, 0);
5015 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5018 group
= peer
->group
;
5019 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5020 if (peer
->allowas_in
[afi
][safi
] != allow_num
5021 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5022 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5023 peer
->allowas_in
[afi
][safi
] = allow_num
;
5024 peer_af_flag_set(peer
, afi
, safi
,
5025 PEER_FLAG_ALLOWAS_IN
);
5026 peer_af_flag_unset(peer
, afi
, safi
,
5027 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5028 peer_on_policy_change(peer
, afi
, safi
, 0);
5036 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5038 struct peer_group
*group
;
5039 struct peer
*tmp_peer
;
5040 struct listnode
*node
, *nnode
;
5042 /* If this is a peer-group we must first clear the flags for all of the
5043 * peer-group members
5045 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5046 group
= peer
->group
;
5047 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
5048 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5049 PEER_FLAG_ALLOWAS_IN
)
5050 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5051 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5052 tmp_peer
->allowas_in
[afi
][safi
] = 0;
5053 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5054 PEER_FLAG_ALLOWAS_IN
);
5055 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5056 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5057 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
5062 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
5063 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5064 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5065 peer
->allowas_in
[afi
][safi
] = 0;
5066 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5067 peer_af_flag_unset(peer
, afi
, safi
,
5068 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5069 peer_on_policy_change(peer
, afi
, safi
, 0);
5075 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5078 struct bgp
*bgp
= peer
->bgp
;
5079 struct peer_group
*group
;
5080 struct listnode
*node
, *nnode
;
5082 if (peer_sort(peer
) != BGP_PEER_EBGP
5083 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5084 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5087 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5090 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5092 if (peer
->change_local_as
== as
5093 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5095 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5097 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5099 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5103 peer
->change_local_as
= as
;
5105 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5107 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5110 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5112 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5114 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5115 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5116 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5117 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5118 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5120 bgp_session_reset(peer
);
5124 group
= peer
->group
;
5125 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5126 peer
->change_local_as
= as
;
5128 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5130 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5133 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5135 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5137 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5138 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5139 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5140 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5142 BGP_EVENT_ADD(peer
, BGP_Stop
);
5148 int peer_local_as_unset(struct peer
*peer
)
5150 struct peer_group
*group
;
5151 struct listnode
*node
, *nnode
;
5153 if (!peer
->change_local_as
)
5156 peer
->change_local_as
= 0;
5157 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5158 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5160 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5161 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5162 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5163 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5164 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5166 BGP_EVENT_ADD(peer
, BGP_Stop
);
5171 group
= peer
->group
;
5172 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5173 peer
->change_local_as
= 0;
5174 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5175 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5177 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5178 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5179 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5180 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5182 bgp_session_reset(peer
);
5187 /* Set password for authenticating with the peer. */
5188 int peer_password_set(struct peer
*peer
, const char *password
)
5190 struct listnode
*nn
, *nnode
;
5191 int len
= password
? strlen(password
) : 0;
5192 int ret
= BGP_SUCCESS
;
5194 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5195 return BGP_ERR_INVALID_VALUE
;
5197 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5198 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5202 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5204 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5207 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5208 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5209 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5211 bgp_session_reset(peer
);
5213 if (BGP_PEER_SU_UNSPEC(peer
))
5216 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5217 : BGP_ERR_TCPSIG_FAILED
;
5220 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5221 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5225 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5227 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5229 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5230 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5231 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5233 bgp_session_reset(peer
);
5235 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5236 if (bgp_md5_set(peer
) < 0)
5237 ret
= BGP_ERR_TCPSIG_FAILED
;
5244 int peer_password_unset(struct peer
*peer
)
5246 struct listnode
*nn
, *nnode
;
5248 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5251 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5252 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5253 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5254 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5256 bgp_session_reset(peer
);
5259 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5261 peer
->password
= NULL
;
5263 if (!BGP_PEER_SU_UNSPEC(peer
))
5264 bgp_md5_unset(peer
);
5269 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5270 peer
->password
= NULL
;
5272 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5273 if (!peer
->password
)
5276 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5277 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5278 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5280 bgp_session_reset(peer
);
5282 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5283 peer
->password
= NULL
;
5285 if (!BGP_PEER_SU_UNSPEC(peer
))
5286 bgp_md5_unset(peer
);
5293 /* Set distribute list to the peer. */
5294 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5297 struct bgp_filter
*filter
;
5298 struct peer_group
*group
;
5299 struct listnode
*node
, *nnode
;
5301 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5302 return BGP_ERR_INVALID_VALUE
;
5304 filter
= &peer
->filter
[afi
][safi
];
5306 if (filter
->plist
[direct
].name
)
5307 return BGP_ERR_PEER_FILTER_CONFLICT
;
5309 if (filter
->dlist
[direct
].name
)
5310 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5311 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5312 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5314 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5315 peer_on_policy_change(peer
, afi
, safi
,
5316 (direct
== FILTER_OUT
) ? 1 : 0);
5320 group
= peer
->group
;
5321 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5322 filter
= &peer
->filter
[afi
][safi
];
5324 if (filter
->dlist
[direct
].name
)
5325 XFREE(MTYPE_BGP_FILTER_NAME
,
5326 filter
->dlist
[direct
].name
);
5327 filter
->dlist
[direct
].name
=
5328 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5329 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5330 peer_on_policy_change(peer
, afi
, safi
,
5331 (direct
== FILTER_OUT
) ? 1 : 0);
5337 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5339 struct bgp_filter
*filter
;
5340 struct bgp_filter
*gfilter
;
5341 struct peer_group
*group
;
5342 struct listnode
*node
, *nnode
;
5344 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5345 return BGP_ERR_INVALID_VALUE
;
5347 filter
= &peer
->filter
[afi
][safi
];
5349 /* apply peer-group filter */
5350 if (peer_group_active(peer
)) {
5351 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5353 if (gfilter
->dlist
[direct
].name
) {
5354 if (filter
->dlist
[direct
].name
)
5355 XFREE(MTYPE_BGP_FILTER_NAME
,
5356 filter
->dlist
[direct
].name
);
5357 filter
->dlist
[direct
].name
=
5358 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5359 gfilter
->dlist
[direct
].name
);
5360 filter
->dlist
[direct
].alist
=
5361 gfilter
->dlist
[direct
].alist
;
5362 peer_on_policy_change(peer
, afi
, safi
,
5363 (direct
== FILTER_OUT
) ? 1 : 0);
5368 if (filter
->dlist
[direct
].name
)
5369 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5370 filter
->dlist
[direct
].name
= NULL
;
5371 filter
->dlist
[direct
].alist
= NULL
;
5373 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5374 peer_on_policy_change(peer
, afi
, safi
,
5375 (direct
== FILTER_OUT
) ? 1 : 0);
5379 group
= peer
->group
;
5380 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5381 filter
= &peer
->filter
[afi
][safi
];
5383 if (filter
->dlist
[direct
].name
)
5384 XFREE(MTYPE_BGP_FILTER_NAME
,
5385 filter
->dlist
[direct
].name
);
5386 filter
->dlist
[direct
].name
= NULL
;
5387 filter
->dlist
[direct
].alist
= NULL
;
5388 peer_on_policy_change(peer
, afi
, safi
,
5389 (direct
== FILTER_OUT
) ? 1 : 0);
5395 /* Update distribute list. */
5396 static void peer_distribute_update(struct access_list
*access
)
5401 struct listnode
*mnode
, *mnnode
;
5402 struct listnode
*node
, *nnode
;
5405 struct peer_group
*group
;
5406 struct bgp_filter
*filter
;
5408 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5410 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5411 access
->name
, 0, 0);
5412 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5413 FOREACH_AFI_SAFI (afi
, safi
) {
5414 filter
= &peer
->filter
[afi
][safi
];
5416 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5418 if (filter
->dlist
[direct
].name
)
5419 filter
->dlist
[direct
]
5420 .alist
= access_list_lookup(
5422 filter
->dlist
[direct
]
5425 filter
->dlist
[direct
].alist
=
5430 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5431 FOREACH_AFI_SAFI (afi
, safi
) {
5432 filter
= &group
->conf
->filter
[afi
][safi
];
5434 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5436 if (filter
->dlist
[direct
].name
)
5437 filter
->dlist
[direct
]
5438 .alist
= access_list_lookup(
5440 filter
->dlist
[direct
]
5443 filter
->dlist
[direct
].alist
=
5449 vnc_prefix_list_update(bgp
);
5454 /* Set prefix list to the peer. */
5455 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5458 struct bgp_filter
*filter
;
5459 struct peer_group
*group
;
5460 struct listnode
*node
, *nnode
;
5462 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5463 return BGP_ERR_INVALID_VALUE
;
5465 filter
= &peer
->filter
[afi
][safi
];
5467 if (filter
->dlist
[direct
].name
)
5468 return BGP_ERR_PEER_FILTER_CONFLICT
;
5470 if (filter
->plist
[direct
].name
)
5471 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5472 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5473 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5475 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5476 peer_on_policy_change(peer
, afi
, safi
,
5477 (direct
== FILTER_OUT
) ? 1 : 0);
5481 group
= peer
->group
;
5482 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5483 filter
= &peer
->filter
[afi
][safi
];
5485 if (filter
->plist
[direct
].name
)
5486 XFREE(MTYPE_BGP_FILTER_NAME
,
5487 filter
->plist
[direct
].name
);
5488 filter
->plist
[direct
].name
=
5489 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5490 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5491 peer_on_policy_change(peer
, afi
, safi
,
5492 (direct
== FILTER_OUT
) ? 1 : 0);
5497 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5500 struct bgp_filter
*filter
;
5501 struct bgp_filter
*gfilter
;
5502 struct peer_group
*group
;
5503 struct listnode
*node
, *nnode
;
5505 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5506 return BGP_ERR_INVALID_VALUE
;
5508 filter
= &peer
->filter
[afi
][safi
];
5510 /* apply peer-group filter */
5511 if (peer_group_active(peer
)) {
5512 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5514 if (gfilter
->plist
[direct
].name
) {
5515 if (filter
->plist
[direct
].name
)
5516 XFREE(MTYPE_BGP_FILTER_NAME
,
5517 filter
->plist
[direct
].name
);
5518 filter
->plist
[direct
].name
=
5519 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5520 gfilter
->plist
[direct
].name
);
5521 filter
->plist
[direct
].plist
=
5522 gfilter
->plist
[direct
].plist
;
5523 peer_on_policy_change(peer
, afi
, safi
,
5524 (direct
== FILTER_OUT
) ? 1 : 0);
5529 if (filter
->plist
[direct
].name
)
5530 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5531 filter
->plist
[direct
].name
= NULL
;
5532 filter
->plist
[direct
].plist
= NULL
;
5534 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5535 peer_on_policy_change(peer
, afi
, safi
,
5536 (direct
== FILTER_OUT
) ? 1 : 0);
5540 group
= peer
->group
;
5541 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5542 filter
= &peer
->filter
[afi
][safi
];
5544 if (filter
->plist
[direct
].name
)
5545 XFREE(MTYPE_BGP_FILTER_NAME
,
5546 filter
->plist
[direct
].name
);
5547 filter
->plist
[direct
].name
= NULL
;
5548 filter
->plist
[direct
].plist
= NULL
;
5549 peer_on_policy_change(peer
, afi
, safi
,
5550 (direct
== FILTER_OUT
) ? 1 : 0);
5556 /* Update prefix-list list. */
5557 static void peer_prefix_list_update(struct prefix_list
*plist
)
5559 struct listnode
*mnode
, *mnnode
;
5560 struct listnode
*node
, *nnode
;
5563 struct peer_group
*group
;
5564 struct bgp_filter
*filter
;
5569 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5572 * Update the prefix-list on update groups.
5574 update_group_policy_update(
5575 bgp
, BGP_POLICY_PREFIX_LIST
,
5576 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5578 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5579 FOREACH_AFI_SAFI (afi
, safi
) {
5580 filter
= &peer
->filter
[afi
][safi
];
5582 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5584 if (filter
->plist
[direct
].name
)
5585 filter
->plist
[direct
]
5586 .plist
= prefix_list_lookup(
5588 filter
->plist
[direct
]
5591 filter
->plist
[direct
].plist
=
5596 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5597 FOREACH_AFI_SAFI (afi
, safi
) {
5598 filter
= &group
->conf
->filter
[afi
][safi
];
5600 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5602 if (filter
->plist
[direct
].name
)
5603 filter
->plist
[direct
]
5604 .plist
= prefix_list_lookup(
5606 filter
->plist
[direct
]
5609 filter
->plist
[direct
].plist
=
5617 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5620 struct bgp_filter
*filter
;
5621 struct peer_group
*group
;
5622 struct listnode
*node
, *nnode
;
5624 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5625 return BGP_ERR_INVALID_VALUE
;
5627 filter
= &peer
->filter
[afi
][safi
];
5629 if (filter
->aslist
[direct
].name
)
5630 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5631 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5632 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5634 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5635 peer_on_policy_change(peer
, afi
, safi
,
5636 (direct
== FILTER_OUT
) ? 1 : 0);
5640 group
= peer
->group
;
5641 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5642 filter
= &peer
->filter
[afi
][safi
];
5644 if (filter
->aslist
[direct
].name
)
5645 XFREE(MTYPE_BGP_FILTER_NAME
,
5646 filter
->aslist
[direct
].name
);
5647 filter
->aslist
[direct
].name
=
5648 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5649 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5650 peer_on_policy_change(peer
, afi
, safi
,
5651 (direct
== FILTER_OUT
) ? 1 : 0);
5656 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5658 struct bgp_filter
*filter
;
5659 struct bgp_filter
*gfilter
;
5660 struct peer_group
*group
;
5661 struct listnode
*node
, *nnode
;
5663 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5664 return BGP_ERR_INVALID_VALUE
;
5666 filter
= &peer
->filter
[afi
][safi
];
5668 /* apply peer-group filter */
5669 if (peer_group_active(peer
)) {
5670 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5672 if (gfilter
->aslist
[direct
].name
) {
5673 if (filter
->aslist
[direct
].name
)
5674 XFREE(MTYPE_BGP_FILTER_NAME
,
5675 filter
->aslist
[direct
].name
);
5676 filter
->aslist
[direct
].name
=
5677 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5678 gfilter
->aslist
[direct
].name
);
5679 filter
->aslist
[direct
].aslist
=
5680 gfilter
->aslist
[direct
].aslist
;
5681 peer_on_policy_change(peer
, afi
, safi
,
5682 (direct
== FILTER_OUT
) ? 1 : 0);
5687 if (filter
->aslist
[direct
].name
)
5688 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5689 filter
->aslist
[direct
].name
= NULL
;
5690 filter
->aslist
[direct
].aslist
= NULL
;
5692 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5693 peer_on_policy_change(peer
, afi
, safi
,
5694 (direct
== FILTER_OUT
) ? 1 : 0);
5698 group
= peer
->group
;
5699 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5700 filter
= &peer
->filter
[afi
][safi
];
5702 if (filter
->aslist
[direct
].name
)
5703 XFREE(MTYPE_BGP_FILTER_NAME
,
5704 filter
->aslist
[direct
].name
);
5705 filter
->aslist
[direct
].name
= NULL
;
5706 filter
->aslist
[direct
].aslist
= NULL
;
5707 peer_on_policy_change(peer
, afi
, safi
,
5708 (direct
== FILTER_OUT
) ? 1 : 0);
5714 static void peer_aslist_update(const char *aslist_name
)
5719 struct listnode
*mnode
, *mnnode
;
5720 struct listnode
*node
, *nnode
;
5723 struct peer_group
*group
;
5724 struct bgp_filter
*filter
;
5726 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5727 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5730 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5731 FOREACH_AFI_SAFI (afi
, safi
) {
5732 filter
= &peer
->filter
[afi
][safi
];
5734 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5736 if (filter
->aslist
[direct
].name
)
5737 filter
->aslist
[direct
]
5738 .aslist
= as_list_lookup(
5739 filter
->aslist
[direct
]
5742 filter
->aslist
[direct
].aslist
=
5747 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5748 FOREACH_AFI_SAFI (afi
, safi
) {
5749 filter
= &group
->conf
->filter
[afi
][safi
];
5751 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5753 if (filter
->aslist
[direct
].name
)
5754 filter
->aslist
[direct
]
5755 .aslist
= as_list_lookup(
5756 filter
->aslist
[direct
]
5759 filter
->aslist
[direct
].aslist
=
5767 static void peer_aslist_add(char *aslist_name
)
5769 peer_aslist_update(aslist_name
);
5770 route_map_notify_dependencies((char *)aslist_name
,
5771 RMAP_EVENT_ASLIST_ADDED
);
5774 static void peer_aslist_del(const char *aslist_name
)
5776 peer_aslist_update(aslist_name
);
5777 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5781 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5784 struct bgp_filter
*filter
;
5785 struct peer_group
*group
;
5786 struct listnode
*node
, *nnode
;
5788 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5789 return BGP_ERR_INVALID_VALUE
;
5791 filter
= &peer
->filter
[afi
][safi
];
5793 if (filter
->map
[direct
].name
)
5794 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5796 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5797 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5799 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5800 peer_on_policy_change(peer
, afi
, safi
,
5801 (direct
== RMAP_OUT
) ? 1 : 0);
5805 group
= peer
->group
;
5806 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5807 filter
= &peer
->filter
[afi
][safi
];
5809 if (filter
->map
[direct
].name
)
5810 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5811 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5812 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5813 peer_on_policy_change(peer
, afi
, safi
,
5814 (direct
== RMAP_OUT
) ? 1 : 0);
5819 /* Unset route-map from the peer. */
5820 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5822 struct bgp_filter
*filter
;
5823 struct bgp_filter
*gfilter
;
5824 struct peer_group
*group
;
5825 struct listnode
*node
, *nnode
;
5827 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5828 return BGP_ERR_INVALID_VALUE
;
5830 filter
= &peer
->filter
[afi
][safi
];
5832 /* apply peer-group filter */
5833 if (peer_group_active(peer
)) {
5834 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5836 if (gfilter
->map
[direct
].name
) {
5837 if (filter
->map
[direct
].name
)
5838 XFREE(MTYPE_BGP_FILTER_NAME
,
5839 filter
->map
[direct
].name
);
5840 filter
->map
[direct
].name
=
5841 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5842 gfilter
->map
[direct
].name
);
5843 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5844 peer_on_policy_change(peer
, afi
, safi
,
5845 (direct
== RMAP_OUT
) ? 1 : 0);
5850 if (filter
->map
[direct
].name
)
5851 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5852 filter
->map
[direct
].name
= NULL
;
5853 filter
->map
[direct
].map
= NULL
;
5855 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5856 peer_on_policy_change(peer
, afi
, safi
,
5857 (direct
== RMAP_OUT
) ? 1 : 0);
5861 group
= peer
->group
;
5862 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5863 filter
= &peer
->filter
[afi
][safi
];
5865 if (filter
->map
[direct
].name
)
5866 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5867 filter
->map
[direct
].name
= NULL
;
5868 filter
->map
[direct
].map
= NULL
;
5869 peer_on_policy_change(peer
, afi
, safi
,
5870 (direct
== RMAP_OUT
) ? 1 : 0);
5875 /* Set unsuppress-map to the peer. */
5876 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5879 struct bgp_filter
*filter
;
5880 struct peer_group
*group
;
5881 struct listnode
*node
, *nnode
;
5883 filter
= &peer
->filter
[afi
][safi
];
5885 if (filter
->usmap
.name
)
5886 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5888 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5889 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5891 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5892 peer_on_policy_change(peer
, afi
, safi
, 1);
5896 group
= peer
->group
;
5897 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5898 filter
= &peer
->filter
[afi
][safi
];
5900 if (filter
->usmap
.name
)
5901 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5902 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5903 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5904 peer_on_policy_change(peer
, afi
, safi
, 1);
5909 /* Unset route-map from the peer. */
5910 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5912 struct bgp_filter
*filter
;
5913 struct peer_group
*group
;
5914 struct listnode
*node
, *nnode
;
5916 filter
= &peer
->filter
[afi
][safi
];
5918 if (filter
->usmap
.name
)
5919 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5920 filter
->usmap
.name
= NULL
;
5921 filter
->usmap
.map
= NULL
;
5923 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5924 peer_on_policy_change(peer
, afi
, safi
, 1);
5928 group
= peer
->group
;
5929 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5930 filter
= &peer
->filter
[afi
][safi
];
5932 if (filter
->usmap
.name
)
5933 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5934 filter
->usmap
.name
= NULL
;
5935 filter
->usmap
.map
= NULL
;
5936 peer_on_policy_change(peer
, afi
, safi
, 1);
5941 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5942 uint32_t max
, uint8_t threshold
, int warning
,
5945 struct peer_group
*group
;
5946 struct listnode
*node
, *nnode
;
5948 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5949 peer
->pmax
[afi
][safi
] = max
;
5950 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5951 peer
->pmax_restart
[afi
][safi
] = restart
;
5953 SET_FLAG(peer
->af_flags
[afi
][safi
],
5954 PEER_FLAG_MAX_PREFIX_WARNING
);
5956 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5957 PEER_FLAG_MAX_PREFIX_WARNING
);
5959 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5960 group
= peer
->group
;
5961 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5962 SET_FLAG(peer
->af_flags
[afi
][safi
],
5963 PEER_FLAG_MAX_PREFIX
);
5964 peer
->pmax
[afi
][safi
] = max
;
5965 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5966 peer
->pmax_restart
[afi
][safi
] = restart
;
5968 SET_FLAG(peer
->af_flags
[afi
][safi
],
5969 PEER_FLAG_MAX_PREFIX_WARNING
);
5971 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5972 PEER_FLAG_MAX_PREFIX_WARNING
);
5974 if ((peer
->status
== Established
)
5975 && (peer
->afc
[afi
][safi
]))
5976 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5979 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5980 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5986 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5988 struct peer_group
*group
;
5989 struct listnode
*node
, *nnode
;
5991 /* apply peer-group config */
5992 if (peer_group_active(peer
)) {
5993 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5994 PEER_FLAG_MAX_PREFIX
))
5995 SET_FLAG(peer
->af_flags
[afi
][safi
],
5996 PEER_FLAG_MAX_PREFIX
);
5998 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5999 PEER_FLAG_MAX_PREFIX
);
6001 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
6002 PEER_FLAG_MAX_PREFIX_WARNING
))
6003 SET_FLAG(peer
->af_flags
[afi
][safi
],
6004 PEER_FLAG_MAX_PREFIX_WARNING
);
6006 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6007 PEER_FLAG_MAX_PREFIX_WARNING
);
6009 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
6010 peer
->pmax_threshold
[afi
][safi
] =
6011 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
6012 peer
->pmax_restart
[afi
][safi
] =
6013 peer
->group
->conf
->pmax_restart
[afi
][safi
];
6017 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6018 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
6019 peer
->pmax
[afi
][safi
] = 0;
6020 peer
->pmax_threshold
[afi
][safi
] = 0;
6021 peer
->pmax_restart
[afi
][safi
] = 0;
6023 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
6026 group
= peer
->group
;
6027 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6028 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6029 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6030 PEER_FLAG_MAX_PREFIX_WARNING
);
6031 peer
->pmax
[afi
][safi
] = 0;
6032 peer
->pmax_threshold
[afi
][safi
] = 0;
6033 peer
->pmax_restart
[afi
][safi
] = 0;
6038 int is_ebgp_multihop_configured(struct peer
*peer
)
6040 struct peer_group
*group
;
6041 struct listnode
*node
, *nnode
;
6044 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6045 group
= peer
->group
;
6046 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6047 && (group
->conf
->ttl
!= 1))
6050 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6051 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6052 && (peer1
->ttl
!= 1))
6056 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6062 /* Set # of hops between us and BGP peer. */
6063 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6065 struct peer_group
*group
;
6066 struct listnode
*node
, *nnode
;
6069 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6070 gtsm_hops
, peer
->host
);
6072 /* We cannot configure ttl-security hops when ebgp-multihop is already
6073 set. For non peer-groups, the check is simple. For peer-groups,
6075 slightly messy, because we need to check both the peer-group
6077 and all peer-group members for any trace of ebgp-multihop
6079 before actually applying the ttl-security rules. Cisco really made a
6080 mess of this configuration parameter, and OpenBGPD got it right.
6083 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6084 if (is_ebgp_multihop_configured(peer
))
6085 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6087 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6088 peer
->gtsm_hops
= gtsm_hops
;
6090 /* Calling ebgp multihop also resets the session.
6091 * On restart, NHT will get setup correctly as will the
6092 * min & max ttls on the socket. The return value is
6095 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6100 group
= peer
->group
;
6101 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6103 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6105 /* Calling ebgp multihop also resets the
6107 * On restart, NHT will get setup correctly as
6109 * min & max ttls on the socket. The return
6113 peer_ebgp_multihop_set(peer
, MAXTTL
);
6117 /* Post the first gtsm setup or if its ibgp, maxttl setting
6119 * necessary, just set the minttl.
6121 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6122 peer
->gtsm_hops
= gtsm_hops
;
6125 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6126 MAXTTL
+ 1 - gtsm_hops
);
6127 if ((peer
->status
< Established
) && peer
->doppelganger
6128 && (peer
->doppelganger
->fd
>= 0))
6129 sockopt_minttl(peer
->su
.sa
.sa_family
,
6130 peer
->doppelganger
->fd
,
6131 MAXTTL
+ 1 - gtsm_hops
);
6133 group
= peer
->group
;
6134 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6136 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6138 /* Change setting of existing peer
6139 * established then change value (may break
6141 * not established yet (teardown session and
6143 * no session then do nothing (will get
6144 * handled by next connection)
6146 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6148 peer
->su
.sa
.sa_family
, peer
->fd
,
6149 MAXTTL
+ 1 - peer
->gtsm_hops
);
6150 if ((peer
->status
< Established
)
6151 && peer
->doppelganger
6152 && (peer
->doppelganger
->fd
>= 0))
6153 sockopt_minttl(peer
->su
.sa
.sa_family
,
6154 peer
->doppelganger
->fd
,
6155 MAXTTL
+ 1 - gtsm_hops
);
6163 int peer_ttl_security_hops_unset(struct peer
*peer
)
6165 struct peer_group
*group
;
6166 struct listnode
*node
, *nnode
;
6169 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6172 /* if a peer-group member, then reset to peer-group default rather than
6174 if (peer_group_active(peer
))
6175 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6177 peer
->gtsm_hops
= 0;
6179 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6180 /* Invoking ebgp_multihop_set will set the TTL back to the
6182 * value as well as restting the NHT and such. The session is
6185 if (peer
->sort
== BGP_PEER_EBGP
)
6186 ret
= peer_ebgp_multihop_unset(peer
);
6189 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6192 if ((peer
->status
< Established
) && peer
->doppelganger
6193 && (peer
->doppelganger
->fd
>= 0))
6194 sockopt_minttl(peer
->su
.sa
.sa_family
,
6195 peer
->doppelganger
->fd
, 0);
6198 group
= peer
->group
;
6199 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6200 peer
->gtsm_hops
= 0;
6201 if (peer
->sort
== BGP_PEER_EBGP
)
6202 ret
= peer_ebgp_multihop_unset(peer
);
6205 sockopt_minttl(peer
->su
.sa
.sa_family
,
6208 if ((peer
->status
< Established
)
6209 && peer
->doppelganger
6210 && (peer
->doppelganger
->fd
>= 0))
6211 sockopt_minttl(peer
->su
.sa
.sa_family
,
6212 peer
->doppelganger
->fd
,
6222 * If peer clear is invoked in a loop for all peers on the BGP instance,
6223 * it may end up freeing the doppelganger, and if this was the next node
6224 * to the current node, we would end up accessing the freed next node.
6225 * Pass along additional parameter which can be updated if next node
6226 * is freed; only required when walking the peer list on BGP instance.
6228 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6230 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6231 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6232 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6233 if (peer
->t_pmax_restart
) {
6234 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6235 if (bgp_debug_neighbor_events(peer
))
6237 "%s Maximum-prefix restart timer canceled",
6240 BGP_EVENT_ADD(peer
, BGP_Start
);
6244 peer
->v_start
= BGP_INIT_START_TIMER
;
6245 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6246 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6247 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6249 bgp_session_reset_safe(peer
, nnode
);
6254 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6255 enum bgp_clear_type stype
)
6257 struct peer_af
*paf
;
6259 if (peer
->status
!= Established
)
6262 if (!peer
->afc
[afi
][safi
])
6263 return BGP_ERR_AF_UNCONFIGURED
;
6265 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6267 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6268 /* Clear the "neighbor x.x.x.x default-originate" flag */
6269 paf
= peer_af_find(peer
, afi
, safi
);
6270 if (paf
&& paf
->subgroup
6271 && CHECK_FLAG(paf
->subgroup
->sflags
,
6272 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6273 UNSET_FLAG(paf
->subgroup
->sflags
,
6274 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6276 bgp_announce_route(peer
, afi
, safi
);
6279 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6280 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6281 PEER_CAP_ORF_PREFIX_SM_ADV
)
6282 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6283 PEER_CAP_ORF_PREFIX_RM_RCV
)
6284 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6285 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6286 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6287 uint8_t prefix_type
;
6289 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6290 PEER_CAP_ORF_PREFIX_RM_RCV
))
6291 prefix_type
= ORF_TYPE_PREFIX
;
6293 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6295 if (filter
->plist
[FILTER_IN
].plist
) {
6296 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6297 PEER_STATUS_ORF_PREFIX_SEND
))
6298 bgp_route_refresh_send(
6299 peer
, afi
, safi
, prefix_type
,
6301 bgp_route_refresh_send(peer
, afi
, safi
,
6303 REFRESH_IMMEDIATE
, 0);
6305 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6306 PEER_STATUS_ORF_PREFIX_SEND
))
6307 bgp_route_refresh_send(
6308 peer
, afi
, safi
, prefix_type
,
6309 REFRESH_IMMEDIATE
, 1);
6311 bgp_route_refresh_send(peer
, afi
, safi
,
6318 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6319 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6320 /* If neighbor has soft reconfiguration inbound flag.
6321 Use Adj-RIB-In database. */
6322 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6323 PEER_FLAG_SOFT_RECONFIG
))
6324 bgp_soft_reconfig_in(peer
, afi
, safi
);
6326 /* If neighbor has route refresh capability, send route
6328 message to the peer. */
6329 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6330 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6331 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6334 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6340 /* Display peer uptime.*/
6341 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, uint8_t use_json
,
6344 time_t uptime1
, epoch_tbuf
;
6347 /* Check buffer length. */
6348 if (len
< BGP_UPTIME_LEN
) {
6350 zlog_warn("peer_uptime (): buffer shortage %lu",
6351 (unsigned long)len
);
6352 /* XXX: should return status instead of buf... */
6353 snprintf(buf
, len
, "<error> ");
6358 /* If there is no connection has been done before print `never'. */
6361 json_object_string_add(json
, "peerUptime", "never");
6362 json_object_int_add(json
, "peerUptimeMsec", 0);
6364 snprintf(buf
, len
, "never");
6368 /* Get current time. */
6369 uptime1
= bgp_clock();
6371 tm
= gmtime(&uptime1
);
6373 if (uptime1
< ONE_DAY_SECOND
)
6374 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6376 else if (uptime1
< ONE_WEEK_SECOND
)
6377 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6379 else if (uptime1
< ONE_YEAR_SECOND
)
6380 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6381 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6383 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6385 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6388 epoch_tbuf
= time(NULL
) - uptime1
;
6389 json_object_string_add(json
, "peerUptime", buf
);
6390 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6391 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6398 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6399 afi_t afi
, safi_t safi
)
6401 struct bgp_filter
*filter
;
6402 struct bgp_filter
*gfilter
= NULL
;
6405 int out
= FILTER_OUT
;
6408 filter
= &peer
->filter
[afi
][safi
];
6410 if (peer_group_active(peer
))
6411 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6413 /* distribute-list. */
6414 if (filter
->dlist
[in
].name
)
6415 if (!gfilter
|| !gfilter
->dlist
[in
].name
6416 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6418 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6419 addr
, filter
->dlist
[in
].name
);
6422 if (filter
->dlist
[out
].name
&& !gfilter
) {
6423 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6424 filter
->dlist
[out
].name
);
6428 if (filter
->plist
[in
].name
)
6429 if (!gfilter
|| !gfilter
->plist
[in
].name
6430 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6432 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6433 filter
->plist
[in
].name
);
6436 if (filter
->plist
[out
].name
)
6437 if (!gfilter
|| !gfilter
->plist
[out
].name
6438 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6440 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6441 filter
->plist
[out
].name
);
6445 if (filter
->map
[RMAP_IN
].name
)
6446 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6447 || strcmp(filter
->map
[RMAP_IN
].name
,
6448 gfilter
->map
[RMAP_IN
].name
)
6450 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6451 filter
->map
[RMAP_IN
].name
);
6454 if (filter
->map
[RMAP_OUT
].name
)
6455 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6456 || strcmp(filter
->map
[RMAP_OUT
].name
,
6457 gfilter
->map
[RMAP_OUT
].name
)
6459 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6460 filter
->map
[RMAP_OUT
].name
);
6463 /* unsuppress-map */
6464 if (filter
->usmap
.name
&& !gfilter
) {
6465 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6466 filter
->usmap
.name
);
6470 if (filter
->aslist
[in
].name
)
6471 if (!gfilter
|| !gfilter
->aslist
[in
].name
6472 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6474 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6475 filter
->aslist
[in
].name
);
6478 if (filter
->aslist
[out
].name
&& !gfilter
) {
6479 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6480 filter
->aslist
[out
].name
);
6484 /* BGP peer configuration display function. */
6485 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6488 struct peer
*g_peer
= NULL
;
6489 char buf
[SU_ADDRSTRLEN
];
6491 int if_pg_printed
= FALSE
;
6492 int if_ras_printed
= FALSE
;
6494 /* Skip dynamic neighbors. */
6495 if (peer_dynamic_neighbor(peer
))
6499 addr
= peer
->conf_if
;
6503 /************************************
6504 ****** Global to the neighbor ******
6505 ************************************/
6506 if (peer
->conf_if
) {
6507 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6508 vty_out(vty
, " neighbor %s interface v6only", addr
);
6510 vty_out(vty
, " neighbor %s interface", addr
);
6512 if (peer_group_active(peer
)) {
6513 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6514 if_pg_printed
= TRUE
;
6515 } else if (peer
->as_type
== AS_SPECIFIED
) {
6516 vty_out(vty
, " remote-as %u", peer
->as
);
6517 if_ras_printed
= TRUE
;
6518 } else if (peer
->as_type
== AS_INTERNAL
) {
6519 vty_out(vty
, " remote-as internal");
6520 if_ras_printed
= TRUE
;
6521 } else if (peer
->as_type
== AS_EXTERNAL
) {
6522 vty_out(vty
, " remote-as external");
6523 if_ras_printed
= TRUE
;
6529 /* remote-as and peer-group */
6530 /* peer is a member of a peer-group */
6531 if (peer_group_active(peer
)) {
6532 g_peer
= peer
->group
->conf
;
6534 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6535 if (peer
->as_type
== AS_SPECIFIED
) {
6536 vty_out(vty
, " neighbor %s remote-as %u\n",
6538 } else if (peer
->as_type
== AS_INTERNAL
) {
6540 " neighbor %s remote-as internal\n",
6542 } else if (peer
->as_type
== AS_EXTERNAL
) {
6544 " neighbor %s remote-as external\n",
6549 /* For swpX peers we displayed the peer-group
6550 * via 'neighbor swpX interface peer-group WORD' */
6552 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6556 /* peer is NOT a member of a peer-group */
6558 /* peer is a peer-group, declare the peer-group */
6559 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6560 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6563 if (!if_ras_printed
) {
6564 if (peer
->as_type
== AS_SPECIFIED
) {
6565 vty_out(vty
, " neighbor %s remote-as %u\n",
6567 } else if (peer
->as_type
== AS_INTERNAL
) {
6569 " neighbor %s remote-as internal\n",
6571 } else if (peer
->as_type
== AS_EXTERNAL
) {
6573 " neighbor %s remote-as external\n",
6580 if (peer
->change_local_as
) {
6581 if (!peer_group_active(peer
)
6582 || peer
->change_local_as
!= g_peer
->change_local_as
6583 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6584 != CHECK_FLAG(g_peer
->flags
,
6585 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6586 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6587 != CHECK_FLAG(g_peer
->flags
,
6588 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6589 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6590 peer
->change_local_as
,
6591 CHECK_FLAG(peer
->flags
,
6592 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6595 CHECK_FLAG(peer
->flags
,
6596 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6604 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6608 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6609 if (!peer_group_active(peer
)
6610 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6611 || peer
->tx_shutdown_message
) {
6612 if (peer
->tx_shutdown_message
)
6614 " neighbor %s shutdown message %s\n",
6615 addr
, peer
->tx_shutdown_message
);
6617 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6622 if (peer
->bfd_info
) {
6623 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6624 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6629 if (peer
->password
) {
6630 if (!peer_group_active(peer
) || !g_peer
->password
6631 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6632 vty_out(vty
, " neighbor %s password %s\n", addr
,
6638 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6639 if (!peer_group_active(peer
)) {
6640 vty_out(vty
, " neighbor %s solo\n", addr
);
6645 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6646 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6649 /* Local interface name */
6651 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6655 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6656 if (!peer_group_active(peer
)
6657 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6658 vty_out(vty
, " neighbor %s passive\n", addr
);
6663 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6664 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6665 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6666 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6671 /* ttl-security hops */
6672 if (peer
->gtsm_hops
!= 0) {
6673 if (!peer_group_active(peer
)
6674 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6675 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6676 addr
, peer
->gtsm_hops
);
6680 /* disable-connected-check */
6681 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6682 if (!peer_group_active(peer
)
6683 || !CHECK_FLAG(g_peer
->flags
,
6684 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6685 vty_out(vty
, " neighbor %s disable-connected-check\n",
6691 if (peer
->update_if
) {
6692 if (!peer_group_active(peer
) || !g_peer
->update_if
6693 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6694 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6698 if (peer
->update_source
) {
6699 if (!peer_group_active(peer
) || !g_peer
->update_source
6700 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6702 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6703 sockunion2str(peer
->update_source
, buf
,
6708 /* advertisement-interval */
6709 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6710 && ((!peer_group_active(peer
)
6711 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6712 || (peer_group_active(peer
)
6713 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6714 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6719 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6720 && ((!peer_group_active(peer
)
6721 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6722 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6723 || (peer_group_active(peer
)
6724 && (peer
->keepalive
!= g_peer
->keepalive
6725 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6726 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6727 peer
->keepalive
, peer
->holdtime
);
6730 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6731 && ((!peer_group_active(peer
)
6732 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6733 || (peer_group_active(peer
)
6734 && peer
->connect
!= g_peer
->connect
)))
6737 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6741 /* capability dynamic */
6742 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6743 if (!peer_group_active(peer
)
6744 || !CHECK_FLAG(g_peer
->flags
,
6745 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6746 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6750 /* capability extended-nexthop */
6751 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6752 if (!peer_group_active(peer
)
6753 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6755 " no neighbor %s capability extended-nexthop\n",
6760 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6761 if (!peer_group_active(peer
)
6762 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6764 " neighbor %s capability extended-nexthop\n",
6769 /* dont-capability-negotiation */
6770 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6771 if (!peer_group_active(peer
)
6772 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6773 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6778 /* override-capability */
6779 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6780 if (!peer_group_active(peer
)
6781 || !CHECK_FLAG(g_peer
->flags
,
6782 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6783 vty_out(vty
, " neighbor %s override-capability\n",
6788 /* strict-capability-match */
6789 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6790 if (!peer_group_active(peer
)
6791 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6792 vty_out(vty
, " neighbor %s strict-capability-match\n",
6798 /* BGP peer configuration display function. */
6799 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6800 struct peer
*peer
, afi_t afi
, safi_t safi
)
6802 struct peer
*g_peer
= NULL
;
6805 /* Skip dynamic neighbors. */
6806 if (peer_dynamic_neighbor(peer
))
6810 addr
= peer
->conf_if
;
6814 /************************************
6815 ****** Per AF to the neighbor ******
6816 ************************************/
6817 if (peer_group_active(peer
)) {
6818 g_peer
= peer
->group
->conf
;
6820 /* If the peer-group is active but peer is not, print a 'no
6822 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6823 vty_out(vty
, " no neighbor %s activate\n", addr
);
6826 /* If the peer-group is not active but peer is, print an
6828 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6829 vty_out(vty
, " neighbor %s activate\n", addr
);
6832 if (peer
->afc
[afi
][safi
]) {
6833 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6834 if (bgp_flag_check(bgp
,
6835 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6836 vty_out(vty
, " neighbor %s activate\n",
6840 vty_out(vty
, " neighbor %s activate\n", addr
);
6842 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6843 if (!bgp_flag_check(bgp
,
6844 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6846 " no neighbor %s activate\n",
6853 /* addpath TX knobs */
6854 if (peergroup_af_flag_check(peer
, afi
, safi
,
6855 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6856 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6859 if (peergroup_af_flag_check(peer
, afi
, safi
,
6860 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6861 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6865 /* ORF capability. */
6866 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6867 || peergroup_af_flag_check(peer
, afi
, safi
,
6868 PEER_FLAG_ORF_PREFIX_RM
)) {
6869 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6871 if (peergroup_af_flag_check(peer
, afi
, safi
,
6872 PEER_FLAG_ORF_PREFIX_SM
)
6873 && peergroup_af_flag_check(peer
, afi
, safi
,
6874 PEER_FLAG_ORF_PREFIX_RM
))
6875 vty_out(vty
, " both");
6876 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6877 PEER_FLAG_ORF_PREFIX_SM
))
6878 vty_out(vty
, " send");
6880 vty_out(vty
, " receive");
6884 /* Route reflector client. */
6885 if (peergroup_af_flag_check(peer
, afi
, safi
,
6886 PEER_FLAG_REFLECTOR_CLIENT
)) {
6887 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6890 /* next-hop-self force */
6891 if (peergroup_af_flag_check(peer
, afi
, safi
,
6892 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6893 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6897 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6898 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6901 /* remove-private-AS */
6902 if (peergroup_af_flag_check(peer
, afi
, safi
,
6903 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6904 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6908 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6909 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6910 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6914 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6915 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6916 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6919 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6920 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6921 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6925 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6926 vty_out(vty
, " neighbor %s as-override\n", addr
);
6929 /* send-community print. */
6930 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6931 if (peergroup_af_flag_check(peer
, afi
, safi
,
6932 PEER_FLAG_SEND_COMMUNITY
)
6933 && peergroup_af_flag_check(peer
, afi
, safi
,
6934 PEER_FLAG_SEND_EXT_COMMUNITY
)
6935 && peergroup_af_flag_check(
6937 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6938 vty_out(vty
, " neighbor %s send-community all\n",
6940 } else if (peergroup_af_flag_check(
6942 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6943 vty_out(vty
, " neighbor %s send-community large\n",
6945 } else if (peergroup_af_flag_check(
6947 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6948 vty_out(vty
, " neighbor %s send-community extended\n",
6950 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6951 PEER_FLAG_SEND_COMMUNITY
)) {
6952 vty_out(vty
, " neighbor %s send-community\n", addr
);
6955 if (!peer_af_flag_check(peer
, afi
, safi
,
6956 PEER_FLAG_SEND_COMMUNITY
)
6957 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6958 PEER_FLAG_SEND_COMMUNITY
))
6959 && !peer_af_flag_check(peer
, afi
, safi
,
6960 PEER_FLAG_SEND_EXT_COMMUNITY
)
6962 || peer_af_flag_check(g_peer
, afi
, safi
,
6963 PEER_FLAG_SEND_EXT_COMMUNITY
))
6964 && !peer_af_flag_check(peer
, afi
, safi
,
6965 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6966 && (!g_peer
|| peer_af_flag_check(
6968 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6969 vty_out(vty
, " no neighbor %s send-community all\n",
6972 if (!peer_af_flag_check(peer
, afi
, safi
,
6973 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6975 || peer_af_flag_check(
6977 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6979 " no neighbor %s send-community large\n",
6983 if (!peer_af_flag_check(peer
, afi
, safi
,
6984 PEER_FLAG_SEND_EXT_COMMUNITY
)
6986 || peer_af_flag_check(
6988 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6990 " no neighbor %s send-community extended\n",
6994 if (!peer_af_flag_check(peer
, afi
, safi
,
6995 PEER_FLAG_SEND_COMMUNITY
)
6996 && (!g_peer
|| peer_af_flag_check(
6998 PEER_FLAG_SEND_COMMUNITY
))) {
7000 " no neighbor %s send-community\n",
7006 /* Default information */
7007 if (peergroup_af_flag_check(peer
, afi
, safi
,
7008 PEER_FLAG_DEFAULT_ORIGINATE
)
7010 && ((peer
->default_rmap
[afi
][safi
].name
7011 && !g_peer
->default_rmap
[afi
][safi
].name
)
7012 || (!peer
->default_rmap
[afi
][safi
].name
7013 && g_peer
->default_rmap
[afi
][safi
].name
)
7014 || (peer
->default_rmap
[afi
][safi
].name
7015 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
7016 g_peer
->default_rmap
[afi
][safi
].name
))))) {
7017 vty_out(vty
, " neighbor %s default-originate", addr
);
7018 if (peer
->default_rmap
[afi
][safi
].name
)
7019 vty_out(vty
, " route-map %s",
7020 peer
->default_rmap
[afi
][safi
].name
);
7024 /* Soft reconfiguration inbound. */
7025 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7026 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7030 /* maximum-prefix. */
7031 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
7032 if (!peer_group_active(peer
)
7033 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
7034 || g_peer
->pmax_threshold
[afi
][safi
]
7035 != peer
->pmax_threshold
[afi
][safi
]
7036 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
7037 PEER_FLAG_MAX_PREFIX_WARNING
)
7038 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7039 PEER_FLAG_MAX_PREFIX_WARNING
)) {
7040 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7041 peer
->pmax
[afi
][safi
]);
7042 if (peer
->pmax_threshold
[afi
][safi
]
7043 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7045 peer
->pmax_threshold
[afi
][safi
]);
7046 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7047 PEER_FLAG_MAX_PREFIX_WARNING
))
7048 vty_out(vty
, " warning-only");
7049 if (peer
->pmax_restart
[afi
][safi
])
7050 vty_out(vty
, " restart %u",
7051 peer
->pmax_restart
[afi
][safi
]);
7055 /* Route server client. */
7056 if (peergroup_af_flag_check(peer
, afi
, safi
,
7057 PEER_FLAG_RSERVER_CLIENT
)) {
7058 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7061 /* Nexthop-local unchanged. */
7062 if (peergroup_af_flag_check(peer
, afi
, safi
,
7063 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7064 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7067 /* allowas-in <1-10> */
7068 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7069 if (!peer_group_active(peer
)
7070 || !peer_af_flag_check(g_peer
, afi
, safi
,
7071 PEER_FLAG_ALLOWAS_IN
)
7072 || peer
->allowas_in
[afi
][safi
]
7073 != g_peer
->allowas_in
[afi
][safi
]) {
7074 if (peer
->allowas_in
[afi
][safi
] == 3) {
7075 vty_out(vty
, " neighbor %s allowas-in\n",
7078 vty_out(vty
, " neighbor %s allowas-in %d\n",
7079 addr
, peer
->allowas_in
[afi
][safi
]);
7084 /* allowas-in origin */
7085 else if (peer_af_flag_check(peer
, afi
, safi
,
7086 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7087 if (!peer_group_active(peer
)
7088 || !peer_af_flag_check(g_peer
, afi
, safi
,
7089 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7090 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7095 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7096 if (!peer_group_active(peer
)
7097 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
7098 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
7099 if (peer
->weight
[afi
][safi
]) {
7100 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7101 peer
->weight
[afi
][safi
]);
7106 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7108 /* atribute-unchanged. */
7109 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7110 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
)
7111 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7113 if (!peer_group_active(peer
)
7114 || peergroup_af_flag_check(peer
, afi
, safi
,
7115 PEER_FLAG_AS_PATH_UNCHANGED
)
7116 || peergroup_af_flag_check(peer
, afi
, safi
,
7117 PEER_FLAG_NEXTHOP_UNCHANGED
)
7118 || peergroup_af_flag_check(peer
, afi
, safi
,
7119 PEER_FLAG_MED_UNCHANGED
)) {
7122 " neighbor %s attribute-unchanged%s%s%s\n",
7124 peer_af_flag_check(peer
, afi
, safi
,
7125 PEER_FLAG_AS_PATH_UNCHANGED
)
7128 peer_af_flag_check(peer
, afi
, safi
,
7129 PEER_FLAG_NEXTHOP_UNCHANGED
)
7132 peer_af_flag_check(peer
, afi
, safi
,
7133 PEER_FLAG_MED_UNCHANGED
)
7140 /* Address family based peer configuration display. */
7141 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7145 struct peer_group
*group
;
7146 struct listnode
*node
, *nnode
;
7149 vty_frame(vty
, " !\n address-family ");
7150 if (afi
== AFI_IP
) {
7151 if (safi
== SAFI_UNICAST
)
7152 vty_frame(vty
, "ipv4 unicast");
7153 else if (safi
== SAFI_LABELED_UNICAST
)
7154 vty_frame(vty
, "ipv4 labeled-unicast");
7155 else if (safi
== SAFI_MULTICAST
)
7156 vty_frame(vty
, "ipv4 multicast");
7157 else if (safi
== SAFI_MPLS_VPN
)
7158 vty_frame(vty
, "ipv4 vpn");
7159 else if (safi
== SAFI_ENCAP
)
7160 vty_frame(vty
, "ipv4 encap");
7161 else if (safi
== SAFI_FLOWSPEC
)
7162 vty_frame(vty
, "ipv4 flowspec");
7163 } else if (afi
== AFI_IP6
) {
7164 if (safi
== SAFI_UNICAST
)
7165 vty_frame(vty
, "ipv6 unicast");
7166 else if (safi
== SAFI_LABELED_UNICAST
)
7167 vty_frame(vty
, "ipv6 labeled-unicast");
7168 else if (safi
== SAFI_MULTICAST
)
7169 vty_frame(vty
, "ipv6 multicast");
7170 else if (safi
== SAFI_MPLS_VPN
)
7171 vty_frame(vty
, "ipv6 vpn");
7172 else if (safi
== SAFI_ENCAP
)
7173 vty_frame(vty
, "ipv6 encap");
7174 else if (safi
== SAFI_FLOWSPEC
)
7175 vty_frame(vty
, "ipv6 flowspec");
7176 } else if (afi
== AFI_L2VPN
) {
7177 if (safi
== SAFI_EVPN
)
7178 vty_frame(vty
, "l2vpn evpn");
7180 vty_frame(vty
, "\n");
7182 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7184 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7186 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7188 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7189 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7191 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7192 /* Skip dynamic neighbors. */
7193 if (peer_dynamic_neighbor(peer
))
7196 /* Do not display doppelganger peers */
7197 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7198 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7201 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7202 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7204 if (safi
== SAFI_EVPN
)
7205 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7207 if (safi
== SAFI_UNICAST
) {
7208 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7209 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7210 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7212 vty_out(vty
, " export vpn\n");
7214 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7215 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7217 vty_out(vty
, " import vpn\n");
7219 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7220 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7221 struct listnode
*node
;
7224 for (ALL_LIST_ELEMENTS_RO(
7225 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7227 vty_out(vty
, " import vrf %s\n", name
);
7231 vty_endframe(vty
, " exit-address-family\n");
7234 int bgp_config_write(struct vty
*vty
)
7238 struct peer_group
*group
;
7240 struct listnode
*node
, *nnode
;
7241 struct listnode
*mnode
, *mnnode
;
7243 /* BGP Multiple instance. */
7244 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7245 vty_out(vty
, "no bgp multiple-instance\n");
7249 /* BGP Config type. */
7250 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7251 vty_out(vty
, "bgp config-type cisco\n");
7255 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7256 vty_out(vty
, "bgp route-map delay-timer %u\n",
7257 bm
->rmap_update_timer
);
7260 vty_out(vty
, "!\n");
7262 /* BGP configuration. */
7263 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7265 /* skip all auto created vrf as they dont have user config */
7266 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7269 /* Router bgp ASN */
7270 vty_out(vty
, "router bgp %u", bgp
->as
);
7272 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7274 vty_out(vty
, " %s %s",
7276 == BGP_INSTANCE_TYPE_VIEW
)
7283 /* No Synchronization */
7284 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7285 vty_out(vty
, " no synchronization\n");
7287 /* BGP fast-external-failover. */
7288 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7289 vty_out(vty
, " no bgp fast-external-failover\n");
7291 /* BGP router ID. */
7292 if (bgp
->router_id_static
.s_addr
!= 0)
7293 vty_out(vty
, " bgp router-id %s\n",
7294 inet_ntoa(bgp
->router_id_static
));
7296 /* BGP log-neighbor-changes. */
7297 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7298 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7299 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7301 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7305 /* BGP configuration. */
7306 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7307 vty_out(vty
, " bgp always-compare-med\n");
7309 /* BGP default ipv4-unicast. */
7310 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7311 vty_out(vty
, " no bgp default ipv4-unicast\n");
7313 /* BGP default local-preference. */
7314 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7315 vty_out(vty
, " bgp default local-preference %u\n",
7316 bgp
->default_local_pref
);
7318 /* BGP default show-hostname */
7319 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7320 != DFLT_BGP_SHOW_HOSTNAME
)
7321 vty_out(vty
, " %sbgp default show-hostname\n",
7322 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7326 /* BGP default subgroup-pkt-queue-max. */
7327 if (bgp
->default_subgroup_pkt_queue_max
7328 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7329 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7330 bgp
->default_subgroup_pkt_queue_max
);
7332 /* BGP default autoshutdown neighbors */
7333 if (bgp
->autoshutdown
)
7334 vty_out(vty
, " bgp default shutdown\n");
7336 /* BGP client-to-client reflection. */
7337 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7338 vty_out(vty
, " no bgp client-to-client reflection\n");
7340 /* BGP cluster ID. */
7341 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7342 vty_out(vty
, " bgp cluster-id %s\n",
7343 inet_ntoa(bgp
->cluster_id
));
7345 /* Disable ebgp connected nexthop check */
7346 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7348 " bgp disable-ebgp-connected-route-check\n");
7350 /* Confederation identifier*/
7351 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7352 vty_out(vty
, " bgp confederation identifier %i\n",
7355 /* Confederation peer */
7356 if (bgp
->confed_peers_cnt
> 0) {
7359 vty_out(vty
, " bgp confederation peers");
7361 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7362 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7367 /* BGP enforce-first-as. */
7368 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7369 vty_out(vty
, " bgp enforce-first-as\n");
7371 /* BGP deterministic-med. */
7372 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7373 != DFLT_BGP_DETERMINISTIC_MED
)
7374 vty_out(vty
, " %sbgp deterministic-med\n",
7375 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7379 /* BGP update-delay. */
7380 bgp_config_write_update_delay(vty
, bgp
);
7382 if (bgp
->v_maxmed_onstartup
7383 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7384 vty_out(vty
, " bgp max-med on-startup %u",
7385 bgp
->v_maxmed_onstartup
);
7386 if (bgp
->maxmed_onstartup_value
7387 != BGP_MAXMED_VALUE_DEFAULT
)
7389 bgp
->maxmed_onstartup_value
);
7392 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7393 vty_out(vty
, " bgp max-med administrative");
7394 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7395 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7400 bgp_config_write_wpkt_quanta(vty
, bgp
);
7402 bgp_config_write_rpkt_quanta(vty
, bgp
);
7405 bgp_config_write_coalesce_time(vty
, bgp
);
7407 /* BGP graceful-restart. */
7408 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7410 " bgp graceful-restart stalepath-time %u\n",
7411 bgp
->stalepath_time
);
7412 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7413 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7415 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7416 vty_out(vty
, " bgp graceful-restart\n");
7418 /* BGP graceful-shutdown */
7419 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7420 vty_out(vty
, " bgp graceful-shutdown\n");
7422 /* BGP graceful-restart Preserve State F bit. */
7423 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7425 " bgp graceful-restart preserve-fw-state\n");
7427 /* BGP bestpath method. */
7428 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7429 vty_out(vty
, " bgp bestpath as-path ignore\n");
7430 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7431 vty_out(vty
, " bgp bestpath as-path confed\n");
7433 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7434 if (bgp_flag_check(bgp
,
7435 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7437 " bgp bestpath as-path multipath-relax as-set\n");
7440 " bgp bestpath as-path multipath-relax\n");
7444 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7446 " bgp route-reflector allow-outbound-policy\n");
7448 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7449 vty_out(vty
, " bgp bestpath compare-routerid\n");
7450 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7451 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7452 vty_out(vty
, " bgp bestpath med");
7453 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7454 vty_out(vty
, " confed");
7455 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7456 vty_out(vty
, " missing-as-worst");
7460 /* BGP network import check. */
7461 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7462 != DFLT_BGP_IMPORT_CHECK
)
7463 vty_out(vty
, " %sbgp network import-check\n",
7464 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7468 /* BGP flag dampening. */
7469 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7470 BGP_CONFIG_DAMPENING
))
7471 bgp_config_write_damp(vty
);
7473 /* BGP timers configuration. */
7474 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7475 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7476 vty_out(vty
, " timers bgp %u %u\n",
7477 bgp
->default_keepalive
, bgp
->default_holdtime
);
7480 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7481 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7484 /* Normal neighbor configuration. */
7485 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7486 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7487 bgp_config_write_peer_global(vty
, bgp
, peer
);
7490 /* listen range and limit for dynamic BGP neighbors */
7491 bgp_config_write_listen(vty
, bgp
);
7493 /* No auto-summary */
7494 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7495 vty_out(vty
, " no auto-summary\n");
7497 /* IPv4 unicast configuration. */
7498 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7500 /* IPv4 multicast configuration. */
7501 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7503 /* IPv4 labeled-unicast configuration. */
7504 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7506 /* IPv4 VPN configuration. */
7507 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7509 /* ENCAPv4 configuration. */
7510 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7512 /* FLOWSPEC v4 configuration. */
7513 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7515 /* IPv6 unicast configuration. */
7516 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7518 /* IPv6 multicast configuration. */
7519 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7521 /* IPv6 labeled-unicast configuration. */
7522 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7523 SAFI_LABELED_UNICAST
);
7525 /* IPv6 VPN configuration. */
7526 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7528 /* ENCAPv6 configuration. */
7529 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7531 /* FLOWSPEC v6 configuration. */
7532 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7534 /* EVPN configuration. */
7535 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7538 bgp_rfapi_cfg_write(vty
, bgp
);
7541 vty_out(vty
, "!\n");
7546 void bgp_master_init(struct thread_master
*master
)
7550 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7553 bm
->bgp
= list_new();
7554 bm
->listen_sockets
= list_new();
7555 bm
->port
= BGP_PORT_DEFAULT
;
7556 bm
->master
= master
;
7557 bm
->start_time
= bgp_clock();
7558 bm
->t_rmap_update
= NULL
;
7559 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7561 bgp_process_queue_init();
7563 /* init the rd id space.
7564 assign 0th index in the bitfield,
7565 so that we start with id 1
7567 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7568 bf_assign_zero_index(bm
->rd_idspace
);
7570 /* Enable multiple instances by default. */
7571 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7573 /* mpls label dynamic allocation pool */
7574 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7576 QOBJ_REG(bm
, bgp_master
);
7580 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7581 * instance delete (non-default only) or BGP exit.
7583 static void bgp_if_finish(struct bgp
*bgp
)
7585 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7586 struct interface
*ifp
;
7588 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7591 FOR_ALL_INTERFACES (vrf
, ifp
) {
7592 struct listnode
*c_node
, *c_nnode
;
7593 struct connected
*c
;
7595 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7596 bgp_connected_delete(bgp
, c
);
7600 extern void bgp_snmp_init(void);
7602 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7604 struct vrf
*vrf
= NULL
;
7605 struct listnode
*next
;
7608 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7609 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7610 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7613 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7614 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7617 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7621 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7622 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7623 {.completions
= NULL
},
7626 static void bgp_pthreads_init()
7630 struct frr_pthread_attr io
= {
7632 .start
= frr_pthread_attr_default
.start
,
7633 .stop
= frr_pthread_attr_default
.stop
,
7635 struct frr_pthread_attr ka
= {
7636 .id
= PTHREAD_KEEPALIVES
,
7637 .start
= bgp_keepalives_start
,
7638 .stop
= bgp_keepalives_stop
,
7640 frr_pthread_new(&io
, "BGP I/O thread");
7641 frr_pthread_new(&ka
, "BGP Keepalives thread");
7644 void bgp_pthreads_run()
7646 struct frr_pthread
*io
= frr_pthread_get(PTHREAD_IO
);
7647 struct frr_pthread
*ka
= frr_pthread_get(PTHREAD_KEEPALIVES
);
7649 frr_pthread_run(io
, NULL
);
7650 frr_pthread_run(ka
, NULL
);
7652 /* Wait until threads are ready. */
7653 frr_pthread_wait_running(io
);
7654 frr_pthread_wait_running(ka
);
7657 void bgp_pthreads_finish()
7659 frr_pthread_stop_all();
7660 frr_pthread_finish();
7666 /* allocates some vital data structures used by peer commands in
7669 /* pre-init pthreads */
7670 bgp_pthreads_init();
7673 bgp_zebra_init(bm
->master
);
7676 vnc_zebra_init(bm
->master
);
7679 /* BGP VTY commands installation. */
7687 bgp_route_map_init();
7688 bgp_scan_vty_init();
7693 bgp_ethernetvpn_init();
7694 bgp_flowspec_vty_init();
7696 /* Access list initialize. */
7698 access_list_add_hook(peer_distribute_update
);
7699 access_list_delete_hook(peer_distribute_update
);
7701 /* Filter list initialize. */
7703 as_list_add_hook(peer_aslist_add
);
7704 as_list_delete_hook(peer_aslist_del
);
7706 /* Prefix list initialize.*/
7708 prefix_list_add_hook(peer_prefix_list_update
);
7709 prefix_list_delete_hook(peer_prefix_list_update
);
7711 /* Community list initialize. */
7712 bgp_clist
= community_list_init();
7717 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7720 void bgp_terminate(void)
7724 struct listnode
*node
, *nnode
;
7725 struct listnode
*mnode
, *mnnode
;
7729 /* Close the listener sockets first as this prevents peers from
7731 * to reconnect on receiving the peer unconfig message. In the presence
7732 * of a large number of peers this will ensure that no peer is left with
7733 * a dangling connection
7735 /* reverse bgp_master_init */
7738 if (bm
->listen_sockets
)
7739 list_delete_and_null(&bm
->listen_sockets
);
7741 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7742 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7743 if (peer
->status
== Established
7744 || peer
->status
== OpenSent
7745 || peer
->status
== OpenConfirm
)
7746 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7747 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7749 if (bm
->process_main_queue
)
7750 work_queue_free_and_null(&bm
->process_main_queue
);
7752 if (bm
->t_rmap_update
)
7753 BGP_TIMER_OFF(bm
->t_rmap_update
);