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
)
1806 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1807 flog_err(BGP_ERR_PEER_GROUP
, "%s was called for peer-group %s",
1808 __func__
, peer
->host
);
1812 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1814 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1815 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1816 return BGP_ERR_PEER_SAFI_CONFLICT
;
1818 /* Nothing to do if we've already activated this peer */
1819 if (peer
->afc
[afi
][safi
])
1822 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1825 active
= peer_active(peer
);
1826 peer
->afc
[afi
][safi
] = 1;
1829 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1831 if (!active
&& peer_active(peer
)) {
1832 bgp_timer_set(peer
);
1834 if (peer
->status
== Established
) {
1835 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1836 peer
->afc_adv
[afi
][safi
] = 1;
1837 bgp_capability_send(peer
, afi
, safi
,
1839 CAPABILITY_ACTION_SET
);
1840 if (peer
->afc_recv
[afi
][safi
]) {
1841 peer
->afc_nego
[afi
][safi
] = 1;
1842 bgp_announce_route(peer
, afi
, safi
);
1845 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1846 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1847 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1850 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1851 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1852 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1853 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1860 /* Activate the peer or peer group for specified AFI and SAFI. */
1861 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1864 struct peer_group
*group
;
1865 struct listnode
*node
, *nnode
;
1866 struct peer
*tmp_peer
;
1869 /* Nothing to do if we've already activated this peer */
1870 if (peer
->afc
[afi
][safi
])
1875 /* This is a peer-group so activate all of the members of the
1876 * peer-group as well */
1877 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1879 /* Do not activate a peer for both SAFI_UNICAST and
1880 * SAFI_LABELED_UNICAST */
1881 if ((safi
== SAFI_UNICAST
1882 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1883 || (safi
== SAFI_LABELED_UNICAST
1884 && peer
->afc
[afi
][SAFI_UNICAST
]))
1885 return BGP_ERR_PEER_SAFI_CONFLICT
;
1887 peer
->afc
[afi
][safi
] = 1;
1888 group
= peer
->group
;
1890 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1891 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1894 ret
|= peer_activate_af(peer
, afi
, safi
);
1897 /* If this is the first peer to be activated for this
1898 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1899 if (safi
== SAFI_LABELED_UNICAST
1900 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1902 if (BGP_DEBUG(zebra
, ZEBRA
))
1904 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1906 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1907 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1910 if (safi
== SAFI_FLOWSPEC
) {
1911 /* connect to table manager */
1912 bgp_zebra_init_tm_connect(bgp
);
1917 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1920 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1921 flog_err(BGP_ERR_PEER_GROUP
, "%s was called for peer-group %s",
1922 __func__
, peer
->host
);
1926 /* Nothing to do if we've already deactivated this peer */
1927 if (!peer
->afc
[afi
][safi
])
1930 /* De-activate the address family configuration. */
1931 peer
->afc
[afi
][safi
] = 0;
1933 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1934 flog_err(BGP_ERR_PEER_DELETE
,
1935 "couldn't delete af structure for peer %s",
1940 if (peer
->status
== Established
) {
1941 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1942 peer
->afc_adv
[afi
][safi
] = 0;
1943 peer
->afc_nego
[afi
][safi
] = 0;
1945 if (peer_active_nego(peer
)) {
1946 bgp_capability_send(peer
, afi
, safi
,
1948 CAPABILITY_ACTION_UNSET
);
1949 bgp_clear_route(peer
, afi
, safi
);
1950 peer
->pcount
[afi
][safi
] = 0;
1952 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1953 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1954 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1957 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1958 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1959 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1966 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1969 struct peer_group
*group
;
1970 struct peer
*tmp_peer
;
1971 struct listnode
*node
, *nnode
;
1974 /* Nothing to do if we've already de-activated this peer */
1975 if (!peer
->afc
[afi
][safi
])
1978 /* This is a peer-group so de-activate all of the members of the
1979 * peer-group as well */
1980 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1981 peer
->afc
[afi
][safi
] = 0;
1982 group
= peer
->group
;
1984 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1985 flog_err(BGP_ERR_PEER_DELETE
,
1986 "couldn't delete af structure for peer %s",
1990 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1991 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
1994 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
1999 /* If this is the last peer to be deactivated for this
2000 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2001 if (safi
== SAFI_LABELED_UNICAST
2002 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2003 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2005 if (BGP_DEBUG(zebra
, ZEBRA
))
2007 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2009 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2010 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2015 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2018 return peer_activate(peer
, afi
, safi
);
2020 return peer_deactivate(peer
, afi
, safi
);
2023 static void peer_nsf_stop(struct peer
*peer
)
2028 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2029 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2031 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2032 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2033 peer
->nsf
[afi
][safi
] = 0;
2035 if (peer
->t_gr_restart
) {
2036 BGP_TIMER_OFF(peer
->t_gr_restart
);
2037 if (bgp_debug_neighbor_events(peer
))
2038 zlog_debug("%s graceful restart timer stopped",
2041 if (peer
->t_gr_stale
) {
2042 BGP_TIMER_OFF(peer
->t_gr_stale
);
2043 if (bgp_debug_neighbor_events(peer
))
2045 "%s graceful restart stalepath timer stopped",
2048 bgp_clear_route_all(peer
);
2051 /* Delete peer from confguration.
2053 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2054 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2056 * This function /should/ take care to be idempotent, to guard against
2057 * it being called multiple times through stray events that come in
2058 * that happen to result in this function being called again. That
2059 * said, getting here for a "Deleted" peer is a bug in the neighbour
2062 int peer_delete(struct peer
*peer
)
2068 struct bgp_filter
*filter
;
2069 struct listnode
*pn
;
2072 assert(peer
->status
!= Deleted
);
2075 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2077 bgp_reads_off(peer
);
2078 bgp_writes_off(peer
);
2079 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2080 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2082 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2083 peer_nsf_stop(peer
);
2085 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2087 /* If this peer belongs to peer group, clear up the
2090 if (peer_dynamic_neighbor(peer
))
2091 peer_drop_dynamic_neighbor(peer
);
2093 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2095 peer
); /* group->peer list reference */
2096 list_delete_node(peer
->group
->peer
, pn
);
2101 /* Withdraw all information from routing table. We can not use
2102 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2103 * executed after peer structure is deleted.
2105 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2107 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2109 if (peer
->doppelganger
) {
2110 peer
->doppelganger
->doppelganger
= NULL
;
2111 peer
->doppelganger
= NULL
;
2114 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2115 bgp_fsm_change_status(peer
, Deleted
);
2117 /* Remove from NHT */
2118 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2119 bgp_unlink_nexthop_by_peer(peer
);
2121 /* Password configuration */
2122 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2123 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2125 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2126 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2127 bgp_md5_unset(peer
);
2130 bgp_timer_set(peer
); /* stops all timers for Deleted */
2132 /* Delete from all peer list. */
2133 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2134 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2135 peer_unlock(peer
); /* bgp peer list reference */
2136 list_delete_node(bgp
->peer
, pn
);
2137 hash_release(bgp
->peerhash
, peer
);
2142 stream_fifo_free(peer
->ibuf
);
2147 stream_fifo_free(peer
->obuf
);
2151 if (peer
->ibuf_work
) {
2152 ringbuf_del(peer
->ibuf_work
);
2153 peer
->ibuf_work
= NULL
;
2156 if (peer
->obuf_work
) {
2157 stream_free(peer
->obuf_work
);
2158 peer
->obuf_work
= NULL
;
2161 if (peer
->scratch
) {
2162 stream_free(peer
->scratch
);
2163 peer
->scratch
= NULL
;
2166 /* Local and remote addresses. */
2167 if (peer
->su_local
) {
2168 sockunion_free(peer
->su_local
);
2169 peer
->su_local
= NULL
;
2172 if (peer
->su_remote
) {
2173 sockunion_free(peer
->su_remote
);
2174 peer
->su_remote
= NULL
;
2177 /* Free filter related memory. */
2178 FOREACH_AFI_SAFI (afi
, safi
) {
2179 filter
= &peer
->filter
[afi
][safi
];
2181 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2182 if (filter
->dlist
[i
].name
) {
2183 XFREE(MTYPE_BGP_FILTER_NAME
,
2184 filter
->dlist
[i
].name
);
2185 filter
->dlist
[i
].name
= NULL
;
2188 if (filter
->plist
[i
].name
) {
2189 XFREE(MTYPE_BGP_FILTER_NAME
,
2190 filter
->plist
[i
].name
);
2191 filter
->plist
[i
].name
= NULL
;
2194 if (filter
->aslist
[i
].name
) {
2195 XFREE(MTYPE_BGP_FILTER_NAME
,
2196 filter
->aslist
[i
].name
);
2197 filter
->aslist
[i
].name
= NULL
;
2201 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2202 if (filter
->map
[i
].name
) {
2203 XFREE(MTYPE_BGP_FILTER_NAME
,
2204 filter
->map
[i
].name
);
2205 filter
->map
[i
].name
= NULL
;
2209 if (filter
->usmap
.name
) {
2210 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2211 filter
->usmap
.name
= NULL
;
2214 if (peer
->default_rmap
[afi
][safi
].name
) {
2215 XFREE(MTYPE_ROUTE_MAP_NAME
,
2216 peer
->default_rmap
[afi
][safi
].name
);
2217 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2221 FOREACH_AFI_SAFI (afi
, safi
)
2222 peer_af_delete(peer
, afi
, safi
);
2224 if (peer
->hostname
) {
2225 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2226 peer
->hostname
= NULL
;
2229 if (peer
->domainname
) {
2230 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2231 peer
->domainname
= NULL
;
2234 peer_unlock(peer
); /* initial reference */
2239 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2241 return strcmp(g1
->name
, g2
->name
);
2244 /* Peer group cofiguration. */
2245 static struct peer_group
*peer_group_new(void)
2247 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2248 sizeof(struct peer_group
));
2251 static void peer_group_free(struct peer_group
*group
)
2253 XFREE(MTYPE_PEER_GROUP
, group
);
2256 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2258 struct peer_group
*group
;
2259 struct listnode
*node
, *nnode
;
2261 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2262 if (strcmp(group
->name
, name
) == 0)
2268 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2270 struct peer_group
*group
;
2273 group
= peer_group_lookup(bgp
, name
);
2277 group
= peer_group_new();
2280 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2281 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2282 group
->peer
= list_new();
2283 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2284 group
->listen_range
[afi
] = list_new();
2285 group
->conf
= peer_new(bgp
);
2286 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2287 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2288 if (group
->conf
->host
)
2289 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2290 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2291 group
->conf
->group
= group
;
2292 group
->conf
->as
= 0;
2293 group
->conf
->ttl
= 1;
2294 group
->conf
->gtsm_hops
= 0;
2295 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2296 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2297 listnode_add_sort(bgp
->group
, group
);
2302 static void peer_group2peer_config_copy(struct peer_group
*group
,
2312 peer
->as
= conf
->as
;
2315 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2316 peer
->change_local_as
= conf
->change_local_as
;
2319 peer
->ttl
= conf
->ttl
;
2322 peer
->gtsm_hops
= conf
->gtsm_hops
;
2324 /* peer flags apply */
2325 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2326 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2327 flags_tmp
&= ~peer
->flags_override
;
2329 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2330 SET_FLAG(peer
->flags
, flags_tmp
);
2331 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2333 /* peer timers apply */
2334 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2335 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2336 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2339 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2340 PEER_ATTR_INHERIT(peer
, group
, connect
);
2341 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2342 peer
->v_connect
= conf
->connect
;
2344 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2347 /* advertisement-interval apply */
2348 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2349 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2350 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2351 peer
->v_routeadv
= conf
->routeadv
;
2353 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2354 ? BGP_DEFAULT_IBGP_ROUTEADV
2355 : BGP_DEFAULT_EBGP_ROUTEADV
;
2358 /* password apply */
2359 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2360 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2361 MTYPE_PEER_PASSWORD
);
2363 if (!BGP_PEER_SU_UNSPEC(peer
))
2366 /* update-source apply */
2367 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2368 if (conf
->update_source
) {
2369 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2370 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2371 } else if (conf
->update_if
) {
2372 sockunion_free(peer
->update_source
);
2373 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2374 MTYPE_PEER_UPDATE_SOURCE
);
2378 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2381 /* Peer group's remote AS configuration. */
2382 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2385 struct peer_group
*group
;
2387 struct listnode
*node
, *nnode
;
2389 group
= peer_group_lookup(bgp
, group_name
);
2393 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2397 /* When we setup peer-group AS number all peer group member's AS
2398 number must be updated to same number. */
2399 peer_as_change(group
->conf
, *as
, as_type
);
2401 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2402 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2403 || (peer
->as_type
!= as_type
))
2404 peer_as_change(peer
, *as
, as_type
);
2410 int peer_group_delete(struct peer_group
*group
)
2414 struct prefix
*prefix
;
2416 struct listnode
*node
, *nnode
;
2421 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2422 other
= peer
->doppelganger
;
2424 if (other
&& other
->status
!= Deleted
) {
2425 other
->group
= NULL
;
2429 list_delete_and_null(&group
->peer
);
2431 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2432 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2434 prefix_free(prefix
);
2436 list_delete_and_null(&group
->listen_range
[afi
]);
2439 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2442 bfd_info_free(&(group
->conf
->bfd_info
));
2444 group
->conf
->group
= NULL
;
2445 peer_delete(group
->conf
);
2447 /* Delete from all peer_group list. */
2448 listnode_delete(bgp
->group
, group
);
2450 peer_group_free(group
);
2455 int peer_group_remote_as_delete(struct peer_group
*group
)
2457 struct peer
*peer
, *other
;
2458 struct listnode
*node
, *nnode
;
2460 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2461 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2464 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2465 other
= peer
->doppelganger
;
2469 if (other
&& other
->status
!= Deleted
) {
2470 other
->group
= NULL
;
2474 list_delete_all_node(group
->peer
);
2476 group
->conf
->as
= 0;
2477 group
->conf
->as_type
= AS_UNSPECIFIED
;
2482 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2484 struct prefix
*prefix
;
2485 struct listnode
*node
, *nnode
;
2488 afi
= family2afi(range
->family
);
2490 /* Group needs remote AS configured. */
2491 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2492 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2494 /* Ensure no duplicates. Currently we don't care about overlaps. */
2495 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2496 if (prefix_same(range
, prefix
))
2500 prefix
= prefix_new();
2501 prefix_copy(prefix
, range
);
2502 listnode_add(group
->listen_range
[afi
], prefix
);
2506 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2508 struct prefix
*prefix
, prefix2
;
2509 struct listnode
*node
, *nnode
;
2512 char buf
[PREFIX2STR_BUFFER
];
2514 afi
= family2afi(range
->family
);
2516 /* Identify the listen range. */
2517 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2518 if (prefix_same(range
, prefix
))
2523 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2525 prefix2str(prefix
, buf
, sizeof(buf
));
2527 /* Dispose off any dynamic neighbors that exist due to this listen range
2529 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2530 if (!peer_dynamic_neighbor(peer
))
2533 sockunion2hostprefix(&peer
->su
, &prefix2
);
2534 if (prefix_match(prefix
, &prefix2
)) {
2535 if (bgp_debug_neighbor_events(peer
))
2537 "Deleting dynamic neighbor %s group %s upon "
2538 "delete of listen range %s",
2539 peer
->host
, group
->name
, buf
);
2544 /* Get rid of the listen range */
2545 listnode_delete(group
->listen_range
[afi
], prefix
);
2550 /* Bind specified peer to peer group. */
2551 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2552 struct peer_group
*group
, as_t
*as
)
2554 int first_member
= 0;
2558 /* Lookup the peer. */
2560 peer
= peer_lookup(bgp
, su
);
2562 /* The peer exist, bind it to the peer-group */
2564 /* When the peer already belongs to a peer-group, check the
2566 if (peer_group_active(peer
)) {
2568 /* The peer is already bound to the peer-group,
2571 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2574 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2577 /* The peer has not specified a remote-as, inherit it from the
2579 if (peer
->as_type
== AS_UNSPECIFIED
) {
2580 peer
->as_type
= group
->conf
->as_type
;
2581 peer
->as
= group
->conf
->as
;
2584 if (!group
->conf
->as
) {
2585 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2586 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2589 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2592 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2596 peer_group2peer_config_copy(group
, peer
);
2598 FOREACH_AFI_SAFI (afi
, safi
) {
2599 if (group
->conf
->afc
[afi
][safi
]) {
2600 peer
->afc
[afi
][safi
] = 1;
2602 if (peer_af_find(peer
, afi
, safi
)
2603 || peer_af_create(peer
, afi
, safi
)) {
2604 peer_group2peer_config_copy_af(
2605 group
, peer
, afi
, safi
);
2607 } else if (peer
->afc
[afi
][safi
])
2608 peer_deactivate(peer
, afi
, safi
);
2612 assert(group
&& peer
->group
== group
);
2614 listnode_delete(bgp
->peer
, peer
);
2616 peer
->group
= group
;
2617 listnode_add_sort(bgp
->peer
, peer
);
2619 peer
= peer_lock(peer
); /* group->peer list reference */
2620 listnode_add(group
->peer
, peer
);
2624 /* Advertisement-interval reset */
2625 if (!CHECK_FLAG(group
->conf
->flags
,
2626 PEER_FLAG_ROUTEADV
)) {
2627 group
->conf
->v_routeadv
=
2628 (peer_sort(group
->conf
)
2630 ? BGP_DEFAULT_IBGP_ROUTEADV
2631 : BGP_DEFAULT_EBGP_ROUTEADV
;
2634 /* ebgp-multihop reset */
2635 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2636 group
->conf
->ttl
= MAXTTL
;
2638 /* local-as reset */
2639 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2640 group
->conf
->change_local_as
= 0;
2641 peer_flag_unset(group
->conf
,
2642 PEER_FLAG_LOCAL_AS
);
2643 peer_flag_unset(group
->conf
,
2644 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2645 peer_flag_unset(group
->conf
,
2646 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2650 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2652 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2653 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2654 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2655 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2657 bgp_session_reset(peer
);
2661 /* Create a new peer. */
2663 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2664 && (!group
->conf
->as
)) {
2665 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2668 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2669 group
->conf
->as_type
, 0, 0, group
);
2671 peer
= peer_lock(peer
); /* group->peer list reference */
2672 listnode_add(group
->peer
, peer
);
2674 peer_group2peer_config_copy(group
, peer
);
2676 /* If the peer-group is active for this afi/safi then activate
2678 FOREACH_AFI_SAFI (afi
, safi
) {
2679 if (group
->conf
->afc
[afi
][safi
]) {
2680 peer
->afc
[afi
][safi
] = 1;
2681 peer_af_create(peer
, afi
, safi
);
2682 peer_group2peer_config_copy_af(group
, peer
, afi
,
2684 } else if (peer
->afc
[afi
][safi
])
2685 peer_deactivate(peer
, afi
, safi
);
2688 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2690 /* Set up peer's events and timers. */
2691 if (peer_active(peer
))
2692 bgp_timer_set(peer
);
2698 static int bgp_startup_timer_expire(struct thread
*thread
)
2702 bgp
= THREAD_ARG(thread
);
2703 bgp
->t_startup
= NULL
;
2709 * On shutdown we call the cleanup function which
2710 * does a free of the link list nodes, free up
2711 * the data we are pointing at too.
2713 static void bgp_vrf_string_name_delete(void *data
)
2717 XFREE(MTYPE_TMP
, vname
);
2720 /* BGP instance creation by `router bgp' commands. */
2721 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2722 enum bgp_instance_type inst_type
)
2728 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2731 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2732 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2733 zlog_debug("Creating Default VRF, AS %u", *as
);
2735 zlog_debug("Creating %s %s, AS %u",
2736 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2743 bgp
->heuristic_coalesce
= true;
2744 bgp
->inst_type
= inst_type
;
2745 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2747 bgp
->peer_self
= peer_new(bgp
);
2748 if (bgp
->peer_self
->host
)
2749 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2750 bgp
->peer_self
->host
=
2751 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2752 if (bgp
->peer_self
->hostname
!= NULL
) {
2753 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2754 bgp
->peer_self
->hostname
= NULL
;
2756 if (cmd_hostname_get())
2757 bgp
->peer_self
->hostname
=
2758 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2760 if (bgp
->peer_self
->domainname
!= NULL
) {
2761 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2762 bgp
->peer_self
->domainname
= NULL
;
2764 if (cmd_domainname_get())
2765 bgp
->peer_self
->domainname
=
2766 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2767 bgp
->peer
= list_new();
2768 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2769 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2771 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2773 bgp
->group
= list_new();
2774 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2776 FOREACH_AFI_SAFI (afi
, safi
) {
2777 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2778 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2779 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2781 /* Enable maximum-paths */
2782 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2784 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2788 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2789 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2790 bgp
->default_subgroup_pkt_queue_max
=
2791 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2792 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2793 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2794 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2795 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2796 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2797 bgp
->dynamic_neighbors_count
= 0;
2798 #if DFLT_BGP_IMPORT_CHECK
2799 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2801 #if DFLT_BGP_SHOW_HOSTNAME
2802 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2804 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2805 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2807 #if DFLT_BGP_DETERMINISTIC_MED
2808 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2810 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2815 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2816 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2818 assert(bgp
->rfapi_cfg
);
2820 #endif /* ENABLE_BGP_VNC */
2822 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2823 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2824 bgp
->vpn_policy
[afi
].afi
= afi
;
2825 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2826 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2829 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2830 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2831 bgp_vrf_string_name_delete
;
2832 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2833 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2834 bgp_vrf_string_name_delete
;
2837 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2839 /* TODO - The startup timer needs to be run for the whole of BGP
2841 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2842 bgp
->restart_time
, &bgp
->t_startup
);
2845 /* printable name we can use in debug messages */
2846 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2847 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2857 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2859 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2860 snprintf(bgp
->name_pretty
, len
, "%s %s",
2861 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2867 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2868 memory_order_relaxed
);
2869 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2870 memory_order_relaxed
);
2871 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2875 update_bgp_group_init(bgp
);
2877 /* assign a unique rd id for auto derivation of vrf's RD */
2878 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2885 /* Return the "default VRF" instance of BGP. */
2886 struct bgp
*bgp_get_default(void)
2889 struct listnode
*node
, *nnode
;
2891 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2892 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2897 /* Lookup BGP entry. */
2898 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2901 struct listnode
*node
, *nnode
;
2903 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2905 && ((bgp
->name
== NULL
&& name
== NULL
)
2906 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2911 /* Lookup BGP structure by view name. */
2912 struct bgp
*bgp_lookup_by_name(const char *name
)
2915 struct listnode
*node
, *nnode
;
2917 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2918 if ((bgp
->name
== NULL
&& name
== NULL
)
2919 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2924 /* Lookup BGP instance based on VRF id. */
2925 /* Note: Only to be used for incoming messages from Zebra. */
2926 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2930 /* Lookup VRF (in tree) and follow link. */
2931 vrf
= vrf_lookup_by_id(vrf_id
);
2934 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2937 /* handle socket creation or deletion, if necessary
2938 * this is called for all new BGP instances
2940 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
2945 /* Create BGP server socket, if listen mode not disabled */
2946 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
2948 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
2950 * suppress vrf socket
2952 if (create
== FALSE
) {
2953 bgp_close_vrf_socket(bgp
);
2957 return BGP_ERR_INVALID_VALUE
;
2959 * if vrf_id did not change
2961 if (vrf
->vrf_id
== old_vrf_id
)
2963 if (old_vrf_id
!= VRF_UNKNOWN
) {
2964 /* look for old socket. close it. */
2965 bgp_close_vrf_socket(bgp
);
2967 /* if backend is not yet identified ( VRF_UNKNOWN) then
2968 * creation will be done later
2970 if (vrf
->vrf_id
== VRF_UNKNOWN
)
2972 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
2974 return BGP_ERR_INVALID_VALUE
;
2977 return bgp_check_main_socket(create
, bgp
);
2980 /* Called from VTY commands. */
2981 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
2982 enum bgp_instance_type inst_type
)
2985 struct vrf
*vrf
= NULL
;
2987 /* Multiple instance check. */
2988 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
2990 bgp
= bgp_lookup_by_name(name
);
2992 bgp
= bgp_get_default();
2994 /* Already exists. */
2996 if (bgp
->as
!= *as
) {
2998 return BGP_ERR_INSTANCE_MISMATCH
;
3000 if (bgp
->inst_type
!= inst_type
)
3001 return BGP_ERR_INSTANCE_MISMATCH
;
3006 /* BGP instance name can not be specified for single instance.
3009 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3011 /* Get default BGP structure if exists. */
3012 bgp
= bgp_get_default();
3015 if (bgp
->as
!= *as
) {
3017 return BGP_ERR_AS_MISMATCH
;
3024 bgp
= bgp_create(as
, name
, inst_type
);
3025 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3026 bgp_address_init(bgp
);
3027 bgp_tip_hash_init(bgp
);
3031 bgp
->t_rmap_def_originate_eval
= NULL
;
3033 /* If Default instance or VRF, link to the VRF structure, if present. */
3034 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3035 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3036 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3038 bgp_vrf_link(bgp
, vrf
);
3040 /* BGP server socket already processed if BGP instance
3041 * already part of the list
3043 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3044 listnode_add(bm
->bgp
, bgp
);
3046 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3047 bgp_zebra_instance_register(bgp
);
3054 * Make BGP instance "up". Applies only to VRFs (non-default) and
3055 * implies the VRF has been learnt from Zebra.
3057 void bgp_instance_up(struct bgp
*bgp
)
3060 struct listnode
*node
, *next
;
3062 /* Register with zebra. */
3063 bgp_zebra_instance_register(bgp
);
3065 /* Kick off any peers that may have been configured. */
3066 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3067 if (!BGP_PEER_START_SUPPRESSED(peer
))
3068 BGP_EVENT_ADD(peer
, BGP_Start
);
3071 /* Process any networks that have been configured. */
3072 bgp_static_add(bgp
);
3076 * Make BGP instance "down". Applies only to VRFs (non-default) and
3077 * implies the VRF has been deleted by Zebra.
3079 void bgp_instance_down(struct bgp
*bgp
)
3082 struct listnode
*node
;
3083 struct listnode
*next
;
3086 if (bgp
->t_rmap_def_originate_eval
) {
3087 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3088 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3092 /* Bring down peers, so corresponding routes are purged. */
3093 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3094 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3095 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3096 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3098 bgp_session_reset(peer
);
3101 /* Purge network and redistributed routes. */
3102 bgp_purge_static_redist_routes(bgp
);
3104 /* Cleanup registered nexthops (flags) */
3105 bgp_cleanup_nexthops(bgp
);
3108 /* Delete BGP instance. */
3109 int bgp_delete(struct bgp
*bgp
)
3112 struct peer_group
*group
;
3113 struct listnode
*node
, *next
;
3119 THREAD_OFF(bgp
->t_startup
);
3120 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3121 THREAD_OFF(bgp
->t_update_delay
);
3122 THREAD_OFF(bgp
->t_establish_wait
);
3124 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3125 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3126 zlog_debug("Deleting Default VRF");
3128 zlog_debug("Deleting %s %s",
3129 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3135 /* unmap from RT list */
3136 bgp_evpn_vrf_delete(bgp
);
3139 if (bgp
->t_rmap_def_originate_eval
) {
3140 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3141 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3145 /* Inform peers we're going down. */
3146 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3147 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3148 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3149 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3152 /* Delete static routes (networks). */
3153 bgp_static_delete(bgp
);
3155 /* Unset redistribution. */
3156 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3157 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3158 if (i
!= ZEBRA_ROUTE_BGP
)
3159 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3161 /* Free peers and peer-groups. */
3162 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3163 peer_group_delete(group
);
3165 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3168 if (bgp
->peer_self
) {
3169 peer_delete(bgp
->peer_self
);
3170 bgp
->peer_self
= NULL
;
3173 update_bgp_group_free(bgp
);
3175 /* TODO - Other memory may need to be freed - e.g., NHT */
3180 bgp_cleanup_routes(bgp
);
3182 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3183 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3186 &bgp
->vpn_policy
[afi
]
3187 .import_redirect_rtlist
);
3188 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3191 /* Deregister from Zebra, if needed */
3192 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3193 bgp_zebra_instance_deregister(bgp
);
3195 /* Remove visibility via the master list - there may however still be
3196 * routes to be processed still referencing the struct bgp.
3198 listnode_delete(bm
->bgp
, bgp
);
3200 /* Free interfaces in this instance. */
3203 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3204 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3206 bgp_vrf_unlink(bgp
, vrf
);
3208 thread_master_free_unused(bm
->master
);
3209 bgp_unlock(bgp
); /* initial reference */
3214 void bgp_free(struct bgp
*bgp
)
3218 struct bgp_table
*table
;
3219 struct bgp_node
*rn
;
3220 struct bgp_rmap
*rmap
;
3224 list_delete_and_null(&bgp
->group
);
3225 list_delete_and_null(&bgp
->peer
);
3227 if (bgp
->peerhash
) {
3228 hash_free(bgp
->peerhash
);
3229 bgp
->peerhash
= NULL
;
3232 FOREACH_AFI_SAFI (afi
, safi
) {
3233 /* Special handling for 2-level routing tables. */
3234 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3235 || safi
== SAFI_EVPN
) {
3236 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3237 rn
= bgp_route_next(rn
)) {
3238 table
= (struct bgp_table
*)rn
->info
;
3239 bgp_table_finish(&table
);
3242 if (bgp
->route
[afi
][safi
])
3243 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3244 if (bgp
->aggregate
[afi
][safi
])
3245 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3246 if (bgp
->rib
[afi
][safi
])
3247 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3248 rmap
= &bgp
->table_map
[afi
][safi
];
3250 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3253 bgp_scan_finish(bgp
);
3254 bgp_address_destroy(bgp
);
3255 bgp_tip_hash_destroy(bgp
);
3257 /* release the auto RD id */
3258 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3260 bgp_evpn_cleanup(bgp
);
3261 bgp_pbr_cleanup(bgp
);
3263 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3264 vpn_policy_direction_t dir
;
3266 if (bgp
->vpn_policy
[afi
].import_vrf
)
3267 list_delete_and_null(&bgp
->vpn_policy
[afi
].import_vrf
);
3268 if (bgp
->vpn_policy
[afi
].export_vrf
)
3269 list_delete_and_null(&bgp
->vpn_policy
[afi
].export_vrf
);
3271 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3272 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3273 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3274 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3275 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3276 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3280 XFREE(MTYPE_BGP
, bgp
->name
);
3281 if (bgp
->name_pretty
)
3282 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3284 XFREE(MTYPE_BGP
, bgp
);
3287 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3290 struct listnode
*node
, *nnode
;
3296 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3297 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3298 && !CHECK_FLAG(peer
->sflags
,
3299 PEER_STATUS_ACCEPT_PEER
))
3301 } else if (bm
->bgp
!= NULL
) {
3302 struct listnode
*bgpnode
, *nbgpnode
;
3304 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3305 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3307 && !strcmp(peer
->conf_if
, conf_if
)
3308 && !CHECK_FLAG(peer
->sflags
,
3309 PEER_STATUS_ACCEPT_PEER
))
3315 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3318 struct listnode
*node
, *nnode
;
3324 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3325 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3326 && !CHECK_FLAG(peer
->sflags
,
3327 PEER_STATUS_ACCEPT_PEER
))
3329 } else if (bm
->bgp
!= NULL
) {
3330 struct listnode
*bgpnode
, *nbgpnode
;
3332 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3333 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3335 && !strcmp(peer
->hostname
, hostname
)
3336 && !CHECK_FLAG(peer
->sflags
,
3337 PEER_STATUS_ACCEPT_PEER
))
3343 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3345 struct peer
*peer
= NULL
;
3346 struct peer tmp_peer
;
3348 memset(&tmp_peer
, 0, sizeof(struct peer
));
3351 * We do not want to find the doppelganger peer so search for the peer
3353 * the hash that has PEER_FLAG_CONFIG_NODE
3355 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3360 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3361 } else if (bm
->bgp
!= NULL
) {
3362 struct listnode
*bgpnode
, *nbgpnode
;
3364 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3365 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3374 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3375 union sockunion
*su
,
3376 struct peer_group
*group
)
3382 /* Create peer first; we've already checked group config is valid. */
3383 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3384 group
->conf
->as_type
, 0, 0, group
);
3389 peer
= peer_lock(peer
);
3390 listnode_add(group
->peer
, peer
);
3392 peer_group2peer_config_copy(group
, peer
);
3395 * Bind peer for all AFs configured for the group. We don't call
3396 * peer_group_bind as that is sub-optimal and does some stuff we don't
3399 FOREACH_AFI_SAFI (afi
, safi
) {
3400 if (!group
->conf
->afc
[afi
][safi
])
3402 peer
->afc
[afi
][safi
] = 1;
3404 if (!peer_af_find(peer
, afi
, safi
))
3405 peer_af_create(peer
, afi
, safi
);
3407 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3410 /* Mark as dynamic, but also as a "config node" for other things to
3412 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3413 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3419 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3420 struct prefix
*prefix
)
3422 struct listnode
*node
, *nnode
;
3423 struct prefix
*range
;
3426 afi
= family2afi(prefix
->family
);
3428 if (group
->listen_range
[afi
])
3429 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3431 if (prefix_match(range
, prefix
))
3438 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3439 struct prefix
**listen_range
)
3441 struct prefix
*range
= NULL
;
3442 struct peer_group
*group
= NULL
;
3443 struct listnode
*node
, *nnode
;
3445 *listen_range
= NULL
;
3447 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3448 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3451 } else if (bm
->bgp
!= NULL
) {
3452 struct listnode
*bgpnode
, *nbgpnode
;
3454 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3455 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3456 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3462 *listen_range
= range
;
3463 return (group
&& range
) ? group
: NULL
;
3466 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3468 struct peer_group
*group
;
3471 struct prefix prefix
;
3472 struct prefix
*listen_range
;
3474 char buf
[PREFIX2STR_BUFFER
];
3475 char buf1
[PREFIX2STR_BUFFER
];
3477 sockunion2hostprefix(su
, &prefix
);
3479 /* See if incoming connection matches a configured listen range. */
3480 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3491 prefix2str(&prefix
, buf
, sizeof(buf
));
3492 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3494 if (bgp_debug_neighbor_events(NULL
))
3496 "Dynamic Neighbor %s matches group %s listen range %s",
3497 buf
, group
->name
, buf1
);
3499 /* Are we within the listen limit? */
3500 dncount
= gbgp
->dynamic_neighbors_count
;
3502 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3503 if (bgp_debug_neighbor_events(NULL
))
3504 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3505 inet_sutop(su
, buf
),
3506 gbgp
->dynamic_neighbors_limit
);
3510 /* Ensure group is not disabled. */
3511 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3512 if (bgp_debug_neighbor_events(NULL
))
3514 "Dynamic Neighbor %s rejected - group %s disabled",
3519 /* Check that at least one AF is activated for the group. */
3520 if (!peer_group_af_configured(group
)) {
3521 if (bgp_debug_neighbor_events(NULL
))
3523 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3528 /* Create dynamic peer and bind to associated group. */
3529 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3532 gbgp
->dynamic_neighbors_count
= ++dncount
;
3534 if (bgp_debug_neighbor_events(peer
))
3535 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3536 peer
->host
, group
->name
, dncount
);
3541 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3544 if (peer
->group
->bgp
) {
3545 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3547 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3549 if (bgp_debug_neighbor_events(peer
))
3550 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3551 peer
->group
->name
, dncount
);
3554 /* If peer is configured at least one address family return 1. */
3555 int peer_active(struct peer
*peer
)
3557 if (BGP_PEER_SU_UNSPEC(peer
))
3559 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3560 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3561 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3562 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3563 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3564 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3565 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3566 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3567 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3568 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3569 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3574 /* If peer is negotiated at least one address family return 1. */
3575 int peer_active_nego(struct peer
*peer
)
3577 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3578 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3579 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3580 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3581 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3582 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3583 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3584 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3585 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3586 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3587 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3588 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3589 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3594 /* peer_flag_change_type. */
3595 enum peer_change_type
{
3598 peer_change_reset_in
,
3599 peer_change_reset_out
,
3602 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3603 enum peer_change_type type
)
3605 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3608 if (peer
->status
!= Established
)
3611 if (type
== peer_change_reset
) {
3612 /* If we're resetting session, we've to delete both peer struct
3614 if ((peer
->doppelganger
)
3615 && (peer
->doppelganger
->status
!= Deleted
)
3616 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3617 PEER_FLAG_CONFIG_NODE
)))
3618 peer_delete(peer
->doppelganger
);
3620 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3621 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3622 } else if (type
== peer_change_reset_in
) {
3623 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3624 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3625 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3627 if ((peer
->doppelganger
)
3628 && (peer
->doppelganger
->status
!= Deleted
)
3629 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3630 PEER_FLAG_CONFIG_NODE
)))
3631 peer_delete(peer
->doppelganger
);
3633 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3634 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3636 } else if (type
== peer_change_reset_out
) {
3637 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3638 bgp_announce_route(peer
, afi
, safi
);
3642 struct peer_flag_action
{
3646 /* This flag can be set for peer-group member. */
3647 uint8_t not_for_member
;
3649 /* Action when the flag is changed. */
3650 enum peer_change_type type
;
3653 static const struct peer_flag_action peer_flag_action_list
[] = {
3654 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3655 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3656 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3657 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3658 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3659 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3660 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3661 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3662 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3663 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3664 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3665 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3666 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3667 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3668 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3669 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3670 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3673 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3674 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3675 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3676 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3677 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3678 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3679 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3680 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3681 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3682 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3683 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3684 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3685 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3686 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3687 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3688 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3689 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3690 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3691 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3692 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3693 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3694 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3695 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3696 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3697 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3698 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3699 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3700 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3703 /* Proper action set. */
3704 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3705 int size
, struct peer_flag_action
*action
,
3712 const struct peer_flag_action
*match
= NULL
;
3714 /* Check peer's frag action. */
3715 for (i
= 0; i
< size
; i
++) {
3716 match
= &action_list
[i
];
3718 if (match
->flag
== 0)
3721 if (match
->flag
& flag
) {
3724 if (match
->type
== peer_change_reset_in
)
3726 if (match
->type
== peer_change_reset_out
)
3728 if (match
->type
== peer_change_reset
) {
3732 if (match
->not_for_member
)
3733 action
->not_for_member
= 1;
3737 /* Set peer clear type. */
3738 if (reset_in
&& reset_out
)
3739 action
->type
= peer_change_reset
;
3741 action
->type
= peer_change_reset_in
;
3743 action
->type
= peer_change_reset_out
;
3745 action
->type
= peer_change_none
;
3750 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3752 if (flag
== PEER_FLAG_SHUTDOWN
) {
3753 if (CHECK_FLAG(peer
->flags
, flag
)) {
3754 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3755 peer_nsf_stop(peer
);
3757 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3758 if (peer
->t_pmax_restart
) {
3759 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3760 if (bgp_debug_neighbor_events(peer
))
3762 "%s Maximum-prefix restart timer canceled",
3766 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3767 peer_nsf_stop(peer
);
3769 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3770 char *msg
= peer
->tx_shutdown_message
;
3773 if (!msg
&& peer_group_active(peer
))
3774 msg
= peer
->group
->conf
3775 ->tx_shutdown_message
;
3776 msglen
= msg
? strlen(msg
) : 0;
3781 uint8_t msgbuf
[129];
3784 memcpy(msgbuf
+ 1, msg
, msglen
);
3786 bgp_notify_send_with_data(
3787 peer
, BGP_NOTIFY_CEASE
,
3788 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3789 msgbuf
, msglen
+ 1);
3792 peer
, BGP_NOTIFY_CEASE
,
3793 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3795 bgp_session_reset(peer
);
3797 peer
->v_start
= BGP_INIT_START_TIMER
;
3798 BGP_EVENT_ADD(peer
, BGP_Stop
);
3800 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3801 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3802 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3803 else if (flag
== PEER_FLAG_PASSIVE
)
3804 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3805 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3806 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3808 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3809 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3811 bgp_session_reset(peer
);
3814 /* Change specified peer flag. */
3815 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3819 bool invert
, member_invert
;
3820 struct peer
*member
;
3821 struct listnode
*node
, *nnode
;
3822 struct peer_flag_action action
;
3824 memset(&action
, 0, sizeof(struct peer_flag_action
));
3825 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3827 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3828 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3831 /* Abort if no flag action exists. */
3833 return BGP_ERR_INVALID_FLAG
;
3835 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3836 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3837 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3838 return BGP_ERR_PEER_FLAG_CONFLICT
;
3840 /* Handle flag updates where desired state matches current state. */
3841 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3842 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3843 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3847 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3848 COND_FLAG(peer
->flags_override
, flag
, invert
);
3853 /* Inherit from peer-group or set/unset flags accordingly. */
3854 if (peer_group_active(peer
) && set
== invert
)
3855 peer_flag_inherit(peer
, flag
);
3857 COND_FLAG(peer
->flags
, flag
, set
);
3859 /* Check if handling a regular peer. */
3860 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3861 /* Update flag override state accordingly. */
3862 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3864 /* Execute flag action on peer. */
3865 if (action
.type
== peer_change_reset
)
3866 peer_flag_modify_action(peer
, flag
);
3868 /* Skip peer-group mechanics for regular peers. */
3873 * Update peer-group members, unless they are explicitely overriding
3874 * peer-group configuration.
3876 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3877 /* Skip peers with overridden configuration. */
3878 if (CHECK_FLAG(member
->flags_override
, flag
))
3881 /* Check if only member without group is inverted. */
3883 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3885 /* Skip peers with equivalent configuration. */
3886 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3889 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3892 /* Update flag on peer-group member. */
3893 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3895 /* Execute flag action on peer-group member. */
3896 if (action
.type
== peer_change_reset
)
3897 peer_flag_modify_action(member
, flag
);
3903 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3905 return peer_flag_modify(peer
, flag
, 1);
3908 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3910 return peer_flag_modify(peer
, flag
, 0);
3913 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3914 uint32_t flag
, bool set
)
3918 int addpath_tx_used
;
3919 bool invert
, member_invert
;
3921 struct peer
*member
;
3922 struct listnode
*node
, *nnode
;
3923 struct peer_flag_action action
;
3925 memset(&action
, 0, sizeof(struct peer_flag_action
));
3926 size
= sizeof peer_af_flag_action_list
3927 / sizeof(struct peer_flag_action
);
3929 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
3930 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3933 /* Abort if flag action exists. */
3935 return BGP_ERR_INVALID_FLAG
;
3937 /* Special check for reflector client. */
3938 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3939 && peer_sort(peer
) != BGP_PEER_IBGP
)
3940 return BGP_ERR_NOT_INTERNAL_PEER
;
3942 /* Special check for remove-private-AS. */
3943 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3944 && peer_sort(peer
) == BGP_PEER_IBGP
)
3945 return BGP_ERR_REMOVE_PRIVATE_AS
;
3947 /* as-override is not allowed for IBGP peers */
3948 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3949 return BGP_ERR_AS_OVERRIDE
;
3951 /* Handle flag updates where desired state matches current state. */
3952 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3953 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3954 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
3959 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3960 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
3967 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
3968 * if we are setting/unsetting flags which conflict with this flag
3969 * handle accordingly
3971 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
3975 * if we are setting NEXTHOP_SELF, we need to unset the
3976 * NEXTHOP_UNCHANGED flag
3978 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
3979 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
3980 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
3981 PEER_FLAG_NEXTHOP_UNCHANGED
);
3985 * if we are unsetting NEXTHOP_SELF, we need to set the
3986 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
3988 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
3989 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
3990 SET_FLAG(peer
->af_flags
[afi
][safi
],
3991 PEER_FLAG_NEXTHOP_UNCHANGED
);
3995 /* Inherit from peer-group or set/unset flags accordingly. */
3996 if (peer_group_active(peer
) && set
== invert
)
3997 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
3999 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4001 /* Execute action when peer is established. */
4002 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4003 && peer
->status
== Established
) {
4004 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4005 bgp_clear_adj_in(peer
, afi
, safi
);
4007 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4008 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4009 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4010 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4011 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4012 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4013 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4014 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4016 peer_change_action(peer
, afi
, safi
, action
.type
);
4020 /* Check if handling a regular peer. */
4021 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4022 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4026 * Update peer-group members, unless they are explicitely
4027 * overriding peer-group configuration.
4029 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4031 /* Skip peers with overridden configuration. */
4032 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4036 /* Check if only member without group is inverted. */
4038 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4042 /* Skip peers with equivalent configuration. */
4043 if (set
!= member_invert
4044 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4047 if (set
== member_invert
4048 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4051 /* Update flag on peer-group member. */
4052 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4053 set
!= member_invert
);
4055 /* Execute flag action on peer-group member. */
4056 if (member
->status
== Established
) {
4057 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4058 bgp_clear_adj_in(member
, afi
, safi
);
4060 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4061 member
->last_reset
=
4062 PEER_DOWN_RR_CLIENT_CHANGE
;
4064 == PEER_FLAG_RSERVER_CLIENT
)
4065 member
->last_reset
=
4066 PEER_DOWN_RS_CLIENT_CHANGE
;
4068 == PEER_FLAG_ORF_PREFIX_SM
)
4069 member
->last_reset
=
4070 PEER_DOWN_CAPABILITY_CHANGE
;
4072 == PEER_FLAG_ORF_PREFIX_RM
)
4073 member
->last_reset
=
4074 PEER_DOWN_CAPABILITY_CHANGE
;
4076 peer_change_action(member
, afi
, safi
,
4083 /* Track if addpath TX is in use */
4084 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4085 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4087 addpath_tx_used
= 0;
4090 addpath_tx_used
= 1;
4092 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4093 if (!bgp_flag_check(
4094 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4096 "%s: enabling bgp deterministic-med, this is required"
4097 " for addpath-tx-bestpath-per-AS",
4101 BGP_FLAG_DETERMINISTIC_MED
);
4102 bgp_recalculate_all_bestpaths(bgp
);
4106 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4108 if (CHECK_FLAG(member
->af_flags
[afi
][safi
],
4109 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4111 member
->af_flags
[afi
][safi
],
4112 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4113 addpath_tx_used
= 1;
4119 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4125 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4127 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4130 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4132 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4136 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4138 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4139 peer
->tx_shutdown_message
=
4140 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4144 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4146 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4151 /* EBGP multihop configuration. */
4152 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4154 struct peer_group
*group
;
4155 struct listnode
*node
, *nnode
;
4158 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4161 /* see comment in peer_ttl_security_hops_set() */
4162 if (ttl
!= MAXTTL
) {
4163 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4164 group
= peer
->group
;
4165 if (group
->conf
->gtsm_hops
!= 0)
4166 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4168 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4170 if (peer1
->sort
== BGP_PEER_IBGP
)
4173 if (peer1
->gtsm_hops
!= 0)
4174 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4177 if (peer
->gtsm_hops
!= 0)
4178 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4184 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4185 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4186 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4187 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4188 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4190 bgp_session_reset(peer
);
4193 group
= peer
->group
;
4194 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4195 if (peer
->sort
== BGP_PEER_IBGP
)
4198 peer
->ttl
= group
->conf
->ttl
;
4200 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4201 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4202 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4204 bgp_session_reset(peer
);
4210 int peer_ebgp_multihop_unset(struct peer
*peer
)
4212 struct peer_group
*group
;
4213 struct listnode
*node
, *nnode
;
4215 if (peer
->sort
== BGP_PEER_IBGP
)
4218 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4219 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4221 if (peer_group_active(peer
))
4222 peer
->ttl
= peer
->group
->conf
->ttl
;
4226 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4227 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4228 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4229 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4231 bgp_session_reset(peer
);
4233 group
= peer
->group
;
4234 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4235 if (peer
->sort
== BGP_PEER_IBGP
)
4240 if (peer
->fd
>= 0) {
4241 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4243 peer
, BGP_NOTIFY_CEASE
,
4244 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4246 bgp_session_reset(peer
);
4253 /* Neighbor description. */
4254 int peer_description_set(struct peer
*peer
, const char *desc
)
4257 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4259 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4264 int peer_description_unset(struct peer
*peer
)
4267 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4274 /* Neighbor update-source. */
4275 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4277 struct peer
*member
;
4278 struct listnode
*node
, *nnode
;
4280 /* Set flag and configuration on peer. */
4281 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4282 if (peer
->update_if
) {
4283 if (strcmp(peer
->update_if
, ifname
) == 0)
4285 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4287 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4288 sockunion_free(peer
->update_source
);
4289 peer
->update_source
= NULL
;
4291 /* Check if handling a regular peer. */
4292 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4293 /* Send notification or reset peer depending on state. */
4294 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4295 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4296 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4297 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4299 bgp_session_reset(peer
);
4301 /* Skip peer-group mechanics for regular peers. */
4306 * Set flag and configuration on all peer-group members, unless they are
4307 * explicitely overriding peer-group configuration.
4309 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4310 /* Skip peers with overridden configuration. */
4311 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4314 /* Skip peers with the same configuration. */
4315 if (member
->update_if
) {
4316 if (strcmp(member
->update_if
, ifname
) == 0)
4318 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4321 /* Set flag and configuration on peer-group member. */
4322 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4323 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4324 sockunion_free(member
->update_source
);
4325 member
->update_source
= NULL
;
4327 /* Send notification or reset peer depending on state. */
4328 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4329 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4330 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4331 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4333 bgp_session_reset(member
);
4339 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4341 struct peer
*member
;
4342 struct listnode
*node
, *nnode
;
4344 /* Set flag and configuration on peer. */
4345 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4346 if (peer
->update_source
) {
4347 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4349 sockunion_free(peer
->update_source
);
4351 peer
->update_source
= sockunion_dup(su
);
4352 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4354 /* Check if handling a regular peer. */
4355 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4356 /* Send notification or reset peer depending on state. */
4357 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4358 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4362 bgp_session_reset(peer
);
4364 /* Skip peer-group mechanics for regular peers. */
4369 * Set flag and configuration on all peer-group members, unless they are
4370 * explicitely overriding peer-group configuration.
4372 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4373 /* Skip peers with overridden configuration. */
4374 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4377 /* Skip peers with the same configuration. */
4378 if (member
->update_source
) {
4379 if (sockunion_cmp(member
->update_source
, su
) == 0)
4381 sockunion_free(member
->update_source
);
4384 /* Set flag and configuration on peer-group member. */
4385 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4386 member
->update_source
= sockunion_dup(su
);
4387 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4389 /* Send notification or reset peer depending on state. */
4390 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4391 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4392 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4393 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4395 bgp_session_reset(member
);
4401 int peer_update_source_unset(struct peer
*peer
)
4403 struct peer
*member
;
4404 struct listnode
*node
, *nnode
;
4406 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4409 /* Inherit configuration from peer-group if peer is member. */
4410 if (peer_group_active(peer
)) {
4411 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4412 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4413 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4414 MTYPE_PEER_UPDATE_SOURCE
);
4416 /* Otherwise remove flag and configuration from peer. */
4417 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4418 sockunion_free(peer
->update_source
);
4419 peer
->update_source
= NULL
;
4420 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4423 /* Check if handling a regular peer. */
4424 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4425 /* Send notification or reset peer depending on state. */
4426 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4427 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4428 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4429 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4431 bgp_session_reset(peer
);
4433 /* Skip peer-group mechanics for regular peers. */
4438 * Set flag and configuration on all peer-group members, unless they are
4439 * explicitely overriding peer-group configuration.
4441 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4442 /* Skip peers with overridden configuration. */
4443 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4446 /* Skip peers with the same configuration. */
4447 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4448 && !member
->update_source
&& !member
->update_if
)
4451 /* Remove flag and configuration on peer-group member. */
4452 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4453 sockunion_free(member
->update_source
);
4454 member
->update_source
= NULL
;
4455 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4457 /* Send notification or reset peer depending on state. */
4458 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4459 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4460 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4461 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4463 bgp_session_reset(member
);
4469 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4472 struct peer
*member
;
4473 struct listnode
*node
, *nnode
;
4475 /* Set flag and configuration on peer. */
4476 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4478 if (!peer
->default_rmap
[afi
][safi
].name
4479 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4480 if (peer
->default_rmap
[afi
][safi
].name
)
4481 XFREE(MTYPE_ROUTE_MAP_NAME
,
4482 peer
->default_rmap
[afi
][safi
].name
);
4484 peer
->default_rmap
[afi
][safi
].name
=
4485 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4486 peer
->default_rmap
[afi
][safi
].map
=
4487 route_map_lookup_by_name(rmap
);
4490 if (peer
->default_rmap
[afi
][safi
].name
)
4491 XFREE(MTYPE_ROUTE_MAP_NAME
,
4492 peer
->default_rmap
[afi
][safi
].name
);
4494 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4495 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4498 /* Check if handling a regular peer. */
4499 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4500 /* Update peer route announcements. */
4501 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4502 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4503 bgp_default_originate(peer
, afi
, safi
, 0);
4504 bgp_announce_route(peer
, afi
, safi
);
4507 /* Skip peer-group mechanics for regular peers. */
4512 * Set flag and configuration on all peer-group members, unless they are
4513 * explicitely overriding peer-group configuration.
4515 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4516 /* Skip peers with overridden configuration. */
4517 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4518 PEER_FLAG_DEFAULT_ORIGINATE
))
4521 /* Set flag and configuration on peer-group member. */
4522 SET_FLAG(member
->af_flags
[afi
][safi
],
4523 PEER_FLAG_DEFAULT_ORIGINATE
);
4525 if (member
->default_rmap
[afi
][safi
].name
)
4526 XFREE(MTYPE_ROUTE_MAP_NAME
,
4527 member
->default_rmap
[afi
][safi
].name
);
4529 member
->default_rmap
[afi
][safi
].name
=
4530 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4531 member
->default_rmap
[afi
][safi
].map
=
4532 route_map_lookup_by_name(rmap
);
4535 /* Update peer route announcements. */
4536 if (member
->status
== Established
4537 && member
->afc_nego
[afi
][safi
]) {
4538 update_group_adjust_peer(
4539 peer_af_find(member
, afi
, safi
));
4540 bgp_default_originate(member
, afi
, safi
, 0);
4541 bgp_announce_route(member
, afi
, safi
);
4548 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4550 struct peer
*member
;
4551 struct listnode
*node
, *nnode
;
4553 /* Inherit configuration from peer-group if peer is member. */
4554 if (peer_group_active(peer
)) {
4555 peer_af_flag_inherit(peer
, afi
, safi
,
4556 PEER_FLAG_DEFAULT_ORIGINATE
);
4557 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4558 default_rmap
[afi
][safi
].name
,
4559 MTYPE_ROUTE_MAP_NAME
);
4560 PEER_ATTR_INHERIT(peer
, peer
->group
,
4561 default_rmap
[afi
][safi
].map
);
4563 /* Otherwise remove flag and configuration from peer. */
4564 peer_af_flag_unset(peer
, afi
, safi
,
4565 PEER_FLAG_DEFAULT_ORIGINATE
);
4566 if (peer
->default_rmap
[afi
][safi
].name
)
4567 XFREE(MTYPE_ROUTE_MAP_NAME
,
4568 peer
->default_rmap
[afi
][safi
].name
);
4569 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4570 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4573 /* Check if handling a regular peer. */
4574 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4575 /* Update peer route announcements. */
4576 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4577 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4578 bgp_default_originate(peer
, afi
, safi
, 1);
4579 bgp_announce_route(peer
, afi
, safi
);
4582 /* Skip peer-group mechanics for regular peers. */
4587 * Remove flag and configuration from all peer-group members, unless
4588 * they are explicitely overriding peer-group configuration.
4590 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4591 /* Skip peers with overridden configuration. */
4592 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4593 PEER_FLAG_DEFAULT_ORIGINATE
))
4596 /* Remove flag and configuration on peer-group member. */
4597 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4598 PEER_FLAG_DEFAULT_ORIGINATE
);
4599 if (peer
->default_rmap
[afi
][safi
].name
)
4600 XFREE(MTYPE_ROUTE_MAP_NAME
,
4601 peer
->default_rmap
[afi
][safi
].name
);
4602 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4603 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4605 /* Update peer route announcements. */
4606 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4607 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4608 bgp_default_originate(peer
, afi
, safi
, 1);
4609 bgp_announce_route(peer
, afi
, safi
);
4616 int peer_port_set(struct peer
*peer
, uint16_t port
)
4622 int peer_port_unset(struct peer
*peer
)
4624 peer
->port
= BGP_PORT_DEFAULT
;
4629 * Helper function that is called after the name of the policy
4630 * being used by a peer has changed (AF specific). Automatically
4631 * initiates inbound or outbound processing as needed.
4633 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4637 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4638 if (peer
->status
== Established
)
4639 bgp_announce_route(peer
, afi
, safi
);
4641 if (peer
->status
!= Established
)
4644 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4645 PEER_FLAG_SOFT_RECONFIG
))
4646 bgp_soft_reconfig_in(peer
, afi
, safi
);
4647 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4648 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4649 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4654 /* neighbor weight. */
4655 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4657 struct peer
*member
;
4658 struct listnode
*node
, *nnode
;
4660 /* Set flag and configuration on peer. */
4661 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4662 if (peer
->weight
[afi
][safi
] != weight
) {
4663 peer
->weight
[afi
][safi
] = weight
;
4664 peer_on_policy_change(peer
, afi
, safi
, 0);
4667 /* Skip peer-group mechanics for regular peers. */
4668 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4672 * Set flag and configuration on all peer-group members, unless they are
4673 * explicitely overriding peer-group configuration.
4675 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4676 /* Skip peers with overridden configuration. */
4677 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4681 /* Set flag and configuration on peer-group member. */
4682 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4683 if (member
->weight
[afi
][safi
] != weight
) {
4684 member
->weight
[afi
][safi
] = weight
;
4685 peer_on_policy_change(member
, afi
, safi
, 0);
4692 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4694 struct peer
*member
;
4695 struct listnode
*node
, *nnode
;
4697 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4700 /* Inherit configuration from peer-group if peer is member. */
4701 if (peer_group_active(peer
)) {
4702 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4703 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4705 peer_on_policy_change(peer
, afi
, safi
, 0);
4709 /* Remove flag and configuration from peer. */
4710 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4711 peer
->weight
[afi
][safi
] = 0;
4712 peer_on_policy_change(peer
, afi
, safi
, 0);
4714 /* Skip peer-group mechanics for regular peers. */
4715 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4719 * Remove flag and configuration from all peer-group members, unless
4720 * they are explicitely overriding peer-group configuration.
4722 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4723 /* Skip peers with overridden configuration. */
4724 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4728 /* Skip peers where flag is already disabled. */
4729 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4732 /* Remove flag and configuration on peer-group member. */
4733 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4734 member
->weight
[afi
][safi
] = 0;
4735 peer_on_policy_change(member
, afi
, safi
, 0);
4741 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4743 struct peer
*member
;
4744 struct listnode
*node
, *nnode
;
4746 if (keepalive
> 65535)
4747 return BGP_ERR_INVALID_VALUE
;
4749 if (holdtime
> 65535)
4750 return BGP_ERR_INVALID_VALUE
;
4752 if (holdtime
< 3 && holdtime
!= 0)
4753 return BGP_ERR_INVALID_VALUE
;
4755 /* Set flag and configuration on peer. */
4756 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4757 peer
->holdtime
= holdtime
;
4758 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4760 /* Skip peer-group mechanics for regular peers. */
4761 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4765 * Set flag and configuration on all peer-group members, unless they are
4766 * explicitely overriding peer-group configuration.
4768 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4769 /* Skip peers with overridden configuration. */
4770 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4773 /* Set flag and configuration on peer-group member. */
4774 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4775 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4776 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4782 int peer_timers_unset(struct peer
*peer
)
4784 struct peer
*member
;
4785 struct listnode
*node
, *nnode
;
4787 /* Inherit configuration from peer-group if peer is member. */
4788 if (peer_group_active(peer
)) {
4789 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4790 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4791 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4793 /* Otherwise remove flag and configuration from peer. */
4794 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4796 peer
->keepalive
= 0;
4799 /* Skip peer-group mechanics for regular peers. */
4800 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4804 * Remove flag and configuration from all peer-group members, unless
4805 * they are explicitely overriding peer-group configuration.
4807 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4808 /* Skip peers with overridden configuration. */
4809 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4812 /* Remove flag and configuration on peer-group member. */
4813 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4814 member
->holdtime
= 0;
4815 member
->keepalive
= 0;
4821 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4823 struct peer
*member
;
4824 struct listnode
*node
, *nnode
;
4826 if (connect
> 65535)
4827 return BGP_ERR_INVALID_VALUE
;
4829 /* Set flag and configuration on peer. */
4830 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4831 peer
->connect
= connect
;
4832 peer
->v_connect
= connect
;
4834 /* Skip peer-group mechanics for regular peers. */
4835 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4839 * Set flag and configuration on all peer-group members, unless they are
4840 * explicitely overriding peer-group configuration.
4842 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4843 /* Skip peers with overridden configuration. */
4844 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4847 /* Set flag and configuration on peer-group member. */
4848 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4849 member
->connect
= connect
;
4850 member
->v_connect
= connect
;
4856 int peer_timers_connect_unset(struct peer
*peer
)
4858 struct peer
*member
;
4859 struct listnode
*node
, *nnode
;
4861 /* Inherit configuration from peer-group if peer is member. */
4862 if (peer_group_active(peer
)) {
4863 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4864 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4866 /* Otherwise remove flag and configuration from peer. */
4867 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4871 /* Set timer with fallback to default value. */
4873 peer
->v_connect
= peer
->connect
;
4875 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4877 /* Skip peer-group mechanics for regular peers. */
4878 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4882 * Remove flag and configuration from all peer-group members, unless
4883 * they are explicitely overriding peer-group configuration.
4885 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4886 /* Skip peers with overridden configuration. */
4887 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4890 /* Remove flag and configuration on peer-group member. */
4891 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4892 member
->connect
= 0;
4893 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4899 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4901 struct peer
*member
;
4902 struct listnode
*node
, *nnode
;
4905 return BGP_ERR_INVALID_VALUE
;
4907 /* Set flag and configuration on peer. */
4908 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4909 peer
->routeadv
= routeadv
;
4910 peer
->v_routeadv
= routeadv
;
4912 /* Check if handling a regular peer. */
4913 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4914 /* Update peer route announcements. */
4915 update_group_adjust_peer_afs(peer
);
4916 if (peer
->status
== Established
)
4917 bgp_announce_route_all(peer
);
4919 /* Skip peer-group mechanics for regular peers. */
4924 * Set flag and configuration on all peer-group members, unless they are
4925 * explicitely overriding peer-group configuration.
4927 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4928 /* Skip peers with overridden configuration. */
4929 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4932 /* Set flag and configuration on peer-group member. */
4933 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4934 member
->routeadv
= routeadv
;
4935 member
->v_routeadv
= routeadv
;
4937 /* Update peer route announcements. */
4938 update_group_adjust_peer_afs(member
);
4939 if (member
->status
== Established
)
4940 bgp_announce_route_all(member
);
4946 int peer_advertise_interval_unset(struct peer
*peer
)
4948 struct peer
*member
;
4949 struct listnode
*node
, *nnode
;
4951 /* Inherit configuration from peer-group if peer is member. */
4952 if (peer_group_active(peer
)) {
4953 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4954 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4956 /* Otherwise remove flag and configuration from peer. */
4957 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
4961 /* Set timer with fallback to default value. */
4963 peer
->v_routeadv
= peer
->routeadv
;
4965 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
4966 ? BGP_DEFAULT_IBGP_ROUTEADV
4967 : BGP_DEFAULT_EBGP_ROUTEADV
;
4969 /* Check if handling a regular peer. */
4970 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4971 /* Update peer route announcements. */
4972 update_group_adjust_peer_afs(peer
);
4973 if (peer
->status
== Established
)
4974 bgp_announce_route_all(peer
);
4976 /* Skip peer-group mechanics for regular peers. */
4981 * Remove flag and configuration from all peer-group members, unless
4982 * they are explicitely overriding peer-group configuration.
4984 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4985 /* Skip peers with overridden configuration. */
4986 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4989 /* Remove flag and configuration on peer-group member. */
4990 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4991 member
->routeadv
= 0;
4992 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
4993 ? BGP_DEFAULT_IBGP_ROUTEADV
4994 : BGP_DEFAULT_EBGP_ROUTEADV
;
4996 /* Update peer route announcements. */
4997 update_group_adjust_peer_afs(member
);
4998 if (member
->status
== Established
)
4999 bgp_announce_route_all(member
);
5005 /* neighbor interface */
5006 void peer_interface_set(struct peer
*peer
, const char *str
)
5009 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5010 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5013 void peer_interface_unset(struct peer
*peer
)
5016 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5017 peer
->ifname
= NULL
;
5021 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5022 int allow_num
, int origin
)
5024 struct peer
*member
;
5025 struct listnode
*node
, *nnode
;
5027 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5028 return BGP_ERR_INVALID_VALUE
;
5030 /* Set flag and configuration on peer. */
5031 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5033 if (peer
->allowas_in
[afi
][safi
] != 0
5034 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5035 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5036 peer_af_flag_set(peer
, afi
, safi
,
5037 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5038 peer
->allowas_in
[afi
][safi
] = 0;
5039 peer_on_policy_change(peer
, afi
, safi
, 0);
5042 if (peer
->allowas_in
[afi
][safi
] != allow_num
5043 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5044 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5046 peer_af_flag_unset(peer
, afi
, safi
,
5047 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5048 peer
->allowas_in
[afi
][safi
] = allow_num
;
5049 peer_on_policy_change(peer
, afi
, safi
, 0);
5053 /* Skip peer-group mechanics for regular peers. */
5054 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5058 * Set flag and configuration on all peer-group members, unless
5059 * they are explicitely overriding peer-group configuration.
5061 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5062 /* Skip peers with overridden configuration. */
5063 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5064 PEER_FLAG_ALLOWAS_IN
))
5067 /* Set flag and configuration on peer-group member. */
5068 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5070 if (member
->allowas_in
[afi
][safi
] != 0
5071 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5072 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5073 SET_FLAG(member
->af_flags
[afi
][safi
],
5074 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5075 member
->allowas_in
[afi
][safi
] = 0;
5076 peer_on_policy_change(peer
, afi
, safi
, 0);
5079 if (member
->allowas_in
[afi
][safi
] != allow_num
5080 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5081 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5082 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5083 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5084 member
->allowas_in
[afi
][safi
] = allow_num
;
5085 peer_on_policy_change(peer
, afi
, safi
, 0);
5093 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5095 struct peer
*member
;
5096 struct listnode
*node
, *nnode
;
5098 /* Skip peer if flag is already disabled. */
5099 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5102 /* Inherit configuration from peer-group if peer is member. */
5103 if (peer_group_active(peer
)) {
5104 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5105 peer_af_flag_inherit(peer
, afi
, safi
,
5106 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5107 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5108 peer_on_policy_change(peer
, afi
, safi
, 0);
5113 /* Remove flag and configuration from peer. */
5114 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5115 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5116 peer
->allowas_in
[afi
][safi
] = 0;
5117 peer_on_policy_change(peer
, afi
, safi
, 0);
5119 /* Skip peer-group mechanics if handling a regular peer. */
5120 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5124 * Remove flags and configuration from all peer-group members, unless
5125 * they are explicitely overriding peer-group configuration.
5127 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5128 /* Skip peers with overridden configuration. */
5129 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5130 PEER_FLAG_ALLOWAS_IN
))
5133 /* Skip peers where flag is already disabled. */
5134 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5135 PEER_FLAG_ALLOWAS_IN
))
5138 /* Remove flags and configuration on peer-group member. */
5139 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5140 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5141 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5142 member
->allowas_in
[afi
][safi
] = 0;
5143 peer_on_policy_change(member
, afi
, safi
, 0);
5149 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5152 bool old_no_prepend
, old_replace_as
;
5153 struct bgp
*bgp
= peer
->bgp
;
5154 struct peer
*member
;
5155 struct listnode
*node
, *nnode
;
5157 if (peer_sort(peer
) != BGP_PEER_EBGP
5158 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5159 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5162 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5165 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5167 /* Save previous flag states. */
5169 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5171 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5173 /* Set flag and configuration on peer. */
5174 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5175 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5176 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5178 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5179 && old_replace_as
== replace_as
)
5181 peer
->change_local_as
= as
;
5183 /* Check if handling a regular peer. */
5184 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5185 /* Send notification or reset peer depending on state. */
5186 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5187 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5188 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5189 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5191 bgp_session_reset(peer
);
5193 /* Skip peer-group mechanics for regular peers. */
5198 * Set flag and configuration on all peer-group members, unless they are
5199 * explicitely overriding peer-group configuration.
5201 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5202 /* Skip peers with overridden configuration. */
5203 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5206 /* Skip peers with the same configuration. */
5207 old_no_prepend
= CHECK_FLAG(member
->flags
,
5208 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5209 old_replace_as
= CHECK_FLAG(member
->flags
,
5210 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5211 if (member
->change_local_as
== as
5212 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5213 && old_no_prepend
== no_prepend
5214 && old_replace_as
== replace_as
)
5217 /* Set flag and configuration on peer-group member. */
5218 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5219 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5221 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5223 member
->change_local_as
= as
;
5225 /* Send notification or stop peer depending on state. */
5226 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5227 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5228 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5229 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5231 BGP_EVENT_ADD(member
, BGP_Stop
);
5237 int peer_local_as_unset(struct peer
*peer
)
5239 struct peer
*member
;
5240 struct listnode
*node
, *nnode
;
5242 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5245 /* Inherit configuration from peer-group if peer is member. */
5246 if (peer_group_active(peer
)) {
5247 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5248 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5249 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5250 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5252 /* Otherwise remove flag and configuration from peer. */
5253 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5254 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5255 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5256 peer
->change_local_as
= 0;
5259 /* Check if handling a regular peer. */
5260 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5261 /* Send notification or stop peer depending on state. */
5262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5263 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5265 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5267 BGP_EVENT_ADD(peer
, BGP_Stop
);
5269 /* Skip peer-group mechanics for regular peers. */
5274 * Remove flag and configuration from all peer-group members, unless
5275 * they are explicitely overriding peer-group configuration.
5277 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5278 /* Skip peers with overridden configuration. */
5279 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5282 /* Remove flag and configuration on peer-group member. */
5283 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5284 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5285 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5286 member
->change_local_as
= 0;
5288 /* Send notification or stop peer depending on state. */
5289 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5290 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5291 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5292 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5294 bgp_session_reset(member
);
5300 /* Set password for authenticating with the peer. */
5301 int peer_password_set(struct peer
*peer
, const char *password
)
5303 struct peer
*member
;
5304 struct listnode
*node
, *nnode
;
5305 int len
= password
? strlen(password
) : 0;
5306 int ret
= BGP_SUCCESS
;
5308 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5309 return BGP_ERR_INVALID_VALUE
;
5311 /* Set flag and configuration on peer. */
5312 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5313 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5315 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5316 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5318 /* Check if handling a regular peer. */
5319 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5320 /* Send notification or reset peer depending on state. */
5321 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5322 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5323 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5325 bgp_session_reset(peer
);
5328 * Attempt to install password on socket and skip peer-group
5331 if (BGP_PEER_SU_UNSPEC(peer
))
5333 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5334 : BGP_ERR_TCPSIG_FAILED
;
5338 * Set flag and configuration on all peer-group members, unless they are
5339 * explicitely overriding peer-group configuration.
5341 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5342 /* Skip peers with overridden configuration. */
5343 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5346 /* Skip peers with the same password. */
5347 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5350 /* Set flag and configuration on peer-group member. */
5351 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5352 if (member
->password
)
5353 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5354 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5356 /* Send notification or reset peer depending on state. */
5357 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5358 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5359 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5361 bgp_session_reset(member
);
5363 /* Attempt to install password on socket. */
5364 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5365 ret
= BGP_ERR_TCPSIG_FAILED
;
5371 int peer_password_unset(struct peer
*peer
)
5373 struct peer
*member
;
5374 struct listnode
*node
, *nnode
;
5376 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5379 /* Inherit configuration from peer-group if peer is member. */
5380 if (peer_group_active(peer
)) {
5381 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5382 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5383 MTYPE_PEER_PASSWORD
);
5385 /* Otherwise remove flag and configuration from peer. */
5386 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5387 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5390 /* Check if handling a regular peer. */
5391 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5392 /* Send notification or reset peer depending on state. */
5393 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5394 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5395 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5397 bgp_session_reset(peer
);
5399 /* Attempt to uninstall password on socket. */
5400 if (!BGP_PEER_SU_UNSPEC(peer
))
5401 bgp_md5_unset(peer
);
5403 /* Skip peer-group mechanics for regular peers. */
5408 * Remove flag and configuration from all peer-group members, unless
5409 * they are explicitely overriding peer-group configuration.
5411 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5412 /* Skip peers with overridden configuration. */
5413 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5416 /* Remove flag and configuration on peer-group member. */
5417 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5418 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5420 /* Send notification or reset peer depending on state. */
5421 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5422 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5423 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5425 bgp_session_reset(member
);
5427 /* Attempt to uninstall password on socket. */
5428 if (!BGP_PEER_SU_UNSPEC(member
))
5429 bgp_md5_unset(member
);
5436 /* Set distribute list to the peer. */
5437 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5440 struct peer
*member
;
5441 struct bgp_filter
*filter
;
5442 struct listnode
*node
, *nnode
;
5444 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5445 return BGP_ERR_INVALID_VALUE
;
5447 /* Set configuration on peer. */
5448 filter
= &peer
->filter
[afi
][safi
];
5449 if (filter
->plist
[direct
].name
)
5450 return BGP_ERR_PEER_FILTER_CONFLICT
;
5451 if (filter
->dlist
[direct
].name
)
5452 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5453 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5454 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5456 /* Check if handling a regular peer. */
5457 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5458 /* Set override-flag and process peer route updates. */
5459 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5460 PEER_FT_DISTRIBUTE_LIST
);
5461 peer_on_policy_change(peer
, afi
, safi
,
5462 (direct
== FILTER_OUT
) ? 1 : 0);
5464 /* Skip peer-group mechanics for regular peers. */
5469 * Set configuration on all peer-group members, un less they are
5470 * explicitely overriding peer-group configuration.
5472 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5473 /* Skip peers with overridden configuration. */
5474 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5475 PEER_FT_DISTRIBUTE_LIST
))
5478 /* Set configuration on peer-group member. */
5479 filter
= &member
->filter
[afi
][safi
];
5480 if (filter
->dlist
[direct
].name
)
5481 XFREE(MTYPE_BGP_FILTER_NAME
,
5482 filter
->dlist
[direct
].name
);
5483 filter
->dlist
[direct
].name
=
5484 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5485 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5487 /* Process peer route updates. */
5488 peer_on_policy_change(member
, afi
, safi
,
5489 (direct
== FILTER_OUT
) ? 1 : 0);
5495 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5497 struct peer
*member
;
5498 struct bgp_filter
*filter
;
5499 struct listnode
*node
, *nnode
;
5501 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5502 return BGP_ERR_INVALID_VALUE
;
5504 /* Unset override-flag unconditionally. */
5505 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5506 PEER_FT_DISTRIBUTE_LIST
);
5508 /* Inherit configuration from peer-group if peer is member. */
5509 if (peer_group_active(peer
)) {
5510 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5511 filter
[afi
][safi
].dlist
[direct
].name
,
5512 MTYPE_BGP_FILTER_NAME
);
5513 PEER_ATTR_INHERIT(peer
, peer
->group
,
5514 filter
[afi
][safi
].dlist
[direct
].alist
);
5516 /* Otherwise remove configuration from peer. */
5517 filter
= &peer
->filter
[afi
][safi
];
5518 if (filter
->dlist
[direct
].name
)
5519 XFREE(MTYPE_BGP_FILTER_NAME
,
5520 filter
->dlist
[direct
].name
);
5521 filter
->dlist
[direct
].name
= NULL
;
5522 filter
->dlist
[direct
].alist
= NULL
;
5525 /* Check if handling a regular peer. */
5526 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5527 /* Process peer route updates. */
5528 peer_on_policy_change(peer
, afi
, safi
,
5529 (direct
== FILTER_OUT
) ? 1 : 0);
5531 /* Skip peer-group mechanics for regular peers. */
5536 * Remove configuration on all peer-group members, unless they are
5537 * explicitely overriding peer-group configuration.
5539 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5540 /* Skip peers with overridden configuration. */
5541 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5542 PEER_FT_DISTRIBUTE_LIST
))
5545 /* Remove configuration on peer-group member. */
5546 filter
= &member
->filter
[afi
][safi
];
5547 if (filter
->dlist
[direct
].name
)
5548 XFREE(MTYPE_BGP_FILTER_NAME
,
5549 filter
->dlist
[direct
].name
);
5550 filter
->dlist
[direct
].name
= NULL
;
5551 filter
->dlist
[direct
].alist
= NULL
;
5553 /* Process peer route updates. */
5554 peer_on_policy_change(member
, afi
, safi
,
5555 (direct
== FILTER_OUT
) ? 1 : 0);
5561 /* Update distribute list. */
5562 static void peer_distribute_update(struct access_list
*access
)
5567 struct listnode
*mnode
, *mnnode
;
5568 struct listnode
*node
, *nnode
;
5571 struct peer_group
*group
;
5572 struct bgp_filter
*filter
;
5574 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5576 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5577 access
->name
, 0, 0);
5578 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5579 FOREACH_AFI_SAFI (afi
, safi
) {
5580 filter
= &peer
->filter
[afi
][safi
];
5582 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5584 if (filter
->dlist
[direct
].name
)
5585 filter
->dlist
[direct
]
5586 .alist
= access_list_lookup(
5588 filter
->dlist
[direct
]
5591 filter
->dlist
[direct
].alist
=
5596 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5597 FOREACH_AFI_SAFI (afi
, safi
) {
5598 filter
= &group
->conf
->filter
[afi
][safi
];
5600 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5602 if (filter
->dlist
[direct
].name
)
5603 filter
->dlist
[direct
]
5604 .alist
= access_list_lookup(
5606 filter
->dlist
[direct
]
5609 filter
->dlist
[direct
].alist
=
5615 vnc_prefix_list_update(bgp
);
5620 /* Set prefix list to the peer. */
5621 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5624 struct peer
*member
;
5625 struct bgp_filter
*filter
;
5626 struct listnode
*node
, *nnode
;
5628 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5629 return BGP_ERR_INVALID_VALUE
;
5631 /* Set configuration on peer. */
5632 filter
= &peer
->filter
[afi
][safi
];
5633 if (filter
->dlist
[direct
].name
)
5634 return BGP_ERR_PEER_FILTER_CONFLICT
;
5635 if (filter
->plist
[direct
].name
)
5636 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5637 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5638 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5640 /* Check if handling a regular peer. */
5641 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5642 /* Set override-flag and process peer route updates. */
5643 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5644 PEER_FT_PREFIX_LIST
);
5645 peer_on_policy_change(peer
, afi
, safi
,
5646 (direct
== FILTER_OUT
) ? 1 : 0);
5648 /* Skip peer-group mechanics for regular peers. */
5653 * Set configuration on all peer-group members, unless they are
5654 * explicitely overriding peer-group configuration.
5656 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5657 /* Skip peers with overridden configuration. */
5658 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5659 PEER_FT_PREFIX_LIST
))
5662 /* Set configuration on peer-group member. */
5663 filter
= &member
->filter
[afi
][safi
];
5664 if (filter
->plist
[direct
].name
)
5665 XFREE(MTYPE_BGP_FILTER_NAME
,
5666 filter
->plist
[direct
].name
);
5667 filter
->plist
[direct
].name
=
5668 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5669 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5671 /* Process peer route updates. */
5672 peer_on_policy_change(member
, afi
, safi
,
5673 (direct
== FILTER_OUT
) ? 1 : 0);
5679 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5682 struct peer
*member
;
5683 struct bgp_filter
*filter
;
5684 struct listnode
*node
, *nnode
;
5686 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5687 return BGP_ERR_INVALID_VALUE
;
5689 /* Unset override-flag unconditionally. */
5690 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5691 PEER_FT_PREFIX_LIST
);
5693 /* Inherit configuration from peer-group if peer is member. */
5694 if (peer_group_active(peer
)) {
5695 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5696 filter
[afi
][safi
].plist
[direct
].name
,
5697 MTYPE_BGP_FILTER_NAME
);
5698 PEER_ATTR_INHERIT(peer
, peer
->group
,
5699 filter
[afi
][safi
].plist
[direct
].plist
);
5701 /* Otherwise remove configuration from peer. */
5702 filter
= &peer
->filter
[afi
][safi
];
5703 if (filter
->plist
[direct
].name
)
5704 XFREE(MTYPE_BGP_FILTER_NAME
,
5705 filter
->plist
[direct
].name
);
5706 filter
->plist
[direct
].name
= NULL
;
5707 filter
->plist
[direct
].plist
= NULL
;
5710 /* Check if handling a regular peer. */
5711 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5712 /* Process peer route updates. */
5713 peer_on_policy_change(peer
, afi
, safi
,
5714 (direct
== FILTER_OUT
) ? 1 : 0);
5716 /* Skip peer-group mechanics for regular peers. */
5721 * Remove configuration on all peer-group members, unless they are
5722 * explicitely overriding peer-group configuration.
5724 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5725 /* Skip peers with overridden configuration. */
5726 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5727 PEER_FT_PREFIX_LIST
))
5730 /* Remove configuration on peer-group member. */
5731 filter
= &member
->filter
[afi
][safi
];
5732 if (filter
->plist
[direct
].name
)
5733 XFREE(MTYPE_BGP_FILTER_NAME
,
5734 filter
->plist
[direct
].name
);
5735 filter
->plist
[direct
].name
= NULL
;
5736 filter
->plist
[direct
].plist
= NULL
;
5738 /* Process peer route updates. */
5739 peer_on_policy_change(member
, afi
, safi
,
5740 (direct
== FILTER_OUT
) ? 1 : 0);
5746 /* Update prefix-list list. */
5747 static void peer_prefix_list_update(struct prefix_list
*plist
)
5749 struct listnode
*mnode
, *mnnode
;
5750 struct listnode
*node
, *nnode
;
5753 struct peer_group
*group
;
5754 struct bgp_filter
*filter
;
5759 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5762 * Update the prefix-list on update groups.
5764 update_group_policy_update(
5765 bgp
, BGP_POLICY_PREFIX_LIST
,
5766 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5768 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5769 FOREACH_AFI_SAFI (afi
, safi
) {
5770 filter
= &peer
->filter
[afi
][safi
];
5772 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5774 if (filter
->plist
[direct
].name
)
5775 filter
->plist
[direct
]
5776 .plist
= prefix_list_lookup(
5778 filter
->plist
[direct
]
5781 filter
->plist
[direct
].plist
=
5786 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5787 FOREACH_AFI_SAFI (afi
, safi
) {
5788 filter
= &group
->conf
->filter
[afi
][safi
];
5790 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5792 if (filter
->plist
[direct
].name
)
5793 filter
->plist
[direct
]
5794 .plist
= prefix_list_lookup(
5796 filter
->plist
[direct
]
5799 filter
->plist
[direct
].plist
=
5807 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5810 struct peer
*member
;
5811 struct bgp_filter
*filter
;
5812 struct listnode
*node
, *nnode
;
5814 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5815 return BGP_ERR_INVALID_VALUE
;
5817 /* Set configuration on peer. */
5818 filter
= &peer
->filter
[afi
][safi
];
5819 if (filter
->aslist
[direct
].name
)
5820 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5821 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5822 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5824 /* Check if handling a regular peer. */
5825 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5826 /* Set override-flag and process peer route updates. */
5827 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5828 PEER_FT_FILTER_LIST
);
5829 peer_on_policy_change(peer
, afi
, safi
,
5830 (direct
== FILTER_OUT
) ? 1 : 0);
5832 /* Skip peer-group mechanics for regular peers. */
5837 * Set configuration on all peer-group members, unless they are
5838 * explicitely overriding peer-group configuration.
5840 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5841 /* Skip peers with overridden configuration. */
5842 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5843 PEER_FT_FILTER_LIST
))
5846 /* Set configuration on peer-group member. */
5847 filter
= &member
->filter
[afi
][safi
];
5848 if (filter
->aslist
[direct
].name
)
5849 XFREE(MTYPE_BGP_FILTER_NAME
,
5850 filter
->aslist
[direct
].name
);
5851 filter
->aslist
[direct
].name
=
5852 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5853 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5855 /* Process peer route updates. */
5856 peer_on_policy_change(member
, afi
, safi
,
5857 (direct
== FILTER_OUT
) ? 1 : 0);
5863 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5865 struct peer
*member
;
5866 struct bgp_filter
*filter
;
5867 struct listnode
*node
, *nnode
;
5869 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5870 return BGP_ERR_INVALID_VALUE
;
5872 /* Unset override-flag unconditionally. */
5873 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5874 PEER_FT_FILTER_LIST
);
5876 /* Inherit configuration from peer-group if peer is member. */
5877 if (peer_group_active(peer
)) {
5878 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5879 filter
[afi
][safi
].aslist
[direct
].name
,
5880 MTYPE_BGP_FILTER_NAME
);
5881 PEER_ATTR_INHERIT(peer
, peer
->group
,
5882 filter
[afi
][safi
].aslist
[direct
].aslist
);
5884 /* Otherwise remove configuration from peer. */
5885 filter
= &peer
->filter
[afi
][safi
];
5886 if (filter
->aslist
[direct
].name
)
5887 XFREE(MTYPE_BGP_FILTER_NAME
,
5888 filter
->aslist
[direct
].name
);
5889 filter
->aslist
[direct
].name
= NULL
;
5890 filter
->aslist
[direct
].aslist
= NULL
;
5893 /* Check if handling a regular peer. */
5894 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5895 /* Process peer route updates. */
5896 peer_on_policy_change(peer
, afi
, safi
,
5897 (direct
== FILTER_OUT
) ? 1 : 0);
5899 /* Skip peer-group mechanics for regular peers. */
5904 * Remove configuration on all peer-group members, unless they are
5905 * explicitely overriding peer-group configuration.
5907 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5908 /* Skip peers with overridden configuration. */
5909 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5910 PEER_FT_FILTER_LIST
))
5913 /* Remove configuration on peer-group member. */
5914 filter
= &member
->filter
[afi
][safi
];
5915 if (filter
->aslist
[direct
].name
)
5916 XFREE(MTYPE_BGP_FILTER_NAME
,
5917 filter
->aslist
[direct
].name
);
5918 filter
->aslist
[direct
].name
= NULL
;
5919 filter
->aslist
[direct
].aslist
= NULL
;
5921 /* Process peer route updates. */
5922 peer_on_policy_change(member
, afi
, safi
,
5923 (direct
== FILTER_OUT
) ? 1 : 0);
5929 static void peer_aslist_update(const char *aslist_name
)
5934 struct listnode
*mnode
, *mnnode
;
5935 struct listnode
*node
, *nnode
;
5938 struct peer_group
*group
;
5939 struct bgp_filter
*filter
;
5941 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5942 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5945 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5946 FOREACH_AFI_SAFI (afi
, safi
) {
5947 filter
= &peer
->filter
[afi
][safi
];
5949 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5951 if (filter
->aslist
[direct
].name
)
5952 filter
->aslist
[direct
]
5953 .aslist
= as_list_lookup(
5954 filter
->aslist
[direct
]
5957 filter
->aslist
[direct
].aslist
=
5962 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5963 FOREACH_AFI_SAFI (afi
, safi
) {
5964 filter
= &group
->conf
->filter
[afi
][safi
];
5966 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5968 if (filter
->aslist
[direct
].name
)
5969 filter
->aslist
[direct
]
5970 .aslist
= as_list_lookup(
5971 filter
->aslist
[direct
]
5974 filter
->aslist
[direct
].aslist
=
5982 static void peer_aslist_add(char *aslist_name
)
5984 peer_aslist_update(aslist_name
);
5985 route_map_notify_dependencies((char *)aslist_name
,
5986 RMAP_EVENT_ASLIST_ADDED
);
5989 static void peer_aslist_del(const char *aslist_name
)
5991 peer_aslist_update(aslist_name
);
5992 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5996 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5999 struct peer
*member
;
6000 struct bgp_filter
*filter
;
6001 struct listnode
*node
, *nnode
;
6003 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6004 return BGP_ERR_INVALID_VALUE
;
6006 /* Set configuration on peer. */
6007 filter
= &peer
->filter
[afi
][safi
];
6008 if (filter
->map
[direct
].name
)
6009 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6010 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6011 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
6013 /* Check if handling a regular peer. */
6014 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6015 /* Set override-flag and process peer route updates. */
6016 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6018 peer_on_policy_change(peer
, afi
, safi
,
6019 (direct
== RMAP_OUT
) ? 1 : 0);
6021 /* Skip peer-group mechanics for regular peers. */
6026 * Set configuration on all peer-group members, unless they are
6027 * explicitely overriding peer-group configuration.
6029 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6030 /* Skip peers with overridden configuration. */
6031 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6035 /* Set configuration on peer-group member. */
6036 filter
= &member
->filter
[afi
][safi
];
6037 if (filter
->map
[direct
].name
)
6038 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6039 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6040 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
6042 /* Process peer route updates. */
6043 peer_on_policy_change(member
, afi
, safi
,
6044 (direct
== RMAP_OUT
) ? 1 : 0);
6049 /* Unset route-map from the peer. */
6050 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6052 struct peer
*member
;
6053 struct bgp_filter
*filter
;
6054 struct listnode
*node
, *nnode
;
6056 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6057 return BGP_ERR_INVALID_VALUE
;
6059 /* Unset override-flag unconditionally. */
6060 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6062 /* Inherit configuration from peer-group if peer is member. */
6063 if (peer_group_active(peer
)) {
6064 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6065 filter
[afi
][safi
].map
[direct
].name
,
6066 MTYPE_BGP_FILTER_NAME
);
6067 PEER_ATTR_INHERIT(peer
, peer
->group
,
6068 filter
[afi
][safi
].map
[direct
].map
);
6070 /* Otherwise remove configuration from peer. */
6071 filter
= &peer
->filter
[afi
][safi
];
6072 if (filter
->map
[direct
].name
)
6073 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6074 filter
->map
[direct
].name
= NULL
;
6075 filter
->map
[direct
].map
= NULL
;
6078 /* Check if handling a regular peer. */
6079 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6080 /* Process peer route updates. */
6081 peer_on_policy_change(peer
, afi
, safi
,
6082 (direct
== RMAP_OUT
) ? 1 : 0);
6084 /* Skip peer-group mechanics for regular peers. */
6089 * Remove configuration on all peer-group members, unless they are
6090 * explicitely overriding peer-group configuration.
6092 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6093 /* Skip peers with overridden configuration. */
6094 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6098 /* Remove configuration on peer-group member. */
6099 filter
= &member
->filter
[afi
][safi
];
6100 if (filter
->map
[direct
].name
)
6101 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6102 filter
->map
[direct
].name
= NULL
;
6103 filter
->map
[direct
].map
= NULL
;
6105 /* Process peer route updates. */
6106 peer_on_policy_change(member
, afi
, safi
,
6107 (direct
== RMAP_OUT
) ? 1 : 0);
6113 /* Set unsuppress-map to the peer. */
6114 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6117 struct peer
*member
;
6118 struct bgp_filter
*filter
;
6119 struct listnode
*node
, *nnode
;
6121 /* Set configuration on peer. */
6122 filter
= &peer
->filter
[afi
][safi
];
6123 if (filter
->usmap
.name
)
6124 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6125 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6126 filter
->usmap
.map
= route_map_lookup_by_name(name
);
6128 /* Check if handling a regular peer. */
6129 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6130 /* Set override-flag and process peer route updates. */
6131 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6132 PEER_FT_UNSUPPRESS_MAP
);
6133 peer_on_policy_change(peer
, afi
, safi
, 1);
6135 /* Skip peer-group mechanics for regular peers. */
6140 * Set configuration on all peer-group members, unless they are
6141 * explicitely overriding peer-group configuration.
6143 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6144 /* Skip peers with overridden configuration. */
6145 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6146 PEER_FT_UNSUPPRESS_MAP
))
6149 /* Set configuration on peer-group member. */
6150 filter
= &member
->filter
[afi
][safi
];
6151 if (filter
->usmap
.name
)
6152 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6153 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6154 filter
->usmap
.map
= route_map_lookup_by_name(name
);
6156 /* Process peer route updates. */
6157 peer_on_policy_change(member
, afi
, safi
, 1);
6163 /* Unset route-map from the peer. */
6164 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6166 struct peer
*member
;
6167 struct bgp_filter
*filter
;
6168 struct listnode
*node
, *nnode
;
6170 /* Unset override-flag unconditionally. */
6171 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6173 /* Inherit configuration from peer-group if peer is member. */
6174 if (peer_group_active(peer
)) {
6175 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6176 filter
[afi
][safi
].usmap
.name
,
6177 MTYPE_BGP_FILTER_NAME
);
6178 PEER_ATTR_INHERIT(peer
, peer
->group
,
6179 filter
[afi
][safi
].usmap
.map
);
6181 /* Otherwise remove configuration from peer. */
6182 filter
= &peer
->filter
[afi
][safi
];
6183 if (filter
->usmap
.name
)
6184 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6185 filter
->usmap
.name
= NULL
;
6186 filter
->usmap
.map
= NULL
;
6189 /* Check if handling a regular peer. */
6190 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6191 /* Process peer route updates. */
6192 peer_on_policy_change(peer
, afi
, safi
, 1);
6194 /* Skip peer-group mechanics for regular peers. */
6199 * Remove configuration on all peer-group members, unless they are
6200 * explicitely overriding peer-group configuration.
6202 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6203 /* Skip peers with overridden configuration. */
6204 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6205 PEER_FT_UNSUPPRESS_MAP
))
6208 /* Remove configuration on peer-group member. */
6209 filter
= &member
->filter
[afi
][safi
];
6210 if (filter
->usmap
.name
)
6211 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6212 filter
->usmap
.name
= NULL
;
6213 filter
->usmap
.map
= NULL
;
6215 /* Process peer route updates. */
6216 peer_on_policy_change(member
, afi
, safi
, 1);
6222 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6223 uint32_t max
, uint8_t threshold
, int warning
,
6226 struct peer
*member
;
6227 struct listnode
*node
, *nnode
;
6229 /* Set flags and configuration on peer. */
6230 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6232 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6234 peer_af_flag_unset(peer
, afi
, safi
,
6235 PEER_FLAG_MAX_PREFIX_WARNING
);
6237 peer
->pmax
[afi
][safi
] = max
;
6238 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6239 peer
->pmax_restart
[afi
][safi
] = restart
;
6241 /* Check if handling a regular peer. */
6242 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6243 /* Re-check if peer violates maximum-prefix. */
6244 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6245 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6247 /* Skip peer-group mechanics for regular peers. */
6252 * Set flags and configuration on all peer-group members, unless they
6253 * are explicitely overriding peer-group configuration.
6255 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6256 /* Skip peers with overridden configuration. */
6257 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6258 PEER_FLAG_MAX_PREFIX
))
6261 /* Set flag and configuration on peer-group member. */
6262 member
->pmax
[afi
][safi
] = max
;
6263 member
->pmax_threshold
[afi
][safi
] = threshold
;
6264 member
->pmax_restart
[afi
][safi
] = restart
;
6266 SET_FLAG(member
->af_flags
[afi
][safi
],
6267 PEER_FLAG_MAX_PREFIX_WARNING
);
6269 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6270 PEER_FLAG_MAX_PREFIX_WARNING
);
6272 /* Re-check if peer violates maximum-prefix. */
6273 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6274 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6280 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6282 struct peer
*member
;
6283 struct listnode
*node
, *nnode
;
6285 /* Inherit configuration from peer-group if peer is member. */
6286 if (peer_group_active(peer
)) {
6287 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6288 peer_af_flag_inherit(peer
, afi
, safi
,
6289 PEER_FLAG_MAX_PREFIX_WARNING
);
6290 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6291 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6292 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6297 /* Remove flags and configuration from peer. */
6298 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6299 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6300 peer
->pmax
[afi
][safi
] = 0;
6301 peer
->pmax_threshold
[afi
][safi
] = 0;
6302 peer
->pmax_restart
[afi
][safi
] = 0;
6305 * Remove flags and configuration from all peer-group members, unless
6306 * they are explicitely overriding peer-group configuration.
6308 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6309 /* Skip peers with overridden configuration. */
6310 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6311 PEER_FLAG_MAX_PREFIX
))
6314 /* Remove flag and configuration on peer-group member. */
6315 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6316 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6317 PEER_FLAG_MAX_PREFIX_WARNING
);
6318 member
->pmax
[afi
][safi
] = 0;
6319 member
->pmax_threshold
[afi
][safi
] = 0;
6320 member
->pmax_restart
[afi
][safi
] = 0;
6326 int is_ebgp_multihop_configured(struct peer
*peer
)
6328 struct peer_group
*group
;
6329 struct listnode
*node
, *nnode
;
6332 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6333 group
= peer
->group
;
6334 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6335 && (group
->conf
->ttl
!= 1))
6338 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6339 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6340 && (peer1
->ttl
!= 1))
6344 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6350 /* Set # of hops between us and BGP peer. */
6351 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6353 struct peer_group
*group
;
6354 struct listnode
*node
, *nnode
;
6357 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6358 gtsm_hops
, peer
->host
);
6360 /* We cannot configure ttl-security hops when ebgp-multihop is already
6361 set. For non peer-groups, the check is simple. For peer-groups,
6363 slightly messy, because we need to check both the peer-group
6365 and all peer-group members for any trace of ebgp-multihop
6367 before actually applying the ttl-security rules. Cisco really made a
6368 mess of this configuration parameter, and OpenBGPD got it right.
6371 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6372 if (is_ebgp_multihop_configured(peer
))
6373 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6375 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6376 peer
->gtsm_hops
= gtsm_hops
;
6378 /* Calling ebgp multihop also resets the session.
6379 * On restart, NHT will get setup correctly as will the
6380 * min & max ttls on the socket. The return value is
6383 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6388 group
= peer
->group
;
6389 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6391 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6393 /* Calling ebgp multihop also resets the
6395 * On restart, NHT will get setup correctly as
6397 * min & max ttls on the socket. The return
6401 peer_ebgp_multihop_set(peer
, MAXTTL
);
6405 /* Post the first gtsm setup or if its ibgp, maxttl setting
6407 * necessary, just set the minttl.
6409 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6410 peer
->gtsm_hops
= gtsm_hops
;
6413 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6414 MAXTTL
+ 1 - gtsm_hops
);
6415 if ((peer
->status
< Established
) && peer
->doppelganger
6416 && (peer
->doppelganger
->fd
>= 0))
6417 sockopt_minttl(peer
->su
.sa
.sa_family
,
6418 peer
->doppelganger
->fd
,
6419 MAXTTL
+ 1 - gtsm_hops
);
6421 group
= peer
->group
;
6422 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6424 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6426 /* Change setting of existing peer
6427 * established then change value (may break
6429 * not established yet (teardown session and
6431 * no session then do nothing (will get
6432 * handled by next connection)
6434 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6436 peer
->su
.sa
.sa_family
, peer
->fd
,
6437 MAXTTL
+ 1 - peer
->gtsm_hops
);
6438 if ((peer
->status
< Established
)
6439 && peer
->doppelganger
6440 && (peer
->doppelganger
->fd
>= 0))
6441 sockopt_minttl(peer
->su
.sa
.sa_family
,
6442 peer
->doppelganger
->fd
,
6443 MAXTTL
+ 1 - gtsm_hops
);
6451 int peer_ttl_security_hops_unset(struct peer
*peer
)
6453 struct peer_group
*group
;
6454 struct listnode
*node
, *nnode
;
6457 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6460 /* if a peer-group member, then reset to peer-group default rather than
6462 if (peer_group_active(peer
))
6463 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6465 peer
->gtsm_hops
= 0;
6467 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6468 /* Invoking ebgp_multihop_set will set the TTL back to the
6470 * value as well as restting the NHT and such. The session is
6473 if (peer
->sort
== BGP_PEER_EBGP
)
6474 ret
= peer_ebgp_multihop_unset(peer
);
6477 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6480 if ((peer
->status
< Established
) && peer
->doppelganger
6481 && (peer
->doppelganger
->fd
>= 0))
6482 sockopt_minttl(peer
->su
.sa
.sa_family
,
6483 peer
->doppelganger
->fd
, 0);
6486 group
= peer
->group
;
6487 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6488 peer
->gtsm_hops
= 0;
6489 if (peer
->sort
== BGP_PEER_EBGP
)
6490 ret
= peer_ebgp_multihop_unset(peer
);
6493 sockopt_minttl(peer
->su
.sa
.sa_family
,
6496 if ((peer
->status
< Established
)
6497 && peer
->doppelganger
6498 && (peer
->doppelganger
->fd
>= 0))
6499 sockopt_minttl(peer
->su
.sa
.sa_family
,
6500 peer
->doppelganger
->fd
,
6510 * If peer clear is invoked in a loop for all peers on the BGP instance,
6511 * it may end up freeing the doppelganger, and if this was the next node
6512 * to the current node, we would end up accessing the freed next node.
6513 * Pass along additional parameter which can be updated if next node
6514 * is freed; only required when walking the peer list on BGP instance.
6516 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6518 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6519 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6520 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6521 if (peer
->t_pmax_restart
) {
6522 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6523 if (bgp_debug_neighbor_events(peer
))
6525 "%s Maximum-prefix restart timer canceled",
6528 BGP_EVENT_ADD(peer
, BGP_Start
);
6532 peer
->v_start
= BGP_INIT_START_TIMER
;
6533 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6534 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6535 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6537 bgp_session_reset_safe(peer
, nnode
);
6542 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6543 enum bgp_clear_type stype
)
6545 struct peer_af
*paf
;
6547 if (peer
->status
!= Established
)
6550 if (!peer
->afc
[afi
][safi
])
6551 return BGP_ERR_AF_UNCONFIGURED
;
6553 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6555 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6556 /* Clear the "neighbor x.x.x.x default-originate" flag */
6557 paf
= peer_af_find(peer
, afi
, safi
);
6558 if (paf
&& paf
->subgroup
6559 && CHECK_FLAG(paf
->subgroup
->sflags
,
6560 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6561 UNSET_FLAG(paf
->subgroup
->sflags
,
6562 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6564 bgp_announce_route(peer
, afi
, safi
);
6567 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6568 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6569 PEER_CAP_ORF_PREFIX_SM_ADV
)
6570 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6571 PEER_CAP_ORF_PREFIX_RM_RCV
)
6572 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6573 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6574 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6575 uint8_t prefix_type
;
6577 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6578 PEER_CAP_ORF_PREFIX_RM_RCV
))
6579 prefix_type
= ORF_TYPE_PREFIX
;
6581 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6583 if (filter
->plist
[FILTER_IN
].plist
) {
6584 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6585 PEER_STATUS_ORF_PREFIX_SEND
))
6586 bgp_route_refresh_send(
6587 peer
, afi
, safi
, prefix_type
,
6589 bgp_route_refresh_send(peer
, afi
, safi
,
6591 REFRESH_IMMEDIATE
, 0);
6593 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6594 PEER_STATUS_ORF_PREFIX_SEND
))
6595 bgp_route_refresh_send(
6596 peer
, afi
, safi
, prefix_type
,
6597 REFRESH_IMMEDIATE
, 1);
6599 bgp_route_refresh_send(peer
, afi
, safi
,
6606 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6607 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6608 /* If neighbor has soft reconfiguration inbound flag.
6609 Use Adj-RIB-In database. */
6610 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6611 PEER_FLAG_SOFT_RECONFIG
))
6612 bgp_soft_reconfig_in(peer
, afi
, safi
);
6614 /* If neighbor has route refresh capability, send route
6616 message to the peer. */
6617 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6618 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6619 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6622 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6628 /* Display peer uptime.*/
6629 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, uint8_t use_json
,
6632 time_t uptime1
, epoch_tbuf
;
6635 /* If there is no connection has been done before print `never'. */
6638 json_object_string_add(json
, "peerUptime", "never");
6639 json_object_int_add(json
, "peerUptimeMsec", 0);
6641 snprintf(buf
, len
, "never");
6645 /* Get current time. */
6646 uptime1
= bgp_clock();
6648 tm
= gmtime(&uptime1
);
6650 if (uptime1
< ONE_DAY_SECOND
)
6651 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6653 else if (uptime1
< ONE_WEEK_SECOND
)
6654 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6656 else if (uptime1
< ONE_YEAR_SECOND
)
6657 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6658 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6660 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6662 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6665 epoch_tbuf
= time(NULL
) - uptime1
;
6666 json_object_string_add(json
, "peerUptime", buf
);
6667 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6668 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6675 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6676 afi_t afi
, safi_t safi
)
6678 struct bgp_filter
*filter
;
6682 filter
= &peer
->filter
[afi
][safi
];
6684 /* distribute-list. */
6685 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6687 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6688 filter
->dlist
[FILTER_IN
].name
);
6690 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6692 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6693 filter
->dlist
[FILTER_OUT
].name
);
6696 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6698 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6699 filter
->plist
[FILTER_IN
].name
);
6701 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6703 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6704 filter
->plist
[FILTER_OUT
].name
);
6707 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6708 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6709 filter
->map
[RMAP_IN
].name
);
6711 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6713 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6714 filter
->map
[RMAP_OUT
].name
);
6716 /* unsuppress-map */
6717 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6718 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6719 filter
->usmap
.name
);
6722 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6724 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6725 filter
->aslist
[FILTER_IN
].name
);
6727 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6729 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6730 filter
->aslist
[FILTER_OUT
].name
);
6733 /* BGP peer configuration display function. */
6734 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6737 struct peer
*g_peer
= NULL
;
6738 char buf
[SU_ADDRSTRLEN
];
6740 int if_pg_printed
= FALSE
;
6741 int if_ras_printed
= FALSE
;
6743 /* Skip dynamic neighbors. */
6744 if (peer_dynamic_neighbor(peer
))
6748 addr
= peer
->conf_if
;
6752 /************************************
6753 ****** Global to the neighbor ******
6754 ************************************/
6755 if (peer
->conf_if
) {
6756 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6757 vty_out(vty
, " neighbor %s interface v6only", addr
);
6759 vty_out(vty
, " neighbor %s interface", addr
);
6761 if (peer_group_active(peer
)) {
6762 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6763 if_pg_printed
= TRUE
;
6764 } else if (peer
->as_type
== AS_SPECIFIED
) {
6765 vty_out(vty
, " remote-as %u", peer
->as
);
6766 if_ras_printed
= TRUE
;
6767 } else if (peer
->as_type
== AS_INTERNAL
) {
6768 vty_out(vty
, " remote-as internal");
6769 if_ras_printed
= TRUE
;
6770 } else if (peer
->as_type
== AS_EXTERNAL
) {
6771 vty_out(vty
, " remote-as external");
6772 if_ras_printed
= TRUE
;
6778 /* remote-as and peer-group */
6779 /* peer is a member of a peer-group */
6780 if (peer_group_active(peer
)) {
6781 g_peer
= peer
->group
->conf
;
6783 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6784 if (peer
->as_type
== AS_SPECIFIED
) {
6785 vty_out(vty
, " neighbor %s remote-as %u\n",
6787 } else if (peer
->as_type
== AS_INTERNAL
) {
6789 " neighbor %s remote-as internal\n",
6791 } else if (peer
->as_type
== AS_EXTERNAL
) {
6793 " neighbor %s remote-as external\n",
6798 /* For swpX peers we displayed the peer-group
6799 * via 'neighbor swpX interface peer-group WORD' */
6801 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6805 /* peer is NOT a member of a peer-group */
6807 /* peer is a peer-group, declare the peer-group */
6808 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6809 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6812 if (!if_ras_printed
) {
6813 if (peer
->as_type
== AS_SPECIFIED
) {
6814 vty_out(vty
, " neighbor %s remote-as %u\n",
6816 } else if (peer
->as_type
== AS_INTERNAL
) {
6818 " neighbor %s remote-as internal\n",
6820 } else if (peer
->as_type
== AS_EXTERNAL
) {
6822 " neighbor %s remote-as external\n",
6829 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6830 vty_out(vty
, " neighbor %s local-as %u", addr
,
6831 peer
->change_local_as
);
6832 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6833 vty_out(vty
, " no-prepend");
6834 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6835 vty_out(vty
, " replace-as");
6841 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6845 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6846 if (peer
->tx_shutdown_message
)
6847 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6848 peer
->tx_shutdown_message
);
6850 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6854 if (peer
->bfd_info
) {
6855 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6856 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6861 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6862 vty_out(vty
, " neighbor %s password %s\n", addr
,
6866 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6867 if (!peer_group_active(peer
)) {
6868 vty_out(vty
, " neighbor %s solo\n", addr
);
6873 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6874 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6877 /* Local interface name */
6879 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6883 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6884 vty_out(vty
, " neighbor %s passive\n", addr
);
6887 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6888 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6889 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6890 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6895 /* ttl-security hops */
6896 if (peer
->gtsm_hops
!= 0) {
6897 if (!peer_group_active(peer
)
6898 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6899 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6900 addr
, peer
->gtsm_hops
);
6904 /* disable-connected-check */
6905 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6906 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6908 /* enforce-first-as */
6909 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6910 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6913 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6914 if (peer
->update_source
)
6915 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6916 sockunion2str(peer
->update_source
, buf
,
6918 else if (peer
->update_if
)
6919 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6923 /* advertisement-interval */
6924 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6925 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6929 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6930 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6931 peer
->keepalive
, peer
->holdtime
);
6933 /* timers connect */
6934 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6935 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6938 /* capability dynamic */
6939 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6940 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6942 /* capability extended-nexthop */
6943 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6944 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6946 " no neighbor %s capability extended-nexthop\n",
6950 " neighbor %s capability extended-nexthop\n",
6954 /* dont-capability-negotiation */
6955 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
6956 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
6958 /* override-capability */
6959 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
6960 vty_out(vty
, " neighbor %s override-capability\n", addr
);
6962 /* strict-capability-match */
6963 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
6964 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
6967 /* BGP peer configuration display function. */
6968 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6969 struct peer
*peer
, afi_t afi
, safi_t safi
)
6971 struct peer
*g_peer
= NULL
;
6973 bool flag_scomm
, flag_secomm
, flag_slcomm
;
6975 /* Skip dynamic neighbors. */
6976 if (peer_dynamic_neighbor(peer
))
6980 addr
= peer
->conf_if
;
6984 /************************************
6985 ****** Per AF to the neighbor ******
6986 ************************************/
6987 if (peer_group_active(peer
)) {
6988 g_peer
= peer
->group
->conf
;
6990 /* If the peer-group is active but peer is not, print a 'no
6992 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6993 vty_out(vty
, " no neighbor %s activate\n", addr
);
6996 /* If the peer-group is not active but peer is, print an
6998 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6999 vty_out(vty
, " neighbor %s activate\n", addr
);
7002 if (peer
->afc
[afi
][safi
]) {
7003 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7004 if (bgp_flag_check(bgp
,
7005 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7006 vty_out(vty
, " neighbor %s activate\n",
7010 vty_out(vty
, " neighbor %s activate\n", addr
);
7012 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7013 if (!bgp_flag_check(bgp
,
7014 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7016 " no neighbor %s activate\n",
7023 /* addpath TX knobs */
7024 if (peergroup_af_flag_check(peer
, afi
, safi
,
7025 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
7026 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
7029 if (peergroup_af_flag_check(peer
, afi
, safi
,
7030 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
7031 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
7035 /* ORF capability. */
7036 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7037 || peergroup_af_flag_check(peer
, afi
, safi
,
7038 PEER_FLAG_ORF_PREFIX_RM
)) {
7039 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7041 if (peergroup_af_flag_check(peer
, afi
, safi
,
7042 PEER_FLAG_ORF_PREFIX_SM
)
7043 && peergroup_af_flag_check(peer
, afi
, safi
,
7044 PEER_FLAG_ORF_PREFIX_RM
))
7045 vty_out(vty
, " both");
7046 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7047 PEER_FLAG_ORF_PREFIX_SM
))
7048 vty_out(vty
, " send");
7050 vty_out(vty
, " receive");
7054 /* Route reflector client. */
7055 if (peergroup_af_flag_check(peer
, afi
, safi
,
7056 PEER_FLAG_REFLECTOR_CLIENT
)) {
7057 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7060 /* next-hop-self force */
7061 if (peergroup_af_flag_check(peer
, afi
, safi
,
7062 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7063 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7067 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7068 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7071 /* remove-private-AS */
7072 if (peergroup_af_flag_check(peer
, afi
, safi
,
7073 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7074 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7078 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7079 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7080 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7084 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7085 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7086 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7089 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7090 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7091 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7095 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7096 vty_out(vty
, " neighbor %s as-override\n", addr
);
7099 /* send-community print. */
7100 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7101 PEER_FLAG_SEND_COMMUNITY
);
7102 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7103 PEER_FLAG_SEND_EXT_COMMUNITY
);
7104 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7105 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7107 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7108 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7109 vty_out(vty
, " no neighbor %s send-community all\n",
7114 " no neighbor %s send-community\n",
7118 " no neighbor %s send-community extended\n",
7123 " no neighbor %s send-community large\n",
7127 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7128 vty_out(vty
, " neighbor %s send-community all\n",
7130 } else if (flag_scomm
&& flag_secomm
) {
7131 vty_out(vty
, " neighbor %s send-community both\n",
7135 vty_out(vty
, " neighbor %s send-community\n",
7139 " neighbor %s send-community extended\n",
7143 " neighbor %s send-community large\n",
7148 /* Default information */
7149 if (peergroup_af_flag_check(peer
, afi
, safi
,
7150 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7151 vty_out(vty
, " neighbor %s default-originate", addr
);
7153 if (peer
->default_rmap
[afi
][safi
].name
)
7154 vty_out(vty
, " route-map %s",
7155 peer
->default_rmap
[afi
][safi
].name
);
7160 /* Soft reconfiguration inbound. */
7161 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7162 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7166 /* maximum-prefix. */
7167 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7168 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7169 peer
->pmax
[afi
][safi
]);
7171 if (peer
->pmax_threshold
[afi
][safi
]
7172 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7173 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7174 if (peer_af_flag_check(peer
, afi
, safi
,
7175 PEER_FLAG_MAX_PREFIX_WARNING
))
7176 vty_out(vty
, " warning-only");
7177 if (peer
->pmax_restart
[afi
][safi
])
7178 vty_out(vty
, " restart %u",
7179 peer
->pmax_restart
[afi
][safi
]);
7184 /* Route server client. */
7185 if (peergroup_af_flag_check(peer
, afi
, safi
,
7186 PEER_FLAG_RSERVER_CLIENT
)) {
7187 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7190 /* Nexthop-local unchanged. */
7191 if (peergroup_af_flag_check(peer
, afi
, safi
,
7192 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7193 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7196 /* allowas-in <1-10> */
7197 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7198 if (peer_af_flag_check(peer
, afi
, safi
,
7199 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7200 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7201 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7202 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7204 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7205 peer
->allowas_in
[afi
][safi
]);
7210 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7211 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7212 peer
->weight
[afi
][safi
]);
7215 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7217 /* atribute-unchanged. */
7218 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7219 || (safi
!= SAFI_EVPN
7220 && peer_af_flag_check(peer
, afi
, safi
,
7221 PEER_FLAG_NEXTHOP_UNCHANGED
))
7222 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7224 if (!peer_group_active(peer
)
7225 || peergroup_af_flag_check(peer
, afi
, safi
,
7226 PEER_FLAG_AS_PATH_UNCHANGED
)
7227 || peergroup_af_flag_check(peer
, afi
, safi
,
7228 PEER_FLAG_NEXTHOP_UNCHANGED
)
7229 || peergroup_af_flag_check(peer
, afi
, safi
,
7230 PEER_FLAG_MED_UNCHANGED
)) {
7233 " neighbor %s attribute-unchanged%s%s%s\n",
7235 peer_af_flag_check(peer
, afi
, safi
,
7236 PEER_FLAG_AS_PATH_UNCHANGED
)
7239 peer_af_flag_check(peer
, afi
, safi
,
7240 PEER_FLAG_NEXTHOP_UNCHANGED
)
7243 peer_af_flag_check(peer
, afi
, safi
,
7244 PEER_FLAG_MED_UNCHANGED
)
7251 /* Address family based peer configuration display. */
7252 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7256 struct peer_group
*group
;
7257 struct listnode
*node
, *nnode
;
7260 vty_frame(vty
, " !\n address-family ");
7261 if (afi
== AFI_IP
) {
7262 if (safi
== SAFI_UNICAST
)
7263 vty_frame(vty
, "ipv4 unicast");
7264 else if (safi
== SAFI_LABELED_UNICAST
)
7265 vty_frame(vty
, "ipv4 labeled-unicast");
7266 else if (safi
== SAFI_MULTICAST
)
7267 vty_frame(vty
, "ipv4 multicast");
7268 else if (safi
== SAFI_MPLS_VPN
)
7269 vty_frame(vty
, "ipv4 vpn");
7270 else if (safi
== SAFI_ENCAP
)
7271 vty_frame(vty
, "ipv4 encap");
7272 else if (safi
== SAFI_FLOWSPEC
)
7273 vty_frame(vty
, "ipv4 flowspec");
7274 } else if (afi
== AFI_IP6
) {
7275 if (safi
== SAFI_UNICAST
)
7276 vty_frame(vty
, "ipv6 unicast");
7277 else if (safi
== SAFI_LABELED_UNICAST
)
7278 vty_frame(vty
, "ipv6 labeled-unicast");
7279 else if (safi
== SAFI_MULTICAST
)
7280 vty_frame(vty
, "ipv6 multicast");
7281 else if (safi
== SAFI_MPLS_VPN
)
7282 vty_frame(vty
, "ipv6 vpn");
7283 else if (safi
== SAFI_ENCAP
)
7284 vty_frame(vty
, "ipv6 encap");
7285 else if (safi
== SAFI_FLOWSPEC
)
7286 vty_frame(vty
, "ipv6 flowspec");
7287 } else if (afi
== AFI_L2VPN
) {
7288 if (safi
== SAFI_EVPN
)
7289 vty_frame(vty
, "l2vpn evpn");
7291 vty_frame(vty
, "\n");
7293 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7295 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7297 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7299 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7300 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7302 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7303 /* Skip dynamic neighbors. */
7304 if (peer_dynamic_neighbor(peer
))
7307 /* Do not display doppelganger peers */
7308 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7309 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7312 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7313 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7315 if (safi
== SAFI_EVPN
)
7316 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7318 if (safi
== SAFI_FLOWSPEC
)
7319 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7321 if (safi
== SAFI_UNICAST
) {
7322 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7323 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7324 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7326 vty_out(vty
, " export vpn\n");
7328 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7329 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7331 vty_out(vty
, " import vpn\n");
7333 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7334 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7335 struct listnode
*node
;
7338 for (ALL_LIST_ELEMENTS_RO(
7339 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7341 vty_out(vty
, " import vrf %s\n", name
);
7345 vty_endframe(vty
, " exit-address-family\n");
7348 /* clang-format off */
7349 #if CONFDATE > 20190517
7350 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7352 /* clang-format on */
7354 int bgp_config_write(struct vty
*vty
)
7358 struct peer_group
*group
;
7360 struct listnode
*node
, *nnode
;
7361 struct listnode
*mnode
, *mnnode
;
7363 /* BGP Multiple instance. */
7364 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7365 vty_out(vty
, "no bgp multiple-instance\n");
7369 /* BGP Config type. */
7370 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7371 vty_out(vty
, "bgp config-type cisco\n");
7375 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7376 vty_out(vty
, "bgp route-map delay-timer %u\n",
7377 bm
->rmap_update_timer
);
7380 vty_out(vty
, "!\n");
7382 /* BGP configuration. */
7383 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7385 /* skip all auto created vrf as they dont have user config */
7386 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7389 /* Migrate deprecated 'bgp enforce-first-as'
7390 * config to 'neighbor * enforce-first-as' configs
7392 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7393 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7394 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7395 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7398 /* Router bgp ASN */
7399 vty_out(vty
, "router bgp %u", bgp
->as
);
7401 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7403 vty_out(vty
, " %s %s",
7405 == BGP_INSTANCE_TYPE_VIEW
)
7412 /* No Synchronization */
7413 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7414 vty_out(vty
, " no synchronization\n");
7416 /* BGP fast-external-failover. */
7417 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7418 vty_out(vty
, " no bgp fast-external-failover\n");
7420 /* BGP router ID. */
7421 if (bgp
->router_id_static
.s_addr
!= 0)
7422 vty_out(vty
, " bgp router-id %s\n",
7423 inet_ntoa(bgp
->router_id_static
));
7425 /* BGP log-neighbor-changes. */
7426 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7427 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7428 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7430 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7434 /* BGP configuration. */
7435 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7436 vty_out(vty
, " bgp always-compare-med\n");
7438 /* BGP default ipv4-unicast. */
7439 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7440 vty_out(vty
, " no bgp default ipv4-unicast\n");
7442 /* BGP default local-preference. */
7443 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7444 vty_out(vty
, " bgp default local-preference %u\n",
7445 bgp
->default_local_pref
);
7447 /* BGP default show-hostname */
7448 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7449 != DFLT_BGP_SHOW_HOSTNAME
)
7450 vty_out(vty
, " %sbgp default show-hostname\n",
7451 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7455 /* BGP default subgroup-pkt-queue-max. */
7456 if (bgp
->default_subgroup_pkt_queue_max
7457 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7458 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7459 bgp
->default_subgroup_pkt_queue_max
);
7461 /* BGP client-to-client reflection. */
7462 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7463 vty_out(vty
, " no bgp client-to-client reflection\n");
7465 /* BGP cluster ID. */
7466 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7467 vty_out(vty
, " bgp cluster-id %s\n",
7468 inet_ntoa(bgp
->cluster_id
));
7470 /* Disable ebgp connected nexthop check */
7471 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7473 " bgp disable-ebgp-connected-route-check\n");
7475 /* Confederation identifier*/
7476 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7477 vty_out(vty
, " bgp confederation identifier %i\n",
7480 /* Confederation peer */
7481 if (bgp
->confed_peers_cnt
> 0) {
7484 vty_out(vty
, " bgp confederation peers");
7486 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7487 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7492 /* BGP deterministic-med. */
7493 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7494 != DFLT_BGP_DETERMINISTIC_MED
)
7495 vty_out(vty
, " %sbgp deterministic-med\n",
7496 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7500 /* BGP update-delay. */
7501 bgp_config_write_update_delay(vty
, bgp
);
7503 if (bgp
->v_maxmed_onstartup
7504 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7505 vty_out(vty
, " bgp max-med on-startup %u",
7506 bgp
->v_maxmed_onstartup
);
7507 if (bgp
->maxmed_onstartup_value
7508 != BGP_MAXMED_VALUE_DEFAULT
)
7510 bgp
->maxmed_onstartup_value
);
7513 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7514 vty_out(vty
, " bgp max-med administrative");
7515 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7516 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7521 bgp_config_write_wpkt_quanta(vty
, bgp
);
7523 bgp_config_write_rpkt_quanta(vty
, bgp
);
7526 bgp_config_write_coalesce_time(vty
, bgp
);
7528 /* BGP graceful-restart. */
7529 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7531 " bgp graceful-restart stalepath-time %u\n",
7532 bgp
->stalepath_time
);
7533 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7534 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7536 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7537 vty_out(vty
, " bgp graceful-restart\n");
7539 /* BGP graceful-shutdown */
7540 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7541 vty_out(vty
, " bgp graceful-shutdown\n");
7543 /* BGP graceful-restart Preserve State F bit. */
7544 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7546 " bgp graceful-restart preserve-fw-state\n");
7548 /* BGP bestpath method. */
7549 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7550 vty_out(vty
, " bgp bestpath as-path ignore\n");
7551 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7552 vty_out(vty
, " bgp bestpath as-path confed\n");
7554 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7555 if (bgp_flag_check(bgp
,
7556 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7558 " bgp bestpath as-path multipath-relax as-set\n");
7561 " bgp bestpath as-path multipath-relax\n");
7565 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7567 " bgp route-reflector allow-outbound-policy\n");
7569 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7570 vty_out(vty
, " bgp bestpath compare-routerid\n");
7571 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7572 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7573 vty_out(vty
, " bgp bestpath med");
7574 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7575 vty_out(vty
, " confed");
7576 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7577 vty_out(vty
, " missing-as-worst");
7581 /* BGP network import check. */
7582 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7583 != DFLT_BGP_IMPORT_CHECK
)
7584 vty_out(vty
, " %sbgp network import-check\n",
7585 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7589 /* BGP flag dampening. */
7590 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7591 BGP_CONFIG_DAMPENING
))
7592 bgp_config_write_damp(vty
);
7594 /* BGP timers configuration. */
7595 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7596 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7597 vty_out(vty
, " timers bgp %u %u\n",
7598 bgp
->default_keepalive
, bgp
->default_holdtime
);
7601 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7602 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7605 /* Normal neighbor configuration. */
7606 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7607 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7608 bgp_config_write_peer_global(vty
, bgp
, peer
);
7611 /* listen range and limit for dynamic BGP neighbors */
7612 bgp_config_write_listen(vty
, bgp
);
7615 * BGP default autoshutdown neighbors
7617 * This must be placed after any peer and peer-group
7618 * configuration, to avoid setting all peers to shutdown after
7619 * a daemon restart, which is undesired behavior. (see #2286)
7621 if (bgp
->autoshutdown
)
7622 vty_out(vty
, " bgp default shutdown\n");
7624 /* No auto-summary */
7625 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7626 vty_out(vty
, " no auto-summary\n");
7628 /* IPv4 unicast configuration. */
7629 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7631 /* IPv4 multicast configuration. */
7632 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7634 /* IPv4 labeled-unicast configuration. */
7635 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7637 /* IPv4 VPN configuration. */
7638 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7640 /* ENCAPv4 configuration. */
7641 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7643 /* FLOWSPEC v4 configuration. */
7644 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7646 /* IPv6 unicast configuration. */
7647 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7649 /* IPv6 multicast configuration. */
7650 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7652 /* IPv6 labeled-unicast configuration. */
7653 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7654 SAFI_LABELED_UNICAST
);
7656 /* IPv6 VPN configuration. */
7657 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7659 /* ENCAPv6 configuration. */
7660 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7662 /* FLOWSPEC v6 configuration. */
7663 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7665 /* EVPN configuration. */
7666 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7669 bgp_rfapi_cfg_write(vty
, bgp
);
7672 vty_out(vty
, "!\n");
7677 void bgp_master_init(struct thread_master
*master
)
7681 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7684 bm
->bgp
= list_new();
7685 bm
->listen_sockets
= list_new();
7686 bm
->port
= BGP_PORT_DEFAULT
;
7687 bm
->master
= master
;
7688 bm
->start_time
= bgp_clock();
7689 bm
->t_rmap_update
= NULL
;
7690 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7691 bm
->terminating
= false;
7693 bgp_process_queue_init();
7695 /* init the rd id space.
7696 assign 0th index in the bitfield,
7697 so that we start with id 1
7699 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7700 bf_assign_zero_index(bm
->rd_idspace
);
7702 /* Enable multiple instances by default. */
7703 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7705 /* mpls label dynamic allocation pool */
7706 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7708 QOBJ_REG(bm
, bgp_master
);
7712 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7713 * instance delete (non-default only) or BGP exit.
7715 static void bgp_if_finish(struct bgp
*bgp
)
7717 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7718 struct interface
*ifp
;
7720 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7723 FOR_ALL_INTERFACES (vrf
, ifp
) {
7724 struct listnode
*c_node
, *c_nnode
;
7725 struct connected
*c
;
7727 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7728 bgp_connected_delete(bgp
, c
);
7732 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7734 struct vrf
*vrf
= NULL
;
7735 struct listnode
*next
;
7738 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7739 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7740 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7743 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7744 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7747 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7751 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7752 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7753 {.completions
= NULL
},
7756 static void bgp_pthreads_init()
7760 struct frr_pthread_attr io
= {
7762 .start
= frr_pthread_attr_default
.start
,
7763 .stop
= frr_pthread_attr_default
.stop
,
7765 struct frr_pthread_attr ka
= {
7766 .id
= PTHREAD_KEEPALIVES
,
7767 .start
= bgp_keepalives_start
,
7768 .stop
= bgp_keepalives_stop
,
7770 frr_pthread_new(&io
, "BGP I/O thread");
7771 frr_pthread_new(&ka
, "BGP Keepalives thread");
7774 void bgp_pthreads_run()
7776 struct frr_pthread
*io
= frr_pthread_get(PTHREAD_IO
);
7777 struct frr_pthread
*ka
= frr_pthread_get(PTHREAD_KEEPALIVES
);
7779 frr_pthread_run(io
, NULL
);
7780 frr_pthread_run(ka
, NULL
);
7782 /* Wait until threads are ready. */
7783 frr_pthread_wait_running(io
);
7784 frr_pthread_wait_running(ka
);
7787 void bgp_pthreads_finish()
7789 frr_pthread_stop_all();
7790 frr_pthread_finish();
7796 /* allocates some vital data structures used by peer commands in
7799 /* pre-init pthreads */
7800 bgp_pthreads_init();
7803 bgp_zebra_init(bm
->master
);
7806 vnc_zebra_init(bm
->master
);
7809 /* BGP VTY commands installation. */
7817 bgp_route_map_init();
7818 bgp_scan_vty_init();
7823 bgp_ethernetvpn_init();
7824 bgp_flowspec_vty_init();
7826 /* Access list initialize. */
7828 access_list_add_hook(peer_distribute_update
);
7829 access_list_delete_hook(peer_distribute_update
);
7831 /* Filter list initialize. */
7833 as_list_add_hook(peer_aslist_add
);
7834 as_list_delete_hook(peer_aslist_del
);
7836 /* Prefix list initialize.*/
7838 prefix_list_add_hook(peer_prefix_list_update
);
7839 prefix_list_delete_hook(peer_prefix_list_update
);
7841 /* Community list initialize. */
7842 bgp_clist
= community_list_init();
7847 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7850 void bgp_terminate(void)
7854 struct listnode
*node
, *nnode
;
7855 struct listnode
*mnode
, *mnnode
;
7859 /* Close the listener sockets first as this prevents peers from
7861 * to reconnect on receiving the peer unconfig message. In the presence
7862 * of a large number of peers this will ensure that no peer is left with
7863 * a dangling connection
7865 /* reverse bgp_master_init */
7868 if (bm
->listen_sockets
)
7869 list_delete_and_null(&bm
->listen_sockets
);
7871 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7872 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7873 if (peer
->status
== Established
7874 || peer
->status
== OpenSent
7875 || peer
->status
== OpenConfirm
)
7876 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7877 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7879 if (bm
->process_main_queue
)
7880 work_queue_free_and_null(&bm
->process_main_queue
);
7882 if (bm
->t_rmap_update
)
7883 BGP_TIMER_OFF(bm
->t_rmap_update
);