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_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
89 #include "bgpd/bgp_evpn_private.h"
91 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
92 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
93 DEFINE_QOBJ_TYPE(bgp_master
)
95 DEFINE_QOBJ_TYPE(peer
)
97 /* BGP process wide configuration. */
98 static struct bgp_master bgp_master
;
100 /* BGP process wide configuration pointer to export. */
101 struct bgp_master
*bm
;
103 /* BGP community-list. */
104 struct community_list_handler
*bgp_clist
;
106 unsigned int multipath_num
= MULTIPATH_NUM
;
108 static void bgp_if_finish(struct bgp
*bgp
);
109 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
111 extern struct zclient
*zclient
;
113 /* handle main socket creation or deletion */
114 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
116 static int bgp_server_main_created
;
118 if (create
== true) {
119 if (bgp_server_main_created
)
121 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
122 return BGP_ERR_INVALID_VALUE
;
123 bgp_server_main_created
= 1;
126 if (!bgp_server_main_created
)
129 bgp_server_main_created
= 0;
133 void bgp_session_reset(struct peer
*peer
)
135 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
136 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
137 peer_delete(peer
->doppelganger
);
139 BGP_EVENT_ADD(peer
, BGP_Stop
);
143 * During session reset, we may delete the doppelganger peer, which would
144 * be the next node to the current node. If the session reset was invoked
145 * during walk of peer list, we would end up accessing the freed next
146 * node. This function moves the next node along.
148 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
153 n
= (nnode
) ? *nnode
: NULL
;
154 npeer
= (n
) ? listgetdata(n
) : NULL
;
156 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
157 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
158 PEER_FLAG_CONFIG_NODE
))) {
159 if (peer
->doppelganger
== npeer
)
160 /* nnode and *nnode are confirmed to be non-NULL here */
161 *nnode
= (*nnode
)->next
;
162 peer_delete(peer
->doppelganger
);
165 BGP_EVENT_ADD(peer
, BGP_Stop
);
168 /* BGP global flag manipulation. */
169 int bgp_option_set(int flag
)
173 case BGP_OPT_MULTIPLE_INSTANCE
:
174 case BGP_OPT_CONFIG_CISCO
:
175 case BGP_OPT_NO_LISTEN
:
176 case BGP_OPT_NO_ZEBRA
:
177 SET_FLAG(bm
->options
, flag
);
180 return BGP_ERR_INVALID_FLAG
;
185 int bgp_option_unset(int flag
)
188 case BGP_OPT_MULTIPLE_INSTANCE
:
189 if (listcount(bm
->bgp
) > 1)
190 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
192 case BGP_OPT_NO_ZEBRA
:
194 case BGP_OPT_CONFIG_CISCO
:
195 UNSET_FLAG(bm
->options
, flag
);
198 return BGP_ERR_INVALID_FLAG
;
203 int bgp_option_check(int flag
)
205 return CHECK_FLAG(bm
->options
, flag
);
208 /* BGP flag manipulation. */
209 int bgp_flag_set(struct bgp
*bgp
, int flag
)
211 SET_FLAG(bgp
->flags
, flag
);
215 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
217 UNSET_FLAG(bgp
->flags
, flag
);
221 int bgp_flag_check(struct bgp
*bgp
, int flag
)
223 return CHECK_FLAG(bgp
->flags
, flag
);
226 /* Internal function to set BGP structure configureation flag. */
227 static void bgp_config_set(struct bgp
*bgp
, int config
)
229 SET_FLAG(bgp
->config
, config
);
232 static void bgp_config_unset(struct bgp
*bgp
, int config
)
234 UNSET_FLAG(bgp
->config
, config
);
237 static int bgp_config_check(struct bgp
*bgp
, int config
)
239 return CHECK_FLAG(bgp
->config
, config
);
242 /* Set BGP router identifier. */
243 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
246 struct listnode
*node
, *nnode
;
248 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
251 /* EVPN uses router id in RD, withdraw them */
252 if (is_evpn_enabled())
253 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
255 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
257 /* Set all peer's local identifier with this value. */
258 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
259 IPV4_ADDR_COPY(&peer
->local_id
, id
);
261 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
262 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
264 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
268 /* EVPN uses router id in RD, update them */
269 if (is_evpn_enabled())
270 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
275 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
277 struct listnode
*node
, *nnode
;
280 if (vrf_id
== VRF_DEFAULT
) {
281 /* Router-id change for default VRF has to also update all
283 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
284 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
287 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
288 if (!bgp
->router_id_static
.s_addr
)
289 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
292 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
294 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
296 if (!bgp
->router_id_static
.s_addr
)
297 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
302 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
304 bgp
->router_id_static
= id
;
305 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
309 /* BGP's cluster-id control. */
310 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
313 struct listnode
*node
, *nnode
;
315 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
316 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
319 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
320 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
322 /* Clear all IBGP peer. */
323 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
324 if (peer
->sort
!= BGP_PEER_IBGP
)
327 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
328 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
329 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
330 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
336 int bgp_cluster_id_unset(struct bgp
*bgp
)
339 struct listnode
*node
, *nnode
;
341 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
344 bgp
->cluster_id
.s_addr
= 0;
345 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
347 /* Clear all IBGP peer. */
348 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
349 if (peer
->sort
!= BGP_PEER_IBGP
)
352 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
353 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
354 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
355 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
361 /* time_t value that is monotonicly increasing
362 * and uneffected by adjustments to system clock
364 time_t bgp_clock(void)
372 /* BGP timer configuration. */
373 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
375 bgp
->default_keepalive
=
376 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
377 bgp
->default_holdtime
= holdtime
;
382 int bgp_timers_unset(struct bgp
*bgp
)
384 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
385 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
390 /* BGP confederation configuration. */
391 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
394 struct listnode
*node
, *nnode
;
398 return BGP_ERR_INVALID_AS
;
400 /* Remember - were we doing confederation before? */
401 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
403 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
405 /* If we were doing confederation already, this is just an external
406 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
407 were not doing confederation before, reset all EBGP sessions. */
408 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
409 /* We're looking for peers who's AS is not local or part of our
411 if (already_confed
) {
412 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
414 if (BGP_IS_VALID_STATE_FOR_NOTIF(
417 PEER_DOWN_CONFED_ID_CHANGE
;
419 peer
, BGP_NOTIFY_CEASE
,
420 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
422 bgp_session_reset_safe(peer
, &nnode
);
425 /* Not doign confederation before, so reset every
428 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
429 /* Reset the local_as to be our EBGP one */
430 if (peer_sort(peer
) == BGP_PEER_EBGP
)
432 if (BGP_IS_VALID_STATE_FOR_NOTIF(
435 PEER_DOWN_CONFED_ID_CHANGE
;
437 peer
, BGP_NOTIFY_CEASE
,
438 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
440 bgp_session_reset_safe(peer
, &nnode
);
447 int bgp_confederation_id_unset(struct bgp
*bgp
)
450 struct listnode
*node
, *nnode
;
453 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
455 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
456 /* We're looking for peers who's AS is not local */
457 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
458 peer
->local_as
= bgp
->as
;
459 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
460 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
461 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
462 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
466 bgp_session_reset_safe(peer
, &nnode
);
472 /* Is an AS part of the confed or not? */
473 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
480 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
481 if (bgp
->confed_peers
[i
] == as
)
487 /* Add an AS to the confederation set. */
488 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
491 struct listnode
*node
, *nnode
;
494 return BGP_ERR_INVALID_BGP
;
497 return BGP_ERR_INVALID_AS
;
499 if (bgp_confederation_peers_check(bgp
, as
))
502 if (bgp
->confed_peers
)
504 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
505 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
508 XMALLOC(MTYPE_BGP_CONFED_LIST
,
509 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
511 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
512 bgp
->confed_peers_cnt
++;
514 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
515 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
516 if (peer
->as
== as
) {
517 peer
->local_as
= bgp
->as
;
518 if (BGP_IS_VALID_STATE_FOR_NOTIF(
521 PEER_DOWN_CONFED_PEER_CHANGE
;
523 peer
, BGP_NOTIFY_CEASE
,
524 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
526 bgp_session_reset_safe(peer
, &nnode
);
533 /* Delete an AS from the confederation set. */
534 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
539 struct listnode
*node
, *nnode
;
544 if (!bgp_confederation_peers_check(bgp
, as
))
547 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
548 if (bgp
->confed_peers
[i
] == as
)
549 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
550 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
552 bgp
->confed_peers_cnt
--;
554 if (bgp
->confed_peers_cnt
== 0) {
555 if (bgp
->confed_peers
)
556 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
557 bgp
->confed_peers
= NULL
;
560 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
561 bgp
->confed_peers_cnt
* sizeof(as_t
));
563 /* Now reset any peer who's remote AS has just been removed from the
565 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
566 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
567 if (peer
->as
== as
) {
568 peer
->local_as
= bgp
->confed_id
;
569 if (BGP_IS_VALID_STATE_FOR_NOTIF(
572 PEER_DOWN_CONFED_PEER_CHANGE
;
574 peer
, BGP_NOTIFY_CEASE
,
575 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
577 bgp_session_reset_safe(peer
, &nnode
);
585 /* Local preference configuration. */
586 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
591 bgp
->default_local_pref
= local_pref
;
596 int bgp_default_local_preference_unset(struct bgp
*bgp
)
601 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
606 /* Local preference configuration. */
607 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
612 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
617 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
621 bgp
->default_subgroup_pkt_queue_max
=
622 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
627 /* Listen limit configuration. */
628 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
633 bgp
->dynamic_neighbors_limit
= listen_limit
;
638 int bgp_listen_limit_unset(struct bgp
*bgp
)
643 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
648 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
649 afi_t
*afi
, safi_t
*safi
)
651 /* Map from IANA values to internal values, return error if
652 * values are unrecognized.
654 *afi
= afi_iana2int(pkt_afi
);
655 *safi
= safi_iana2int(pkt_safi
);
656 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
662 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
663 iana_safi_t
*pkt_safi
)
665 /* Map from internal values to IANA values, return error if
666 * internal values are bad (unexpected).
668 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
670 *pkt_afi
= afi_int2iana(afi
);
671 *pkt_safi
= safi_int2iana(safi
);
675 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
683 afid
= afindex(afi
, safi
);
684 if (afid
>= BGP_AF_MAX
)
687 assert(peer
->peer_af_array
[afid
] == NULL
);
689 /* Allocate new peer af */
690 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
692 peer
->peer_af_array
[afid
] = af
;
701 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
708 afid
= afindex(afi
, safi
);
709 if (afid
>= BGP_AF_MAX
)
712 return peer
->peer_af_array
[afid
];
715 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
723 afid
= afindex(afi
, safi
);
724 if (afid
>= BGP_AF_MAX
)
727 af
= peer
->peer_af_array
[afid
];
731 bgp_stop_announce_route_timer(af
);
733 if (PAF_SUBGRP(af
)) {
734 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
735 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
736 af
->subgroup
->update_group
->id
,
737 af
->subgroup
->id
, peer
->host
);
740 update_subgroup_remove_peer(af
->subgroup
, af
);
742 peer
->peer_af_array
[afid
] = NULL
;
743 XFREE(MTYPE_BGP_PEER_AF
, af
);
747 /* Peer comparison function for sorting. */
748 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
750 if (p1
->group
&& !p2
->group
)
753 if (!p1
->group
&& p2
->group
)
756 if (p1
->group
== p2
->group
) {
757 if (p1
->conf_if
&& !p2
->conf_if
)
760 if (!p1
->conf_if
&& p2
->conf_if
)
763 if (p1
->conf_if
&& p2
->conf_if
)
764 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
766 return strcmp(p1
->group
->name
, p2
->group
->name
);
768 return sockunion_cmp(&p1
->su
, &p2
->su
);
771 static unsigned int peer_hash_key_make(void *p
)
773 struct peer
*peer
= p
;
774 return sockunion_hash(&peer
->su
);
777 static bool peer_hash_same(const void *p1
, const void *p2
)
779 const struct peer
*peer1
= p1
;
780 const struct peer
*peer2
= p2
;
781 return (sockunion_same(&peer1
->su
, &peer2
->su
)
782 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
783 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
786 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
790 /* Skip if peer is not a peer-group member. */
791 if (!peer_group_active(peer
))
794 /* Unset override flag to signal inheritance from peer-group. */
795 UNSET_FLAG(peer
->flags_override
, flag
);
798 * Inherit flag state from peer-group. If the flag of the peer-group is
799 * not being inverted, the peer must inherit the inverse of the current
800 * peer-group flag state.
802 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
803 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
804 && CHECK_FLAG(peer
->flags_invert
, flag
))
805 COND_FLAG(peer
->flags
, flag
, !group_val
);
807 COND_FLAG(peer
->flags
, flag
, group_val
);
810 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
812 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
815 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
820 /* Skip if peer is not a peer-group member. */
821 if (!peer_group_active(peer
))
824 /* Unset override flag to signal inheritance from peer-group. */
825 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
828 * Inherit flag state from peer-group. If the flag of the peer-group is
829 * not being inverted, the peer must inherit the inverse of the current
830 * peer-group flag state.
832 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
833 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
834 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
835 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
837 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
840 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
842 if (!peer_group_active(peer
)) {
843 if (CHECK_FLAG(peer
->flags_invert
, flag
))
844 return !CHECK_FLAG(peer
->flags
, flag
);
846 return !!CHECK_FLAG(peer
->flags
, flag
);
849 return !!CHECK_FLAG(peer
->flags_override
, flag
);
852 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
855 if (!peer_group_active(peer
)) {
856 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
857 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
859 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
862 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
865 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
866 uint8_t type
, int direct
)
868 struct bgp_filter
*filter
;
870 if (peer_group_active(peer
))
871 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
874 filter
= &peer
->filter
[afi
][safi
];
876 case PEER_FT_DISTRIBUTE_LIST
:
877 return !!(filter
->dlist
[direct
].name
);
878 case PEER_FT_FILTER_LIST
:
879 return !!(filter
->aslist
[direct
].name
);
880 case PEER_FT_PREFIX_LIST
:
881 return !!(filter
->plist
[direct
].name
);
882 case PEER_FT_ROUTE_MAP
:
883 return !!(filter
->map
[direct
].name
);
884 case PEER_FT_UNSUPPRESS_MAP
:
885 return !!(filter
->usmap
.name
);
891 /* Return true if the addpath type is set for peer and different from
894 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
896 enum bgp_addpath_strat type
, g_type
;
898 type
= peer
->addpath_type
[afi
][safi
];
900 if (type
!= BGP_ADDPATH_NONE
) {
901 if (peer_group_active(peer
)) {
902 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
916 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
917 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
924 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
925 if (peer
->as_type
== AS_INTERNAL
)
926 return BGP_PEER_IBGP
;
928 else if (peer
->as_type
== AS_EXTERNAL
)
929 return BGP_PEER_EBGP
;
931 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
933 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
941 peer1
= listnode_head(peer
->group
->peer
);
946 return BGP_PEER_INTERNAL
;
950 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
951 if (peer
->local_as
== 0)
952 return BGP_PEER_INTERNAL
;
954 if (peer
->local_as
== peer
->as
) {
955 if (bgp
->as
== bgp
->confed_id
) {
956 if (peer
->local_as
== bgp
->as
)
957 return BGP_PEER_IBGP
;
959 return BGP_PEER_EBGP
;
961 if (peer
->local_as
== bgp
->confed_id
)
962 return BGP_PEER_EBGP
;
964 return BGP_PEER_IBGP
;
968 if (bgp_confederation_peers_check(bgp
, peer
->as
))
969 return BGP_PEER_CONFED
;
971 return BGP_PEER_EBGP
;
973 if (peer
->as_type
!= AS_SPECIFIED
)
974 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
977 return (peer
->local_as
== 0
979 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
984 /* Calculate and cache the peer "sort" */
985 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
987 peer
->sort
= peer_calc_sort(peer
);
991 static void peer_free(struct peer
*peer
)
996 assert(peer
->status
== Deleted
);
1000 /* this /ought/ to have been done already through bgp_stop earlier,
1001 * but just to be sure..
1003 bgp_timer_set(peer
);
1004 bgp_reads_off(peer
);
1005 bgp_writes_off(peer
);
1006 assert(!peer
->t_write
);
1007 assert(!peer
->t_read
);
1008 BGP_EVENT_FLUSH(peer
);
1010 pthread_mutex_destroy(&peer
->io_mtx
);
1012 /* Free connected nexthop, if present */
1013 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1014 && !peer_dynamic_neighbor(peer
))
1015 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1018 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1021 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1025 /* Free allocated host character. */
1027 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1031 if (peer
->domainname
) {
1032 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1033 peer
->domainname
= NULL
;
1037 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1038 peer
->ifname
= NULL
;
1041 /* Update source configuration. */
1042 if (peer
->update_source
) {
1043 sockunion_free(peer
->update_source
);
1044 peer
->update_source
= NULL
;
1047 if (peer
->update_if
) {
1048 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1049 peer
->update_if
= NULL
;
1052 if (peer
->notify
.data
)
1053 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1054 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1056 if (peer
->clear_node_queue
)
1057 work_queue_free_and_null(&peer
->clear_node_queue
);
1059 bgp_sync_delete(peer
);
1061 if (peer
->conf_if
) {
1062 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1063 peer
->conf_if
= NULL
;
1066 bfd_info_free(&(peer
->bfd_info
));
1068 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1069 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1070 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1075 bgp_unlock(peer
->bgp
);
1077 memset(peer
, 0, sizeof(struct peer
));
1079 XFREE(MTYPE_BGP_PEER
, peer
);
1082 /* increase reference count on a struct peer */
1083 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1085 assert(peer
&& (peer
->lock
>= 0));
1088 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1096 /* decrease reference count on a struct peer
1097 * struct peer is freed and NULL returned if last reference
1099 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1101 assert(peer
&& (peer
->lock
> 0));
1104 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1109 if (peer
->lock
== 0) {
1117 /* Allocate new peer object, implicitely locked. */
1118 struct peer
*peer_new(struct bgp
*bgp
)
1125 /* bgp argument is absolutely required */
1130 /* Allocate new peer. */
1131 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1133 /* Set default value. */
1135 peer
->v_start
= BGP_INIT_START_TIMER
;
1136 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1137 peer
->status
= Idle
;
1138 peer
->ostatus
= Idle
;
1139 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1140 peer
->bgp
= bgp_lock(bgp
);
1141 peer
= peer_lock(peer
); /* initial reference */
1142 peer
->password
= NULL
;
1144 /* Set default flags. */
1145 FOREACH_AFI_SAFI (afi
, safi
) {
1146 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1147 SET_FLAG(peer
->af_flags
[afi
][safi
],
1148 PEER_FLAG_SEND_COMMUNITY
);
1149 SET_FLAG(peer
->af_flags
[afi
][safi
],
1150 PEER_FLAG_SEND_EXT_COMMUNITY
);
1151 SET_FLAG(peer
->af_flags
[afi
][safi
],
1152 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1154 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1155 PEER_FLAG_SEND_COMMUNITY
);
1156 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1157 PEER_FLAG_SEND_EXT_COMMUNITY
);
1158 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1159 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1161 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1164 /* set nexthop-unchanged for l2vpn evpn by default */
1165 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1166 PEER_FLAG_NEXTHOP_UNCHANGED
);
1168 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1170 /* Create buffers. */
1171 peer
->ibuf
= stream_fifo_new();
1172 peer
->obuf
= stream_fifo_new();
1173 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1175 /* We use a larger buffer for peer->obuf_work in the event that:
1176 * - We RX a BGP_UPDATE where the attributes alone are just
1177 * under BGP_MAX_PACKET_SIZE
1178 * - The user configures an outbound route-map that does many as-path
1179 * prepends or adds many communities. At most they can have
1180 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1181 * large they can make the attributes.
1183 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1184 * bounds checking for every single attribute as we construct an
1188 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1190 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1192 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1194 bgp_sync_init(peer
);
1196 /* Get service port number. */
1197 sp
= getservbyname("bgp", "tcp");
1198 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1200 QOBJ_REG(peer
, peer
);
1205 * This function is invoked when a duplicate peer structure associated with
1206 * a neighbor is being deleted. If this about-to-be-deleted structure is
1207 * the one with all the config, then we have to copy over the info.
1209 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1211 struct peer_af
*paf
;
1219 /* The following function is used by both peer group config copy to
1220 * individual peer and when we transfer config
1222 if (peer_src
->change_local_as
)
1223 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1225 /* peer flags apply */
1226 peer_dst
->flags
= peer_src
->flags
;
1227 peer_dst
->cap
= peer_src
->cap
;
1229 peer_dst
->local_as
= peer_src
->local_as
;
1230 peer_dst
->port
= peer_src
->port
;
1231 (void)peer_sort(peer_dst
);
1232 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1235 peer_dst
->holdtime
= peer_src
->holdtime
;
1236 peer_dst
->keepalive
= peer_src
->keepalive
;
1237 peer_dst
->connect
= peer_src
->connect
;
1238 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1239 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1240 peer_dst
->routeadv
= peer_src
->routeadv
;
1241 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1243 /* password apply */
1244 if (peer_src
->password
&& !peer_dst
->password
)
1245 peer_dst
->password
=
1246 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1248 FOREACH_AFI_SAFI (afi
, safi
) {
1249 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1250 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1251 peer_dst
->allowas_in
[afi
][safi
] =
1252 peer_src
->allowas_in
[afi
][safi
];
1253 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1254 peer_dst
->addpath_type
[afi
][safi
] =
1255 peer_src
->addpath_type
[afi
][safi
];
1258 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1259 paf
= peer_src
->peer_af_array
[afidx
];
1261 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1264 /* update-source apply */
1265 if (peer_src
->update_source
) {
1266 if (peer_dst
->update_source
)
1267 sockunion_free(peer_dst
->update_source
);
1268 if (peer_dst
->update_if
) {
1269 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1270 peer_dst
->update_if
= NULL
;
1272 peer_dst
->update_source
=
1273 sockunion_dup(peer_src
->update_source
);
1274 } else if (peer_src
->update_if
) {
1275 if (peer_dst
->update_if
)
1276 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1277 if (peer_dst
->update_source
) {
1278 sockunion_free(peer_dst
->update_source
);
1279 peer_dst
->update_source
= NULL
;
1281 peer_dst
->update_if
=
1282 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1285 if (peer_src
->ifname
) {
1286 if (peer_dst
->ifname
)
1287 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1290 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1294 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1295 struct interface
*ifp
)
1297 struct connected
*ifc
;
1300 struct listnode
*node
;
1302 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1303 * IPv4 address of the other end.
1305 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1306 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1307 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1308 if (p
.prefixlen
== 30) {
1309 peer
->su
.sa
.sa_family
= AF_INET
;
1310 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1312 peer
->su
.sin
.sin_addr
.s_addr
=
1314 else if (addr
% 4 == 2)
1315 peer
->su
.sin
.sin_addr
.s_addr
=
1317 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1318 peer
->su
.sin
.sin_len
=
1319 sizeof(struct sockaddr_in
);
1320 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1322 } else if (p
.prefixlen
== 31) {
1323 peer
->su
.sa
.sa_family
= AF_INET
;
1324 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1326 peer
->su
.sin
.sin_addr
.s_addr
=
1329 peer
->su
.sin
.sin_addr
.s_addr
=
1331 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1332 peer
->su
.sin
.sin_len
=
1333 sizeof(struct sockaddr_in
);
1334 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1336 } else if (bgp_debug_neighbor_events(peer
))
1338 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1346 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1347 struct interface
*ifp
)
1349 struct nbr_connected
*ifc_nbr
;
1351 /* Have we learnt the peer's IPv6 link-local address? */
1352 if (ifp
->nbr_connected
1353 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1354 peer
->su
.sa
.sa_family
= AF_INET6
;
1355 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1356 sizeof(struct in6_addr
));
1358 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1360 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1368 * Set or reset the peer address socketunion structure based on the
1369 * learnt/derived peer address. If the address has changed, update the
1370 * password on the listen socket, if needed.
1372 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1374 struct interface
*ifp
;
1376 int peer_addr_updated
= 0;
1382 * Our peer structure is stored in the bgp->peerhash
1383 * release it before we modify anything.
1385 hash_release(peer
->bgp
->peerhash
, peer
);
1387 prev_family
= peer
->su
.sa
.sa_family
;
1388 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1390 /* If BGP unnumbered is not "v6only", we first see if we can
1392 * peer's IPv4 address.
1394 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1396 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1398 /* If "v6only" or we can't derive peer's IPv4 address, see if
1400 * learnt the peer's IPv6 link-local address. This is from the
1402 * IPv6 address in router advertisement.
1404 if (!peer_addr_updated
)
1406 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1408 /* If we could derive the peer address, we may need to install the
1410 * configured for the peer, if any, on the listen socket. Otherwise,
1412 * that peer's address is not available and uninstall the password, if
1415 if (peer_addr_updated
) {
1416 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1417 && prev_family
== AF_UNSPEC
)
1420 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1421 && prev_family
!= AF_UNSPEC
)
1422 bgp_md5_unset(peer
);
1423 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1424 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1428 * Since our su changed we need to del/add peer to the peerhash
1430 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1433 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1436 struct bgp_node
*rn
, *nrn
;
1438 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1439 rn
= bgp_route_next(rn
)) {
1440 if (rn
->info
!= NULL
) {
1441 /* Special handling for 2-level routing
1443 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1444 || safi
== SAFI_EVPN
) {
1445 for (nrn
= bgp_table_top(
1446 (struct bgp_table
*)(rn
->info
));
1447 nrn
; nrn
= bgp_route_next(nrn
))
1448 bgp_process(bgp
, nrn
, afi
, safi
);
1450 bgp_process(bgp
, rn
, afi
, safi
);
1455 /* Force a bestpath recalculation for all prefixes. This is used
1456 * when 'bgp bestpath' commands are entered.
1458 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1463 FOREACH_AFI_SAFI (afi
, safi
) {
1464 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1469 * Create new BGP peer.
1471 * conf_if and su are mutually exclusive if configuring from the cli.
1472 * If we are handing a doppelganger, then we *must* pass in both
1473 * the original peer's su and conf_if, so that we can appropriately
1474 * track the bgp->peerhash( ie we don't want to remove the current
1475 * one from the config ).
1477 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1478 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1479 int as_type
, afi_t afi
, safi_t safi
,
1480 struct peer_group
*group
)
1484 char buf
[SU_ADDRSTRLEN
];
1486 peer
= peer_new(bgp
);
1488 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1492 bgp_peer_conf_if_to_su_update(peer
);
1494 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1495 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1498 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1500 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1501 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1503 peer
->local_as
= local_as
;
1504 peer
->as
= remote_as
;
1505 peer
->as_type
= as_type
;
1506 peer
->local_id
= bgp
->router_id
;
1507 peer
->v_holdtime
= bgp
->default_holdtime
;
1508 peer
->v_keepalive
= bgp
->default_keepalive
;
1509 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1510 ? BGP_DEFAULT_IBGP_ROUTEADV
1511 : BGP_DEFAULT_EBGP_ROUTEADV
;
1513 peer
= peer_lock(peer
); /* bgp peer list reference */
1514 peer
->group
= group
;
1515 listnode_add_sort(bgp
->peer
, peer
);
1516 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1518 /* Adjust update-group coalesce timer heuristics for # peers. */
1519 if (bgp
->heuristic_coalesce
) {
1520 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1522 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1523 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1526 active
= peer_active(peer
);
1528 /* Last read and reset time set */
1529 peer
->readtime
= peer
->resettime
= bgp_clock();
1531 /* Default TTL set. */
1532 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1534 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1537 peer
->afc
[afi
][safi
] = 1;
1538 peer_af_create(peer
, afi
, safi
);
1541 /* auto shutdown if configured */
1542 if (bgp
->autoshutdown
)
1543 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1544 /* Set up peer's events and timers. */
1545 else if (!active
&& peer_active(peer
))
1546 bgp_timer_set(peer
);
1551 /* Make accept BGP peer. This function is only called from the test code */
1552 struct peer
*peer_create_accept(struct bgp
*bgp
)
1556 peer
= peer_new(bgp
);
1558 peer
= peer_lock(peer
); /* bgp peer list reference */
1559 listnode_add_sort(bgp
->peer
, peer
);
1565 * Return true if we have a peer configured to use this afi/safi
1567 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1569 struct listnode
*node
;
1572 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1573 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1576 if (peer
->afc
[afi
][safi
])
1583 /* Change peer's AS number. */
1584 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1586 bgp_peer_sort_t type
;
1589 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1590 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1591 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1592 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1593 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1595 bgp_session_reset(peer
);
1597 type
= peer_sort(peer
);
1599 peer
->as_type
= as_specified
;
1601 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1602 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1603 && peer
->bgp
->as
!= as
)
1604 peer
->local_as
= peer
->bgp
->confed_id
;
1606 peer
->local_as
= peer
->bgp
->as
;
1608 /* Advertisement-interval reset */
1609 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1610 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1611 ? BGP_DEFAULT_IBGP_ROUTEADV
1612 : BGP_DEFAULT_EBGP_ROUTEADV
;
1616 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1618 else if (type
== BGP_PEER_IBGP
)
1621 /* reflector-client reset */
1622 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1623 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1624 PEER_FLAG_REFLECTOR_CLIENT
);
1625 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1626 PEER_FLAG_REFLECTOR_CLIENT
);
1627 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1628 PEER_FLAG_REFLECTOR_CLIENT
);
1629 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1630 PEER_FLAG_REFLECTOR_CLIENT
);
1631 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1632 PEER_FLAG_REFLECTOR_CLIENT
);
1633 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1634 PEER_FLAG_REFLECTOR_CLIENT
);
1635 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1636 PEER_FLAG_REFLECTOR_CLIENT
);
1637 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1638 PEER_FLAG_REFLECTOR_CLIENT
);
1639 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1640 PEER_FLAG_REFLECTOR_CLIENT
);
1641 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1642 PEER_FLAG_REFLECTOR_CLIENT
);
1643 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1644 PEER_FLAG_REFLECTOR_CLIENT
);
1645 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1646 PEER_FLAG_REFLECTOR_CLIENT
);
1647 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1648 PEER_FLAG_REFLECTOR_CLIENT
);
1651 /* local-as reset */
1652 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1653 peer
->change_local_as
= 0;
1654 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1655 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1656 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1660 /* If peer does not exist, create new one. If peer already exists,
1661 set AS number to the peer. */
1662 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1663 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1669 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1671 peer
= peer_lookup(bgp
, su
);
1674 /* Not allowed for a dynamic peer. */
1675 if (peer_dynamic_neighbor(peer
)) {
1677 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1680 /* When this peer is a member of peer-group. */
1682 if (peer
->group
->conf
->as
) {
1683 /* Return peer group's AS number. */
1684 *as
= peer
->group
->conf
->as
;
1685 return BGP_ERR_PEER_GROUP_MEMBER
;
1687 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1688 if ((as_type
!= AS_INTERNAL
)
1689 && (bgp
->as
!= *as
)) {
1691 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1694 if ((as_type
!= AS_EXTERNAL
)
1695 && (bgp
->as
== *as
)) {
1697 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1702 /* Existing peer's AS number change. */
1703 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1704 || (peer
->as_type
!= as_type
))
1705 peer_as_change(peer
, *as
, as_type
);
1708 return BGP_ERR_NO_INTERFACE_CONFIG
;
1710 /* If the peer is not part of our confederation, and its not an
1711 iBGP peer then spoof the source AS */
1712 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1713 && !bgp_confederation_peers_check(bgp
, *as
)
1715 local_as
= bgp
->confed_id
;
1719 /* If this is IPv4 unicast configuration and "no bgp default
1720 ipv4-unicast" is specified. */
1722 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1723 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1724 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1727 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1734 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1735 struct peer
*peer
, afi_t afi
,
1739 int out
= FILTER_OUT
;
1741 uint32_t pflags_ovrd
;
1742 uint8_t *pfilter_ovrd
;
1746 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1747 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1749 /* peer af_flags apply */
1750 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1751 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1752 ^ peer
->af_flags_invert
[afi
][safi
];
1753 flags_tmp
&= ~pflags_ovrd
;
1755 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1756 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1757 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1758 conf
->af_flags_invert
[afi
][safi
]);
1760 /* maximum-prefix */
1761 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1762 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1763 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1764 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1768 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1769 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1772 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1773 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1775 /* default-originate route-map */
1776 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1777 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1778 MTYPE_ROUTE_MAP_NAME
);
1779 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1782 /* inbound filter apply */
1783 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1784 PEER_STR_ATTR_INHERIT(peer
, group
,
1785 filter
[afi
][safi
].dlist
[in
].name
,
1786 MTYPE_BGP_FILTER_NAME
);
1787 PEER_ATTR_INHERIT(peer
, group
,
1788 filter
[afi
][safi
].dlist
[in
].alist
);
1791 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1792 PEER_STR_ATTR_INHERIT(peer
, group
,
1793 filter
[afi
][safi
].plist
[in
].name
,
1794 MTYPE_BGP_FILTER_NAME
);
1795 PEER_ATTR_INHERIT(peer
, group
,
1796 filter
[afi
][safi
].plist
[in
].plist
);
1799 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1800 PEER_STR_ATTR_INHERIT(peer
, group
,
1801 filter
[afi
][safi
].aslist
[in
].name
,
1802 MTYPE_BGP_FILTER_NAME
);
1803 PEER_ATTR_INHERIT(peer
, group
,
1804 filter
[afi
][safi
].aslist
[in
].aslist
);
1807 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1808 PEER_STR_ATTR_INHERIT(peer
, group
,
1809 filter
[afi
][safi
].map
[in
].name
,
1810 MTYPE_BGP_FILTER_NAME
);
1811 PEER_ATTR_INHERIT(peer
, group
,
1812 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1815 /* outbound filter apply */
1816 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1817 PEER_STR_ATTR_INHERIT(peer
, group
,
1818 filter
[afi
][safi
].dlist
[out
].name
,
1819 MTYPE_BGP_FILTER_NAME
);
1820 PEER_ATTR_INHERIT(peer
, group
,
1821 filter
[afi
][safi
].dlist
[out
].alist
);
1824 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1825 PEER_STR_ATTR_INHERIT(peer
, group
,
1826 filter
[afi
][safi
].plist
[out
].name
,
1827 MTYPE_BGP_FILTER_NAME
);
1828 PEER_ATTR_INHERIT(peer
, group
,
1829 filter
[afi
][safi
].plist
[out
].plist
);
1832 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1833 PEER_STR_ATTR_INHERIT(peer
, group
,
1834 filter
[afi
][safi
].aslist
[out
].name
,
1835 MTYPE_BGP_FILTER_NAME
);
1836 PEER_ATTR_INHERIT(peer
, group
,
1837 filter
[afi
][safi
].aslist
[out
].aslist
);
1840 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1841 PEER_STR_ATTR_INHERIT(peer
, group
,
1842 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1843 MTYPE_BGP_FILTER_NAME
);
1844 PEER_ATTR_INHERIT(peer
, group
,
1845 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1848 /* nondirectional filter apply */
1849 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1850 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1851 MTYPE_BGP_FILTER_NAME
);
1852 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1855 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1856 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1857 bgp_addpath_type_changed(conf
->bgp
);
1861 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1866 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1867 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1868 __func__
, peer
->host
);
1872 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1874 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1875 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1876 return BGP_ERR_PEER_SAFI_CONFLICT
;
1878 /* Nothing to do if we've already activated this peer */
1879 if (peer
->afc
[afi
][safi
])
1882 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1885 active
= peer_active(peer
);
1886 peer
->afc
[afi
][safi
] = 1;
1889 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1891 if (!active
&& peer_active(peer
)) {
1892 bgp_timer_set(peer
);
1894 if (peer
->status
== Established
) {
1895 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1896 peer
->afc_adv
[afi
][safi
] = 1;
1897 bgp_capability_send(peer
, afi
, safi
,
1899 CAPABILITY_ACTION_SET
);
1900 if (peer
->afc_recv
[afi
][safi
]) {
1901 peer
->afc_nego
[afi
][safi
] = 1;
1902 bgp_announce_route(peer
, afi
, safi
);
1905 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1906 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1907 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1910 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1911 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1912 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1913 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1916 * If we are turning on a AFI/SAFI locally and we've
1917 * started bringing a peer up, we need to tell
1918 * the other peer to restart because we might loose
1919 * configuration here because when the doppelganger
1920 * gets to a established state due to how
1921 * we resolve we could just overwrite the afi/safi
1924 other
= peer
->doppelganger
;
1926 && (other
->status
== OpenSent
1927 || other
->status
== OpenConfirm
)) {
1928 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1929 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1930 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1937 /* Activate the peer or peer group for specified AFI and SAFI. */
1938 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1941 struct peer_group
*group
;
1942 struct listnode
*node
, *nnode
;
1943 struct peer
*tmp_peer
;
1946 /* Nothing to do if we've already activated this peer */
1947 if (peer
->afc
[afi
][safi
])
1952 /* This is a peer-group so activate all of the members of the
1953 * peer-group as well */
1954 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1956 /* Do not activate a peer for both SAFI_UNICAST and
1957 * SAFI_LABELED_UNICAST */
1958 if ((safi
== SAFI_UNICAST
1959 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1960 || (safi
== SAFI_LABELED_UNICAST
1961 && peer
->afc
[afi
][SAFI_UNICAST
]))
1962 return BGP_ERR_PEER_SAFI_CONFLICT
;
1964 peer
->afc
[afi
][safi
] = 1;
1965 group
= peer
->group
;
1967 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1968 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1971 ret
|= peer_activate_af(peer
, afi
, safi
);
1974 /* If this is the first peer to be activated for this
1975 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1976 if (safi
== SAFI_LABELED_UNICAST
1977 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1979 if (BGP_DEBUG(zebra
, ZEBRA
))
1981 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1983 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1984 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1987 if (safi
== SAFI_FLOWSPEC
) {
1988 /* connect to table manager */
1989 bgp_zebra_init_tm_connect(bgp
);
1994 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1997 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1998 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1999 __func__
, peer
->host
);
2003 /* Nothing to do if we've already deactivated this peer */
2004 if (!peer
->afc
[afi
][safi
])
2007 /* De-activate the address family configuration. */
2008 peer
->afc
[afi
][safi
] = 0;
2010 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2011 flog_err(EC_BGP_PEER_DELETE
,
2012 "couldn't delete af structure for peer %s",
2017 if (peer
->status
== Established
) {
2018 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2019 peer
->afc_adv
[afi
][safi
] = 0;
2020 peer
->afc_nego
[afi
][safi
] = 0;
2022 if (peer_active_nego(peer
)) {
2023 bgp_capability_send(peer
, afi
, safi
,
2025 CAPABILITY_ACTION_UNSET
);
2026 bgp_clear_route(peer
, afi
, safi
);
2027 peer
->pcount
[afi
][safi
] = 0;
2029 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2030 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2031 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2034 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2035 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2036 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2043 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2046 struct peer_group
*group
;
2047 struct peer
*tmp_peer
;
2048 struct listnode
*node
, *nnode
;
2051 /* Nothing to do if we've already de-activated this peer */
2052 if (!peer
->afc
[afi
][safi
])
2055 /* This is a peer-group so de-activate all of the members of the
2056 * peer-group as well */
2057 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2058 peer
->afc
[afi
][safi
] = 0;
2059 group
= peer
->group
;
2061 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2062 flog_err(EC_BGP_PEER_DELETE
,
2063 "couldn't delete af structure for peer %s",
2067 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2068 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2071 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2076 /* If this is the last peer to be deactivated for this
2077 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2078 if (safi
== SAFI_LABELED_UNICAST
2079 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2080 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2082 if (BGP_DEBUG(zebra
, ZEBRA
))
2084 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2086 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2087 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2092 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2095 return peer_activate(peer
, afi
, safi
);
2097 return peer_deactivate(peer
, afi
, safi
);
2100 static void peer_nsf_stop(struct peer
*peer
)
2105 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2106 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2108 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2109 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2110 peer
->nsf
[afi
][safi
] = 0;
2112 if (peer
->t_gr_restart
) {
2113 BGP_TIMER_OFF(peer
->t_gr_restart
);
2114 if (bgp_debug_neighbor_events(peer
))
2115 zlog_debug("%s graceful restart timer stopped",
2118 if (peer
->t_gr_stale
) {
2119 BGP_TIMER_OFF(peer
->t_gr_stale
);
2120 if (bgp_debug_neighbor_events(peer
))
2122 "%s graceful restart stalepath timer stopped",
2125 bgp_clear_route_all(peer
);
2128 /* Delete peer from confguration.
2130 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2131 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2133 * This function /should/ take care to be idempotent, to guard against
2134 * it being called multiple times through stray events that come in
2135 * that happen to result in this function being called again. That
2136 * said, getting here for a "Deleted" peer is a bug in the neighbour
2139 int peer_delete(struct peer
*peer
)
2145 struct bgp_filter
*filter
;
2146 struct listnode
*pn
;
2149 assert(peer
->status
!= Deleted
);
2152 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2154 bgp_reads_off(peer
);
2155 bgp_writes_off(peer
);
2156 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2157 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2159 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2160 peer_nsf_stop(peer
);
2162 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2164 /* If this peer belongs to peer group, clear up the
2167 if (peer_dynamic_neighbor(peer
))
2168 peer_drop_dynamic_neighbor(peer
);
2170 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2172 peer
); /* group->peer list reference */
2173 list_delete_node(peer
->group
->peer
, pn
);
2178 /* Withdraw all information from routing table. We can not use
2179 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2180 * executed after peer structure is deleted.
2182 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2184 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2186 if (peer
->doppelganger
) {
2187 peer
->doppelganger
->doppelganger
= NULL
;
2188 peer
->doppelganger
= NULL
;
2191 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2192 bgp_fsm_change_status(peer
, Deleted
);
2194 /* Remove from NHT */
2195 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2196 bgp_unlink_nexthop_by_peer(peer
);
2198 /* Password configuration */
2199 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2200 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2202 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2203 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2204 bgp_md5_unset(peer
);
2207 bgp_timer_set(peer
); /* stops all timers for Deleted */
2209 /* Delete from all peer list. */
2210 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2211 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2212 peer_unlock(peer
); /* bgp peer list reference */
2213 list_delete_node(bgp
->peer
, pn
);
2214 hash_release(bgp
->peerhash
, peer
);
2219 stream_fifo_free(peer
->ibuf
);
2224 stream_fifo_free(peer
->obuf
);
2228 if (peer
->ibuf_work
) {
2229 ringbuf_del(peer
->ibuf_work
);
2230 peer
->ibuf_work
= NULL
;
2233 if (peer
->obuf_work
) {
2234 stream_free(peer
->obuf_work
);
2235 peer
->obuf_work
= NULL
;
2238 if (peer
->scratch
) {
2239 stream_free(peer
->scratch
);
2240 peer
->scratch
= NULL
;
2243 /* Local and remote addresses. */
2244 if (peer
->su_local
) {
2245 sockunion_free(peer
->su_local
);
2246 peer
->su_local
= NULL
;
2249 if (peer
->su_remote
) {
2250 sockunion_free(peer
->su_remote
);
2251 peer
->su_remote
= NULL
;
2254 /* Free filter related memory. */
2255 FOREACH_AFI_SAFI (afi
, safi
) {
2256 filter
= &peer
->filter
[afi
][safi
];
2258 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2259 if (filter
->dlist
[i
].name
) {
2260 XFREE(MTYPE_BGP_FILTER_NAME
,
2261 filter
->dlist
[i
].name
);
2262 filter
->dlist
[i
].name
= NULL
;
2265 if (filter
->plist
[i
].name
) {
2266 XFREE(MTYPE_BGP_FILTER_NAME
,
2267 filter
->plist
[i
].name
);
2268 filter
->plist
[i
].name
= NULL
;
2271 if (filter
->aslist
[i
].name
) {
2272 XFREE(MTYPE_BGP_FILTER_NAME
,
2273 filter
->aslist
[i
].name
);
2274 filter
->aslist
[i
].name
= NULL
;
2278 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2279 if (filter
->map
[i
].name
) {
2280 XFREE(MTYPE_BGP_FILTER_NAME
,
2281 filter
->map
[i
].name
);
2282 filter
->map
[i
].name
= NULL
;
2286 if (filter
->usmap
.name
) {
2287 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2288 filter
->usmap
.name
= NULL
;
2291 if (peer
->default_rmap
[afi
][safi
].name
) {
2292 XFREE(MTYPE_ROUTE_MAP_NAME
,
2293 peer
->default_rmap
[afi
][safi
].name
);
2294 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2298 FOREACH_AFI_SAFI (afi
, safi
)
2299 peer_af_delete(peer
, afi
, safi
);
2301 if (peer
->hostname
) {
2302 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2303 peer
->hostname
= NULL
;
2306 if (peer
->domainname
) {
2307 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2308 peer
->domainname
= NULL
;
2311 peer_unlock(peer
); /* initial reference */
2316 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2318 return strcmp(g1
->name
, g2
->name
);
2321 /* Peer group cofiguration. */
2322 static struct peer_group
*peer_group_new(void)
2324 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2325 sizeof(struct peer_group
));
2328 static void peer_group_free(struct peer_group
*group
)
2330 XFREE(MTYPE_PEER_GROUP
, group
);
2333 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2335 struct peer_group
*group
;
2336 struct listnode
*node
, *nnode
;
2338 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2339 if (strcmp(group
->name
, name
) == 0)
2345 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2347 struct peer_group
*group
;
2350 group
= peer_group_lookup(bgp
, name
);
2354 group
= peer_group_new();
2357 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2358 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2359 group
->peer
= list_new();
2360 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2361 group
->listen_range
[afi
] = list_new();
2362 group
->conf
= peer_new(bgp
);
2363 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2364 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2365 if (group
->conf
->host
)
2366 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2367 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2368 group
->conf
->group
= group
;
2369 group
->conf
->as
= 0;
2370 group
->conf
->ttl
= 1;
2371 group
->conf
->gtsm_hops
= 0;
2372 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2373 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2374 listnode_add_sort(bgp
->group
, group
);
2379 static void peer_group2peer_config_copy(struct peer_group
*group
,
2389 peer
->as
= conf
->as
;
2392 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2393 peer
->change_local_as
= conf
->change_local_as
;
2396 peer
->ttl
= conf
->ttl
;
2399 peer
->gtsm_hops
= conf
->gtsm_hops
;
2401 /* peer flags apply */
2402 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2403 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2404 flags_tmp
&= ~peer
->flags_override
;
2406 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2407 SET_FLAG(peer
->flags
, flags_tmp
);
2408 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2410 /* peer timers apply */
2411 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2412 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2413 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2416 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2417 PEER_ATTR_INHERIT(peer
, group
, connect
);
2418 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2419 peer
->v_connect
= conf
->connect
;
2421 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2424 /* advertisement-interval apply */
2425 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2426 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2427 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2428 peer
->v_routeadv
= conf
->routeadv
;
2430 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2431 ? BGP_DEFAULT_IBGP_ROUTEADV
2432 : BGP_DEFAULT_EBGP_ROUTEADV
;
2435 /* password apply */
2436 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2437 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2438 MTYPE_PEER_PASSWORD
);
2440 if (!BGP_PEER_SU_UNSPEC(peer
))
2443 /* update-source apply */
2444 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2445 if (conf
->update_source
) {
2446 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2447 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2448 } else if (conf
->update_if
) {
2449 sockunion_free(peer
->update_source
);
2450 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2451 MTYPE_PEER_UPDATE_SOURCE
);
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(&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(&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;
2635 /* Lookup the peer. */
2637 peer
= peer_lookup(bgp
, su
);
2639 /* The peer exist, bind it to the peer-group */
2641 /* When the peer already belongs to a peer-group, check the
2643 if (peer_group_active(peer
)) {
2645 /* The peer is already bound to the peer-group,
2648 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2651 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2654 /* The peer has not specified a remote-as, inherit it from the
2656 if (peer
->as_type
== AS_UNSPECIFIED
) {
2657 peer
->as_type
= group
->conf
->as_type
;
2658 peer
->as
= group
->conf
->as
;
2661 if (!group
->conf
->as
) {
2662 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2663 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2666 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2669 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2673 peer_group2peer_config_copy(group
, peer
);
2675 FOREACH_AFI_SAFI (afi
, safi
) {
2676 if (group
->conf
->afc
[afi
][safi
]) {
2677 peer
->afc
[afi
][safi
] = 1;
2679 if (peer_af_find(peer
, afi
, safi
)
2680 || peer_af_create(peer
, afi
, safi
)) {
2681 peer_group2peer_config_copy_af(
2682 group
, peer
, afi
, safi
);
2684 } else if (peer
->afc
[afi
][safi
])
2685 peer_deactivate(peer
, afi
, safi
);
2689 assert(group
&& peer
->group
== group
);
2691 listnode_delete(bgp
->peer
, peer
);
2693 peer
->group
= group
;
2694 listnode_add_sort(bgp
->peer
, peer
);
2696 peer
= peer_lock(peer
); /* group->peer list reference */
2697 listnode_add(group
->peer
, peer
);
2701 /* Advertisement-interval reset */
2702 if (!CHECK_FLAG(group
->conf
->flags
,
2703 PEER_FLAG_ROUTEADV
)) {
2704 group
->conf
->v_routeadv
=
2705 (peer_sort(group
->conf
)
2707 ? BGP_DEFAULT_IBGP_ROUTEADV
2708 : BGP_DEFAULT_EBGP_ROUTEADV
;
2711 /* ebgp-multihop reset */
2712 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2713 group
->conf
->ttl
= MAXTTL
;
2715 /* local-as reset */
2716 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2717 group
->conf
->change_local_as
= 0;
2718 peer_flag_unset(group
->conf
,
2719 PEER_FLAG_LOCAL_AS
);
2720 peer_flag_unset(group
->conf
,
2721 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2722 peer_flag_unset(group
->conf
,
2723 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2727 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2729 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2730 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2731 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2732 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2734 bgp_session_reset(peer
);
2738 /* Create a new peer. */
2740 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2741 && (!group
->conf
->as
)) {
2742 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2745 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2746 group
->conf
->as_type
, 0, 0, group
);
2748 peer
= peer_lock(peer
); /* group->peer list reference */
2749 listnode_add(group
->peer
, peer
);
2751 peer_group2peer_config_copy(group
, peer
);
2753 /* If the peer-group is active for this afi/safi then activate
2755 FOREACH_AFI_SAFI (afi
, safi
) {
2756 if (group
->conf
->afc
[afi
][safi
]) {
2757 peer
->afc
[afi
][safi
] = 1;
2758 peer_af_create(peer
, afi
, safi
);
2759 peer_group2peer_config_copy_af(group
, peer
, afi
,
2761 } else if (peer
->afc
[afi
][safi
])
2762 peer_deactivate(peer
, afi
, safi
);
2765 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2767 /* Set up peer's events and timers. */
2768 if (peer_active(peer
))
2769 bgp_timer_set(peer
);
2775 static int bgp_startup_timer_expire(struct thread
*thread
)
2779 bgp
= THREAD_ARG(thread
);
2780 bgp
->t_startup
= NULL
;
2786 * On shutdown we call the cleanup function which
2787 * does a free of the link list nodes, free up
2788 * the data we are pointing at too.
2790 static void bgp_vrf_string_name_delete(void *data
)
2794 XFREE(MTYPE_TMP
, vname
);
2797 /* BGP instance creation by `router bgp' commands. */
2798 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2799 enum bgp_instance_type inst_type
)
2805 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2808 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2809 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2810 zlog_debug("Creating Default VRF, AS %u", *as
);
2812 zlog_debug("Creating %s %s, AS %u",
2813 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2820 bgp
->heuristic_coalesce
= true;
2821 bgp
->inst_type
= inst_type
;
2822 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2824 bgp
->peer_self
= peer_new(bgp
);
2825 if (bgp
->peer_self
->host
)
2826 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2827 bgp
->peer_self
->host
=
2828 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2829 if (bgp
->peer_self
->hostname
!= NULL
) {
2830 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2831 bgp
->peer_self
->hostname
= NULL
;
2833 if (cmd_hostname_get())
2834 bgp
->peer_self
->hostname
=
2835 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2837 if (bgp
->peer_self
->domainname
!= NULL
) {
2838 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2839 bgp
->peer_self
->domainname
= NULL
;
2841 if (cmd_domainname_get())
2842 bgp
->peer_self
->domainname
=
2843 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2844 bgp
->peer
= list_new();
2845 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2846 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2848 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2850 bgp
->group
= list_new();
2851 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2853 FOREACH_AFI_SAFI (afi
, safi
) {
2854 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2855 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2856 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2858 /* Enable maximum-paths */
2859 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2861 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2865 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2866 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2867 bgp
->default_subgroup_pkt_queue_max
=
2868 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2869 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2870 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2871 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2872 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2873 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2874 bgp
->dynamic_neighbors_count
= 0;
2875 #if DFLT_BGP_IMPORT_CHECK
2876 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2878 #if DFLT_BGP_SHOW_HOSTNAME
2879 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2881 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2882 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2884 #if DFLT_BGP_DETERMINISTIC_MED
2885 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2887 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2892 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2893 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2895 assert(bgp
->rfapi_cfg
);
2897 #endif /* ENABLE_BGP_VNC */
2899 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2900 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2901 bgp
->vpn_policy
[afi
].afi
= afi
;
2902 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2903 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2906 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2907 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2908 bgp_vrf_string_name_delete
;
2909 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2910 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2911 bgp_vrf_string_name_delete
;
2914 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2916 /* TODO - The startup timer needs to be run for the whole of BGP
2918 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2919 bgp
->restart_time
, &bgp
->t_startup
);
2922 /* printable name we can use in debug messages */
2923 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2924 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2934 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2936 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2937 snprintf(bgp
->name_pretty
, len
, "%s %s",
2938 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2944 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2945 memory_order_relaxed
);
2946 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2947 memory_order_relaxed
);
2948 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2952 update_bgp_group_init(bgp
);
2954 /* assign a unique rd id for auto derivation of vrf's RD */
2955 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2957 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
2958 sizeof(struct bgp_evpn_info
));
2965 /* Return the "default VRF" instance of BGP. */
2966 struct bgp
*bgp_get_default(void)
2969 struct listnode
*node
, *nnode
;
2971 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2972 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2977 /* Lookup BGP entry. */
2978 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2981 struct listnode
*node
, *nnode
;
2983 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2985 && ((bgp
->name
== NULL
&& name
== NULL
)
2986 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2991 /* Lookup BGP structure by view name. */
2992 struct bgp
*bgp_lookup_by_name(const char *name
)
2995 struct listnode
*node
, *nnode
;
2997 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2998 if ((bgp
->name
== NULL
&& name
== NULL
)
2999 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3004 /* Lookup BGP instance based on VRF id. */
3005 /* Note: Only to be used for incoming messages from Zebra. */
3006 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3010 /* Lookup VRF (in tree) and follow link. */
3011 vrf
= vrf_lookup_by_id(vrf_id
);
3014 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3017 /* handle socket creation or deletion, if necessary
3018 * this is called for all new BGP instances
3020 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3025 /* Create BGP server socket, if listen mode not disabled */
3026 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3028 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3030 * suppress vrf socket
3032 if (create
== FALSE
) {
3033 bgp_close_vrf_socket(bgp
);
3037 return BGP_ERR_INVALID_VALUE
;
3039 * if vrf_id did not change
3041 if (vrf
->vrf_id
== old_vrf_id
)
3043 if (old_vrf_id
!= VRF_UNKNOWN
) {
3044 /* look for old socket. close it. */
3045 bgp_close_vrf_socket(bgp
);
3047 /* if backend is not yet identified ( VRF_UNKNOWN) then
3048 * creation will be done later
3050 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3052 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3054 return BGP_ERR_INVALID_VALUE
;
3057 return bgp_check_main_socket(create
, bgp
);
3060 /* Called from VTY commands. */
3061 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3062 enum bgp_instance_type inst_type
)
3065 struct vrf
*vrf
= NULL
;
3067 /* Multiple instance check. */
3068 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3070 bgp
= bgp_lookup_by_name(name
);
3072 bgp
= bgp_get_default();
3074 /* Already exists. */
3076 if (bgp
->as
!= *as
) {
3078 return BGP_ERR_INSTANCE_MISMATCH
;
3080 if (bgp
->inst_type
!= inst_type
)
3081 return BGP_ERR_INSTANCE_MISMATCH
;
3086 /* BGP instance name can not be specified for single instance.
3089 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3091 /* Get default BGP structure if exists. */
3092 bgp
= bgp_get_default();
3095 if (bgp
->as
!= *as
) {
3097 return BGP_ERR_AS_MISMATCH
;
3104 bgp
= bgp_create(as
, name
, inst_type
);
3105 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3106 bgp
->vrf_id
= vrf_generate_id();
3107 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3108 bgp_address_init(bgp
);
3109 bgp_tip_hash_init(bgp
);
3113 bgp
->t_rmap_def_originate_eval
= NULL
;
3115 /* If Default instance or VRF, link to the VRF structure, if present. */
3116 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3117 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3118 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3120 bgp_vrf_link(bgp
, vrf
);
3122 /* BGP server socket already processed if BGP instance
3123 * already part of the list
3125 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3126 listnode_add(bm
->bgp
, bgp
);
3128 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3129 if (BGP_DEBUG(zebra
, ZEBRA
))
3130 zlog_debug("%s: Registering BGP instance %s to zebra",
3131 __PRETTY_FUNCTION__
, name
);
3132 bgp_zebra_instance_register(bgp
);
3139 * Make BGP instance "up". Applies only to VRFs (non-default) and
3140 * implies the VRF has been learnt from Zebra.
3142 void bgp_instance_up(struct bgp
*bgp
)
3145 struct listnode
*node
, *next
;
3147 /* Register with zebra. */
3148 bgp_zebra_instance_register(bgp
);
3150 /* Kick off any peers that may have been configured. */
3151 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3152 if (!BGP_PEER_START_SUPPRESSED(peer
))
3153 BGP_EVENT_ADD(peer
, BGP_Start
);
3156 /* Process any networks that have been configured. */
3157 bgp_static_add(bgp
);
3161 * Make BGP instance "down". Applies only to VRFs (non-default) and
3162 * implies the VRF has been deleted by Zebra.
3164 void bgp_instance_down(struct bgp
*bgp
)
3167 struct listnode
*node
;
3168 struct listnode
*next
;
3171 if (bgp
->t_rmap_def_originate_eval
) {
3172 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3173 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3177 /* Bring down peers, so corresponding routes are purged. */
3178 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3179 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3180 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3181 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3183 bgp_session_reset(peer
);
3186 /* Purge network and redistributed routes. */
3187 bgp_purge_static_redist_routes(bgp
);
3189 /* Cleanup registered nexthops (flags) */
3190 bgp_cleanup_nexthops(bgp
);
3193 /* Delete BGP instance. */
3194 int bgp_delete(struct bgp
*bgp
)
3197 struct peer_group
*group
;
3198 struct listnode
*node
, *next
;
3204 THREAD_OFF(bgp
->t_startup
);
3205 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3206 THREAD_OFF(bgp
->t_update_delay
);
3207 THREAD_OFF(bgp
->t_establish_wait
);
3209 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3210 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3211 zlog_debug("Deleting Default VRF");
3213 zlog_debug("Deleting %s %s",
3214 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3220 /* unmap from RT list */
3221 bgp_evpn_vrf_delete(bgp
);
3224 if (bgp
->t_rmap_def_originate_eval
) {
3225 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3226 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3230 /* Inform peers we're going down. */
3231 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3232 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3233 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3234 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3237 /* Delete static routes (networks). */
3238 bgp_static_delete(bgp
);
3240 /* Unset redistribution. */
3241 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3242 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3243 if (i
!= ZEBRA_ROUTE_BGP
)
3244 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3246 /* Free peers and peer-groups. */
3247 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3248 peer_group_delete(group
);
3250 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3253 if (bgp
->peer_self
) {
3254 peer_delete(bgp
->peer_self
);
3255 bgp
->peer_self
= NULL
;
3258 update_bgp_group_free(bgp
);
3260 /* TODO - Other memory may need to be freed - e.g., NHT */
3265 bgp_cleanup_routes(bgp
);
3267 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3268 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3271 &bgp
->vpn_policy
[afi
]
3272 .import_redirect_rtlist
);
3273 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3276 /* Deregister from Zebra, if needed */
3277 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3278 if (BGP_DEBUG(zebra
, ZEBRA
))
3279 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3280 __PRETTY_FUNCTION__
, bgp
->name
);
3281 bgp_zebra_instance_deregister(bgp
);
3284 /* Remove visibility via the master list - there may however still be
3285 * routes to be processed still referencing the struct bgp.
3287 listnode_delete(bm
->bgp
, bgp
);
3289 /* Free interfaces in this instance. */
3292 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3293 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3295 bgp_vrf_unlink(bgp
, vrf
);
3297 thread_master_free_unused(bm
->master
);
3298 bgp_unlock(bgp
); /* initial reference */
3303 void bgp_free(struct bgp
*bgp
)
3307 struct bgp_table
*table
;
3308 struct bgp_node
*rn
;
3309 struct bgp_rmap
*rmap
;
3313 list_delete(&bgp
->group
);
3314 list_delete(&bgp
->peer
);
3316 if (bgp
->peerhash
) {
3317 hash_free(bgp
->peerhash
);
3318 bgp
->peerhash
= NULL
;
3321 FOREACH_AFI_SAFI (afi
, safi
) {
3322 /* Special handling for 2-level routing tables. */
3323 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3324 || safi
== SAFI_EVPN
) {
3325 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3326 rn
= bgp_route_next(rn
)) {
3327 table
= (struct bgp_table
*)rn
->info
;
3328 bgp_table_finish(&table
);
3331 if (bgp
->route
[afi
][safi
])
3332 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3333 if (bgp
->aggregate
[afi
][safi
])
3334 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3335 if (bgp
->rib
[afi
][safi
])
3336 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3337 rmap
= &bgp
->table_map
[afi
][safi
];
3339 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3342 bgp_scan_finish(bgp
);
3343 bgp_address_destroy(bgp
);
3344 bgp_tip_hash_destroy(bgp
);
3346 /* release the auto RD id */
3347 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3349 bgp_evpn_cleanup(bgp
);
3350 bgp_pbr_cleanup(bgp
);
3351 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3353 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3354 vpn_policy_direction_t dir
;
3356 if (bgp
->vpn_policy
[afi
].import_vrf
)
3357 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3358 if (bgp
->vpn_policy
[afi
].export_vrf
)
3359 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3361 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3362 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3363 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3364 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3365 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3366 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3370 XFREE(MTYPE_BGP
, bgp
->name
);
3371 if (bgp
->name_pretty
)
3372 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3374 XFREE(MTYPE_BGP
, bgp
);
3377 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3380 struct listnode
*node
, *nnode
;
3386 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3387 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3388 && !CHECK_FLAG(peer
->sflags
,
3389 PEER_STATUS_ACCEPT_PEER
))
3391 } else if (bm
->bgp
!= NULL
) {
3392 struct listnode
*bgpnode
, *nbgpnode
;
3394 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3395 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3397 && !strcmp(peer
->conf_if
, conf_if
)
3398 && !CHECK_FLAG(peer
->sflags
,
3399 PEER_STATUS_ACCEPT_PEER
))
3405 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3408 struct listnode
*node
, *nnode
;
3414 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3415 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3416 && !CHECK_FLAG(peer
->sflags
,
3417 PEER_STATUS_ACCEPT_PEER
))
3419 } else if (bm
->bgp
!= NULL
) {
3420 struct listnode
*bgpnode
, *nbgpnode
;
3422 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3423 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3425 && !strcmp(peer
->hostname
, hostname
)
3426 && !CHECK_FLAG(peer
->sflags
,
3427 PEER_STATUS_ACCEPT_PEER
))
3433 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3435 struct peer
*peer
= NULL
;
3436 struct peer tmp_peer
;
3438 memset(&tmp_peer
, 0, sizeof(struct peer
));
3441 * We do not want to find the doppelganger peer so search for the peer
3443 * the hash that has PEER_FLAG_CONFIG_NODE
3445 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3450 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3451 } else if (bm
->bgp
!= NULL
) {
3452 struct listnode
*bgpnode
, *nbgpnode
;
3454 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3455 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3464 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3465 union sockunion
*su
,
3466 struct peer_group
*group
)
3472 /* Create peer first; we've already checked group config is valid. */
3473 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3474 group
->conf
->as_type
, 0, 0, group
);
3479 peer
= peer_lock(peer
);
3480 listnode_add(group
->peer
, peer
);
3482 peer_group2peer_config_copy(group
, peer
);
3485 * Bind peer for all AFs configured for the group. We don't call
3486 * peer_group_bind as that is sub-optimal and does some stuff we don't
3489 FOREACH_AFI_SAFI (afi
, safi
) {
3490 if (!group
->conf
->afc
[afi
][safi
])
3492 peer
->afc
[afi
][safi
] = 1;
3494 if (!peer_af_find(peer
, afi
, safi
))
3495 peer_af_create(peer
, afi
, safi
);
3497 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3500 /* Mark as dynamic, but also as a "config node" for other things to
3502 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3503 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3509 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3510 struct prefix
*prefix
)
3512 struct listnode
*node
, *nnode
;
3513 struct prefix
*range
;
3516 afi
= family2afi(prefix
->family
);
3518 if (group
->listen_range
[afi
])
3519 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3521 if (prefix_match(range
, prefix
))
3528 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3529 struct prefix
**listen_range
)
3531 struct prefix
*range
= NULL
;
3532 struct peer_group
*group
= NULL
;
3533 struct listnode
*node
, *nnode
;
3535 *listen_range
= NULL
;
3537 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3538 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3541 } else if (bm
->bgp
!= NULL
) {
3542 struct listnode
*bgpnode
, *nbgpnode
;
3544 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3545 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3546 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3552 *listen_range
= range
;
3553 return (group
&& range
) ? group
: NULL
;
3556 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3558 struct peer_group
*group
;
3561 struct prefix prefix
;
3562 struct prefix
*listen_range
;
3564 char buf
[PREFIX2STR_BUFFER
];
3565 char buf1
[PREFIX2STR_BUFFER
];
3567 sockunion2hostprefix(su
, &prefix
);
3569 /* See if incoming connection matches a configured listen range. */
3570 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3581 prefix2str(&prefix
, buf
, sizeof(buf
));
3582 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3584 if (bgp_debug_neighbor_events(NULL
))
3586 "Dynamic Neighbor %s matches group %s listen range %s",
3587 buf
, group
->name
, buf1
);
3589 /* Are we within the listen limit? */
3590 dncount
= gbgp
->dynamic_neighbors_count
;
3592 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3593 if (bgp_debug_neighbor_events(NULL
))
3594 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3595 inet_sutop(su
, buf
),
3596 gbgp
->dynamic_neighbors_limit
);
3600 /* Ensure group is not disabled. */
3601 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3602 if (bgp_debug_neighbor_events(NULL
))
3604 "Dynamic Neighbor %s rejected - group %s disabled",
3609 /* Check that at least one AF is activated for the group. */
3610 if (!peer_group_af_configured(group
)) {
3611 if (bgp_debug_neighbor_events(NULL
))
3613 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3618 /* Create dynamic peer and bind to associated group. */
3619 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3622 gbgp
->dynamic_neighbors_count
= ++dncount
;
3624 if (bgp_debug_neighbor_events(peer
))
3625 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3626 peer
->host
, group
->name
, dncount
);
3631 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3634 if (peer
->group
->bgp
) {
3635 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3637 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3639 if (bgp_debug_neighbor_events(peer
))
3640 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3641 peer
->group
->name
, dncount
);
3644 /* If peer is configured at least one address family return 1. */
3645 int peer_active(struct peer
*peer
)
3647 if (BGP_PEER_SU_UNSPEC(peer
))
3649 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3650 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3651 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3652 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3653 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3654 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3655 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3656 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3657 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3658 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3659 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3664 /* If peer is negotiated at least one address family return 1. */
3665 int peer_active_nego(struct peer
*peer
)
3667 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3668 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3669 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3670 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3671 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3672 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3673 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3674 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3675 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3676 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3677 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3678 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3679 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3684 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3685 enum peer_change_type type
)
3687 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3690 if (peer
->status
!= Established
)
3693 if (type
== peer_change_reset
) {
3694 /* If we're resetting session, we've to delete both peer struct
3696 if ((peer
->doppelganger
)
3697 && (peer
->doppelganger
->status
!= Deleted
)
3698 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3699 PEER_FLAG_CONFIG_NODE
)))
3700 peer_delete(peer
->doppelganger
);
3702 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3703 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3704 } else if (type
== peer_change_reset_in
) {
3705 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3706 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3707 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3709 if ((peer
->doppelganger
)
3710 && (peer
->doppelganger
->status
!= Deleted
)
3711 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3712 PEER_FLAG_CONFIG_NODE
)))
3713 peer_delete(peer
->doppelganger
);
3715 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3716 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3718 } else if (type
== peer_change_reset_out
) {
3719 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3720 bgp_announce_route(peer
, afi
, safi
);
3724 struct peer_flag_action
{
3728 /* This flag can be set for peer-group member. */
3729 uint8_t not_for_member
;
3731 /* Action when the flag is changed. */
3732 enum peer_change_type type
;
3735 static const struct peer_flag_action peer_flag_action_list
[] = {
3736 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3737 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3738 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3739 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3740 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3741 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3742 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3743 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3744 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3745 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3746 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3747 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3748 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3749 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3750 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3751 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3752 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3755 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3756 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3757 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3758 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3759 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3760 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3761 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3762 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3763 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3764 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3765 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3766 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3767 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3768 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3769 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3770 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3771 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3772 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3773 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3774 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3775 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3776 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3777 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3778 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3779 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3780 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3783 /* Proper action set. */
3784 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3785 int size
, struct peer_flag_action
*action
,
3792 const struct peer_flag_action
*match
= NULL
;
3794 /* Check peer's frag action. */
3795 for (i
= 0; i
< size
; i
++) {
3796 match
= &action_list
[i
];
3798 if (match
->flag
== 0)
3801 if (match
->flag
& flag
) {
3804 if (match
->type
== peer_change_reset_in
)
3806 if (match
->type
== peer_change_reset_out
)
3808 if (match
->type
== peer_change_reset
) {
3812 if (match
->not_for_member
)
3813 action
->not_for_member
= 1;
3817 /* Set peer clear type. */
3818 if (reset_in
&& reset_out
)
3819 action
->type
= peer_change_reset
;
3821 action
->type
= peer_change_reset_in
;
3823 action
->type
= peer_change_reset_out
;
3825 action
->type
= peer_change_none
;
3830 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3832 if (flag
== PEER_FLAG_SHUTDOWN
) {
3833 if (CHECK_FLAG(peer
->flags
, flag
)) {
3834 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3835 peer_nsf_stop(peer
);
3837 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3838 if (peer
->t_pmax_restart
) {
3839 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3840 if (bgp_debug_neighbor_events(peer
))
3842 "%s Maximum-prefix restart timer canceled",
3846 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3847 peer_nsf_stop(peer
);
3849 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3850 char *msg
= peer
->tx_shutdown_message
;
3853 if (!msg
&& peer_group_active(peer
))
3854 msg
= peer
->group
->conf
3855 ->tx_shutdown_message
;
3856 msglen
= msg
? strlen(msg
) : 0;
3861 uint8_t msgbuf
[129];
3864 memcpy(msgbuf
+ 1, msg
, msglen
);
3866 bgp_notify_send_with_data(
3867 peer
, BGP_NOTIFY_CEASE
,
3868 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3869 msgbuf
, msglen
+ 1);
3872 peer
, BGP_NOTIFY_CEASE
,
3873 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3875 bgp_session_reset(peer
);
3877 peer
->v_start
= BGP_INIT_START_TIMER
;
3878 BGP_EVENT_ADD(peer
, BGP_Stop
);
3880 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3881 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3882 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3883 else if (flag
== PEER_FLAG_PASSIVE
)
3884 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3885 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3886 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3888 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3889 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3891 bgp_session_reset(peer
);
3894 /* Change specified peer flag. */
3895 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3899 bool invert
, member_invert
;
3900 struct peer
*member
;
3901 struct listnode
*node
, *nnode
;
3902 struct peer_flag_action action
;
3904 memset(&action
, 0, sizeof(struct peer_flag_action
));
3905 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3907 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3908 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3911 /* Abort if no flag action exists. */
3913 return BGP_ERR_INVALID_FLAG
;
3915 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3916 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3917 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3918 return BGP_ERR_PEER_FLAG_CONFLICT
;
3920 /* Handle flag updates where desired state matches current state. */
3921 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3922 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3923 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3927 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3928 COND_FLAG(peer
->flags_override
, flag
, invert
);
3933 /* Inherit from peer-group or set/unset flags accordingly. */
3934 if (peer_group_active(peer
) && set
== invert
)
3935 peer_flag_inherit(peer
, flag
);
3937 COND_FLAG(peer
->flags
, flag
, set
);
3939 /* Check if handling a regular peer. */
3940 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3941 /* Update flag override state accordingly. */
3942 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3944 /* Execute flag action on peer. */
3945 if (action
.type
== peer_change_reset
)
3946 peer_flag_modify_action(peer
, flag
);
3948 /* Skip peer-group mechanics for regular peers. */
3952 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3953 bgp_nht_register_enhe_capability_interfaces(peer
);
3956 * Update peer-group members, unless they are explicitely overriding
3957 * peer-group configuration.
3959 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3960 /* Skip peers with overridden configuration. */
3961 if (CHECK_FLAG(member
->flags_override
, flag
))
3964 /* Check if only member without group is inverted. */
3966 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3968 /* Skip peers with equivalent configuration. */
3969 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3972 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3975 /* Update flag on peer-group member. */
3976 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3978 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3979 bgp_nht_register_enhe_capability_interfaces(member
);
3981 /* Execute flag action on peer-group member. */
3982 if (action
.type
== peer_change_reset
)
3983 peer_flag_modify_action(member
, flag
);
3989 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3991 return peer_flag_modify(peer
, flag
, 1);
3994 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3996 return peer_flag_modify(peer
, flag
, 0);
3999 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4000 uint32_t flag
, bool set
)
4004 bool invert
, member_invert
;
4005 struct peer
*member
;
4006 struct listnode
*node
, *nnode
;
4007 struct peer_flag_action action
;
4009 memset(&action
, 0, sizeof(struct peer_flag_action
));
4010 size
= sizeof peer_af_flag_action_list
4011 / sizeof(struct peer_flag_action
);
4013 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4014 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4017 /* Abort if flag action exists. */
4019 return BGP_ERR_INVALID_FLAG
;
4021 /* Special check for reflector client. */
4022 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4023 && peer_sort(peer
) != BGP_PEER_IBGP
)
4024 return BGP_ERR_NOT_INTERNAL_PEER
;
4026 /* Special check for remove-private-AS. */
4027 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4028 && peer_sort(peer
) == BGP_PEER_IBGP
)
4029 return BGP_ERR_REMOVE_PRIVATE_AS
;
4031 /* as-override is not allowed for IBGP peers */
4032 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4033 return BGP_ERR_AS_OVERRIDE
;
4035 /* Handle flag updates where desired state matches current state. */
4036 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4037 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4038 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4043 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4044 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4051 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4052 * if we are setting/unsetting flags which conflict with this flag
4053 * handle accordingly
4055 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4059 * if we are setting NEXTHOP_SELF, we need to unset the
4060 * NEXTHOP_UNCHANGED flag
4062 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4063 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4064 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4065 PEER_FLAG_NEXTHOP_UNCHANGED
);
4069 * if we are unsetting NEXTHOP_SELF, we need to set the
4070 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4072 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4073 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4074 SET_FLAG(peer
->af_flags
[afi
][safi
],
4075 PEER_FLAG_NEXTHOP_UNCHANGED
);
4079 /* Inherit from peer-group or set/unset flags accordingly. */
4080 if (peer_group_active(peer
) && set
== invert
)
4081 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4083 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4085 /* Execute action when peer is established. */
4086 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4087 && peer
->status
== Established
) {
4088 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4089 bgp_clear_adj_in(peer
, afi
, safi
);
4091 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4092 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4093 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4094 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4095 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4096 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4097 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4098 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4100 peer_change_action(peer
, afi
, safi
, action
.type
);
4104 /* Check if handling a regular peer. */
4105 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4106 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4110 * Update peer-group members, unless they are explicitely
4111 * overriding peer-group configuration.
4113 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4115 /* Skip peers with overridden configuration. */
4116 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4120 /* Check if only member without group is inverted. */
4122 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4126 /* Skip peers with equivalent configuration. */
4127 if (set
!= member_invert
4128 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4131 if (set
== member_invert
4132 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4135 /* Update flag on peer-group member. */
4136 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4137 set
!= member_invert
);
4139 /* Execute flag action on peer-group member. */
4140 if (member
->status
== Established
) {
4141 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4142 bgp_clear_adj_in(member
, afi
, safi
);
4144 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4145 member
->last_reset
=
4146 PEER_DOWN_RR_CLIENT_CHANGE
;
4148 == PEER_FLAG_RSERVER_CLIENT
)
4149 member
->last_reset
=
4150 PEER_DOWN_RS_CLIENT_CHANGE
;
4152 == PEER_FLAG_ORF_PREFIX_SM
)
4153 member
->last_reset
=
4154 PEER_DOWN_CAPABILITY_CHANGE
;
4156 == PEER_FLAG_ORF_PREFIX_RM
)
4157 member
->last_reset
=
4158 PEER_DOWN_CAPABILITY_CHANGE
;
4160 peer_change_action(member
, afi
, safi
,
4170 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4172 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4175 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4177 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4181 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4183 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4184 peer
->tx_shutdown_message
=
4185 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4189 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4191 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4196 /* EBGP multihop configuration. */
4197 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4199 struct peer_group
*group
;
4200 struct listnode
*node
, *nnode
;
4203 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4206 /* see comment in peer_ttl_security_hops_set() */
4207 if (ttl
!= MAXTTL
) {
4208 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4209 group
= peer
->group
;
4210 if (group
->conf
->gtsm_hops
!= 0)
4211 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4213 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4215 if (peer1
->sort
== BGP_PEER_IBGP
)
4218 if (peer1
->gtsm_hops
!= 0)
4219 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4222 if (peer
->gtsm_hops
!= 0)
4223 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4229 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4230 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4231 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4233 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4235 bgp_session_reset(peer
);
4238 group
= peer
->group
;
4239 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4240 if (peer
->sort
== BGP_PEER_IBGP
)
4243 peer
->ttl
= group
->conf
->ttl
;
4245 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4246 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4247 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4249 bgp_session_reset(peer
);
4255 int peer_ebgp_multihop_unset(struct peer
*peer
)
4257 struct peer_group
*group
;
4258 struct listnode
*node
, *nnode
;
4260 if (peer
->sort
== BGP_PEER_IBGP
)
4263 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4264 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4266 if (peer_group_active(peer
))
4267 peer
->ttl
= peer
->group
->conf
->ttl
;
4271 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4272 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4273 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4274 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4276 bgp_session_reset(peer
);
4278 group
= peer
->group
;
4279 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4280 if (peer
->sort
== BGP_PEER_IBGP
)
4285 if (peer
->fd
>= 0) {
4286 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4288 peer
, BGP_NOTIFY_CEASE
,
4289 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4291 bgp_session_reset(peer
);
4298 /* Neighbor description. */
4299 int peer_description_set(struct peer
*peer
, const char *desc
)
4302 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4304 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4309 int peer_description_unset(struct peer
*peer
)
4312 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4319 /* Neighbor update-source. */
4320 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4322 struct peer
*member
;
4323 struct listnode
*node
, *nnode
;
4325 /* Set flag and configuration on peer. */
4326 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4327 if (peer
->update_if
) {
4328 if (strcmp(peer
->update_if
, ifname
) == 0)
4330 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4332 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4333 sockunion_free(peer
->update_source
);
4334 peer
->update_source
= NULL
;
4336 /* Check if handling a regular peer. */
4337 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4338 /* Send notification or reset peer depending on state. */
4339 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4340 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4341 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4342 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4344 bgp_session_reset(peer
);
4346 /* Skip peer-group mechanics for regular peers. */
4351 * Set flag and configuration on all peer-group members, unless they are
4352 * explicitely overriding peer-group configuration.
4354 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4355 /* Skip peers with overridden configuration. */
4356 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4359 /* Skip peers with the same configuration. */
4360 if (member
->update_if
) {
4361 if (strcmp(member
->update_if
, ifname
) == 0)
4363 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4366 /* Set flag and configuration on peer-group member. */
4367 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4368 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4369 sockunion_free(member
->update_source
);
4370 member
->update_source
= NULL
;
4372 /* Send notification or reset peer depending on state. */
4373 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4374 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4375 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4376 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4378 bgp_session_reset(member
);
4384 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4386 struct peer
*member
;
4387 struct listnode
*node
, *nnode
;
4389 /* Set flag and configuration on peer. */
4390 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4391 if (peer
->update_source
) {
4392 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4394 sockunion_free(peer
->update_source
);
4396 peer
->update_source
= sockunion_dup(su
);
4397 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4399 /* Check if handling a regular peer. */
4400 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4401 /* Send notification or reset peer depending on state. */
4402 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4403 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4404 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4405 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4407 bgp_session_reset(peer
);
4409 /* Skip peer-group mechanics for regular peers. */
4414 * Set flag and configuration on all peer-group members, unless they are
4415 * explicitely overriding peer-group configuration.
4417 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4418 /* Skip peers with overridden configuration. */
4419 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4422 /* Skip peers with the same configuration. */
4423 if (member
->update_source
) {
4424 if (sockunion_cmp(member
->update_source
, su
) == 0)
4426 sockunion_free(member
->update_source
);
4429 /* Set flag and configuration on peer-group member. */
4430 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4431 member
->update_source
= sockunion_dup(su
);
4432 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4434 /* Send notification or reset peer depending on state. */
4435 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4436 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4437 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4438 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4440 bgp_session_reset(member
);
4446 int peer_update_source_unset(struct peer
*peer
)
4448 struct peer
*member
;
4449 struct listnode
*node
, *nnode
;
4451 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4454 /* Inherit configuration from peer-group if peer is member. */
4455 if (peer_group_active(peer
)) {
4456 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4457 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4458 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4459 MTYPE_PEER_UPDATE_SOURCE
);
4461 /* Otherwise remove flag and configuration from peer. */
4462 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4463 sockunion_free(peer
->update_source
);
4464 peer
->update_source
= NULL
;
4465 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4468 /* Check if handling a regular peer. */
4469 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4470 /* Send notification or reset peer depending on state. */
4471 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4472 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4473 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4474 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4476 bgp_session_reset(peer
);
4478 /* Skip peer-group mechanics for regular peers. */
4483 * Set flag and configuration on all peer-group members, unless they are
4484 * explicitely overriding peer-group configuration.
4486 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4487 /* Skip peers with overridden configuration. */
4488 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4491 /* Skip peers with the same configuration. */
4492 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4493 && !member
->update_source
&& !member
->update_if
)
4496 /* Remove flag and configuration on peer-group member. */
4497 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4498 sockunion_free(member
->update_source
);
4499 member
->update_source
= NULL
;
4500 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4502 /* Send notification or reset peer depending on state. */
4503 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4504 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4505 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4506 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4508 bgp_session_reset(member
);
4514 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4515 const char *rmap
, struct route_map
*route_map
)
4517 struct peer
*member
;
4518 struct listnode
*node
, *nnode
;
4520 /* Set flag and configuration on peer. */
4521 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4523 if (!peer
->default_rmap
[afi
][safi
].name
4524 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4525 if (peer
->default_rmap
[afi
][safi
].name
)
4526 XFREE(MTYPE_ROUTE_MAP_NAME
,
4527 peer
->default_rmap
[afi
][safi
].name
);
4529 peer
->default_rmap
[afi
][safi
].name
=
4530 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4531 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4534 if (peer
->default_rmap
[afi
][safi
].name
)
4535 XFREE(MTYPE_ROUTE_MAP_NAME
,
4536 peer
->default_rmap
[afi
][safi
].name
);
4538 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4539 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4542 /* Check if handling a regular peer. */
4543 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4544 /* Update peer route announcements. */
4545 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4546 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4547 bgp_default_originate(peer
, afi
, safi
, 0);
4548 bgp_announce_route(peer
, afi
, safi
);
4551 /* Skip peer-group mechanics for regular peers. */
4556 * Set flag and configuration on all peer-group members, unless they are
4557 * explicitely overriding peer-group configuration.
4559 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4560 /* Skip peers with overridden configuration. */
4561 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4562 PEER_FLAG_DEFAULT_ORIGINATE
))
4565 /* Set flag and configuration on peer-group member. */
4566 SET_FLAG(member
->af_flags
[afi
][safi
],
4567 PEER_FLAG_DEFAULT_ORIGINATE
);
4569 if (member
->default_rmap
[afi
][safi
].name
)
4570 XFREE(MTYPE_ROUTE_MAP_NAME
,
4571 member
->default_rmap
[afi
][safi
].name
);
4573 member
->default_rmap
[afi
][safi
].name
=
4574 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4575 member
->default_rmap
[afi
][safi
].map
= route_map
;
4578 /* Update peer route announcements. */
4579 if (member
->status
== Established
4580 && member
->afc_nego
[afi
][safi
]) {
4581 update_group_adjust_peer(
4582 peer_af_find(member
, afi
, safi
));
4583 bgp_default_originate(member
, afi
, safi
, 0);
4584 bgp_announce_route(member
, afi
, safi
);
4591 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4593 struct peer
*member
;
4594 struct listnode
*node
, *nnode
;
4596 /* Inherit configuration from peer-group if peer is member. */
4597 if (peer_group_active(peer
)) {
4598 peer_af_flag_inherit(peer
, afi
, safi
,
4599 PEER_FLAG_DEFAULT_ORIGINATE
);
4600 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4601 default_rmap
[afi
][safi
].name
,
4602 MTYPE_ROUTE_MAP_NAME
);
4603 PEER_ATTR_INHERIT(peer
, peer
->group
,
4604 default_rmap
[afi
][safi
].map
);
4606 /* Otherwise remove flag and configuration from peer. */
4607 peer_af_flag_unset(peer
, afi
, safi
,
4608 PEER_FLAG_DEFAULT_ORIGINATE
);
4609 if (peer
->default_rmap
[afi
][safi
].name
)
4610 XFREE(MTYPE_ROUTE_MAP_NAME
,
4611 peer
->default_rmap
[afi
][safi
].name
);
4612 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4613 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4616 /* Check if handling a regular peer. */
4617 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4618 /* Update peer route announcements. */
4619 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4620 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4621 bgp_default_originate(peer
, afi
, safi
, 1);
4622 bgp_announce_route(peer
, afi
, safi
);
4625 /* Skip peer-group mechanics for regular peers. */
4630 * Remove flag and configuration from all peer-group members, unless
4631 * they are explicitely overriding peer-group configuration.
4633 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4634 /* Skip peers with overridden configuration. */
4635 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4636 PEER_FLAG_DEFAULT_ORIGINATE
))
4639 /* Remove flag and configuration on peer-group member. */
4640 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4641 PEER_FLAG_DEFAULT_ORIGINATE
);
4642 if (peer
->default_rmap
[afi
][safi
].name
)
4643 XFREE(MTYPE_ROUTE_MAP_NAME
,
4644 peer
->default_rmap
[afi
][safi
].name
);
4645 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4646 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4648 /* Update peer route announcements. */
4649 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4650 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4651 bgp_default_originate(peer
, afi
, safi
, 1);
4652 bgp_announce_route(peer
, afi
, safi
);
4659 int peer_port_set(struct peer
*peer
, uint16_t port
)
4665 int peer_port_unset(struct peer
*peer
)
4667 peer
->port
= BGP_PORT_DEFAULT
;
4672 * Helper function that is called after the name of the policy
4673 * being used by a peer has changed (AF specific). Automatically
4674 * initiates inbound or outbound processing as needed.
4676 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4680 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4681 if (peer
->status
== Established
)
4682 bgp_announce_route(peer
, afi
, safi
);
4684 if (peer
->status
!= Established
)
4687 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4688 PEER_FLAG_SOFT_RECONFIG
))
4689 bgp_soft_reconfig_in(peer
, afi
, safi
);
4690 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4691 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4692 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4697 /* neighbor weight. */
4698 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4700 struct peer
*member
;
4701 struct listnode
*node
, *nnode
;
4703 /* Set flag and configuration on peer. */
4704 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4705 if (peer
->weight
[afi
][safi
] != weight
) {
4706 peer
->weight
[afi
][safi
] = weight
;
4707 peer_on_policy_change(peer
, afi
, safi
, 0);
4710 /* Skip peer-group mechanics for regular peers. */
4711 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4715 * Set flag and configuration on all peer-group members, unless they are
4716 * explicitely overriding peer-group configuration.
4718 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4719 /* Skip peers with overridden configuration. */
4720 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4724 /* Set flag and configuration on peer-group member. */
4725 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4726 if (member
->weight
[afi
][safi
] != weight
) {
4727 member
->weight
[afi
][safi
] = weight
;
4728 peer_on_policy_change(member
, afi
, safi
, 0);
4735 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4737 struct peer
*member
;
4738 struct listnode
*node
, *nnode
;
4740 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4743 /* Inherit configuration from peer-group if peer is member. */
4744 if (peer_group_active(peer
)) {
4745 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4746 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4748 peer_on_policy_change(peer
, afi
, safi
, 0);
4752 /* Remove flag and configuration from peer. */
4753 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4754 peer
->weight
[afi
][safi
] = 0;
4755 peer_on_policy_change(peer
, afi
, safi
, 0);
4757 /* Skip peer-group mechanics for regular peers. */
4758 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4762 * Remove flag and configuration from all peer-group members, unless
4763 * they are explicitely overriding peer-group configuration.
4765 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4766 /* Skip peers with overridden configuration. */
4767 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4771 /* Skip peers where flag is already disabled. */
4772 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4775 /* Remove flag and configuration on peer-group member. */
4776 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4777 member
->weight
[afi
][safi
] = 0;
4778 peer_on_policy_change(member
, afi
, safi
, 0);
4784 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4786 struct peer
*member
;
4787 struct listnode
*node
, *nnode
;
4789 if (keepalive
> 65535)
4790 return BGP_ERR_INVALID_VALUE
;
4792 if (holdtime
> 65535)
4793 return BGP_ERR_INVALID_VALUE
;
4795 if (holdtime
< 3 && holdtime
!= 0)
4796 return BGP_ERR_INVALID_VALUE
;
4798 /* Set flag and configuration on peer. */
4799 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4800 peer
->holdtime
= holdtime
;
4801 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4803 /* Skip peer-group mechanics for regular peers. */
4804 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4808 * Set flag and configuration on all peer-group members, unless they are
4809 * explicitely overriding peer-group configuration.
4811 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4812 /* Skip peers with overridden configuration. */
4813 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4816 /* Set flag and configuration on peer-group member. */
4817 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4818 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4819 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4825 int peer_timers_unset(struct peer
*peer
)
4827 struct peer
*member
;
4828 struct listnode
*node
, *nnode
;
4830 /* Inherit configuration from peer-group if peer is member. */
4831 if (peer_group_active(peer
)) {
4832 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4833 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4834 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4836 /* Otherwise remove flag and configuration from peer. */
4837 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4839 peer
->keepalive
= 0;
4842 /* Skip peer-group mechanics for regular peers. */
4843 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4847 * Remove flag and configuration from all peer-group members, unless
4848 * they are explicitely overriding peer-group configuration.
4850 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4851 /* Skip peers with overridden configuration. */
4852 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4855 /* Remove flag and configuration on peer-group member. */
4856 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4857 member
->holdtime
= 0;
4858 member
->keepalive
= 0;
4864 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4866 struct peer
*member
;
4867 struct listnode
*node
, *nnode
;
4869 if (connect
> 65535)
4870 return BGP_ERR_INVALID_VALUE
;
4872 /* Set flag and configuration on peer. */
4873 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4874 peer
->connect
= connect
;
4875 peer
->v_connect
= connect
;
4877 /* Skip peer-group mechanics for regular peers. */
4878 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4882 * Set flag and configuration on all peer-group members, unless they are
4883 * explicitely overriding peer-group configuration.
4885 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4886 /* Skip peers with overridden configuration. */
4887 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4890 /* Set flag and configuration on peer-group member. */
4891 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4892 member
->connect
= connect
;
4893 member
->v_connect
= connect
;
4899 int peer_timers_connect_unset(struct peer
*peer
)
4901 struct peer
*member
;
4902 struct listnode
*node
, *nnode
;
4904 /* Inherit configuration from peer-group if peer is member. */
4905 if (peer_group_active(peer
)) {
4906 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4907 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4909 /* Otherwise remove flag and configuration from peer. */
4910 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4914 /* Set timer with fallback to default value. */
4916 peer
->v_connect
= peer
->connect
;
4918 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4920 /* Skip peer-group mechanics for regular peers. */
4921 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4925 * Remove flag and configuration from all peer-group members, unless
4926 * they are explicitely overriding peer-group configuration.
4928 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4929 /* Skip peers with overridden configuration. */
4930 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4933 /* Remove flag and configuration on peer-group member. */
4934 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4935 member
->connect
= 0;
4936 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4942 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4944 struct peer
*member
;
4945 struct listnode
*node
, *nnode
;
4948 return BGP_ERR_INVALID_VALUE
;
4950 /* Set flag and configuration on peer. */
4951 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4952 peer
->routeadv
= routeadv
;
4953 peer
->v_routeadv
= routeadv
;
4955 /* Check if handling a regular peer. */
4956 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4957 /* Update peer route announcements. */
4958 update_group_adjust_peer_afs(peer
);
4959 if (peer
->status
== Established
)
4960 bgp_announce_route_all(peer
);
4962 /* Skip peer-group mechanics for regular peers. */
4967 * Set flag and configuration on all peer-group members, unless they are
4968 * explicitely overriding peer-group configuration.
4970 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4971 /* Skip peers with overridden configuration. */
4972 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4975 /* Set flag and configuration on peer-group member. */
4976 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4977 member
->routeadv
= routeadv
;
4978 member
->v_routeadv
= routeadv
;
4980 /* Update peer route announcements. */
4981 update_group_adjust_peer_afs(member
);
4982 if (member
->status
== Established
)
4983 bgp_announce_route_all(member
);
4989 int peer_advertise_interval_unset(struct peer
*peer
)
4991 struct peer
*member
;
4992 struct listnode
*node
, *nnode
;
4994 /* Inherit configuration from peer-group if peer is member. */
4995 if (peer_group_active(peer
)) {
4996 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4997 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4999 /* Otherwise remove flag and configuration from peer. */
5000 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5004 /* Set timer with fallback to default value. */
5006 peer
->v_routeadv
= peer
->routeadv
;
5008 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5009 ? BGP_DEFAULT_IBGP_ROUTEADV
5010 : BGP_DEFAULT_EBGP_ROUTEADV
;
5012 /* Check if handling a regular peer. */
5013 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5014 /* Update peer route announcements. */
5015 update_group_adjust_peer_afs(peer
);
5016 if (peer
->status
== Established
)
5017 bgp_announce_route_all(peer
);
5019 /* Skip peer-group mechanics for regular peers. */
5024 * Remove flag and configuration from all peer-group members, unless
5025 * they are explicitely overriding peer-group configuration.
5027 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5028 /* Skip peers with overridden configuration. */
5029 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5032 /* Remove flag and configuration on peer-group member. */
5033 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5034 member
->routeadv
= 0;
5035 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5036 ? BGP_DEFAULT_IBGP_ROUTEADV
5037 : BGP_DEFAULT_EBGP_ROUTEADV
;
5039 /* Update peer route announcements. */
5040 update_group_adjust_peer_afs(member
);
5041 if (member
->status
== Established
)
5042 bgp_announce_route_all(member
);
5048 /* neighbor interface */
5049 void peer_interface_set(struct peer
*peer
, const char *str
)
5052 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5053 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5056 void peer_interface_unset(struct peer
*peer
)
5059 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5060 peer
->ifname
= NULL
;
5064 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5065 int allow_num
, int origin
)
5067 struct peer
*member
;
5068 struct listnode
*node
, *nnode
;
5070 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5071 return BGP_ERR_INVALID_VALUE
;
5073 /* Set flag and configuration on peer. */
5074 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5076 if (peer
->allowas_in
[afi
][safi
] != 0
5077 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5078 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5079 peer_af_flag_set(peer
, afi
, safi
,
5080 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5081 peer
->allowas_in
[afi
][safi
] = 0;
5082 peer_on_policy_change(peer
, afi
, safi
, 0);
5085 if (peer
->allowas_in
[afi
][safi
] != allow_num
5086 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5087 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5089 peer_af_flag_unset(peer
, afi
, safi
,
5090 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5091 peer
->allowas_in
[afi
][safi
] = allow_num
;
5092 peer_on_policy_change(peer
, afi
, safi
, 0);
5096 /* Skip peer-group mechanics for regular peers. */
5097 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5101 * Set flag and configuration on all peer-group members, unless
5102 * they are explicitely overriding peer-group configuration.
5104 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5105 /* Skip peers with overridden configuration. */
5106 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5107 PEER_FLAG_ALLOWAS_IN
))
5110 /* Set flag and configuration on peer-group member. */
5111 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5113 if (member
->allowas_in
[afi
][safi
] != 0
5114 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5115 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5116 SET_FLAG(member
->af_flags
[afi
][safi
],
5117 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5118 member
->allowas_in
[afi
][safi
] = 0;
5119 peer_on_policy_change(peer
, afi
, safi
, 0);
5122 if (member
->allowas_in
[afi
][safi
] != allow_num
5123 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5124 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5125 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5126 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5127 member
->allowas_in
[afi
][safi
] = allow_num
;
5128 peer_on_policy_change(peer
, afi
, safi
, 0);
5136 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5138 struct peer
*member
;
5139 struct listnode
*node
, *nnode
;
5141 /* Skip peer if flag is already disabled. */
5142 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5145 /* Inherit configuration from peer-group if peer is member. */
5146 if (peer_group_active(peer
)) {
5147 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5148 peer_af_flag_inherit(peer
, afi
, safi
,
5149 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5150 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5151 peer_on_policy_change(peer
, afi
, safi
, 0);
5156 /* Remove flag and configuration from peer. */
5157 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5158 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5159 peer
->allowas_in
[afi
][safi
] = 0;
5160 peer_on_policy_change(peer
, afi
, safi
, 0);
5162 /* Skip peer-group mechanics if handling a regular peer. */
5163 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5167 * Remove flags and configuration from all peer-group members, unless
5168 * they are explicitely overriding peer-group configuration.
5170 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5171 /* Skip peers with overridden configuration. */
5172 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5173 PEER_FLAG_ALLOWAS_IN
))
5176 /* Skip peers where flag is already disabled. */
5177 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5178 PEER_FLAG_ALLOWAS_IN
))
5181 /* Remove flags and configuration on peer-group member. */
5182 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5183 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5184 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5185 member
->allowas_in
[afi
][safi
] = 0;
5186 peer_on_policy_change(member
, afi
, safi
, 0);
5192 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5195 bool old_no_prepend
, old_replace_as
;
5196 struct bgp
*bgp
= peer
->bgp
;
5197 struct peer
*member
;
5198 struct listnode
*node
, *nnode
;
5200 if (peer_sort(peer
) != BGP_PEER_EBGP
5201 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5202 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5205 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5208 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5210 /* Save previous flag states. */
5212 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5214 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5216 /* Set flag and configuration on peer. */
5217 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5218 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5219 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5221 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5222 && old_replace_as
== replace_as
)
5224 peer
->change_local_as
= as
;
5226 /* Check if handling a regular peer. */
5227 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5228 /* Send notification or reset peer depending on state. */
5229 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5230 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5231 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5232 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5234 bgp_session_reset(peer
);
5236 /* Skip peer-group mechanics for regular peers. */
5241 * Set flag and configuration on all peer-group members, unless they are
5242 * explicitely overriding peer-group configuration.
5244 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5245 /* Skip peers with overridden configuration. */
5246 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5249 /* Skip peers with the same configuration. */
5250 old_no_prepend
= CHECK_FLAG(member
->flags
,
5251 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5252 old_replace_as
= CHECK_FLAG(member
->flags
,
5253 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5254 if (member
->change_local_as
== as
5255 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5256 && old_no_prepend
== no_prepend
5257 && old_replace_as
== replace_as
)
5260 /* Set flag and configuration on peer-group member. */
5261 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5262 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5264 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5266 member
->change_local_as
= as
;
5268 /* Send notification or stop peer depending on state. */
5269 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5270 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5271 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5272 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5274 BGP_EVENT_ADD(member
, BGP_Stop
);
5280 int peer_local_as_unset(struct peer
*peer
)
5282 struct peer
*member
;
5283 struct listnode
*node
, *nnode
;
5285 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5288 /* Inherit configuration from peer-group if peer is member. */
5289 if (peer_group_active(peer
)) {
5290 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5291 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5292 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5293 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5295 /* Otherwise remove flag and configuration from peer. */
5296 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5297 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5298 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5299 peer
->change_local_as
= 0;
5302 /* Check if handling a regular peer. */
5303 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5304 /* Send notification or stop peer depending on state. */
5305 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5306 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5307 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5308 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5310 BGP_EVENT_ADD(peer
, BGP_Stop
);
5312 /* Skip peer-group mechanics for regular peers. */
5317 * Remove flag and configuration from all peer-group members, unless
5318 * they are explicitely overriding peer-group configuration.
5320 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5321 /* Skip peers with overridden configuration. */
5322 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5325 /* Remove flag and configuration on peer-group member. */
5326 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5327 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5328 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5329 member
->change_local_as
= 0;
5331 /* Send notification or stop peer depending on state. */
5332 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5333 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5334 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5335 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5337 bgp_session_reset(member
);
5343 /* Set password for authenticating with the peer. */
5344 int peer_password_set(struct peer
*peer
, const char *password
)
5346 struct peer
*member
;
5347 struct listnode
*node
, *nnode
;
5348 int len
= password
? strlen(password
) : 0;
5349 int ret
= BGP_SUCCESS
;
5351 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5352 return BGP_ERR_INVALID_VALUE
;
5354 /* Set flag and configuration on peer. */
5355 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5356 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5358 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5359 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5361 /* Check if handling a regular peer. */
5362 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5363 /* Send notification or reset peer depending on state. */
5364 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5365 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5366 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5368 bgp_session_reset(peer
);
5371 * Attempt to install password on socket and skip peer-group
5374 if (BGP_PEER_SU_UNSPEC(peer
))
5376 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5377 : BGP_ERR_TCPSIG_FAILED
;
5381 * Set flag and configuration on all peer-group members, unless they are
5382 * explicitely overriding peer-group configuration.
5384 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5385 /* Skip peers with overridden configuration. */
5386 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5389 /* Skip peers with the same password. */
5390 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5393 /* Set flag and configuration on peer-group member. */
5394 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5395 if (member
->password
)
5396 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5397 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5399 /* Send notification or reset peer depending on state. */
5400 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5401 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5402 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5404 bgp_session_reset(member
);
5406 /* Attempt to install password on socket. */
5407 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5408 ret
= BGP_ERR_TCPSIG_FAILED
;
5414 int peer_password_unset(struct peer
*peer
)
5416 struct peer
*member
;
5417 struct listnode
*node
, *nnode
;
5419 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5422 /* Inherit configuration from peer-group if peer is member. */
5423 if (peer_group_active(peer
)) {
5424 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5425 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5426 MTYPE_PEER_PASSWORD
);
5428 /* Otherwise remove flag and configuration from peer. */
5429 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5430 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5433 /* Check if handling a regular peer. */
5434 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5435 /* Send notification or reset peer depending on state. */
5436 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5437 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5438 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5440 bgp_session_reset(peer
);
5442 /* Attempt to uninstall password on socket. */
5443 if (!BGP_PEER_SU_UNSPEC(peer
))
5444 bgp_md5_unset(peer
);
5446 /* Skip peer-group mechanics for regular peers. */
5451 * Remove flag and configuration from all peer-group members, unless
5452 * they are explicitely overriding peer-group configuration.
5454 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5455 /* Skip peers with overridden configuration. */
5456 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5459 /* Remove flag and configuration on peer-group member. */
5460 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5461 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5463 /* Send notification or reset peer depending on state. */
5464 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5465 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5466 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5468 bgp_session_reset(member
);
5470 /* Attempt to uninstall password on socket. */
5471 if (!BGP_PEER_SU_UNSPEC(member
))
5472 bgp_md5_unset(member
);
5479 /* Set distribute list to the peer. */
5480 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5483 struct peer
*member
;
5484 struct bgp_filter
*filter
;
5485 struct listnode
*node
, *nnode
;
5487 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5488 return BGP_ERR_INVALID_VALUE
;
5490 /* Set configuration on peer. */
5491 filter
= &peer
->filter
[afi
][safi
];
5492 if (filter
->plist
[direct
].name
)
5493 return BGP_ERR_PEER_FILTER_CONFLICT
;
5494 if (filter
->dlist
[direct
].name
)
5495 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5496 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5497 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5499 /* Check if handling a regular peer. */
5500 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5501 /* Set override-flag and process peer route updates. */
5502 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5503 PEER_FT_DISTRIBUTE_LIST
);
5504 peer_on_policy_change(peer
, afi
, safi
,
5505 (direct
== FILTER_OUT
) ? 1 : 0);
5507 /* Skip peer-group mechanics for regular peers. */
5512 * Set configuration on all peer-group members, un less they are
5513 * explicitely overriding peer-group configuration.
5515 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5516 /* Skip peers with overridden configuration. */
5517 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5518 PEER_FT_DISTRIBUTE_LIST
))
5521 /* Set configuration on peer-group member. */
5522 filter
= &member
->filter
[afi
][safi
];
5523 if (filter
->dlist
[direct
].name
)
5524 XFREE(MTYPE_BGP_FILTER_NAME
,
5525 filter
->dlist
[direct
].name
);
5526 filter
->dlist
[direct
].name
=
5527 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5528 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5530 /* Process peer route updates. */
5531 peer_on_policy_change(member
, afi
, safi
,
5532 (direct
== FILTER_OUT
) ? 1 : 0);
5538 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5540 struct peer
*member
;
5541 struct bgp_filter
*filter
;
5542 struct listnode
*node
, *nnode
;
5544 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5545 return BGP_ERR_INVALID_VALUE
;
5547 /* Unset override-flag unconditionally. */
5548 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5549 PEER_FT_DISTRIBUTE_LIST
);
5551 /* Inherit configuration from peer-group if peer is member. */
5552 if (peer_group_active(peer
)) {
5553 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5554 filter
[afi
][safi
].dlist
[direct
].name
,
5555 MTYPE_BGP_FILTER_NAME
);
5556 PEER_ATTR_INHERIT(peer
, peer
->group
,
5557 filter
[afi
][safi
].dlist
[direct
].alist
);
5559 /* Otherwise remove configuration from peer. */
5560 filter
= &peer
->filter
[afi
][safi
];
5561 if (filter
->dlist
[direct
].name
)
5562 XFREE(MTYPE_BGP_FILTER_NAME
,
5563 filter
->dlist
[direct
].name
);
5564 filter
->dlist
[direct
].name
= NULL
;
5565 filter
->dlist
[direct
].alist
= NULL
;
5568 /* Check if handling a regular peer. */
5569 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5570 /* Process peer route updates. */
5571 peer_on_policy_change(peer
, afi
, safi
,
5572 (direct
== FILTER_OUT
) ? 1 : 0);
5574 /* Skip peer-group mechanics for regular peers. */
5579 * Remove configuration on all peer-group members, unless they are
5580 * explicitely overriding peer-group configuration.
5582 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5583 /* Skip peers with overridden configuration. */
5584 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5585 PEER_FT_DISTRIBUTE_LIST
))
5588 /* Remove configuration on peer-group member. */
5589 filter
= &member
->filter
[afi
][safi
];
5590 if (filter
->dlist
[direct
].name
)
5591 XFREE(MTYPE_BGP_FILTER_NAME
,
5592 filter
->dlist
[direct
].name
);
5593 filter
->dlist
[direct
].name
= NULL
;
5594 filter
->dlist
[direct
].alist
= NULL
;
5596 /* Process peer route updates. */
5597 peer_on_policy_change(member
, afi
, safi
,
5598 (direct
== FILTER_OUT
) ? 1 : 0);
5604 /* Update distribute list. */
5605 static void peer_distribute_update(struct access_list
*access
)
5610 struct listnode
*mnode
, *mnnode
;
5611 struct listnode
*node
, *nnode
;
5614 struct peer_group
*group
;
5615 struct bgp_filter
*filter
;
5617 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5619 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5620 access
->name
, 0, 0);
5621 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5622 FOREACH_AFI_SAFI (afi
, safi
) {
5623 filter
= &peer
->filter
[afi
][safi
];
5625 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5627 if (filter
->dlist
[direct
].name
)
5628 filter
->dlist
[direct
]
5629 .alist
= access_list_lookup(
5631 filter
->dlist
[direct
]
5634 filter
->dlist
[direct
].alist
=
5639 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5640 FOREACH_AFI_SAFI (afi
, safi
) {
5641 filter
= &group
->conf
->filter
[afi
][safi
];
5643 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5645 if (filter
->dlist
[direct
].name
)
5646 filter
->dlist
[direct
]
5647 .alist
= access_list_lookup(
5649 filter
->dlist
[direct
]
5652 filter
->dlist
[direct
].alist
=
5658 vnc_prefix_list_update(bgp
);
5663 /* Set prefix list to the peer. */
5664 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5667 struct peer
*member
;
5668 struct bgp_filter
*filter
;
5669 struct listnode
*node
, *nnode
;
5671 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5672 return BGP_ERR_INVALID_VALUE
;
5674 /* Set configuration on peer. */
5675 filter
= &peer
->filter
[afi
][safi
];
5676 if (filter
->dlist
[direct
].name
)
5677 return BGP_ERR_PEER_FILTER_CONFLICT
;
5678 if (filter
->plist
[direct
].name
)
5679 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5680 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5681 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5683 /* Check if handling a regular peer. */
5684 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5685 /* Set override-flag and process peer route updates. */
5686 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5687 PEER_FT_PREFIX_LIST
);
5688 peer_on_policy_change(peer
, afi
, safi
,
5689 (direct
== FILTER_OUT
) ? 1 : 0);
5691 /* Skip peer-group mechanics for regular peers. */
5696 * Set configuration on all peer-group members, unless they are
5697 * explicitely overriding peer-group configuration.
5699 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5700 /* Skip peers with overridden configuration. */
5701 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5702 PEER_FT_PREFIX_LIST
))
5705 /* Set configuration on peer-group member. */
5706 filter
= &member
->filter
[afi
][safi
];
5707 if (filter
->plist
[direct
].name
)
5708 XFREE(MTYPE_BGP_FILTER_NAME
,
5709 filter
->plist
[direct
].name
);
5710 filter
->plist
[direct
].name
=
5711 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5712 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5714 /* Process peer route updates. */
5715 peer_on_policy_change(member
, afi
, safi
,
5716 (direct
== FILTER_OUT
) ? 1 : 0);
5722 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5725 struct peer
*member
;
5726 struct bgp_filter
*filter
;
5727 struct listnode
*node
, *nnode
;
5729 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5730 return BGP_ERR_INVALID_VALUE
;
5732 /* Unset override-flag unconditionally. */
5733 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5734 PEER_FT_PREFIX_LIST
);
5736 /* Inherit configuration from peer-group if peer is member. */
5737 if (peer_group_active(peer
)) {
5738 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5739 filter
[afi
][safi
].plist
[direct
].name
,
5740 MTYPE_BGP_FILTER_NAME
);
5741 PEER_ATTR_INHERIT(peer
, peer
->group
,
5742 filter
[afi
][safi
].plist
[direct
].plist
);
5744 /* Otherwise remove configuration from peer. */
5745 filter
= &peer
->filter
[afi
][safi
];
5746 if (filter
->plist
[direct
].name
)
5747 XFREE(MTYPE_BGP_FILTER_NAME
,
5748 filter
->plist
[direct
].name
);
5749 filter
->plist
[direct
].name
= NULL
;
5750 filter
->plist
[direct
].plist
= NULL
;
5753 /* Check if handling a regular peer. */
5754 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5755 /* Process peer route updates. */
5756 peer_on_policy_change(peer
, afi
, safi
,
5757 (direct
== FILTER_OUT
) ? 1 : 0);
5759 /* Skip peer-group mechanics for regular peers. */
5764 * Remove configuration on all peer-group members, unless they are
5765 * explicitely overriding peer-group configuration.
5767 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5768 /* Skip peers with overridden configuration. */
5769 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5770 PEER_FT_PREFIX_LIST
))
5773 /* Remove configuration on peer-group member. */
5774 filter
= &member
->filter
[afi
][safi
];
5775 if (filter
->plist
[direct
].name
)
5776 XFREE(MTYPE_BGP_FILTER_NAME
,
5777 filter
->plist
[direct
].name
);
5778 filter
->plist
[direct
].name
= NULL
;
5779 filter
->plist
[direct
].plist
= NULL
;
5781 /* Process peer route updates. */
5782 peer_on_policy_change(member
, afi
, safi
,
5783 (direct
== FILTER_OUT
) ? 1 : 0);
5789 /* Update prefix-list list. */
5790 static void peer_prefix_list_update(struct prefix_list
*plist
)
5792 struct listnode
*mnode
, *mnnode
;
5793 struct listnode
*node
, *nnode
;
5796 struct peer_group
*group
;
5797 struct bgp_filter
*filter
;
5802 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5805 * Update the prefix-list on update groups.
5807 update_group_policy_update(
5808 bgp
, BGP_POLICY_PREFIX_LIST
,
5809 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5811 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5812 FOREACH_AFI_SAFI (afi
, safi
) {
5813 filter
= &peer
->filter
[afi
][safi
];
5815 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5817 if (filter
->plist
[direct
].name
)
5818 filter
->plist
[direct
]
5819 .plist
= prefix_list_lookup(
5821 filter
->plist
[direct
]
5824 filter
->plist
[direct
].plist
=
5829 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5830 FOREACH_AFI_SAFI (afi
, safi
) {
5831 filter
= &group
->conf
->filter
[afi
][safi
];
5833 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5835 if (filter
->plist
[direct
].name
)
5836 filter
->plist
[direct
]
5837 .plist
= prefix_list_lookup(
5839 filter
->plist
[direct
]
5842 filter
->plist
[direct
].plist
=
5850 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5853 struct peer
*member
;
5854 struct bgp_filter
*filter
;
5855 struct listnode
*node
, *nnode
;
5857 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5858 return BGP_ERR_INVALID_VALUE
;
5860 /* Set configuration on peer. */
5861 filter
= &peer
->filter
[afi
][safi
];
5862 if (filter
->aslist
[direct
].name
)
5863 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5864 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5865 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5867 /* Check if handling a regular peer. */
5868 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5869 /* Set override-flag and process peer route updates. */
5870 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5871 PEER_FT_FILTER_LIST
);
5872 peer_on_policy_change(peer
, afi
, safi
,
5873 (direct
== FILTER_OUT
) ? 1 : 0);
5875 /* Skip peer-group mechanics for regular peers. */
5880 * Set configuration on all peer-group members, unless they are
5881 * explicitely overriding peer-group configuration.
5883 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5884 /* Skip peers with overridden configuration. */
5885 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5886 PEER_FT_FILTER_LIST
))
5889 /* Set configuration on peer-group member. */
5890 filter
= &member
->filter
[afi
][safi
];
5891 if (filter
->aslist
[direct
].name
)
5892 XFREE(MTYPE_BGP_FILTER_NAME
,
5893 filter
->aslist
[direct
].name
);
5894 filter
->aslist
[direct
].name
=
5895 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5896 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5898 /* Process peer route updates. */
5899 peer_on_policy_change(member
, afi
, safi
,
5900 (direct
== FILTER_OUT
) ? 1 : 0);
5906 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5908 struct peer
*member
;
5909 struct bgp_filter
*filter
;
5910 struct listnode
*node
, *nnode
;
5912 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5913 return BGP_ERR_INVALID_VALUE
;
5915 /* Unset override-flag unconditionally. */
5916 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5917 PEER_FT_FILTER_LIST
);
5919 /* Inherit configuration from peer-group if peer is member. */
5920 if (peer_group_active(peer
)) {
5921 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5922 filter
[afi
][safi
].aslist
[direct
].name
,
5923 MTYPE_BGP_FILTER_NAME
);
5924 PEER_ATTR_INHERIT(peer
, peer
->group
,
5925 filter
[afi
][safi
].aslist
[direct
].aslist
);
5927 /* Otherwise remove configuration from peer. */
5928 filter
= &peer
->filter
[afi
][safi
];
5929 if (filter
->aslist
[direct
].name
)
5930 XFREE(MTYPE_BGP_FILTER_NAME
,
5931 filter
->aslist
[direct
].name
);
5932 filter
->aslist
[direct
].name
= NULL
;
5933 filter
->aslist
[direct
].aslist
= NULL
;
5936 /* Check if handling a regular peer. */
5937 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5938 /* Process peer route updates. */
5939 peer_on_policy_change(peer
, afi
, safi
,
5940 (direct
== FILTER_OUT
) ? 1 : 0);
5942 /* Skip peer-group mechanics for regular peers. */
5947 * Remove configuration on all peer-group members, unless they are
5948 * explicitely overriding peer-group configuration.
5950 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5951 /* Skip peers with overridden configuration. */
5952 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5953 PEER_FT_FILTER_LIST
))
5956 /* Remove configuration on peer-group member. */
5957 filter
= &member
->filter
[afi
][safi
];
5958 if (filter
->aslist
[direct
].name
)
5959 XFREE(MTYPE_BGP_FILTER_NAME
,
5960 filter
->aslist
[direct
].name
);
5961 filter
->aslist
[direct
].name
= NULL
;
5962 filter
->aslist
[direct
].aslist
= NULL
;
5964 /* Process peer route updates. */
5965 peer_on_policy_change(member
, afi
, safi
,
5966 (direct
== FILTER_OUT
) ? 1 : 0);
5972 static void peer_aslist_update(const char *aslist_name
)
5977 struct listnode
*mnode
, *mnnode
;
5978 struct listnode
*node
, *nnode
;
5981 struct peer_group
*group
;
5982 struct bgp_filter
*filter
;
5984 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5985 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5988 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5989 FOREACH_AFI_SAFI (afi
, safi
) {
5990 filter
= &peer
->filter
[afi
][safi
];
5992 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5994 if (filter
->aslist
[direct
].name
)
5995 filter
->aslist
[direct
]
5996 .aslist
= as_list_lookup(
5997 filter
->aslist
[direct
]
6000 filter
->aslist
[direct
].aslist
=
6005 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6006 FOREACH_AFI_SAFI (afi
, safi
) {
6007 filter
= &group
->conf
->filter
[afi
][safi
];
6009 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6011 if (filter
->aslist
[direct
].name
)
6012 filter
->aslist
[direct
]
6013 .aslist
= as_list_lookup(
6014 filter
->aslist
[direct
]
6017 filter
->aslist
[direct
].aslist
=
6025 static void peer_aslist_add(char *aslist_name
)
6027 peer_aslist_update(aslist_name
);
6028 route_map_notify_dependencies((char *)aslist_name
,
6029 RMAP_EVENT_ASLIST_ADDED
);
6032 static void peer_aslist_del(const char *aslist_name
)
6034 peer_aslist_update(aslist_name
);
6035 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6039 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6040 const char *name
, struct route_map
*route_map
)
6042 struct peer
*member
;
6043 struct bgp_filter
*filter
;
6044 struct listnode
*node
, *nnode
;
6046 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6047 return BGP_ERR_INVALID_VALUE
;
6049 /* Set configuration on peer. */
6050 filter
= &peer
->filter
[afi
][safi
];
6051 if (filter
->map
[direct
].name
)
6052 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6053 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6054 filter
->map
[direct
].map
= route_map
;
6056 /* Check if handling a regular peer. */
6057 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6058 /* Set override-flag and process peer route updates. */
6059 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6061 peer_on_policy_change(peer
, afi
, safi
,
6062 (direct
== RMAP_OUT
) ? 1 : 0);
6064 /* Skip peer-group mechanics for regular peers. */
6069 * Set configuration on all peer-group members, unless they are
6070 * explicitely overriding peer-group configuration.
6072 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6073 /* Skip peers with overridden configuration. */
6074 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6078 /* Set configuration on peer-group member. */
6079 filter
= &member
->filter
[afi
][safi
];
6080 if (filter
->map
[direct
].name
)
6081 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6082 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6083 filter
->map
[direct
].map
= route_map
;
6085 /* Process peer route updates. */
6086 peer_on_policy_change(member
, afi
, safi
,
6087 (direct
== RMAP_OUT
) ? 1 : 0);
6092 /* Unset route-map from the peer. */
6093 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6095 struct peer
*member
;
6096 struct bgp_filter
*filter
;
6097 struct listnode
*node
, *nnode
;
6099 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6100 return BGP_ERR_INVALID_VALUE
;
6102 /* Unset override-flag unconditionally. */
6103 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6105 /* Inherit configuration from peer-group if peer is member. */
6106 if (peer_group_active(peer
)) {
6107 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6108 filter
[afi
][safi
].map
[direct
].name
,
6109 MTYPE_BGP_FILTER_NAME
);
6110 PEER_ATTR_INHERIT(peer
, peer
->group
,
6111 filter
[afi
][safi
].map
[direct
].map
);
6113 /* Otherwise remove configuration from peer. */
6114 filter
= &peer
->filter
[afi
][safi
];
6115 if (filter
->map
[direct
].name
)
6116 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6117 filter
->map
[direct
].name
= NULL
;
6118 filter
->map
[direct
].map
= NULL
;
6121 /* Check if handling a regular peer. */
6122 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6123 /* Process peer route updates. */
6124 peer_on_policy_change(peer
, afi
, safi
,
6125 (direct
== RMAP_OUT
) ? 1 : 0);
6127 /* Skip peer-group mechanics for regular peers. */
6132 * Remove configuration on all peer-group members, unless they are
6133 * explicitely overriding peer-group configuration.
6135 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6136 /* Skip peers with overridden configuration. */
6137 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6141 /* Remove configuration on peer-group member. */
6142 filter
= &member
->filter
[afi
][safi
];
6143 if (filter
->map
[direct
].name
)
6144 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6145 filter
->map
[direct
].name
= NULL
;
6146 filter
->map
[direct
].map
= NULL
;
6148 /* Process peer route updates. */
6149 peer_on_policy_change(member
, afi
, safi
,
6150 (direct
== RMAP_OUT
) ? 1 : 0);
6156 /* Set unsuppress-map to the peer. */
6157 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6158 const char *name
, struct route_map
*route_map
)
6160 struct peer
*member
;
6161 struct bgp_filter
*filter
;
6162 struct listnode
*node
, *nnode
;
6164 /* Set configuration on peer. */
6165 filter
= &peer
->filter
[afi
][safi
];
6166 if (filter
->usmap
.name
)
6167 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6168 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6169 filter
->usmap
.map
= route_map
;
6171 /* Check if handling a regular peer. */
6172 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6173 /* Set override-flag and process peer route updates. */
6174 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6175 PEER_FT_UNSUPPRESS_MAP
);
6176 peer_on_policy_change(peer
, afi
, safi
, 1);
6178 /* Skip peer-group mechanics for regular peers. */
6183 * Set configuration on all peer-group members, unless they are
6184 * explicitely overriding peer-group configuration.
6186 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6187 /* Skip peers with overridden configuration. */
6188 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6189 PEER_FT_UNSUPPRESS_MAP
))
6192 /* Set configuration on peer-group member. */
6193 filter
= &member
->filter
[afi
][safi
];
6194 if (filter
->usmap
.name
)
6195 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6196 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6197 filter
->usmap
.map
= route_map
;
6199 /* Process peer route updates. */
6200 peer_on_policy_change(member
, afi
, safi
, 1);
6206 /* Unset route-map from the peer. */
6207 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6209 struct peer
*member
;
6210 struct bgp_filter
*filter
;
6211 struct listnode
*node
, *nnode
;
6213 /* Unset override-flag unconditionally. */
6214 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6216 /* Inherit configuration from peer-group if peer is member. */
6217 if (peer_group_active(peer
)) {
6218 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6219 filter
[afi
][safi
].usmap
.name
,
6220 MTYPE_BGP_FILTER_NAME
);
6221 PEER_ATTR_INHERIT(peer
, peer
->group
,
6222 filter
[afi
][safi
].usmap
.map
);
6224 /* Otherwise remove configuration from peer. */
6225 filter
= &peer
->filter
[afi
][safi
];
6226 if (filter
->usmap
.name
)
6227 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6228 filter
->usmap
.name
= NULL
;
6229 filter
->usmap
.map
= NULL
;
6232 /* Check if handling a regular peer. */
6233 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6234 /* Process peer route updates. */
6235 peer_on_policy_change(peer
, afi
, safi
, 1);
6237 /* Skip peer-group mechanics for regular peers. */
6242 * Remove configuration on all peer-group members, unless they are
6243 * explicitely overriding peer-group configuration.
6245 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6246 /* Skip peers with overridden configuration. */
6247 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6248 PEER_FT_UNSUPPRESS_MAP
))
6251 /* Remove configuration on peer-group member. */
6252 filter
= &member
->filter
[afi
][safi
];
6253 if (filter
->usmap
.name
)
6254 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6255 filter
->usmap
.name
= NULL
;
6256 filter
->usmap
.map
= NULL
;
6258 /* Process peer route updates. */
6259 peer_on_policy_change(member
, afi
, safi
, 1);
6265 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6266 uint32_t max
, uint8_t threshold
, int warning
,
6269 struct peer
*member
;
6270 struct listnode
*node
, *nnode
;
6272 /* Set flags and configuration on peer. */
6273 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6275 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6277 peer_af_flag_unset(peer
, afi
, safi
,
6278 PEER_FLAG_MAX_PREFIX_WARNING
);
6280 peer
->pmax
[afi
][safi
] = max
;
6281 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6282 peer
->pmax_restart
[afi
][safi
] = restart
;
6284 /* Check if handling a regular peer. */
6285 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6286 /* Re-check if peer violates maximum-prefix. */
6287 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6288 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6290 /* Skip peer-group mechanics for regular peers. */
6295 * Set flags and configuration on all peer-group members, unless they
6296 * are explicitely overriding peer-group configuration.
6298 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6299 /* Skip peers with overridden configuration. */
6300 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6301 PEER_FLAG_MAX_PREFIX
))
6304 /* Set flag and configuration on peer-group member. */
6305 member
->pmax
[afi
][safi
] = max
;
6306 member
->pmax_threshold
[afi
][safi
] = threshold
;
6307 member
->pmax_restart
[afi
][safi
] = restart
;
6309 SET_FLAG(member
->af_flags
[afi
][safi
],
6310 PEER_FLAG_MAX_PREFIX_WARNING
);
6312 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6313 PEER_FLAG_MAX_PREFIX_WARNING
);
6315 /* Re-check if peer violates maximum-prefix. */
6316 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6317 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6323 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6325 /* Inherit configuration from peer-group if peer is member. */
6326 if (peer_group_active(peer
)) {
6327 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6328 peer_af_flag_inherit(peer
, afi
, safi
,
6329 PEER_FLAG_MAX_PREFIX_WARNING
);
6330 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6331 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6332 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6337 /* Remove flags and configuration from peer. */
6338 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6339 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6340 peer
->pmax
[afi
][safi
] = 0;
6341 peer
->pmax_threshold
[afi
][safi
] = 0;
6342 peer
->pmax_restart
[afi
][safi
] = 0;
6345 * Remove flags and configuration from all peer-group members, unless
6346 * they are explicitely overriding peer-group configuration.
6348 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6349 struct peer
*member
;
6350 struct listnode
*node
;
6352 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6353 /* Skip peers with overridden configuration. */
6354 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6355 PEER_FLAG_MAX_PREFIX
))
6358 /* Remove flag and configuration on peer-group member.
6360 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6361 PEER_FLAG_MAX_PREFIX
);
6362 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6363 PEER_FLAG_MAX_PREFIX_WARNING
);
6364 member
->pmax
[afi
][safi
] = 0;
6365 member
->pmax_threshold
[afi
][safi
] = 0;
6366 member
->pmax_restart
[afi
][safi
] = 0;
6373 int is_ebgp_multihop_configured(struct peer
*peer
)
6375 struct peer_group
*group
;
6376 struct listnode
*node
, *nnode
;
6379 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6380 group
= peer
->group
;
6381 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6382 && (group
->conf
->ttl
!= 1))
6385 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6386 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6387 && (peer1
->ttl
!= 1))
6391 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6397 /* Set # of hops between us and BGP peer. */
6398 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6400 struct peer_group
*group
;
6401 struct listnode
*node
, *nnode
;
6404 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6405 gtsm_hops
, peer
->host
);
6407 /* We cannot configure ttl-security hops when ebgp-multihop is already
6408 set. For non peer-groups, the check is simple. For peer-groups,
6410 slightly messy, because we need to check both the peer-group
6412 and all peer-group members for any trace of ebgp-multihop
6414 before actually applying the ttl-security rules. Cisco really made a
6415 mess of this configuration parameter, and OpenBGPD got it right.
6418 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6419 if (is_ebgp_multihop_configured(peer
))
6420 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6422 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6423 peer
->gtsm_hops
= gtsm_hops
;
6425 /* Calling ebgp multihop also resets the session.
6426 * On restart, NHT will get setup correctly as will the
6427 * min & max ttls on the socket. The return value is
6430 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6435 group
= peer
->group
;
6436 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6438 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6440 /* Calling ebgp multihop also resets the
6442 * On restart, NHT will get setup correctly as
6444 * min & max ttls on the socket. The return
6448 peer_ebgp_multihop_set(peer
, MAXTTL
);
6452 /* Post the first gtsm setup or if its ibgp, maxttl setting
6454 * necessary, just set the minttl.
6456 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6457 peer
->gtsm_hops
= gtsm_hops
;
6460 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6461 MAXTTL
+ 1 - gtsm_hops
);
6462 if ((peer
->status
< Established
) && peer
->doppelganger
6463 && (peer
->doppelganger
->fd
>= 0))
6464 sockopt_minttl(peer
->su
.sa
.sa_family
,
6465 peer
->doppelganger
->fd
,
6466 MAXTTL
+ 1 - gtsm_hops
);
6468 group
= peer
->group
;
6469 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6471 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6473 /* Change setting of existing peer
6474 * established then change value (may break
6476 * not established yet (teardown session and
6478 * no session then do nothing (will get
6479 * handled by next connection)
6481 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6483 peer
->su
.sa
.sa_family
, peer
->fd
,
6484 MAXTTL
+ 1 - peer
->gtsm_hops
);
6485 if ((peer
->status
< Established
)
6486 && peer
->doppelganger
6487 && (peer
->doppelganger
->fd
>= 0))
6488 sockopt_minttl(peer
->su
.sa
.sa_family
,
6489 peer
->doppelganger
->fd
,
6490 MAXTTL
+ 1 - gtsm_hops
);
6498 int peer_ttl_security_hops_unset(struct peer
*peer
)
6500 struct peer_group
*group
;
6501 struct listnode
*node
, *nnode
;
6504 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6507 /* if a peer-group member, then reset to peer-group default rather than
6509 if (peer_group_active(peer
))
6510 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6512 peer
->gtsm_hops
= 0;
6514 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6515 /* Invoking ebgp_multihop_set will set the TTL back to the
6517 * value as well as restting the NHT and such. The session is
6520 if (peer
->sort
== BGP_PEER_EBGP
)
6521 ret
= peer_ebgp_multihop_unset(peer
);
6524 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6527 if ((peer
->status
< Established
) && peer
->doppelganger
6528 && (peer
->doppelganger
->fd
>= 0))
6529 sockopt_minttl(peer
->su
.sa
.sa_family
,
6530 peer
->doppelganger
->fd
, 0);
6533 group
= peer
->group
;
6534 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6535 peer
->gtsm_hops
= 0;
6536 if (peer
->sort
== BGP_PEER_EBGP
)
6537 ret
= peer_ebgp_multihop_unset(peer
);
6540 sockopt_minttl(peer
->su
.sa
.sa_family
,
6543 if ((peer
->status
< Established
)
6544 && peer
->doppelganger
6545 && (peer
->doppelganger
->fd
>= 0))
6546 sockopt_minttl(peer
->su
.sa
.sa_family
,
6547 peer
->doppelganger
->fd
,
6557 * If peer clear is invoked in a loop for all peers on the BGP instance,
6558 * it may end up freeing the doppelganger, and if this was the next node
6559 * to the current node, we would end up accessing the freed next node.
6560 * Pass along additional parameter which can be updated if next node
6561 * is freed; only required when walking the peer list on BGP instance.
6563 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6565 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6566 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6567 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6568 if (peer
->t_pmax_restart
) {
6569 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6570 if (bgp_debug_neighbor_events(peer
))
6572 "%s Maximum-prefix restart timer canceled",
6575 BGP_EVENT_ADD(peer
, BGP_Start
);
6579 peer
->v_start
= BGP_INIT_START_TIMER
;
6580 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6581 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6582 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6584 bgp_session_reset_safe(peer
, nnode
);
6589 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6590 enum bgp_clear_type stype
)
6592 struct peer_af
*paf
;
6594 if (peer
->status
!= Established
)
6597 if (!peer
->afc
[afi
][safi
])
6598 return BGP_ERR_AF_UNCONFIGURED
;
6600 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6602 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6603 /* Clear the "neighbor x.x.x.x default-originate" flag */
6604 paf
= peer_af_find(peer
, afi
, safi
);
6605 if (paf
&& paf
->subgroup
6606 && CHECK_FLAG(paf
->subgroup
->sflags
,
6607 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6608 UNSET_FLAG(paf
->subgroup
->sflags
,
6609 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6611 bgp_announce_route(peer
, afi
, safi
);
6614 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6615 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6616 PEER_CAP_ORF_PREFIX_SM_ADV
)
6617 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6618 PEER_CAP_ORF_PREFIX_RM_RCV
)
6619 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6620 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6621 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6622 uint8_t prefix_type
;
6624 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6625 PEER_CAP_ORF_PREFIX_RM_RCV
))
6626 prefix_type
= ORF_TYPE_PREFIX
;
6628 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6630 if (filter
->plist
[FILTER_IN
].plist
) {
6631 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6632 PEER_STATUS_ORF_PREFIX_SEND
))
6633 bgp_route_refresh_send(
6634 peer
, afi
, safi
, prefix_type
,
6636 bgp_route_refresh_send(peer
, afi
, safi
,
6638 REFRESH_IMMEDIATE
, 0);
6640 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6641 PEER_STATUS_ORF_PREFIX_SEND
))
6642 bgp_route_refresh_send(
6643 peer
, afi
, safi
, prefix_type
,
6644 REFRESH_IMMEDIATE
, 1);
6646 bgp_route_refresh_send(peer
, afi
, safi
,
6653 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6654 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6655 /* If neighbor has soft reconfiguration inbound flag.
6656 Use Adj-RIB-In database. */
6657 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6658 PEER_FLAG_SOFT_RECONFIG
))
6659 bgp_soft_reconfig_in(peer
, afi
, safi
);
6661 /* If neighbor has route refresh capability, send route
6663 message to the peer. */
6664 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6665 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6666 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6669 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6675 /* Display peer uptime.*/
6676 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6679 time_t uptime1
, epoch_tbuf
;
6682 /* If there is no connection has been done before print `never'. */
6685 json_object_string_add(json
, "peerUptime", "never");
6686 json_object_int_add(json
, "peerUptimeMsec", 0);
6688 snprintf(buf
, len
, "never");
6692 /* Get current time. */
6693 uptime1
= bgp_clock();
6695 tm
= gmtime(&uptime1
);
6697 if (uptime1
< ONE_DAY_SECOND
)
6698 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6700 else if (uptime1
< ONE_WEEK_SECOND
)
6701 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6703 else if (uptime1
< ONE_YEAR_SECOND
)
6704 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6705 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6707 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6709 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6712 epoch_tbuf
= time(NULL
) - uptime1
;
6713 json_object_string_add(json
, "peerUptime", buf
);
6714 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6715 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6722 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6723 afi_t afi
, safi_t safi
)
6725 struct bgp_filter
*filter
;
6729 filter
= &peer
->filter
[afi
][safi
];
6731 /* distribute-list. */
6732 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6734 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6735 filter
->dlist
[FILTER_IN
].name
);
6737 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6739 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6740 filter
->dlist
[FILTER_OUT
].name
);
6743 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6745 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6746 filter
->plist
[FILTER_IN
].name
);
6748 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6750 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6751 filter
->plist
[FILTER_OUT
].name
);
6754 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6755 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6756 filter
->map
[RMAP_IN
].name
);
6758 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6760 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6761 filter
->map
[RMAP_OUT
].name
);
6763 /* unsuppress-map */
6764 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6765 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6766 filter
->usmap
.name
);
6769 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6771 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6772 filter
->aslist
[FILTER_IN
].name
);
6774 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6776 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6777 filter
->aslist
[FILTER_OUT
].name
);
6780 /* BGP peer configuration display function. */
6781 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6784 struct peer
*g_peer
= NULL
;
6785 char buf
[SU_ADDRSTRLEN
];
6787 int if_pg_printed
= FALSE
;
6788 int if_ras_printed
= FALSE
;
6790 /* Skip dynamic neighbors. */
6791 if (peer_dynamic_neighbor(peer
))
6795 addr
= peer
->conf_if
;
6799 /************************************
6800 ****** Global to the neighbor ******
6801 ************************************/
6802 if (peer
->conf_if
) {
6803 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6804 vty_out(vty
, " neighbor %s interface v6only", addr
);
6806 vty_out(vty
, " neighbor %s interface", addr
);
6808 if (peer_group_active(peer
)) {
6809 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6810 if_pg_printed
= TRUE
;
6811 } else if (peer
->as_type
== AS_SPECIFIED
) {
6812 vty_out(vty
, " remote-as %u", peer
->as
);
6813 if_ras_printed
= TRUE
;
6814 } else if (peer
->as_type
== AS_INTERNAL
) {
6815 vty_out(vty
, " remote-as internal");
6816 if_ras_printed
= TRUE
;
6817 } else if (peer
->as_type
== AS_EXTERNAL
) {
6818 vty_out(vty
, " remote-as external");
6819 if_ras_printed
= TRUE
;
6825 /* remote-as and peer-group */
6826 /* peer is a member of a peer-group */
6827 if (peer_group_active(peer
)) {
6828 g_peer
= peer
->group
->conf
;
6830 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6831 if (peer
->as_type
== AS_SPECIFIED
) {
6832 vty_out(vty
, " neighbor %s remote-as %u\n",
6834 } else if (peer
->as_type
== AS_INTERNAL
) {
6836 " neighbor %s remote-as internal\n",
6838 } else if (peer
->as_type
== AS_EXTERNAL
) {
6840 " neighbor %s remote-as external\n",
6845 /* For swpX peers we displayed the peer-group
6846 * via 'neighbor swpX interface peer-group WORD' */
6848 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6852 /* peer is NOT a member of a peer-group */
6854 /* peer is a peer-group, declare the peer-group */
6855 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6856 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6859 if (!if_ras_printed
) {
6860 if (peer
->as_type
== AS_SPECIFIED
) {
6861 vty_out(vty
, " neighbor %s remote-as %u\n",
6863 } else if (peer
->as_type
== AS_INTERNAL
) {
6865 " neighbor %s remote-as internal\n",
6867 } else if (peer
->as_type
== AS_EXTERNAL
) {
6869 " neighbor %s remote-as external\n",
6876 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6877 vty_out(vty
, " neighbor %s local-as %u", addr
,
6878 peer
->change_local_as
);
6879 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6880 vty_out(vty
, " no-prepend");
6881 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6882 vty_out(vty
, " replace-as");
6888 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6892 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6893 if (peer
->tx_shutdown_message
)
6894 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6895 peer
->tx_shutdown_message
);
6897 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6901 if (peer
->bfd_info
) {
6902 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6903 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6908 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6909 vty_out(vty
, " neighbor %s password %s\n", addr
,
6913 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6914 if (!peer_group_active(peer
)) {
6915 vty_out(vty
, " neighbor %s solo\n", addr
);
6920 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6921 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6924 /* Local interface name */
6926 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6930 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6931 vty_out(vty
, " neighbor %s passive\n", addr
);
6934 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6935 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6936 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6937 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6942 /* ttl-security hops */
6943 if (peer
->gtsm_hops
!= 0) {
6944 if (!peer_group_active(peer
)
6945 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6946 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6947 addr
, peer
->gtsm_hops
);
6951 /* disable-connected-check */
6952 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6953 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6955 /* enforce-first-as */
6956 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6957 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6960 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6961 if (peer
->update_source
)
6962 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6963 sockunion2str(peer
->update_source
, buf
,
6965 else if (peer
->update_if
)
6966 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6970 /* advertisement-interval */
6971 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6972 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6976 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6977 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6978 peer
->keepalive
, peer
->holdtime
);
6980 /* timers connect */
6981 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6982 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6985 /* capability dynamic */
6986 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6987 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6989 /* capability extended-nexthop */
6990 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6991 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6993 " no neighbor %s capability extended-nexthop\n",
6997 " neighbor %s capability extended-nexthop\n",
7001 /* dont-capability-negotiation */
7002 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7003 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7005 /* override-capability */
7006 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7007 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7009 /* strict-capability-match */
7010 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7011 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7014 /* BGP peer configuration display function. */
7015 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7016 struct peer
*peer
, afi_t afi
, safi_t safi
)
7018 struct peer
*g_peer
= NULL
;
7020 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7022 /* Skip dynamic neighbors. */
7023 if (peer_dynamic_neighbor(peer
))
7027 addr
= peer
->conf_if
;
7031 /************************************
7032 ****** Per AF to the neighbor ******
7033 ************************************/
7034 if (peer_group_active(peer
)) {
7035 g_peer
= peer
->group
->conf
;
7037 /* If the peer-group is active but peer is not, print a 'no
7039 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7040 vty_out(vty
, " no neighbor %s activate\n", addr
);
7043 /* If the peer-group is not active but peer is, print an
7045 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7046 vty_out(vty
, " neighbor %s activate\n", addr
);
7049 if (peer
->afc
[afi
][safi
]) {
7050 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7051 if (bgp_flag_check(bgp
,
7052 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7053 vty_out(vty
, " neighbor %s activate\n",
7057 vty_out(vty
, " neighbor %s activate\n", addr
);
7059 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7060 if (!bgp_flag_check(bgp
,
7061 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7063 " no neighbor %s activate\n",
7070 /* addpath TX knobs */
7071 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7072 switch (peer
->addpath_type
[afi
][safi
]) {
7073 case BGP_ADDPATH_ALL
:
7074 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7077 case BGP_ADDPATH_BEST_PER_AS
:
7079 " neighbor %s addpath-tx-bestpath-per-AS\n",
7082 case BGP_ADDPATH_MAX
:
7083 case BGP_ADDPATH_NONE
:
7088 /* ORF capability. */
7089 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7090 || peergroup_af_flag_check(peer
, afi
, safi
,
7091 PEER_FLAG_ORF_PREFIX_RM
)) {
7092 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7094 if (peergroup_af_flag_check(peer
, afi
, safi
,
7095 PEER_FLAG_ORF_PREFIX_SM
)
7096 && peergroup_af_flag_check(peer
, afi
, safi
,
7097 PEER_FLAG_ORF_PREFIX_RM
))
7098 vty_out(vty
, " both");
7099 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7100 PEER_FLAG_ORF_PREFIX_SM
))
7101 vty_out(vty
, " send");
7103 vty_out(vty
, " receive");
7107 /* Route reflector client. */
7108 if (peergroup_af_flag_check(peer
, afi
, safi
,
7109 PEER_FLAG_REFLECTOR_CLIENT
)) {
7110 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7113 /* next-hop-self force */
7114 if (peergroup_af_flag_check(peer
, afi
, safi
,
7115 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7116 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7120 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7121 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7124 /* remove-private-AS */
7125 if (peergroup_af_flag_check(peer
, afi
, safi
,
7126 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7127 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7131 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7132 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7133 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7137 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7138 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7139 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7142 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7143 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7144 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7148 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7149 vty_out(vty
, " neighbor %s as-override\n", addr
);
7152 /* send-community print. */
7153 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7154 PEER_FLAG_SEND_COMMUNITY
);
7155 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7156 PEER_FLAG_SEND_EXT_COMMUNITY
);
7157 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7158 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7160 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7161 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7162 vty_out(vty
, " no neighbor %s send-community all\n",
7167 " no neighbor %s send-community\n",
7171 " no neighbor %s send-community extended\n",
7176 " no neighbor %s send-community large\n",
7180 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7181 vty_out(vty
, " neighbor %s send-community all\n",
7183 } else if (flag_scomm
&& flag_secomm
) {
7184 vty_out(vty
, " neighbor %s send-community both\n",
7188 vty_out(vty
, " neighbor %s send-community\n",
7192 " neighbor %s send-community extended\n",
7196 " neighbor %s send-community large\n",
7201 /* Default information */
7202 if (peergroup_af_flag_check(peer
, afi
, safi
,
7203 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7204 vty_out(vty
, " neighbor %s default-originate", addr
);
7206 if (peer
->default_rmap
[afi
][safi
].name
)
7207 vty_out(vty
, " route-map %s",
7208 peer
->default_rmap
[afi
][safi
].name
);
7213 /* Soft reconfiguration inbound. */
7214 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7215 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7219 /* maximum-prefix. */
7220 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7221 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7222 peer
->pmax
[afi
][safi
]);
7224 if (peer
->pmax_threshold
[afi
][safi
]
7225 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7226 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7227 if (peer_af_flag_check(peer
, afi
, safi
,
7228 PEER_FLAG_MAX_PREFIX_WARNING
))
7229 vty_out(vty
, " warning-only");
7230 if (peer
->pmax_restart
[afi
][safi
])
7231 vty_out(vty
, " restart %u",
7232 peer
->pmax_restart
[afi
][safi
]);
7237 /* Route server client. */
7238 if (peergroup_af_flag_check(peer
, afi
, safi
,
7239 PEER_FLAG_RSERVER_CLIENT
)) {
7240 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7243 /* Nexthop-local unchanged. */
7244 if (peergroup_af_flag_check(peer
, afi
, safi
,
7245 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7246 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7249 /* allowas-in <1-10> */
7250 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7251 if (peer_af_flag_check(peer
, afi
, safi
,
7252 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7253 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7254 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7255 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7257 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7258 peer
->allowas_in
[afi
][safi
]);
7263 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7264 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7265 peer
->weight
[afi
][safi
]);
7268 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7270 /* atribute-unchanged. */
7271 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7272 || (safi
!= SAFI_EVPN
7273 && peer_af_flag_check(peer
, afi
, safi
,
7274 PEER_FLAG_NEXTHOP_UNCHANGED
))
7275 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7277 if (!peer_group_active(peer
)
7278 || peergroup_af_flag_check(peer
, afi
, safi
,
7279 PEER_FLAG_AS_PATH_UNCHANGED
)
7280 || peergroup_af_flag_check(peer
, afi
, safi
,
7281 PEER_FLAG_NEXTHOP_UNCHANGED
)
7282 || peergroup_af_flag_check(peer
, afi
, safi
,
7283 PEER_FLAG_MED_UNCHANGED
)) {
7286 " neighbor %s attribute-unchanged%s%s%s\n",
7288 peer_af_flag_check(peer
, afi
, safi
,
7289 PEER_FLAG_AS_PATH_UNCHANGED
)
7292 peer_af_flag_check(peer
, afi
, safi
,
7293 PEER_FLAG_NEXTHOP_UNCHANGED
)
7296 peer_af_flag_check(peer
, afi
, safi
,
7297 PEER_FLAG_MED_UNCHANGED
)
7304 /* Address family based peer configuration display. */
7305 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7309 struct peer_group
*group
;
7310 struct listnode
*node
, *nnode
;
7313 vty_frame(vty
, " !\n address-family ");
7314 if (afi
== AFI_IP
) {
7315 if (safi
== SAFI_UNICAST
)
7316 vty_frame(vty
, "ipv4 unicast");
7317 else if (safi
== SAFI_LABELED_UNICAST
)
7318 vty_frame(vty
, "ipv4 labeled-unicast");
7319 else if (safi
== SAFI_MULTICAST
)
7320 vty_frame(vty
, "ipv4 multicast");
7321 else if (safi
== SAFI_MPLS_VPN
)
7322 vty_frame(vty
, "ipv4 vpn");
7323 else if (safi
== SAFI_ENCAP
)
7324 vty_frame(vty
, "ipv4 encap");
7325 else if (safi
== SAFI_FLOWSPEC
)
7326 vty_frame(vty
, "ipv4 flowspec");
7327 } else if (afi
== AFI_IP6
) {
7328 if (safi
== SAFI_UNICAST
)
7329 vty_frame(vty
, "ipv6 unicast");
7330 else if (safi
== SAFI_LABELED_UNICAST
)
7331 vty_frame(vty
, "ipv6 labeled-unicast");
7332 else if (safi
== SAFI_MULTICAST
)
7333 vty_frame(vty
, "ipv6 multicast");
7334 else if (safi
== SAFI_MPLS_VPN
)
7335 vty_frame(vty
, "ipv6 vpn");
7336 else if (safi
== SAFI_ENCAP
)
7337 vty_frame(vty
, "ipv6 encap");
7338 else if (safi
== SAFI_FLOWSPEC
)
7339 vty_frame(vty
, "ipv6 flowspec");
7340 } else if (afi
== AFI_L2VPN
) {
7341 if (safi
== SAFI_EVPN
)
7342 vty_frame(vty
, "l2vpn evpn");
7344 vty_frame(vty
, "\n");
7346 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7348 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7350 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7352 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7353 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7355 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7356 /* Skip dynamic neighbors. */
7357 if (peer_dynamic_neighbor(peer
))
7360 /* Do not display doppelganger peers */
7361 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7362 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7365 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7366 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7368 if (safi
== SAFI_EVPN
)
7369 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7371 if (safi
== SAFI_FLOWSPEC
)
7372 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7374 if (safi
== SAFI_UNICAST
) {
7375 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7376 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7377 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7379 vty_out(vty
, " export vpn\n");
7381 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7382 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7384 vty_out(vty
, " import vpn\n");
7386 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7387 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7390 for (ALL_LIST_ELEMENTS_RO(
7391 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7393 vty_out(vty
, " import vrf %s\n", name
);
7397 vty_endframe(vty
, " exit-address-family\n");
7400 /* clang-format off */
7401 #if CONFDATE > 20190517
7402 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7404 /* clang-format on */
7406 int bgp_config_write(struct vty
*vty
)
7410 struct peer_group
*group
;
7412 struct listnode
*node
, *nnode
;
7413 struct listnode
*mnode
, *mnnode
;
7415 /* BGP Multiple instance. */
7416 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7417 vty_out(vty
, "no bgp multiple-instance\n");
7421 /* BGP Config type. */
7422 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7423 vty_out(vty
, "bgp config-type cisco\n");
7427 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7428 vty_out(vty
, "bgp route-map delay-timer %u\n",
7429 bm
->rmap_update_timer
);
7432 vty_out(vty
, "!\n");
7434 /* BGP configuration. */
7435 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7437 /* skip all auto created vrf as they dont have user config */
7438 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7441 /* Migrate deprecated 'bgp enforce-first-as'
7442 * config to 'neighbor * enforce-first-as' configs
7444 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7445 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7446 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7447 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7450 /* Router bgp ASN */
7451 vty_out(vty
, "router bgp %u", bgp
->as
);
7453 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7455 vty_out(vty
, " %s %s",
7457 == BGP_INSTANCE_TYPE_VIEW
)
7464 /* No Synchronization */
7465 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7466 vty_out(vty
, " no synchronization\n");
7468 /* BGP fast-external-failover. */
7469 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7470 vty_out(vty
, " no bgp fast-external-failover\n");
7472 /* BGP router ID. */
7473 if (bgp
->router_id_static
.s_addr
!= 0)
7474 vty_out(vty
, " bgp router-id %s\n",
7475 inet_ntoa(bgp
->router_id_static
));
7477 /* BGP log-neighbor-changes. */
7478 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7479 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7480 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7482 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7486 /* BGP configuration. */
7487 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7488 vty_out(vty
, " bgp always-compare-med\n");
7490 /* BGP default ipv4-unicast. */
7491 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7492 vty_out(vty
, " no bgp default ipv4-unicast\n");
7494 /* BGP default local-preference. */
7495 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7496 vty_out(vty
, " bgp default local-preference %u\n",
7497 bgp
->default_local_pref
);
7499 /* BGP default show-hostname */
7500 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7501 != DFLT_BGP_SHOW_HOSTNAME
)
7502 vty_out(vty
, " %sbgp default show-hostname\n",
7503 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7507 /* BGP default subgroup-pkt-queue-max. */
7508 if (bgp
->default_subgroup_pkt_queue_max
7509 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7510 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7511 bgp
->default_subgroup_pkt_queue_max
);
7513 /* BGP client-to-client reflection. */
7514 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7515 vty_out(vty
, " no bgp client-to-client reflection\n");
7517 /* BGP cluster ID. */
7518 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7519 vty_out(vty
, " bgp cluster-id %s\n",
7520 inet_ntoa(bgp
->cluster_id
));
7522 /* Disable ebgp connected nexthop check */
7523 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7525 " bgp disable-ebgp-connected-route-check\n");
7527 /* Confederation identifier*/
7528 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7529 vty_out(vty
, " bgp confederation identifier %i\n",
7532 /* Confederation peer */
7533 if (bgp
->confed_peers_cnt
> 0) {
7536 vty_out(vty
, " bgp confederation peers");
7538 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7539 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7544 /* BGP deterministic-med. */
7545 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7546 != DFLT_BGP_DETERMINISTIC_MED
)
7547 vty_out(vty
, " %sbgp deterministic-med\n",
7548 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7552 /* BGP update-delay. */
7553 bgp_config_write_update_delay(vty
, bgp
);
7555 if (bgp
->v_maxmed_onstartup
7556 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7557 vty_out(vty
, " bgp max-med on-startup %u",
7558 bgp
->v_maxmed_onstartup
);
7559 if (bgp
->maxmed_onstartup_value
7560 != BGP_MAXMED_VALUE_DEFAULT
)
7562 bgp
->maxmed_onstartup_value
);
7565 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7566 vty_out(vty
, " bgp max-med administrative");
7567 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7568 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7573 bgp_config_write_wpkt_quanta(vty
, bgp
);
7575 bgp_config_write_rpkt_quanta(vty
, bgp
);
7578 bgp_config_write_coalesce_time(vty
, bgp
);
7580 /* BGP graceful-restart. */
7581 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7583 " bgp graceful-restart stalepath-time %u\n",
7584 bgp
->stalepath_time
);
7585 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7586 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7588 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7589 vty_out(vty
, " bgp graceful-restart\n");
7591 /* BGP graceful-shutdown */
7592 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7593 vty_out(vty
, " bgp graceful-shutdown\n");
7595 /* BGP graceful-restart Preserve State F bit. */
7596 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7598 " bgp graceful-restart preserve-fw-state\n");
7600 /* BGP bestpath method. */
7601 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7602 vty_out(vty
, " bgp bestpath as-path ignore\n");
7603 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7604 vty_out(vty
, " bgp bestpath as-path confed\n");
7606 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7607 if (bgp_flag_check(bgp
,
7608 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7610 " bgp bestpath as-path multipath-relax as-set\n");
7613 " bgp bestpath as-path multipath-relax\n");
7617 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7619 " bgp route-reflector allow-outbound-policy\n");
7621 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7622 vty_out(vty
, " bgp bestpath compare-routerid\n");
7623 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7624 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7625 vty_out(vty
, " bgp bestpath med");
7626 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7627 vty_out(vty
, " confed");
7628 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7629 vty_out(vty
, " missing-as-worst");
7633 /* BGP network import check. */
7634 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7635 != DFLT_BGP_IMPORT_CHECK
)
7636 vty_out(vty
, " %sbgp network import-check\n",
7637 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7641 /* BGP flag dampening. */
7642 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7643 BGP_CONFIG_DAMPENING
))
7644 bgp_config_write_damp(vty
);
7646 /* BGP timers configuration. */
7647 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7648 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7649 vty_out(vty
, " timers bgp %u %u\n",
7650 bgp
->default_keepalive
, bgp
->default_holdtime
);
7653 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7654 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7657 /* Normal neighbor configuration. */
7658 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7659 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7660 bgp_config_write_peer_global(vty
, bgp
, peer
);
7663 /* listen range and limit for dynamic BGP neighbors */
7664 bgp_config_write_listen(vty
, bgp
);
7667 * BGP default autoshutdown neighbors
7669 * This must be placed after any peer and peer-group
7670 * configuration, to avoid setting all peers to shutdown after
7671 * a daemon restart, which is undesired behavior. (see #2286)
7673 if (bgp
->autoshutdown
)
7674 vty_out(vty
, " bgp default shutdown\n");
7676 /* No auto-summary */
7677 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7678 vty_out(vty
, " no auto-summary\n");
7680 /* IPv4 unicast configuration. */
7681 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7683 /* IPv4 multicast configuration. */
7684 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7686 /* IPv4 labeled-unicast configuration. */
7687 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7689 /* IPv4 VPN configuration. */
7690 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7692 /* ENCAPv4 configuration. */
7693 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7695 /* FLOWSPEC v4 configuration. */
7696 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7698 /* IPv6 unicast configuration. */
7699 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7701 /* IPv6 multicast configuration. */
7702 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7704 /* IPv6 labeled-unicast configuration. */
7705 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7706 SAFI_LABELED_UNICAST
);
7708 /* IPv6 VPN configuration. */
7709 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7711 /* ENCAPv6 configuration. */
7712 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7714 /* FLOWSPEC v6 configuration. */
7715 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7717 /* EVPN configuration. */
7718 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7721 bgp_rfapi_cfg_write(vty
, bgp
);
7724 vty_out(vty
, "!\n");
7729 void bgp_master_init(struct thread_master
*master
)
7733 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7736 bm
->bgp
= list_new();
7737 bm
->listen_sockets
= list_new();
7738 bm
->port
= BGP_PORT_DEFAULT
;
7739 bm
->master
= master
;
7740 bm
->start_time
= bgp_clock();
7741 bm
->t_rmap_update
= NULL
;
7742 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7743 bm
->terminating
= false;
7745 bgp_process_queue_init();
7747 /* init the rd id space.
7748 assign 0th index in the bitfield,
7749 so that we start with id 1
7751 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7752 bf_assign_zero_index(bm
->rd_idspace
);
7754 /* Enable multiple instances by default. */
7755 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7757 /* mpls label dynamic allocation pool */
7758 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7760 QOBJ_REG(bm
, bgp_master
);
7764 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7765 * instance delete (non-default only) or BGP exit.
7767 static void bgp_if_finish(struct bgp
*bgp
)
7769 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7770 struct interface
*ifp
;
7772 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7775 FOR_ALL_INTERFACES (vrf
, ifp
) {
7776 struct listnode
*c_node
, *c_nnode
;
7777 struct connected
*c
;
7779 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7780 bgp_connected_delete(bgp
, c
);
7784 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7786 struct vrf
*vrf
= NULL
;
7787 struct listnode
*next
;
7790 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7791 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7793 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7794 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7797 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7801 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7802 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7803 {.completions
= NULL
},
7806 struct frr_pthread
*bgp_pth_io
;
7807 struct frr_pthread
*bgp_pth_ka
;
7809 static void bgp_pthreads_init()
7811 assert(!bgp_pth_io
);
7812 assert(!bgp_pth_ka
);
7816 struct frr_pthread_attr io
= {
7817 .start
= frr_pthread_attr_default
.start
,
7818 .stop
= frr_pthread_attr_default
.stop
,
7820 struct frr_pthread_attr ka
= {
7821 .start
= bgp_keepalives_start
,
7822 .stop
= bgp_keepalives_stop
,
7824 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7825 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7828 void bgp_pthreads_run()
7830 frr_pthread_run(bgp_pth_io
, NULL
);
7831 frr_pthread_run(bgp_pth_ka
, NULL
);
7833 /* Wait until threads are ready. */
7834 frr_pthread_wait_running(bgp_pth_io
);
7835 frr_pthread_wait_running(bgp_pth_ka
);
7838 void bgp_pthreads_finish()
7840 frr_pthread_stop_all();
7841 frr_pthread_finish();
7844 void bgp_init(unsigned short instance
)
7847 /* allocates some vital data structures used by peer commands in
7850 /* pre-init pthreads */
7851 bgp_pthreads_init();
7854 bgp_zebra_init(bm
->master
, instance
);
7857 vnc_zebra_init(bm
->master
);
7860 /* BGP VTY commands installation. */
7868 bgp_route_map_init();
7869 bgp_scan_vty_init();
7874 bgp_ethernetvpn_init();
7875 bgp_flowspec_vty_init();
7877 /* Access list initialize. */
7879 access_list_add_hook(peer_distribute_update
);
7880 access_list_delete_hook(peer_distribute_update
);
7882 /* Filter list initialize. */
7884 as_list_add_hook(peer_aslist_add
);
7885 as_list_delete_hook(peer_aslist_del
);
7887 /* Prefix list initialize.*/
7889 prefix_list_add_hook(peer_prefix_list_update
);
7890 prefix_list_delete_hook(peer_prefix_list_update
);
7892 /* Community list initialize. */
7893 bgp_clist
= community_list_init();
7898 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7901 void bgp_terminate(void)
7905 struct listnode
*node
, *nnode
;
7906 struct listnode
*mnode
, *mnnode
;
7910 /* Close the listener sockets first as this prevents peers from
7912 * to reconnect on receiving the peer unconfig message. In the presence
7913 * of a large number of peers this will ensure that no peer is left with
7914 * a dangling connection
7916 /* reverse bgp_master_init */
7919 if (bm
->listen_sockets
)
7920 list_delete(&bm
->listen_sockets
);
7922 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7923 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7924 if (peer
->status
== Established
7925 || peer
->status
== OpenSent
7926 || peer
->status
== OpenConfirm
)
7927 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7928 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7930 if (bm
->process_main_queue
)
7931 work_queue_free_and_null(&bm
->process_main_queue
);
7933 if (bm
->t_rmap_update
)
7934 BGP_TIMER_OFF(bm
->t_rmap_update
);