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 bool 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
);
1426 * Create new BGP peer.
1428 * conf_if and su are mutually exclusive if configuring from the cli.
1429 * If we are handing a doppelganger, then we *must* pass in both
1430 * the original peer's su and conf_if, so that we can appropriately
1431 * track the bgp->peerhash( ie we don't want to remove the current
1432 * one from the config ).
1434 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1435 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1436 int as_type
, afi_t afi
, safi_t safi
,
1437 struct peer_group
*group
)
1441 char buf
[SU_ADDRSTRLEN
];
1443 peer
= peer_new(bgp
);
1445 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1449 bgp_peer_conf_if_to_su_update(peer
);
1451 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1452 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1455 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1457 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1458 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1460 peer
->local_as
= local_as
;
1461 peer
->as
= remote_as
;
1462 peer
->as_type
= as_type
;
1463 peer
->local_id
= bgp
->router_id
;
1464 peer
->v_holdtime
= bgp
->default_holdtime
;
1465 peer
->v_keepalive
= bgp
->default_keepalive
;
1466 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1467 ? BGP_DEFAULT_IBGP_ROUTEADV
1468 : BGP_DEFAULT_EBGP_ROUTEADV
;
1470 peer
= peer_lock(peer
); /* bgp peer list reference */
1471 peer
->group
= group
;
1472 listnode_add_sort(bgp
->peer
, peer
);
1473 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1475 /* Adjust update-group coalesce timer heuristics for # peers. */
1476 if (bgp
->heuristic_coalesce
) {
1477 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1479 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1480 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1483 active
= peer_active(peer
);
1485 /* Last read and reset time set */
1486 peer
->readtime
= peer
->resettime
= bgp_clock();
1488 /* Default TTL set. */
1489 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1491 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1494 peer
->afc
[afi
][safi
] = 1;
1495 peer_af_create(peer
, afi
, safi
);
1498 /* auto shutdown if configured */
1499 if (bgp
->autoshutdown
)
1500 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1501 /* Set up peer's events and timers. */
1502 else if (!active
&& peer_active(peer
))
1503 bgp_timer_set(peer
);
1508 /* Make accept BGP peer. This function is only called from the test code */
1509 struct peer
*peer_create_accept(struct bgp
*bgp
)
1513 peer
= peer_new(bgp
);
1515 peer
= peer_lock(peer
); /* bgp peer list reference */
1516 listnode_add_sort(bgp
->peer
, peer
);
1522 * Return true if we have a peer configured to use this afi/safi
1524 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1526 struct listnode
*node
;
1529 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1530 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1533 if (peer
->afc
[afi
][safi
])
1540 /* Change peer's AS number. */
1541 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1543 bgp_peer_sort_t type
;
1546 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1547 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1548 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1549 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1550 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1552 bgp_session_reset(peer
);
1554 type
= peer_sort(peer
);
1556 peer
->as_type
= as_specified
;
1558 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1559 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1560 && peer
->bgp
->as
!= as
)
1561 peer
->local_as
= peer
->bgp
->confed_id
;
1563 peer
->local_as
= peer
->bgp
->as
;
1565 /* Advertisement-interval reset */
1566 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1567 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1568 ? BGP_DEFAULT_IBGP_ROUTEADV
1569 : BGP_DEFAULT_EBGP_ROUTEADV
;
1573 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1575 else if (type
== BGP_PEER_IBGP
)
1578 /* reflector-client reset */
1579 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1580 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1581 PEER_FLAG_REFLECTOR_CLIENT
);
1582 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1583 PEER_FLAG_REFLECTOR_CLIENT
);
1584 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1585 PEER_FLAG_REFLECTOR_CLIENT
);
1586 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1587 PEER_FLAG_REFLECTOR_CLIENT
);
1588 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1589 PEER_FLAG_REFLECTOR_CLIENT
);
1590 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1591 PEER_FLAG_REFLECTOR_CLIENT
);
1592 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1593 PEER_FLAG_REFLECTOR_CLIENT
);
1594 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1595 PEER_FLAG_REFLECTOR_CLIENT
);
1596 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1597 PEER_FLAG_REFLECTOR_CLIENT
);
1598 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1599 PEER_FLAG_REFLECTOR_CLIENT
);
1600 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1601 PEER_FLAG_REFLECTOR_CLIENT
);
1602 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1603 PEER_FLAG_REFLECTOR_CLIENT
);
1604 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1605 PEER_FLAG_REFLECTOR_CLIENT
);
1608 /* local-as reset */
1609 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1610 peer
->change_local_as
= 0;
1611 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1612 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1613 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1617 /* If peer does not exist, create new one. If peer already exists,
1618 set AS number to the peer. */
1619 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1620 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1626 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1628 peer
= peer_lookup(bgp
, su
);
1631 /* Not allowed for a dynamic peer. */
1632 if (peer_dynamic_neighbor(peer
)) {
1634 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1637 /* When this peer is a member of peer-group. */
1639 if (peer
->group
->conf
->as
) {
1640 /* Return peer group's AS number. */
1641 *as
= peer
->group
->conf
->as
;
1642 return BGP_ERR_PEER_GROUP_MEMBER
;
1644 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1645 if ((as_type
!= AS_INTERNAL
)
1646 && (bgp
->as
!= *as
)) {
1648 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1651 if ((as_type
!= AS_EXTERNAL
)
1652 && (bgp
->as
== *as
)) {
1654 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1659 /* Existing peer's AS number change. */
1660 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1661 || (peer
->as_type
!= as_type
))
1662 peer_as_change(peer
, *as
, as_type
);
1665 return BGP_ERR_NO_INTERFACE_CONFIG
;
1667 /* If the peer is not part of our confederation, and its not an
1668 iBGP peer then spoof the source AS */
1669 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1670 && !bgp_confederation_peers_check(bgp
, *as
)
1672 local_as
= bgp
->confed_id
;
1676 /* If this is IPv4 unicast configuration and "no bgp default
1677 ipv4-unicast" is specified. */
1679 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1680 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1681 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1684 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1691 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1692 struct peer
*peer
, afi_t afi
,
1696 int out
= FILTER_OUT
;
1698 uint32_t pflags_ovrd
;
1699 uint8_t *pfilter_ovrd
;
1703 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1704 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1706 /* peer af_flags apply */
1707 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1708 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1709 ^ peer
->af_flags_invert
[afi
][safi
];
1710 flags_tmp
&= ~pflags_ovrd
;
1712 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1713 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1714 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1715 conf
->af_flags_invert
[afi
][safi
]);
1717 /* maximum-prefix */
1718 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1719 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1720 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1721 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1725 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1726 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1729 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1730 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1732 /* default-originate route-map */
1733 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1734 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1735 MTYPE_ROUTE_MAP_NAME
);
1736 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1739 /* inbound filter apply */
1740 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1741 PEER_STR_ATTR_INHERIT(peer
, group
,
1742 filter
[afi
][safi
].dlist
[in
].name
,
1743 MTYPE_BGP_FILTER_NAME
);
1744 PEER_ATTR_INHERIT(peer
, group
,
1745 filter
[afi
][safi
].dlist
[in
].alist
);
1748 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1749 PEER_STR_ATTR_INHERIT(peer
, group
,
1750 filter
[afi
][safi
].plist
[in
].name
,
1751 MTYPE_BGP_FILTER_NAME
);
1752 PEER_ATTR_INHERIT(peer
, group
,
1753 filter
[afi
][safi
].plist
[in
].plist
);
1756 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1757 PEER_STR_ATTR_INHERIT(peer
, group
,
1758 filter
[afi
][safi
].aslist
[in
].name
,
1759 MTYPE_BGP_FILTER_NAME
);
1760 PEER_ATTR_INHERIT(peer
, group
,
1761 filter
[afi
][safi
].aslist
[in
].aslist
);
1764 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1765 PEER_STR_ATTR_INHERIT(peer
, group
,
1766 filter
[afi
][safi
].map
[in
].name
,
1767 MTYPE_BGP_FILTER_NAME
);
1768 PEER_ATTR_INHERIT(peer
, group
,
1769 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1772 /* outbound filter apply */
1773 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1774 PEER_STR_ATTR_INHERIT(peer
, group
,
1775 filter
[afi
][safi
].dlist
[out
].name
,
1776 MTYPE_BGP_FILTER_NAME
);
1777 PEER_ATTR_INHERIT(peer
, group
,
1778 filter
[afi
][safi
].dlist
[out
].alist
);
1781 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1782 PEER_STR_ATTR_INHERIT(peer
, group
,
1783 filter
[afi
][safi
].plist
[out
].name
,
1784 MTYPE_BGP_FILTER_NAME
);
1785 PEER_ATTR_INHERIT(peer
, group
,
1786 filter
[afi
][safi
].plist
[out
].plist
);
1789 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1790 PEER_STR_ATTR_INHERIT(peer
, group
,
1791 filter
[afi
][safi
].aslist
[out
].name
,
1792 MTYPE_BGP_FILTER_NAME
);
1793 PEER_ATTR_INHERIT(peer
, group
,
1794 filter
[afi
][safi
].aslist
[out
].aslist
);
1797 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1798 PEER_STR_ATTR_INHERIT(peer
, group
,
1799 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1800 MTYPE_BGP_FILTER_NAME
);
1801 PEER_ATTR_INHERIT(peer
, group
,
1802 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1805 /* nondirectional filter apply */
1806 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1807 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1808 MTYPE_BGP_FILTER_NAME
);
1809 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1813 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1818 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1819 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1820 __func__
, peer
->host
);
1824 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1826 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1827 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1828 return BGP_ERR_PEER_SAFI_CONFLICT
;
1830 /* Nothing to do if we've already activated this peer */
1831 if (peer
->afc
[afi
][safi
])
1834 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1837 active
= peer_active(peer
);
1838 peer
->afc
[afi
][safi
] = 1;
1841 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1843 if (!active
&& peer_active(peer
)) {
1844 bgp_timer_set(peer
);
1846 if (peer
->status
== Established
) {
1847 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1848 peer
->afc_adv
[afi
][safi
] = 1;
1849 bgp_capability_send(peer
, afi
, safi
,
1851 CAPABILITY_ACTION_SET
);
1852 if (peer
->afc_recv
[afi
][safi
]) {
1853 peer
->afc_nego
[afi
][safi
] = 1;
1854 bgp_announce_route(peer
, afi
, safi
);
1857 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1858 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1859 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1862 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1863 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1864 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1865 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1868 * If we are turning on a AFI/SAFI locally and we've
1869 * started bringing a peer up, we need to tell
1870 * the other peer to restart because we might loose
1871 * configuration here because when the doppelganger
1872 * gets to a established state due to how
1873 * we resolve we could just overwrite the afi/safi
1876 other
= peer
->doppelganger
;
1878 && (other
->status
== OpenSent
1879 || other
->status
== OpenConfirm
)) {
1880 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1881 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1882 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1889 /* Activate the peer or peer group for specified AFI and SAFI. */
1890 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1893 struct peer_group
*group
;
1894 struct listnode
*node
, *nnode
;
1895 struct peer
*tmp_peer
;
1898 /* Nothing to do if we've already activated this peer */
1899 if (peer
->afc
[afi
][safi
])
1904 /* This is a peer-group so activate all of the members of the
1905 * peer-group as well */
1906 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1908 /* Do not activate a peer for both SAFI_UNICAST and
1909 * SAFI_LABELED_UNICAST */
1910 if ((safi
== SAFI_UNICAST
1911 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1912 || (safi
== SAFI_LABELED_UNICAST
1913 && peer
->afc
[afi
][SAFI_UNICAST
]))
1914 return BGP_ERR_PEER_SAFI_CONFLICT
;
1916 peer
->afc
[afi
][safi
] = 1;
1917 group
= peer
->group
;
1919 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1920 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1923 ret
|= peer_activate_af(peer
, afi
, safi
);
1926 /* If this is the first peer to be activated for this
1927 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1928 if (safi
== SAFI_LABELED_UNICAST
1929 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1931 if (BGP_DEBUG(zebra
, ZEBRA
))
1933 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1935 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1936 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1939 if (safi
== SAFI_FLOWSPEC
) {
1940 /* connect to table manager */
1941 bgp_zebra_init_tm_connect(bgp
);
1946 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1949 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1950 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1951 __func__
, peer
->host
);
1955 /* Nothing to do if we've already deactivated this peer */
1956 if (!peer
->afc
[afi
][safi
])
1959 /* De-activate the address family configuration. */
1960 peer
->afc
[afi
][safi
] = 0;
1962 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1963 flog_err(EC_BGP_PEER_DELETE
,
1964 "couldn't delete af structure for peer %s",
1969 if (peer
->status
== Established
) {
1970 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1971 peer
->afc_adv
[afi
][safi
] = 0;
1972 peer
->afc_nego
[afi
][safi
] = 0;
1974 if (peer_active_nego(peer
)) {
1975 bgp_capability_send(peer
, afi
, safi
,
1977 CAPABILITY_ACTION_UNSET
);
1978 bgp_clear_route(peer
, afi
, safi
);
1979 peer
->pcount
[afi
][safi
] = 0;
1981 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1982 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1983 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1986 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1987 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1988 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1995 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1998 struct peer_group
*group
;
1999 struct peer
*tmp_peer
;
2000 struct listnode
*node
, *nnode
;
2003 /* Nothing to do if we've already de-activated this peer */
2004 if (!peer
->afc
[afi
][safi
])
2007 /* This is a peer-group so de-activate all of the members of the
2008 * peer-group as well */
2009 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2010 peer
->afc
[afi
][safi
] = 0;
2011 group
= peer
->group
;
2013 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2014 flog_err(EC_BGP_PEER_DELETE
,
2015 "couldn't delete af structure for peer %s",
2019 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2020 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2023 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2028 /* If this is the last peer to be deactivated for this
2029 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2030 if (safi
== SAFI_LABELED_UNICAST
2031 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2032 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2034 if (BGP_DEBUG(zebra
, ZEBRA
))
2036 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2038 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2039 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2044 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2047 return peer_activate(peer
, afi
, safi
);
2049 return peer_deactivate(peer
, afi
, safi
);
2052 static void peer_nsf_stop(struct peer
*peer
)
2057 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2058 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2060 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2061 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2062 peer
->nsf
[afi
][safi
] = 0;
2064 if (peer
->t_gr_restart
) {
2065 BGP_TIMER_OFF(peer
->t_gr_restart
);
2066 if (bgp_debug_neighbor_events(peer
))
2067 zlog_debug("%s graceful restart timer stopped",
2070 if (peer
->t_gr_stale
) {
2071 BGP_TIMER_OFF(peer
->t_gr_stale
);
2072 if (bgp_debug_neighbor_events(peer
))
2074 "%s graceful restart stalepath timer stopped",
2077 bgp_clear_route_all(peer
);
2080 /* Delete peer from confguration.
2082 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2083 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2085 * This function /should/ take care to be idempotent, to guard against
2086 * it being called multiple times through stray events that come in
2087 * that happen to result in this function being called again. That
2088 * said, getting here for a "Deleted" peer is a bug in the neighbour
2091 int peer_delete(struct peer
*peer
)
2097 struct bgp_filter
*filter
;
2098 struct listnode
*pn
;
2101 assert(peer
->status
!= Deleted
);
2104 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2106 bgp_reads_off(peer
);
2107 bgp_writes_off(peer
);
2108 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2109 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2111 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2112 peer_nsf_stop(peer
);
2114 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2116 /* If this peer belongs to peer group, clear up the
2119 if (peer_dynamic_neighbor(peer
))
2120 peer_drop_dynamic_neighbor(peer
);
2122 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2124 peer
); /* group->peer list reference */
2125 list_delete_node(peer
->group
->peer
, pn
);
2130 /* Withdraw all information from routing table. We can not use
2131 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2132 * executed after peer structure is deleted.
2134 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2136 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2138 if (peer
->doppelganger
) {
2139 peer
->doppelganger
->doppelganger
= NULL
;
2140 peer
->doppelganger
= NULL
;
2143 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2144 bgp_fsm_change_status(peer
, Deleted
);
2146 /* Remove from NHT */
2147 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2148 bgp_unlink_nexthop_by_peer(peer
);
2150 /* Password configuration */
2151 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2152 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2154 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2155 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2156 bgp_md5_unset(peer
);
2159 bgp_timer_set(peer
); /* stops all timers for Deleted */
2161 /* Delete from all peer list. */
2162 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2163 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2164 peer_unlock(peer
); /* bgp peer list reference */
2165 list_delete_node(bgp
->peer
, pn
);
2166 hash_release(bgp
->peerhash
, peer
);
2171 stream_fifo_free(peer
->ibuf
);
2176 stream_fifo_free(peer
->obuf
);
2180 if (peer
->ibuf_work
) {
2181 ringbuf_del(peer
->ibuf_work
);
2182 peer
->ibuf_work
= NULL
;
2185 if (peer
->obuf_work
) {
2186 stream_free(peer
->obuf_work
);
2187 peer
->obuf_work
= NULL
;
2190 if (peer
->scratch
) {
2191 stream_free(peer
->scratch
);
2192 peer
->scratch
= NULL
;
2195 /* Local and remote addresses. */
2196 if (peer
->su_local
) {
2197 sockunion_free(peer
->su_local
);
2198 peer
->su_local
= NULL
;
2201 if (peer
->su_remote
) {
2202 sockunion_free(peer
->su_remote
);
2203 peer
->su_remote
= NULL
;
2206 /* Free filter related memory. */
2207 FOREACH_AFI_SAFI (afi
, safi
) {
2208 filter
= &peer
->filter
[afi
][safi
];
2210 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2211 if (filter
->dlist
[i
].name
) {
2212 XFREE(MTYPE_BGP_FILTER_NAME
,
2213 filter
->dlist
[i
].name
);
2214 filter
->dlist
[i
].name
= NULL
;
2217 if (filter
->plist
[i
].name
) {
2218 XFREE(MTYPE_BGP_FILTER_NAME
,
2219 filter
->plist
[i
].name
);
2220 filter
->plist
[i
].name
= NULL
;
2223 if (filter
->aslist
[i
].name
) {
2224 XFREE(MTYPE_BGP_FILTER_NAME
,
2225 filter
->aslist
[i
].name
);
2226 filter
->aslist
[i
].name
= NULL
;
2230 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2231 if (filter
->map
[i
].name
) {
2232 XFREE(MTYPE_BGP_FILTER_NAME
,
2233 filter
->map
[i
].name
);
2234 filter
->map
[i
].name
= NULL
;
2238 if (filter
->usmap
.name
) {
2239 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2240 filter
->usmap
.name
= NULL
;
2243 if (peer
->default_rmap
[afi
][safi
].name
) {
2244 XFREE(MTYPE_ROUTE_MAP_NAME
,
2245 peer
->default_rmap
[afi
][safi
].name
);
2246 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2250 FOREACH_AFI_SAFI (afi
, safi
)
2251 peer_af_delete(peer
, afi
, safi
);
2253 if (peer
->hostname
) {
2254 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2255 peer
->hostname
= NULL
;
2258 if (peer
->domainname
) {
2259 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2260 peer
->domainname
= NULL
;
2263 peer_unlock(peer
); /* initial reference */
2268 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2270 return strcmp(g1
->name
, g2
->name
);
2273 /* Peer group cofiguration. */
2274 static struct peer_group
*peer_group_new(void)
2276 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2277 sizeof(struct peer_group
));
2280 static void peer_group_free(struct peer_group
*group
)
2282 XFREE(MTYPE_PEER_GROUP
, group
);
2285 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2287 struct peer_group
*group
;
2288 struct listnode
*node
, *nnode
;
2290 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2291 if (strcmp(group
->name
, name
) == 0)
2297 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2299 struct peer_group
*group
;
2302 group
= peer_group_lookup(bgp
, name
);
2306 group
= peer_group_new();
2309 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2310 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2311 group
->peer
= list_new();
2312 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2313 group
->listen_range
[afi
] = list_new();
2314 group
->conf
= peer_new(bgp
);
2315 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2316 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2317 if (group
->conf
->host
)
2318 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2319 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2320 group
->conf
->group
= group
;
2321 group
->conf
->as
= 0;
2322 group
->conf
->ttl
= 1;
2323 group
->conf
->gtsm_hops
= 0;
2324 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2325 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2326 listnode_add_sort(bgp
->group
, group
);
2331 static void peer_group2peer_config_copy(struct peer_group
*group
,
2341 peer
->as
= conf
->as
;
2344 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2345 peer
->change_local_as
= conf
->change_local_as
;
2348 peer
->ttl
= conf
->ttl
;
2351 peer
->gtsm_hops
= conf
->gtsm_hops
;
2353 /* peer flags apply */
2354 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2355 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2356 flags_tmp
&= ~peer
->flags_override
;
2358 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2359 SET_FLAG(peer
->flags
, flags_tmp
);
2360 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2362 /* peer timers apply */
2363 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2364 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2365 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2368 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2369 PEER_ATTR_INHERIT(peer
, group
, connect
);
2370 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2371 peer
->v_connect
= conf
->connect
;
2373 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2376 /* advertisement-interval apply */
2377 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2378 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2379 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2380 peer
->v_routeadv
= conf
->routeadv
;
2382 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2383 ? BGP_DEFAULT_IBGP_ROUTEADV
2384 : BGP_DEFAULT_EBGP_ROUTEADV
;
2387 /* password apply */
2388 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2389 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2390 MTYPE_PEER_PASSWORD
);
2392 if (!BGP_PEER_SU_UNSPEC(peer
))
2395 /* update-source apply */
2396 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2397 if (conf
->update_source
) {
2398 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2399 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2400 } else if (conf
->update_if
) {
2401 sockunion_free(peer
->update_source
);
2402 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2403 MTYPE_PEER_UPDATE_SOURCE
);
2407 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2410 /* Peer group's remote AS configuration. */
2411 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2414 struct peer_group
*group
;
2416 struct listnode
*node
, *nnode
;
2418 group
= peer_group_lookup(bgp
, group_name
);
2422 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2426 /* When we setup peer-group AS number all peer group member's AS
2427 number must be updated to same number. */
2428 peer_as_change(group
->conf
, *as
, as_type
);
2430 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2431 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2432 || (peer
->as_type
!= as_type
))
2433 peer_as_change(peer
, *as
, as_type
);
2439 int peer_group_delete(struct peer_group
*group
)
2443 struct prefix
*prefix
;
2445 struct listnode
*node
, *nnode
;
2450 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2451 other
= peer
->doppelganger
;
2453 if (other
&& other
->status
!= Deleted
) {
2454 other
->group
= NULL
;
2458 list_delete(&group
->peer
);
2460 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2461 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2463 prefix_free(prefix
);
2465 list_delete(&group
->listen_range
[afi
]);
2468 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2471 bfd_info_free(&(group
->conf
->bfd_info
));
2473 group
->conf
->group
= NULL
;
2474 peer_delete(group
->conf
);
2476 /* Delete from all peer_group list. */
2477 listnode_delete(bgp
->group
, group
);
2479 peer_group_free(group
);
2484 int peer_group_remote_as_delete(struct peer_group
*group
)
2486 struct peer
*peer
, *other
;
2487 struct listnode
*node
, *nnode
;
2489 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2490 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2493 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2494 other
= peer
->doppelganger
;
2498 if (other
&& other
->status
!= Deleted
) {
2499 other
->group
= NULL
;
2503 list_delete_all_node(group
->peer
);
2505 group
->conf
->as
= 0;
2506 group
->conf
->as_type
= AS_UNSPECIFIED
;
2511 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2513 struct prefix
*prefix
;
2514 struct listnode
*node
, *nnode
;
2517 afi
= family2afi(range
->family
);
2519 /* Group needs remote AS configured. */
2520 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2521 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2523 /* Ensure no duplicates. Currently we don't care about overlaps. */
2524 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2525 if (prefix_same(range
, prefix
))
2529 prefix
= prefix_new();
2530 prefix_copy(prefix
, range
);
2531 listnode_add(group
->listen_range
[afi
], prefix
);
2535 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2537 struct prefix
*prefix
, prefix2
;
2538 struct listnode
*node
, *nnode
;
2541 char buf
[PREFIX2STR_BUFFER
];
2543 afi
= family2afi(range
->family
);
2545 /* Identify the listen range. */
2546 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2547 if (prefix_same(range
, prefix
))
2552 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2554 prefix2str(prefix
, buf
, sizeof(buf
));
2556 /* Dispose off any dynamic neighbors that exist due to this listen range
2558 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2559 if (!peer_dynamic_neighbor(peer
))
2562 sockunion2hostprefix(&peer
->su
, &prefix2
);
2563 if (prefix_match(prefix
, &prefix2
)) {
2564 if (bgp_debug_neighbor_events(peer
))
2566 "Deleting dynamic neighbor %s group %s upon "
2567 "delete of listen range %s",
2568 peer
->host
, group
->name
, buf
);
2573 /* Get rid of the listen range */
2574 listnode_delete(group
->listen_range
[afi
], prefix
);
2579 /* Bind specified peer to peer group. */
2580 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2581 struct peer_group
*group
, as_t
*as
)
2583 int first_member
= 0;
2587 /* Lookup the peer. */
2589 peer
= peer_lookup(bgp
, su
);
2591 /* The peer exist, bind it to the peer-group */
2593 /* When the peer already belongs to a peer-group, check the
2595 if (peer_group_active(peer
)) {
2597 /* The peer is already bound to the peer-group,
2600 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2603 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2606 /* The peer has not specified a remote-as, inherit it from the
2608 if (peer
->as_type
== AS_UNSPECIFIED
) {
2609 peer
->as_type
= group
->conf
->as_type
;
2610 peer
->as
= group
->conf
->as
;
2613 if (!group
->conf
->as
) {
2614 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2615 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2618 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2621 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2625 peer_group2peer_config_copy(group
, peer
);
2627 FOREACH_AFI_SAFI (afi
, safi
) {
2628 if (group
->conf
->afc
[afi
][safi
]) {
2629 peer
->afc
[afi
][safi
] = 1;
2631 if (peer_af_find(peer
, afi
, safi
)
2632 || peer_af_create(peer
, afi
, safi
)) {
2633 peer_group2peer_config_copy_af(
2634 group
, peer
, afi
, safi
);
2636 } else if (peer
->afc
[afi
][safi
])
2637 peer_deactivate(peer
, afi
, safi
);
2641 assert(group
&& peer
->group
== group
);
2643 listnode_delete(bgp
->peer
, peer
);
2645 peer
->group
= group
;
2646 listnode_add_sort(bgp
->peer
, peer
);
2648 peer
= peer_lock(peer
); /* group->peer list reference */
2649 listnode_add(group
->peer
, peer
);
2653 /* Advertisement-interval reset */
2654 if (!CHECK_FLAG(group
->conf
->flags
,
2655 PEER_FLAG_ROUTEADV
)) {
2656 group
->conf
->v_routeadv
=
2657 (peer_sort(group
->conf
)
2659 ? BGP_DEFAULT_IBGP_ROUTEADV
2660 : BGP_DEFAULT_EBGP_ROUTEADV
;
2663 /* ebgp-multihop reset */
2664 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2665 group
->conf
->ttl
= MAXTTL
;
2667 /* local-as reset */
2668 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2669 group
->conf
->change_local_as
= 0;
2670 peer_flag_unset(group
->conf
,
2671 PEER_FLAG_LOCAL_AS
);
2672 peer_flag_unset(group
->conf
,
2673 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2674 peer_flag_unset(group
->conf
,
2675 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2679 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2681 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2682 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2683 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2684 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2686 bgp_session_reset(peer
);
2690 /* Create a new peer. */
2692 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2693 && (!group
->conf
->as
)) {
2694 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2697 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2698 group
->conf
->as_type
, 0, 0, group
);
2700 peer
= peer_lock(peer
); /* group->peer list reference */
2701 listnode_add(group
->peer
, peer
);
2703 peer_group2peer_config_copy(group
, peer
);
2705 /* If the peer-group is active for this afi/safi then activate
2707 FOREACH_AFI_SAFI (afi
, safi
) {
2708 if (group
->conf
->afc
[afi
][safi
]) {
2709 peer
->afc
[afi
][safi
] = 1;
2710 peer_af_create(peer
, afi
, safi
);
2711 peer_group2peer_config_copy_af(group
, peer
, afi
,
2713 } else if (peer
->afc
[afi
][safi
])
2714 peer_deactivate(peer
, afi
, safi
);
2717 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2719 /* Set up peer's events and timers. */
2720 if (peer_active(peer
))
2721 bgp_timer_set(peer
);
2727 static int bgp_startup_timer_expire(struct thread
*thread
)
2731 bgp
= THREAD_ARG(thread
);
2732 bgp
->t_startup
= NULL
;
2738 * On shutdown we call the cleanup function which
2739 * does a free of the link list nodes, free up
2740 * the data we are pointing at too.
2742 static void bgp_vrf_string_name_delete(void *data
)
2746 XFREE(MTYPE_TMP
, vname
);
2749 /* BGP instance creation by `router bgp' commands. */
2750 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2751 enum bgp_instance_type inst_type
)
2757 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2760 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2761 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2762 zlog_debug("Creating Default VRF, AS %u", *as
);
2764 zlog_debug("Creating %s %s, AS %u",
2765 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2772 bgp
->heuristic_coalesce
= true;
2773 bgp
->inst_type
= inst_type
;
2774 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2776 bgp
->peer_self
= peer_new(bgp
);
2777 if (bgp
->peer_self
->host
)
2778 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2779 bgp
->peer_self
->host
=
2780 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2781 if (bgp
->peer_self
->hostname
!= NULL
) {
2782 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2783 bgp
->peer_self
->hostname
= NULL
;
2785 if (cmd_hostname_get())
2786 bgp
->peer_self
->hostname
=
2787 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2789 if (bgp
->peer_self
->domainname
!= NULL
) {
2790 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2791 bgp
->peer_self
->domainname
= NULL
;
2793 if (cmd_domainname_get())
2794 bgp
->peer_self
->domainname
=
2795 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2796 bgp
->peer
= list_new();
2797 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2798 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2800 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2802 bgp
->group
= list_new();
2803 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2805 FOREACH_AFI_SAFI (afi
, safi
) {
2806 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2807 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2808 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2810 /* Enable maximum-paths */
2811 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2813 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2817 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2818 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2819 bgp
->default_subgroup_pkt_queue_max
=
2820 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2821 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2822 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2823 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2824 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2825 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2826 bgp
->dynamic_neighbors_count
= 0;
2827 #if DFLT_BGP_IMPORT_CHECK
2828 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2830 #if DFLT_BGP_SHOW_HOSTNAME
2831 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2833 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2834 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2836 #if DFLT_BGP_DETERMINISTIC_MED
2837 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2839 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2844 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2845 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2847 assert(bgp
->rfapi_cfg
);
2849 #endif /* ENABLE_BGP_VNC */
2851 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2852 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2853 bgp
->vpn_policy
[afi
].afi
= afi
;
2854 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2855 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2858 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2859 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2860 bgp_vrf_string_name_delete
;
2861 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2862 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2863 bgp_vrf_string_name_delete
;
2866 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2868 /* TODO - The startup timer needs to be run for the whole of BGP
2870 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2871 bgp
->restart_time
, &bgp
->t_startup
);
2874 /* printable name we can use in debug messages */
2875 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2876 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2886 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2888 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2889 snprintf(bgp
->name_pretty
, len
, "%s %s",
2890 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2896 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2897 memory_order_relaxed
);
2898 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2899 memory_order_relaxed
);
2900 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2904 update_bgp_group_init(bgp
);
2906 /* assign a unique rd id for auto derivation of vrf's RD */
2907 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2914 /* Return the "default VRF" instance of BGP. */
2915 struct bgp
*bgp_get_default(void)
2918 struct listnode
*node
, *nnode
;
2920 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2921 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2926 /* Lookup BGP entry. */
2927 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2930 struct listnode
*node
, *nnode
;
2932 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2934 && ((bgp
->name
== NULL
&& name
== NULL
)
2935 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2940 /* Lookup BGP structure by view name. */
2941 struct bgp
*bgp_lookup_by_name(const char *name
)
2944 struct listnode
*node
, *nnode
;
2946 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2947 if ((bgp
->name
== NULL
&& name
== NULL
)
2948 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2953 /* Lookup BGP instance based on VRF id. */
2954 /* Note: Only to be used for incoming messages from Zebra. */
2955 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2959 /* Lookup VRF (in tree) and follow link. */
2960 vrf
= vrf_lookup_by_id(vrf_id
);
2963 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2966 /* handle socket creation or deletion, if necessary
2967 * this is called for all new BGP instances
2969 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
2974 /* Create BGP server socket, if listen mode not disabled */
2975 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
2977 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
2979 * suppress vrf socket
2981 if (create
== FALSE
) {
2982 bgp_close_vrf_socket(bgp
);
2986 return BGP_ERR_INVALID_VALUE
;
2988 * if vrf_id did not change
2990 if (vrf
->vrf_id
== old_vrf_id
)
2992 if (old_vrf_id
!= VRF_UNKNOWN
) {
2993 /* look for old socket. close it. */
2994 bgp_close_vrf_socket(bgp
);
2996 /* if backend is not yet identified ( VRF_UNKNOWN) then
2997 * creation will be done later
2999 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3001 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3003 return BGP_ERR_INVALID_VALUE
;
3006 return bgp_check_main_socket(create
, bgp
);
3009 /* Called from VTY commands. */
3010 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3011 enum bgp_instance_type inst_type
)
3014 struct vrf
*vrf
= NULL
;
3016 /* Multiple instance check. */
3017 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3019 bgp
= bgp_lookup_by_name(name
);
3021 bgp
= bgp_get_default();
3023 /* Already exists. */
3025 if (bgp
->as
!= *as
) {
3027 return BGP_ERR_INSTANCE_MISMATCH
;
3029 if (bgp
->inst_type
!= inst_type
)
3030 return BGP_ERR_INSTANCE_MISMATCH
;
3035 /* BGP instance name can not be specified for single instance.
3038 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3040 /* Get default BGP structure if exists. */
3041 bgp
= bgp_get_default();
3044 if (bgp
->as
!= *as
) {
3046 return BGP_ERR_AS_MISMATCH
;
3053 bgp
= bgp_create(as
, name
, inst_type
);
3054 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3055 bgp_address_init(bgp
);
3056 bgp_tip_hash_init(bgp
);
3060 bgp
->t_rmap_def_originate_eval
= NULL
;
3062 /* If Default instance or VRF, link to the VRF structure, if present. */
3063 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3064 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3065 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3067 bgp_vrf_link(bgp
, vrf
);
3069 /* BGP server socket already processed if BGP instance
3070 * already part of the list
3072 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3073 listnode_add(bm
->bgp
, bgp
);
3075 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3076 if (BGP_DEBUG(zebra
, ZEBRA
))
3077 zlog_debug("%s: Registering BGP instance %s to zebra",
3078 __PRETTY_FUNCTION__
, name
);
3079 bgp_zebra_instance_register(bgp
);
3086 * Make BGP instance "up". Applies only to VRFs (non-default) and
3087 * implies the VRF has been learnt from Zebra.
3089 void bgp_instance_up(struct bgp
*bgp
)
3092 struct listnode
*node
, *next
;
3094 /* Register with zebra. */
3095 bgp_zebra_instance_register(bgp
);
3097 /* Kick off any peers that may have been configured. */
3098 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3099 if (!BGP_PEER_START_SUPPRESSED(peer
))
3100 BGP_EVENT_ADD(peer
, BGP_Start
);
3103 /* Process any networks that have been configured. */
3104 bgp_static_add(bgp
);
3108 * Make BGP instance "down". Applies only to VRFs (non-default) and
3109 * implies the VRF has been deleted by Zebra.
3111 void bgp_instance_down(struct bgp
*bgp
)
3114 struct listnode
*node
;
3115 struct listnode
*next
;
3118 if (bgp
->t_rmap_def_originate_eval
) {
3119 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3120 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3124 /* Bring down peers, so corresponding routes are purged. */
3125 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3126 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3127 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3128 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3130 bgp_session_reset(peer
);
3133 /* Purge network and redistributed routes. */
3134 bgp_purge_static_redist_routes(bgp
);
3136 /* Cleanup registered nexthops (flags) */
3137 bgp_cleanup_nexthops(bgp
);
3140 /* Delete BGP instance. */
3141 int bgp_delete(struct bgp
*bgp
)
3144 struct peer_group
*group
;
3145 struct listnode
*node
, *next
;
3151 THREAD_OFF(bgp
->t_startup
);
3152 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3153 THREAD_OFF(bgp
->t_update_delay
);
3154 THREAD_OFF(bgp
->t_establish_wait
);
3156 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3157 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3158 zlog_debug("Deleting Default VRF");
3160 zlog_debug("Deleting %s %s",
3161 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3167 /* unmap from RT list */
3168 bgp_evpn_vrf_delete(bgp
);
3171 if (bgp
->t_rmap_def_originate_eval
) {
3172 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3173 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3177 /* Inform peers we're going down. */
3178 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3179 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3180 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3181 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3184 /* Delete static routes (networks). */
3185 bgp_static_delete(bgp
);
3187 /* Unset redistribution. */
3188 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3189 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3190 if (i
!= ZEBRA_ROUTE_BGP
)
3191 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3193 /* Free peers and peer-groups. */
3194 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3195 peer_group_delete(group
);
3197 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3200 if (bgp
->peer_self
) {
3201 peer_delete(bgp
->peer_self
);
3202 bgp
->peer_self
= NULL
;
3205 update_bgp_group_free(bgp
);
3207 /* TODO - Other memory may need to be freed - e.g., NHT */
3212 bgp_cleanup_routes(bgp
);
3214 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3215 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3218 &bgp
->vpn_policy
[afi
]
3219 .import_redirect_rtlist
);
3220 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3223 /* Deregister from Zebra, if needed */
3224 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3225 if (BGP_DEBUG(zebra
, ZEBRA
))
3226 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3227 __PRETTY_FUNCTION__
, bgp
->name
);
3228 bgp_zebra_instance_deregister(bgp
);
3231 /* Remove visibility via the master list - there may however still be
3232 * routes to be processed still referencing the struct bgp.
3234 listnode_delete(bm
->bgp
, bgp
);
3236 /* Free interfaces in this instance. */
3239 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3240 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3242 bgp_vrf_unlink(bgp
, vrf
);
3244 thread_master_free_unused(bm
->master
);
3245 bgp_unlock(bgp
); /* initial reference */
3250 void bgp_free(struct bgp
*bgp
)
3254 struct bgp_table
*table
;
3255 struct bgp_node
*rn
;
3256 struct bgp_rmap
*rmap
;
3260 list_delete(&bgp
->group
);
3261 list_delete(&bgp
->peer
);
3263 if (bgp
->peerhash
) {
3264 hash_free(bgp
->peerhash
);
3265 bgp
->peerhash
= NULL
;
3268 FOREACH_AFI_SAFI (afi
, safi
) {
3269 /* Special handling for 2-level routing tables. */
3270 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3271 || safi
== SAFI_EVPN
) {
3272 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3273 rn
= bgp_route_next(rn
)) {
3274 table
= (struct bgp_table
*)rn
->info
;
3275 bgp_table_finish(&table
);
3278 if (bgp
->route
[afi
][safi
])
3279 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3280 if (bgp
->aggregate
[afi
][safi
])
3281 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3282 if (bgp
->rib
[afi
][safi
])
3283 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3284 rmap
= &bgp
->table_map
[afi
][safi
];
3286 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3289 bgp_scan_finish(bgp
);
3290 bgp_address_destroy(bgp
);
3291 bgp_tip_hash_destroy(bgp
);
3293 /* release the auto RD id */
3294 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3296 bgp_evpn_cleanup(bgp
);
3297 bgp_pbr_cleanup(bgp
);
3299 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3300 vpn_policy_direction_t dir
;
3302 if (bgp
->vpn_policy
[afi
].import_vrf
)
3303 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3304 if (bgp
->vpn_policy
[afi
].export_vrf
)
3305 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3307 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3308 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3309 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3310 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3311 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3312 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3316 XFREE(MTYPE_BGP
, bgp
->name
);
3317 if (bgp
->name_pretty
)
3318 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3320 XFREE(MTYPE_BGP
, bgp
);
3323 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3326 struct listnode
*node
, *nnode
;
3332 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3333 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3334 && !CHECK_FLAG(peer
->sflags
,
3335 PEER_STATUS_ACCEPT_PEER
))
3337 } else if (bm
->bgp
!= NULL
) {
3338 struct listnode
*bgpnode
, *nbgpnode
;
3340 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3341 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3343 && !strcmp(peer
->conf_if
, conf_if
)
3344 && !CHECK_FLAG(peer
->sflags
,
3345 PEER_STATUS_ACCEPT_PEER
))
3351 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3354 struct listnode
*node
, *nnode
;
3360 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3361 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3362 && !CHECK_FLAG(peer
->sflags
,
3363 PEER_STATUS_ACCEPT_PEER
))
3365 } else if (bm
->bgp
!= NULL
) {
3366 struct listnode
*bgpnode
, *nbgpnode
;
3368 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3369 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3371 && !strcmp(peer
->hostname
, hostname
)
3372 && !CHECK_FLAG(peer
->sflags
,
3373 PEER_STATUS_ACCEPT_PEER
))
3379 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3381 struct peer
*peer
= NULL
;
3382 struct peer tmp_peer
;
3384 memset(&tmp_peer
, 0, sizeof(struct peer
));
3387 * We do not want to find the doppelganger peer so search for the peer
3389 * the hash that has PEER_FLAG_CONFIG_NODE
3391 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3396 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3397 } else if (bm
->bgp
!= NULL
) {
3398 struct listnode
*bgpnode
, *nbgpnode
;
3400 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3401 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3410 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3411 union sockunion
*su
,
3412 struct peer_group
*group
)
3418 /* Create peer first; we've already checked group config is valid. */
3419 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3420 group
->conf
->as_type
, 0, 0, group
);
3425 peer
= peer_lock(peer
);
3426 listnode_add(group
->peer
, peer
);
3428 peer_group2peer_config_copy(group
, peer
);
3431 * Bind peer for all AFs configured for the group. We don't call
3432 * peer_group_bind as that is sub-optimal and does some stuff we don't
3435 FOREACH_AFI_SAFI (afi
, safi
) {
3436 if (!group
->conf
->afc
[afi
][safi
])
3438 peer
->afc
[afi
][safi
] = 1;
3440 if (!peer_af_find(peer
, afi
, safi
))
3441 peer_af_create(peer
, afi
, safi
);
3443 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3446 /* Mark as dynamic, but also as a "config node" for other things to
3448 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3449 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3455 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3456 struct prefix
*prefix
)
3458 struct listnode
*node
, *nnode
;
3459 struct prefix
*range
;
3462 afi
= family2afi(prefix
->family
);
3464 if (group
->listen_range
[afi
])
3465 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3467 if (prefix_match(range
, prefix
))
3474 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3475 struct prefix
**listen_range
)
3477 struct prefix
*range
= NULL
;
3478 struct peer_group
*group
= NULL
;
3479 struct listnode
*node
, *nnode
;
3481 *listen_range
= NULL
;
3483 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3484 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3487 } else if (bm
->bgp
!= NULL
) {
3488 struct listnode
*bgpnode
, *nbgpnode
;
3490 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3491 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3492 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3498 *listen_range
= range
;
3499 return (group
&& range
) ? group
: NULL
;
3502 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3504 struct peer_group
*group
;
3507 struct prefix prefix
;
3508 struct prefix
*listen_range
;
3510 char buf
[PREFIX2STR_BUFFER
];
3511 char buf1
[PREFIX2STR_BUFFER
];
3513 sockunion2hostprefix(su
, &prefix
);
3515 /* See if incoming connection matches a configured listen range. */
3516 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3527 prefix2str(&prefix
, buf
, sizeof(buf
));
3528 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3530 if (bgp_debug_neighbor_events(NULL
))
3532 "Dynamic Neighbor %s matches group %s listen range %s",
3533 buf
, group
->name
, buf1
);
3535 /* Are we within the listen limit? */
3536 dncount
= gbgp
->dynamic_neighbors_count
;
3538 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3539 if (bgp_debug_neighbor_events(NULL
))
3540 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3541 inet_sutop(su
, buf
),
3542 gbgp
->dynamic_neighbors_limit
);
3546 /* Ensure group is not disabled. */
3547 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3548 if (bgp_debug_neighbor_events(NULL
))
3550 "Dynamic Neighbor %s rejected - group %s disabled",
3555 /* Check that at least one AF is activated for the group. */
3556 if (!peer_group_af_configured(group
)) {
3557 if (bgp_debug_neighbor_events(NULL
))
3559 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3564 /* Create dynamic peer and bind to associated group. */
3565 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3568 gbgp
->dynamic_neighbors_count
= ++dncount
;
3570 if (bgp_debug_neighbor_events(peer
))
3571 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3572 peer
->host
, group
->name
, dncount
);
3577 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3580 if (peer
->group
->bgp
) {
3581 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3583 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3585 if (bgp_debug_neighbor_events(peer
))
3586 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3587 peer
->group
->name
, dncount
);
3590 /* If peer is configured at least one address family return 1. */
3591 int peer_active(struct peer
*peer
)
3593 if (BGP_PEER_SU_UNSPEC(peer
))
3595 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3596 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3597 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3598 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3599 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3600 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3601 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3602 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3603 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3604 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3605 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3610 /* If peer is negotiated at least one address family return 1. */
3611 int peer_active_nego(struct peer
*peer
)
3613 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3614 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3615 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3616 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3617 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3618 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3619 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3620 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3621 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3622 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3623 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3624 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3625 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3630 /* peer_flag_change_type. */
3631 enum peer_change_type
{
3634 peer_change_reset_in
,
3635 peer_change_reset_out
,
3638 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3639 enum peer_change_type type
)
3641 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3644 if (peer
->status
!= Established
)
3647 if (type
== peer_change_reset
) {
3648 /* If we're resetting session, we've to delete both peer struct
3650 if ((peer
->doppelganger
)
3651 && (peer
->doppelganger
->status
!= Deleted
)
3652 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3653 PEER_FLAG_CONFIG_NODE
)))
3654 peer_delete(peer
->doppelganger
);
3656 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3657 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3658 } else if (type
== peer_change_reset_in
) {
3659 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3660 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3661 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3663 if ((peer
->doppelganger
)
3664 && (peer
->doppelganger
->status
!= Deleted
)
3665 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3666 PEER_FLAG_CONFIG_NODE
)))
3667 peer_delete(peer
->doppelganger
);
3669 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3670 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3672 } else if (type
== peer_change_reset_out
) {
3673 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3674 bgp_announce_route(peer
, afi
, safi
);
3678 struct peer_flag_action
{
3682 /* This flag can be set for peer-group member. */
3683 uint8_t not_for_member
;
3685 /* Action when the flag is changed. */
3686 enum peer_change_type type
;
3689 static const struct peer_flag_action peer_flag_action_list
[] = {
3690 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3691 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3692 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3693 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3694 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3695 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3696 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3697 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3698 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3699 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3700 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3701 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3702 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3703 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3704 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3705 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3706 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3709 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3710 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3711 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3712 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3713 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3714 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3715 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3716 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3717 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3718 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3719 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3720 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3721 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3722 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3723 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3724 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3725 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3726 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3727 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3728 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3729 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3730 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3731 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3732 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3733 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3734 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3735 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3736 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3739 /* Proper action set. */
3740 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3741 int size
, struct peer_flag_action
*action
,
3748 const struct peer_flag_action
*match
= NULL
;
3750 /* Check peer's frag action. */
3751 for (i
= 0; i
< size
; i
++) {
3752 match
= &action_list
[i
];
3754 if (match
->flag
== 0)
3757 if (match
->flag
& flag
) {
3760 if (match
->type
== peer_change_reset_in
)
3762 if (match
->type
== peer_change_reset_out
)
3764 if (match
->type
== peer_change_reset
) {
3768 if (match
->not_for_member
)
3769 action
->not_for_member
= 1;
3773 /* Set peer clear type. */
3774 if (reset_in
&& reset_out
)
3775 action
->type
= peer_change_reset
;
3777 action
->type
= peer_change_reset_in
;
3779 action
->type
= peer_change_reset_out
;
3781 action
->type
= peer_change_none
;
3786 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3788 if (flag
== PEER_FLAG_SHUTDOWN
) {
3789 if (CHECK_FLAG(peer
->flags
, flag
)) {
3790 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3791 peer_nsf_stop(peer
);
3793 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3794 if (peer
->t_pmax_restart
) {
3795 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3796 if (bgp_debug_neighbor_events(peer
))
3798 "%s Maximum-prefix restart timer canceled",
3802 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3803 peer_nsf_stop(peer
);
3805 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3806 char *msg
= peer
->tx_shutdown_message
;
3809 if (!msg
&& peer_group_active(peer
))
3810 msg
= peer
->group
->conf
3811 ->tx_shutdown_message
;
3812 msglen
= msg
? strlen(msg
) : 0;
3817 uint8_t msgbuf
[129];
3820 memcpy(msgbuf
+ 1, msg
, msglen
);
3822 bgp_notify_send_with_data(
3823 peer
, BGP_NOTIFY_CEASE
,
3824 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3825 msgbuf
, msglen
+ 1);
3828 peer
, BGP_NOTIFY_CEASE
,
3829 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3831 bgp_session_reset(peer
);
3833 peer
->v_start
= BGP_INIT_START_TIMER
;
3834 BGP_EVENT_ADD(peer
, BGP_Stop
);
3836 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3837 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3838 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3839 else if (flag
== PEER_FLAG_PASSIVE
)
3840 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3841 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3842 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3844 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3845 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3847 bgp_session_reset(peer
);
3850 /* Change specified peer flag. */
3851 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3855 bool invert
, member_invert
;
3856 struct peer
*member
;
3857 struct listnode
*node
, *nnode
;
3858 struct peer_flag_action action
;
3860 memset(&action
, 0, sizeof(struct peer_flag_action
));
3861 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3863 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3864 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3867 /* Abort if no flag action exists. */
3869 return BGP_ERR_INVALID_FLAG
;
3871 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3872 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3873 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3874 return BGP_ERR_PEER_FLAG_CONFLICT
;
3876 /* Handle flag updates where desired state matches current state. */
3877 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3878 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3879 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3883 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3884 COND_FLAG(peer
->flags_override
, flag
, invert
);
3889 /* Inherit from peer-group or set/unset flags accordingly. */
3890 if (peer_group_active(peer
) && set
== invert
)
3891 peer_flag_inherit(peer
, flag
);
3893 COND_FLAG(peer
->flags
, flag
, set
);
3895 /* Check if handling a regular peer. */
3896 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3897 /* Update flag override state accordingly. */
3898 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3900 /* Execute flag action on peer. */
3901 if (action
.type
== peer_change_reset
)
3902 peer_flag_modify_action(peer
, flag
);
3904 /* Skip peer-group mechanics for regular peers. */
3909 * Update peer-group members, unless they are explicitely overriding
3910 * peer-group configuration.
3912 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3913 /* Skip peers with overridden configuration. */
3914 if (CHECK_FLAG(member
->flags_override
, flag
))
3917 /* Check if only member without group is inverted. */
3919 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3921 /* Skip peers with equivalent configuration. */
3922 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3925 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3928 /* Update flag on peer-group member. */
3929 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3931 /* Execute flag action on peer-group member. */
3932 if (action
.type
== peer_change_reset
)
3933 peer_flag_modify_action(member
, flag
);
3939 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3941 return peer_flag_modify(peer
, flag
, 1);
3944 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3946 return peer_flag_modify(peer
, flag
, 0);
3949 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3950 uint32_t flag
, bool set
)
3954 int addpath_tx_used
;
3955 bool invert
, member_invert
;
3957 struct peer
*member
;
3958 struct listnode
*node
, *nnode
;
3959 struct peer_flag_action action
;
3961 memset(&action
, 0, sizeof(struct peer_flag_action
));
3962 size
= sizeof peer_af_flag_action_list
3963 / sizeof(struct peer_flag_action
);
3965 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
3966 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3969 /* Abort if flag action exists. */
3971 return BGP_ERR_INVALID_FLAG
;
3973 /* Special check for reflector client. */
3974 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3975 && peer_sort(peer
) != BGP_PEER_IBGP
)
3976 return BGP_ERR_NOT_INTERNAL_PEER
;
3978 /* Special check for remove-private-AS. */
3979 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3980 && peer_sort(peer
) == BGP_PEER_IBGP
)
3981 return BGP_ERR_REMOVE_PRIVATE_AS
;
3983 /* as-override is not allowed for IBGP peers */
3984 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3985 return BGP_ERR_AS_OVERRIDE
;
3987 /* Handle flag updates where desired state matches current state. */
3988 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3989 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3990 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
3995 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
3996 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4003 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4004 * if we are setting/unsetting flags which conflict with this flag
4005 * handle accordingly
4007 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4011 * if we are setting NEXTHOP_SELF, we need to unset the
4012 * NEXTHOP_UNCHANGED flag
4014 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4015 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4016 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4017 PEER_FLAG_NEXTHOP_UNCHANGED
);
4021 * if we are unsetting NEXTHOP_SELF, we need to set the
4022 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4024 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4025 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4026 SET_FLAG(peer
->af_flags
[afi
][safi
],
4027 PEER_FLAG_NEXTHOP_UNCHANGED
);
4031 /* Inherit from peer-group or set/unset flags accordingly. */
4032 if (peer_group_active(peer
) && set
== invert
)
4033 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4035 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4037 /* Execute action when peer is established. */
4038 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4039 && peer
->status
== Established
) {
4040 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4041 bgp_clear_adj_in(peer
, afi
, safi
);
4043 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4044 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4045 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4046 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4047 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4048 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4049 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4050 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4052 peer_change_action(peer
, afi
, safi
, action
.type
);
4056 /* Check if handling a regular peer. */
4057 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4058 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4062 * Update peer-group members, unless they are explicitely
4063 * overriding peer-group configuration.
4065 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4067 /* Skip peers with overridden configuration. */
4068 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4072 /* Check if only member without group is inverted. */
4074 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4078 /* Skip peers with equivalent configuration. */
4079 if (set
!= member_invert
4080 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4083 if (set
== member_invert
4084 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4087 /* Update flag on peer-group member. */
4088 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4089 set
!= member_invert
);
4091 /* Execute flag action on peer-group member. */
4092 if (member
->status
== Established
) {
4093 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4094 bgp_clear_adj_in(member
, afi
, safi
);
4096 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4097 member
->last_reset
=
4098 PEER_DOWN_RR_CLIENT_CHANGE
;
4100 == PEER_FLAG_RSERVER_CLIENT
)
4101 member
->last_reset
=
4102 PEER_DOWN_RS_CLIENT_CHANGE
;
4104 == PEER_FLAG_ORF_PREFIX_SM
)
4105 member
->last_reset
=
4106 PEER_DOWN_CAPABILITY_CHANGE
;
4108 == PEER_FLAG_ORF_PREFIX_RM
)
4109 member
->last_reset
=
4110 PEER_DOWN_CAPABILITY_CHANGE
;
4112 peer_change_action(member
, afi
, safi
,
4119 /* Track if addpath TX is in use */
4120 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4121 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4123 addpath_tx_used
= 0;
4126 addpath_tx_used
= 1;
4128 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4129 if (!bgp_flag_check(
4130 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4132 "%s: enabling bgp deterministic-med, this is required"
4133 " for addpath-tx-bestpath-per-AS",
4137 BGP_FLAG_DETERMINISTIC_MED
);
4138 bgp_recalculate_all_bestpaths(bgp
);
4142 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4144 if (CHECK_FLAG(member
->af_flags
[afi
][safi
],
4145 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4147 member
->af_flags
[afi
][safi
],
4148 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4149 addpath_tx_used
= 1;
4155 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4161 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4163 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4166 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4168 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4172 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4174 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4175 peer
->tx_shutdown_message
=
4176 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4180 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4182 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4187 /* EBGP multihop configuration. */
4188 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4190 struct peer_group
*group
;
4191 struct listnode
*node
, *nnode
;
4194 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4197 /* see comment in peer_ttl_security_hops_set() */
4198 if (ttl
!= MAXTTL
) {
4199 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4200 group
= peer
->group
;
4201 if (group
->conf
->gtsm_hops
!= 0)
4202 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4204 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4206 if (peer1
->sort
== BGP_PEER_IBGP
)
4209 if (peer1
->gtsm_hops
!= 0)
4210 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4213 if (peer
->gtsm_hops
!= 0)
4214 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4220 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4221 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4222 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4223 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4224 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4226 bgp_session_reset(peer
);
4229 group
= peer
->group
;
4230 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4231 if (peer
->sort
== BGP_PEER_IBGP
)
4234 peer
->ttl
= group
->conf
->ttl
;
4236 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4237 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4238 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4240 bgp_session_reset(peer
);
4246 int peer_ebgp_multihop_unset(struct peer
*peer
)
4248 struct peer_group
*group
;
4249 struct listnode
*node
, *nnode
;
4251 if (peer
->sort
== BGP_PEER_IBGP
)
4254 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4255 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4257 if (peer_group_active(peer
))
4258 peer
->ttl
= peer
->group
->conf
->ttl
;
4262 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4263 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4265 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4267 bgp_session_reset(peer
);
4269 group
= peer
->group
;
4270 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4271 if (peer
->sort
== BGP_PEER_IBGP
)
4276 if (peer
->fd
>= 0) {
4277 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4279 peer
, BGP_NOTIFY_CEASE
,
4280 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4282 bgp_session_reset(peer
);
4289 /* Neighbor description. */
4290 int peer_description_set(struct peer
*peer
, const char *desc
)
4293 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4295 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4300 int peer_description_unset(struct peer
*peer
)
4303 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4310 /* Neighbor update-source. */
4311 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4313 struct peer
*member
;
4314 struct listnode
*node
, *nnode
;
4316 /* Set flag and configuration on peer. */
4317 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4318 if (peer
->update_if
) {
4319 if (strcmp(peer
->update_if
, ifname
) == 0)
4321 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4323 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4324 sockunion_free(peer
->update_source
);
4325 peer
->update_source
= NULL
;
4327 /* Check if handling a regular peer. */
4328 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4329 /* Send notification or reset peer depending on state. */
4330 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4331 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4332 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4333 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4335 bgp_session_reset(peer
);
4337 /* Skip peer-group mechanics for regular peers. */
4342 * Set flag and configuration on all peer-group members, unless they are
4343 * explicitely overriding peer-group configuration.
4345 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4346 /* Skip peers with overridden configuration. */
4347 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4350 /* Skip peers with the same configuration. */
4351 if (member
->update_if
) {
4352 if (strcmp(member
->update_if
, ifname
) == 0)
4354 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4357 /* Set flag and configuration on peer-group member. */
4358 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4359 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4360 sockunion_free(member
->update_source
);
4361 member
->update_source
= NULL
;
4363 /* Send notification or reset peer depending on state. */
4364 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4365 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4366 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4367 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4369 bgp_session_reset(member
);
4375 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4377 struct peer
*member
;
4378 struct listnode
*node
, *nnode
;
4380 /* Set flag and configuration on peer. */
4381 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4382 if (peer
->update_source
) {
4383 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4385 sockunion_free(peer
->update_source
);
4387 peer
->update_source
= sockunion_dup(su
);
4388 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4390 /* Check if handling a regular peer. */
4391 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4392 /* Send notification or reset peer depending on state. */
4393 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4394 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4395 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4396 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4398 bgp_session_reset(peer
);
4400 /* Skip peer-group mechanics for regular peers. */
4405 * Set flag and configuration on all peer-group members, unless they are
4406 * explicitely overriding peer-group configuration.
4408 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4409 /* Skip peers with overridden configuration. */
4410 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4413 /* Skip peers with the same configuration. */
4414 if (member
->update_source
) {
4415 if (sockunion_cmp(member
->update_source
, su
) == 0)
4417 sockunion_free(member
->update_source
);
4420 /* Set flag and configuration on peer-group member. */
4421 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4422 member
->update_source
= sockunion_dup(su
);
4423 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4425 /* Send notification or reset peer depending on state. */
4426 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4427 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4428 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4429 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4431 bgp_session_reset(member
);
4437 int peer_update_source_unset(struct peer
*peer
)
4439 struct peer
*member
;
4440 struct listnode
*node
, *nnode
;
4442 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4445 /* Inherit configuration from peer-group if peer is member. */
4446 if (peer_group_active(peer
)) {
4447 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4448 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4449 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4450 MTYPE_PEER_UPDATE_SOURCE
);
4452 /* Otherwise remove flag and configuration from peer. */
4453 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4454 sockunion_free(peer
->update_source
);
4455 peer
->update_source
= NULL
;
4456 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4459 /* Check if handling a regular peer. */
4460 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4461 /* Send notification or reset peer depending on state. */
4462 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4463 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4464 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4465 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4467 bgp_session_reset(peer
);
4469 /* Skip peer-group mechanics for regular peers. */
4474 * Set flag and configuration on all peer-group members, unless they are
4475 * explicitely overriding peer-group configuration.
4477 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4478 /* Skip peers with overridden configuration. */
4479 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4482 /* Skip peers with the same configuration. */
4483 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4484 && !member
->update_source
&& !member
->update_if
)
4487 /* Remove flag and configuration on peer-group member. */
4488 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4489 sockunion_free(member
->update_source
);
4490 member
->update_source
= NULL
;
4491 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4493 /* Send notification or reset peer depending on state. */
4494 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4495 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4496 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4497 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4499 bgp_session_reset(member
);
4505 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4506 const char *rmap
, struct route_map
*route_map
)
4508 struct peer
*member
;
4509 struct listnode
*node
, *nnode
;
4511 /* Set flag and configuration on peer. */
4512 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4514 if (!peer
->default_rmap
[afi
][safi
].name
4515 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4516 if (peer
->default_rmap
[afi
][safi
].name
)
4517 XFREE(MTYPE_ROUTE_MAP_NAME
,
4518 peer
->default_rmap
[afi
][safi
].name
);
4520 peer
->default_rmap
[afi
][safi
].name
=
4521 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4522 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4525 if (peer
->default_rmap
[afi
][safi
].name
)
4526 XFREE(MTYPE_ROUTE_MAP_NAME
,
4527 peer
->default_rmap
[afi
][safi
].name
);
4529 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4530 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4533 /* Check if handling a regular peer. */
4534 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4535 /* Update peer route announcements. */
4536 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4537 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4538 bgp_default_originate(peer
, afi
, safi
, 0);
4539 bgp_announce_route(peer
, afi
, safi
);
4542 /* Skip peer-group mechanics for regular peers. */
4547 * Set flag and configuration on all peer-group members, unless they are
4548 * explicitely overriding peer-group configuration.
4550 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4551 /* Skip peers with overridden configuration. */
4552 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4553 PEER_FLAG_DEFAULT_ORIGINATE
))
4556 /* Set flag and configuration on peer-group member. */
4557 SET_FLAG(member
->af_flags
[afi
][safi
],
4558 PEER_FLAG_DEFAULT_ORIGINATE
);
4560 if (member
->default_rmap
[afi
][safi
].name
)
4561 XFREE(MTYPE_ROUTE_MAP_NAME
,
4562 member
->default_rmap
[afi
][safi
].name
);
4564 member
->default_rmap
[afi
][safi
].name
=
4565 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4566 member
->default_rmap
[afi
][safi
].map
= route_map
;
4569 /* Update peer route announcements. */
4570 if (member
->status
== Established
4571 && member
->afc_nego
[afi
][safi
]) {
4572 update_group_adjust_peer(
4573 peer_af_find(member
, afi
, safi
));
4574 bgp_default_originate(member
, afi
, safi
, 0);
4575 bgp_announce_route(member
, afi
, safi
);
4582 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4584 struct peer
*member
;
4585 struct listnode
*node
, *nnode
;
4587 /* Inherit configuration from peer-group if peer is member. */
4588 if (peer_group_active(peer
)) {
4589 peer_af_flag_inherit(peer
, afi
, safi
,
4590 PEER_FLAG_DEFAULT_ORIGINATE
);
4591 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4592 default_rmap
[afi
][safi
].name
,
4593 MTYPE_ROUTE_MAP_NAME
);
4594 PEER_ATTR_INHERIT(peer
, peer
->group
,
4595 default_rmap
[afi
][safi
].map
);
4597 /* Otherwise remove flag and configuration from peer. */
4598 peer_af_flag_unset(peer
, afi
, safi
,
4599 PEER_FLAG_DEFAULT_ORIGINATE
);
4600 if (peer
->default_rmap
[afi
][safi
].name
)
4601 XFREE(MTYPE_ROUTE_MAP_NAME
,
4602 peer
->default_rmap
[afi
][safi
].name
);
4603 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4604 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4607 /* Check if handling a regular peer. */
4608 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4609 /* Update peer route announcements. */
4610 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4611 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4612 bgp_default_originate(peer
, afi
, safi
, 1);
4613 bgp_announce_route(peer
, afi
, safi
);
4616 /* Skip peer-group mechanics for regular peers. */
4621 * Remove flag and configuration from all peer-group members, unless
4622 * they are explicitely overriding peer-group configuration.
4624 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4625 /* Skip peers with overridden configuration. */
4626 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4627 PEER_FLAG_DEFAULT_ORIGINATE
))
4630 /* Remove flag and configuration on peer-group member. */
4631 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4632 PEER_FLAG_DEFAULT_ORIGINATE
);
4633 if (peer
->default_rmap
[afi
][safi
].name
)
4634 XFREE(MTYPE_ROUTE_MAP_NAME
,
4635 peer
->default_rmap
[afi
][safi
].name
);
4636 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4637 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4639 /* Update peer route announcements. */
4640 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4641 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4642 bgp_default_originate(peer
, afi
, safi
, 1);
4643 bgp_announce_route(peer
, afi
, safi
);
4650 int peer_port_set(struct peer
*peer
, uint16_t port
)
4656 int peer_port_unset(struct peer
*peer
)
4658 peer
->port
= BGP_PORT_DEFAULT
;
4663 * Helper function that is called after the name of the policy
4664 * being used by a peer has changed (AF specific). Automatically
4665 * initiates inbound or outbound processing as needed.
4667 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4671 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4672 if (peer
->status
== Established
)
4673 bgp_announce_route(peer
, afi
, safi
);
4675 if (peer
->status
!= Established
)
4678 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4679 PEER_FLAG_SOFT_RECONFIG
))
4680 bgp_soft_reconfig_in(peer
, afi
, safi
);
4681 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4682 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4683 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4688 /* neighbor weight. */
4689 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4691 struct peer
*member
;
4692 struct listnode
*node
, *nnode
;
4694 /* Set flag and configuration on peer. */
4695 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4696 if (peer
->weight
[afi
][safi
] != weight
) {
4697 peer
->weight
[afi
][safi
] = weight
;
4698 peer_on_policy_change(peer
, afi
, safi
, 0);
4701 /* Skip peer-group mechanics for regular peers. */
4702 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4706 * Set flag and configuration on all peer-group members, unless they are
4707 * explicitely overriding peer-group configuration.
4709 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4710 /* Skip peers with overridden configuration. */
4711 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4715 /* Set flag and configuration on peer-group member. */
4716 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4717 if (member
->weight
[afi
][safi
] != weight
) {
4718 member
->weight
[afi
][safi
] = weight
;
4719 peer_on_policy_change(member
, afi
, safi
, 0);
4726 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4728 struct peer
*member
;
4729 struct listnode
*node
, *nnode
;
4731 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4734 /* Inherit configuration from peer-group if peer is member. */
4735 if (peer_group_active(peer
)) {
4736 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4737 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4739 peer_on_policy_change(peer
, afi
, safi
, 0);
4743 /* Remove flag and configuration from peer. */
4744 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4745 peer
->weight
[afi
][safi
] = 0;
4746 peer_on_policy_change(peer
, afi
, safi
, 0);
4748 /* Skip peer-group mechanics for regular peers. */
4749 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4753 * Remove flag and configuration from all peer-group members, unless
4754 * they are explicitely overriding peer-group configuration.
4756 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4757 /* Skip peers with overridden configuration. */
4758 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4762 /* Skip peers where flag is already disabled. */
4763 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4766 /* Remove flag and configuration on peer-group member. */
4767 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4768 member
->weight
[afi
][safi
] = 0;
4769 peer_on_policy_change(member
, afi
, safi
, 0);
4775 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4777 struct peer
*member
;
4778 struct listnode
*node
, *nnode
;
4780 if (keepalive
> 65535)
4781 return BGP_ERR_INVALID_VALUE
;
4783 if (holdtime
> 65535)
4784 return BGP_ERR_INVALID_VALUE
;
4786 if (holdtime
< 3 && holdtime
!= 0)
4787 return BGP_ERR_INVALID_VALUE
;
4789 /* Set flag and configuration on peer. */
4790 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4791 peer
->holdtime
= holdtime
;
4792 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4794 /* Skip peer-group mechanics for regular peers. */
4795 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4799 * Set flag and configuration on all peer-group members, unless they are
4800 * explicitely overriding peer-group configuration.
4802 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4803 /* Skip peers with overridden configuration. */
4804 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4807 /* Set flag and configuration on peer-group member. */
4808 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4809 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4810 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4816 int peer_timers_unset(struct peer
*peer
)
4818 struct peer
*member
;
4819 struct listnode
*node
, *nnode
;
4821 /* Inherit configuration from peer-group if peer is member. */
4822 if (peer_group_active(peer
)) {
4823 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4824 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4825 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4827 /* Otherwise remove flag and configuration from peer. */
4828 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4830 peer
->keepalive
= 0;
4833 /* Skip peer-group mechanics for regular peers. */
4834 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4838 * Remove flag and configuration from all peer-group members, unless
4839 * they are explicitely overriding peer-group configuration.
4841 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4842 /* Skip peers with overridden configuration. */
4843 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4846 /* Remove flag and configuration on peer-group member. */
4847 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4848 member
->holdtime
= 0;
4849 member
->keepalive
= 0;
4855 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4857 struct peer
*member
;
4858 struct listnode
*node
, *nnode
;
4860 if (connect
> 65535)
4861 return BGP_ERR_INVALID_VALUE
;
4863 /* Set flag and configuration on peer. */
4864 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4865 peer
->connect
= connect
;
4866 peer
->v_connect
= connect
;
4868 /* Skip peer-group mechanics for regular peers. */
4869 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4873 * Set flag and configuration on all peer-group members, unless they are
4874 * explicitely overriding peer-group configuration.
4876 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4877 /* Skip peers with overridden configuration. */
4878 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4881 /* Set flag and configuration on peer-group member. */
4882 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4883 member
->connect
= connect
;
4884 member
->v_connect
= connect
;
4890 int peer_timers_connect_unset(struct peer
*peer
)
4892 struct peer
*member
;
4893 struct listnode
*node
, *nnode
;
4895 /* Inherit configuration from peer-group if peer is member. */
4896 if (peer_group_active(peer
)) {
4897 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4898 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4900 /* Otherwise remove flag and configuration from peer. */
4901 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4905 /* Set timer with fallback to default value. */
4907 peer
->v_connect
= peer
->connect
;
4909 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4911 /* Skip peer-group mechanics for regular peers. */
4912 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4916 * Remove flag and configuration from all peer-group members, unless
4917 * they are explicitely overriding peer-group configuration.
4919 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4920 /* Skip peers with overridden configuration. */
4921 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4924 /* Remove flag and configuration on peer-group member. */
4925 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4926 member
->connect
= 0;
4927 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4933 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4935 struct peer
*member
;
4936 struct listnode
*node
, *nnode
;
4939 return BGP_ERR_INVALID_VALUE
;
4941 /* Set flag and configuration on peer. */
4942 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4943 peer
->routeadv
= routeadv
;
4944 peer
->v_routeadv
= routeadv
;
4946 /* Check if handling a regular peer. */
4947 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4948 /* Update peer route announcements. */
4949 update_group_adjust_peer_afs(peer
);
4950 if (peer
->status
== Established
)
4951 bgp_announce_route_all(peer
);
4953 /* Skip peer-group mechanics for regular peers. */
4958 * Set flag and configuration on all peer-group members, unless they are
4959 * explicitely overriding peer-group configuration.
4961 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4962 /* Skip peers with overridden configuration. */
4963 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4966 /* Set flag and configuration on peer-group member. */
4967 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4968 member
->routeadv
= routeadv
;
4969 member
->v_routeadv
= routeadv
;
4971 /* Update peer route announcements. */
4972 update_group_adjust_peer_afs(member
);
4973 if (member
->status
== Established
)
4974 bgp_announce_route_all(member
);
4980 int peer_advertise_interval_unset(struct peer
*peer
)
4982 struct peer
*member
;
4983 struct listnode
*node
, *nnode
;
4985 /* Inherit configuration from peer-group if peer is member. */
4986 if (peer_group_active(peer
)) {
4987 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4988 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4990 /* Otherwise remove flag and configuration from peer. */
4991 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
4995 /* Set timer with fallback to default value. */
4997 peer
->v_routeadv
= peer
->routeadv
;
4999 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5000 ? BGP_DEFAULT_IBGP_ROUTEADV
5001 : BGP_DEFAULT_EBGP_ROUTEADV
;
5003 /* Check if handling a regular peer. */
5004 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5005 /* Update peer route announcements. */
5006 update_group_adjust_peer_afs(peer
);
5007 if (peer
->status
== Established
)
5008 bgp_announce_route_all(peer
);
5010 /* Skip peer-group mechanics for regular peers. */
5015 * Remove flag and configuration from all peer-group members, unless
5016 * they are explicitely overriding peer-group configuration.
5018 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5019 /* Skip peers with overridden configuration. */
5020 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5023 /* Remove flag and configuration on peer-group member. */
5024 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5025 member
->routeadv
= 0;
5026 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5027 ? BGP_DEFAULT_IBGP_ROUTEADV
5028 : BGP_DEFAULT_EBGP_ROUTEADV
;
5030 /* Update peer route announcements. */
5031 update_group_adjust_peer_afs(member
);
5032 if (member
->status
== Established
)
5033 bgp_announce_route_all(member
);
5039 /* neighbor interface */
5040 void peer_interface_set(struct peer
*peer
, const char *str
)
5043 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5044 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5047 void peer_interface_unset(struct peer
*peer
)
5050 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5051 peer
->ifname
= NULL
;
5055 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5056 int allow_num
, int origin
)
5058 struct peer
*member
;
5059 struct listnode
*node
, *nnode
;
5061 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5062 return BGP_ERR_INVALID_VALUE
;
5064 /* Set flag and configuration on peer. */
5065 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5067 if (peer
->allowas_in
[afi
][safi
] != 0
5068 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5069 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5070 peer_af_flag_set(peer
, afi
, safi
,
5071 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5072 peer
->allowas_in
[afi
][safi
] = 0;
5073 peer_on_policy_change(peer
, afi
, safi
, 0);
5076 if (peer
->allowas_in
[afi
][safi
] != allow_num
5077 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5078 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5080 peer_af_flag_unset(peer
, afi
, safi
,
5081 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5082 peer
->allowas_in
[afi
][safi
] = allow_num
;
5083 peer_on_policy_change(peer
, afi
, safi
, 0);
5087 /* Skip peer-group mechanics for regular peers. */
5088 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5092 * Set flag and configuration on all peer-group members, unless
5093 * they are explicitely overriding peer-group configuration.
5095 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5096 /* Skip peers with overridden configuration. */
5097 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5098 PEER_FLAG_ALLOWAS_IN
))
5101 /* Set flag and configuration on peer-group member. */
5102 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5104 if (member
->allowas_in
[afi
][safi
] != 0
5105 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5106 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5107 SET_FLAG(member
->af_flags
[afi
][safi
],
5108 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5109 member
->allowas_in
[afi
][safi
] = 0;
5110 peer_on_policy_change(peer
, afi
, safi
, 0);
5113 if (member
->allowas_in
[afi
][safi
] != allow_num
5114 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5115 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5116 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5117 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5118 member
->allowas_in
[afi
][safi
] = allow_num
;
5119 peer_on_policy_change(peer
, afi
, safi
, 0);
5127 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5129 struct peer
*member
;
5130 struct listnode
*node
, *nnode
;
5132 /* Skip peer if flag is already disabled. */
5133 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5136 /* Inherit configuration from peer-group if peer is member. */
5137 if (peer_group_active(peer
)) {
5138 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5139 peer_af_flag_inherit(peer
, afi
, safi
,
5140 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5141 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5142 peer_on_policy_change(peer
, afi
, safi
, 0);
5147 /* Remove flag and configuration from peer. */
5148 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5149 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5150 peer
->allowas_in
[afi
][safi
] = 0;
5151 peer_on_policy_change(peer
, afi
, safi
, 0);
5153 /* Skip peer-group mechanics if handling a regular peer. */
5154 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5158 * Remove flags and configuration from all peer-group members, unless
5159 * they are explicitely overriding peer-group configuration.
5161 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5162 /* Skip peers with overridden configuration. */
5163 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5164 PEER_FLAG_ALLOWAS_IN
))
5167 /* Skip peers where flag is already disabled. */
5168 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5169 PEER_FLAG_ALLOWAS_IN
))
5172 /* Remove flags and configuration on peer-group member. */
5173 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5174 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5175 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5176 member
->allowas_in
[afi
][safi
] = 0;
5177 peer_on_policy_change(member
, afi
, safi
, 0);
5183 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5186 bool old_no_prepend
, old_replace_as
;
5187 struct bgp
*bgp
= peer
->bgp
;
5188 struct peer
*member
;
5189 struct listnode
*node
, *nnode
;
5191 if (peer_sort(peer
) != BGP_PEER_EBGP
5192 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5193 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5196 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5199 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5201 /* Save previous flag states. */
5203 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5205 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5207 /* Set flag and configuration on peer. */
5208 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5209 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5210 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5212 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5213 && old_replace_as
== replace_as
)
5215 peer
->change_local_as
= as
;
5217 /* Check if handling a regular peer. */
5218 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5219 /* Send notification or reset peer depending on state. */
5220 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5221 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5222 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5223 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5225 bgp_session_reset(peer
);
5227 /* Skip peer-group mechanics for regular peers. */
5232 * Set flag and configuration on all peer-group members, unless they are
5233 * explicitely overriding peer-group configuration.
5235 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5236 /* Skip peers with overridden configuration. */
5237 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5240 /* Skip peers with the same configuration. */
5241 old_no_prepend
= CHECK_FLAG(member
->flags
,
5242 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5243 old_replace_as
= CHECK_FLAG(member
->flags
,
5244 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5245 if (member
->change_local_as
== as
5246 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5247 && old_no_prepend
== no_prepend
5248 && old_replace_as
== replace_as
)
5251 /* Set flag and configuration on peer-group member. */
5252 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5253 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5255 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5257 member
->change_local_as
= as
;
5259 /* Send notification or stop peer depending on state. */
5260 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5261 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5262 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5263 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5265 BGP_EVENT_ADD(member
, BGP_Stop
);
5271 int peer_local_as_unset(struct peer
*peer
)
5273 struct peer
*member
;
5274 struct listnode
*node
, *nnode
;
5276 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5279 /* Inherit configuration from peer-group if peer is member. */
5280 if (peer_group_active(peer
)) {
5281 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5282 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5283 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5284 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5286 /* Otherwise remove flag and configuration from peer. */
5287 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5288 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5289 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5290 peer
->change_local_as
= 0;
5293 /* Check if handling a regular peer. */
5294 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5295 /* Send notification or stop peer depending on state. */
5296 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5297 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5298 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5299 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5301 BGP_EVENT_ADD(peer
, BGP_Stop
);
5303 /* Skip peer-group mechanics for regular peers. */
5308 * Remove flag and configuration from all peer-group members, unless
5309 * they are explicitely overriding peer-group configuration.
5311 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5312 /* Skip peers with overridden configuration. */
5313 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5316 /* Remove flag and configuration on peer-group member. */
5317 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5318 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5319 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5320 member
->change_local_as
= 0;
5322 /* Send notification or stop peer depending on state. */
5323 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5324 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5325 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5328 bgp_session_reset(member
);
5334 /* Set password for authenticating with the peer. */
5335 int peer_password_set(struct peer
*peer
, const char *password
)
5337 struct peer
*member
;
5338 struct listnode
*node
, *nnode
;
5339 int len
= password
? strlen(password
) : 0;
5340 int ret
= BGP_SUCCESS
;
5342 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5343 return BGP_ERR_INVALID_VALUE
;
5345 /* Set flag and configuration on peer. */
5346 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5347 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5349 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5350 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5352 /* Check if handling a regular peer. */
5353 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5354 /* Send notification or reset peer depending on state. */
5355 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5356 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5357 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5359 bgp_session_reset(peer
);
5362 * Attempt to install password on socket and skip peer-group
5365 if (BGP_PEER_SU_UNSPEC(peer
))
5367 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5368 : BGP_ERR_TCPSIG_FAILED
;
5372 * Set flag and configuration on all peer-group members, unless they are
5373 * explicitely overriding peer-group configuration.
5375 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5376 /* Skip peers with overridden configuration. */
5377 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5380 /* Skip peers with the same password. */
5381 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5384 /* Set flag and configuration on peer-group member. */
5385 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5386 if (member
->password
)
5387 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5388 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5390 /* Send notification or reset peer depending on state. */
5391 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5392 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5393 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5395 bgp_session_reset(member
);
5397 /* Attempt to install password on socket. */
5398 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5399 ret
= BGP_ERR_TCPSIG_FAILED
;
5405 int peer_password_unset(struct peer
*peer
)
5407 struct peer
*member
;
5408 struct listnode
*node
, *nnode
;
5410 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5413 /* Inherit configuration from peer-group if peer is member. */
5414 if (peer_group_active(peer
)) {
5415 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5416 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5417 MTYPE_PEER_PASSWORD
);
5419 /* Otherwise remove flag and configuration from peer. */
5420 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5421 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5424 /* Check if handling a regular peer. */
5425 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5426 /* Send notification or reset peer depending on state. */
5427 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5428 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5429 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5431 bgp_session_reset(peer
);
5433 /* Attempt to uninstall password on socket. */
5434 if (!BGP_PEER_SU_UNSPEC(peer
))
5435 bgp_md5_unset(peer
);
5437 /* Skip peer-group mechanics for regular peers. */
5442 * Remove flag and configuration from all peer-group members, unless
5443 * they are explicitely overriding peer-group configuration.
5445 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5446 /* Skip peers with overridden configuration. */
5447 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5450 /* Remove flag and configuration on peer-group member. */
5451 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5452 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5454 /* Send notification or reset peer depending on state. */
5455 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5456 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5457 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5459 bgp_session_reset(member
);
5461 /* Attempt to uninstall password on socket. */
5462 if (!BGP_PEER_SU_UNSPEC(member
))
5463 bgp_md5_unset(member
);
5470 /* Set distribute list to the peer. */
5471 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5474 struct peer
*member
;
5475 struct bgp_filter
*filter
;
5476 struct listnode
*node
, *nnode
;
5478 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5479 return BGP_ERR_INVALID_VALUE
;
5481 /* Set configuration on peer. */
5482 filter
= &peer
->filter
[afi
][safi
];
5483 if (filter
->plist
[direct
].name
)
5484 return BGP_ERR_PEER_FILTER_CONFLICT
;
5485 if (filter
->dlist
[direct
].name
)
5486 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5487 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5488 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5490 /* Check if handling a regular peer. */
5491 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5492 /* Set override-flag and process peer route updates. */
5493 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5494 PEER_FT_DISTRIBUTE_LIST
);
5495 peer_on_policy_change(peer
, afi
, safi
,
5496 (direct
== FILTER_OUT
) ? 1 : 0);
5498 /* Skip peer-group mechanics for regular peers. */
5503 * Set configuration on all peer-group members, un less they are
5504 * explicitely overriding peer-group configuration.
5506 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5507 /* Skip peers with overridden configuration. */
5508 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5509 PEER_FT_DISTRIBUTE_LIST
))
5512 /* Set configuration on peer-group member. */
5513 filter
= &member
->filter
[afi
][safi
];
5514 if (filter
->dlist
[direct
].name
)
5515 XFREE(MTYPE_BGP_FILTER_NAME
,
5516 filter
->dlist
[direct
].name
);
5517 filter
->dlist
[direct
].name
=
5518 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5519 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5521 /* Process peer route updates. */
5522 peer_on_policy_change(member
, afi
, safi
,
5523 (direct
== FILTER_OUT
) ? 1 : 0);
5529 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5531 struct peer
*member
;
5532 struct bgp_filter
*filter
;
5533 struct listnode
*node
, *nnode
;
5535 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5536 return BGP_ERR_INVALID_VALUE
;
5538 /* Unset override-flag unconditionally. */
5539 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5540 PEER_FT_DISTRIBUTE_LIST
);
5542 /* Inherit configuration from peer-group if peer is member. */
5543 if (peer_group_active(peer
)) {
5544 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5545 filter
[afi
][safi
].dlist
[direct
].name
,
5546 MTYPE_BGP_FILTER_NAME
);
5547 PEER_ATTR_INHERIT(peer
, peer
->group
,
5548 filter
[afi
][safi
].dlist
[direct
].alist
);
5550 /* Otherwise remove configuration from peer. */
5551 filter
= &peer
->filter
[afi
][safi
];
5552 if (filter
->dlist
[direct
].name
)
5553 XFREE(MTYPE_BGP_FILTER_NAME
,
5554 filter
->dlist
[direct
].name
);
5555 filter
->dlist
[direct
].name
= NULL
;
5556 filter
->dlist
[direct
].alist
= NULL
;
5559 /* Check if handling a regular peer. */
5560 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5561 /* Process peer route updates. */
5562 peer_on_policy_change(peer
, afi
, safi
,
5563 (direct
== FILTER_OUT
) ? 1 : 0);
5565 /* Skip peer-group mechanics for regular peers. */
5570 * Remove configuration on all peer-group members, unless they are
5571 * explicitely overriding peer-group configuration.
5573 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5574 /* Skip peers with overridden configuration. */
5575 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5576 PEER_FT_DISTRIBUTE_LIST
))
5579 /* Remove configuration on peer-group member. */
5580 filter
= &member
->filter
[afi
][safi
];
5581 if (filter
->dlist
[direct
].name
)
5582 XFREE(MTYPE_BGP_FILTER_NAME
,
5583 filter
->dlist
[direct
].name
);
5584 filter
->dlist
[direct
].name
= NULL
;
5585 filter
->dlist
[direct
].alist
= NULL
;
5587 /* Process peer route updates. */
5588 peer_on_policy_change(member
, afi
, safi
,
5589 (direct
== FILTER_OUT
) ? 1 : 0);
5595 /* Update distribute list. */
5596 static void peer_distribute_update(struct access_list
*access
)
5601 struct listnode
*mnode
, *mnnode
;
5602 struct listnode
*node
, *nnode
;
5605 struct peer_group
*group
;
5606 struct bgp_filter
*filter
;
5608 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5610 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5611 access
->name
, 0, 0);
5612 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5613 FOREACH_AFI_SAFI (afi
, safi
) {
5614 filter
= &peer
->filter
[afi
][safi
];
5616 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5618 if (filter
->dlist
[direct
].name
)
5619 filter
->dlist
[direct
]
5620 .alist
= access_list_lookup(
5622 filter
->dlist
[direct
]
5625 filter
->dlist
[direct
].alist
=
5630 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5631 FOREACH_AFI_SAFI (afi
, safi
) {
5632 filter
= &group
->conf
->filter
[afi
][safi
];
5634 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5636 if (filter
->dlist
[direct
].name
)
5637 filter
->dlist
[direct
]
5638 .alist
= access_list_lookup(
5640 filter
->dlist
[direct
]
5643 filter
->dlist
[direct
].alist
=
5649 vnc_prefix_list_update(bgp
);
5654 /* Set prefix list to the peer. */
5655 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5658 struct peer
*member
;
5659 struct bgp_filter
*filter
;
5660 struct listnode
*node
, *nnode
;
5662 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5663 return BGP_ERR_INVALID_VALUE
;
5665 /* Set configuration on peer. */
5666 filter
= &peer
->filter
[afi
][safi
];
5667 if (filter
->dlist
[direct
].name
)
5668 return BGP_ERR_PEER_FILTER_CONFLICT
;
5669 if (filter
->plist
[direct
].name
)
5670 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5671 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5672 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5674 /* Check if handling a regular peer. */
5675 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5676 /* Set override-flag and process peer route updates. */
5677 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5678 PEER_FT_PREFIX_LIST
);
5679 peer_on_policy_change(peer
, afi
, safi
,
5680 (direct
== FILTER_OUT
) ? 1 : 0);
5682 /* Skip peer-group mechanics for regular peers. */
5687 * Set configuration on all peer-group members, unless they are
5688 * explicitely overriding peer-group configuration.
5690 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5691 /* Skip peers with overridden configuration. */
5692 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5693 PEER_FT_PREFIX_LIST
))
5696 /* Set configuration on peer-group member. */
5697 filter
= &member
->filter
[afi
][safi
];
5698 if (filter
->plist
[direct
].name
)
5699 XFREE(MTYPE_BGP_FILTER_NAME
,
5700 filter
->plist
[direct
].name
);
5701 filter
->plist
[direct
].name
=
5702 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5703 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5705 /* Process peer route updates. */
5706 peer_on_policy_change(member
, afi
, safi
,
5707 (direct
== FILTER_OUT
) ? 1 : 0);
5713 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5716 struct peer
*member
;
5717 struct bgp_filter
*filter
;
5718 struct listnode
*node
, *nnode
;
5720 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5721 return BGP_ERR_INVALID_VALUE
;
5723 /* Unset override-flag unconditionally. */
5724 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5725 PEER_FT_PREFIX_LIST
);
5727 /* Inherit configuration from peer-group if peer is member. */
5728 if (peer_group_active(peer
)) {
5729 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5730 filter
[afi
][safi
].plist
[direct
].name
,
5731 MTYPE_BGP_FILTER_NAME
);
5732 PEER_ATTR_INHERIT(peer
, peer
->group
,
5733 filter
[afi
][safi
].plist
[direct
].plist
);
5735 /* Otherwise remove configuration from peer. */
5736 filter
= &peer
->filter
[afi
][safi
];
5737 if (filter
->plist
[direct
].name
)
5738 XFREE(MTYPE_BGP_FILTER_NAME
,
5739 filter
->plist
[direct
].name
);
5740 filter
->plist
[direct
].name
= NULL
;
5741 filter
->plist
[direct
].plist
= NULL
;
5744 /* Check if handling a regular peer. */
5745 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5746 /* Process peer route updates. */
5747 peer_on_policy_change(peer
, afi
, safi
,
5748 (direct
== FILTER_OUT
) ? 1 : 0);
5750 /* Skip peer-group mechanics for regular peers. */
5755 * Remove configuration on all peer-group members, unless they are
5756 * explicitely overriding peer-group configuration.
5758 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5759 /* Skip peers with overridden configuration. */
5760 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5761 PEER_FT_PREFIX_LIST
))
5764 /* Remove configuration on peer-group member. */
5765 filter
= &member
->filter
[afi
][safi
];
5766 if (filter
->plist
[direct
].name
)
5767 XFREE(MTYPE_BGP_FILTER_NAME
,
5768 filter
->plist
[direct
].name
);
5769 filter
->plist
[direct
].name
= NULL
;
5770 filter
->plist
[direct
].plist
= NULL
;
5772 /* Process peer route updates. */
5773 peer_on_policy_change(member
, afi
, safi
,
5774 (direct
== FILTER_OUT
) ? 1 : 0);
5780 /* Update prefix-list list. */
5781 static void peer_prefix_list_update(struct prefix_list
*plist
)
5783 struct listnode
*mnode
, *mnnode
;
5784 struct listnode
*node
, *nnode
;
5787 struct peer_group
*group
;
5788 struct bgp_filter
*filter
;
5793 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5796 * Update the prefix-list on update groups.
5798 update_group_policy_update(
5799 bgp
, BGP_POLICY_PREFIX_LIST
,
5800 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5802 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5803 FOREACH_AFI_SAFI (afi
, safi
) {
5804 filter
= &peer
->filter
[afi
][safi
];
5806 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5808 if (filter
->plist
[direct
].name
)
5809 filter
->plist
[direct
]
5810 .plist
= prefix_list_lookup(
5812 filter
->plist
[direct
]
5815 filter
->plist
[direct
].plist
=
5820 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5821 FOREACH_AFI_SAFI (afi
, safi
) {
5822 filter
= &group
->conf
->filter
[afi
][safi
];
5824 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5826 if (filter
->plist
[direct
].name
)
5827 filter
->plist
[direct
]
5828 .plist
= prefix_list_lookup(
5830 filter
->plist
[direct
]
5833 filter
->plist
[direct
].plist
=
5841 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5844 struct peer
*member
;
5845 struct bgp_filter
*filter
;
5846 struct listnode
*node
, *nnode
;
5848 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5849 return BGP_ERR_INVALID_VALUE
;
5851 /* Set configuration on peer. */
5852 filter
= &peer
->filter
[afi
][safi
];
5853 if (filter
->aslist
[direct
].name
)
5854 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5855 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5856 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5858 /* Check if handling a regular peer. */
5859 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5860 /* Set override-flag and process peer route updates. */
5861 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5862 PEER_FT_FILTER_LIST
);
5863 peer_on_policy_change(peer
, afi
, safi
,
5864 (direct
== FILTER_OUT
) ? 1 : 0);
5866 /* Skip peer-group mechanics for regular peers. */
5871 * Set configuration on all peer-group members, unless they are
5872 * explicitely overriding peer-group configuration.
5874 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5875 /* Skip peers with overridden configuration. */
5876 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5877 PEER_FT_FILTER_LIST
))
5880 /* Set configuration on peer-group member. */
5881 filter
= &member
->filter
[afi
][safi
];
5882 if (filter
->aslist
[direct
].name
)
5883 XFREE(MTYPE_BGP_FILTER_NAME
,
5884 filter
->aslist
[direct
].name
);
5885 filter
->aslist
[direct
].name
=
5886 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5887 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5889 /* Process peer route updates. */
5890 peer_on_policy_change(member
, afi
, safi
,
5891 (direct
== FILTER_OUT
) ? 1 : 0);
5897 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5899 struct peer
*member
;
5900 struct bgp_filter
*filter
;
5901 struct listnode
*node
, *nnode
;
5903 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5904 return BGP_ERR_INVALID_VALUE
;
5906 /* Unset override-flag unconditionally. */
5907 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5908 PEER_FT_FILTER_LIST
);
5910 /* Inherit configuration from peer-group if peer is member. */
5911 if (peer_group_active(peer
)) {
5912 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5913 filter
[afi
][safi
].aslist
[direct
].name
,
5914 MTYPE_BGP_FILTER_NAME
);
5915 PEER_ATTR_INHERIT(peer
, peer
->group
,
5916 filter
[afi
][safi
].aslist
[direct
].aslist
);
5918 /* Otherwise remove configuration from peer. */
5919 filter
= &peer
->filter
[afi
][safi
];
5920 if (filter
->aslist
[direct
].name
)
5921 XFREE(MTYPE_BGP_FILTER_NAME
,
5922 filter
->aslist
[direct
].name
);
5923 filter
->aslist
[direct
].name
= NULL
;
5924 filter
->aslist
[direct
].aslist
= NULL
;
5927 /* Check if handling a regular peer. */
5928 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5929 /* Process peer route updates. */
5930 peer_on_policy_change(peer
, afi
, safi
,
5931 (direct
== FILTER_OUT
) ? 1 : 0);
5933 /* Skip peer-group mechanics for regular peers. */
5938 * Remove configuration on all peer-group members, unless they are
5939 * explicitely overriding peer-group configuration.
5941 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5942 /* Skip peers with overridden configuration. */
5943 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5944 PEER_FT_FILTER_LIST
))
5947 /* Remove configuration on peer-group member. */
5948 filter
= &member
->filter
[afi
][safi
];
5949 if (filter
->aslist
[direct
].name
)
5950 XFREE(MTYPE_BGP_FILTER_NAME
,
5951 filter
->aslist
[direct
].name
);
5952 filter
->aslist
[direct
].name
= NULL
;
5953 filter
->aslist
[direct
].aslist
= NULL
;
5955 /* Process peer route updates. */
5956 peer_on_policy_change(member
, afi
, safi
,
5957 (direct
== FILTER_OUT
) ? 1 : 0);
5963 static void peer_aslist_update(const char *aslist_name
)
5968 struct listnode
*mnode
, *mnnode
;
5969 struct listnode
*node
, *nnode
;
5972 struct peer_group
*group
;
5973 struct bgp_filter
*filter
;
5975 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5976 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5979 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5980 FOREACH_AFI_SAFI (afi
, safi
) {
5981 filter
= &peer
->filter
[afi
][safi
];
5983 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5985 if (filter
->aslist
[direct
].name
)
5986 filter
->aslist
[direct
]
5987 .aslist
= as_list_lookup(
5988 filter
->aslist
[direct
]
5991 filter
->aslist
[direct
].aslist
=
5996 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5997 FOREACH_AFI_SAFI (afi
, safi
) {
5998 filter
= &group
->conf
->filter
[afi
][safi
];
6000 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6002 if (filter
->aslist
[direct
].name
)
6003 filter
->aslist
[direct
]
6004 .aslist
= as_list_lookup(
6005 filter
->aslist
[direct
]
6008 filter
->aslist
[direct
].aslist
=
6016 static void peer_aslist_add(char *aslist_name
)
6018 peer_aslist_update(aslist_name
);
6019 route_map_notify_dependencies((char *)aslist_name
,
6020 RMAP_EVENT_ASLIST_ADDED
);
6023 static void peer_aslist_del(const char *aslist_name
)
6025 peer_aslist_update(aslist_name
);
6026 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6030 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6031 const char *name
, struct route_map
*route_map
)
6033 struct peer
*member
;
6034 struct bgp_filter
*filter
;
6035 struct listnode
*node
, *nnode
;
6037 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6038 return BGP_ERR_INVALID_VALUE
;
6040 /* Set configuration on peer. */
6041 filter
= &peer
->filter
[afi
][safi
];
6042 if (filter
->map
[direct
].name
)
6043 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6044 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6045 filter
->map
[direct
].map
= route_map
;
6047 /* Check if handling a regular peer. */
6048 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6049 /* Set override-flag and process peer route updates. */
6050 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6052 peer_on_policy_change(peer
, afi
, safi
,
6053 (direct
== RMAP_OUT
) ? 1 : 0);
6055 /* Skip peer-group mechanics for regular peers. */
6060 * Set configuration on all peer-group members, unless they are
6061 * explicitely overriding peer-group configuration.
6063 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6064 /* Skip peers with overridden configuration. */
6065 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6069 /* Set configuration on peer-group member. */
6070 filter
= &member
->filter
[afi
][safi
];
6071 if (filter
->map
[direct
].name
)
6072 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6073 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6074 filter
->map
[direct
].map
= route_map
;
6076 /* Process peer route updates. */
6077 peer_on_policy_change(member
, afi
, safi
,
6078 (direct
== RMAP_OUT
) ? 1 : 0);
6083 /* Unset route-map from the peer. */
6084 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6086 struct peer
*member
;
6087 struct bgp_filter
*filter
;
6088 struct listnode
*node
, *nnode
;
6090 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6091 return BGP_ERR_INVALID_VALUE
;
6093 /* Unset override-flag unconditionally. */
6094 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6096 /* Inherit configuration from peer-group if peer is member. */
6097 if (peer_group_active(peer
)) {
6098 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6099 filter
[afi
][safi
].map
[direct
].name
,
6100 MTYPE_BGP_FILTER_NAME
);
6101 PEER_ATTR_INHERIT(peer
, peer
->group
,
6102 filter
[afi
][safi
].map
[direct
].map
);
6104 /* Otherwise remove configuration from peer. */
6105 filter
= &peer
->filter
[afi
][safi
];
6106 if (filter
->map
[direct
].name
)
6107 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6108 filter
->map
[direct
].name
= NULL
;
6109 filter
->map
[direct
].map
= NULL
;
6112 /* Check if handling a regular peer. */
6113 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6114 /* Process peer route updates. */
6115 peer_on_policy_change(peer
, afi
, safi
,
6116 (direct
== RMAP_OUT
) ? 1 : 0);
6118 /* Skip peer-group mechanics for regular peers. */
6123 * Remove configuration on all peer-group members, unless they are
6124 * explicitely overriding peer-group configuration.
6126 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6127 /* Skip peers with overridden configuration. */
6128 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6132 /* Remove configuration on peer-group member. */
6133 filter
= &member
->filter
[afi
][safi
];
6134 if (filter
->map
[direct
].name
)
6135 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6136 filter
->map
[direct
].name
= NULL
;
6137 filter
->map
[direct
].map
= NULL
;
6139 /* Process peer route updates. */
6140 peer_on_policy_change(member
, afi
, safi
,
6141 (direct
== RMAP_OUT
) ? 1 : 0);
6147 /* Set unsuppress-map to the peer. */
6148 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6149 const char *name
, struct route_map
*route_map
)
6151 struct peer
*member
;
6152 struct bgp_filter
*filter
;
6153 struct listnode
*node
, *nnode
;
6155 /* Set configuration on peer. */
6156 filter
= &peer
->filter
[afi
][safi
];
6157 if (filter
->usmap
.name
)
6158 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6159 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6160 filter
->usmap
.map
= route_map
;
6162 /* Check if handling a regular peer. */
6163 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6164 /* Set override-flag and process peer route updates. */
6165 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6166 PEER_FT_UNSUPPRESS_MAP
);
6167 peer_on_policy_change(peer
, afi
, safi
, 1);
6169 /* Skip peer-group mechanics for regular peers. */
6174 * Set configuration on all peer-group members, unless they are
6175 * explicitely overriding peer-group configuration.
6177 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6178 /* Skip peers with overridden configuration. */
6179 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6180 PEER_FT_UNSUPPRESS_MAP
))
6183 /* Set configuration on peer-group member. */
6184 filter
= &member
->filter
[afi
][safi
];
6185 if (filter
->usmap
.name
)
6186 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6187 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6188 filter
->usmap
.map
= route_map
;
6190 /* Process peer route updates. */
6191 peer_on_policy_change(member
, afi
, safi
, 1);
6197 /* Unset route-map from the peer. */
6198 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6200 struct peer
*member
;
6201 struct bgp_filter
*filter
;
6202 struct listnode
*node
, *nnode
;
6204 /* Unset override-flag unconditionally. */
6205 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6207 /* Inherit configuration from peer-group if peer is member. */
6208 if (peer_group_active(peer
)) {
6209 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6210 filter
[afi
][safi
].usmap
.name
,
6211 MTYPE_BGP_FILTER_NAME
);
6212 PEER_ATTR_INHERIT(peer
, peer
->group
,
6213 filter
[afi
][safi
].usmap
.map
);
6215 /* Otherwise remove configuration from peer. */
6216 filter
= &peer
->filter
[afi
][safi
];
6217 if (filter
->usmap
.name
)
6218 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6219 filter
->usmap
.name
= NULL
;
6220 filter
->usmap
.map
= NULL
;
6223 /* Check if handling a regular peer. */
6224 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6225 /* Process peer route updates. */
6226 peer_on_policy_change(peer
, afi
, safi
, 1);
6228 /* Skip peer-group mechanics for regular peers. */
6233 * Remove configuration on all peer-group members, unless they are
6234 * explicitely overriding peer-group configuration.
6236 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6237 /* Skip peers with overridden configuration. */
6238 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6239 PEER_FT_UNSUPPRESS_MAP
))
6242 /* Remove configuration on peer-group member. */
6243 filter
= &member
->filter
[afi
][safi
];
6244 if (filter
->usmap
.name
)
6245 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6246 filter
->usmap
.name
= NULL
;
6247 filter
->usmap
.map
= NULL
;
6249 /* Process peer route updates. */
6250 peer_on_policy_change(member
, afi
, safi
, 1);
6256 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6257 uint32_t max
, uint8_t threshold
, int warning
,
6260 struct peer
*member
;
6261 struct listnode
*node
, *nnode
;
6263 /* Set flags and configuration on peer. */
6264 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6266 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6268 peer_af_flag_unset(peer
, afi
, safi
,
6269 PEER_FLAG_MAX_PREFIX_WARNING
);
6271 peer
->pmax
[afi
][safi
] = max
;
6272 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6273 peer
->pmax_restart
[afi
][safi
] = restart
;
6275 /* Check if handling a regular peer. */
6276 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6277 /* Re-check if peer violates maximum-prefix. */
6278 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6279 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6281 /* Skip peer-group mechanics for regular peers. */
6286 * Set flags and configuration on all peer-group members, unless they
6287 * are explicitely overriding peer-group configuration.
6289 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6290 /* Skip peers with overridden configuration. */
6291 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6292 PEER_FLAG_MAX_PREFIX
))
6295 /* Set flag and configuration on peer-group member. */
6296 member
->pmax
[afi
][safi
] = max
;
6297 member
->pmax_threshold
[afi
][safi
] = threshold
;
6298 member
->pmax_restart
[afi
][safi
] = restart
;
6300 SET_FLAG(member
->af_flags
[afi
][safi
],
6301 PEER_FLAG_MAX_PREFIX_WARNING
);
6303 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6304 PEER_FLAG_MAX_PREFIX_WARNING
);
6306 /* Re-check if peer violates maximum-prefix. */
6307 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6308 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6314 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6316 /* Inherit configuration from peer-group if peer is member. */
6317 if (peer_group_active(peer
)) {
6318 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6319 peer_af_flag_inherit(peer
, afi
, safi
,
6320 PEER_FLAG_MAX_PREFIX_WARNING
);
6321 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6322 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6323 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6328 /* Remove flags and configuration from peer. */
6329 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6330 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6331 peer
->pmax
[afi
][safi
] = 0;
6332 peer
->pmax_threshold
[afi
][safi
] = 0;
6333 peer
->pmax_restart
[afi
][safi
] = 0;
6336 * Remove flags and configuration from all peer-group members, unless
6337 * they are explicitely overriding peer-group configuration.
6339 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6340 struct peer
*member
;
6341 struct listnode
*node
;
6343 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6344 /* Skip peers with overridden configuration. */
6345 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6346 PEER_FLAG_MAX_PREFIX
))
6349 /* Remove flag and configuration on peer-group member.
6351 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6352 PEER_FLAG_MAX_PREFIX
);
6353 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6354 PEER_FLAG_MAX_PREFIX_WARNING
);
6355 member
->pmax
[afi
][safi
] = 0;
6356 member
->pmax_threshold
[afi
][safi
] = 0;
6357 member
->pmax_restart
[afi
][safi
] = 0;
6364 int is_ebgp_multihop_configured(struct peer
*peer
)
6366 struct peer_group
*group
;
6367 struct listnode
*node
, *nnode
;
6370 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6371 group
= peer
->group
;
6372 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6373 && (group
->conf
->ttl
!= 1))
6376 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6377 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6378 && (peer1
->ttl
!= 1))
6382 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6388 /* Set # of hops between us and BGP peer. */
6389 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6391 struct peer_group
*group
;
6392 struct listnode
*node
, *nnode
;
6395 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6396 gtsm_hops
, peer
->host
);
6398 /* We cannot configure ttl-security hops when ebgp-multihop is already
6399 set. For non peer-groups, the check is simple. For peer-groups,
6401 slightly messy, because we need to check both the peer-group
6403 and all peer-group members for any trace of ebgp-multihop
6405 before actually applying the ttl-security rules. Cisco really made a
6406 mess of this configuration parameter, and OpenBGPD got it right.
6409 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6410 if (is_ebgp_multihop_configured(peer
))
6411 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6413 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6414 peer
->gtsm_hops
= gtsm_hops
;
6416 /* Calling ebgp multihop also resets the session.
6417 * On restart, NHT will get setup correctly as will the
6418 * min & max ttls on the socket. The return value is
6421 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6426 group
= peer
->group
;
6427 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6429 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6431 /* Calling ebgp multihop also resets the
6433 * On restart, NHT will get setup correctly as
6435 * min & max ttls on the socket. The return
6439 peer_ebgp_multihop_set(peer
, MAXTTL
);
6443 /* Post the first gtsm setup or if its ibgp, maxttl setting
6445 * necessary, just set the minttl.
6447 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6448 peer
->gtsm_hops
= gtsm_hops
;
6451 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6452 MAXTTL
+ 1 - gtsm_hops
);
6453 if ((peer
->status
< Established
) && peer
->doppelganger
6454 && (peer
->doppelganger
->fd
>= 0))
6455 sockopt_minttl(peer
->su
.sa
.sa_family
,
6456 peer
->doppelganger
->fd
,
6457 MAXTTL
+ 1 - gtsm_hops
);
6459 group
= peer
->group
;
6460 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6462 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6464 /* Change setting of existing peer
6465 * established then change value (may break
6467 * not established yet (teardown session and
6469 * no session then do nothing (will get
6470 * handled by next connection)
6472 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6474 peer
->su
.sa
.sa_family
, peer
->fd
,
6475 MAXTTL
+ 1 - peer
->gtsm_hops
);
6476 if ((peer
->status
< Established
)
6477 && peer
->doppelganger
6478 && (peer
->doppelganger
->fd
>= 0))
6479 sockopt_minttl(peer
->su
.sa
.sa_family
,
6480 peer
->doppelganger
->fd
,
6481 MAXTTL
+ 1 - gtsm_hops
);
6489 int peer_ttl_security_hops_unset(struct peer
*peer
)
6491 struct peer_group
*group
;
6492 struct listnode
*node
, *nnode
;
6495 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6498 /* if a peer-group member, then reset to peer-group default rather than
6500 if (peer_group_active(peer
))
6501 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6503 peer
->gtsm_hops
= 0;
6505 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6506 /* Invoking ebgp_multihop_set will set the TTL back to the
6508 * value as well as restting the NHT and such. The session is
6511 if (peer
->sort
== BGP_PEER_EBGP
)
6512 ret
= peer_ebgp_multihop_unset(peer
);
6515 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6518 if ((peer
->status
< Established
) && peer
->doppelganger
6519 && (peer
->doppelganger
->fd
>= 0))
6520 sockopt_minttl(peer
->su
.sa
.sa_family
,
6521 peer
->doppelganger
->fd
, 0);
6524 group
= peer
->group
;
6525 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6526 peer
->gtsm_hops
= 0;
6527 if (peer
->sort
== BGP_PEER_EBGP
)
6528 ret
= peer_ebgp_multihop_unset(peer
);
6531 sockopt_minttl(peer
->su
.sa
.sa_family
,
6534 if ((peer
->status
< Established
)
6535 && peer
->doppelganger
6536 && (peer
->doppelganger
->fd
>= 0))
6537 sockopt_minttl(peer
->su
.sa
.sa_family
,
6538 peer
->doppelganger
->fd
,
6548 * If peer clear is invoked in a loop for all peers on the BGP instance,
6549 * it may end up freeing the doppelganger, and if this was the next node
6550 * to the current node, we would end up accessing the freed next node.
6551 * Pass along additional parameter which can be updated if next node
6552 * is freed; only required when walking the peer list on BGP instance.
6554 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6556 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6557 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6558 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6559 if (peer
->t_pmax_restart
) {
6560 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6561 if (bgp_debug_neighbor_events(peer
))
6563 "%s Maximum-prefix restart timer canceled",
6566 BGP_EVENT_ADD(peer
, BGP_Start
);
6570 peer
->v_start
= BGP_INIT_START_TIMER
;
6571 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6572 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6573 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6575 bgp_session_reset_safe(peer
, nnode
);
6580 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6581 enum bgp_clear_type stype
)
6583 struct peer_af
*paf
;
6585 if (peer
->status
!= Established
)
6588 if (!peer
->afc
[afi
][safi
])
6589 return BGP_ERR_AF_UNCONFIGURED
;
6591 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6593 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6594 /* Clear the "neighbor x.x.x.x default-originate" flag */
6595 paf
= peer_af_find(peer
, afi
, safi
);
6596 if (paf
&& paf
->subgroup
6597 && CHECK_FLAG(paf
->subgroup
->sflags
,
6598 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6599 UNSET_FLAG(paf
->subgroup
->sflags
,
6600 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6602 bgp_announce_route(peer
, afi
, safi
);
6605 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6606 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6607 PEER_CAP_ORF_PREFIX_SM_ADV
)
6608 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6609 PEER_CAP_ORF_PREFIX_RM_RCV
)
6610 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6611 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6612 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6613 uint8_t prefix_type
;
6615 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6616 PEER_CAP_ORF_PREFIX_RM_RCV
))
6617 prefix_type
= ORF_TYPE_PREFIX
;
6619 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6621 if (filter
->plist
[FILTER_IN
].plist
) {
6622 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6623 PEER_STATUS_ORF_PREFIX_SEND
))
6624 bgp_route_refresh_send(
6625 peer
, afi
, safi
, prefix_type
,
6627 bgp_route_refresh_send(peer
, afi
, safi
,
6629 REFRESH_IMMEDIATE
, 0);
6631 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6632 PEER_STATUS_ORF_PREFIX_SEND
))
6633 bgp_route_refresh_send(
6634 peer
, afi
, safi
, prefix_type
,
6635 REFRESH_IMMEDIATE
, 1);
6637 bgp_route_refresh_send(peer
, afi
, safi
,
6644 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6645 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6646 /* If neighbor has soft reconfiguration inbound flag.
6647 Use Adj-RIB-In database. */
6648 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6649 PEER_FLAG_SOFT_RECONFIG
))
6650 bgp_soft_reconfig_in(peer
, afi
, safi
);
6652 /* If neighbor has route refresh capability, send route
6654 message to the peer. */
6655 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6656 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6657 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6660 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6666 /* Display peer uptime.*/
6667 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6670 time_t uptime1
, epoch_tbuf
;
6673 /* If there is no connection has been done before print `never'. */
6676 json_object_string_add(json
, "peerUptime", "never");
6677 json_object_int_add(json
, "peerUptimeMsec", 0);
6679 snprintf(buf
, len
, "never");
6683 /* Get current time. */
6684 uptime1
= bgp_clock();
6686 tm
= gmtime(&uptime1
);
6688 if (uptime1
< ONE_DAY_SECOND
)
6689 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6691 else if (uptime1
< ONE_WEEK_SECOND
)
6692 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6694 else if (uptime1
< ONE_YEAR_SECOND
)
6695 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6696 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6698 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6700 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6703 epoch_tbuf
= time(NULL
) - uptime1
;
6704 json_object_string_add(json
, "peerUptime", buf
);
6705 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6706 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6713 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6714 afi_t afi
, safi_t safi
)
6716 struct bgp_filter
*filter
;
6720 filter
= &peer
->filter
[afi
][safi
];
6722 /* distribute-list. */
6723 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6725 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6726 filter
->dlist
[FILTER_IN
].name
);
6728 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6730 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6731 filter
->dlist
[FILTER_OUT
].name
);
6734 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6736 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6737 filter
->plist
[FILTER_IN
].name
);
6739 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6741 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6742 filter
->plist
[FILTER_OUT
].name
);
6745 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6746 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6747 filter
->map
[RMAP_IN
].name
);
6749 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6751 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6752 filter
->map
[RMAP_OUT
].name
);
6754 /* unsuppress-map */
6755 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6756 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6757 filter
->usmap
.name
);
6760 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6762 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6763 filter
->aslist
[FILTER_IN
].name
);
6765 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6767 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6768 filter
->aslist
[FILTER_OUT
].name
);
6771 /* BGP peer configuration display function. */
6772 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6775 struct peer
*g_peer
= NULL
;
6776 char buf
[SU_ADDRSTRLEN
];
6778 int if_pg_printed
= FALSE
;
6779 int if_ras_printed
= FALSE
;
6781 /* Skip dynamic neighbors. */
6782 if (peer_dynamic_neighbor(peer
))
6786 addr
= peer
->conf_if
;
6790 /************************************
6791 ****** Global to the neighbor ******
6792 ************************************/
6793 if (peer
->conf_if
) {
6794 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6795 vty_out(vty
, " neighbor %s interface v6only", addr
);
6797 vty_out(vty
, " neighbor %s interface", addr
);
6799 if (peer_group_active(peer
)) {
6800 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6801 if_pg_printed
= TRUE
;
6802 } else if (peer
->as_type
== AS_SPECIFIED
) {
6803 vty_out(vty
, " remote-as %u", peer
->as
);
6804 if_ras_printed
= TRUE
;
6805 } else if (peer
->as_type
== AS_INTERNAL
) {
6806 vty_out(vty
, " remote-as internal");
6807 if_ras_printed
= TRUE
;
6808 } else if (peer
->as_type
== AS_EXTERNAL
) {
6809 vty_out(vty
, " remote-as external");
6810 if_ras_printed
= TRUE
;
6816 /* remote-as and peer-group */
6817 /* peer is a member of a peer-group */
6818 if (peer_group_active(peer
)) {
6819 g_peer
= peer
->group
->conf
;
6821 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6822 if (peer
->as_type
== AS_SPECIFIED
) {
6823 vty_out(vty
, " neighbor %s remote-as %u\n",
6825 } else if (peer
->as_type
== AS_INTERNAL
) {
6827 " neighbor %s remote-as internal\n",
6829 } else if (peer
->as_type
== AS_EXTERNAL
) {
6831 " neighbor %s remote-as external\n",
6836 /* For swpX peers we displayed the peer-group
6837 * via 'neighbor swpX interface peer-group WORD' */
6839 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6843 /* peer is NOT a member of a peer-group */
6845 /* peer is a peer-group, declare the peer-group */
6846 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6847 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6850 if (!if_ras_printed
) {
6851 if (peer
->as_type
== AS_SPECIFIED
) {
6852 vty_out(vty
, " neighbor %s remote-as %u\n",
6854 } else if (peer
->as_type
== AS_INTERNAL
) {
6856 " neighbor %s remote-as internal\n",
6858 } else if (peer
->as_type
== AS_EXTERNAL
) {
6860 " neighbor %s remote-as external\n",
6867 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6868 vty_out(vty
, " neighbor %s local-as %u", addr
,
6869 peer
->change_local_as
);
6870 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6871 vty_out(vty
, " no-prepend");
6872 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6873 vty_out(vty
, " replace-as");
6879 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6883 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6884 if (peer
->tx_shutdown_message
)
6885 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6886 peer
->tx_shutdown_message
);
6888 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6892 if (peer
->bfd_info
) {
6893 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6894 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6899 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6900 vty_out(vty
, " neighbor %s password %s\n", addr
,
6904 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6905 if (!peer_group_active(peer
)) {
6906 vty_out(vty
, " neighbor %s solo\n", addr
);
6911 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6912 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6915 /* Local interface name */
6917 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6921 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6922 vty_out(vty
, " neighbor %s passive\n", addr
);
6925 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6926 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6927 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6928 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6933 /* ttl-security hops */
6934 if (peer
->gtsm_hops
!= 0) {
6935 if (!peer_group_active(peer
)
6936 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6937 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6938 addr
, peer
->gtsm_hops
);
6942 /* disable-connected-check */
6943 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6944 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6946 /* enforce-first-as */
6947 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6948 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6951 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6952 if (peer
->update_source
)
6953 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6954 sockunion2str(peer
->update_source
, buf
,
6956 else if (peer
->update_if
)
6957 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6961 /* advertisement-interval */
6962 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6963 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6967 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6968 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6969 peer
->keepalive
, peer
->holdtime
);
6971 /* timers connect */
6972 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6973 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6976 /* capability dynamic */
6977 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6978 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6980 /* capability extended-nexthop */
6981 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6982 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6984 " no neighbor %s capability extended-nexthop\n",
6988 " neighbor %s capability extended-nexthop\n",
6992 /* dont-capability-negotiation */
6993 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
6994 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
6996 /* override-capability */
6997 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
6998 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7000 /* strict-capability-match */
7001 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7002 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7005 /* BGP peer configuration display function. */
7006 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7007 struct peer
*peer
, afi_t afi
, safi_t safi
)
7009 struct peer
*g_peer
= NULL
;
7011 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7013 /* Skip dynamic neighbors. */
7014 if (peer_dynamic_neighbor(peer
))
7018 addr
= peer
->conf_if
;
7022 /************************************
7023 ****** Per AF to the neighbor ******
7024 ************************************/
7025 if (peer_group_active(peer
)) {
7026 g_peer
= peer
->group
->conf
;
7028 /* If the peer-group is active but peer is not, print a 'no
7030 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7031 vty_out(vty
, " no neighbor %s activate\n", addr
);
7034 /* If the peer-group is not active but peer is, print an
7036 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7037 vty_out(vty
, " neighbor %s activate\n", addr
);
7040 if (peer
->afc
[afi
][safi
]) {
7041 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7042 if (bgp_flag_check(bgp
,
7043 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7044 vty_out(vty
, " neighbor %s activate\n",
7048 vty_out(vty
, " neighbor %s activate\n", addr
);
7050 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7051 if (!bgp_flag_check(bgp
,
7052 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7054 " no neighbor %s activate\n",
7061 /* addpath TX knobs */
7062 if (peergroup_af_flag_check(peer
, afi
, safi
,
7063 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
7064 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
7067 if (peergroup_af_flag_check(peer
, afi
, safi
,
7068 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
7069 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
7073 /* ORF capability. */
7074 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7075 || peergroup_af_flag_check(peer
, afi
, safi
,
7076 PEER_FLAG_ORF_PREFIX_RM
)) {
7077 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7079 if (peergroup_af_flag_check(peer
, afi
, safi
,
7080 PEER_FLAG_ORF_PREFIX_SM
)
7081 && peergroup_af_flag_check(peer
, afi
, safi
,
7082 PEER_FLAG_ORF_PREFIX_RM
))
7083 vty_out(vty
, " both");
7084 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7085 PEER_FLAG_ORF_PREFIX_SM
))
7086 vty_out(vty
, " send");
7088 vty_out(vty
, " receive");
7092 /* Route reflector client. */
7093 if (peergroup_af_flag_check(peer
, afi
, safi
,
7094 PEER_FLAG_REFLECTOR_CLIENT
)) {
7095 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7098 /* next-hop-self force */
7099 if (peergroup_af_flag_check(peer
, afi
, safi
,
7100 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7101 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7105 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7106 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7109 /* remove-private-AS */
7110 if (peergroup_af_flag_check(peer
, afi
, safi
,
7111 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7112 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7116 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7117 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7118 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7122 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7123 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7124 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7127 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7128 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7129 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7133 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7134 vty_out(vty
, " neighbor %s as-override\n", addr
);
7137 /* send-community print. */
7138 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7139 PEER_FLAG_SEND_COMMUNITY
);
7140 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7141 PEER_FLAG_SEND_EXT_COMMUNITY
);
7142 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7143 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7145 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7146 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7147 vty_out(vty
, " no neighbor %s send-community all\n",
7152 " no neighbor %s send-community\n",
7156 " no neighbor %s send-community extended\n",
7161 " no neighbor %s send-community large\n",
7165 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7166 vty_out(vty
, " neighbor %s send-community all\n",
7168 } else if (flag_scomm
&& flag_secomm
) {
7169 vty_out(vty
, " neighbor %s send-community both\n",
7173 vty_out(vty
, " neighbor %s send-community\n",
7177 " neighbor %s send-community extended\n",
7181 " neighbor %s send-community large\n",
7186 /* Default information */
7187 if (peergroup_af_flag_check(peer
, afi
, safi
,
7188 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7189 vty_out(vty
, " neighbor %s default-originate", addr
);
7191 if (peer
->default_rmap
[afi
][safi
].name
)
7192 vty_out(vty
, " route-map %s",
7193 peer
->default_rmap
[afi
][safi
].name
);
7198 /* Soft reconfiguration inbound. */
7199 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7200 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7204 /* maximum-prefix. */
7205 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7206 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7207 peer
->pmax
[afi
][safi
]);
7209 if (peer
->pmax_threshold
[afi
][safi
]
7210 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7211 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7212 if (peer_af_flag_check(peer
, afi
, safi
,
7213 PEER_FLAG_MAX_PREFIX_WARNING
))
7214 vty_out(vty
, " warning-only");
7215 if (peer
->pmax_restart
[afi
][safi
])
7216 vty_out(vty
, " restart %u",
7217 peer
->pmax_restart
[afi
][safi
]);
7222 /* Route server client. */
7223 if (peergroup_af_flag_check(peer
, afi
, safi
,
7224 PEER_FLAG_RSERVER_CLIENT
)) {
7225 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7228 /* Nexthop-local unchanged. */
7229 if (peergroup_af_flag_check(peer
, afi
, safi
,
7230 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7231 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7234 /* allowas-in <1-10> */
7235 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7236 if (peer_af_flag_check(peer
, afi
, safi
,
7237 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7238 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7239 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7240 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7242 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7243 peer
->allowas_in
[afi
][safi
]);
7248 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7249 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7250 peer
->weight
[afi
][safi
]);
7253 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7255 /* atribute-unchanged. */
7256 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7257 || (safi
!= SAFI_EVPN
7258 && peer_af_flag_check(peer
, afi
, safi
,
7259 PEER_FLAG_NEXTHOP_UNCHANGED
))
7260 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7262 if (!peer_group_active(peer
)
7263 || peergroup_af_flag_check(peer
, afi
, safi
,
7264 PEER_FLAG_AS_PATH_UNCHANGED
)
7265 || peergroup_af_flag_check(peer
, afi
, safi
,
7266 PEER_FLAG_NEXTHOP_UNCHANGED
)
7267 || peergroup_af_flag_check(peer
, afi
, safi
,
7268 PEER_FLAG_MED_UNCHANGED
)) {
7271 " neighbor %s attribute-unchanged%s%s%s\n",
7273 peer_af_flag_check(peer
, afi
, safi
,
7274 PEER_FLAG_AS_PATH_UNCHANGED
)
7277 peer_af_flag_check(peer
, afi
, safi
,
7278 PEER_FLAG_NEXTHOP_UNCHANGED
)
7281 peer_af_flag_check(peer
, afi
, safi
,
7282 PEER_FLAG_MED_UNCHANGED
)
7289 /* Address family based peer configuration display. */
7290 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7294 struct peer_group
*group
;
7295 struct listnode
*node
, *nnode
;
7298 vty_frame(vty
, " !\n address-family ");
7299 if (afi
== AFI_IP
) {
7300 if (safi
== SAFI_UNICAST
)
7301 vty_frame(vty
, "ipv4 unicast");
7302 else if (safi
== SAFI_LABELED_UNICAST
)
7303 vty_frame(vty
, "ipv4 labeled-unicast");
7304 else if (safi
== SAFI_MULTICAST
)
7305 vty_frame(vty
, "ipv4 multicast");
7306 else if (safi
== SAFI_MPLS_VPN
)
7307 vty_frame(vty
, "ipv4 vpn");
7308 else if (safi
== SAFI_ENCAP
)
7309 vty_frame(vty
, "ipv4 encap");
7310 else if (safi
== SAFI_FLOWSPEC
)
7311 vty_frame(vty
, "ipv4 flowspec");
7312 } else if (afi
== AFI_IP6
) {
7313 if (safi
== SAFI_UNICAST
)
7314 vty_frame(vty
, "ipv6 unicast");
7315 else if (safi
== SAFI_LABELED_UNICAST
)
7316 vty_frame(vty
, "ipv6 labeled-unicast");
7317 else if (safi
== SAFI_MULTICAST
)
7318 vty_frame(vty
, "ipv6 multicast");
7319 else if (safi
== SAFI_MPLS_VPN
)
7320 vty_frame(vty
, "ipv6 vpn");
7321 else if (safi
== SAFI_ENCAP
)
7322 vty_frame(vty
, "ipv6 encap");
7323 else if (safi
== SAFI_FLOWSPEC
)
7324 vty_frame(vty
, "ipv6 flowspec");
7325 } else if (afi
== AFI_L2VPN
) {
7326 if (safi
== SAFI_EVPN
)
7327 vty_frame(vty
, "l2vpn evpn");
7329 vty_frame(vty
, "\n");
7331 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7333 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7335 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7337 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7338 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7340 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7341 /* Skip dynamic neighbors. */
7342 if (peer_dynamic_neighbor(peer
))
7345 /* Do not display doppelganger peers */
7346 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7347 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7350 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7351 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7353 if (safi
== SAFI_EVPN
)
7354 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7356 if (safi
== SAFI_FLOWSPEC
)
7357 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7359 if (safi
== SAFI_UNICAST
) {
7360 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7361 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7362 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7364 vty_out(vty
, " export vpn\n");
7366 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7367 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7369 vty_out(vty
, " import vpn\n");
7371 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7372 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7375 for (ALL_LIST_ELEMENTS_RO(
7376 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7378 vty_out(vty
, " import vrf %s\n", name
);
7382 vty_endframe(vty
, " exit-address-family\n");
7385 /* clang-format off */
7386 #if CONFDATE > 20190517
7387 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7389 /* clang-format on */
7391 int bgp_config_write(struct vty
*vty
)
7395 struct peer_group
*group
;
7397 struct listnode
*node
, *nnode
;
7398 struct listnode
*mnode
, *mnnode
;
7400 /* BGP Multiple instance. */
7401 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7402 vty_out(vty
, "no bgp multiple-instance\n");
7406 /* BGP Config type. */
7407 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7408 vty_out(vty
, "bgp config-type cisco\n");
7412 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7413 vty_out(vty
, "bgp route-map delay-timer %u\n",
7414 bm
->rmap_update_timer
);
7417 vty_out(vty
, "!\n");
7419 /* BGP configuration. */
7420 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7422 /* skip all auto created vrf as they dont have user config */
7423 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7426 /* Migrate deprecated 'bgp enforce-first-as'
7427 * config to 'neighbor * enforce-first-as' configs
7429 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7430 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7431 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7432 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7435 /* Router bgp ASN */
7436 vty_out(vty
, "router bgp %u", bgp
->as
);
7438 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7440 vty_out(vty
, " %s %s",
7442 == BGP_INSTANCE_TYPE_VIEW
)
7449 /* No Synchronization */
7450 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7451 vty_out(vty
, " no synchronization\n");
7453 /* BGP fast-external-failover. */
7454 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7455 vty_out(vty
, " no bgp fast-external-failover\n");
7457 /* BGP router ID. */
7458 if (bgp
->router_id_static
.s_addr
!= 0)
7459 vty_out(vty
, " bgp router-id %s\n",
7460 inet_ntoa(bgp
->router_id_static
));
7462 /* BGP log-neighbor-changes. */
7463 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7464 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7465 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7467 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7471 /* BGP configuration. */
7472 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7473 vty_out(vty
, " bgp always-compare-med\n");
7475 /* BGP default ipv4-unicast. */
7476 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7477 vty_out(vty
, " no bgp default ipv4-unicast\n");
7479 /* BGP default local-preference. */
7480 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7481 vty_out(vty
, " bgp default local-preference %u\n",
7482 bgp
->default_local_pref
);
7484 /* BGP default show-hostname */
7485 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7486 != DFLT_BGP_SHOW_HOSTNAME
)
7487 vty_out(vty
, " %sbgp default show-hostname\n",
7488 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7492 /* BGP default subgroup-pkt-queue-max. */
7493 if (bgp
->default_subgroup_pkt_queue_max
7494 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7495 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7496 bgp
->default_subgroup_pkt_queue_max
);
7498 /* BGP client-to-client reflection. */
7499 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7500 vty_out(vty
, " no bgp client-to-client reflection\n");
7502 /* BGP cluster ID. */
7503 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7504 vty_out(vty
, " bgp cluster-id %s\n",
7505 inet_ntoa(bgp
->cluster_id
));
7507 /* Disable ebgp connected nexthop check */
7508 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7510 " bgp disable-ebgp-connected-route-check\n");
7512 /* Confederation identifier*/
7513 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7514 vty_out(vty
, " bgp confederation identifier %i\n",
7517 /* Confederation peer */
7518 if (bgp
->confed_peers_cnt
> 0) {
7521 vty_out(vty
, " bgp confederation peers");
7523 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7524 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7529 /* BGP deterministic-med. */
7530 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7531 != DFLT_BGP_DETERMINISTIC_MED
)
7532 vty_out(vty
, " %sbgp deterministic-med\n",
7533 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7537 /* BGP update-delay. */
7538 bgp_config_write_update_delay(vty
, bgp
);
7540 if (bgp
->v_maxmed_onstartup
7541 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7542 vty_out(vty
, " bgp max-med on-startup %u",
7543 bgp
->v_maxmed_onstartup
);
7544 if (bgp
->maxmed_onstartup_value
7545 != BGP_MAXMED_VALUE_DEFAULT
)
7547 bgp
->maxmed_onstartup_value
);
7550 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7551 vty_out(vty
, " bgp max-med administrative");
7552 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7553 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7558 bgp_config_write_wpkt_quanta(vty
, bgp
);
7560 bgp_config_write_rpkt_quanta(vty
, bgp
);
7563 bgp_config_write_coalesce_time(vty
, bgp
);
7565 /* BGP graceful-restart. */
7566 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7568 " bgp graceful-restart stalepath-time %u\n",
7569 bgp
->stalepath_time
);
7570 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7571 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7573 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7574 vty_out(vty
, " bgp graceful-restart\n");
7576 /* BGP graceful-shutdown */
7577 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7578 vty_out(vty
, " bgp graceful-shutdown\n");
7580 /* BGP graceful-restart Preserve State F bit. */
7581 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7583 " bgp graceful-restart preserve-fw-state\n");
7585 /* BGP bestpath method. */
7586 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7587 vty_out(vty
, " bgp bestpath as-path ignore\n");
7588 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7589 vty_out(vty
, " bgp bestpath as-path confed\n");
7591 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7592 if (bgp_flag_check(bgp
,
7593 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7595 " bgp bestpath as-path multipath-relax as-set\n");
7598 " bgp bestpath as-path multipath-relax\n");
7602 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7604 " bgp route-reflector allow-outbound-policy\n");
7606 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7607 vty_out(vty
, " bgp bestpath compare-routerid\n");
7608 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7609 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7610 vty_out(vty
, " bgp bestpath med");
7611 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7612 vty_out(vty
, " confed");
7613 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7614 vty_out(vty
, " missing-as-worst");
7618 /* BGP network import check. */
7619 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7620 != DFLT_BGP_IMPORT_CHECK
)
7621 vty_out(vty
, " %sbgp network import-check\n",
7622 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7626 /* BGP flag dampening. */
7627 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7628 BGP_CONFIG_DAMPENING
))
7629 bgp_config_write_damp(vty
);
7631 /* BGP timers configuration. */
7632 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7633 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7634 vty_out(vty
, " timers bgp %u %u\n",
7635 bgp
->default_keepalive
, bgp
->default_holdtime
);
7638 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7639 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7642 /* Normal neighbor configuration. */
7643 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7644 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7645 bgp_config_write_peer_global(vty
, bgp
, peer
);
7648 /* listen range and limit for dynamic BGP neighbors */
7649 bgp_config_write_listen(vty
, bgp
);
7652 * BGP default autoshutdown neighbors
7654 * This must be placed after any peer and peer-group
7655 * configuration, to avoid setting all peers to shutdown after
7656 * a daemon restart, which is undesired behavior. (see #2286)
7658 if (bgp
->autoshutdown
)
7659 vty_out(vty
, " bgp default shutdown\n");
7661 /* No auto-summary */
7662 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7663 vty_out(vty
, " no auto-summary\n");
7665 /* IPv4 unicast configuration. */
7666 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7668 /* IPv4 multicast configuration. */
7669 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7671 /* IPv4 labeled-unicast configuration. */
7672 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7674 /* IPv4 VPN configuration. */
7675 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7677 /* ENCAPv4 configuration. */
7678 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7680 /* FLOWSPEC v4 configuration. */
7681 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7683 /* IPv6 unicast configuration. */
7684 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7686 /* IPv6 multicast configuration. */
7687 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7689 /* IPv6 labeled-unicast configuration. */
7690 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7691 SAFI_LABELED_UNICAST
);
7693 /* IPv6 VPN configuration. */
7694 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7696 /* ENCAPv6 configuration. */
7697 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7699 /* FLOWSPEC v6 configuration. */
7700 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7702 /* EVPN configuration. */
7703 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7706 bgp_rfapi_cfg_write(vty
, bgp
);
7709 vty_out(vty
, "!\n");
7714 void bgp_master_init(struct thread_master
*master
)
7718 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7721 bm
->bgp
= list_new();
7722 bm
->listen_sockets
= list_new();
7723 bm
->port
= BGP_PORT_DEFAULT
;
7724 bm
->master
= master
;
7725 bm
->start_time
= bgp_clock();
7726 bm
->t_rmap_update
= NULL
;
7727 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7728 bm
->terminating
= false;
7730 bgp_process_queue_init();
7732 /* init the rd id space.
7733 assign 0th index in the bitfield,
7734 so that we start with id 1
7736 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7737 bf_assign_zero_index(bm
->rd_idspace
);
7739 /* Enable multiple instances by default. */
7740 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7742 /* mpls label dynamic allocation pool */
7743 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7745 QOBJ_REG(bm
, bgp_master
);
7749 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7750 * instance delete (non-default only) or BGP exit.
7752 static void bgp_if_finish(struct bgp
*bgp
)
7754 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7755 struct interface
*ifp
;
7757 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7760 FOR_ALL_INTERFACES (vrf
, ifp
) {
7761 struct listnode
*c_node
, *c_nnode
;
7762 struct connected
*c
;
7764 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7765 bgp_connected_delete(bgp
, c
);
7769 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7771 struct vrf
*vrf
= NULL
;
7772 struct listnode
*next
;
7775 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7776 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7778 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7779 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7782 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7786 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7787 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7788 {.completions
= NULL
},
7791 struct frr_pthread
*bgp_pth_io
;
7792 struct frr_pthread
*bgp_pth_ka
;
7794 static void bgp_pthreads_init()
7796 assert(!bgp_pth_io
);
7797 assert(!bgp_pth_ka
);
7801 struct frr_pthread_attr io
= {
7802 .start
= frr_pthread_attr_default
.start
,
7803 .stop
= frr_pthread_attr_default
.stop
,
7805 struct frr_pthread_attr ka
= {
7806 .start
= bgp_keepalives_start
,
7807 .stop
= bgp_keepalives_stop
,
7809 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7810 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7813 void bgp_pthreads_run()
7815 frr_pthread_run(bgp_pth_io
, NULL
);
7816 frr_pthread_run(bgp_pth_ka
, NULL
);
7818 /* Wait until threads are ready. */
7819 frr_pthread_wait_running(bgp_pth_io
);
7820 frr_pthread_wait_running(bgp_pth_ka
);
7823 void bgp_pthreads_finish()
7825 frr_pthread_stop_all();
7826 frr_pthread_finish();
7829 void bgp_init(unsigned short instance
)
7832 /* allocates some vital data structures used by peer commands in
7835 /* pre-init pthreads */
7836 bgp_pthreads_init();
7839 bgp_zebra_init(bm
->master
, instance
);
7842 vnc_zebra_init(bm
->master
);
7845 /* BGP VTY commands installation. */
7853 bgp_route_map_init();
7854 bgp_scan_vty_init();
7859 bgp_ethernetvpn_init();
7860 bgp_flowspec_vty_init();
7862 /* Access list initialize. */
7864 access_list_add_hook(peer_distribute_update
);
7865 access_list_delete_hook(peer_distribute_update
);
7867 /* Filter list initialize. */
7869 as_list_add_hook(peer_aslist_add
);
7870 as_list_delete_hook(peer_aslist_del
);
7872 /* Prefix list initialize.*/
7874 prefix_list_add_hook(peer_prefix_list_update
);
7875 prefix_list_delete_hook(peer_prefix_list_update
);
7877 /* Community list initialize. */
7878 bgp_clist
= community_list_init();
7883 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7886 void bgp_terminate(void)
7890 struct listnode
*node
, *nnode
;
7891 struct listnode
*mnode
, *mnnode
;
7895 /* Close the listener sockets first as this prevents peers from
7897 * to reconnect on receiving the peer unconfig message. In the presence
7898 * of a large number of peers this will ensure that no peer is left with
7899 * a dangling connection
7901 /* reverse bgp_master_init */
7904 if (bm
->listen_sockets
)
7905 list_delete(&bm
->listen_sockets
);
7907 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7908 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7909 if (peer
->status
== Established
7910 || peer
->status
== OpenSent
7911 || peer
->status
== OpenConfirm
)
7912 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7913 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7915 if (bm
->process_main_queue
)
7916 work_queue_free_and_null(&bm
->process_main_queue
);
7918 if (bm
->t_rmap_update
)
7919 BGP_TIMER_OFF(bm
->t_rmap_update
);