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"
89 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
90 DEFINE_QOBJ_TYPE(bgp_master
)
92 DEFINE_QOBJ_TYPE(peer
)
94 /* BGP process wide configuration. */
95 static struct bgp_master bgp_master
;
97 /* BGP process wide configuration pointer to export. */
98 struct bgp_master
*bm
;
100 /* BGP community-list. */
101 struct community_list_handler
*bgp_clist
;
103 unsigned int multipath_num
= MULTIPATH_NUM
;
105 static void bgp_if_finish(struct bgp
*bgp
);
106 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
108 extern struct zclient
*zclient
;
110 /* handle main socket creation or deletion */
111 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
113 static int bgp_server_main_created
;
115 if (create
== true) {
116 if (bgp_server_main_created
)
118 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
119 return BGP_ERR_INVALID_VALUE
;
120 bgp_server_main_created
= 1;
123 if (!bgp_server_main_created
)
126 bgp_server_main_created
= 0;
130 void bgp_session_reset(struct peer
*peer
)
132 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
133 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
134 peer_delete(peer
->doppelganger
);
136 BGP_EVENT_ADD(peer
, BGP_Stop
);
140 * During session reset, we may delete the doppelganger peer, which would
141 * be the next node to the current node. If the session reset was invoked
142 * during walk of peer list, we would end up accessing the freed next
143 * node. This function moves the next node along.
145 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
150 n
= (nnode
) ? *nnode
: NULL
;
151 npeer
= (n
) ? listgetdata(n
) : NULL
;
153 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
154 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
155 PEER_FLAG_CONFIG_NODE
))) {
156 if (peer
->doppelganger
== npeer
)
157 /* nnode and *nnode are confirmed to be non-NULL here */
158 *nnode
= (*nnode
)->next
;
159 peer_delete(peer
->doppelganger
);
162 BGP_EVENT_ADD(peer
, BGP_Stop
);
165 /* BGP global flag manipulation. */
166 int bgp_option_set(int flag
)
170 case BGP_OPT_MULTIPLE_INSTANCE
:
171 case BGP_OPT_CONFIG_CISCO
:
172 case BGP_OPT_NO_LISTEN
:
173 SET_FLAG(bm
->options
, flag
);
176 return BGP_ERR_INVALID_FLAG
;
181 int bgp_option_unset(int flag
)
184 case BGP_OPT_MULTIPLE_INSTANCE
:
185 if (listcount(bm
->bgp
) > 1)
186 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
189 case BGP_OPT_CONFIG_CISCO
:
190 UNSET_FLAG(bm
->options
, flag
);
193 return BGP_ERR_INVALID_FLAG
;
198 int bgp_option_check(int flag
)
200 return CHECK_FLAG(bm
->options
, flag
);
203 /* BGP flag manipulation. */
204 int bgp_flag_set(struct bgp
*bgp
, int flag
)
206 SET_FLAG(bgp
->flags
, flag
);
210 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
212 UNSET_FLAG(bgp
->flags
, flag
);
216 int bgp_flag_check(struct bgp
*bgp
, int flag
)
218 return CHECK_FLAG(bgp
->flags
, flag
);
221 /* Internal function to set BGP structure configureation flag. */
222 static void bgp_config_set(struct bgp
*bgp
, int config
)
224 SET_FLAG(bgp
->config
, config
);
227 static void bgp_config_unset(struct bgp
*bgp
, int config
)
229 UNSET_FLAG(bgp
->config
, config
);
232 static int bgp_config_check(struct bgp
*bgp
, int config
)
234 return CHECK_FLAG(bgp
->config
, config
);
237 /* Set BGP router identifier. */
238 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
241 struct listnode
*node
, *nnode
;
243 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
246 /* EVPN uses router id in RD, withdraw them */
247 if (is_evpn_enabled())
248 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
250 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
252 /* Set all peer's local identifier with this value. */
253 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
254 IPV4_ADDR_COPY(&peer
->local_id
, id
);
256 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
257 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
258 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
259 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
263 /* EVPN uses router id in RD, update them */
264 if (is_evpn_enabled())
265 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
270 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
272 struct listnode
*node
, *nnode
;
275 if (vrf_id
== VRF_DEFAULT
) {
276 /* Router-id change for default VRF has to also update all
278 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
279 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
282 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
283 if (!bgp
->router_id_static
.s_addr
)
284 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
287 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
289 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
291 if (!bgp
->router_id_static
.s_addr
)
292 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
297 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
299 bgp
->router_id_static
= id
;
300 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
304 /* BGP's cluster-id control. */
305 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
308 struct listnode
*node
, *nnode
;
310 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
311 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
314 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
315 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
317 /* Clear all IBGP peer. */
318 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
319 if (peer
->sort
!= BGP_PEER_IBGP
)
322 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
323 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
324 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
325 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
331 int bgp_cluster_id_unset(struct bgp
*bgp
)
334 struct listnode
*node
, *nnode
;
336 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
339 bgp
->cluster_id
.s_addr
= 0;
340 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
342 /* Clear all IBGP peer. */
343 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
344 if (peer
->sort
!= BGP_PEER_IBGP
)
347 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
348 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
349 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
350 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
356 /* time_t value that is monotonicly increasing
357 * and uneffected by adjustments to system clock
359 time_t bgp_clock(void)
367 /* BGP timer configuration. */
368 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
370 bgp
->default_keepalive
=
371 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
372 bgp
->default_holdtime
= holdtime
;
377 int bgp_timers_unset(struct bgp
*bgp
)
379 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
380 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
385 /* BGP confederation configuration. */
386 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
389 struct listnode
*node
, *nnode
;
393 return BGP_ERR_INVALID_AS
;
395 /* Remember - were we doing confederation before? */
396 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
398 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
400 /* If we were doing confederation already, this is just an external
401 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
402 were not doing confederation before, reset all EBGP sessions. */
403 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
404 /* We're looking for peers who's AS is not local or part of our
406 if (already_confed
) {
407 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
409 if (BGP_IS_VALID_STATE_FOR_NOTIF(
412 PEER_DOWN_CONFED_ID_CHANGE
;
414 peer
, BGP_NOTIFY_CEASE
,
415 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
417 bgp_session_reset_safe(peer
, &nnode
);
420 /* Not doign confederation before, so reset every
423 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
424 /* Reset the local_as to be our EBGP one */
425 if (peer_sort(peer
) == BGP_PEER_EBGP
)
427 if (BGP_IS_VALID_STATE_FOR_NOTIF(
430 PEER_DOWN_CONFED_ID_CHANGE
;
432 peer
, BGP_NOTIFY_CEASE
,
433 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
435 bgp_session_reset_safe(peer
, &nnode
);
442 int bgp_confederation_id_unset(struct bgp
*bgp
)
445 struct listnode
*node
, *nnode
;
448 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
450 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
451 /* We're looking for peers who's AS is not local */
452 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
453 peer
->local_as
= bgp
->as
;
454 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
455 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
456 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
457 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
461 bgp_session_reset_safe(peer
, &nnode
);
467 /* Is an AS part of the confed or not? */
468 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
475 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
476 if (bgp
->confed_peers
[i
] == as
)
482 /* Add an AS to the confederation set. */
483 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
486 struct listnode
*node
, *nnode
;
489 return BGP_ERR_INVALID_BGP
;
492 return BGP_ERR_INVALID_AS
;
494 if (bgp_confederation_peers_check(bgp
, as
))
497 if (bgp
->confed_peers
)
499 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
500 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
503 XMALLOC(MTYPE_BGP_CONFED_LIST
,
504 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
506 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
507 bgp
->confed_peers_cnt
++;
509 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
510 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
511 if (peer
->as
== as
) {
512 peer
->local_as
= bgp
->as
;
513 if (BGP_IS_VALID_STATE_FOR_NOTIF(
516 PEER_DOWN_CONFED_PEER_CHANGE
;
518 peer
, BGP_NOTIFY_CEASE
,
519 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
521 bgp_session_reset_safe(peer
, &nnode
);
528 /* Delete an AS from the confederation set. */
529 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
534 struct listnode
*node
, *nnode
;
539 if (!bgp_confederation_peers_check(bgp
, as
))
542 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
543 if (bgp
->confed_peers
[i
] == as
)
544 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
545 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
547 bgp
->confed_peers_cnt
--;
549 if (bgp
->confed_peers_cnt
== 0) {
550 if (bgp
->confed_peers
)
551 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
552 bgp
->confed_peers
= NULL
;
555 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
556 bgp
->confed_peers_cnt
* sizeof(as_t
));
558 /* Now reset any peer who's remote AS has just been removed from the
560 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
561 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
562 if (peer
->as
== as
) {
563 peer
->local_as
= bgp
->confed_id
;
564 if (BGP_IS_VALID_STATE_FOR_NOTIF(
567 PEER_DOWN_CONFED_PEER_CHANGE
;
569 peer
, BGP_NOTIFY_CEASE
,
570 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
572 bgp_session_reset_safe(peer
, &nnode
);
580 /* Local preference configuration. */
581 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
586 bgp
->default_local_pref
= local_pref
;
591 int bgp_default_local_preference_unset(struct bgp
*bgp
)
596 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
601 /* Local preference configuration. */
602 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
607 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
612 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
616 bgp
->default_subgroup_pkt_queue_max
=
617 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
622 /* Listen limit configuration. */
623 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
628 bgp
->dynamic_neighbors_limit
= listen_limit
;
633 int bgp_listen_limit_unset(struct bgp
*bgp
)
638 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
643 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
644 afi_t
*afi
, safi_t
*safi
)
646 /* Map from IANA values to internal values, return error if
647 * values are unrecognized.
649 *afi
= afi_iana2int(pkt_afi
);
650 *safi
= safi_iana2int(pkt_safi
);
651 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
657 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
658 iana_safi_t
*pkt_safi
)
660 /* Map from internal values to IANA values, return error if
661 * internal values are bad (unexpected).
663 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
665 *pkt_afi
= afi_int2iana(afi
);
666 *pkt_safi
= safi_int2iana(safi
);
670 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
678 afid
= afindex(afi
, safi
);
679 if (afid
>= BGP_AF_MAX
)
682 assert(peer
->peer_af_array
[afid
] == NULL
);
684 /* Allocate new peer af */
685 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
687 peer
->peer_af_array
[afid
] = af
;
696 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
703 afid
= afindex(afi
, safi
);
704 if (afid
>= BGP_AF_MAX
)
707 return peer
->peer_af_array
[afid
];
710 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
718 afid
= afindex(afi
, safi
);
719 if (afid
>= BGP_AF_MAX
)
722 af
= peer
->peer_af_array
[afid
];
726 bgp_stop_announce_route_timer(af
);
728 if (PAF_SUBGRP(af
)) {
729 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
730 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
731 af
->subgroup
->update_group
->id
,
732 af
->subgroup
->id
, peer
->host
);
735 update_subgroup_remove_peer(af
->subgroup
, af
);
737 peer
->peer_af_array
[afid
] = NULL
;
738 XFREE(MTYPE_BGP_PEER_AF
, af
);
742 /* Peer comparison function for sorting. */
743 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
745 if (p1
->group
&& !p2
->group
)
748 if (!p1
->group
&& p2
->group
)
751 if (p1
->group
== p2
->group
) {
752 if (p1
->conf_if
&& !p2
->conf_if
)
755 if (!p1
->conf_if
&& p2
->conf_if
)
758 if (p1
->conf_if
&& p2
->conf_if
)
759 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
761 return strcmp(p1
->group
->name
, p2
->group
->name
);
763 return sockunion_cmp(&p1
->su
, &p2
->su
);
766 static unsigned int peer_hash_key_make(void *p
)
768 struct peer
*peer
= p
;
769 return sockunion_hash(&peer
->su
);
772 static int peer_hash_same(const void *p1
, const void *p2
)
774 const struct peer
*peer1
= p1
;
775 const struct peer
*peer2
= p2
;
776 return (sockunion_same(&peer1
->su
, &peer2
->su
)
777 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
778 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
781 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
785 /* Skip if peer is not a peer-group member. */
786 if (!peer_group_active(peer
))
789 /* Unset override flag to signal inheritance from peer-group. */
790 UNSET_FLAG(peer
->flags_override
, flag
);
793 * Inherit flag state from peer-group. If the flag of the peer-group is
794 * not being inverted, the peer must inherit the inverse of the current
795 * peer-group flag state.
797 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
798 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
799 && CHECK_FLAG(peer
->flags_invert
, flag
))
800 COND_FLAG(peer
->flags
, flag
, !group_val
);
802 COND_FLAG(peer
->flags
, flag
, group_val
);
805 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
807 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
810 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
815 /* Skip if peer is not a peer-group member. */
816 if (!peer_group_active(peer
))
819 /* Unset override flag to signal inheritance from peer-group. */
820 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
823 * Inherit flag state from peer-group. If the flag of the peer-group is
824 * not being inverted, the peer must inherit the inverse of the current
825 * peer-group flag state.
827 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
828 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
829 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
830 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
832 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
835 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
837 if (!peer_group_active(peer
)) {
838 if (CHECK_FLAG(peer
->flags_invert
, flag
))
839 return !CHECK_FLAG(peer
->flags
, flag
);
841 return !!CHECK_FLAG(peer
->flags
, flag
);
844 return !!CHECK_FLAG(peer
->flags_override
, flag
);
847 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
850 if (!peer_group_active(peer
)) {
851 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
852 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
854 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
857 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
860 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
861 uint8_t type
, int direct
)
863 struct bgp_filter
*filter
;
865 if (peer_group_active(peer
))
866 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
869 filter
= &peer
->filter
[afi
][safi
];
871 case PEER_FT_DISTRIBUTE_LIST
:
872 return !!(filter
->dlist
[direct
].name
);
873 case PEER_FT_FILTER_LIST
:
874 return !!(filter
->aslist
[direct
].name
);
875 case PEER_FT_PREFIX_LIST
:
876 return !!(filter
->plist
[direct
].name
);
877 case PEER_FT_ROUTE_MAP
:
878 return !!(filter
->map
[direct
].name
);
879 case PEER_FT_UNSUPPRESS_MAP
:
880 return !!(filter
->usmap
.name
);
886 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
887 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
894 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
895 if (peer
->as_type
== AS_INTERNAL
)
896 return BGP_PEER_IBGP
;
898 else if (peer
->as_type
== AS_EXTERNAL
)
899 return BGP_PEER_EBGP
;
901 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
903 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
911 peer1
= listnode_head(peer
->group
->peer
);
916 return BGP_PEER_INTERNAL
;
920 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
921 if (peer
->local_as
== 0)
922 return BGP_PEER_INTERNAL
;
924 if (peer
->local_as
== peer
->as
) {
925 if (bgp
->as
== bgp
->confed_id
) {
926 if (peer
->local_as
== bgp
->as
)
927 return BGP_PEER_IBGP
;
929 return BGP_PEER_EBGP
;
931 if (peer
->local_as
== bgp
->confed_id
)
932 return BGP_PEER_EBGP
;
934 return BGP_PEER_IBGP
;
938 if (bgp_confederation_peers_check(bgp
, peer
->as
))
939 return BGP_PEER_CONFED
;
941 return BGP_PEER_EBGP
;
943 if (peer
->as_type
!= AS_SPECIFIED
)
944 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
947 return (peer
->local_as
== 0
949 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
954 /* Calculate and cache the peer "sort" */
955 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
957 peer
->sort
= peer_calc_sort(peer
);
961 static void peer_free(struct peer
*peer
)
963 assert(peer
->status
== Deleted
);
967 /* this /ought/ to have been done already through bgp_stop earlier,
968 * but just to be sure..
972 bgp_writes_off(peer
);
973 assert(!peer
->t_write
);
974 assert(!peer
->t_read
);
975 BGP_EVENT_FLUSH(peer
);
977 pthread_mutex_destroy(&peer
->io_mtx
);
979 /* Free connected nexthop, if present */
980 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
981 && !peer_dynamic_neighbor(peer
))
982 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
985 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
988 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
992 /* Free allocated host character. */
994 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
998 if (peer
->domainname
) {
999 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1000 peer
->domainname
= NULL
;
1004 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1005 peer
->ifname
= NULL
;
1008 /* Update source configuration. */
1009 if (peer
->update_source
) {
1010 sockunion_free(peer
->update_source
);
1011 peer
->update_source
= NULL
;
1014 if (peer
->update_if
) {
1015 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1016 peer
->update_if
= NULL
;
1019 if (peer
->notify
.data
)
1020 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1021 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1023 if (peer
->clear_node_queue
)
1024 work_queue_free_and_null(&peer
->clear_node_queue
);
1026 bgp_sync_delete(peer
);
1028 if (peer
->conf_if
) {
1029 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1030 peer
->conf_if
= NULL
;
1033 bfd_info_free(&(peer
->bfd_info
));
1035 bgp_unlock(peer
->bgp
);
1037 memset(peer
, 0, sizeof(struct peer
));
1039 XFREE(MTYPE_BGP_PEER
, peer
);
1042 /* increase reference count on a struct peer */
1043 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1045 assert(peer
&& (peer
->lock
>= 0));
1048 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1056 /* decrease reference count on a struct peer
1057 * struct peer is freed and NULL returned if last reference
1059 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1061 assert(peer
&& (peer
->lock
> 0));
1064 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1069 if (peer
->lock
== 0) {
1077 /* Allocate new peer object, implicitely locked. */
1078 struct peer
*peer_new(struct bgp
*bgp
)
1085 /* bgp argument is absolutely required */
1090 /* Allocate new peer. */
1091 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1093 /* Set default value. */
1095 peer
->v_start
= BGP_INIT_START_TIMER
;
1096 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1097 peer
->status
= Idle
;
1098 peer
->ostatus
= Idle
;
1099 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1100 peer
->bgp
= bgp_lock(bgp
);
1101 peer
= peer_lock(peer
); /* initial reference */
1102 peer
->password
= NULL
;
1104 /* Set default flags. */
1105 FOREACH_AFI_SAFI (afi
, safi
) {
1106 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1107 SET_FLAG(peer
->af_flags
[afi
][safi
],
1108 PEER_FLAG_SEND_COMMUNITY
);
1109 SET_FLAG(peer
->af_flags
[afi
][safi
],
1110 PEER_FLAG_SEND_EXT_COMMUNITY
);
1111 SET_FLAG(peer
->af_flags
[afi
][safi
],
1112 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1114 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1115 PEER_FLAG_SEND_COMMUNITY
);
1116 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1117 PEER_FLAG_SEND_EXT_COMMUNITY
);
1118 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1119 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1123 /* set nexthop-unchanged for l2vpn evpn by default */
1124 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1125 PEER_FLAG_NEXTHOP_UNCHANGED
);
1127 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1129 /* Create buffers. */
1130 peer
->ibuf
= stream_fifo_new();
1131 peer
->obuf
= stream_fifo_new();
1132 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1134 /* We use a larger buffer for peer->obuf_work in the event that:
1135 * - We RX a BGP_UPDATE where the attributes alone are just
1136 * under BGP_MAX_PACKET_SIZE
1137 * - The user configures an outbound route-map that does many as-path
1138 * prepends or adds many communities. At most they can have
1139 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1140 * large they can make the attributes.
1142 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1143 * bounds checking for every single attribute as we construct an
1147 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1149 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1151 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1153 bgp_sync_init(peer
);
1155 /* Get service port number. */
1156 sp
= getservbyname("bgp", "tcp");
1157 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1159 QOBJ_REG(peer
, peer
);
1164 * This function is invoked when a duplicate peer structure associated with
1165 * a neighbor is being deleted. If this about-to-be-deleted structure is
1166 * the one with all the config, then we have to copy over the info.
1168 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1170 struct peer_af
*paf
;
1178 /* The following function is used by both peer group config copy to
1179 * individual peer and when we transfer config
1181 if (peer_src
->change_local_as
)
1182 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1184 /* peer flags apply */
1185 peer_dst
->flags
= peer_src
->flags
;
1186 peer_dst
->cap
= peer_src
->cap
;
1188 peer_dst
->local_as
= peer_src
->local_as
;
1189 peer_dst
->port
= peer_src
->port
;
1190 (void)peer_sort(peer_dst
);
1191 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1194 peer_dst
->holdtime
= peer_src
->holdtime
;
1195 peer_dst
->keepalive
= peer_src
->keepalive
;
1196 peer_dst
->connect
= peer_src
->connect
;
1197 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1198 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1199 peer_dst
->routeadv
= peer_src
->routeadv
;
1200 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1202 /* password apply */
1203 if (peer_src
->password
&& !peer_dst
->password
)
1204 peer_dst
->password
=
1205 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1207 FOREACH_AFI_SAFI (afi
, safi
) {
1208 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1209 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1210 peer_dst
->allowas_in
[afi
][safi
] =
1211 peer_src
->allowas_in
[afi
][safi
];
1212 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1215 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1216 paf
= peer_src
->peer_af_array
[afidx
];
1218 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1221 /* update-source apply */
1222 if (peer_src
->update_source
) {
1223 if (peer_dst
->update_source
)
1224 sockunion_free(peer_dst
->update_source
);
1225 if (peer_dst
->update_if
) {
1226 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1227 peer_dst
->update_if
= NULL
;
1229 peer_dst
->update_source
=
1230 sockunion_dup(peer_src
->update_source
);
1231 } else if (peer_src
->update_if
) {
1232 if (peer_dst
->update_if
)
1233 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1234 if (peer_dst
->update_source
) {
1235 sockunion_free(peer_dst
->update_source
);
1236 peer_dst
->update_source
= NULL
;
1238 peer_dst
->update_if
=
1239 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1242 if (peer_src
->ifname
) {
1243 if (peer_dst
->ifname
)
1244 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1247 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1251 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1252 struct interface
*ifp
)
1254 struct connected
*ifc
;
1257 struct listnode
*node
;
1259 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1260 * IPv4 address of the other end.
1262 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1263 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1264 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1265 if (p
.prefixlen
== 30) {
1266 peer
->su
.sa
.sa_family
= AF_INET
;
1267 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1269 peer
->su
.sin
.sin_addr
.s_addr
=
1271 else if (addr
% 4 == 2)
1272 peer
->su
.sin
.sin_addr
.s_addr
=
1274 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1275 peer
->su
.sin
.sin_len
=
1276 sizeof(struct sockaddr_in
);
1277 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1279 } else if (p
.prefixlen
== 31) {
1280 peer
->su
.sa
.sa_family
= AF_INET
;
1281 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1283 peer
->su
.sin
.sin_addr
.s_addr
=
1286 peer
->su
.sin
.sin_addr
.s_addr
=
1288 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1289 peer
->su
.sin
.sin_len
=
1290 sizeof(struct sockaddr_in
);
1291 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1293 } else if (bgp_debug_neighbor_events(peer
))
1295 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1303 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1304 struct interface
*ifp
)
1306 struct nbr_connected
*ifc_nbr
;
1308 /* Have we learnt the peer's IPv6 link-local address? */
1309 if (ifp
->nbr_connected
1310 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1311 peer
->su
.sa
.sa_family
= AF_INET6
;
1312 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1313 sizeof(struct in6_addr
));
1315 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1317 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1325 * Set or reset the peer address socketunion structure based on the
1326 * learnt/derived peer address. If the address has changed, update the
1327 * password on the listen socket, if needed.
1329 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1331 struct interface
*ifp
;
1333 int peer_addr_updated
= 0;
1339 * Our peer structure is stored in the bgp->peerhash
1340 * release it before we modify anything.
1342 hash_release(peer
->bgp
->peerhash
, peer
);
1344 prev_family
= peer
->su
.sa
.sa_family
;
1345 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1347 /* If BGP unnumbered is not "v6only", we first see if we can
1349 * peer's IPv4 address.
1351 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1353 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1355 /* If "v6only" or we can't derive peer's IPv4 address, see if
1357 * learnt the peer's IPv6 link-local address. This is from the
1359 * IPv6 address in router advertisement.
1361 if (!peer_addr_updated
)
1363 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1365 /* If we could derive the peer address, we may need to install the
1367 * configured for the peer, if any, on the listen socket. Otherwise,
1369 * that peer's address is not available and uninstall the password, if
1372 if (peer_addr_updated
) {
1373 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1374 && prev_family
== AF_UNSPEC
)
1377 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1378 && prev_family
!= AF_UNSPEC
)
1379 bgp_md5_unset(peer
);
1380 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1381 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1385 * Since our su changed we need to del/add peer to the peerhash
1387 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1390 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1393 struct bgp_node
*rn
, *nrn
;
1395 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1396 rn
= bgp_route_next(rn
)) {
1397 if (rn
->info
!= NULL
) {
1398 /* Special handling for 2-level routing
1400 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1401 || safi
== SAFI_EVPN
) {
1402 for (nrn
= bgp_table_top(
1403 (struct bgp_table
*)(rn
->info
));
1404 nrn
; nrn
= bgp_route_next(nrn
))
1405 bgp_process(bgp
, nrn
, afi
, safi
);
1407 bgp_process(bgp
, rn
, afi
, safi
);
1412 /* Force a bestpath recalculation for all prefixes. This is used
1413 * when 'bgp bestpath' commands are entered.
1415 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1420 FOREACH_AFI_SAFI (afi
, safi
) {
1421 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1425 /* Create new BGP peer. */
1426 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1427 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1428 int as_type
, afi_t afi
, safi_t safi
,
1429 struct peer_group
*group
)
1433 char buf
[SU_ADDRSTRLEN
];
1435 peer
= peer_new(bgp
);
1437 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1438 bgp_peer_conf_if_to_su_update(peer
);
1440 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1441 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1444 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1446 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1447 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1449 peer
->local_as
= local_as
;
1450 peer
->as
= remote_as
;
1451 peer
->as_type
= as_type
;
1452 peer
->local_id
= bgp
->router_id
;
1453 peer
->v_holdtime
= bgp
->default_holdtime
;
1454 peer
->v_keepalive
= bgp
->default_keepalive
;
1455 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1456 ? BGP_DEFAULT_IBGP_ROUTEADV
1457 : BGP_DEFAULT_EBGP_ROUTEADV
;
1459 peer
= peer_lock(peer
); /* bgp peer list reference */
1460 peer
->group
= group
;
1461 listnode_add_sort(bgp
->peer
, peer
);
1462 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1464 /* Adjust update-group coalesce timer heuristics for # peers. */
1465 if (bgp
->heuristic_coalesce
) {
1466 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1468 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1469 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1472 active
= peer_active(peer
);
1474 /* Last read and reset time set */
1475 peer
->readtime
= peer
->resettime
= bgp_clock();
1477 /* Default TTL set. */
1478 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1480 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1483 peer
->afc
[afi
][safi
] = 1;
1484 peer_af_create(peer
, afi
, safi
);
1487 /* auto shutdown if configured */
1488 if (bgp
->autoshutdown
)
1489 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1490 /* Set up peer's events and timers. */
1491 else if (!active
&& peer_active(peer
))
1492 bgp_timer_set(peer
);
1497 /* Make accept BGP peer. This function is only called from the test code */
1498 struct peer
*peer_create_accept(struct bgp
*bgp
)
1502 peer
= peer_new(bgp
);
1504 peer
= peer_lock(peer
); /* bgp peer list reference */
1505 listnode_add_sort(bgp
->peer
, peer
);
1511 * Return true if we have a peer configured to use this afi/safi
1513 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1515 struct listnode
*node
;
1518 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1519 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1522 if (peer
->afc
[afi
][safi
])
1529 /* Change peer's AS number. */
1530 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1532 bgp_peer_sort_t type
;
1535 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1536 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1537 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1538 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1539 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1541 bgp_session_reset(peer
);
1543 type
= peer_sort(peer
);
1545 peer
->as_type
= as_specified
;
1547 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1548 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1549 && peer
->bgp
->as
!= as
)
1550 peer
->local_as
= peer
->bgp
->confed_id
;
1552 peer
->local_as
= peer
->bgp
->as
;
1554 /* Advertisement-interval reset */
1555 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1556 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1557 ? BGP_DEFAULT_IBGP_ROUTEADV
1558 : BGP_DEFAULT_EBGP_ROUTEADV
;
1562 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1564 else if (type
== BGP_PEER_IBGP
)
1567 /* reflector-client reset */
1568 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1569 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1570 PEER_FLAG_REFLECTOR_CLIENT
);
1571 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1572 PEER_FLAG_REFLECTOR_CLIENT
);
1573 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1574 PEER_FLAG_REFLECTOR_CLIENT
);
1575 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1576 PEER_FLAG_REFLECTOR_CLIENT
);
1577 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1578 PEER_FLAG_REFLECTOR_CLIENT
);
1579 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1580 PEER_FLAG_REFLECTOR_CLIENT
);
1581 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1582 PEER_FLAG_REFLECTOR_CLIENT
);
1583 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1584 PEER_FLAG_REFLECTOR_CLIENT
);
1585 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1586 PEER_FLAG_REFLECTOR_CLIENT
);
1587 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1588 PEER_FLAG_REFLECTOR_CLIENT
);
1589 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1590 PEER_FLAG_REFLECTOR_CLIENT
);
1591 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1592 PEER_FLAG_REFLECTOR_CLIENT
);
1593 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1594 PEER_FLAG_REFLECTOR_CLIENT
);
1597 /* local-as reset */
1598 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1599 peer
->change_local_as
= 0;
1600 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1601 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1602 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1606 /* If peer does not exist, create new one. If peer already exists,
1607 set AS number to the peer. */
1608 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1609 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1615 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1617 peer
= peer_lookup(bgp
, su
);
1620 /* Not allowed for a dynamic peer. */
1621 if (peer_dynamic_neighbor(peer
)) {
1623 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1626 /* When this peer is a member of peer-group. */
1628 if (peer
->group
->conf
->as
) {
1629 /* Return peer group's AS number. */
1630 *as
= peer
->group
->conf
->as
;
1631 return BGP_ERR_PEER_GROUP_MEMBER
;
1633 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1634 if ((as_type
!= AS_INTERNAL
)
1635 && (bgp
->as
!= *as
)) {
1637 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1640 if ((as_type
!= AS_EXTERNAL
)
1641 && (bgp
->as
== *as
)) {
1643 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1648 /* Existing peer's AS number change. */
1649 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1650 || (peer
->as_type
!= as_type
))
1651 peer_as_change(peer
, *as
, as_type
);
1654 return BGP_ERR_NO_INTERFACE_CONFIG
;
1656 /* If the peer is not part of our confederation, and its not an
1657 iBGP peer then spoof the source AS */
1658 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1659 && !bgp_confederation_peers_check(bgp
, *as
)
1661 local_as
= bgp
->confed_id
;
1665 /* If this is IPv4 unicast configuration and "no bgp default
1666 ipv4-unicast" is specified. */
1668 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1669 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1670 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1673 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1680 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1681 struct peer
*peer
, afi_t afi
,
1685 int out
= FILTER_OUT
;
1687 uint32_t pflags_ovrd
;
1688 uint8_t *pfilter_ovrd
;
1692 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1693 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1695 /* peer af_flags apply */
1696 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1697 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1698 ^ peer
->af_flags_invert
[afi
][safi
];
1699 flags_tmp
&= ~pflags_ovrd
;
1701 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1702 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1703 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1704 conf
->af_flags_invert
[afi
][safi
]);
1706 /* maximum-prefix */
1707 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1708 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1709 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1710 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1714 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1715 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1718 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1719 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1721 /* default-originate route-map */
1722 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1723 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1724 MTYPE_ROUTE_MAP_NAME
);
1725 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1728 /* inbound filter apply */
1729 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1730 PEER_STR_ATTR_INHERIT(peer
, group
,
1731 filter
[afi
][safi
].dlist
[in
].name
,
1732 MTYPE_BGP_FILTER_NAME
);
1733 PEER_ATTR_INHERIT(peer
, group
,
1734 filter
[afi
][safi
].dlist
[in
].alist
);
1737 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1738 PEER_STR_ATTR_INHERIT(peer
, group
,
1739 filter
[afi
][safi
].plist
[in
].name
,
1740 MTYPE_BGP_FILTER_NAME
);
1741 PEER_ATTR_INHERIT(peer
, group
,
1742 filter
[afi
][safi
].plist
[in
].plist
);
1745 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1746 PEER_STR_ATTR_INHERIT(peer
, group
,
1747 filter
[afi
][safi
].aslist
[in
].name
,
1748 MTYPE_BGP_FILTER_NAME
);
1749 PEER_ATTR_INHERIT(peer
, group
,
1750 filter
[afi
][safi
].aslist
[in
].aslist
);
1753 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1754 PEER_STR_ATTR_INHERIT(peer
, group
,
1755 filter
[afi
][safi
].map
[in
].name
,
1756 MTYPE_BGP_FILTER_NAME
);
1757 PEER_ATTR_INHERIT(peer
, group
,
1758 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1761 /* outbound filter apply */
1762 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1763 PEER_STR_ATTR_INHERIT(peer
, group
,
1764 filter
[afi
][safi
].dlist
[out
].name
,
1765 MTYPE_BGP_FILTER_NAME
);
1766 PEER_ATTR_INHERIT(peer
, group
,
1767 filter
[afi
][safi
].dlist
[out
].alist
);
1770 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1771 PEER_STR_ATTR_INHERIT(peer
, group
,
1772 filter
[afi
][safi
].plist
[out
].name
,
1773 MTYPE_BGP_FILTER_NAME
);
1774 PEER_ATTR_INHERIT(peer
, group
,
1775 filter
[afi
][safi
].plist
[out
].plist
);
1778 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1779 PEER_STR_ATTR_INHERIT(peer
, group
,
1780 filter
[afi
][safi
].aslist
[out
].name
,
1781 MTYPE_BGP_FILTER_NAME
);
1782 PEER_ATTR_INHERIT(peer
, group
,
1783 filter
[afi
][safi
].aslist
[out
].aslist
);
1786 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1787 PEER_STR_ATTR_INHERIT(peer
, group
,
1788 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1789 MTYPE_BGP_FILTER_NAME
);
1790 PEER_ATTR_INHERIT(peer
, group
,
1791 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1794 /* nondirectional filter apply */
1795 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1796 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1797 MTYPE_BGP_FILTER_NAME
);
1798 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1802 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1807 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1808 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1809 __func__
, peer
->host
);
1813 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1815 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1816 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1817 return BGP_ERR_PEER_SAFI_CONFLICT
;
1819 /* Nothing to do if we've already activated this peer */
1820 if (peer
->afc
[afi
][safi
])
1823 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1826 active
= peer_active(peer
);
1827 peer
->afc
[afi
][safi
] = 1;
1830 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1832 if (!active
&& peer_active(peer
)) {
1833 bgp_timer_set(peer
);
1835 if (peer
->status
== Established
) {
1836 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1837 peer
->afc_adv
[afi
][safi
] = 1;
1838 bgp_capability_send(peer
, afi
, safi
,
1840 CAPABILITY_ACTION_SET
);
1841 if (peer
->afc_recv
[afi
][safi
]) {
1842 peer
->afc_nego
[afi
][safi
] = 1;
1843 bgp_announce_route(peer
, afi
, safi
);
1846 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1847 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1848 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1851 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1852 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1853 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1854 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1857 * If we are turning on a AFI/SAFI locally and we've
1858 * started bringing a peer up, we need to tell
1859 * the other peer to restart because we might loose
1860 * configuration here because when the doppelganger
1861 * gets to a established state due to how
1862 * we resolve we could just overwrite the afi/safi
1865 other
= peer
->doppelganger
;
1867 && (other
->status
== OpenSent
1868 || other
->status
== OpenConfirm
)) {
1869 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1870 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1871 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1878 /* Activate the peer or peer group for specified AFI and SAFI. */
1879 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1882 struct peer_group
*group
;
1883 struct listnode
*node
, *nnode
;
1884 struct peer
*tmp_peer
;
1887 /* Nothing to do if we've already activated this peer */
1888 if (peer
->afc
[afi
][safi
])
1893 /* This is a peer-group so activate all of the members of the
1894 * peer-group as well */
1895 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1897 /* Do not activate a peer for both SAFI_UNICAST and
1898 * SAFI_LABELED_UNICAST */
1899 if ((safi
== SAFI_UNICAST
1900 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1901 || (safi
== SAFI_LABELED_UNICAST
1902 && peer
->afc
[afi
][SAFI_UNICAST
]))
1903 return BGP_ERR_PEER_SAFI_CONFLICT
;
1905 peer
->afc
[afi
][safi
] = 1;
1906 group
= peer
->group
;
1908 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1909 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1912 ret
|= peer_activate_af(peer
, afi
, safi
);
1915 /* If this is the first peer to be activated for this
1916 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1917 if (safi
== SAFI_LABELED_UNICAST
1918 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1920 if (BGP_DEBUG(zebra
, ZEBRA
))
1922 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1924 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1925 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1928 if (safi
== SAFI_FLOWSPEC
) {
1929 /* connect to table manager */
1930 bgp_zebra_init_tm_connect(bgp
);
1935 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1938 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1939 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1940 __func__
, peer
->host
);
1944 /* Nothing to do if we've already deactivated this peer */
1945 if (!peer
->afc
[afi
][safi
])
1948 /* De-activate the address family configuration. */
1949 peer
->afc
[afi
][safi
] = 0;
1951 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1952 flog_err(EC_BGP_PEER_DELETE
,
1953 "couldn't delete af structure for peer %s",
1958 if (peer
->status
== Established
) {
1959 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1960 peer
->afc_adv
[afi
][safi
] = 0;
1961 peer
->afc_nego
[afi
][safi
] = 0;
1963 if (peer_active_nego(peer
)) {
1964 bgp_capability_send(peer
, afi
, safi
,
1966 CAPABILITY_ACTION_UNSET
);
1967 bgp_clear_route(peer
, afi
, safi
);
1968 peer
->pcount
[afi
][safi
] = 0;
1970 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1971 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1972 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1975 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1976 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1977 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1984 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1987 struct peer_group
*group
;
1988 struct peer
*tmp_peer
;
1989 struct listnode
*node
, *nnode
;
1992 /* Nothing to do if we've already de-activated this peer */
1993 if (!peer
->afc
[afi
][safi
])
1996 /* This is a peer-group so de-activate all of the members of the
1997 * peer-group as well */
1998 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1999 peer
->afc
[afi
][safi
] = 0;
2000 group
= peer
->group
;
2002 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2003 flog_err(EC_BGP_PEER_DELETE
,
2004 "couldn't delete af structure for peer %s",
2008 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2009 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2012 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2017 /* If this is the last peer to be deactivated for this
2018 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2019 if (safi
== SAFI_LABELED_UNICAST
2020 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2021 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2023 if (BGP_DEBUG(zebra
, ZEBRA
))
2025 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2027 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2028 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2033 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2036 return peer_activate(peer
, afi
, safi
);
2038 return peer_deactivate(peer
, afi
, safi
);
2041 static void peer_nsf_stop(struct peer
*peer
)
2046 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2047 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2049 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2050 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2051 peer
->nsf
[afi
][safi
] = 0;
2053 if (peer
->t_gr_restart
) {
2054 BGP_TIMER_OFF(peer
->t_gr_restart
);
2055 if (bgp_debug_neighbor_events(peer
))
2056 zlog_debug("%s graceful restart timer stopped",
2059 if (peer
->t_gr_stale
) {
2060 BGP_TIMER_OFF(peer
->t_gr_stale
);
2061 if (bgp_debug_neighbor_events(peer
))
2063 "%s graceful restart stalepath timer stopped",
2066 bgp_clear_route_all(peer
);
2069 /* Delete peer from confguration.
2071 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2072 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2074 * This function /should/ take care to be idempotent, to guard against
2075 * it being called multiple times through stray events that come in
2076 * that happen to result in this function being called again. That
2077 * said, getting here for a "Deleted" peer is a bug in the neighbour
2080 int peer_delete(struct peer
*peer
)
2086 struct bgp_filter
*filter
;
2087 struct listnode
*pn
;
2090 assert(peer
->status
!= Deleted
);
2093 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2095 bgp_reads_off(peer
);
2096 bgp_writes_off(peer
);
2097 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2098 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2100 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2101 peer_nsf_stop(peer
);
2103 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2105 /* If this peer belongs to peer group, clear up the
2108 if (peer_dynamic_neighbor(peer
))
2109 peer_drop_dynamic_neighbor(peer
);
2111 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2113 peer
); /* group->peer list reference */
2114 list_delete_node(peer
->group
->peer
, pn
);
2119 /* Withdraw all information from routing table. We can not use
2120 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2121 * executed after peer structure is deleted.
2123 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2125 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2127 if (peer
->doppelganger
) {
2128 peer
->doppelganger
->doppelganger
= NULL
;
2129 peer
->doppelganger
= NULL
;
2132 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2133 bgp_fsm_change_status(peer
, Deleted
);
2135 /* Remove from NHT */
2136 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2137 bgp_unlink_nexthop_by_peer(peer
);
2139 /* Password configuration */
2140 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2141 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2143 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2144 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2145 bgp_md5_unset(peer
);
2148 bgp_timer_set(peer
); /* stops all timers for Deleted */
2150 /* Delete from all peer list. */
2151 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2152 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2153 peer_unlock(peer
); /* bgp peer list reference */
2154 list_delete_node(bgp
->peer
, pn
);
2155 hash_release(bgp
->peerhash
, peer
);
2160 stream_fifo_free(peer
->ibuf
);
2165 stream_fifo_free(peer
->obuf
);
2169 if (peer
->ibuf_work
) {
2170 ringbuf_del(peer
->ibuf_work
);
2171 peer
->ibuf_work
= NULL
;
2174 if (peer
->obuf_work
) {
2175 stream_free(peer
->obuf_work
);
2176 peer
->obuf_work
= NULL
;
2179 if (peer
->scratch
) {
2180 stream_free(peer
->scratch
);
2181 peer
->scratch
= NULL
;
2184 /* Local and remote addresses. */
2185 if (peer
->su_local
) {
2186 sockunion_free(peer
->su_local
);
2187 peer
->su_local
= NULL
;
2190 if (peer
->su_remote
) {
2191 sockunion_free(peer
->su_remote
);
2192 peer
->su_remote
= NULL
;
2195 /* Free filter related memory. */
2196 FOREACH_AFI_SAFI (afi
, safi
) {
2197 filter
= &peer
->filter
[afi
][safi
];
2199 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2200 if (filter
->dlist
[i
].name
) {
2201 XFREE(MTYPE_BGP_FILTER_NAME
,
2202 filter
->dlist
[i
].name
);
2203 filter
->dlist
[i
].name
= NULL
;
2206 if (filter
->plist
[i
].name
) {
2207 XFREE(MTYPE_BGP_FILTER_NAME
,
2208 filter
->plist
[i
].name
);
2209 filter
->plist
[i
].name
= NULL
;
2212 if (filter
->aslist
[i
].name
) {
2213 XFREE(MTYPE_BGP_FILTER_NAME
,
2214 filter
->aslist
[i
].name
);
2215 filter
->aslist
[i
].name
= NULL
;
2219 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2220 if (filter
->map
[i
].name
) {
2221 XFREE(MTYPE_BGP_FILTER_NAME
,
2222 filter
->map
[i
].name
);
2223 filter
->map
[i
].name
= NULL
;
2227 if (filter
->usmap
.name
) {
2228 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2229 filter
->usmap
.name
= NULL
;
2232 if (peer
->default_rmap
[afi
][safi
].name
) {
2233 XFREE(MTYPE_ROUTE_MAP_NAME
,
2234 peer
->default_rmap
[afi
][safi
].name
);
2235 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2239 FOREACH_AFI_SAFI (afi
, safi
)
2240 peer_af_delete(peer
, afi
, safi
);
2242 if (peer
->hostname
) {
2243 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2244 peer
->hostname
= NULL
;
2247 if (peer
->domainname
) {
2248 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2249 peer
->domainname
= NULL
;
2252 peer_unlock(peer
); /* initial reference */
2257 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2259 return strcmp(g1
->name
, g2
->name
);
2262 /* Peer group cofiguration. */
2263 static struct peer_group
*peer_group_new(void)
2265 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2266 sizeof(struct peer_group
));
2269 static void peer_group_free(struct peer_group
*group
)
2271 XFREE(MTYPE_PEER_GROUP
, group
);
2274 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2276 struct peer_group
*group
;
2277 struct listnode
*node
, *nnode
;
2279 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2280 if (strcmp(group
->name
, name
) == 0)
2286 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2288 struct peer_group
*group
;
2291 group
= peer_group_lookup(bgp
, name
);
2295 group
= peer_group_new();
2298 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2299 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2300 group
->peer
= list_new();
2301 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2302 group
->listen_range
[afi
] = list_new();
2303 group
->conf
= peer_new(bgp
);
2304 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2305 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2306 if (group
->conf
->host
)
2307 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2308 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2309 group
->conf
->group
= group
;
2310 group
->conf
->as
= 0;
2311 group
->conf
->ttl
= 1;
2312 group
->conf
->gtsm_hops
= 0;
2313 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2314 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2315 listnode_add_sort(bgp
->group
, group
);
2320 static void peer_group2peer_config_copy(struct peer_group
*group
,
2330 peer
->as
= conf
->as
;
2333 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2334 peer
->change_local_as
= conf
->change_local_as
;
2337 peer
->ttl
= conf
->ttl
;
2340 peer
->gtsm_hops
= conf
->gtsm_hops
;
2342 /* peer flags apply */
2343 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2344 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2345 flags_tmp
&= ~peer
->flags_override
;
2347 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2348 SET_FLAG(peer
->flags
, flags_tmp
);
2349 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2351 /* peer timers apply */
2352 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2353 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2354 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2357 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2358 PEER_ATTR_INHERIT(peer
, group
, connect
);
2359 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2360 peer
->v_connect
= conf
->connect
;
2362 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2365 /* advertisement-interval apply */
2366 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2367 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2368 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2369 peer
->v_routeadv
= conf
->routeadv
;
2371 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2372 ? BGP_DEFAULT_IBGP_ROUTEADV
2373 : BGP_DEFAULT_EBGP_ROUTEADV
;
2376 /* password apply */
2377 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2378 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2379 MTYPE_PEER_PASSWORD
);
2381 if (!BGP_PEER_SU_UNSPEC(peer
))
2384 /* update-source apply */
2385 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2386 if (conf
->update_source
) {
2387 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2388 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2389 } else if (conf
->update_if
) {
2390 sockunion_free(peer
->update_source
);
2391 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2392 MTYPE_PEER_UPDATE_SOURCE
);
2396 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2399 /* Peer group's remote AS configuration. */
2400 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2403 struct peer_group
*group
;
2405 struct listnode
*node
, *nnode
;
2407 group
= peer_group_lookup(bgp
, group_name
);
2411 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2415 /* When we setup peer-group AS number all peer group member's AS
2416 number must be updated to same number. */
2417 peer_as_change(group
->conf
, *as
, as_type
);
2419 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2420 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2421 || (peer
->as_type
!= as_type
))
2422 peer_as_change(peer
, *as
, as_type
);
2428 int peer_group_delete(struct peer_group
*group
)
2432 struct prefix
*prefix
;
2434 struct listnode
*node
, *nnode
;
2439 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2440 other
= peer
->doppelganger
;
2442 if (other
&& other
->status
!= Deleted
) {
2443 other
->group
= NULL
;
2447 list_delete(&group
->peer
);
2449 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2450 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2452 prefix_free(prefix
);
2454 list_delete(&group
->listen_range
[afi
]);
2457 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2460 bfd_info_free(&(group
->conf
->bfd_info
));
2462 group
->conf
->group
= NULL
;
2463 peer_delete(group
->conf
);
2465 /* Delete from all peer_group list. */
2466 listnode_delete(bgp
->group
, group
);
2468 peer_group_free(group
);
2473 int peer_group_remote_as_delete(struct peer_group
*group
)
2475 struct peer
*peer
, *other
;
2476 struct listnode
*node
, *nnode
;
2478 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2479 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2482 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2483 other
= peer
->doppelganger
;
2487 if (other
&& other
->status
!= Deleted
) {
2488 other
->group
= NULL
;
2492 list_delete_all_node(group
->peer
);
2494 group
->conf
->as
= 0;
2495 group
->conf
->as_type
= AS_UNSPECIFIED
;
2500 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2502 struct prefix
*prefix
;
2503 struct listnode
*node
, *nnode
;
2506 afi
= family2afi(range
->family
);
2508 /* Group needs remote AS configured. */
2509 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2510 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2512 /* Ensure no duplicates. Currently we don't care about overlaps. */
2513 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2514 if (prefix_same(range
, prefix
))
2518 prefix
= prefix_new();
2519 prefix_copy(prefix
, range
);
2520 listnode_add(group
->listen_range
[afi
], prefix
);
2524 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2526 struct prefix
*prefix
, prefix2
;
2527 struct listnode
*node
, *nnode
;
2530 char buf
[PREFIX2STR_BUFFER
];
2532 afi
= family2afi(range
->family
);
2534 /* Identify the listen range. */
2535 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2536 if (prefix_same(range
, prefix
))
2541 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2543 prefix2str(prefix
, buf
, sizeof(buf
));
2545 /* Dispose off any dynamic neighbors that exist due to this listen range
2547 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2548 if (!peer_dynamic_neighbor(peer
))
2551 sockunion2hostprefix(&peer
->su
, &prefix2
);
2552 if (prefix_match(prefix
, &prefix2
)) {
2553 if (bgp_debug_neighbor_events(peer
))
2555 "Deleting dynamic neighbor %s group %s upon "
2556 "delete of listen range %s",
2557 peer
->host
, group
->name
, buf
);
2562 /* Get rid of the listen range */
2563 listnode_delete(group
->listen_range
[afi
], prefix
);
2568 /* Bind specified peer to peer group. */
2569 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2570 struct peer_group
*group
, as_t
*as
)
2572 int first_member
= 0;
2576 /* Lookup the peer. */
2578 peer
= peer_lookup(bgp
, su
);
2580 /* The peer exist, bind it to the peer-group */
2582 /* When the peer already belongs to a peer-group, check the
2584 if (peer_group_active(peer
)) {
2586 /* The peer is already bound to the peer-group,
2589 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2592 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2595 /* The peer has not specified a remote-as, inherit it from the
2597 if (peer
->as_type
== AS_UNSPECIFIED
) {
2598 peer
->as_type
= group
->conf
->as_type
;
2599 peer
->as
= group
->conf
->as
;
2602 if (!group
->conf
->as
) {
2603 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2604 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2607 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2610 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2614 peer_group2peer_config_copy(group
, peer
);
2616 FOREACH_AFI_SAFI (afi
, safi
) {
2617 if (group
->conf
->afc
[afi
][safi
]) {
2618 peer
->afc
[afi
][safi
] = 1;
2620 if (peer_af_find(peer
, afi
, safi
)
2621 || peer_af_create(peer
, afi
, safi
)) {
2622 peer_group2peer_config_copy_af(
2623 group
, peer
, afi
, safi
);
2625 } else if (peer
->afc
[afi
][safi
])
2626 peer_deactivate(peer
, afi
, safi
);
2630 assert(group
&& peer
->group
== group
);
2632 listnode_delete(bgp
->peer
, peer
);
2634 peer
->group
= group
;
2635 listnode_add_sort(bgp
->peer
, peer
);
2637 peer
= peer_lock(peer
); /* group->peer list reference */
2638 listnode_add(group
->peer
, peer
);
2642 /* Advertisement-interval reset */
2643 if (!CHECK_FLAG(group
->conf
->flags
,
2644 PEER_FLAG_ROUTEADV
)) {
2645 group
->conf
->v_routeadv
=
2646 (peer_sort(group
->conf
)
2648 ? BGP_DEFAULT_IBGP_ROUTEADV
2649 : BGP_DEFAULT_EBGP_ROUTEADV
;
2652 /* ebgp-multihop reset */
2653 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2654 group
->conf
->ttl
= MAXTTL
;
2656 /* local-as reset */
2657 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2658 group
->conf
->change_local_as
= 0;
2659 peer_flag_unset(group
->conf
,
2660 PEER_FLAG_LOCAL_AS
);
2661 peer_flag_unset(group
->conf
,
2662 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2663 peer_flag_unset(group
->conf
,
2664 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2668 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2670 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2671 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2672 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2673 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2675 bgp_session_reset(peer
);
2679 /* Create a new peer. */
2681 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2682 && (!group
->conf
->as
)) {
2683 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2686 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2687 group
->conf
->as_type
, 0, 0, group
);
2689 peer
= peer_lock(peer
); /* group->peer list reference */
2690 listnode_add(group
->peer
, peer
);
2692 peer_group2peer_config_copy(group
, peer
);
2694 /* If the peer-group is active for this afi/safi then activate
2696 FOREACH_AFI_SAFI (afi
, safi
) {
2697 if (group
->conf
->afc
[afi
][safi
]) {
2698 peer
->afc
[afi
][safi
] = 1;
2699 peer_af_create(peer
, afi
, safi
);
2700 peer_group2peer_config_copy_af(group
, peer
, afi
,
2702 } else if (peer
->afc
[afi
][safi
])
2703 peer_deactivate(peer
, afi
, safi
);
2706 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2708 /* Set up peer's events and timers. */
2709 if (peer_active(peer
))
2710 bgp_timer_set(peer
);
2716 static int bgp_startup_timer_expire(struct thread
*thread
)
2720 bgp
= THREAD_ARG(thread
);
2721 bgp
->t_startup
= NULL
;
2727 * On shutdown we call the cleanup function which
2728 * does a free of the link list nodes, free up
2729 * the data we are pointing at too.
2731 static void bgp_vrf_string_name_delete(void *data
)
2735 XFREE(MTYPE_TMP
, vname
);
2738 /* BGP instance creation by `router bgp' commands. */
2739 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2740 enum bgp_instance_type inst_type
)
2746 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2749 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2750 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2751 zlog_debug("Creating Default VRF, AS %u", *as
);
2753 zlog_debug("Creating %s %s, AS %u",
2754 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2761 bgp
->heuristic_coalesce
= true;
2762 bgp
->inst_type
= inst_type
;
2763 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2765 bgp
->peer_self
= peer_new(bgp
);
2766 if (bgp
->peer_self
->host
)
2767 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2768 bgp
->peer_self
->host
=
2769 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2770 if (bgp
->peer_self
->hostname
!= NULL
) {
2771 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2772 bgp
->peer_self
->hostname
= NULL
;
2774 if (cmd_hostname_get())
2775 bgp
->peer_self
->hostname
=
2776 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2778 if (bgp
->peer_self
->domainname
!= NULL
) {
2779 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2780 bgp
->peer_self
->domainname
= NULL
;
2782 if (cmd_domainname_get())
2783 bgp
->peer_self
->domainname
=
2784 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2785 bgp
->peer
= list_new();
2786 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2787 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2789 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2791 bgp
->group
= list_new();
2792 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2794 FOREACH_AFI_SAFI (afi
, safi
) {
2795 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2796 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2797 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2799 /* Enable maximum-paths */
2800 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2802 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2806 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2807 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2808 bgp
->default_subgroup_pkt_queue_max
=
2809 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2810 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2811 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2812 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2813 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2814 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2815 bgp
->dynamic_neighbors_count
= 0;
2816 #if DFLT_BGP_IMPORT_CHECK
2817 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2819 #if DFLT_BGP_SHOW_HOSTNAME
2820 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2822 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2823 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2825 #if DFLT_BGP_DETERMINISTIC_MED
2826 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2828 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2833 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2834 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2836 assert(bgp
->rfapi_cfg
);
2838 #endif /* ENABLE_BGP_VNC */
2840 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2841 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2842 bgp
->vpn_policy
[afi
].afi
= afi
;
2843 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2844 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2847 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2848 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2849 bgp_vrf_string_name_delete
;
2850 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2851 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2852 bgp_vrf_string_name_delete
;
2855 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2857 /* TODO - The startup timer needs to be run for the whole of BGP
2859 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2860 bgp
->restart_time
, &bgp
->t_startup
);
2863 /* printable name we can use in debug messages */
2864 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2865 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2875 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2877 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2878 snprintf(bgp
->name_pretty
, len
, "%s %s",
2879 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2885 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2886 memory_order_relaxed
);
2887 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2888 memory_order_relaxed
);
2889 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2893 update_bgp_group_init(bgp
);
2895 /* assign a unique rd id for auto derivation of vrf's RD */
2896 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2903 /* Return the "default VRF" instance of BGP. */
2904 struct bgp
*bgp_get_default(void)
2907 struct listnode
*node
, *nnode
;
2909 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2910 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2915 /* Lookup BGP entry. */
2916 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2919 struct listnode
*node
, *nnode
;
2921 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2923 && ((bgp
->name
== NULL
&& name
== NULL
)
2924 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2929 /* Lookup BGP structure by view name. */
2930 struct bgp
*bgp_lookup_by_name(const char *name
)
2933 struct listnode
*node
, *nnode
;
2935 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2936 if ((bgp
->name
== NULL
&& name
== NULL
)
2937 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2942 /* Lookup BGP instance based on VRF id. */
2943 /* Note: Only to be used for incoming messages from Zebra. */
2944 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2948 /* Lookup VRF (in tree) and follow link. */
2949 vrf
= vrf_lookup_by_id(vrf_id
);
2952 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2955 /* handle socket creation or deletion, if necessary
2956 * this is called for all new BGP instances
2958 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
2963 /* Create BGP server socket, if listen mode not disabled */
2964 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
2966 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
2968 * suppress vrf socket
2970 if (create
== FALSE
) {
2971 bgp_close_vrf_socket(bgp
);
2975 return BGP_ERR_INVALID_VALUE
;
2977 * if vrf_id did not change
2979 if (vrf
->vrf_id
== old_vrf_id
)
2981 if (old_vrf_id
!= VRF_UNKNOWN
) {
2982 /* look for old socket. close it. */
2983 bgp_close_vrf_socket(bgp
);
2985 /* if backend is not yet identified ( VRF_UNKNOWN) then
2986 * creation will be done later
2988 if (vrf
->vrf_id
== VRF_UNKNOWN
)
2990 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
2992 return BGP_ERR_INVALID_VALUE
;
2995 return bgp_check_main_socket(create
, bgp
);
2998 /* Called from VTY commands. */
2999 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3000 enum bgp_instance_type inst_type
)
3003 struct vrf
*vrf
= NULL
;
3005 /* Multiple instance check. */
3006 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3008 bgp
= bgp_lookup_by_name(name
);
3010 bgp
= bgp_get_default();
3012 /* Already exists. */
3014 if (bgp
->as
!= *as
) {
3016 return BGP_ERR_INSTANCE_MISMATCH
;
3018 if (bgp
->inst_type
!= inst_type
)
3019 return BGP_ERR_INSTANCE_MISMATCH
;
3024 /* BGP instance name can not be specified for single instance.
3027 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3029 /* Get default BGP structure if exists. */
3030 bgp
= bgp_get_default();
3033 if (bgp
->as
!= *as
) {
3035 return BGP_ERR_AS_MISMATCH
;
3042 bgp
= bgp_create(as
, name
, inst_type
);
3043 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3044 bgp_address_init(bgp
);
3045 bgp_tip_hash_init(bgp
);
3049 bgp
->t_rmap_def_originate_eval
= NULL
;
3051 /* If Default instance or VRF, link to the VRF structure, if present. */
3052 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3053 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3054 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3056 bgp_vrf_link(bgp
, vrf
);
3058 /* BGP server socket already processed if BGP instance
3059 * already part of the list
3061 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3062 listnode_add(bm
->bgp
, bgp
);
3064 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3065 bgp_zebra_instance_register(bgp
);
3072 * Make BGP instance "up". Applies only to VRFs (non-default) and
3073 * implies the VRF has been learnt from Zebra.
3075 void bgp_instance_up(struct bgp
*bgp
)
3078 struct listnode
*node
, *next
;
3080 /* Register with zebra. */
3081 bgp_zebra_instance_register(bgp
);
3083 /* Kick off any peers that may have been configured. */
3084 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3085 if (!BGP_PEER_START_SUPPRESSED(peer
))
3086 BGP_EVENT_ADD(peer
, BGP_Start
);
3089 /* Process any networks that have been configured. */
3090 bgp_static_add(bgp
);
3094 * Make BGP instance "down". Applies only to VRFs (non-default) and
3095 * implies the VRF has been deleted by Zebra.
3097 void bgp_instance_down(struct bgp
*bgp
)
3100 struct listnode
*node
;
3101 struct listnode
*next
;
3104 if (bgp
->t_rmap_def_originate_eval
) {
3105 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3106 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3110 /* Bring down peers, so corresponding routes are purged. */
3111 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3112 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3113 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3114 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3116 bgp_session_reset(peer
);
3119 /* Purge network and redistributed routes. */
3120 bgp_purge_static_redist_routes(bgp
);
3122 /* Cleanup registered nexthops (flags) */
3123 bgp_cleanup_nexthops(bgp
);
3126 /* Delete BGP instance. */
3127 int bgp_delete(struct bgp
*bgp
)
3130 struct peer_group
*group
;
3131 struct listnode
*node
, *next
;
3137 THREAD_OFF(bgp
->t_startup
);
3138 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3139 THREAD_OFF(bgp
->t_update_delay
);
3140 THREAD_OFF(bgp
->t_establish_wait
);
3142 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3143 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3144 zlog_debug("Deleting Default VRF");
3146 zlog_debug("Deleting %s %s",
3147 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3153 /* unmap from RT list */
3154 bgp_evpn_vrf_delete(bgp
);
3157 if (bgp
->t_rmap_def_originate_eval
) {
3158 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3159 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3163 /* Inform peers we're going down. */
3164 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3165 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3166 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3167 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3170 /* Delete static routes (networks). */
3171 bgp_static_delete(bgp
);
3173 /* Unset redistribution. */
3174 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3175 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3176 if (i
!= ZEBRA_ROUTE_BGP
)
3177 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3179 /* Free peers and peer-groups. */
3180 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3181 peer_group_delete(group
);
3183 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3186 if (bgp
->peer_self
) {
3187 peer_delete(bgp
->peer_self
);
3188 bgp
->peer_self
= NULL
;
3191 update_bgp_group_free(bgp
);
3193 /* TODO - Other memory may need to be freed - e.g., NHT */
3198 bgp_cleanup_routes(bgp
);
3200 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3201 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3204 &bgp
->vpn_policy
[afi
]
3205 .import_redirect_rtlist
);
3206 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3209 /* Deregister from Zebra, if needed */
3210 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3211 bgp_zebra_instance_deregister(bgp
);
3213 /* Remove visibility via the master list - there may however still be
3214 * routes to be processed still referencing the struct bgp.
3216 listnode_delete(bm
->bgp
, bgp
);
3218 /* Free interfaces in this instance. */
3221 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3222 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3224 bgp_vrf_unlink(bgp
, vrf
);
3226 thread_master_free_unused(bm
->master
);
3227 bgp_unlock(bgp
); /* initial reference */
3232 void bgp_free(struct bgp
*bgp
)
3236 struct bgp_table
*table
;
3237 struct bgp_node
*rn
;
3238 struct bgp_rmap
*rmap
;
3242 list_delete(&bgp
->group
);
3243 list_delete(&bgp
->peer
);
3245 if (bgp
->peerhash
) {
3246 hash_free(bgp
->peerhash
);
3247 bgp
->peerhash
= NULL
;
3250 FOREACH_AFI_SAFI (afi
, safi
) {
3251 /* Special handling for 2-level routing tables. */
3252 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3253 || safi
== SAFI_EVPN
) {
3254 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3255 rn
= bgp_route_next(rn
)) {
3256 table
= (struct bgp_table
*)rn
->info
;
3257 bgp_table_finish(&table
);
3260 if (bgp
->route
[afi
][safi
])
3261 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3262 if (bgp
->aggregate
[afi
][safi
])
3263 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3264 if (bgp
->rib
[afi
][safi
])
3265 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3266 rmap
= &bgp
->table_map
[afi
][safi
];
3268 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3271 bgp_scan_finish(bgp
);
3272 bgp_address_destroy(bgp
);
3273 bgp_tip_hash_destroy(bgp
);
3275 /* release the auto RD id */
3276 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3278 bgp_evpn_cleanup(bgp
);
3279 bgp_pbr_cleanup(bgp
);
3281 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3282 vpn_policy_direction_t dir
;
3284 if (bgp
->vpn_policy
[afi
].import_vrf
)
3285 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3286 if (bgp
->vpn_policy
[afi
].export_vrf
)
3287 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3289 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3290 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3291 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3292 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3293 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3294 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3298 XFREE(MTYPE_BGP
, bgp
->name
);
3299 if (bgp
->name_pretty
)
3300 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3302 XFREE(MTYPE_BGP
, bgp
);
3305 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3308 struct listnode
*node
, *nnode
;
3314 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3315 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3316 && !CHECK_FLAG(peer
->sflags
,
3317 PEER_STATUS_ACCEPT_PEER
))
3319 } else if (bm
->bgp
!= NULL
) {
3320 struct listnode
*bgpnode
, *nbgpnode
;
3322 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3323 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3325 && !strcmp(peer
->conf_if
, conf_if
)
3326 && !CHECK_FLAG(peer
->sflags
,
3327 PEER_STATUS_ACCEPT_PEER
))
3333 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3336 struct listnode
*node
, *nnode
;
3342 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3343 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3344 && !CHECK_FLAG(peer
->sflags
,
3345 PEER_STATUS_ACCEPT_PEER
))
3347 } else if (bm
->bgp
!= NULL
) {
3348 struct listnode
*bgpnode
, *nbgpnode
;
3350 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3351 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3353 && !strcmp(peer
->hostname
, hostname
)
3354 && !CHECK_FLAG(peer
->sflags
,
3355 PEER_STATUS_ACCEPT_PEER
))
3361 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3363 struct peer
*peer
= NULL
;
3364 struct peer tmp_peer
;
3366 memset(&tmp_peer
, 0, sizeof(struct peer
));
3369 * We do not want to find the doppelganger peer so search for the peer
3371 * the hash that has PEER_FLAG_CONFIG_NODE
3373 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3378 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3379 } else if (bm
->bgp
!= NULL
) {
3380 struct listnode
*bgpnode
, *nbgpnode
;
3382 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3383 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3392 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3393 union sockunion
*su
,
3394 struct peer_group
*group
)
3400 /* Create peer first; we've already checked group config is valid. */
3401 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3402 group
->conf
->as_type
, 0, 0, group
);
3407 peer
= peer_lock(peer
);
3408 listnode_add(group
->peer
, peer
);
3410 peer_group2peer_config_copy(group
, peer
);
3413 * Bind peer for all AFs configured for the group. We don't call
3414 * peer_group_bind as that is sub-optimal and does some stuff we don't
3417 FOREACH_AFI_SAFI (afi
, safi
) {
3418 if (!group
->conf
->afc
[afi
][safi
])
3420 peer
->afc
[afi
][safi
] = 1;
3422 if (!peer_af_find(peer
, afi
, safi
))
3423 peer_af_create(peer
, afi
, safi
);
3425 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3428 /* Mark as dynamic, but also as a "config node" for other things to
3430 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3431 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3437 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3438 struct prefix
*prefix
)
3440 struct listnode
*node
, *nnode
;
3441 struct prefix
*range
;
3444 afi
= family2afi(prefix
->family
);
3446 if (group
->listen_range
[afi
])
3447 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3449 if (prefix_match(range
, prefix
))
3456 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3457 struct prefix
**listen_range
)
3459 struct prefix
*range
= NULL
;
3460 struct peer_group
*group
= NULL
;
3461 struct listnode
*node
, *nnode
;
3463 *listen_range
= NULL
;
3465 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3466 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3469 } else if (bm
->bgp
!= NULL
) {
3470 struct listnode
*bgpnode
, *nbgpnode
;
3472 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3473 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3474 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3480 *listen_range
= range
;
3481 return (group
&& range
) ? group
: NULL
;
3484 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3486 struct peer_group
*group
;
3489 struct prefix prefix
;
3490 struct prefix
*listen_range
;
3492 char buf
[PREFIX2STR_BUFFER
];
3493 char buf1
[PREFIX2STR_BUFFER
];
3495 sockunion2hostprefix(su
, &prefix
);
3497 /* See if incoming connection matches a configured listen range. */
3498 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3509 prefix2str(&prefix
, buf
, sizeof(buf
));
3510 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3512 if (bgp_debug_neighbor_events(NULL
))
3514 "Dynamic Neighbor %s matches group %s listen range %s",
3515 buf
, group
->name
, buf1
);
3517 /* Are we within the listen limit? */
3518 dncount
= gbgp
->dynamic_neighbors_count
;
3520 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3521 if (bgp_debug_neighbor_events(NULL
))
3522 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3523 inet_sutop(su
, buf
),
3524 gbgp
->dynamic_neighbors_limit
);
3528 /* Ensure group is not disabled. */
3529 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3530 if (bgp_debug_neighbor_events(NULL
))
3532 "Dynamic Neighbor %s rejected - group %s disabled",
3537 /* Check that at least one AF is activated for the group. */
3538 if (!peer_group_af_configured(group
)) {
3539 if (bgp_debug_neighbor_events(NULL
))
3541 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3546 /* Create dynamic peer and bind to associated group. */
3547 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3550 gbgp
->dynamic_neighbors_count
= ++dncount
;
3552 if (bgp_debug_neighbor_events(peer
))
3553 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3554 peer
->host
, group
->name
, dncount
);
3559 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3562 if (peer
->group
->bgp
) {
3563 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3565 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3567 if (bgp_debug_neighbor_events(peer
))
3568 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3569 peer
->group
->name
, dncount
);
3572 /* If peer is configured at least one address family return 1. */
3573 int peer_active(struct peer
*peer
)
3575 if (BGP_PEER_SU_UNSPEC(peer
))
3577 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3578 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3579 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3580 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3581 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3582 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3583 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3584 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3585 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3586 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3587 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3592 /* If peer is negotiated at least one address family return 1. */
3593 int peer_active_nego(struct peer
*peer
)
3595 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3596 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3597 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3598 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3599 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3600 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3601 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3602 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3603 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3604 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3605 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3606 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3607 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3612 /* peer_flag_change_type. */
3613 enum peer_change_type
{
3616 peer_change_reset_in
,
3617 peer_change_reset_out
,
3620 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3621 enum peer_change_type type
)
3623 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3626 if (peer
->status
!= Established
)
3629 if (type
== peer_change_reset
) {
3630 /* If we're resetting session, we've to delete both peer struct
3632 if ((peer
->doppelganger
)
3633 && (peer
->doppelganger
->status
!= Deleted
)
3634 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3635 PEER_FLAG_CONFIG_NODE
)))
3636 peer_delete(peer
->doppelganger
);
3638 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3639 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3640 } else if (type
== peer_change_reset_in
) {
3641 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3642 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3643 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3645 if ((peer
->doppelganger
)
3646 && (peer
->doppelganger
->status
!= Deleted
)
3647 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3648 PEER_FLAG_CONFIG_NODE
)))
3649 peer_delete(peer
->doppelganger
);
3651 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3652 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3654 } else if (type
== peer_change_reset_out
) {
3655 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3656 bgp_announce_route(peer
, afi
, safi
);
3660 struct peer_flag_action
{
3664 /* This flag can be set for peer-group member. */
3665 uint8_t not_for_member
;
3667 /* Action when the flag is changed. */
3668 enum peer_change_type type
;
3671 static const struct peer_flag_action peer_flag_action_list
[] = {
3672 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3673 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3674 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3675 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3676 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3677 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3678 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3679 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3680 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3681 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3682 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3683 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3684 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3685 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3686 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3687 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3688 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3691 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3692 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3693 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3694 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3695 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3696 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3697 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3698 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3699 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3700 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3701 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3702 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3703 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3704 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3705 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3706 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3707 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3708 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3709 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3710 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3711 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3712 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3713 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3714 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3715 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3716 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3717 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3718 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3721 /* Proper action set. */
3722 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3723 int size
, struct peer_flag_action
*action
,
3730 const struct peer_flag_action
*match
= NULL
;
3732 /* Check peer's frag action. */
3733 for (i
= 0; i
< size
; i
++) {
3734 match
= &action_list
[i
];
3736 if (match
->flag
== 0)
3739 if (match
->flag
& flag
) {
3742 if (match
->type
== peer_change_reset_in
)
3744 if (match
->type
== peer_change_reset_out
)
3746 if (match
->type
== peer_change_reset
) {
3750 if (match
->not_for_member
)
3751 action
->not_for_member
= 1;
3755 /* Set peer clear type. */
3756 if (reset_in
&& reset_out
)
3757 action
->type
= peer_change_reset
;
3759 action
->type
= peer_change_reset_in
;
3761 action
->type
= peer_change_reset_out
;
3763 action
->type
= peer_change_none
;
3768 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3770 if (flag
== PEER_FLAG_SHUTDOWN
) {
3771 if (CHECK_FLAG(peer
->flags
, flag
)) {
3772 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3773 peer_nsf_stop(peer
);
3775 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3776 if (peer
->t_pmax_restart
) {
3777 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3778 if (bgp_debug_neighbor_events(peer
))
3780 "%s Maximum-prefix restart timer canceled",
3784 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3785 peer_nsf_stop(peer
);
3787 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3788 char *msg
= peer
->tx_shutdown_message
;
3791 if (!msg
&& peer_group_active(peer
))
3792 msg
= peer
->group
->conf
3793 ->tx_shutdown_message
;
3794 msglen
= msg
? strlen(msg
) : 0;
3799 uint8_t msgbuf
[129];
3802 memcpy(msgbuf
+ 1, msg
, msglen
);
3804 bgp_notify_send_with_data(
3805 peer
, BGP_NOTIFY_CEASE
,
3806 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3807 msgbuf
, msglen
+ 1);
3810 peer
, BGP_NOTIFY_CEASE
,
3811 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3813 bgp_session_reset(peer
);
3815 peer
->v_start
= BGP_INIT_START_TIMER
;
3816 BGP_EVENT_ADD(peer
, BGP_Stop
);
3818 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3819 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3820 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3821 else if (flag
== PEER_FLAG_PASSIVE
)
3822 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3823 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3824 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3826 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3827 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3829 bgp_session_reset(peer
);
3832 /* Change specified peer flag. */
3833 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3837 bool invert
, member_invert
;
3838 struct peer
*member
;
3839 struct listnode
*node
, *nnode
;
3840 struct peer_flag_action action
;
3842 memset(&action
, 0, sizeof(struct peer_flag_action
));
3843 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3845 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3846 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3849 /* Abort if no flag action exists. */
3851 return BGP_ERR_INVALID_FLAG
;
3853 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3854 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3855 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3856 return BGP_ERR_PEER_FLAG_CONFLICT
;
3858 /* Handle flag updates where desired state matches current state. */
3859 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3860 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3861 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3865 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3866 COND_FLAG(peer
->flags_override
, flag
, invert
);
3871 /* Inherit from peer-group or set/unset flags accordingly. */
3872 if (peer_group_active(peer
) && set
== invert
)
3873 peer_flag_inherit(peer
, flag
);
3875 COND_FLAG(peer
->flags
, flag
, set
);
3877 /* Check if handling a regular peer. */
3878 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3879 /* Update flag override state accordingly. */
3880 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3882 /* Execute flag action on peer. */
3883 if (action
.type
== peer_change_reset
)
3884 peer_flag_modify_action(peer
, flag
);
3886 /* Skip peer-group mechanics for regular peers. */
3891 * Update peer-group members, unless they are explicitely overriding
3892 * peer-group configuration.
3894 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3895 /* Skip peers with overridden configuration. */
3896 if (CHECK_FLAG(member
->flags_override
, flag
))
3899 /* Check if only member without group is inverted. */
3901 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3903 /* Skip peers with equivalent configuration. */
3904 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3907 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3910 /* Update flag on peer-group member. */
3911 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3913 /* Execute flag action on peer-group member. */
3914 if (action
.type
== peer_change_reset
)
3915 peer_flag_modify_action(member
, flag
);
3921 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3923 return peer_flag_modify(peer
, flag
, 1);
3926 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3928 return peer_flag_modify(peer
, flag
, 0);
3931 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3932 uint32_t flag
, bool set
)
3936 int addpath_tx_used
;
3937 bool invert
, member_invert
;
3939 struct peer
*member
;
3940 struct listnode
*node
, *nnode
;
3941 struct peer_flag_action action
;
3943 memset(&action
, 0, sizeof(struct peer_flag_action
));
3944 size
= sizeof peer_af_flag_action_list
3945 / sizeof(struct peer_flag_action
);
3947 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
3948 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3951 /* Abort if flag action exists. */
3953 return BGP_ERR_INVALID_FLAG
;
3955 /* Special check for reflector client. */
3956 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3957 && peer_sort(peer
) != BGP_PEER_IBGP
)
3958 return BGP_ERR_NOT_INTERNAL_PEER
;
3960 /* Special check for remove-private-AS. */
3961 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3962 && peer_sort(peer
) == BGP_PEER_IBGP
)
3963 return BGP_ERR_REMOVE_PRIVATE_AS
;
3965 /* as-override is not allowed for IBGP peers */
3966 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3967 return BGP_ERR_AS_OVERRIDE
;
3969 /* Handle flag updates where desired state matches current state. */
3970 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3971 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3972 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
3977 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3978 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
3985 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
3986 * if we are setting/unsetting flags which conflict with this flag
3987 * handle accordingly
3989 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
3993 * if we are setting NEXTHOP_SELF, we need to unset the
3994 * NEXTHOP_UNCHANGED flag
3996 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
3997 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
3998 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
3999 PEER_FLAG_NEXTHOP_UNCHANGED
);
4003 * if we are unsetting NEXTHOP_SELF, we need to set the
4004 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4006 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4007 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4008 SET_FLAG(peer
->af_flags
[afi
][safi
],
4009 PEER_FLAG_NEXTHOP_UNCHANGED
);
4013 /* Inherit from peer-group or set/unset flags accordingly. */
4014 if (peer_group_active(peer
) && set
== invert
)
4015 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4017 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4019 /* Execute action when peer is established. */
4020 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4021 && peer
->status
== Established
) {
4022 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4023 bgp_clear_adj_in(peer
, afi
, safi
);
4025 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4026 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4027 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4028 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4029 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4030 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4031 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4032 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4034 peer_change_action(peer
, afi
, safi
, action
.type
);
4038 /* Check if handling a regular peer. */
4039 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4040 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4044 * Update peer-group members, unless they are explicitely
4045 * overriding peer-group configuration.
4047 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4049 /* Skip peers with overridden configuration. */
4050 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4054 /* Check if only member without group is inverted. */
4056 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4060 /* Skip peers with equivalent configuration. */
4061 if (set
!= member_invert
4062 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4065 if (set
== member_invert
4066 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4069 /* Update flag on peer-group member. */
4070 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4071 set
!= member_invert
);
4073 /* Execute flag action on peer-group member. */
4074 if (member
->status
== Established
) {
4075 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4076 bgp_clear_adj_in(member
, afi
, safi
);
4078 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4079 member
->last_reset
=
4080 PEER_DOWN_RR_CLIENT_CHANGE
;
4082 == PEER_FLAG_RSERVER_CLIENT
)
4083 member
->last_reset
=
4084 PEER_DOWN_RS_CLIENT_CHANGE
;
4086 == PEER_FLAG_ORF_PREFIX_SM
)
4087 member
->last_reset
=
4088 PEER_DOWN_CAPABILITY_CHANGE
;
4090 == PEER_FLAG_ORF_PREFIX_RM
)
4091 member
->last_reset
=
4092 PEER_DOWN_CAPABILITY_CHANGE
;
4094 peer_change_action(member
, afi
, safi
,
4101 /* Track if addpath TX is in use */
4102 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4103 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4105 addpath_tx_used
= 0;
4108 addpath_tx_used
= 1;
4110 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4111 if (!bgp_flag_check(
4112 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4114 "%s: enabling bgp deterministic-med, this is required"
4115 " for addpath-tx-bestpath-per-AS",
4119 BGP_FLAG_DETERMINISTIC_MED
);
4120 bgp_recalculate_all_bestpaths(bgp
);
4124 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4126 if (CHECK_FLAG(member
->af_flags
[afi
][safi
],
4127 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4129 member
->af_flags
[afi
][safi
],
4130 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4131 addpath_tx_used
= 1;
4137 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4143 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4145 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4148 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4150 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4154 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4156 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4157 peer
->tx_shutdown_message
=
4158 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4162 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4164 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4169 /* EBGP multihop configuration. */
4170 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4172 struct peer_group
*group
;
4173 struct listnode
*node
, *nnode
;
4176 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4179 /* see comment in peer_ttl_security_hops_set() */
4180 if (ttl
!= MAXTTL
) {
4181 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4182 group
= peer
->group
;
4183 if (group
->conf
->gtsm_hops
!= 0)
4184 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4186 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4188 if (peer1
->sort
== BGP_PEER_IBGP
)
4191 if (peer1
->gtsm_hops
!= 0)
4192 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4195 if (peer
->gtsm_hops
!= 0)
4196 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4202 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4203 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4204 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4205 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4206 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4208 bgp_session_reset(peer
);
4211 group
= peer
->group
;
4212 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4213 if (peer
->sort
== BGP_PEER_IBGP
)
4216 peer
->ttl
= group
->conf
->ttl
;
4218 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4219 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4220 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4222 bgp_session_reset(peer
);
4228 int peer_ebgp_multihop_unset(struct peer
*peer
)
4230 struct peer_group
*group
;
4231 struct listnode
*node
, *nnode
;
4233 if (peer
->sort
== BGP_PEER_IBGP
)
4236 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4237 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4239 if (peer_group_active(peer
))
4240 peer
->ttl
= peer
->group
->conf
->ttl
;
4244 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
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
);
4251 group
= peer
->group
;
4252 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4253 if (peer
->sort
== BGP_PEER_IBGP
)
4258 if (peer
->fd
>= 0) {
4259 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4261 peer
, BGP_NOTIFY_CEASE
,
4262 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4264 bgp_session_reset(peer
);
4271 /* Neighbor description. */
4272 int peer_description_set(struct peer
*peer
, const char *desc
)
4275 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4277 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4282 int peer_description_unset(struct peer
*peer
)
4285 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4292 /* Neighbor update-source. */
4293 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4295 struct peer
*member
;
4296 struct listnode
*node
, *nnode
;
4298 /* Set flag and configuration on peer. */
4299 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4300 if (peer
->update_if
) {
4301 if (strcmp(peer
->update_if
, ifname
) == 0)
4303 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4305 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4306 sockunion_free(peer
->update_source
);
4307 peer
->update_source
= NULL
;
4309 /* Check if handling a regular peer. */
4310 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4311 /* Send notification or reset peer depending on state. */
4312 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4313 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4314 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4315 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4317 bgp_session_reset(peer
);
4319 /* Skip peer-group mechanics for regular peers. */
4324 * Set flag and configuration on all peer-group members, unless they are
4325 * explicitely overriding peer-group configuration.
4327 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4328 /* Skip peers with overridden configuration. */
4329 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4332 /* Skip peers with the same configuration. */
4333 if (member
->update_if
) {
4334 if (strcmp(member
->update_if
, ifname
) == 0)
4336 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4339 /* Set flag and configuration on peer-group member. */
4340 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4341 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4342 sockunion_free(member
->update_source
);
4343 member
->update_source
= NULL
;
4345 /* Send notification or reset peer depending on state. */
4346 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4347 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4348 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4349 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4351 bgp_session_reset(member
);
4357 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4359 struct peer
*member
;
4360 struct listnode
*node
, *nnode
;
4362 /* Set flag and configuration on peer. */
4363 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4364 if (peer
->update_source
) {
4365 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4367 sockunion_free(peer
->update_source
);
4369 peer
->update_source
= sockunion_dup(su
);
4370 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4372 /* Check if handling a regular peer. */
4373 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4374 /* Send notification or reset peer depending on state. */
4375 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4376 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4377 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4378 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4380 bgp_session_reset(peer
);
4382 /* Skip peer-group mechanics for regular peers. */
4387 * Set flag and configuration on all peer-group members, unless they are
4388 * explicitely overriding peer-group configuration.
4390 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4391 /* Skip peers with overridden configuration. */
4392 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4395 /* Skip peers with the same configuration. */
4396 if (member
->update_source
) {
4397 if (sockunion_cmp(member
->update_source
, su
) == 0)
4399 sockunion_free(member
->update_source
);
4402 /* Set flag and configuration on peer-group member. */
4403 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4404 member
->update_source
= sockunion_dup(su
);
4405 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4407 /* Send notification or reset peer depending on state. */
4408 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4409 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4410 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4411 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4413 bgp_session_reset(member
);
4419 int peer_update_source_unset(struct peer
*peer
)
4421 struct peer
*member
;
4422 struct listnode
*node
, *nnode
;
4424 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4427 /* Inherit configuration from peer-group if peer is member. */
4428 if (peer_group_active(peer
)) {
4429 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4430 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4431 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4432 MTYPE_PEER_UPDATE_SOURCE
);
4434 /* Otherwise remove flag and configuration from peer. */
4435 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4436 sockunion_free(peer
->update_source
);
4437 peer
->update_source
= NULL
;
4438 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4441 /* Check if handling a regular peer. */
4442 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4443 /* Send notification or reset peer depending on state. */
4444 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4445 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4446 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4447 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4449 bgp_session_reset(peer
);
4451 /* Skip peer-group mechanics for regular peers. */
4456 * Set flag and configuration on all peer-group members, unless they are
4457 * explicitely overriding peer-group configuration.
4459 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4460 /* Skip peers with overridden configuration. */
4461 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4464 /* Skip peers with the same configuration. */
4465 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4466 && !member
->update_source
&& !member
->update_if
)
4469 /* Remove flag and configuration on peer-group member. */
4470 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4471 sockunion_free(member
->update_source
);
4472 member
->update_source
= NULL
;
4473 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4475 /* Send notification or reset peer depending on state. */
4476 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4477 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4478 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4479 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4481 bgp_session_reset(member
);
4487 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4488 const char *rmap
, struct route_map
*route_map
)
4490 struct peer
*member
;
4491 struct listnode
*node
, *nnode
;
4493 /* Set flag and configuration on peer. */
4494 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4496 if (!peer
->default_rmap
[afi
][safi
].name
4497 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4498 if (peer
->default_rmap
[afi
][safi
].name
)
4499 XFREE(MTYPE_ROUTE_MAP_NAME
,
4500 peer
->default_rmap
[afi
][safi
].name
);
4502 peer
->default_rmap
[afi
][safi
].name
=
4503 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4504 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4507 if (peer
->default_rmap
[afi
][safi
].name
)
4508 XFREE(MTYPE_ROUTE_MAP_NAME
,
4509 peer
->default_rmap
[afi
][safi
].name
);
4511 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4512 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4515 /* Check if handling a regular peer. */
4516 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4517 /* Update peer route announcements. */
4518 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4519 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4520 bgp_default_originate(peer
, afi
, safi
, 0);
4521 bgp_announce_route(peer
, afi
, safi
);
4524 /* Skip peer-group mechanics for regular peers. */
4529 * Set flag and configuration on all peer-group members, unless they are
4530 * explicitely overriding peer-group configuration.
4532 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4533 /* Skip peers with overridden configuration. */
4534 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4535 PEER_FLAG_DEFAULT_ORIGINATE
))
4538 /* Set flag and configuration on peer-group member. */
4539 SET_FLAG(member
->af_flags
[afi
][safi
],
4540 PEER_FLAG_DEFAULT_ORIGINATE
);
4542 if (member
->default_rmap
[afi
][safi
].name
)
4543 XFREE(MTYPE_ROUTE_MAP_NAME
,
4544 member
->default_rmap
[afi
][safi
].name
);
4546 member
->default_rmap
[afi
][safi
].name
=
4547 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4548 member
->default_rmap
[afi
][safi
].map
= route_map
;
4551 /* Update peer route announcements. */
4552 if (member
->status
== Established
4553 && member
->afc_nego
[afi
][safi
]) {
4554 update_group_adjust_peer(
4555 peer_af_find(member
, afi
, safi
));
4556 bgp_default_originate(member
, afi
, safi
, 0);
4557 bgp_announce_route(member
, afi
, safi
);
4564 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4566 struct peer
*member
;
4567 struct listnode
*node
, *nnode
;
4569 /* Inherit configuration from peer-group if peer is member. */
4570 if (peer_group_active(peer
)) {
4571 peer_af_flag_inherit(peer
, afi
, safi
,
4572 PEER_FLAG_DEFAULT_ORIGINATE
);
4573 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4574 default_rmap
[afi
][safi
].name
,
4575 MTYPE_ROUTE_MAP_NAME
);
4576 PEER_ATTR_INHERIT(peer
, peer
->group
,
4577 default_rmap
[afi
][safi
].map
);
4579 /* Otherwise remove flag and configuration from peer. */
4580 peer_af_flag_unset(peer
, afi
, safi
,
4581 PEER_FLAG_DEFAULT_ORIGINATE
);
4582 if (peer
->default_rmap
[afi
][safi
].name
)
4583 XFREE(MTYPE_ROUTE_MAP_NAME
,
4584 peer
->default_rmap
[afi
][safi
].name
);
4585 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4586 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4589 /* Check if handling a regular peer. */
4590 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4591 /* Update peer route announcements. */
4592 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4593 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4594 bgp_default_originate(peer
, afi
, safi
, 1);
4595 bgp_announce_route(peer
, afi
, safi
);
4598 /* Skip peer-group mechanics for regular peers. */
4603 * Remove flag and configuration from all peer-group members, unless
4604 * they are explicitely overriding peer-group configuration.
4606 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4607 /* Skip peers with overridden configuration. */
4608 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4609 PEER_FLAG_DEFAULT_ORIGINATE
))
4612 /* Remove flag and configuration on peer-group member. */
4613 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4614 PEER_FLAG_DEFAULT_ORIGINATE
);
4615 if (peer
->default_rmap
[afi
][safi
].name
)
4616 XFREE(MTYPE_ROUTE_MAP_NAME
,
4617 peer
->default_rmap
[afi
][safi
].name
);
4618 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4619 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4621 /* Update peer route announcements. */
4622 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4623 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4624 bgp_default_originate(peer
, afi
, safi
, 1);
4625 bgp_announce_route(peer
, afi
, safi
);
4632 int peer_port_set(struct peer
*peer
, uint16_t port
)
4638 int peer_port_unset(struct peer
*peer
)
4640 peer
->port
= BGP_PORT_DEFAULT
;
4645 * Helper function that is called after the name of the policy
4646 * being used by a peer has changed (AF specific). Automatically
4647 * initiates inbound or outbound processing as needed.
4649 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4653 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4654 if (peer
->status
== Established
)
4655 bgp_announce_route(peer
, afi
, safi
);
4657 if (peer
->status
!= Established
)
4660 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4661 PEER_FLAG_SOFT_RECONFIG
))
4662 bgp_soft_reconfig_in(peer
, afi
, safi
);
4663 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4664 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4665 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4670 /* neighbor weight. */
4671 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4673 struct peer
*member
;
4674 struct listnode
*node
, *nnode
;
4676 /* Set flag and configuration on peer. */
4677 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4678 if (peer
->weight
[afi
][safi
] != weight
) {
4679 peer
->weight
[afi
][safi
] = weight
;
4680 peer_on_policy_change(peer
, afi
, safi
, 0);
4683 /* Skip peer-group mechanics for regular peers. */
4684 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4688 * Set flag and configuration on all peer-group members, unless they are
4689 * explicitely overriding peer-group configuration.
4691 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4692 /* Skip peers with overridden configuration. */
4693 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4697 /* Set flag and configuration on peer-group member. */
4698 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4699 if (member
->weight
[afi
][safi
] != weight
) {
4700 member
->weight
[afi
][safi
] = weight
;
4701 peer_on_policy_change(member
, afi
, safi
, 0);
4708 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4710 struct peer
*member
;
4711 struct listnode
*node
, *nnode
;
4713 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4716 /* Inherit configuration from peer-group if peer is member. */
4717 if (peer_group_active(peer
)) {
4718 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4719 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4721 peer_on_policy_change(peer
, afi
, safi
, 0);
4725 /* Remove flag and configuration from peer. */
4726 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4727 peer
->weight
[afi
][safi
] = 0;
4728 peer_on_policy_change(peer
, afi
, safi
, 0);
4730 /* Skip peer-group mechanics for regular peers. */
4731 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4735 * Remove flag and configuration from all peer-group members, unless
4736 * they are explicitely overriding peer-group configuration.
4738 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4739 /* Skip peers with overridden configuration. */
4740 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4744 /* Skip peers where flag is already disabled. */
4745 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4748 /* Remove flag and configuration on peer-group member. */
4749 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4750 member
->weight
[afi
][safi
] = 0;
4751 peer_on_policy_change(member
, afi
, safi
, 0);
4757 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4759 struct peer
*member
;
4760 struct listnode
*node
, *nnode
;
4762 if (keepalive
> 65535)
4763 return BGP_ERR_INVALID_VALUE
;
4765 if (holdtime
> 65535)
4766 return BGP_ERR_INVALID_VALUE
;
4768 if (holdtime
< 3 && holdtime
!= 0)
4769 return BGP_ERR_INVALID_VALUE
;
4771 /* Set flag and configuration on peer. */
4772 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4773 peer
->holdtime
= holdtime
;
4774 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4776 /* Skip peer-group mechanics for regular peers. */
4777 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4781 * Set flag and configuration on all peer-group members, unless they are
4782 * explicitely overriding peer-group configuration.
4784 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4785 /* Skip peers with overridden configuration. */
4786 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4789 /* Set flag and configuration on peer-group member. */
4790 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4791 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4792 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4798 int peer_timers_unset(struct peer
*peer
)
4800 struct peer
*member
;
4801 struct listnode
*node
, *nnode
;
4803 /* Inherit configuration from peer-group if peer is member. */
4804 if (peer_group_active(peer
)) {
4805 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4806 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4807 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4809 /* Otherwise remove flag and configuration from peer. */
4810 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4812 peer
->keepalive
= 0;
4815 /* Skip peer-group mechanics for regular peers. */
4816 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4820 * Remove flag and configuration from all peer-group members, unless
4821 * they are explicitely overriding peer-group configuration.
4823 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4824 /* Skip peers with overridden configuration. */
4825 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4828 /* Remove flag and configuration on peer-group member. */
4829 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4830 member
->holdtime
= 0;
4831 member
->keepalive
= 0;
4837 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4839 struct peer
*member
;
4840 struct listnode
*node
, *nnode
;
4842 if (connect
> 65535)
4843 return BGP_ERR_INVALID_VALUE
;
4845 /* Set flag and configuration on peer. */
4846 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4847 peer
->connect
= connect
;
4848 peer
->v_connect
= connect
;
4850 /* Skip peer-group mechanics for regular peers. */
4851 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4855 * Set flag and configuration on all peer-group members, unless they are
4856 * explicitely overriding peer-group configuration.
4858 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4859 /* Skip peers with overridden configuration. */
4860 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4863 /* Set flag and configuration on peer-group member. */
4864 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4865 member
->connect
= connect
;
4866 member
->v_connect
= connect
;
4872 int peer_timers_connect_unset(struct peer
*peer
)
4874 struct peer
*member
;
4875 struct listnode
*node
, *nnode
;
4877 /* Inherit configuration from peer-group if peer is member. */
4878 if (peer_group_active(peer
)) {
4879 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4880 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4882 /* Otherwise remove flag and configuration from peer. */
4883 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4887 /* Set timer with fallback to default value. */
4889 peer
->v_connect
= peer
->connect
;
4891 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4893 /* Skip peer-group mechanics for regular peers. */
4894 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4898 * Remove flag and configuration from all peer-group members, unless
4899 * they are explicitely overriding peer-group configuration.
4901 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4902 /* Skip peers with overridden configuration. */
4903 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4906 /* Remove flag and configuration on peer-group member. */
4907 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4908 member
->connect
= 0;
4909 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4915 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4917 struct peer
*member
;
4918 struct listnode
*node
, *nnode
;
4921 return BGP_ERR_INVALID_VALUE
;
4923 /* Set flag and configuration on peer. */
4924 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4925 peer
->routeadv
= routeadv
;
4926 peer
->v_routeadv
= routeadv
;
4928 /* Check if handling a regular peer. */
4929 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4930 /* Update peer route announcements. */
4931 update_group_adjust_peer_afs(peer
);
4932 if (peer
->status
== Established
)
4933 bgp_announce_route_all(peer
);
4935 /* Skip peer-group mechanics for regular peers. */
4940 * Set flag and configuration on all peer-group members, unless they are
4941 * explicitely overriding peer-group configuration.
4943 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4944 /* Skip peers with overridden configuration. */
4945 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4948 /* Set flag and configuration on peer-group member. */
4949 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4950 member
->routeadv
= routeadv
;
4951 member
->v_routeadv
= routeadv
;
4953 /* Update peer route announcements. */
4954 update_group_adjust_peer_afs(member
);
4955 if (member
->status
== Established
)
4956 bgp_announce_route_all(member
);
4962 int peer_advertise_interval_unset(struct peer
*peer
)
4964 struct peer
*member
;
4965 struct listnode
*node
, *nnode
;
4967 /* Inherit configuration from peer-group if peer is member. */
4968 if (peer_group_active(peer
)) {
4969 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4970 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4972 /* Otherwise remove flag and configuration from peer. */
4973 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
4977 /* Set timer with fallback to default value. */
4979 peer
->v_routeadv
= peer
->routeadv
;
4981 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
4982 ? BGP_DEFAULT_IBGP_ROUTEADV
4983 : BGP_DEFAULT_EBGP_ROUTEADV
;
4985 /* Check if handling a regular peer. */
4986 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4987 /* Update peer route announcements. */
4988 update_group_adjust_peer_afs(peer
);
4989 if (peer
->status
== Established
)
4990 bgp_announce_route_all(peer
);
4992 /* Skip peer-group mechanics for regular peers. */
4997 * Remove flag and configuration from all peer-group members, unless
4998 * they are explicitely overriding peer-group configuration.
5000 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5001 /* Skip peers with overridden configuration. */
5002 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5005 /* Remove flag and configuration on peer-group member. */
5006 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5007 member
->routeadv
= 0;
5008 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5009 ? BGP_DEFAULT_IBGP_ROUTEADV
5010 : BGP_DEFAULT_EBGP_ROUTEADV
;
5012 /* Update peer route announcements. */
5013 update_group_adjust_peer_afs(member
);
5014 if (member
->status
== Established
)
5015 bgp_announce_route_all(member
);
5021 /* neighbor interface */
5022 void peer_interface_set(struct peer
*peer
, const char *str
)
5025 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5026 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5029 void peer_interface_unset(struct peer
*peer
)
5032 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5033 peer
->ifname
= NULL
;
5037 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5038 int allow_num
, int origin
)
5040 struct peer
*member
;
5041 struct listnode
*node
, *nnode
;
5043 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5044 return BGP_ERR_INVALID_VALUE
;
5046 /* Set flag and configuration on peer. */
5047 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5049 if (peer
->allowas_in
[afi
][safi
] != 0
5050 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5051 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5052 peer_af_flag_set(peer
, afi
, safi
,
5053 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5054 peer
->allowas_in
[afi
][safi
] = 0;
5055 peer_on_policy_change(peer
, afi
, safi
, 0);
5058 if (peer
->allowas_in
[afi
][safi
] != allow_num
5059 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5060 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5062 peer_af_flag_unset(peer
, afi
, safi
,
5063 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5064 peer
->allowas_in
[afi
][safi
] = allow_num
;
5065 peer_on_policy_change(peer
, afi
, safi
, 0);
5069 /* Skip peer-group mechanics for regular peers. */
5070 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5074 * Set flag and configuration on all peer-group members, unless
5075 * they are explicitely overriding peer-group configuration.
5077 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5078 /* Skip peers with overridden configuration. */
5079 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5080 PEER_FLAG_ALLOWAS_IN
))
5083 /* Set flag and configuration on peer-group member. */
5084 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5086 if (member
->allowas_in
[afi
][safi
] != 0
5087 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5088 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5089 SET_FLAG(member
->af_flags
[afi
][safi
],
5090 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5091 member
->allowas_in
[afi
][safi
] = 0;
5092 peer_on_policy_change(peer
, afi
, safi
, 0);
5095 if (member
->allowas_in
[afi
][safi
] != allow_num
5096 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5097 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5098 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5099 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5100 member
->allowas_in
[afi
][safi
] = allow_num
;
5101 peer_on_policy_change(peer
, afi
, safi
, 0);
5109 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5111 struct peer
*member
;
5112 struct listnode
*node
, *nnode
;
5114 /* Skip peer if flag is already disabled. */
5115 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5118 /* Inherit configuration from peer-group if peer is member. */
5119 if (peer_group_active(peer
)) {
5120 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5121 peer_af_flag_inherit(peer
, afi
, safi
,
5122 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5123 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5124 peer_on_policy_change(peer
, afi
, safi
, 0);
5129 /* Remove flag and configuration from peer. */
5130 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5131 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5132 peer
->allowas_in
[afi
][safi
] = 0;
5133 peer_on_policy_change(peer
, afi
, safi
, 0);
5135 /* Skip peer-group mechanics if handling a regular peer. */
5136 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5140 * Remove flags and configuration from all peer-group members, unless
5141 * they are explicitely overriding peer-group configuration.
5143 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5144 /* Skip peers with overridden configuration. */
5145 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5146 PEER_FLAG_ALLOWAS_IN
))
5149 /* Skip peers where flag is already disabled. */
5150 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5151 PEER_FLAG_ALLOWAS_IN
))
5154 /* Remove flags and configuration on peer-group member. */
5155 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5156 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5157 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5158 member
->allowas_in
[afi
][safi
] = 0;
5159 peer_on_policy_change(member
, afi
, safi
, 0);
5165 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5168 bool old_no_prepend
, old_replace_as
;
5169 struct bgp
*bgp
= peer
->bgp
;
5170 struct peer
*member
;
5171 struct listnode
*node
, *nnode
;
5173 if (peer_sort(peer
) != BGP_PEER_EBGP
5174 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5175 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5178 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5181 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5183 /* Save previous flag states. */
5185 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5187 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5189 /* Set flag and configuration on peer. */
5190 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5191 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5192 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5194 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5195 && old_replace_as
== replace_as
)
5197 peer
->change_local_as
= as
;
5199 /* Check if handling a regular peer. */
5200 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5201 /* Send notification or reset peer depending on state. */
5202 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5203 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5204 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5205 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5207 bgp_session_reset(peer
);
5209 /* Skip peer-group mechanics for regular peers. */
5214 * Set flag and configuration on all peer-group members, unless they are
5215 * explicitely overriding peer-group configuration.
5217 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5218 /* Skip peers with overridden configuration. */
5219 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5222 /* Skip peers with the same configuration. */
5223 old_no_prepend
= CHECK_FLAG(member
->flags
,
5224 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5225 old_replace_as
= CHECK_FLAG(member
->flags
,
5226 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5227 if (member
->change_local_as
== as
5228 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5229 && old_no_prepend
== no_prepend
5230 && old_replace_as
== replace_as
)
5233 /* Set flag and configuration on peer-group member. */
5234 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5235 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5237 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5239 member
->change_local_as
= as
;
5241 /* Send notification or stop peer depending on state. */
5242 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5243 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5244 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5245 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5247 BGP_EVENT_ADD(member
, BGP_Stop
);
5253 int peer_local_as_unset(struct peer
*peer
)
5255 struct peer
*member
;
5256 struct listnode
*node
, *nnode
;
5258 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5261 /* Inherit configuration from peer-group if peer is member. */
5262 if (peer_group_active(peer
)) {
5263 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5264 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5265 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5266 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5268 /* Otherwise remove flag and configuration from peer. */
5269 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5270 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5271 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5272 peer
->change_local_as
= 0;
5275 /* Check if handling a regular peer. */
5276 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5277 /* Send notification or stop peer depending on state. */
5278 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5279 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5280 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5281 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5283 BGP_EVENT_ADD(peer
, BGP_Stop
);
5285 /* Skip peer-group mechanics for regular peers. */
5290 * Remove flag and configuration from all peer-group members, unless
5291 * they are explicitely overriding peer-group configuration.
5293 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5294 /* Skip peers with overridden configuration. */
5295 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5298 /* Remove flag and configuration on peer-group member. */
5299 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5300 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5301 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5302 member
->change_local_as
= 0;
5304 /* Send notification or stop peer depending on state. */
5305 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5306 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5307 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5308 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5310 bgp_session_reset(member
);
5316 /* Set password for authenticating with the peer. */
5317 int peer_password_set(struct peer
*peer
, const char *password
)
5319 struct peer
*member
;
5320 struct listnode
*node
, *nnode
;
5321 int len
= password
? strlen(password
) : 0;
5322 int ret
= BGP_SUCCESS
;
5324 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5325 return BGP_ERR_INVALID_VALUE
;
5327 /* Set flag and configuration on peer. */
5328 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5329 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5331 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5332 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5334 /* Check if handling a regular peer. */
5335 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5336 /* Send notification or reset peer depending on state. */
5337 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5338 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5339 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5341 bgp_session_reset(peer
);
5344 * Attempt to install password on socket and skip peer-group
5347 if (BGP_PEER_SU_UNSPEC(peer
))
5349 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5350 : BGP_ERR_TCPSIG_FAILED
;
5354 * Set flag and configuration on all peer-group members, unless they are
5355 * explicitely overriding peer-group configuration.
5357 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5358 /* Skip peers with overridden configuration. */
5359 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5362 /* Skip peers with the same password. */
5363 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5366 /* Set flag and configuration on peer-group member. */
5367 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5368 if (member
->password
)
5369 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5370 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5372 /* Send notification or reset peer depending on state. */
5373 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5374 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5375 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5377 bgp_session_reset(member
);
5379 /* Attempt to install password on socket. */
5380 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5381 ret
= BGP_ERR_TCPSIG_FAILED
;
5387 int peer_password_unset(struct peer
*peer
)
5389 struct peer
*member
;
5390 struct listnode
*node
, *nnode
;
5392 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5395 /* Inherit configuration from peer-group if peer is member. */
5396 if (peer_group_active(peer
)) {
5397 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5398 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5399 MTYPE_PEER_PASSWORD
);
5401 /* Otherwise remove flag and configuration from peer. */
5402 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5403 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5406 /* Check if handling a regular peer. */
5407 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5408 /* Send notification or reset peer depending on state. */
5409 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5410 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5411 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5413 bgp_session_reset(peer
);
5415 /* Attempt to uninstall password on socket. */
5416 if (!BGP_PEER_SU_UNSPEC(peer
))
5417 bgp_md5_unset(peer
);
5419 /* Skip peer-group mechanics for regular peers. */
5424 * Remove flag and configuration from all peer-group members, unless
5425 * they are explicitely overriding peer-group configuration.
5427 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5428 /* Skip peers with overridden configuration. */
5429 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5432 /* Remove flag and configuration on peer-group member. */
5433 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5434 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5436 /* Send notification or reset peer depending on state. */
5437 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5438 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5439 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5441 bgp_session_reset(member
);
5443 /* Attempt to uninstall password on socket. */
5444 if (!BGP_PEER_SU_UNSPEC(member
))
5445 bgp_md5_unset(member
);
5452 /* Set distribute list to the peer. */
5453 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5456 struct peer
*member
;
5457 struct bgp_filter
*filter
;
5458 struct listnode
*node
, *nnode
;
5460 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5461 return BGP_ERR_INVALID_VALUE
;
5463 /* Set configuration on peer. */
5464 filter
= &peer
->filter
[afi
][safi
];
5465 if (filter
->plist
[direct
].name
)
5466 return BGP_ERR_PEER_FILTER_CONFLICT
;
5467 if (filter
->dlist
[direct
].name
)
5468 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5469 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5470 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5472 /* Check if handling a regular peer. */
5473 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5474 /* Set override-flag and process peer route updates. */
5475 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5476 PEER_FT_DISTRIBUTE_LIST
);
5477 peer_on_policy_change(peer
, afi
, safi
,
5478 (direct
== FILTER_OUT
) ? 1 : 0);
5480 /* Skip peer-group mechanics for regular peers. */
5485 * Set configuration on all peer-group members, un less they are
5486 * explicitely overriding peer-group configuration.
5488 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5489 /* Skip peers with overridden configuration. */
5490 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5491 PEER_FT_DISTRIBUTE_LIST
))
5494 /* Set configuration on peer-group member. */
5495 filter
= &member
->filter
[afi
][safi
];
5496 if (filter
->dlist
[direct
].name
)
5497 XFREE(MTYPE_BGP_FILTER_NAME
,
5498 filter
->dlist
[direct
].name
);
5499 filter
->dlist
[direct
].name
=
5500 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5501 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5503 /* Process peer route updates. */
5504 peer_on_policy_change(member
, afi
, safi
,
5505 (direct
== FILTER_OUT
) ? 1 : 0);
5511 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5513 struct peer
*member
;
5514 struct bgp_filter
*filter
;
5515 struct listnode
*node
, *nnode
;
5517 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5518 return BGP_ERR_INVALID_VALUE
;
5520 /* Unset override-flag unconditionally. */
5521 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5522 PEER_FT_DISTRIBUTE_LIST
);
5524 /* Inherit configuration from peer-group if peer is member. */
5525 if (peer_group_active(peer
)) {
5526 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5527 filter
[afi
][safi
].dlist
[direct
].name
,
5528 MTYPE_BGP_FILTER_NAME
);
5529 PEER_ATTR_INHERIT(peer
, peer
->group
,
5530 filter
[afi
][safi
].dlist
[direct
].alist
);
5532 /* Otherwise remove configuration from peer. */
5533 filter
= &peer
->filter
[afi
][safi
];
5534 if (filter
->dlist
[direct
].name
)
5535 XFREE(MTYPE_BGP_FILTER_NAME
,
5536 filter
->dlist
[direct
].name
);
5537 filter
->dlist
[direct
].name
= NULL
;
5538 filter
->dlist
[direct
].alist
= NULL
;
5541 /* Check if handling a regular peer. */
5542 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5543 /* Process peer route updates. */
5544 peer_on_policy_change(peer
, afi
, safi
,
5545 (direct
== FILTER_OUT
) ? 1 : 0);
5547 /* Skip peer-group mechanics for regular peers. */
5552 * Remove configuration on all peer-group members, unless they are
5553 * explicitely overriding peer-group configuration.
5555 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5556 /* Skip peers with overridden configuration. */
5557 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5558 PEER_FT_DISTRIBUTE_LIST
))
5561 /* Remove configuration on peer-group member. */
5562 filter
= &member
->filter
[afi
][safi
];
5563 if (filter
->dlist
[direct
].name
)
5564 XFREE(MTYPE_BGP_FILTER_NAME
,
5565 filter
->dlist
[direct
].name
);
5566 filter
->dlist
[direct
].name
= NULL
;
5567 filter
->dlist
[direct
].alist
= NULL
;
5569 /* Process peer route updates. */
5570 peer_on_policy_change(member
, afi
, safi
,
5571 (direct
== FILTER_OUT
) ? 1 : 0);
5577 /* Update distribute list. */
5578 static void peer_distribute_update(struct access_list
*access
)
5583 struct listnode
*mnode
, *mnnode
;
5584 struct listnode
*node
, *nnode
;
5587 struct peer_group
*group
;
5588 struct bgp_filter
*filter
;
5590 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5592 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5593 access
->name
, 0, 0);
5594 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5595 FOREACH_AFI_SAFI (afi
, safi
) {
5596 filter
= &peer
->filter
[afi
][safi
];
5598 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5600 if (filter
->dlist
[direct
].name
)
5601 filter
->dlist
[direct
]
5602 .alist
= access_list_lookup(
5604 filter
->dlist
[direct
]
5607 filter
->dlist
[direct
].alist
=
5612 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5613 FOREACH_AFI_SAFI (afi
, safi
) {
5614 filter
= &group
->conf
->filter
[afi
][safi
];
5616 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5618 if (filter
->dlist
[direct
].name
)
5619 filter
->dlist
[direct
]
5620 .alist
= access_list_lookup(
5622 filter
->dlist
[direct
]
5625 filter
->dlist
[direct
].alist
=
5631 vnc_prefix_list_update(bgp
);
5636 /* Set prefix list to the peer. */
5637 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5640 struct peer
*member
;
5641 struct bgp_filter
*filter
;
5642 struct listnode
*node
, *nnode
;
5644 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5645 return BGP_ERR_INVALID_VALUE
;
5647 /* Set configuration on peer. */
5648 filter
= &peer
->filter
[afi
][safi
];
5649 if (filter
->dlist
[direct
].name
)
5650 return BGP_ERR_PEER_FILTER_CONFLICT
;
5651 if (filter
->plist
[direct
].name
)
5652 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5653 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5654 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5656 /* Check if handling a regular peer. */
5657 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5658 /* Set override-flag and process peer route updates. */
5659 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5660 PEER_FT_PREFIX_LIST
);
5661 peer_on_policy_change(peer
, afi
, safi
,
5662 (direct
== FILTER_OUT
) ? 1 : 0);
5664 /* Skip peer-group mechanics for regular peers. */
5669 * Set configuration on all peer-group members, unless they are
5670 * explicitely overriding peer-group configuration.
5672 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5673 /* Skip peers with overridden configuration. */
5674 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5675 PEER_FT_PREFIX_LIST
))
5678 /* Set configuration on peer-group member. */
5679 filter
= &member
->filter
[afi
][safi
];
5680 if (filter
->plist
[direct
].name
)
5681 XFREE(MTYPE_BGP_FILTER_NAME
,
5682 filter
->plist
[direct
].name
);
5683 filter
->plist
[direct
].name
=
5684 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5685 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5687 /* Process peer route updates. */
5688 peer_on_policy_change(member
, afi
, safi
,
5689 (direct
== FILTER_OUT
) ? 1 : 0);
5695 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5698 struct peer
*member
;
5699 struct bgp_filter
*filter
;
5700 struct listnode
*node
, *nnode
;
5702 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5703 return BGP_ERR_INVALID_VALUE
;
5705 /* Unset override-flag unconditionally. */
5706 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5707 PEER_FT_PREFIX_LIST
);
5709 /* Inherit configuration from peer-group if peer is member. */
5710 if (peer_group_active(peer
)) {
5711 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5712 filter
[afi
][safi
].plist
[direct
].name
,
5713 MTYPE_BGP_FILTER_NAME
);
5714 PEER_ATTR_INHERIT(peer
, peer
->group
,
5715 filter
[afi
][safi
].plist
[direct
].plist
);
5717 /* Otherwise remove configuration from peer. */
5718 filter
= &peer
->filter
[afi
][safi
];
5719 if (filter
->plist
[direct
].name
)
5720 XFREE(MTYPE_BGP_FILTER_NAME
,
5721 filter
->plist
[direct
].name
);
5722 filter
->plist
[direct
].name
= NULL
;
5723 filter
->plist
[direct
].plist
= NULL
;
5726 /* Check if handling a regular peer. */
5727 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5728 /* Process peer route updates. */
5729 peer_on_policy_change(peer
, afi
, safi
,
5730 (direct
== FILTER_OUT
) ? 1 : 0);
5732 /* Skip peer-group mechanics for regular peers. */
5737 * Remove configuration on all peer-group members, unless they are
5738 * explicitely overriding peer-group configuration.
5740 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5741 /* Skip peers with overridden configuration. */
5742 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5743 PEER_FT_PREFIX_LIST
))
5746 /* Remove configuration on peer-group member. */
5747 filter
= &member
->filter
[afi
][safi
];
5748 if (filter
->plist
[direct
].name
)
5749 XFREE(MTYPE_BGP_FILTER_NAME
,
5750 filter
->plist
[direct
].name
);
5751 filter
->plist
[direct
].name
= NULL
;
5752 filter
->plist
[direct
].plist
= NULL
;
5754 /* Process peer route updates. */
5755 peer_on_policy_change(member
, afi
, safi
,
5756 (direct
== FILTER_OUT
) ? 1 : 0);
5762 /* Update prefix-list list. */
5763 static void peer_prefix_list_update(struct prefix_list
*plist
)
5765 struct listnode
*mnode
, *mnnode
;
5766 struct listnode
*node
, *nnode
;
5769 struct peer_group
*group
;
5770 struct bgp_filter
*filter
;
5775 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5778 * Update the prefix-list on update groups.
5780 update_group_policy_update(
5781 bgp
, BGP_POLICY_PREFIX_LIST
,
5782 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5784 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5785 FOREACH_AFI_SAFI (afi
, safi
) {
5786 filter
= &peer
->filter
[afi
][safi
];
5788 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5790 if (filter
->plist
[direct
].name
)
5791 filter
->plist
[direct
]
5792 .plist
= prefix_list_lookup(
5794 filter
->plist
[direct
]
5797 filter
->plist
[direct
].plist
=
5802 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5803 FOREACH_AFI_SAFI (afi
, safi
) {
5804 filter
= &group
->conf
->filter
[afi
][safi
];
5806 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5808 if (filter
->plist
[direct
].name
)
5809 filter
->plist
[direct
]
5810 .plist
= prefix_list_lookup(
5812 filter
->plist
[direct
]
5815 filter
->plist
[direct
].plist
=
5823 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5826 struct peer
*member
;
5827 struct bgp_filter
*filter
;
5828 struct listnode
*node
, *nnode
;
5830 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5831 return BGP_ERR_INVALID_VALUE
;
5833 /* Set configuration on peer. */
5834 filter
= &peer
->filter
[afi
][safi
];
5835 if (filter
->aslist
[direct
].name
)
5836 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5837 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5838 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5840 /* Check if handling a regular peer. */
5841 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5842 /* Set override-flag and process peer route updates. */
5843 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5844 PEER_FT_FILTER_LIST
);
5845 peer_on_policy_change(peer
, afi
, safi
,
5846 (direct
== FILTER_OUT
) ? 1 : 0);
5848 /* Skip peer-group mechanics for regular peers. */
5853 * Set configuration on all peer-group members, unless they are
5854 * explicitely overriding peer-group configuration.
5856 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5857 /* Skip peers with overridden configuration. */
5858 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5859 PEER_FT_FILTER_LIST
))
5862 /* Set configuration on peer-group member. */
5863 filter
= &member
->filter
[afi
][safi
];
5864 if (filter
->aslist
[direct
].name
)
5865 XFREE(MTYPE_BGP_FILTER_NAME
,
5866 filter
->aslist
[direct
].name
);
5867 filter
->aslist
[direct
].name
=
5868 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5869 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5871 /* Process peer route updates. */
5872 peer_on_policy_change(member
, afi
, safi
,
5873 (direct
== FILTER_OUT
) ? 1 : 0);
5879 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5881 struct peer
*member
;
5882 struct bgp_filter
*filter
;
5883 struct listnode
*node
, *nnode
;
5885 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5886 return BGP_ERR_INVALID_VALUE
;
5888 /* Unset override-flag unconditionally. */
5889 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5890 PEER_FT_FILTER_LIST
);
5892 /* Inherit configuration from peer-group if peer is member. */
5893 if (peer_group_active(peer
)) {
5894 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5895 filter
[afi
][safi
].aslist
[direct
].name
,
5896 MTYPE_BGP_FILTER_NAME
);
5897 PEER_ATTR_INHERIT(peer
, peer
->group
,
5898 filter
[afi
][safi
].aslist
[direct
].aslist
);
5900 /* Otherwise remove configuration from peer. */
5901 filter
= &peer
->filter
[afi
][safi
];
5902 if (filter
->aslist
[direct
].name
)
5903 XFREE(MTYPE_BGP_FILTER_NAME
,
5904 filter
->aslist
[direct
].name
);
5905 filter
->aslist
[direct
].name
= NULL
;
5906 filter
->aslist
[direct
].aslist
= NULL
;
5909 /* Check if handling a regular peer. */
5910 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5911 /* Process peer route updates. */
5912 peer_on_policy_change(peer
, afi
, safi
,
5913 (direct
== FILTER_OUT
) ? 1 : 0);
5915 /* Skip peer-group mechanics for regular peers. */
5920 * Remove configuration on all peer-group members, unless they are
5921 * explicitely overriding peer-group configuration.
5923 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5924 /* Skip peers with overridden configuration. */
5925 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5926 PEER_FT_FILTER_LIST
))
5929 /* Remove configuration on peer-group member. */
5930 filter
= &member
->filter
[afi
][safi
];
5931 if (filter
->aslist
[direct
].name
)
5932 XFREE(MTYPE_BGP_FILTER_NAME
,
5933 filter
->aslist
[direct
].name
);
5934 filter
->aslist
[direct
].name
= NULL
;
5935 filter
->aslist
[direct
].aslist
= NULL
;
5937 /* Process peer route updates. */
5938 peer_on_policy_change(member
, afi
, safi
,
5939 (direct
== FILTER_OUT
) ? 1 : 0);
5945 static void peer_aslist_update(const char *aslist_name
)
5950 struct listnode
*mnode
, *mnnode
;
5951 struct listnode
*node
, *nnode
;
5954 struct peer_group
*group
;
5955 struct bgp_filter
*filter
;
5957 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5958 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5961 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5962 FOREACH_AFI_SAFI (afi
, safi
) {
5963 filter
= &peer
->filter
[afi
][safi
];
5965 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5967 if (filter
->aslist
[direct
].name
)
5968 filter
->aslist
[direct
]
5969 .aslist
= as_list_lookup(
5970 filter
->aslist
[direct
]
5973 filter
->aslist
[direct
].aslist
=
5978 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5979 FOREACH_AFI_SAFI (afi
, safi
) {
5980 filter
= &group
->conf
->filter
[afi
][safi
];
5982 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5984 if (filter
->aslist
[direct
].name
)
5985 filter
->aslist
[direct
]
5986 .aslist
= as_list_lookup(
5987 filter
->aslist
[direct
]
5990 filter
->aslist
[direct
].aslist
=
5998 static void peer_aslist_add(char *aslist_name
)
6000 peer_aslist_update(aslist_name
);
6001 route_map_notify_dependencies((char *)aslist_name
,
6002 RMAP_EVENT_ASLIST_ADDED
);
6005 static void peer_aslist_del(const char *aslist_name
)
6007 peer_aslist_update(aslist_name
);
6008 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6012 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6013 const char *name
, struct route_map
*route_map
)
6015 struct peer
*member
;
6016 struct bgp_filter
*filter
;
6017 struct listnode
*node
, *nnode
;
6019 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6020 return BGP_ERR_INVALID_VALUE
;
6022 /* Set configuration on peer. */
6023 filter
= &peer
->filter
[afi
][safi
];
6024 if (filter
->map
[direct
].name
)
6025 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6026 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6027 filter
->map
[direct
].map
= route_map
;
6029 /* Check if handling a regular peer. */
6030 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6031 /* Set override-flag and process peer route updates. */
6032 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6034 peer_on_policy_change(peer
, afi
, safi
,
6035 (direct
== RMAP_OUT
) ? 1 : 0);
6037 /* Skip peer-group mechanics for regular peers. */
6042 * Set configuration on all peer-group members, unless they are
6043 * explicitely overriding peer-group configuration.
6045 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6046 /* Skip peers with overridden configuration. */
6047 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6051 /* Set configuration on peer-group member. */
6052 filter
= &member
->filter
[afi
][safi
];
6053 if (filter
->map
[direct
].name
)
6054 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6055 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6056 filter
->map
[direct
].map
= route_map
;
6058 /* Process peer route updates. */
6059 peer_on_policy_change(member
, afi
, safi
,
6060 (direct
== RMAP_OUT
) ? 1 : 0);
6065 /* Unset route-map from the peer. */
6066 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6068 struct peer
*member
;
6069 struct bgp_filter
*filter
;
6070 struct listnode
*node
, *nnode
;
6072 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6073 return BGP_ERR_INVALID_VALUE
;
6075 /* Unset override-flag unconditionally. */
6076 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6078 /* Inherit configuration from peer-group if peer is member. */
6079 if (peer_group_active(peer
)) {
6080 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6081 filter
[afi
][safi
].map
[direct
].name
,
6082 MTYPE_BGP_FILTER_NAME
);
6083 PEER_ATTR_INHERIT(peer
, peer
->group
,
6084 filter
[afi
][safi
].map
[direct
].map
);
6086 /* Otherwise remove configuration from peer. */
6087 filter
= &peer
->filter
[afi
][safi
];
6088 if (filter
->map
[direct
].name
)
6089 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6090 filter
->map
[direct
].name
= NULL
;
6091 filter
->map
[direct
].map
= NULL
;
6094 /* Check if handling a regular peer. */
6095 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6096 /* Process peer route updates. */
6097 peer_on_policy_change(peer
, afi
, safi
,
6098 (direct
== RMAP_OUT
) ? 1 : 0);
6100 /* Skip peer-group mechanics for regular peers. */
6105 * Remove configuration on all peer-group members, unless they are
6106 * explicitely overriding peer-group configuration.
6108 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6109 /* Skip peers with overridden configuration. */
6110 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6114 /* Remove configuration on peer-group member. */
6115 filter
= &member
->filter
[afi
][safi
];
6116 if (filter
->map
[direct
].name
)
6117 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6118 filter
->map
[direct
].name
= NULL
;
6119 filter
->map
[direct
].map
= NULL
;
6121 /* Process peer route updates. */
6122 peer_on_policy_change(member
, afi
, safi
,
6123 (direct
== RMAP_OUT
) ? 1 : 0);
6129 /* Set unsuppress-map to the peer. */
6130 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6131 const char *name
, struct route_map
*route_map
)
6133 struct peer
*member
;
6134 struct bgp_filter
*filter
;
6135 struct listnode
*node
, *nnode
;
6137 /* Set configuration on peer. */
6138 filter
= &peer
->filter
[afi
][safi
];
6139 if (filter
->usmap
.name
)
6140 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6141 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6142 filter
->usmap
.map
= route_map
;
6144 /* Check if handling a regular peer. */
6145 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6146 /* Set override-flag and process peer route updates. */
6147 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6148 PEER_FT_UNSUPPRESS_MAP
);
6149 peer_on_policy_change(peer
, afi
, safi
, 1);
6151 /* Skip peer-group mechanics for regular peers. */
6156 * Set configuration on all peer-group members, unless they are
6157 * explicitely overriding peer-group configuration.
6159 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6160 /* Skip peers with overridden configuration. */
6161 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6162 PEER_FT_UNSUPPRESS_MAP
))
6165 /* Set configuration on peer-group member. */
6166 filter
= &member
->filter
[afi
][safi
];
6167 if (filter
->usmap
.name
)
6168 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6169 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6170 filter
->usmap
.map
= route_map
;
6172 /* Process peer route updates. */
6173 peer_on_policy_change(member
, afi
, safi
, 1);
6179 /* Unset route-map from the peer. */
6180 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6182 struct peer
*member
;
6183 struct bgp_filter
*filter
;
6184 struct listnode
*node
, *nnode
;
6186 /* Unset override-flag unconditionally. */
6187 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6189 /* Inherit configuration from peer-group if peer is member. */
6190 if (peer_group_active(peer
)) {
6191 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6192 filter
[afi
][safi
].usmap
.name
,
6193 MTYPE_BGP_FILTER_NAME
);
6194 PEER_ATTR_INHERIT(peer
, peer
->group
,
6195 filter
[afi
][safi
].usmap
.map
);
6197 /* Otherwise remove configuration from peer. */
6198 filter
= &peer
->filter
[afi
][safi
];
6199 if (filter
->usmap
.name
)
6200 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6201 filter
->usmap
.name
= NULL
;
6202 filter
->usmap
.map
= NULL
;
6205 /* Check if handling a regular peer. */
6206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6207 /* Process peer route updates. */
6208 peer_on_policy_change(peer
, afi
, safi
, 1);
6210 /* Skip peer-group mechanics for regular peers. */
6215 * Remove configuration on all peer-group members, unless they are
6216 * explicitely overriding peer-group configuration.
6218 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6219 /* Skip peers with overridden configuration. */
6220 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6221 PEER_FT_UNSUPPRESS_MAP
))
6224 /* Remove configuration on peer-group member. */
6225 filter
= &member
->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
;
6231 /* Process peer route updates. */
6232 peer_on_policy_change(member
, afi
, safi
, 1);
6238 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6239 uint32_t max
, uint8_t threshold
, int warning
,
6242 struct peer
*member
;
6243 struct listnode
*node
, *nnode
;
6245 /* Set flags and configuration on peer. */
6246 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6248 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6250 peer_af_flag_unset(peer
, afi
, safi
,
6251 PEER_FLAG_MAX_PREFIX_WARNING
);
6253 peer
->pmax
[afi
][safi
] = max
;
6254 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6255 peer
->pmax_restart
[afi
][safi
] = restart
;
6257 /* Check if handling a regular peer. */
6258 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6259 /* Re-check if peer violates maximum-prefix. */
6260 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6261 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6263 /* Skip peer-group mechanics for regular peers. */
6268 * Set flags and configuration on all peer-group members, unless they
6269 * are explicitely overriding peer-group configuration.
6271 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6272 /* Skip peers with overridden configuration. */
6273 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6274 PEER_FLAG_MAX_PREFIX
))
6277 /* Set flag and configuration on peer-group member. */
6278 member
->pmax
[afi
][safi
] = max
;
6279 member
->pmax_threshold
[afi
][safi
] = threshold
;
6280 member
->pmax_restart
[afi
][safi
] = restart
;
6282 SET_FLAG(member
->af_flags
[afi
][safi
],
6283 PEER_FLAG_MAX_PREFIX_WARNING
);
6285 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6286 PEER_FLAG_MAX_PREFIX_WARNING
);
6288 /* Re-check if peer violates maximum-prefix. */
6289 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6290 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6296 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6298 struct peer
*member
;
6299 struct listnode
*node
, *nnode
;
6301 /* Inherit configuration from peer-group if peer is member. */
6302 if (peer_group_active(peer
)) {
6303 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6304 peer_af_flag_inherit(peer
, afi
, safi
,
6305 PEER_FLAG_MAX_PREFIX_WARNING
);
6306 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6307 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6308 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6313 /* Remove flags and configuration from peer. */
6314 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6315 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6316 peer
->pmax
[afi
][safi
] = 0;
6317 peer
->pmax_threshold
[afi
][safi
] = 0;
6318 peer
->pmax_restart
[afi
][safi
] = 0;
6321 * Remove flags and configuration from all peer-group members, unless
6322 * they are explicitely overriding peer-group configuration.
6324 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6325 /* Skip peers with overridden configuration. */
6326 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6327 PEER_FLAG_MAX_PREFIX
))
6330 /* Remove flag and configuration on peer-group member. */
6331 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6332 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6333 PEER_FLAG_MAX_PREFIX_WARNING
);
6334 member
->pmax
[afi
][safi
] = 0;
6335 member
->pmax_threshold
[afi
][safi
] = 0;
6336 member
->pmax_restart
[afi
][safi
] = 0;
6342 int is_ebgp_multihop_configured(struct peer
*peer
)
6344 struct peer_group
*group
;
6345 struct listnode
*node
, *nnode
;
6348 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6349 group
= peer
->group
;
6350 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6351 && (group
->conf
->ttl
!= 1))
6354 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6355 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6356 && (peer1
->ttl
!= 1))
6360 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6366 /* Set # of hops between us and BGP peer. */
6367 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6369 struct peer_group
*group
;
6370 struct listnode
*node
, *nnode
;
6373 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6374 gtsm_hops
, peer
->host
);
6376 /* We cannot configure ttl-security hops when ebgp-multihop is already
6377 set. For non peer-groups, the check is simple. For peer-groups,
6379 slightly messy, because we need to check both the peer-group
6381 and all peer-group members for any trace of ebgp-multihop
6383 before actually applying the ttl-security rules. Cisco really made a
6384 mess of this configuration parameter, and OpenBGPD got it right.
6387 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6388 if (is_ebgp_multihop_configured(peer
))
6389 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6391 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6392 peer
->gtsm_hops
= gtsm_hops
;
6394 /* Calling ebgp multihop also resets the session.
6395 * On restart, NHT will get setup correctly as will the
6396 * min & max ttls on the socket. The return value is
6399 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6404 group
= peer
->group
;
6405 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6407 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6409 /* Calling ebgp multihop also resets the
6411 * On restart, NHT will get setup correctly as
6413 * min & max ttls on the socket. The return
6417 peer_ebgp_multihop_set(peer
, MAXTTL
);
6421 /* Post the first gtsm setup or if its ibgp, maxttl setting
6423 * necessary, just set the minttl.
6425 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6426 peer
->gtsm_hops
= gtsm_hops
;
6429 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6430 MAXTTL
+ 1 - gtsm_hops
);
6431 if ((peer
->status
< Established
) && peer
->doppelganger
6432 && (peer
->doppelganger
->fd
>= 0))
6433 sockopt_minttl(peer
->su
.sa
.sa_family
,
6434 peer
->doppelganger
->fd
,
6435 MAXTTL
+ 1 - gtsm_hops
);
6437 group
= peer
->group
;
6438 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6440 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6442 /* Change setting of existing peer
6443 * established then change value (may break
6445 * not established yet (teardown session and
6447 * no session then do nothing (will get
6448 * handled by next connection)
6450 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6452 peer
->su
.sa
.sa_family
, peer
->fd
,
6453 MAXTTL
+ 1 - peer
->gtsm_hops
);
6454 if ((peer
->status
< Established
)
6455 && peer
->doppelganger
6456 && (peer
->doppelganger
->fd
>= 0))
6457 sockopt_minttl(peer
->su
.sa
.sa_family
,
6458 peer
->doppelganger
->fd
,
6459 MAXTTL
+ 1 - gtsm_hops
);
6467 int peer_ttl_security_hops_unset(struct peer
*peer
)
6469 struct peer_group
*group
;
6470 struct listnode
*node
, *nnode
;
6473 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6476 /* if a peer-group member, then reset to peer-group default rather than
6478 if (peer_group_active(peer
))
6479 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6481 peer
->gtsm_hops
= 0;
6483 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6484 /* Invoking ebgp_multihop_set will set the TTL back to the
6486 * value as well as restting the NHT and such. The session is
6489 if (peer
->sort
== BGP_PEER_EBGP
)
6490 ret
= peer_ebgp_multihop_unset(peer
);
6493 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6496 if ((peer
->status
< Established
) && peer
->doppelganger
6497 && (peer
->doppelganger
->fd
>= 0))
6498 sockopt_minttl(peer
->su
.sa
.sa_family
,
6499 peer
->doppelganger
->fd
, 0);
6502 group
= peer
->group
;
6503 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6504 peer
->gtsm_hops
= 0;
6505 if (peer
->sort
== BGP_PEER_EBGP
)
6506 ret
= peer_ebgp_multihop_unset(peer
);
6509 sockopt_minttl(peer
->su
.sa
.sa_family
,
6512 if ((peer
->status
< Established
)
6513 && peer
->doppelganger
6514 && (peer
->doppelganger
->fd
>= 0))
6515 sockopt_minttl(peer
->su
.sa
.sa_family
,
6516 peer
->doppelganger
->fd
,
6526 * If peer clear is invoked in a loop for all peers on the BGP instance,
6527 * it may end up freeing the doppelganger, and if this was the next node
6528 * to the current node, we would end up accessing the freed next node.
6529 * Pass along additional parameter which can be updated if next node
6530 * is freed; only required when walking the peer list on BGP instance.
6532 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6534 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6535 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6536 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6537 if (peer
->t_pmax_restart
) {
6538 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6539 if (bgp_debug_neighbor_events(peer
))
6541 "%s Maximum-prefix restart timer canceled",
6544 BGP_EVENT_ADD(peer
, BGP_Start
);
6548 peer
->v_start
= BGP_INIT_START_TIMER
;
6549 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6550 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6551 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6553 bgp_session_reset_safe(peer
, nnode
);
6558 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6559 enum bgp_clear_type stype
)
6561 struct peer_af
*paf
;
6563 if (peer
->status
!= Established
)
6566 if (!peer
->afc
[afi
][safi
])
6567 return BGP_ERR_AF_UNCONFIGURED
;
6569 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6571 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6572 /* Clear the "neighbor x.x.x.x default-originate" flag */
6573 paf
= peer_af_find(peer
, afi
, safi
);
6574 if (paf
&& paf
->subgroup
6575 && CHECK_FLAG(paf
->subgroup
->sflags
,
6576 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6577 UNSET_FLAG(paf
->subgroup
->sflags
,
6578 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6580 bgp_announce_route(peer
, afi
, safi
);
6583 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6584 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6585 PEER_CAP_ORF_PREFIX_SM_ADV
)
6586 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6587 PEER_CAP_ORF_PREFIX_RM_RCV
)
6588 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6589 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6590 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6591 uint8_t prefix_type
;
6593 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6594 PEER_CAP_ORF_PREFIX_RM_RCV
))
6595 prefix_type
= ORF_TYPE_PREFIX
;
6597 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6599 if (filter
->plist
[FILTER_IN
].plist
) {
6600 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6601 PEER_STATUS_ORF_PREFIX_SEND
))
6602 bgp_route_refresh_send(
6603 peer
, afi
, safi
, prefix_type
,
6605 bgp_route_refresh_send(peer
, afi
, safi
,
6607 REFRESH_IMMEDIATE
, 0);
6609 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6610 PEER_STATUS_ORF_PREFIX_SEND
))
6611 bgp_route_refresh_send(
6612 peer
, afi
, safi
, prefix_type
,
6613 REFRESH_IMMEDIATE
, 1);
6615 bgp_route_refresh_send(peer
, afi
, safi
,
6622 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6623 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6624 /* If neighbor has soft reconfiguration inbound flag.
6625 Use Adj-RIB-In database. */
6626 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6627 PEER_FLAG_SOFT_RECONFIG
))
6628 bgp_soft_reconfig_in(peer
, afi
, safi
);
6630 /* If neighbor has route refresh capability, send route
6632 message to the peer. */
6633 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6634 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6635 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6638 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6644 /* Display peer uptime.*/
6645 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6648 time_t uptime1
, epoch_tbuf
;
6651 /* If there is no connection has been done before print `never'. */
6654 json_object_string_add(json
, "peerUptime", "never");
6655 json_object_int_add(json
, "peerUptimeMsec", 0);
6657 snprintf(buf
, len
, "never");
6661 /* Get current time. */
6662 uptime1
= bgp_clock();
6664 tm
= gmtime(&uptime1
);
6666 if (uptime1
< ONE_DAY_SECOND
)
6667 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6669 else if (uptime1
< ONE_WEEK_SECOND
)
6670 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6672 else if (uptime1
< ONE_YEAR_SECOND
)
6673 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6674 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6676 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6678 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6681 epoch_tbuf
= time(NULL
) - uptime1
;
6682 json_object_string_add(json
, "peerUptime", buf
);
6683 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6684 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6691 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6692 afi_t afi
, safi_t safi
)
6694 struct bgp_filter
*filter
;
6698 filter
= &peer
->filter
[afi
][safi
];
6700 /* distribute-list. */
6701 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6703 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6704 filter
->dlist
[FILTER_IN
].name
);
6706 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6708 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6709 filter
->dlist
[FILTER_OUT
].name
);
6712 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6714 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6715 filter
->plist
[FILTER_IN
].name
);
6717 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6719 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6720 filter
->plist
[FILTER_OUT
].name
);
6723 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6724 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6725 filter
->map
[RMAP_IN
].name
);
6727 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6729 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6730 filter
->map
[RMAP_OUT
].name
);
6732 /* unsuppress-map */
6733 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6734 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6735 filter
->usmap
.name
);
6738 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6740 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6741 filter
->aslist
[FILTER_IN
].name
);
6743 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6745 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6746 filter
->aslist
[FILTER_OUT
].name
);
6749 /* BGP peer configuration display function. */
6750 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6753 struct peer
*g_peer
= NULL
;
6754 char buf
[SU_ADDRSTRLEN
];
6756 int if_pg_printed
= FALSE
;
6757 int if_ras_printed
= FALSE
;
6759 /* Skip dynamic neighbors. */
6760 if (peer_dynamic_neighbor(peer
))
6764 addr
= peer
->conf_if
;
6768 /************************************
6769 ****** Global to the neighbor ******
6770 ************************************/
6771 if (peer
->conf_if
) {
6772 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6773 vty_out(vty
, " neighbor %s interface v6only", addr
);
6775 vty_out(vty
, " neighbor %s interface", addr
);
6777 if (peer_group_active(peer
)) {
6778 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6779 if_pg_printed
= TRUE
;
6780 } else if (peer
->as_type
== AS_SPECIFIED
) {
6781 vty_out(vty
, " remote-as %u", peer
->as
);
6782 if_ras_printed
= TRUE
;
6783 } else if (peer
->as_type
== AS_INTERNAL
) {
6784 vty_out(vty
, " remote-as internal");
6785 if_ras_printed
= TRUE
;
6786 } else if (peer
->as_type
== AS_EXTERNAL
) {
6787 vty_out(vty
, " remote-as external");
6788 if_ras_printed
= TRUE
;
6794 /* remote-as and peer-group */
6795 /* peer is a member of a peer-group */
6796 if (peer_group_active(peer
)) {
6797 g_peer
= peer
->group
->conf
;
6799 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6800 if (peer
->as_type
== AS_SPECIFIED
) {
6801 vty_out(vty
, " neighbor %s remote-as %u\n",
6803 } else if (peer
->as_type
== AS_INTERNAL
) {
6805 " neighbor %s remote-as internal\n",
6807 } else if (peer
->as_type
== AS_EXTERNAL
) {
6809 " neighbor %s remote-as external\n",
6814 /* For swpX peers we displayed the peer-group
6815 * via 'neighbor swpX interface peer-group WORD' */
6817 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6821 /* peer is NOT a member of a peer-group */
6823 /* peer is a peer-group, declare the peer-group */
6824 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6825 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6828 if (!if_ras_printed
) {
6829 if (peer
->as_type
== AS_SPECIFIED
) {
6830 vty_out(vty
, " neighbor %s remote-as %u\n",
6832 } else if (peer
->as_type
== AS_INTERNAL
) {
6834 " neighbor %s remote-as internal\n",
6836 } else if (peer
->as_type
== AS_EXTERNAL
) {
6838 " neighbor %s remote-as external\n",
6845 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6846 vty_out(vty
, " neighbor %s local-as %u", addr
,
6847 peer
->change_local_as
);
6848 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6849 vty_out(vty
, " no-prepend");
6850 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6851 vty_out(vty
, " replace-as");
6857 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6861 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6862 if (peer
->tx_shutdown_message
)
6863 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6864 peer
->tx_shutdown_message
);
6866 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6870 if (peer
->bfd_info
) {
6871 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6872 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6877 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6878 vty_out(vty
, " neighbor %s password %s\n", addr
,
6882 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6883 if (!peer_group_active(peer
)) {
6884 vty_out(vty
, " neighbor %s solo\n", addr
);
6889 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6890 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6893 /* Local interface name */
6895 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6899 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6900 vty_out(vty
, " neighbor %s passive\n", addr
);
6903 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6904 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6905 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6906 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6911 /* ttl-security hops */
6912 if (peer
->gtsm_hops
!= 0) {
6913 if (!peer_group_active(peer
)
6914 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6915 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6916 addr
, peer
->gtsm_hops
);
6920 /* disable-connected-check */
6921 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6922 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6924 /* enforce-first-as */
6925 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6926 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6929 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6930 if (peer
->update_source
)
6931 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6932 sockunion2str(peer
->update_source
, buf
,
6934 else if (peer
->update_if
)
6935 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6939 /* advertisement-interval */
6940 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6941 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6945 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6946 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6947 peer
->keepalive
, peer
->holdtime
);
6949 /* timers connect */
6950 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6951 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6954 /* capability dynamic */
6955 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6956 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6958 /* capability extended-nexthop */
6959 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6960 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6962 " no neighbor %s capability extended-nexthop\n",
6966 " neighbor %s capability extended-nexthop\n",
6970 /* dont-capability-negotiation */
6971 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
6972 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
6974 /* override-capability */
6975 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
6976 vty_out(vty
, " neighbor %s override-capability\n", addr
);
6978 /* strict-capability-match */
6979 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
6980 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
6983 /* BGP peer configuration display function. */
6984 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6985 struct peer
*peer
, afi_t afi
, safi_t safi
)
6987 struct peer
*g_peer
= NULL
;
6989 bool flag_scomm
, flag_secomm
, flag_slcomm
;
6991 /* Skip dynamic neighbors. */
6992 if (peer_dynamic_neighbor(peer
))
6996 addr
= peer
->conf_if
;
7000 /************************************
7001 ****** Per AF to the neighbor ******
7002 ************************************/
7003 if (peer_group_active(peer
)) {
7004 g_peer
= peer
->group
->conf
;
7006 /* If the peer-group is active but peer is not, print a 'no
7008 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7009 vty_out(vty
, " no neighbor %s activate\n", addr
);
7012 /* If the peer-group is not active but peer is, print an
7014 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7015 vty_out(vty
, " neighbor %s activate\n", addr
);
7018 if (peer
->afc
[afi
][safi
]) {
7019 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7020 if (bgp_flag_check(bgp
,
7021 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7022 vty_out(vty
, " neighbor %s activate\n",
7026 vty_out(vty
, " neighbor %s activate\n", addr
);
7028 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7029 if (!bgp_flag_check(bgp
,
7030 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7032 " no neighbor %s activate\n",
7039 /* addpath TX knobs */
7040 if (peergroup_af_flag_check(peer
, afi
, safi
,
7041 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
7042 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
7045 if (peergroup_af_flag_check(peer
, afi
, safi
,
7046 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
7047 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
7051 /* ORF capability. */
7052 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7053 || peergroup_af_flag_check(peer
, afi
, safi
,
7054 PEER_FLAG_ORF_PREFIX_RM
)) {
7055 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7057 if (peergroup_af_flag_check(peer
, afi
, safi
,
7058 PEER_FLAG_ORF_PREFIX_SM
)
7059 && peergroup_af_flag_check(peer
, afi
, safi
,
7060 PEER_FLAG_ORF_PREFIX_RM
))
7061 vty_out(vty
, " both");
7062 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7063 PEER_FLAG_ORF_PREFIX_SM
))
7064 vty_out(vty
, " send");
7066 vty_out(vty
, " receive");
7070 /* Route reflector client. */
7071 if (peergroup_af_flag_check(peer
, afi
, safi
,
7072 PEER_FLAG_REFLECTOR_CLIENT
)) {
7073 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7076 /* next-hop-self force */
7077 if (peergroup_af_flag_check(peer
, afi
, safi
,
7078 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7079 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7083 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7084 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7087 /* remove-private-AS */
7088 if (peergroup_af_flag_check(peer
, afi
, safi
,
7089 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7090 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7094 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7095 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7096 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7100 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7101 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7102 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7105 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7106 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7107 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7111 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7112 vty_out(vty
, " neighbor %s as-override\n", addr
);
7115 /* send-community print. */
7116 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7117 PEER_FLAG_SEND_COMMUNITY
);
7118 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7119 PEER_FLAG_SEND_EXT_COMMUNITY
);
7120 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7121 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7123 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7124 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7125 vty_out(vty
, " no neighbor %s send-community all\n",
7130 " no neighbor %s send-community\n",
7134 " no neighbor %s send-community extended\n",
7139 " no neighbor %s send-community large\n",
7143 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7144 vty_out(vty
, " neighbor %s send-community all\n",
7146 } else if (flag_scomm
&& flag_secomm
) {
7147 vty_out(vty
, " neighbor %s send-community both\n",
7151 vty_out(vty
, " neighbor %s send-community\n",
7155 " neighbor %s send-community extended\n",
7159 " neighbor %s send-community large\n",
7164 /* Default information */
7165 if (peergroup_af_flag_check(peer
, afi
, safi
,
7166 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7167 vty_out(vty
, " neighbor %s default-originate", addr
);
7169 if (peer
->default_rmap
[afi
][safi
].name
)
7170 vty_out(vty
, " route-map %s",
7171 peer
->default_rmap
[afi
][safi
].name
);
7176 /* Soft reconfiguration inbound. */
7177 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7178 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7182 /* maximum-prefix. */
7183 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7184 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7185 peer
->pmax
[afi
][safi
]);
7187 if (peer
->pmax_threshold
[afi
][safi
]
7188 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7189 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7190 if (peer_af_flag_check(peer
, afi
, safi
,
7191 PEER_FLAG_MAX_PREFIX_WARNING
))
7192 vty_out(vty
, " warning-only");
7193 if (peer
->pmax_restart
[afi
][safi
])
7194 vty_out(vty
, " restart %u",
7195 peer
->pmax_restart
[afi
][safi
]);
7200 /* Route server client. */
7201 if (peergroup_af_flag_check(peer
, afi
, safi
,
7202 PEER_FLAG_RSERVER_CLIENT
)) {
7203 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7206 /* Nexthop-local unchanged. */
7207 if (peergroup_af_flag_check(peer
, afi
, safi
,
7208 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7209 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7212 /* allowas-in <1-10> */
7213 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7214 if (peer_af_flag_check(peer
, afi
, safi
,
7215 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7216 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7217 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7218 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7220 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7221 peer
->allowas_in
[afi
][safi
]);
7226 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7227 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7228 peer
->weight
[afi
][safi
]);
7231 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7233 /* atribute-unchanged. */
7234 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7235 || (safi
!= SAFI_EVPN
7236 && peer_af_flag_check(peer
, afi
, safi
,
7237 PEER_FLAG_NEXTHOP_UNCHANGED
))
7238 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7240 if (!peer_group_active(peer
)
7241 || peergroup_af_flag_check(peer
, afi
, safi
,
7242 PEER_FLAG_AS_PATH_UNCHANGED
)
7243 || peergroup_af_flag_check(peer
, afi
, safi
,
7244 PEER_FLAG_NEXTHOP_UNCHANGED
)
7245 || peergroup_af_flag_check(peer
, afi
, safi
,
7246 PEER_FLAG_MED_UNCHANGED
)) {
7249 " neighbor %s attribute-unchanged%s%s%s\n",
7251 peer_af_flag_check(peer
, afi
, safi
,
7252 PEER_FLAG_AS_PATH_UNCHANGED
)
7255 peer_af_flag_check(peer
, afi
, safi
,
7256 PEER_FLAG_NEXTHOP_UNCHANGED
)
7259 peer_af_flag_check(peer
, afi
, safi
,
7260 PEER_FLAG_MED_UNCHANGED
)
7267 /* Address family based peer configuration display. */
7268 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7272 struct peer_group
*group
;
7273 struct listnode
*node
, *nnode
;
7276 vty_frame(vty
, " !\n address-family ");
7277 if (afi
== AFI_IP
) {
7278 if (safi
== SAFI_UNICAST
)
7279 vty_frame(vty
, "ipv4 unicast");
7280 else if (safi
== SAFI_LABELED_UNICAST
)
7281 vty_frame(vty
, "ipv4 labeled-unicast");
7282 else if (safi
== SAFI_MULTICAST
)
7283 vty_frame(vty
, "ipv4 multicast");
7284 else if (safi
== SAFI_MPLS_VPN
)
7285 vty_frame(vty
, "ipv4 vpn");
7286 else if (safi
== SAFI_ENCAP
)
7287 vty_frame(vty
, "ipv4 encap");
7288 else if (safi
== SAFI_FLOWSPEC
)
7289 vty_frame(vty
, "ipv4 flowspec");
7290 } else if (afi
== AFI_IP6
) {
7291 if (safi
== SAFI_UNICAST
)
7292 vty_frame(vty
, "ipv6 unicast");
7293 else if (safi
== SAFI_LABELED_UNICAST
)
7294 vty_frame(vty
, "ipv6 labeled-unicast");
7295 else if (safi
== SAFI_MULTICAST
)
7296 vty_frame(vty
, "ipv6 multicast");
7297 else if (safi
== SAFI_MPLS_VPN
)
7298 vty_frame(vty
, "ipv6 vpn");
7299 else if (safi
== SAFI_ENCAP
)
7300 vty_frame(vty
, "ipv6 encap");
7301 else if (safi
== SAFI_FLOWSPEC
)
7302 vty_frame(vty
, "ipv6 flowspec");
7303 } else if (afi
== AFI_L2VPN
) {
7304 if (safi
== SAFI_EVPN
)
7305 vty_frame(vty
, "l2vpn evpn");
7307 vty_frame(vty
, "\n");
7309 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7311 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7313 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7315 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7316 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7318 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7319 /* Skip dynamic neighbors. */
7320 if (peer_dynamic_neighbor(peer
))
7323 /* Do not display doppelganger peers */
7324 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7325 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7328 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7329 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7331 if (safi
== SAFI_EVPN
)
7332 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7334 if (safi
== SAFI_FLOWSPEC
)
7335 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7337 if (safi
== SAFI_UNICAST
) {
7338 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7339 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7340 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7342 vty_out(vty
, " export vpn\n");
7344 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7345 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7347 vty_out(vty
, " import vpn\n");
7349 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7350 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7353 for (ALL_LIST_ELEMENTS_RO(
7354 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7356 vty_out(vty
, " import vrf %s\n", name
);
7360 vty_endframe(vty
, " exit-address-family\n");
7363 /* clang-format off */
7364 #if CONFDATE > 20190517
7365 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7367 /* clang-format on */
7369 int bgp_config_write(struct vty
*vty
)
7373 struct peer_group
*group
;
7375 struct listnode
*node
, *nnode
;
7376 struct listnode
*mnode
, *mnnode
;
7378 /* BGP Multiple instance. */
7379 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7380 vty_out(vty
, "no bgp multiple-instance\n");
7384 /* BGP Config type. */
7385 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7386 vty_out(vty
, "bgp config-type cisco\n");
7390 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7391 vty_out(vty
, "bgp route-map delay-timer %u\n",
7392 bm
->rmap_update_timer
);
7395 vty_out(vty
, "!\n");
7397 /* BGP configuration. */
7398 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7400 /* skip all auto created vrf as they dont have user config */
7401 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7404 /* Migrate deprecated 'bgp enforce-first-as'
7405 * config to 'neighbor * enforce-first-as' configs
7407 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7408 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7409 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7410 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7413 /* Router bgp ASN */
7414 vty_out(vty
, "router bgp %u", bgp
->as
);
7416 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7418 vty_out(vty
, " %s %s",
7420 == BGP_INSTANCE_TYPE_VIEW
)
7427 /* No Synchronization */
7428 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7429 vty_out(vty
, " no synchronization\n");
7431 /* BGP fast-external-failover. */
7432 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7433 vty_out(vty
, " no bgp fast-external-failover\n");
7435 /* BGP router ID. */
7436 if (bgp
->router_id_static
.s_addr
!= 0)
7437 vty_out(vty
, " bgp router-id %s\n",
7438 inet_ntoa(bgp
->router_id_static
));
7440 /* BGP log-neighbor-changes. */
7441 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7442 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7443 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7445 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7449 /* BGP configuration. */
7450 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7451 vty_out(vty
, " bgp always-compare-med\n");
7453 /* BGP default ipv4-unicast. */
7454 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7455 vty_out(vty
, " no bgp default ipv4-unicast\n");
7457 /* BGP default local-preference. */
7458 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7459 vty_out(vty
, " bgp default local-preference %u\n",
7460 bgp
->default_local_pref
);
7462 /* BGP default show-hostname */
7463 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7464 != DFLT_BGP_SHOW_HOSTNAME
)
7465 vty_out(vty
, " %sbgp default show-hostname\n",
7466 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7470 /* BGP default subgroup-pkt-queue-max. */
7471 if (bgp
->default_subgroup_pkt_queue_max
7472 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7473 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7474 bgp
->default_subgroup_pkt_queue_max
);
7476 /* BGP client-to-client reflection. */
7477 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7478 vty_out(vty
, " no bgp client-to-client reflection\n");
7480 /* BGP cluster ID. */
7481 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7482 vty_out(vty
, " bgp cluster-id %s\n",
7483 inet_ntoa(bgp
->cluster_id
));
7485 /* Disable ebgp connected nexthop check */
7486 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7488 " bgp disable-ebgp-connected-route-check\n");
7490 /* Confederation identifier*/
7491 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7492 vty_out(vty
, " bgp confederation identifier %i\n",
7495 /* Confederation peer */
7496 if (bgp
->confed_peers_cnt
> 0) {
7499 vty_out(vty
, " bgp confederation peers");
7501 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7502 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7507 /* BGP deterministic-med. */
7508 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7509 != DFLT_BGP_DETERMINISTIC_MED
)
7510 vty_out(vty
, " %sbgp deterministic-med\n",
7511 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7515 /* BGP update-delay. */
7516 bgp_config_write_update_delay(vty
, bgp
);
7518 if (bgp
->v_maxmed_onstartup
7519 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7520 vty_out(vty
, " bgp max-med on-startup %u",
7521 bgp
->v_maxmed_onstartup
);
7522 if (bgp
->maxmed_onstartup_value
7523 != BGP_MAXMED_VALUE_DEFAULT
)
7525 bgp
->maxmed_onstartup_value
);
7528 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7529 vty_out(vty
, " bgp max-med administrative");
7530 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7531 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7536 bgp_config_write_wpkt_quanta(vty
, bgp
);
7538 bgp_config_write_rpkt_quanta(vty
, bgp
);
7541 bgp_config_write_coalesce_time(vty
, bgp
);
7543 /* BGP graceful-restart. */
7544 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7546 " bgp graceful-restart stalepath-time %u\n",
7547 bgp
->stalepath_time
);
7548 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7549 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7551 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7552 vty_out(vty
, " bgp graceful-restart\n");
7554 /* BGP graceful-shutdown */
7555 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7556 vty_out(vty
, " bgp graceful-shutdown\n");
7558 /* BGP graceful-restart Preserve State F bit. */
7559 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7561 " bgp graceful-restart preserve-fw-state\n");
7563 /* BGP bestpath method. */
7564 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7565 vty_out(vty
, " bgp bestpath as-path ignore\n");
7566 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7567 vty_out(vty
, " bgp bestpath as-path confed\n");
7569 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7570 if (bgp_flag_check(bgp
,
7571 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7573 " bgp bestpath as-path multipath-relax as-set\n");
7576 " bgp bestpath as-path multipath-relax\n");
7580 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7582 " bgp route-reflector allow-outbound-policy\n");
7584 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7585 vty_out(vty
, " bgp bestpath compare-routerid\n");
7586 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7587 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7588 vty_out(vty
, " bgp bestpath med");
7589 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7590 vty_out(vty
, " confed");
7591 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7592 vty_out(vty
, " missing-as-worst");
7596 /* BGP network import check. */
7597 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7598 != DFLT_BGP_IMPORT_CHECK
)
7599 vty_out(vty
, " %sbgp network import-check\n",
7600 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7604 /* BGP flag dampening. */
7605 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7606 BGP_CONFIG_DAMPENING
))
7607 bgp_config_write_damp(vty
);
7609 /* BGP timers configuration. */
7610 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7611 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7612 vty_out(vty
, " timers bgp %u %u\n",
7613 bgp
->default_keepalive
, bgp
->default_holdtime
);
7616 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7617 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7620 /* Normal neighbor configuration. */
7621 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7622 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7623 bgp_config_write_peer_global(vty
, bgp
, peer
);
7626 /* listen range and limit for dynamic BGP neighbors */
7627 bgp_config_write_listen(vty
, bgp
);
7630 * BGP default autoshutdown neighbors
7632 * This must be placed after any peer and peer-group
7633 * configuration, to avoid setting all peers to shutdown after
7634 * a daemon restart, which is undesired behavior. (see #2286)
7636 if (bgp
->autoshutdown
)
7637 vty_out(vty
, " bgp default shutdown\n");
7639 /* No auto-summary */
7640 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7641 vty_out(vty
, " no auto-summary\n");
7643 /* IPv4 unicast configuration. */
7644 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7646 /* IPv4 multicast configuration. */
7647 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7649 /* IPv4 labeled-unicast configuration. */
7650 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7652 /* IPv4 VPN configuration. */
7653 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7655 /* ENCAPv4 configuration. */
7656 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7658 /* FLOWSPEC v4 configuration. */
7659 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7661 /* IPv6 unicast configuration. */
7662 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7664 /* IPv6 multicast configuration. */
7665 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7667 /* IPv6 labeled-unicast configuration. */
7668 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7669 SAFI_LABELED_UNICAST
);
7671 /* IPv6 VPN configuration. */
7672 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7674 /* ENCAPv6 configuration. */
7675 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7677 /* FLOWSPEC v6 configuration. */
7678 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7680 /* EVPN configuration. */
7681 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7684 bgp_rfapi_cfg_write(vty
, bgp
);
7687 vty_out(vty
, "!\n");
7692 void bgp_master_init(struct thread_master
*master
)
7696 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7699 bm
->bgp
= list_new();
7700 bm
->listen_sockets
= list_new();
7701 bm
->port
= BGP_PORT_DEFAULT
;
7702 bm
->master
= master
;
7703 bm
->start_time
= bgp_clock();
7704 bm
->t_rmap_update
= NULL
;
7705 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7706 bm
->terminating
= false;
7708 bgp_process_queue_init();
7710 /* init the rd id space.
7711 assign 0th index in the bitfield,
7712 so that we start with id 1
7714 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7715 bf_assign_zero_index(bm
->rd_idspace
);
7717 /* Enable multiple instances by default. */
7718 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7720 /* mpls label dynamic allocation pool */
7721 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7723 QOBJ_REG(bm
, bgp_master
);
7727 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7728 * instance delete (non-default only) or BGP exit.
7730 static void bgp_if_finish(struct bgp
*bgp
)
7732 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7733 struct interface
*ifp
;
7735 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7738 FOR_ALL_INTERFACES (vrf
, ifp
) {
7739 struct listnode
*c_node
, *c_nnode
;
7740 struct connected
*c
;
7742 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7743 bgp_connected_delete(bgp
, c
);
7747 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7749 struct vrf
*vrf
= NULL
;
7750 struct listnode
*next
;
7753 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7754 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7756 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7757 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7760 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7764 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7765 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7766 {.completions
= NULL
},
7769 struct frr_pthread
*bgp_pth_io
;
7770 struct frr_pthread
*bgp_pth_ka
;
7772 static void bgp_pthreads_init()
7774 assert(!bgp_pth_io
);
7775 assert(!bgp_pth_ka
);
7779 struct frr_pthread_attr io
= {
7780 .start
= frr_pthread_attr_default
.start
,
7781 .stop
= frr_pthread_attr_default
.stop
,
7783 struct frr_pthread_attr ka
= {
7784 .start
= bgp_keepalives_start
,
7785 .stop
= bgp_keepalives_stop
,
7787 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7788 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7791 void bgp_pthreads_run()
7793 frr_pthread_run(bgp_pth_io
, NULL
);
7794 frr_pthread_run(bgp_pth_ka
, NULL
);
7796 /* Wait until threads are ready. */
7797 frr_pthread_wait_running(bgp_pth_io
);
7798 frr_pthread_wait_running(bgp_pth_ka
);
7801 void bgp_pthreads_finish()
7803 frr_pthread_stop_all();
7804 frr_pthread_finish();
7807 void bgp_init(unsigned short instance
)
7810 /* allocates some vital data structures used by peer commands in
7813 /* pre-init pthreads */
7814 bgp_pthreads_init();
7817 bgp_zebra_init(bm
->master
, instance
);
7820 vnc_zebra_init(bm
->master
);
7823 /* BGP VTY commands installation. */
7831 bgp_route_map_init();
7832 bgp_scan_vty_init();
7837 bgp_ethernetvpn_init();
7838 bgp_flowspec_vty_init();
7840 /* Access list initialize. */
7842 access_list_add_hook(peer_distribute_update
);
7843 access_list_delete_hook(peer_distribute_update
);
7845 /* Filter list initialize. */
7847 as_list_add_hook(peer_aslist_add
);
7848 as_list_delete_hook(peer_aslist_del
);
7850 /* Prefix list initialize.*/
7852 prefix_list_add_hook(peer_prefix_list_update
);
7853 prefix_list_delete_hook(peer_prefix_list_update
);
7855 /* Community list initialize. */
7856 bgp_clist
= community_list_init();
7861 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7864 void bgp_terminate(void)
7868 struct listnode
*node
, *nnode
;
7869 struct listnode
*mnode
, *mnnode
;
7873 /* Close the listener sockets first as this prevents peers from
7875 * to reconnect on receiving the peer unconfig message. In the presence
7876 * of a large number of peers this will ensure that no peer is left with
7877 * a dangling connection
7879 /* reverse bgp_master_init */
7882 if (bm
->listen_sockets
)
7883 list_delete(&bm
->listen_sockets
);
7885 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7886 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7887 if (peer
->status
== Established
7888 || peer
->status
== OpenSent
7889 || peer
->status
== OpenConfirm
)
7890 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7891 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7893 if (bm
->process_main_queue
)
7894 work_queue_free_and_null(&bm
->process_main_queue
);
7896 if (bm
->t_rmap_update
)
7897 BGP_TIMER_OFF(bm
->t_rmap_update
);