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 "lib/sockopt.h"
47 #include "frr_pthread.h"
50 #include "bgpd/bgpd.h"
51 #include "bgpd/bgp_table.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_route.h"
54 #include "bgpd/bgp_dump.h"
55 #include "bgpd/bgp_debug.h"
56 #include "bgpd/bgp_errors.h"
57 #include "bgpd/bgp_community.h"
58 #include "bgpd/bgp_community_alias.h"
59 #include "bgpd/bgp_conditional_adv.h"
60 #include "bgpd/bgp_attr.h"
61 #include "bgpd/bgp_regex.h"
62 #include "bgpd/bgp_clist.h"
63 #include "bgpd/bgp_fsm.h"
64 #include "bgpd/bgp_packet.h"
65 #include "bgpd/bgp_zebra.h"
66 #include "bgpd/bgp_open.h"
67 #include "bgpd/bgp_filter.h"
68 #include "bgpd/bgp_nexthop.h"
69 #include "bgpd/bgp_damp.h"
70 #include "bgpd/bgp_mplsvpn.h"
72 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
73 #include "bgpd/rfapi/rfapi_backend.h"
75 #include "bgpd/bgp_evpn.h"
76 #include "bgpd/bgp_advertise.h"
77 #include "bgpd/bgp_network.h"
78 #include "bgpd/bgp_vty.h"
79 #include "bgpd/bgp_mpath.h"
80 #include "bgpd/bgp_nht.h"
81 #include "bgpd/bgp_updgrp.h"
82 #include "bgpd/bgp_bfd.h"
83 #include "bgpd/bgp_memory.h"
84 #include "bgpd/bgp_evpn_vty.h"
85 #include "bgpd/bgp_keepalives.h"
86 #include "bgpd/bgp_io.h"
87 #include "bgpd/bgp_ecommunity.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_labelpool.h"
90 #include "bgpd/bgp_pbr.h"
91 #include "bgpd/bgp_addpath.h"
92 #include "bgpd/bgp_evpn_private.h"
93 #include "bgpd/bgp_evpn_mh.h"
94 #include "bgpd/bgp_mac.h"
96 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
97 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
98 DEFINE_QOBJ_TYPE(bgp_master
);
99 DEFINE_QOBJ_TYPE(bgp
);
100 DEFINE_QOBJ_TYPE(peer
);
101 DEFINE_HOOK(bgp_inst_delete
, (struct bgp
*bgp
), (bgp
));
103 /* BGP process wide configuration. */
104 static struct bgp_master bgp_master
;
106 /* BGP process wide configuration pointer to export. */
107 struct bgp_master
*bm
;
109 /* BGP community-list. */
110 struct community_list_handler
*bgp_clist
;
112 unsigned int multipath_num
= MULTIPATH_NUM
;
114 /* Number of bgp instances configured for suppress fib config */
115 unsigned int bgp_suppress_fib_count
;
117 static void bgp_if_finish(struct bgp
*bgp
);
118 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
120 extern struct zclient
*zclient
;
122 /* handle main socket creation or deletion */
123 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
125 static int bgp_server_main_created
;
126 struct listnode
*node
;
130 if (bgp_server_main_created
)
132 if (list_isempty(bm
->addresses
)) {
133 if (bgp_socket(bgp
, bm
->port
, NULL
) < 0)
134 return BGP_ERR_INVALID_VALUE
;
136 for (ALL_LIST_ELEMENTS_RO(bm
->addresses
, node
, address
))
137 if (bgp_socket(bgp
, bm
->port
, address
) < 0)
138 return BGP_ERR_INVALID_VALUE
;
140 bgp_server_main_created
= 1;
143 if (!bgp_server_main_created
)
146 bgp_server_main_created
= 0;
150 void bgp_session_reset(struct peer
*peer
)
152 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
153 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
154 peer_delete(peer
->doppelganger
);
156 BGP_EVENT_ADD(peer
, BGP_Stop
);
160 * During session reset, we may delete the doppelganger peer, which would
161 * be the next node to the current node. If the session reset was invoked
162 * during walk of peer list, we would end up accessing the freed next
163 * node. This function moves the next node along.
165 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
170 n
= (nnode
) ? *nnode
: NULL
;
171 npeer
= (n
) ? listgetdata(n
) : NULL
;
173 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
174 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
175 PEER_FLAG_CONFIG_NODE
))) {
176 if (peer
->doppelganger
== npeer
)
177 /* nnode and *nnode are confirmed to be non-NULL here */
178 *nnode
= (*nnode
)->next
;
179 peer_delete(peer
->doppelganger
);
182 BGP_EVENT_ADD(peer
, BGP_Stop
);
185 /* BGP global flag manipulation. */
186 int bgp_option_set(int flag
)
190 case BGP_OPT_NO_LISTEN
:
191 case BGP_OPT_NO_ZEBRA
:
192 SET_FLAG(bm
->options
, flag
);
195 return BGP_ERR_INVALID_FLAG
;
200 int bgp_option_unset(int flag
)
204 case BGP_OPT_NO_ZEBRA
:
206 UNSET_FLAG(bm
->options
, flag
);
209 return BGP_ERR_INVALID_FLAG
;
214 int bgp_option_check(int flag
)
216 return CHECK_FLAG(bm
->options
, flag
);
219 /* set the bgp no-rib option during runtime and remove installed routes */
220 void bgp_option_norib_set_runtime(void)
223 struct listnode
*node
;
227 if (bgp_option_check(BGP_OPT_NO_FIB
))
230 bgp_option_set(BGP_OPT_NO_FIB
);
232 zlog_info("Disabled BGP route installation to RIB (Zebra)");
234 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
235 FOREACH_AFI_SAFI (afi
, safi
) {
237 * Stop a crash, more work is needed
238 * here to properly add/remove these types of
241 if (!bgp_fibupd_safi(safi
))
244 bgp_zebra_withdraw_table_all_subtypes(bgp
, afi
, safi
);
248 zlog_info("All routes have been withdrawn from RIB (Zebra)");
251 /* unset the bgp no-rib option during runtime and announce routes to Zebra */
252 void bgp_option_norib_unset_runtime(void)
255 struct listnode
*node
;
259 if (!bgp_option_check(BGP_OPT_NO_FIB
))
262 bgp_option_unset(BGP_OPT_NO_FIB
);
264 zlog_info("Enabled BGP route installation to RIB (Zebra)");
266 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
267 FOREACH_AFI_SAFI (afi
, safi
) {
269 * Stop a crash, more work is needed
270 * here to properly add/remove these types
271 * of routes from zebra
273 if (!bgp_fibupd_safi(safi
))
276 bgp_zebra_announce_table_all_subtypes(bgp
, afi
, safi
);
280 zlog_info("All routes have been installed in RIB (Zebra)");
283 /* Internal function to set BGP structure configureation flag. */
284 static void bgp_config_set(struct bgp
*bgp
, int config
)
286 SET_FLAG(bgp
->config
, config
);
289 static void bgp_config_unset(struct bgp
*bgp
, int config
)
291 UNSET_FLAG(bgp
->config
, config
);
294 static int bgp_config_check(struct bgp
*bgp
, int config
)
296 return CHECK_FLAG(bgp
->config
, config
);
299 /* Set BGP router identifier; distinguish between explicit config and other
302 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
306 struct listnode
*node
, *nnode
;
308 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
311 /* EVPN uses router id in RD, withdraw them */
312 if (is_evpn_enabled())
313 bgp_evpn_handle_router_id_update(bgp
, true);
315 vpn_handle_router_id_update(bgp
, true, is_config
);
317 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
319 /* Set all peer's local identifier with this value. */
320 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
321 IPV4_ADDR_COPY(&peer
->local_id
, id
);
323 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
324 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
325 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
330 /* EVPN uses router id in RD, update them */
331 if (is_evpn_enabled())
332 bgp_evpn_handle_router_id_update(bgp
, false);
334 vpn_handle_router_id_update(bgp
, false, is_config
);
339 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
341 struct listnode
*node
, *nnode
;
343 struct in_addr
*addr
= NULL
;
345 if (router_id
!= NULL
)
346 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
348 if (vrf_id
== VRF_DEFAULT
) {
349 /* Router-id change for default VRF has to also update all
351 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
352 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
356 bgp
->router_id_zebra
= *addr
;
358 addr
= &bgp
->router_id_zebra
;
360 if (!bgp
->router_id_static
.s_addr
) {
361 /* Router ID is updated if there are no active
364 if (bgp
->established_peers
== 0) {
365 if (BGP_DEBUG(zebra
, ZEBRA
))
367 "RID change : vrf %s(%u), RTR ID %pI4",
371 * if old router-id was 0x0, set flag
372 * to use this new value
374 bgp_router_id_set(bgp
, addr
,
375 (bgp
->router_id
.s_addr
383 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
386 bgp
->router_id_zebra
= *addr
;
388 addr
= &bgp
->router_id_zebra
;
390 if (!bgp
->router_id_static
.s_addr
) {
391 /* Router ID is updated if there are no active
394 if (bgp
->established_peers
== 0) {
395 if (BGP_DEBUG(zebra
, ZEBRA
))
397 "RID change : vrf %s(%u), RTR ID %pI4",
401 * if old router-id was 0x0, set flag
402 * to use this new value
404 bgp_router_id_set(bgp
, addr
,
405 (bgp
->router_id
.s_addr
416 void bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
418 bgp
->router_id_static
= id
;
419 bgp_router_id_set(bgp
,
420 id
.s_addr
!= INADDR_ANY
? &id
: &bgp
->router_id_zebra
,
421 true /* is config */);
424 void bm_wait_for_fib_set(bool set
)
426 bool send_msg
= false;
428 if (bm
->wait_for_fib
== set
)
431 bm
->wait_for_fib
= set
;
433 if (bgp_suppress_fib_count
== 0)
435 bgp_suppress_fib_count
++;
437 bgp_suppress_fib_count
--;
438 if (bgp_suppress_fib_count
== 0)
442 if (send_msg
&& zclient
)
443 zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST
,
447 /* Set the suppress fib pending for the bgp configuration */
448 void bgp_suppress_fib_pending_set(struct bgp
*bgp
, bool set
)
450 bool send_msg
= false;
452 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
)
456 SET_FLAG(bgp
->flags
, BGP_FLAG_SUPPRESS_FIB_PENDING
);
457 /* Send msg to zebra for the first instance of bgp enabled
460 if (bgp_suppress_fib_count
== 0)
462 bgp_suppress_fib_count
++;
464 UNSET_FLAG(bgp
->flags
, BGP_FLAG_SUPPRESS_FIB_PENDING
);
465 bgp_suppress_fib_count
--;
467 /* Send msg to zebra if there are no instances enabled
470 if (bgp_suppress_fib_count
== 0)
473 /* Send route notify request to RIB */
475 if (BGP_DEBUG(zebra
, ZEBRA
))
476 zlog_debug("Sending ZEBRA_ROUTE_NOTIFY_REQUEST");
479 zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST
,
484 /* BGP's cluster-id control. */
485 void bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
488 struct listnode
*node
, *nnode
;
490 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
491 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
494 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
495 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
497 /* Clear all IBGP peer. */
498 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
499 if (peer
->sort
!= BGP_PEER_IBGP
)
502 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
503 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
504 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
505 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
510 void bgp_cluster_id_unset(struct bgp
*bgp
)
513 struct listnode
*node
, *nnode
;
515 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
518 bgp
->cluster_id
.s_addr
= 0;
519 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
521 /* Clear all IBGP peer. */
522 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
523 if (peer
->sort
!= BGP_PEER_IBGP
)
526 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
527 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
528 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
529 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
534 /* BGP timer configuration. */
535 void bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
,
536 uint32_t connect_retry
, uint32_t delayopen
)
538 bgp
->default_keepalive
=
539 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
540 bgp
->default_holdtime
= holdtime
;
541 bgp
->default_connect_retry
= connect_retry
;
542 bgp
->default_delayopen
= delayopen
;
545 /* mostly for completeness - CLI uses its own defaults */
546 void bgp_timers_unset(struct bgp
*bgp
)
548 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
549 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
550 bgp
->default_connect_retry
= BGP_DEFAULT_CONNECT_RETRY
;
551 bgp
->default_delayopen
= BGP_DEFAULT_DELAYOPEN
;
554 /* BGP confederation configuration. */
555 void bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
558 struct listnode
*node
, *nnode
;
564 /* Remember - were we doing confederation before? */
565 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
567 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
569 /* If we were doing confederation already, this is just an external
570 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
571 were not doing confederation before, reset all EBGP sessions. */
572 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
573 enum bgp_peer_sort ptype
= peer_sort(peer
);
575 /* We're looking for peers who's AS is not local or part of our
577 if (already_confed
) {
578 if (ptype
== BGP_PEER_EBGP
) {
580 if (BGP_IS_VALID_STATE_FOR_NOTIF(
583 PEER_DOWN_CONFED_ID_CHANGE
;
585 peer
, BGP_NOTIFY_CEASE
,
586 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
588 bgp_session_reset_safe(peer
, &nnode
);
591 /* Not doign confederation before, so reset every
594 if (ptype
!= BGP_PEER_IBGP
) {
595 /* Reset the local_as to be our EBGP one */
596 if (ptype
== BGP_PEER_EBGP
)
598 if (BGP_IS_VALID_STATE_FOR_NOTIF(
601 PEER_DOWN_CONFED_ID_CHANGE
;
603 peer
, BGP_NOTIFY_CEASE
,
604 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
606 bgp_session_reset_safe(peer
, &nnode
);
613 void bgp_confederation_id_unset(struct bgp
*bgp
)
616 struct listnode
*node
, *nnode
;
619 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
621 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
622 /* We're looking for peers who's AS is not local */
623 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
624 peer
->local_as
= bgp
->as
;
625 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
626 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
627 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
628 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
632 bgp_session_reset_safe(peer
, &nnode
);
637 /* Is an AS part of the confed or not? */
638 bool bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
645 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
646 if (bgp
->confed_peers
[i
] == as
)
652 /* Add an AS to the confederation set. */
653 void bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
656 struct listnode
*node
, *nnode
;
661 if (bgp_confederation_peers_check(bgp
, as
))
665 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
666 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
668 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
669 bgp
->confed_peers_cnt
++;
671 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
672 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
673 if (peer
->as
== as
) {
674 (void)peer_sort(peer
);
675 peer
->local_as
= bgp
->as
;
676 if (BGP_IS_VALID_STATE_FOR_NOTIF(
679 PEER_DOWN_CONFED_PEER_CHANGE
;
681 peer
, BGP_NOTIFY_CEASE
,
682 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
684 bgp_session_reset_safe(peer
, &nnode
);
690 /* Delete an AS from the confederation set. */
691 void bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
696 struct listnode
*node
, *nnode
;
701 if (!bgp_confederation_peers_check(bgp
, as
))
704 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
705 if (bgp
->confed_peers
[i
] == as
)
706 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
707 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
709 bgp
->confed_peers_cnt
--;
711 if (bgp
->confed_peers_cnt
== 0) {
712 if (bgp
->confed_peers
)
713 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
714 bgp
->confed_peers
= NULL
;
717 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
718 bgp
->confed_peers_cnt
* sizeof(as_t
));
720 /* Now reset any peer who's remote AS has just been removed from the
722 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
723 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
724 if (peer
->as
== as
) {
725 (void)peer_sort(peer
);
726 peer
->local_as
= bgp
->confed_id
;
727 if (BGP_IS_VALID_STATE_FOR_NOTIF(
730 PEER_DOWN_CONFED_PEER_CHANGE
;
732 peer
, BGP_NOTIFY_CEASE
,
733 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
735 bgp_session_reset_safe(peer
, &nnode
);
741 /* Local preference configuration. */
742 void bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
747 bgp
->default_local_pref
= local_pref
;
750 void bgp_default_local_preference_unset(struct bgp
*bgp
)
755 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
758 /* Local preference configuration. */
759 void bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
,
765 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
768 void bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
772 bgp
->default_subgroup_pkt_queue_max
=
773 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
776 /* Listen limit configuration. */
777 void bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
782 bgp
->dynamic_neighbors_limit
= listen_limit
;
785 void bgp_listen_limit_unset(struct bgp
*bgp
)
790 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
793 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
794 afi_t
*afi
, safi_t
*safi
)
796 /* Map from IANA values to internal values, return error if
797 * values are unrecognized.
799 *afi
= afi_iana2int(pkt_afi
);
800 *safi
= safi_iana2int(pkt_safi
);
801 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
807 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
808 iana_safi_t
*pkt_safi
)
810 /* Map from internal values to IANA values, return error if
811 * internal values are bad (unexpected).
813 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
815 *pkt_afi
= afi_int2iana(afi
);
816 *pkt_safi
= safi_int2iana(safi
);
820 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
829 afid
= afindex(afi
, safi
);
830 if (afid
>= BGP_AF_MAX
)
834 assert(peer
->peer_af_array
[afid
] == NULL
);
836 /* Allocate new peer af */
837 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
839 peer
->peer_af_array
[afid
] = af
;
844 bgp
->af_peer_count
[afi
][safi
]++;
849 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
856 afid
= afindex(afi
, safi
);
857 if (afid
>= BGP_AF_MAX
)
860 return peer
->peer_af_array
[afid
];
863 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
872 afid
= afindex(afi
, safi
);
873 if (afid
>= BGP_AF_MAX
)
876 af
= peer
->peer_af_array
[afid
];
881 bgp_soft_reconfig_table_task_cancel(bgp
, bgp
->rib
[afi
][safi
], peer
);
883 bgp_stop_announce_route_timer(af
);
885 if (PAF_SUBGRP(af
)) {
886 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
887 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
888 af
->subgroup
->update_group
->id
,
889 af
->subgroup
->id
, peer
->host
);
893 update_subgroup_remove_peer(af
->subgroup
, af
);
895 if (bgp
->af_peer_count
[afi
][safi
])
896 bgp
->af_peer_count
[afi
][safi
]--;
898 peer
->peer_af_array
[afid
] = NULL
;
899 XFREE(MTYPE_BGP_PEER_AF
, af
);
903 /* Peer comparison function for sorting. */
904 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
906 if (p1
->group
&& !p2
->group
)
909 if (!p1
->group
&& p2
->group
)
912 if (p1
->group
== p2
->group
) {
913 if (p1
->conf_if
&& !p2
->conf_if
)
916 if (!p1
->conf_if
&& p2
->conf_if
)
919 if (p1
->conf_if
&& p2
->conf_if
)
920 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
922 return strcmp(p1
->group
->name
, p2
->group
->name
);
924 return sockunion_cmp(&p1
->su
, &p2
->su
);
927 static unsigned int peer_hash_key_make(const void *p
)
929 const struct peer
*peer
= p
;
930 return sockunion_hash(&peer
->su
);
933 static bool peer_hash_same(const void *p1
, const void *p2
)
935 const struct peer
*peer1
= p1
;
936 const struct peer
*peer2
= p2
;
937 return (sockunion_same(&peer1
->su
, &peer2
->su
)
938 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
939 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
942 void peer_flag_inherit(struct peer
*peer
, uint64_t flag
)
946 /* Skip if peer is not a peer-group member. */
947 if (!peer_group_active(peer
))
950 /* Unset override flag to signal inheritance from peer-group. */
951 UNSET_FLAG(peer
->flags_override
, flag
);
954 * Inherit flag state from peer-group. If the flag of the peer-group is
955 * not being inverted, the peer must inherit the inverse of the current
956 * peer-group flag state.
958 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
959 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
960 && CHECK_FLAG(peer
->flags_invert
, flag
))
961 COND_FLAG(peer
->flags
, flag
, !group_val
);
963 COND_FLAG(peer
->flags
, flag
, group_val
);
966 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
968 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
971 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
976 /* Skip if peer is not a peer-group member. */
977 if (!peer_group_active(peer
))
980 /* Unset override flag to signal inheritance from peer-group. */
981 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
984 * Inherit flag state from peer-group. If the flag of the peer-group is
985 * not being inverted, the peer must inherit the inverse of the current
986 * peer-group flag state.
988 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
989 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
990 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
991 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
993 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
996 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
997 static inline enum bgp_peer_sort
peer_calc_sort(struct peer
*peer
)
1004 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1005 if (peer
->as_type
== AS_INTERNAL
)
1006 return BGP_PEER_IBGP
;
1008 else if (peer
->as_type
== AS_EXTERNAL
)
1009 return BGP_PEER_EBGP
;
1011 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
1013 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
1020 assert(peer
->group
);
1021 peer1
= listnode_head(peer
->group
->peer
);
1026 return BGP_PEER_INTERNAL
;
1030 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1031 if (peer
->local_as
== 0)
1032 return BGP_PEER_INTERNAL
;
1034 if (peer
->local_as
== peer
->as
) {
1035 if (bgp
->as
== bgp
->confed_id
) {
1036 if (peer
->local_as
== bgp
->as
)
1037 return BGP_PEER_IBGP
;
1039 return BGP_PEER_EBGP
;
1041 if (peer
->local_as
== bgp
->confed_id
)
1042 return BGP_PEER_EBGP
;
1044 return BGP_PEER_IBGP
;
1048 if (bgp_confederation_peers_check(bgp
, peer
->as
))
1049 return BGP_PEER_CONFED
;
1051 return BGP_PEER_EBGP
;
1053 if (peer
->as_type
== AS_UNSPECIFIED
) {
1054 /* check if in peer-group with AS information */
1056 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
1057 if (peer
->group
->conf
->as_type
1060 == peer
->group
->conf
->as
)
1061 return BGP_PEER_IBGP
;
1063 return BGP_PEER_EBGP
;
1064 } else if (peer
->group
->conf
->as_type
1066 return BGP_PEER_IBGP
;
1068 return BGP_PEER_EBGP
;
1070 /* no AS information anywhere, let caller know */
1071 return BGP_PEER_UNSPECIFIED
;
1072 } else if (peer
->as_type
!= AS_SPECIFIED
)
1073 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1076 return (peer
->local_as
== 0
1078 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1083 /* Calculate and cache the peer "sort" */
1084 enum bgp_peer_sort
peer_sort(struct peer
*peer
)
1086 peer
->sort
= peer_calc_sort(peer
);
1090 enum bgp_peer_sort
peer_sort_lookup(struct peer
*peer
)
1095 static void peer_free(struct peer
*peer
)
1100 assert(peer
->status
== Deleted
);
1104 /* this /ought/ to have been done already through bgp_stop earlier,
1105 * but just to be sure..
1107 bgp_timer_set(peer
);
1108 bgp_reads_off(peer
);
1109 bgp_writes_off(peer
);
1110 assert(!peer
->t_write
);
1111 assert(!peer
->t_read
);
1112 BGP_EVENT_FLUSH(peer
);
1114 pthread_mutex_destroy(&peer
->io_mtx
);
1116 /* Free connected nexthop, if present */
1117 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1118 && !peer_dynamic_neighbor(peer
))
1119 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1122 FOREACH_AFI_SAFI (afi
, safi
) {
1123 if (peer
->filter
[afi
][safi
].advmap
.aname
)
1124 XFREE(MTYPE_BGP_FILTER_NAME
,
1125 peer
->filter
[afi
][safi
].advmap
.aname
);
1126 if (peer
->filter
[afi
][safi
].advmap
.cname
)
1127 XFREE(MTYPE_BGP_FILTER_NAME
,
1128 peer
->filter
[afi
][safi
].advmap
.cname
);
1131 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1133 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1134 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1135 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1136 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1138 /* Update source configuration. */
1139 if (peer
->update_source
) {
1140 sockunion_free(peer
->update_source
);
1141 peer
->update_source
= NULL
;
1144 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1146 XFREE(MTYPE_BGP_NOTIFICATION
, peer
->notify
.data
);
1147 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1149 if (peer
->clear_node_queue
)
1150 work_queue_free_and_null(&peer
->clear_node_queue
);
1152 bgp_sync_delete(peer
);
1154 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1156 /* Remove BFD configuration. */
1157 if (peer
->bfd_config
)
1158 bgp_peer_remove_bfd_config(peer
);
1160 FOREACH_AFI_SAFI (afi
, safi
)
1161 bgp_addpath_set_peer_type(peer
, afi
, safi
, BGP_ADDPATH_NONE
);
1163 bgp_unlock(peer
->bgp
);
1165 memset(peer
, 0, sizeof(struct peer
));
1167 XFREE(MTYPE_BGP_PEER
, peer
);
1170 /* increase reference count on a struct peer */
1171 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1173 assert(peer
&& (peer
->lock
>= 0));
1180 /* decrease reference count on a struct peer
1181 * struct peer is freed and NULL returned if last reference
1183 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1185 assert(peer
&& (peer
->lock
> 0));
1189 if (peer
->lock
== 0) {
1196 /* BGP GR changes */
1198 int bgp_global_gr_init(struct bgp
*bgp
)
1200 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1201 zlog_debug("%s called ..", __func__
);
1203 int local_GLOBAL_GR_FSM
[BGP_GLOBAL_GR_MODE
][BGP_GLOBAL_GR_EVENT_CMD
] = {
1204 /* GLOBAL_HELPER Mode */
1207 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1208 GLOBAL_GR
, GLOBAL_INVALID
,
1209 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1210 GLOBAL_DISABLE
, GLOBAL_INVALID
1212 /* GLOBAL_GR Mode */
1215 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1216 GLOBAL_GR
, GLOBAL_HELPER
,
1217 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1218 GLOBAL_DISABLE
, GLOBAL_INVALID
1220 /* GLOBAL_DISABLE Mode */
1223 /*GLOBAL_GR_cmd */ /*no_Global_GR_cmd*/
1224 GLOBAL_GR
, GLOBAL_INVALID
,
1225 /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
1226 GLOBAL_INVALID
, GLOBAL_HELPER
1228 /* GLOBAL_INVALID Mode */
1231 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1232 GLOBAL_INVALID
, GLOBAL_INVALID
,
1233 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1234 GLOBAL_INVALID
, GLOBAL_INVALID
1237 memcpy(bgp
->GLOBAL_GR_FSM
, local_GLOBAL_GR_FSM
,
1238 sizeof(local_GLOBAL_GR_FSM
));
1240 bgp
->global_gr_present_state
= GLOBAL_HELPER
;
1241 bgp
->present_zebra_gr_state
= ZEBRA_GR_DISABLE
;
1243 return BGP_GR_SUCCESS
;
1246 int bgp_peer_gr_init(struct peer
*peer
)
1248 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1249 zlog_debug("%s called ..", __func__
);
1251 struct bgp_peer_gr local_Peer_GR_FSM
[BGP_PEER_GR_MODE
]
1252 [BGP_PEER_GR_EVENT_CMD
] = {
1254 /* PEER_HELPER Mode */
1255 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1256 { PEER_GR
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1257 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1258 {PEER_DISABLE
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1259 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1260 { PEER_INVALID
, NULL
}, {PEER_GLOBAL_INHERIT
,
1261 bgp_peer_gr_action
}
1265 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1266 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1267 bgp_peer_gr_action
},
1268 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1269 {PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1270 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1271 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1274 /* PEER_DISABLE Mode */
1275 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1276 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1277 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1278 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1279 bgp_peer_gr_action
},
1280 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1281 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1284 /* PEER_INVALID Mode */
1285 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1286 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1287 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1288 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1289 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1290 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1293 /* PEER_GLOBAL_INHERIT Mode */
1294 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1295 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1296 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1297 { PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1298 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1299 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1302 memcpy(&peer
->PEER_GR_FSM
, local_Peer_GR_FSM
,
1303 sizeof(local_Peer_GR_FSM
));
1304 peer
->peer_gr_present_state
= PEER_GLOBAL_INHERIT
;
1305 bgp_peer_move_to_gr_mode(peer
, PEER_GLOBAL_INHERIT
);
1307 return BGP_GR_SUCCESS
;
1310 static void bgp_srv6_init(struct bgp
*bgp
)
1312 bgp
->srv6_enabled
= false;
1313 memset(bgp
->srv6_locator_name
, 0, sizeof(bgp
->srv6_locator_name
));
1314 bgp
->srv6_locator_chunks
= list_new();
1315 bgp
->srv6_functions
= list_new();
1318 static void bgp_srv6_cleanup(struct bgp
*bgp
)
1320 if (bgp
->srv6_locator_chunks
)
1321 list_delete(&bgp
->srv6_locator_chunks
);
1322 if (bgp
->srv6_functions
)
1323 list_delete(&bgp
->srv6_functions
);
1326 /* Allocate new peer object, implicitely locked. */
1327 struct peer
*peer_new(struct bgp
*bgp
)
1334 /* bgp argument is absolutely required */
1337 /* Allocate new peer. */
1338 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1340 /* Set default value. */
1342 peer
->v_start
= BGP_INIT_START_TIMER
;
1343 peer
->v_connect
= bgp
->default_connect_retry
;
1344 peer
->status
= Idle
;
1345 peer
->ostatus
= Idle
;
1346 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1347 peer
->bgp
= bgp_lock(bgp
);
1348 peer
= peer_lock(peer
); /* initial reference */
1349 peer
->local_role
= ROLE_UNDEFINED
;
1350 peer
->remote_role
= ROLE_UNDEFINED
;
1351 peer
->password
= NULL
;
1352 peer
->max_packet_size
= BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE
;
1354 /* Set default flags. */
1355 FOREACH_AFI_SAFI (afi
, safi
) {
1356 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1357 SET_FLAG(peer
->af_flags
[afi
][safi
],
1358 PEER_FLAG_SEND_EXT_COMMUNITY
);
1359 SET_FLAG(peer
->af_flags
[afi
][safi
],
1360 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1362 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1363 PEER_FLAG_SEND_COMMUNITY
);
1364 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1365 PEER_FLAG_SEND_EXT_COMMUNITY
);
1366 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1367 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1368 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1369 peer
->soo
[afi
][safi
] = NULL
;
1372 /* set nexthop-unchanged for l2vpn evpn by default */
1373 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1374 PEER_FLAG_NEXTHOP_UNCHANGED
);
1376 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1378 /* Initialize per peer bgp GR FSM */
1379 bgp_peer_gr_init(peer
);
1381 /* Create buffers. */
1382 peer
->ibuf
= stream_fifo_new();
1383 peer
->obuf
= stream_fifo_new();
1384 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1386 /* We use a larger buffer for peer->obuf_work in the event that:
1387 * - We RX a BGP_UPDATE where the attributes alone are just
1388 * under BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE.
1389 * - The user configures an outbound route-map that does many as-path
1390 * prepends or adds many communities. At most they can have
1391 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1392 * large they can make the attributes.
1394 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1395 * bounds checking for every single attribute as we construct an
1399 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1401 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1403 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1405 bgp_sync_init(peer
);
1407 /* Get service port number. */
1408 sp
= getservbyname("bgp", "tcp");
1409 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1411 QOBJ_REG(peer
, peer
);
1416 * This function is invoked when a duplicate peer structure associated with
1417 * a neighbor is being deleted. If this about-to-be-deleted structure is
1418 * the one with all the config, then we have to copy over the info.
1420 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1422 struct peer_af
*paf
;
1430 /* The following function is used by both peer group config copy to
1431 * individual peer and when we transfer config
1433 if (peer_src
->change_local_as
)
1434 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1436 /* peer flags apply */
1437 peer_dst
->flags
= peer_src
->flags
;
1439 peer_dst
->peer_gr_present_state
= peer_src
->peer_gr_present_state
;
1440 peer_dst
->peer_gr_new_status_flag
= peer_src
->peer_gr_new_status_flag
;
1442 peer_dst
->local_as
= peer_src
->local_as
;
1443 peer_dst
->port
= peer_src
->port
;
1444 /* copy tcp_mss value */
1445 peer_dst
->tcp_mss
= peer_src
->tcp_mss
;
1446 (void)peer_sort(peer_dst
);
1447 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1448 peer_dst
->local_role
= peer_src
->local_role
;
1450 peer_dst
->max_packet_size
= peer_src
->max_packet_size
;
1453 peer_dst
->holdtime
= peer_src
->holdtime
;
1454 peer_dst
->keepalive
= peer_src
->keepalive
;
1455 peer_dst
->connect
= peer_src
->connect
;
1456 peer_dst
->delayopen
= peer_src
->delayopen
;
1457 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1458 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1459 peer_dst
->routeadv
= peer_src
->routeadv
;
1460 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1461 peer_dst
->v_delayopen
= peer_src
->v_delayopen
;
1463 /* password apply */
1464 if (peer_src
->password
&& !peer_dst
->password
)
1465 peer_dst
->password
=
1466 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1468 FOREACH_AFI_SAFI (afi
, safi
) {
1469 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1470 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1471 peer_dst
->allowas_in
[afi
][safi
] =
1472 peer_src
->allowas_in
[afi
][safi
];
1473 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1474 peer_dst
->addpath_type
[afi
][safi
] =
1475 peer_src
->addpath_type
[afi
][safi
];
1478 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1479 paf
= peer_src
->peer_af_array
[afidx
];
1481 if (!peer_af_find(peer_dst
, paf
->afi
, paf
->safi
))
1482 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1486 /* update-source apply */
1487 if (peer_src
->update_source
) {
1488 if (peer_dst
->update_source
)
1489 sockunion_free(peer_dst
->update_source
);
1490 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1491 peer_dst
->update_source
=
1492 sockunion_dup(peer_src
->update_source
);
1493 } else if (peer_src
->update_if
) {
1494 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1495 if (peer_dst
->update_source
) {
1496 sockunion_free(peer_dst
->update_source
);
1497 peer_dst
->update_source
= NULL
;
1499 peer_dst
->update_if
=
1500 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1503 if (peer_src
->ifname
) {
1504 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1507 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1511 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1512 struct interface
*ifp
)
1514 struct connected
*ifc
;
1517 struct listnode
*node
;
1519 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1520 * IPv4 address of the other end.
1522 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1523 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1524 prefix_copy(&p
, CONNECTED_PREFIX(ifc
));
1525 if (p
.prefixlen
== 30) {
1526 peer
->su
.sa
.sa_family
= AF_INET
;
1527 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1529 peer
->su
.sin
.sin_addr
.s_addr
=
1531 else if (addr
% 4 == 2)
1532 peer
->su
.sin
.sin_addr
.s_addr
=
1534 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1535 peer
->su
.sin
.sin_len
=
1536 sizeof(struct sockaddr_in
);
1537 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1539 } else if (p
.prefixlen
== 31) {
1540 peer
->su
.sa
.sa_family
= AF_INET
;
1541 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1543 peer
->su
.sin
.sin_addr
.s_addr
=
1546 peer
->su
.sin
.sin_addr
.s_addr
=
1548 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1549 peer
->su
.sin
.sin_len
=
1550 sizeof(struct sockaddr_in
);
1551 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1553 } else if (bgp_debug_neighbor_events(peer
))
1555 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1563 static bool bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1564 struct interface
*ifp
)
1566 struct nbr_connected
*ifc_nbr
;
1568 /* Have we learnt the peer's IPv6 link-local address? */
1569 if (ifp
->nbr_connected
1570 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1571 peer
->su
.sa
.sa_family
= AF_INET6
;
1572 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1573 sizeof(struct in6_addr
));
1575 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1577 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1585 * Set or reset the peer address socketunion structure based on the
1586 * learnt/derived peer address. If the address has changed, update the
1587 * password on the listen socket, if needed.
1589 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1591 struct interface
*ifp
;
1593 int peer_addr_updated
= 0;
1599 * Our peer structure is stored in the bgp->peerhash
1600 * release it before we modify anything.
1602 hash_release(peer
->bgp
->peerhash
, peer
);
1604 prev_family
= peer
->su
.sa
.sa_family
;
1605 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1607 /* If BGP unnumbered is not "v6only", we first see if we can
1609 * peer's IPv4 address.
1611 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1613 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1615 /* If "v6only" or we can't derive peer's IPv4 address, see if
1617 * learnt the peer's IPv6 link-local address. This is from the
1619 * IPv6 address in router advertisement.
1621 if (!peer_addr_updated
)
1623 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1625 /* If we could derive the peer address, we may need to install the
1627 * configured for the peer, if any, on the listen socket. Otherwise,
1629 * that peer's address is not available and uninstall the password, if
1632 if (peer_addr_updated
) {
1633 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1634 && prev_family
== AF_UNSPEC
)
1637 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1638 && prev_family
!= AF_UNSPEC
)
1639 bgp_md5_unset(peer
);
1640 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1641 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1645 * Since our su changed we need to del/add peer to the peerhash
1647 (void)hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1650 void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1652 struct bgp_dest
*dest
, *ndest
;
1653 struct bgp_table
*table
;
1655 for (dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); dest
;
1656 dest
= bgp_route_next(dest
)) {
1657 table
= bgp_dest_get_bgp_table_info(dest
);
1658 if (table
!= NULL
) {
1659 /* Special handling for 2-level routing
1661 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1662 || safi
== SAFI_EVPN
) {
1663 for (ndest
= bgp_table_top(table
); ndest
;
1664 ndest
= bgp_route_next(ndest
))
1665 bgp_process(bgp
, ndest
, afi
, safi
);
1667 bgp_process(bgp
, dest
, afi
, safi
);
1672 /* Force a bestpath recalculation for all prefixes. This is used
1673 * when 'bgp bestpath' commands are entered.
1675 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1680 FOREACH_AFI_SAFI (afi
, safi
) {
1681 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1686 * Create new BGP peer.
1688 * conf_if and su are mutually exclusive if configuring from the cli.
1689 * If we are handing a doppelganger, then we *must* pass in both
1690 * the original peer's su and conf_if, so that we can appropriately
1691 * track the bgp->peerhash( ie we don't want to remove the current
1692 * one from the config ).
1694 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1695 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1696 int as_type
, struct peer_group
*group
)
1700 char buf
[SU_ADDRSTRLEN
];
1704 peer
= peer_new(bgp
);
1706 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1710 bgp_peer_conf_if_to_su_update(peer
);
1711 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1712 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1715 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1716 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1717 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1719 peer
->local_as
= local_as
;
1720 peer
->as
= remote_as
;
1721 peer
->as_type
= as_type
;
1722 peer
->local_id
= bgp
->router_id
;
1723 peer
->v_holdtime
= bgp
->default_holdtime
;
1724 peer
->v_keepalive
= bgp
->default_keepalive
;
1725 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1726 ? BGP_DEFAULT_IBGP_ROUTEADV
1727 : BGP_DEFAULT_EBGP_ROUTEADV
;
1728 if (bgp_config_inprocess())
1729 peer
->shut_during_cfg
= true;
1731 peer
= peer_lock(peer
); /* bgp peer list reference */
1732 peer
->group
= group
;
1733 listnode_add_sort(bgp
->peer
, peer
);
1734 (void)hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1736 /* Adjust update-group coalesce timer heuristics for # peers. */
1737 if (bgp
->heuristic_coalesce
) {
1738 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1740 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1741 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1744 active
= peer_active(peer
);
1746 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
)
1747 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1749 peer
->last_reset
= PEER_DOWN_NOAFI_ACTIVATED
;
1752 /* Last read and reset time set */
1753 peer
->readtime
= peer
->resettime
= monotime(NULL
);
1755 /* Default TTL set. */
1756 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: BGP_DEFAULT_TTL
;
1758 /* Default configured keepalives count for shutdown rtt command */
1759 peer
->rtt_keepalive_conf
= 1;
1761 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1763 /* If 'bgp default <afi>-<safi>' is configured, then activate the
1764 * neighbor for the corresponding address family. IPv4 Unicast is
1765 * the only address family enabled by default without expliict
1768 FOREACH_AFI_SAFI (afi
, safi
) {
1769 if (bgp
->default_af
[afi
][safi
]) {
1770 peer
->afc
[afi
][safi
] = 1;
1771 peer_af_create(peer
, afi
, safi
);
1775 /* auto shutdown if configured */
1776 if (bgp
->autoshutdown
)
1777 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1778 /* Set up peer's events and timers. */
1779 else if (!active
&& peer_active(peer
))
1780 bgp_timer_set(peer
);
1782 bgp_peer_gr_flags_update(peer
);
1783 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp
, bgp
->peer
);
1788 /* Make accept BGP peer. This function is only called from the test code */
1789 struct peer
*peer_create_accept(struct bgp
*bgp
)
1793 peer
= peer_new(bgp
);
1795 peer
= peer_lock(peer
); /* bgp peer list reference */
1796 listnode_add_sort(bgp
->peer
, peer
);
1802 * Return true if we have a peer configured to use this afi/safi
1804 bool bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1806 struct listnode
*node
;
1809 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1810 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1813 if (peer
->afc
[afi
][safi
])
1820 /* Change peer's AS number. */
1821 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1823 enum bgp_peer_sort origtype
, newtype
;
1826 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1827 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1828 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1829 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1830 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1832 bgp_session_reset(peer
);
1834 origtype
= peer_sort_lookup(peer
);
1836 peer
->as_type
= as_specified
;
1838 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1839 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1840 && peer
->bgp
->as
!= as
)
1841 peer
->local_as
= peer
->bgp
->confed_id
;
1843 peer
->local_as
= peer
->bgp
->as
;
1845 newtype
= peer_sort(peer
);
1846 /* Advertisement-interval reset */
1847 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1848 peer
->v_routeadv
= (newtype
== BGP_PEER_IBGP
)
1849 ? BGP_DEFAULT_IBGP_ROUTEADV
1850 : BGP_DEFAULT_EBGP_ROUTEADV
;
1854 if (newtype
== BGP_PEER_IBGP
)
1856 else if (origtype
== BGP_PEER_IBGP
)
1857 peer
->ttl
= BGP_DEFAULT_TTL
;
1859 /* reflector-client reset */
1860 if (newtype
!= BGP_PEER_IBGP
) {
1861 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1862 PEER_FLAG_REFLECTOR_CLIENT
);
1863 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1864 PEER_FLAG_REFLECTOR_CLIENT
);
1865 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1866 PEER_FLAG_REFLECTOR_CLIENT
);
1867 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1868 PEER_FLAG_REFLECTOR_CLIENT
);
1869 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1870 PEER_FLAG_REFLECTOR_CLIENT
);
1871 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1872 PEER_FLAG_REFLECTOR_CLIENT
);
1873 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1874 PEER_FLAG_REFLECTOR_CLIENT
);
1875 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1876 PEER_FLAG_REFLECTOR_CLIENT
);
1877 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1878 PEER_FLAG_REFLECTOR_CLIENT
);
1879 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1880 PEER_FLAG_REFLECTOR_CLIENT
);
1881 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1882 PEER_FLAG_REFLECTOR_CLIENT
);
1883 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1884 PEER_FLAG_REFLECTOR_CLIENT
);
1885 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1886 PEER_FLAG_REFLECTOR_CLIENT
);
1889 /* local-as reset */
1890 if (newtype
!= BGP_PEER_EBGP
) {
1891 peer
->change_local_as
= 0;
1892 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1893 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1894 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1898 /* If peer does not exist, create new one. If peer already exists,
1899 set AS number to the peer. */
1900 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1901 as_t
*as
, int as_type
)
1907 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1909 peer
= peer_lookup(bgp
, su
);
1912 /* Not allowed for a dynamic peer. */
1913 if (peer_dynamic_neighbor(peer
)) {
1915 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1918 /* When this peer is a member of peer-group. */
1920 /* peer-group already has AS number/internal/external */
1921 if (peer
->group
->conf
->as
1922 || peer
->group
->conf
->as_type
) {
1923 /* Return peer group's AS number. */
1924 *as
= peer
->group
->conf
->as
;
1925 return BGP_ERR_PEER_GROUP_MEMBER
;
1928 enum bgp_peer_sort peer_sort_type
=
1929 peer_sort(peer
->group
->conf
);
1931 /* Explicit AS numbers used, compare AS numbers */
1932 if (as_type
== AS_SPECIFIED
) {
1933 if (((peer_sort_type
== BGP_PEER_IBGP
)
1934 && (bgp
->as
!= *as
))
1935 || ((peer_sort_type
== BGP_PEER_EBGP
)
1936 && (bgp
->as
== *as
))) {
1938 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1941 /* internal/external used, compare as-types */
1942 if (((peer_sort_type
== BGP_PEER_IBGP
)
1943 && (as_type
!= AS_INTERNAL
))
1944 || ((peer_sort_type
== BGP_PEER_EBGP
)
1945 && (as_type
!= AS_EXTERNAL
))) {
1947 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1952 /* Existing peer's AS number change. */
1953 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1954 || (peer
->as_type
!= as_type
))
1955 peer_as_change(peer
, *as
, as_type
);
1958 return BGP_ERR_NO_INTERFACE_CONFIG
;
1960 /* If the peer is not part of our confederation, and its not an
1961 iBGP peer then spoof the source AS */
1962 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1963 && !bgp_confederation_peers_check(bgp
, *as
)
1965 local_as
= bgp
->confed_id
;
1969 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, NULL
);
1975 const char *bgp_get_name_by_role(uint8_t role
)
1980 case ROLE_RS_SERVER
:
1982 case ROLE_RS_CLIENT
:
1988 case ROLE_UNDEFINED
:
1994 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1995 struct peer
*peer
, afi_t afi
,
1999 int out
= FILTER_OUT
;
2001 uint64_t pflags_ovrd
;
2002 uint8_t *pfilter_ovrd
;
2006 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
2007 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
2009 /* peer af_flags apply */
2010 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
2011 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
2012 ^ peer
->af_flags_invert
[afi
][safi
];
2013 flags_tmp
&= ~pflags_ovrd
;
2015 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
2016 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
2017 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
2018 conf
->af_flags_invert
[afi
][safi
]);
2020 /* maximum-prefix */
2021 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
2022 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
2023 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
2024 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
2027 /* maximum-prefix-out */
2028 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX_OUT
))
2029 PEER_ATTR_INHERIT(peer
, group
, pmax_out
[afi
][safi
]);
2032 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
2033 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
2036 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_SOO
))
2037 PEER_ATTR_INHERIT(peer
, group
, soo
[afi
][safi
]);
2040 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
2041 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
2043 /* default-originate route-map */
2044 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
2045 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
2046 MTYPE_ROUTE_MAP_NAME
);
2047 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
2050 /* inbound filter apply */
2051 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
2052 PEER_STR_ATTR_INHERIT(peer
, group
,
2053 filter
[afi
][safi
].dlist
[in
].name
,
2054 MTYPE_BGP_FILTER_NAME
);
2055 PEER_ATTR_INHERIT(peer
, group
,
2056 filter
[afi
][safi
].dlist
[in
].alist
);
2059 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
2060 PEER_STR_ATTR_INHERIT(peer
, group
,
2061 filter
[afi
][safi
].plist
[in
].name
,
2062 MTYPE_BGP_FILTER_NAME
);
2063 PEER_ATTR_INHERIT(peer
, group
,
2064 filter
[afi
][safi
].plist
[in
].plist
);
2067 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
2068 PEER_STR_ATTR_INHERIT(peer
, group
,
2069 filter
[afi
][safi
].aslist
[in
].name
,
2070 MTYPE_BGP_FILTER_NAME
);
2071 PEER_ATTR_INHERIT(peer
, group
,
2072 filter
[afi
][safi
].aslist
[in
].aslist
);
2075 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
2076 PEER_STR_ATTR_INHERIT(peer
, group
,
2077 filter
[afi
][safi
].map
[in
].name
,
2078 MTYPE_BGP_FILTER_NAME
);
2079 PEER_ATTR_INHERIT(peer
, group
,
2080 filter
[afi
][safi
].map
[RMAP_IN
].map
);
2083 /* outbound filter apply */
2084 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
2085 PEER_STR_ATTR_INHERIT(peer
, group
,
2086 filter
[afi
][safi
].dlist
[out
].name
,
2087 MTYPE_BGP_FILTER_NAME
);
2088 PEER_ATTR_INHERIT(peer
, group
,
2089 filter
[afi
][safi
].dlist
[out
].alist
);
2092 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
2093 PEER_STR_ATTR_INHERIT(peer
, group
,
2094 filter
[afi
][safi
].plist
[out
].name
,
2095 MTYPE_BGP_FILTER_NAME
);
2096 PEER_ATTR_INHERIT(peer
, group
,
2097 filter
[afi
][safi
].plist
[out
].plist
);
2100 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
2101 PEER_STR_ATTR_INHERIT(peer
, group
,
2102 filter
[afi
][safi
].aslist
[out
].name
,
2103 MTYPE_BGP_FILTER_NAME
);
2104 PEER_ATTR_INHERIT(peer
, group
,
2105 filter
[afi
][safi
].aslist
[out
].aslist
);
2108 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
2109 PEER_STR_ATTR_INHERIT(peer
, group
,
2110 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
2111 MTYPE_BGP_FILTER_NAME
);
2112 PEER_ATTR_INHERIT(peer
, group
,
2113 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
2116 /* nondirectional filter apply */
2117 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
2118 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
2119 MTYPE_BGP_FILTER_NAME
);
2120 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
2123 /* Conditional Advertisements */
2124 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ADVERTISE_MAP
)) {
2125 PEER_STR_ATTR_INHERIT(peer
, group
,
2126 filter
[afi
][safi
].advmap
.aname
,
2127 MTYPE_BGP_FILTER_NAME
);
2128 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].advmap
.amap
);
2129 PEER_STR_ATTR_INHERIT(peer
, group
,
2130 filter
[afi
][safi
].advmap
.cname
,
2131 MTYPE_BGP_FILTER_NAME
);
2132 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].advmap
.cmap
);
2133 PEER_ATTR_INHERIT(peer
, group
,
2134 filter
[afi
][safi
].advmap
.condition
);
2137 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
2138 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
2139 bgp_addpath_type_changed(conf
->bgp
);
2143 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
2148 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2149 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2150 __func__
, peer
->host
);
2154 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
2156 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2157 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
2158 return BGP_ERR_PEER_SAFI_CONFLICT
;
2160 /* Nothing to do if we've already activated this peer */
2161 if (peer
->afc
[afi
][safi
])
2164 if (peer_af_create(peer
, afi
, safi
) == NULL
)
2167 active
= peer_active(peer
);
2168 peer
->afc
[afi
][safi
] = 1;
2171 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
2173 if (!active
&& peer_active(peer
)) {
2174 bgp_timer_set(peer
);
2176 if (peer_established(peer
)) {
2177 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2178 peer
->afc_adv
[afi
][safi
] = 1;
2179 bgp_capability_send(peer
, afi
, safi
,
2181 CAPABILITY_ACTION_SET
);
2182 if (peer
->afc_recv
[afi
][safi
]) {
2183 peer
->afc_nego
[afi
][safi
] = 1;
2184 bgp_announce_route(peer
, afi
, safi
,
2188 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2189 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2190 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2193 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
2194 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2195 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2196 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2199 * If we are turning on a AFI/SAFI locally and we've
2200 * started bringing a peer up, we need to tell
2201 * the other peer to restart because we might loose
2202 * configuration here because when the doppelganger
2203 * gets to a established state due to how
2204 * we resolve we could just overwrite the afi/safi
2207 other
= peer
->doppelganger
;
2209 && (other
->status
== OpenSent
2210 || other
->status
== OpenConfirm
)) {
2211 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2212 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
2213 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2220 /* Activate the peer or peer group for specified AFI and SAFI. */
2221 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2224 struct peer_group
*group
;
2225 struct listnode
*node
, *nnode
;
2226 struct peer
*tmp_peer
;
2229 /* Nothing to do if we've already activated this peer */
2230 if (peer
->afc
[afi
][safi
])
2235 /* This is a peer-group so activate all of the members of the
2236 * peer-group as well */
2237 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2239 /* Do not activate a peer for both SAFI_UNICAST and
2240 * SAFI_LABELED_UNICAST */
2241 if ((safi
== SAFI_UNICAST
2242 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2243 || (safi
== SAFI_LABELED_UNICAST
2244 && peer
->afc
[afi
][SAFI_UNICAST
]))
2245 return BGP_ERR_PEER_SAFI_CONFLICT
;
2247 peer
->afc
[afi
][safi
] = 1;
2248 group
= peer
->group
;
2250 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2251 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2254 ret
|= peer_activate_af(peer
, afi
, safi
);
2257 /* If this is the first peer to be activated for this
2258 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2259 if (ret
!= BGP_ERR_PEER_SAFI_CONFLICT
&& safi
== SAFI_LABELED_UNICAST
2260 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2262 if (BGP_DEBUG(zebra
, ZEBRA
))
2264 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2266 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2267 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2270 if (safi
== SAFI_FLOWSPEC
) {
2271 /* connect to table manager */
2272 bgp_zebra_init_tm_connect(bgp
);
2277 static bool non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2280 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2281 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2282 __func__
, peer
->host
);
2286 /* Nothing to do if we've already deactivated this peer */
2287 if (!peer
->afc
[afi
][safi
])
2290 /* De-activate the address family configuration. */
2291 peer
->afc
[afi
][safi
] = 0;
2293 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2294 flog_err(EC_BGP_PEER_DELETE
,
2295 "couldn't delete af structure for peer %s(%s, %s)",
2296 peer
->host
, afi2str(afi
), safi2str(safi
));
2300 if (peer_established(peer
)) {
2301 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2302 peer
->afc_adv
[afi
][safi
] = 0;
2303 peer
->afc_nego
[afi
][safi
] = 0;
2305 if (peer_active_nego(peer
)) {
2306 bgp_capability_send(peer
, afi
, safi
,
2308 CAPABILITY_ACTION_UNSET
);
2309 bgp_clear_route(peer
, afi
, safi
);
2310 peer
->pcount
[afi
][safi
] = 0;
2312 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2313 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2314 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2317 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2318 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2319 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2326 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2329 struct peer_group
*group
;
2330 struct peer
*tmp_peer
;
2331 struct listnode
*node
, *nnode
;
2334 /* Nothing to do if we've already de-activated this peer */
2335 if (!peer
->afc
[afi
][safi
])
2338 /* This is a peer-group so de-activate all of the members of the
2339 * peer-group as well */
2340 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2341 peer
->afc
[afi
][safi
] = 0;
2342 group
= peer
->group
;
2344 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2345 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2348 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2353 /* If this is the last peer to be deactivated for this
2354 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2355 if (safi
== SAFI_LABELED_UNICAST
2356 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2357 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2359 if (BGP_DEBUG(zebra
, ZEBRA
))
2361 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2363 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2364 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2369 void peer_nsf_stop(struct peer
*peer
)
2374 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2375 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2377 FOREACH_AFI_SAFI_NSF (afi
, safi
) {
2378 peer
->nsf
[afi
][safi
] = 0;
2379 THREAD_OFF(peer
->t_llgr_stale
[afi
][safi
]);
2382 if (peer
->t_gr_restart
) {
2383 THREAD_OFF(peer
->t_gr_restart
);
2384 if (bgp_debug_neighbor_events(peer
))
2385 zlog_debug("%pBP graceful restart timer stopped", peer
);
2387 if (peer
->t_gr_stale
) {
2388 THREAD_OFF(peer
->t_gr_stale
);
2389 if (bgp_debug_neighbor_events(peer
))
2391 "%pBP graceful restart stalepath timer stopped",
2394 bgp_clear_route_all(peer
);
2397 /* Delete peer from confguration.
2399 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2400 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2402 * This function /should/ take care to be idempotent, to guard against
2403 * it being called multiple times through stray events that come in
2404 * that happen to result in this function being called again. That
2405 * said, getting here for a "Deleted" peer is a bug in the neighbour
2408 int peer_delete(struct peer
*peer
)
2414 struct bgp_filter
*filter
;
2415 struct listnode
*pn
;
2418 assert(peer
->status
!= Deleted
);
2421 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2423 bgp_soft_reconfig_table_task_cancel(bgp
, NULL
, peer
);
2425 bgp_keepalives_off(peer
);
2426 bgp_reads_off(peer
);
2427 bgp_writes_off(peer
);
2428 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2429 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2430 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2432 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2433 peer_nsf_stop(peer
);
2435 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2437 /* Remove BFD settings. */
2438 if (peer
->bfd_config
)
2439 bgp_peer_remove_bfd_config(peer
);
2441 /* If this peer belongs to peer group, clear up the
2444 if (peer_dynamic_neighbor(peer
))
2445 peer_drop_dynamic_neighbor(peer
);
2447 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2449 peer
); /* group->peer list reference */
2450 list_delete_node(peer
->group
->peer
, pn
);
2455 /* Withdraw all information from routing table. We can not use
2456 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2457 * executed after peer structure is deleted.
2459 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2461 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2463 if (peer
->doppelganger
) {
2464 peer
->doppelganger
->doppelganger
= NULL
;
2465 peer
->doppelganger
= NULL
;
2468 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2469 bgp_fsm_change_status(peer
, Deleted
);
2471 /* Remove from NHT */
2472 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2473 bgp_unlink_nexthop_by_peer(peer
);
2475 /* Password configuration */
2476 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2477 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2478 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2479 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2480 && !CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
))
2481 bgp_md5_unset(peer
);
2484 bgp_timer_set(peer
); /* stops all timers for Deleted */
2486 /* Delete from all peer list. */
2487 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2488 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2489 peer_unlock(peer
); /* bgp peer list reference */
2490 list_delete_node(bgp
->peer
, pn
);
2491 hash_release(bgp
->peerhash
, peer
);
2496 stream_fifo_free(peer
->ibuf
);
2501 stream_fifo_free(peer
->obuf
);
2505 if (peer
->ibuf_work
) {
2506 ringbuf_del(peer
->ibuf_work
);
2507 peer
->ibuf_work
= NULL
;
2510 if (peer
->obuf_work
) {
2511 stream_free(peer
->obuf_work
);
2512 peer
->obuf_work
= NULL
;
2515 if (peer
->scratch
) {
2516 stream_free(peer
->scratch
);
2517 peer
->scratch
= NULL
;
2520 /* Local and remote addresses. */
2521 if (peer
->su_local
) {
2522 sockunion_free(peer
->su_local
);
2523 peer
->su_local
= NULL
;
2526 if (peer
->su_remote
) {
2527 sockunion_free(peer
->su_remote
);
2528 peer
->su_remote
= NULL
;
2531 /* Free filter related memory. */
2532 FOREACH_AFI_SAFI (afi
, safi
) {
2533 filter
= &peer
->filter
[afi
][safi
];
2535 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2536 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
2537 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
2538 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
2541 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2542 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
2545 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2546 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
2547 ecommunity_free(&peer
->soo
[afi
][safi
]);
2550 FOREACH_AFI_SAFI (afi
, safi
)
2551 peer_af_delete(peer
, afi
, safi
);
2553 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2554 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2556 peer_unlock(peer
); /* initial reference */
2561 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2563 return strcmp(g1
->name
, g2
->name
);
2566 /* Peer group cofiguration. */
2567 static struct peer_group
*peer_group_new(void)
2569 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2572 static void peer_group_free(struct peer_group
*group
)
2574 XFREE(MTYPE_PEER_GROUP
, group
);
2577 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2579 struct peer_group
*group
;
2580 struct listnode
*node
, *nnode
;
2582 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2583 if (strcmp(group
->name
, name
) == 0)
2589 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2591 struct peer_group
*group
;
2595 group
= peer_group_lookup(bgp
, name
);
2599 group
= peer_group_new();
2601 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2602 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2603 group
->peer
= list_new();
2604 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2605 group
->listen_range
[afi
] = list_new();
2606 group
->conf
= peer_new(bgp
);
2607 FOREACH_AFI_SAFI (afi
, safi
) {
2608 if (bgp
->default_af
[afi
][safi
])
2609 group
->conf
->afc
[afi
][safi
] = 1;
2611 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2612 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2613 group
->conf
->group
= group
;
2614 group
->conf
->as
= 0;
2615 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2616 group
->conf
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
2617 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2618 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2619 listnode_add_sort(bgp
->group
, group
);
2624 static void peer_group2peer_config_copy(struct peer_group
*group
,
2634 peer
->as
= conf
->as
;
2637 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2638 peer
->change_local_as
= conf
->change_local_as
;
2640 /* If peer-group has configured TTL then override it */
2641 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2642 peer
->ttl
= conf
->ttl
;
2645 peer
->gtsm_hops
= conf
->gtsm_hops
;
2647 /* peer flags apply */
2648 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2649 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2650 flags_tmp
&= ~peer
->flags_override
;
2652 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2653 SET_FLAG(peer
->flags
, flags_tmp
);
2654 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2656 /* peer timers apply */
2657 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2658 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2659 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2662 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2663 PEER_ATTR_INHERIT(peer
, group
, connect
);
2664 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2665 peer
->v_connect
= conf
->connect
;
2667 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
2670 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_DELAYOPEN
)) {
2671 PEER_ATTR_INHERIT(peer
, group
, delayopen
);
2672 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
2673 peer
->v_delayopen
= conf
->delayopen
;
2675 peer
->v_delayopen
= peer
->bgp
->default_delayopen
;
2678 /* advertisement-interval apply */
2679 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2680 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2681 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2682 peer
->v_routeadv
= conf
->routeadv
;
2684 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2685 ? BGP_DEFAULT_IBGP_ROUTEADV
2686 : BGP_DEFAULT_EBGP_ROUTEADV
;
2689 /* capability extended-nexthop apply */
2690 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_CAPABILITY_ENHE
))
2691 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2692 SET_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
);
2694 /* password apply */
2695 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2696 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2697 MTYPE_PEER_PASSWORD
);
2699 if (!BGP_PEER_SU_UNSPEC(peer
))
2702 /* update-source apply */
2703 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2704 if (conf
->update_source
) {
2705 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2706 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2707 } else if (conf
->update_if
) {
2708 sockunion_free(peer
->update_source
);
2709 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2710 MTYPE_PEER_UPDATE_SOURCE
);
2715 PEER_ATTR_INHERIT(peer
, group
, local_role
);
2717 /* Update GR flags for the peer. */
2718 bgp_peer_gr_flags_update(peer
);
2720 /* Apply BFD settings from group to peer if it exists. */
2721 if (conf
->bfd_config
) {
2722 bgp_peer_configure_bfd(peer
, false);
2723 bgp_peer_config_apply(peer
, group
);
2727 /* Peer group's remote AS configuration. */
2728 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2731 struct peer_group
*group
;
2733 struct listnode
*node
, *nnode
;
2735 group
= peer_group_lookup(bgp
, group_name
);
2739 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2743 /* When we setup peer-group AS number all peer group member's AS
2744 number must be updated to same number. */
2745 peer_as_change(group
->conf
, *as
, as_type
);
2747 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2748 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2749 || (peer
->as_type
!= as_type
))
2750 peer_as_change(peer
, *as
, as_type
);
2756 void peer_notify_unconfig(struct peer
*peer
)
2758 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2759 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2760 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2763 static void peer_notify_shutdown(struct peer
*peer
)
2765 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
)) {
2766 if (bgp_debug_neighbor_events(peer
))
2768 "%pBP configured Graceful-Restart, skipping shutdown notification",
2773 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2774 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2775 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
2778 void peer_group_notify_unconfig(struct peer_group
*group
)
2780 struct peer
*peer
, *other
;
2781 struct listnode
*node
, *nnode
;
2783 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2784 other
= peer
->doppelganger
;
2785 if (other
&& other
->status
!= Deleted
) {
2786 other
->group
= NULL
;
2787 peer_notify_unconfig(other
);
2789 peer_notify_unconfig(peer
);
2793 int peer_group_delete(struct peer_group
*group
)
2797 struct prefix
*prefix
;
2799 struct listnode
*node
, *nnode
;
2804 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2805 other
= peer
->doppelganger
;
2807 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2808 bgp_zebra_terminate_radv(bgp
, peer
);
2811 if (other
&& other
->status
!= Deleted
) {
2812 other
->group
= NULL
;
2816 list_delete(&group
->peer
);
2818 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2819 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2821 prefix_free(&prefix
);
2823 list_delete(&group
->listen_range
[afi
]);
2826 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2829 if (group
->conf
->bfd_config
)
2830 bgp_peer_remove_bfd_config(group
->conf
);
2832 group
->conf
->group
= NULL
;
2833 peer_delete(group
->conf
);
2835 /* Delete from all peer_group list. */
2836 listnode_delete(bgp
->group
, group
);
2838 peer_group_free(group
);
2843 int peer_group_remote_as_delete(struct peer_group
*group
)
2845 struct peer
*peer
, *other
;
2846 struct listnode
*node
, *nnode
;
2848 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2849 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2852 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2853 other
= peer
->doppelganger
;
2855 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2856 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
2860 if (other
&& other
->status
!= Deleted
) {
2861 other
->group
= NULL
;
2865 list_delete_all_node(group
->peer
);
2867 group
->conf
->as
= 0;
2868 group
->conf
->as_type
= AS_UNSPECIFIED
;
2873 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2875 struct prefix
*prefix
;
2876 struct listnode
*node
, *nnode
;
2879 afi
= family2afi(range
->family
);
2881 /* Group needs remote AS configured. */
2882 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2883 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2885 /* Ensure no duplicates. Currently we don't care about overlaps. */
2886 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2887 if (prefix_same(range
, prefix
))
2891 prefix
= prefix_new();
2892 prefix_copy(prefix
, range
);
2893 listnode_add(group
->listen_range
[afi
], prefix
);
2895 /* Update passwords for new ranges */
2896 if (group
->conf
->password
)
2897 bgp_md5_set_prefix(group
->bgp
, prefix
, group
->conf
->password
);
2902 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2904 struct prefix
*prefix
, prefix2
;
2905 struct listnode
*node
, *nnode
;
2909 afi
= family2afi(range
->family
);
2911 /* Identify the listen range. */
2912 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2913 if (prefix_same(range
, prefix
))
2918 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2920 /* Dispose off any dynamic neighbors that exist due to this listen range
2922 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2923 if (!peer_dynamic_neighbor(peer
))
2926 if (sockunion2hostprefix(&peer
->su
, &prefix2
)
2927 && prefix_match(prefix
, &prefix2
)) {
2928 if (bgp_debug_neighbor_events(peer
))
2930 "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX",
2931 peer
->host
, group
->name
, prefix
);
2936 /* Get rid of the listen range */
2937 listnode_delete(group
->listen_range
[afi
], prefix
);
2939 /* Remove passwords for deleted ranges */
2940 if (group
->conf
->password
)
2941 bgp_md5_unset_prefix(group
->bgp
, prefix
);
2946 /* Bind specified peer to peer group. */
2947 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2948 struct peer_group
*group
, as_t
*as
)
2950 int first_member
= 0;
2953 enum bgp_peer_sort ptype
, gtype
;
2955 /* Lookup the peer. */
2957 peer
= peer_lookup(bgp
, su
);
2959 /* The peer exist, bind it to the peer-group */
2961 /* When the peer already belongs to a peer-group, check the
2963 if (peer_group_active(peer
)) {
2965 /* The peer is already bound to the peer-group,
2968 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2971 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2974 /* The peer has not specified a remote-as, inherit it from the
2976 if (peer
->as_type
== AS_UNSPECIFIED
) {
2977 peer
->as_type
= group
->conf
->as_type
;
2978 peer
->as
= group
->conf
->as
;
2979 peer
->sort
= group
->conf
->sort
;
2982 ptype
= peer_sort(peer
);
2983 if (!group
->conf
->as
&& ptype
!= BGP_PEER_UNSPECIFIED
) {
2984 gtype
= peer_sort(group
->conf
);
2985 if ((gtype
!= BGP_PEER_INTERNAL
) && (gtype
!= ptype
)) {
2988 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2991 if (gtype
== BGP_PEER_INTERNAL
)
2995 peer_group2peer_config_copy(group
, peer
);
2997 FOREACH_AFI_SAFI (afi
, safi
) {
2998 if (group
->conf
->afc
[afi
][safi
]) {
2999 peer
->afc
[afi
][safi
] = 1;
3001 if (peer_af_find(peer
, afi
, safi
)
3002 || peer_af_create(peer
, afi
, safi
)) {
3003 peer_group2peer_config_copy_af(
3004 group
, peer
, afi
, safi
);
3006 } else if (peer
->afc
[afi
][safi
])
3007 peer_deactivate(peer
, afi
, safi
);
3011 assert(group
&& peer
->group
== group
);
3013 listnode_delete(bgp
->peer
, peer
);
3015 peer
->group
= group
;
3016 listnode_add_sort(bgp
->peer
, peer
);
3018 peer
= peer_lock(peer
); /* group->peer list reference */
3019 listnode_add(group
->peer
, peer
);
3023 gtype
= peer_sort(group
->conf
);
3024 /* Advertisement-interval reset */
3025 if (!CHECK_FLAG(group
->conf
->flags
,
3026 PEER_FLAG_ROUTEADV
)) {
3027 group
->conf
->v_routeadv
=
3028 (gtype
== BGP_PEER_IBGP
)
3029 ? BGP_DEFAULT_IBGP_ROUTEADV
3030 : BGP_DEFAULT_EBGP_ROUTEADV
;
3033 /* ebgp-multihop reset */
3034 if (gtype
== BGP_PEER_IBGP
)
3035 group
->conf
->ttl
= MAXTTL
;
3037 /* local-as reset */
3038 if (gtype
!= BGP_PEER_EBGP
) {
3039 group
->conf
->change_local_as
= 0;
3040 peer_flag_unset(group
->conf
,
3041 PEER_FLAG_LOCAL_AS
);
3042 peer_flag_unset(group
->conf
,
3043 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
3044 peer_flag_unset(group
->conf
,
3045 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
3049 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3051 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3052 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
3053 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3054 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3056 bgp_session_reset(peer
);
3060 /* Create a new peer. */
3062 if ((group
->conf
->as_type
== AS_SPECIFIED
)
3063 && (!group
->conf
->as
)) {
3064 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
3067 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3068 group
->conf
->as_type
, group
);
3070 peer
= peer_lock(peer
); /* group->peer list reference */
3071 listnode_add(group
->peer
, peer
);
3073 peer_group2peer_config_copy(group
, peer
);
3075 /* If the peer-group is active for this afi/safi then activate
3077 FOREACH_AFI_SAFI (afi
, safi
) {
3078 if (group
->conf
->afc
[afi
][safi
]) {
3079 peer
->afc
[afi
][safi
] = 1;
3081 if (!peer_af_find(peer
, afi
, safi
))
3082 peer_af_create(peer
, afi
, safi
);
3084 peer_group2peer_config_copy_af(group
, peer
, afi
,
3086 } else if (peer
->afc
[afi
][safi
])
3087 peer_deactivate(peer
, afi
, safi
);
3090 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3092 /* Set up peer's events and timers. */
3093 if (peer_active(peer
))
3094 bgp_timer_set(peer
);
3100 static void bgp_startup_timer_expire(struct thread
*thread
)
3104 bgp
= THREAD_ARG(thread
);
3105 bgp
->t_startup
= NULL
;
3109 * On shutdown we call the cleanup function which
3110 * does a free of the link list nodes, free up
3111 * the data we are pointing at too.
3113 static void bgp_vrf_string_name_delete(void *data
)
3117 XFREE(MTYPE_TMP
, vname
);
3120 /* BGP instance creation by `router bgp' commands. */
3121 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
3122 enum bgp_instance_type inst_type
)
3128 bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
));
3130 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3131 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3132 zlog_debug("Creating Default VRF, AS %u", *as
);
3134 zlog_debug("Creating %s %s, AS %u",
3135 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
3141 /* Default the EVPN VRF to the default one */
3142 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
3149 bgp
->allow_martian
= false;
3150 bgp_process_queue_init(bgp
);
3151 bgp
->heuristic_coalesce
= true;
3152 bgp
->inst_type
= inst_type
;
3153 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
3155 bgp
->peer_self
= peer_new(bgp
);
3156 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
3157 bgp
->peer_self
->host
=
3158 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
3159 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
3160 if (cmd_hostname_get())
3161 bgp
->peer_self
->hostname
=
3162 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
3164 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
3165 if (cmd_domainname_get())
3166 bgp
->peer_self
->domainname
=
3167 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
3168 bgp
->peer
= list_new();
3169 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
3170 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
3172 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
3174 bgp
->group
= list_new();
3175 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
3177 FOREACH_AFI_SAFI (afi
, safi
) {
3178 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
3179 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
3180 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
3182 /* Enable maximum-paths */
3183 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
3185 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
3187 /* Initialize graceful restart info */
3188 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
3189 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
3190 bgp
->gr_info
[afi
][safi
].t_select_deferral
= NULL
;
3191 bgp
->gr_info
[afi
][safi
].t_route_select
= NULL
;
3192 bgp
->gr_info
[afi
][safi
].gr_deferred
= 0;
3195 bgp
->v_update_delay
= bm
->v_update_delay
;
3196 bgp
->v_establish_wait
= bm
->v_establish_wait
;
3197 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
3198 bgp
->default_subgroup_pkt_queue_max
=
3199 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
3200 bgp_timers_unset(bgp
);
3201 bgp
->default_min_holdtime
= 0;
3202 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
3203 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
3204 bgp
->select_defer_time
= BGP_DEFAULT_SELECT_DEFERRAL_TIME
;
3205 bgp
->rib_stale_time
= BGP_DEFAULT_RIB_STALE_TIME
;
3206 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
3207 bgp
->dynamic_neighbors_count
= 0;
3208 bgp
->lb_ref_bw
= BGP_LINK_BW_REF_BW
;
3209 bgp
->lb_handling
= BGP_LINK_BW_ECMP
;
3210 bgp
->reject_as_sets
= false;
3211 bgp
->condition_check_period
= DEFAULT_CONDITIONAL_ROUTES_POLL_TIME
;
3212 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
3213 bgp
->fast_convergence
= false;
3215 bgp
->llgr_stale_time
= BGP_DEFAULT_LLGR_STALE_TIME
;
3217 #ifdef ENABLE_BGP_VNC
3218 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
3219 bgp
->rfapi
= bgp_rfapi_new(bgp
);
3221 assert(bgp
->rfapi_cfg
);
3223 #endif /* ENABLE_BGP_VNC */
3225 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3226 bgp
->vpn_policy
[afi
].bgp
= bgp
;
3227 bgp
->vpn_policy
[afi
].afi
= afi
;
3228 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
3229 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
3232 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
3233 bgp
->vpn_policy
[afi
].import_vrf
->del
=
3234 bgp_vrf_string_name_delete
;
3235 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3236 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3237 bgp_vrf_string_name_delete
;
3238 SET_FLAG(bgp
->af_flags
[afi
][SAFI_MPLS_VPN
],
3239 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL
);
3242 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3244 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3245 bgp
->restart_time
, &bgp
->t_startup
);
3247 /* printable name we can use in debug messages */
3248 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3249 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3259 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3261 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3262 snprintf(bgp
->name_pretty
, len
, "%s %s",
3263 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3269 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3270 memory_order_relaxed
);
3271 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3272 memory_order_relaxed
);
3273 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3274 bgp
->default_af
[AFI_IP
][SAFI_UNICAST
] = true;
3278 update_bgp_group_init(bgp
);
3280 /* assign a unique rd id for auto derivation of vrf's RD */
3281 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3283 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3284 sizeof(struct bgp_evpn_info
));
3286 bgp_evpn_vrf_es_init(bgp
);
3290 /*initilize global GR FSM */
3291 bgp_global_gr_init(bgp
);
3293 memset(&bgp
->ebgprequirespolicywarning
, 0,
3294 sizeof(bgp
->ebgprequirespolicywarning
));
3299 /* Return the "default VRF" instance of BGP. */
3300 struct bgp
*bgp_get_default(void)
3303 struct listnode
*node
, *nnode
;
3305 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3306 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3311 /* Lookup BGP entry. */
3312 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3315 struct listnode
*node
, *nnode
;
3317 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3319 && ((bgp
->name
== NULL
&& name
== NULL
)
3320 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3325 /* Lookup BGP structure by view name. */
3326 struct bgp
*bgp_lookup_by_name(const char *name
)
3329 struct listnode
*node
, *nnode
;
3331 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3332 if ((bgp
->name
== NULL
&& name
== NULL
)
3333 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3338 /* Lookup BGP instance based on VRF id. */
3339 /* Note: Only to be used for incoming messages from Zebra. */
3340 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3344 /* Lookup VRF (in tree) and follow link. */
3345 vrf
= vrf_lookup_by_id(vrf_id
);
3348 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3351 /* Sets the BGP instance where EVPN is enabled */
3352 void bgp_set_evpn(struct bgp
*bgp
)
3354 if (bm
->bgp_evpn
== bgp
)
3357 /* First, release the reference count we hold on the instance */
3359 bgp_unlock(bm
->bgp_evpn
);
3363 /* Increase the reference count on this new VRF */
3365 bgp_lock(bm
->bgp_evpn
);
3368 /* Returns the BGP instance where EVPN is enabled, if any */
3369 struct bgp
*bgp_get_evpn(void)
3371 return bm
->bgp_evpn
;
3374 /* handle socket creation or deletion, if necessary
3375 * this is called for all new BGP instances
3377 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3380 struct listnode
*node
;
3383 /* Create BGP server socket, if listen mode not disabled */
3384 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3386 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3388 * suppress vrf socket
3391 bgp_close_vrf_socket(bgp
);
3395 return BGP_ERR_INVALID_VALUE
;
3397 * if vrf_id did not change
3399 if (vrf
->vrf_id
== old_vrf_id
)
3401 if (old_vrf_id
!= VRF_UNKNOWN
) {
3402 /* look for old socket. close it. */
3403 bgp_close_vrf_socket(bgp
);
3405 /* if backend is not yet identified ( VRF_UNKNOWN) then
3406 * creation will be done later
3408 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3410 if (list_isempty(bm
->addresses
)) {
3411 if (bgp_socket(bgp
, bm
->port
, NULL
) < 0)
3412 return BGP_ERR_INVALID_VALUE
;
3414 for (ALL_LIST_ELEMENTS_RO(bm
->addresses
, node
, address
))
3415 if (bgp_socket(bgp
, bm
->port
, address
) < 0)
3416 return BGP_ERR_INVALID_VALUE
;
3420 return bgp_check_main_socket(create
, bgp
);
3423 int bgp_lookup_by_as_name_type(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3424 enum bgp_instance_type inst_type
)
3428 /* Multiple instance check. */
3430 bgp
= bgp_lookup_by_name(name
);
3432 bgp
= bgp_get_default();
3436 if (bgp
->as
!= *as
) {
3438 return BGP_ERR_AS_MISMATCH
;
3440 if (bgp
->inst_type
!= inst_type
)
3441 return BGP_ERR_INSTANCE_MISMATCH
;
3449 /* Called from VTY commands. */
3450 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3451 enum bgp_instance_type inst_type
)
3454 struct vrf
*vrf
= NULL
;
3457 ret
= bgp_lookup_by_as_name_type(bgp_val
, as
, name
, inst_type
);
3458 if (ret
|| *bgp_val
)
3461 bgp
= bgp_create(as
, name
, inst_type
);
3464 * view instances will never work inside of a vrf
3465 * as such they must always be in the VRF_DEFAULT
3466 * Also we must set this to something useful because
3467 * of the vrf socket code needing an actual useful
3468 * default value to send to the underlying OS.
3470 * This code is currently ignoring vrf based
3471 * code using the -Z option( and that is probably
3472 * best addressed elsewhere in the code )
3474 if (inst_type
== BGP_INSTANCE_TYPE_VIEW
)
3475 bgp
->vrf_id
= VRF_DEFAULT
;
3477 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3478 bgp_address_init(bgp
);
3479 bgp_tip_hash_init(bgp
);
3483 bgp
->t_rmap_def_originate_eval
= NULL
;
3485 /* If Default instance or VRF, link to the VRF structure, if present. */
3486 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3487 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3488 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3490 bgp_vrf_link(bgp
, vrf
);
3492 /* BGP server socket already processed if BGP instance
3493 * already part of the list
3495 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3496 listnode_add(bm
->bgp
, bgp
);
3498 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3499 if (BGP_DEBUG(zebra
, ZEBRA
))
3500 zlog_debug("%s: Registering BGP instance %s to zebra",
3502 bgp_zebra_instance_register(bgp
);
3508 static void bgp_zclient_set_redist(afi_t afi
, int type
, unsigned short instance
,
3509 vrf_id_t vrf_id
, bool set
)
3513 redist_add_instance(&zclient
->mi_redist
[afi
][type
],
3516 redist_del_instance(&zclient
->mi_redist
[afi
][type
],
3520 vrf_bitmap_set(zclient
->redist
[afi
][type
], vrf_id
);
3522 vrf_bitmap_unset(zclient
->redist
[afi
][type
], vrf_id
);
3526 static void bgp_set_redist_vrf_bitmaps(struct bgp
*bgp
, bool set
)
3530 struct list
*red_list
;
3531 struct listnode
*node
;
3532 struct bgp_redist
*red
;
3534 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3535 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3537 red_list
= bgp
->redist
[afi
][i
];
3541 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
3542 bgp_zclient_set_redist(afi
, i
, red
->instance
,
3549 * Make BGP instance "up". Applies only to VRFs (non-default) and
3550 * implies the VRF has been learnt from Zebra.
3552 void bgp_instance_up(struct bgp
*bgp
)
3555 struct listnode
*node
, *next
;
3557 bgp_set_redist_vrf_bitmaps(bgp
, true);
3559 /* Register with zebra. */
3560 bgp_zebra_instance_register(bgp
);
3562 /* Kick off any peers that may have been configured. */
3563 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3564 if (!BGP_PEER_START_SUPPRESSED(peer
))
3565 BGP_EVENT_ADD(peer
, BGP_Start
);
3568 /* Process any networks that have been configured. */
3569 bgp_static_add(bgp
);
3573 * Make BGP instance "down". Applies only to VRFs (non-default) and
3574 * implies the VRF has been deleted by Zebra.
3576 void bgp_instance_down(struct bgp
*bgp
)
3579 struct listnode
*node
;
3580 struct listnode
*next
;
3583 if (bgp
->t_rmap_def_originate_eval
) {
3584 THREAD_OFF(bgp
->t_rmap_def_originate_eval
);
3585 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3589 /* Bring down peers, so corresponding routes are purged. */
3590 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3591 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3592 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3593 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3595 bgp_session_reset(peer
);
3598 /* Purge network and redistributed routes. */
3599 bgp_purge_static_redist_routes(bgp
);
3601 /* Cleanup registered nexthops (flags) */
3602 bgp_cleanup_nexthops(bgp
);
3604 bgp_zebra_instance_deregister(bgp
);
3606 bgp_set_redist_vrf_bitmaps(bgp
, false);
3609 /* Delete BGP instance. */
3610 int bgp_delete(struct bgp
*bgp
)
3613 struct peer_group
*group
;
3614 struct listnode
*node
, *next
;
3619 struct graceful_restart_info
*gr_info
;
3623 bgp_soft_reconfig_table_task_cancel(bgp
, NULL
, NULL
);
3625 /* make sure we withdraw any exported routes */
3626 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP
, bgp_get_default(),
3628 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP6
, bgp_get_default(),
3631 bgp_vpn_leak_unimport(bgp
);
3633 hook_call(bgp_inst_delete
, bgp
);
3635 THREAD_OFF(bgp
->t_condition_check
);
3636 THREAD_OFF(bgp
->t_startup
);
3637 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3638 THREAD_OFF(bgp
->t_update_delay
);
3639 THREAD_OFF(bgp
->t_establish_wait
);
3641 /* Set flag indicating bgp instance delete in progress */
3642 SET_FLAG(bgp
->flags
, BGP_FLAG_DELETE_IN_PROGRESS
);
3644 /* Delete the graceful restart info */
3645 FOREACH_AFI_SAFI (afi
, safi
) {
3648 gr_info
= &bgp
->gr_info
[afi
][safi
];
3651 t
= gr_info
->t_select_deferral
;
3653 void *info
= THREAD_ARG(t
);
3655 XFREE(MTYPE_TMP
, info
);
3657 THREAD_OFF(gr_info
->t_select_deferral
);
3659 t
= gr_info
->t_route_select
;
3661 void *info
= THREAD_ARG(t
);
3663 XFREE(MTYPE_TMP
, info
);
3665 THREAD_OFF(gr_info
->t_route_select
);
3668 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3669 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3670 zlog_debug("Deleting Default VRF");
3672 zlog_debug("Deleting %s %s",
3673 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3679 /* unmap from RT list */
3680 bgp_evpn_vrf_delete(bgp
);
3682 /* unmap bgp vrf label */
3683 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3684 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3687 if (bgp
->t_rmap_def_originate_eval
) {
3688 THREAD_OFF(bgp
->t_rmap_def_originate_eval
);
3689 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3693 /* Inform peers we're going down. */
3694 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3695 peer_notify_shutdown(peer
);
3697 /* Delete static routes (networks). */
3698 bgp_static_delete(bgp
);
3700 /* Unset redistribution. */
3701 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3702 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3703 if (i
!= ZEBRA_ROUTE_BGP
)
3704 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3706 /* Free peers and peer-groups. */
3707 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3708 peer_group_delete(group
);
3710 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3713 if (bgp
->peer_self
) {
3714 peer_delete(bgp
->peer_self
);
3715 bgp
->peer_self
= NULL
;
3718 update_bgp_group_free(bgp
);
3720 /* TODO - Other memory may need to be freed - e.g., NHT */
3722 #ifdef ENABLE_BGP_VNC
3725 bgp_cleanup_routes(bgp
);
3727 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3728 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3731 &bgp
->vpn_policy
[afi
]
3732 .import_redirect_rtlist
);
3733 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3736 /* Free any memory allocated to holding routemap references */
3737 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3738 for (enum vpn_policy_direction dir
= 0;
3739 dir
< BGP_VPN_POLICY_DIR_MAX
; ++dir
) {
3740 if (bgp
->vpn_policy
[afi
].rmap_name
[dir
])
3741 XFREE(MTYPE_ROUTE_MAP_NAME
,
3742 bgp
->vpn_policy
[afi
].rmap_name
[dir
]);
3743 bgp
->vpn_policy
[afi
].rmap
[dir
] = NULL
;
3747 /* Deregister from Zebra, if needed */
3748 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3749 if (BGP_DEBUG(zebra
, ZEBRA
))
3751 "%s: deregistering this bgp %s instance from zebra",
3752 __func__
, bgp
->name
);
3753 bgp_zebra_instance_deregister(bgp
);
3756 /* Remove visibility via the master list - there may however still be
3757 * routes to be processed still referencing the struct bgp.
3759 listnode_delete(bm
->bgp
, bgp
);
3761 /* Free interfaces in this instance. */
3764 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3765 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3767 bgp_vrf_unlink(bgp
, vrf
);
3769 /* Update EVPN VRF pointer */
3770 if (bm
->bgp_evpn
== bgp
) {
3771 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3774 bgp_set_evpn(bgp_get_default());
3777 if (bgp
->process_queue
)
3778 work_queue_free_and_null(&bgp
->process_queue
);
3780 thread_master_free_unused(bm
->master
);
3781 bgp_unlock(bgp
); /* initial reference */
3786 void bgp_free(struct bgp
*bgp
)
3790 struct bgp_table
*table
;
3791 struct bgp_dest
*dest
;
3792 struct bgp_rmap
*rmap
;
3796 list_delete(&bgp
->group
);
3797 list_delete(&bgp
->peer
);
3799 if (bgp
->peerhash
) {
3800 hash_free(bgp
->peerhash
);
3801 bgp
->peerhash
= NULL
;
3804 FOREACH_AFI_SAFI (afi
, safi
) {
3805 /* Special handling for 2-level routing tables. */
3806 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3807 || safi
== SAFI_EVPN
) {
3808 for (dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); dest
;
3809 dest
= bgp_route_next(dest
)) {
3810 table
= bgp_dest_get_bgp_table_info(dest
);
3811 bgp_table_finish(&table
);
3814 if (bgp
->route
[afi
][safi
])
3815 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3816 if (bgp
->aggregate
[afi
][safi
])
3817 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3818 if (bgp
->rib
[afi
][safi
])
3819 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3820 rmap
= &bgp
->table_map
[afi
][safi
];
3821 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3824 bgp_scan_finish(bgp
);
3825 bgp_address_destroy(bgp
);
3826 bgp_tip_hash_destroy(bgp
);
3828 /* release the auto RD id */
3829 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3831 bgp_evpn_cleanup(bgp
);
3832 bgp_pbr_cleanup(bgp
);
3833 bgp_srv6_cleanup(bgp
);
3834 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3836 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3837 enum vpn_policy_direction dir
;
3839 if (bgp
->vpn_policy
[afi
].import_vrf
)
3840 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3841 if (bgp
->vpn_policy
[afi
].export_vrf
)
3842 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3844 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3845 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3846 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3847 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3848 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3849 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3852 XFREE(MTYPE_BGP
, bgp
->name
);
3853 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3854 XFREE(MTYPE_BGP
, bgp
->snmp_stats
);
3856 XFREE(MTYPE_BGP
, bgp
);
3859 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3862 struct listnode
*node
, *nnode
;
3868 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3869 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3870 && !CHECK_FLAG(peer
->sflags
,
3871 PEER_STATUS_ACCEPT_PEER
))
3873 } else if (bm
->bgp
!= NULL
) {
3874 struct listnode
*bgpnode
, *nbgpnode
;
3876 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3877 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3879 && !strcmp(peer
->conf_if
, conf_if
)
3880 && !CHECK_FLAG(peer
->sflags
,
3881 PEER_STATUS_ACCEPT_PEER
))
3887 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3890 struct listnode
*node
, *nnode
;
3896 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3897 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3898 && !CHECK_FLAG(peer
->sflags
,
3899 PEER_STATUS_ACCEPT_PEER
))
3901 } else if (bm
->bgp
!= NULL
) {
3902 struct listnode
*bgpnode
, *nbgpnode
;
3904 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3905 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3907 && !strcmp(peer
->hostname
, hostname
)
3908 && !CHECK_FLAG(peer
->sflags
,
3909 PEER_STATUS_ACCEPT_PEER
))
3915 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3917 struct peer
*peer
= NULL
;
3918 struct peer tmp_peer
;
3920 memset(&tmp_peer
, 0, sizeof(struct peer
));
3923 * We do not want to find the doppelganger peer so search for the peer
3925 * the hash that has PEER_FLAG_CONFIG_NODE
3927 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3932 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3933 } else if (bm
->bgp
!= NULL
) {
3934 struct listnode
*bgpnode
, *nbgpnode
;
3936 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3937 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3946 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3947 union sockunion
*su
,
3948 struct peer_group
*group
)
3954 /* Create peer first; we've already checked group config is valid. */
3955 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3956 group
->conf
->as_type
, group
);
3961 peer
= peer_lock(peer
);
3962 listnode_add(group
->peer
, peer
);
3964 peer_group2peer_config_copy(group
, peer
);
3967 * Bind peer for all AFs configured for the group. We don't call
3968 * peer_group_bind as that is sub-optimal and does some stuff we don't
3971 FOREACH_AFI_SAFI (afi
, safi
) {
3972 if (!group
->conf
->afc
[afi
][safi
])
3974 peer
->afc
[afi
][safi
] = 1;
3976 if (!peer_af_find(peer
, afi
, safi
))
3977 peer_af_create(peer
, afi
, safi
);
3979 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3982 /* Mark as dynamic, but also as a "config node" for other things to
3984 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3985 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3991 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3992 struct prefix
*prefix
)
3994 struct listnode
*node
, *nnode
;
3995 struct prefix
*range
;
3998 afi
= family2afi(prefix
->family
);
4000 if (group
->listen_range
[afi
])
4001 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
4003 if (prefix_match(range
, prefix
))
4010 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
4011 struct prefix
**listen_range
)
4013 struct prefix
*range
= NULL
;
4014 struct peer_group
*group
= NULL
;
4015 struct listnode
*node
, *nnode
;
4017 *listen_range
= NULL
;
4019 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
4020 if ((range
= peer_group_lookup_dynamic_neighbor_range(
4023 } else if (bm
->bgp
!= NULL
) {
4024 struct listnode
*bgpnode
, *nbgpnode
;
4026 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
4027 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
4028 if ((range
= peer_group_lookup_dynamic_neighbor_range(
4034 *listen_range
= range
;
4035 return (group
&& range
) ? group
: NULL
;
4038 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
4040 struct peer_group
*group
;
4043 struct prefix prefix
;
4044 struct prefix
*listen_range
;
4047 if (!sockunion2hostprefix(su
, &prefix
))
4050 /* See if incoming connection matches a configured listen range. */
4051 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
4062 if (bgp_debug_neighbor_events(NULL
))
4064 "Dynamic Neighbor %pFX matches group %s listen range %pFX",
4065 &prefix
, group
->name
, listen_range
);
4067 /* Are we within the listen limit? */
4068 dncount
= gbgp
->dynamic_neighbors_count
;
4070 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
4071 if (bgp_debug_neighbor_events(NULL
))
4073 "Dynamic Neighbor %pFX rejected - at limit %d",
4074 &prefix
, gbgp
->dynamic_neighbors_limit
);
4078 /* Ensure group is not disabled. */
4079 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
4080 if (bgp_debug_neighbor_events(NULL
))
4082 "Dynamic Neighbor %pFX rejected - group %s disabled",
4083 &prefix
, group
->name
);
4087 /* Check that at least one AF is activated for the group. */
4088 if (!peer_group_af_configured(group
)) {
4089 if (bgp_debug_neighbor_events(NULL
))
4091 "Dynamic Neighbor %pFX rejected - no AF activated for group %s",
4092 &prefix
, group
->name
);
4096 /* Create dynamic peer and bind to associated group. */
4097 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
4100 gbgp
->dynamic_neighbors_count
= ++dncount
;
4102 if (bgp_debug_neighbor_events(peer
))
4103 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
4104 peer
->host
, group
->name
, dncount
);
4109 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
4112 if (peer
->group
->bgp
) {
4113 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
4115 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
4117 if (bgp_debug_neighbor_events(peer
))
4118 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
4119 peer
->group
->name
, dncount
);
4122 /* If peer is configured at least one address family return 1. */
4123 bool peer_active(struct peer
*peer
)
4125 if (BGP_PEER_SU_UNSPEC(peer
))
4127 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
4128 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
4129 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
4130 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
4131 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
4132 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
4133 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
4134 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
4135 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
4136 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
4137 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
4142 /* If peer is negotiated at least one address family return 1. */
4143 bool peer_active_nego(struct peer
*peer
)
4145 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
4146 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
4147 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
4148 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
4149 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
4150 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
4151 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
4152 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
4153 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
4154 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
4155 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
4156 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
4157 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
4162 /* If peer received at least one address family MP, return true */
4163 bool peer_afc_received(struct peer
*peer
)
4168 FOREACH_AFI_SAFI (afi
, safi
)
4169 if (peer
->afc_recv
[afi
][safi
])
4175 /* If peer advertised at least one address family MP, return true */
4176 bool peer_afc_advertised(struct peer
*peer
)
4181 FOREACH_AFI_SAFI (afi
, safi
)
4182 if (peer
->afc_adv
[afi
][safi
])
4188 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
4189 enum peer_change_type type
)
4191 struct peer_af
*paf
;
4193 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4196 if (!peer_established(peer
))
4199 if (type
== peer_change_reset
) {
4200 /* If we're resetting session, we've to delete both peer struct
4202 if ((peer
->doppelganger
)
4203 && (peer
->doppelganger
->status
!= Deleted
)
4204 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
4205 PEER_FLAG_CONFIG_NODE
)))
4206 peer_delete(peer
->doppelganger
);
4208 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4209 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4210 } else if (type
== peer_change_reset_in
) {
4211 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4212 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4213 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0,
4214 BGP_ROUTE_REFRESH_NORMAL
);
4216 if ((peer
->doppelganger
)
4217 && (peer
->doppelganger
->status
!= Deleted
)
4218 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
4219 PEER_FLAG_CONFIG_NODE
)))
4220 peer_delete(peer
->doppelganger
);
4222 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4223 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4225 } else if (type
== peer_change_reset_out
) {
4226 paf
= peer_af_find(peer
, afi
, safi
);
4227 if (paf
&& paf
->subgroup
)
4228 SET_FLAG(paf
->subgroup
->sflags
,
4229 SUBGRP_STATUS_FORCE_UPDATES
);
4231 update_group_adjust_peer(paf
);
4232 bgp_announce_route(peer
, afi
, safi
, false);
4236 struct peer_flag_action
{
4240 /* This flag can be set for peer-group member. */
4241 uint8_t not_for_member
;
4243 /* Action when the flag is changed. */
4244 enum peer_change_type type
;
4247 static const struct peer_flag_action peer_flag_action_list
[] = {
4248 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
4249 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
4250 {PEER_FLAG_RTT_SHUTDOWN
, 0, peer_change_none
},
4251 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
4252 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
4253 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
4254 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
4255 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
4256 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
4257 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
4258 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
4259 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
4260 {PEER_FLAG_TIMER
, 0, peer_change_none
},
4261 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
4262 {PEER_FLAG_TIMER_DELAYOPEN
, 0, peer_change_none
},
4263 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
4264 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
4265 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
4266 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
4267 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
4268 {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE
, 0, peer_change_none
},
4269 {PEER_FLAG_EXTENDED_OPT_PARAMS
, 0, peer_change_reset
},
4270 {PEER_FLAG_ROLE_STRICT_MODE
, 0, peer_change_reset
},
4271 {PEER_FLAG_ROLE
, 0, peer_change_reset
},
4272 {PEER_FLAG_PORT
, 0, peer_change_reset
},
4275 static const struct peer_flag_action peer_af_flag_action_list
[] = {
4276 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
4277 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
4278 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
4279 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
4280 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
4281 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
4282 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
4283 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
4284 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
4285 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
4286 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
4287 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
4288 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
4289 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
4290 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
4291 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
4292 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
4293 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
4294 {PEER_FLAG_MAX_PREFIX_FORCE
, 0, peer_change_none
},
4295 {PEER_FLAG_MAX_PREFIX_OUT
, 0, peer_change_none
},
4296 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
4297 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
4298 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
4299 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
4300 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
4301 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
4302 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
4303 {PEER_FLAG_DISABLE_ADDPATH_RX
, 0, peer_change_reset
},
4304 {PEER_FLAG_SOO
, 0, peer_change_reset
},
4307 /* Proper action set. */
4308 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
4309 int size
, struct peer_flag_action
*action
,
4316 const struct peer_flag_action
*match
= NULL
;
4318 /* Check peer's frag action. */
4319 for (i
= 0; i
< size
; i
++) {
4320 match
= &action_list
[i
];
4322 if (match
->flag
== 0)
4325 if (match
->flag
& flag
) {
4328 if (match
->type
== peer_change_reset_in
)
4330 if (match
->type
== peer_change_reset_out
)
4332 if (match
->type
== peer_change_reset
) {
4336 if (match
->not_for_member
)
4337 action
->not_for_member
= 1;
4341 /* Set peer clear type. */
4342 if (reset_in
&& reset_out
)
4343 action
->type
= peer_change_reset
;
4345 action
->type
= peer_change_reset_in
;
4347 action
->type
= peer_change_reset_out
;
4349 action
->type
= peer_change_none
;
4354 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
4356 if (flag
== PEER_FLAG_SHUTDOWN
) {
4357 if (CHECK_FLAG(peer
->flags
, flag
)) {
4358 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
4359 peer_nsf_stop(peer
);
4361 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
4363 if (peer
->t_pmax_restart
) {
4364 THREAD_OFF(peer
->t_pmax_restart
);
4365 if (bgp_debug_neighbor_events(peer
))
4367 "%pBP Maximum-prefix restart timer canceled",
4371 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4372 char *msg
= peer
->tx_shutdown_message
;
4374 uint8_t msgbuf
[BGP_ADMIN_SHUTDOWN_MSG_LEN
+ 1];
4376 if (!msg
&& peer_group_active(peer
))
4377 msg
= peer
->group
->conf
4378 ->tx_shutdown_message
;
4379 msglen
= msg
? strlen(msg
) : 0;
4380 if (msglen
> BGP_ADMIN_SHUTDOWN_MSG_LEN
)
4381 msglen
= BGP_ADMIN_SHUTDOWN_MSG_LEN
;
4385 memcpy(msgbuf
+ 1, msg
, msglen
);
4387 bgp_notify_send_with_data(
4388 peer
, BGP_NOTIFY_CEASE
,
4389 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
4390 msgbuf
, msglen
+ 1);
4393 peer
, BGP_NOTIFY_CEASE
,
4394 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4396 bgp_session_reset(peer
);
4398 peer
->v_start
= BGP_INIT_START_TIMER
;
4399 BGP_EVENT_ADD(peer
, BGP_Stop
);
4401 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4402 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
4403 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4404 else if (flag
== PEER_FLAG_PASSIVE
)
4405 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4406 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4407 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4409 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4410 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4412 bgp_session_reset(peer
);
4415 /* Enable global administrative shutdown of all peers of BGP instance */
4416 void bgp_shutdown_enable(struct bgp
*bgp
, const char *msg
)
4419 struct listnode
*node
;
4420 /* length(1) + message(N) */
4421 uint8_t data
[BGP_ADMIN_SHUTDOWN_MSG_LEN
+ 1];
4423 /* do nothing if already shut down */
4424 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_SHUTDOWN
))
4427 /* informational log message */
4428 zlog_info("Enabled administrative shutdown on BGP instance AS %u",
4431 /* iterate through peers of BGP instance */
4432 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
4433 /* continue, if peer is already in administrative shutdown. */
4434 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
4437 /* send a RFC 4486 notification message if necessary */
4438 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4440 size_t datalen
= strlen(msg
);
4442 if (datalen
> BGP_ADMIN_SHUTDOWN_MSG_LEN
)
4443 datalen
= BGP_ADMIN_SHUTDOWN_MSG_LEN
;
4446 memcpy(data
+ 1, msg
, datalen
);
4448 bgp_notify_send_with_data(
4449 peer
, BGP_NOTIFY_CEASE
,
4450 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
, data
,
4454 peer
, BGP_NOTIFY_CEASE
,
4455 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4459 /* reset start timer to initial value */
4460 peer
->v_start
= BGP_INIT_START_TIMER
;
4462 /* trigger a RFC 4271 ManualStop event */
4463 BGP_EVENT_ADD(peer
, BGP_Stop
);
4466 /* set the BGP instances shutdown flag */
4467 SET_FLAG(bgp
->flags
, BGP_FLAG_SHUTDOWN
);
4470 /* Disable global administrative shutdown of all peers of BGP instance */
4471 void bgp_shutdown_disable(struct bgp
*bgp
)
4473 /* do nothing if not shut down. */
4474 if (!CHECK_FLAG(bgp
->flags
, BGP_FLAG_SHUTDOWN
))
4477 /* informational log message */
4478 zlog_info("Disabled administrative shutdown on BGP instance AS %u",
4481 /* clear the BGP instances shutdown flag */
4482 UNSET_FLAG(bgp
->flags
, BGP_FLAG_SHUTDOWN
);
4485 /* Change specified peer flag. */
4486 static int peer_flag_modify(struct peer
*peer
, uint64_t flag
, int set
)
4490 bool invert
, member_invert
;
4491 struct peer
*member
;
4492 struct listnode
*node
, *nnode
;
4493 struct peer_flag_action action
;
4495 memset(&action
, 0, sizeof(struct peer_flag_action
));
4496 size
= sizeof(peer_flag_action_list
) / sizeof(struct peer_flag_action
);
4498 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4499 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4502 /* Abort if no flag action exists. */
4504 return BGP_ERR_INVALID_FLAG
;
4506 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4507 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4508 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4509 return BGP_ERR_PEER_FLAG_CONFLICT
;
4511 /* Handle flag updates where desired state matches current state. */
4512 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4513 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4514 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4518 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4519 COND_FLAG(peer
->flags_override
, flag
, invert
);
4524 /* Inherit from peer-group or set/unset flags accordingly. */
4525 if (peer_group_active(peer
) && set
== invert
)
4526 peer_flag_inherit(peer
, flag
);
4528 COND_FLAG(peer
->flags
, flag
, set
);
4530 /* Check if handling a regular peer. */
4531 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4532 /* Update flag override state accordingly. */
4533 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4536 * For the extended next-hop encoding flag we need to turn RAs
4537 * on if flag is being set, but only turn RAs off if the flag
4538 * is being unset on this peer and if this peer is a member of a
4539 * peer-group, the peer-group also doesn't have the flag set.
4541 if (flag
== PEER_FLAG_CAPABILITY_ENHE
) {
4543 bgp_zebra_initiate_radv(peer
->bgp
, peer
);
4544 } else if (peer_group_active(peer
)) {
4545 if (!CHECK_FLAG(peer
->group
->conf
->flags
,
4548 bgp_zebra_terminate_radv(peer
->bgp
,
4551 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
4554 /* Execute flag action on peer. */
4555 if (action
.type
== peer_change_reset
)
4556 peer_flag_modify_action(peer
, flag
);
4558 /* Skip peer-group mechanics for regular peers. */
4563 * Update peer-group members, unless they are explicitly overriding
4564 * peer-group configuration.
4566 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4567 /* Skip peers with overridden configuration. */
4568 if (CHECK_FLAG(member
->flags_override
, flag
))
4571 /* Check if only member without group is inverted. */
4573 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4575 /* Skip peers with equivalent configuration. */
4576 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4579 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4582 /* Update flag on peer-group member. */
4583 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4585 if (flag
== PEER_FLAG_CAPABILITY_ENHE
&& !member
->conf_if
)
4586 set
? bgp_zebra_initiate_radv(member
->bgp
, member
)
4587 : bgp_zebra_terminate_radv(member
->bgp
, member
);
4589 /* Execute flag action on peer-group member. */
4590 if (action
.type
== peer_change_reset
)
4591 peer_flag_modify_action(member
, flag
);
4597 int peer_flag_set(struct peer
*peer
, uint64_t flag
)
4599 return peer_flag_modify(peer
, flag
, 1);
4602 int peer_flag_unset(struct peer
*peer
, uint64_t flag
)
4604 return peer_flag_modify(peer
, flag
, 0);
4607 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4608 uint64_t flag
, bool set
)
4612 bool invert
, member_invert
;
4613 struct peer
*member
;
4614 struct listnode
*node
, *nnode
;
4615 struct peer_flag_action action
;
4616 enum bgp_peer_sort ptype
;
4618 memset(&action
, 0, sizeof(struct peer_flag_action
));
4619 size
= sizeof(peer_af_flag_action_list
)
4620 / sizeof(struct peer_flag_action
);
4622 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4623 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4626 /* Abort if flag action exists. */
4628 return BGP_ERR_INVALID_FLAG
;
4630 ptype
= peer_sort(peer
);
4631 /* Special check for reflector client. */
4632 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
&& ptype
!= BGP_PEER_IBGP
)
4633 return BGP_ERR_NOT_INTERNAL_PEER
;
4635 /* Special check for remove-private-AS. */
4636 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
&& ptype
== BGP_PEER_IBGP
)
4637 return BGP_ERR_REMOVE_PRIVATE_AS
;
4639 /* as-override is not allowed for IBGP peers */
4640 if (flag
& PEER_FLAG_AS_OVERRIDE
&& ptype
== BGP_PEER_IBGP
)
4641 return BGP_ERR_AS_OVERRIDE
;
4643 /* Handle flag updates where desired state matches current state. */
4644 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4645 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4646 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4651 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4652 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4659 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4660 * if we are setting/unsetting flags which conflict with this flag
4661 * handle accordingly
4663 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4667 * if we are setting NEXTHOP_SELF, we need to unset the
4668 * NEXTHOP_UNCHANGED flag
4670 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4671 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4672 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4673 PEER_FLAG_NEXTHOP_UNCHANGED
);
4677 * if we are unsetting NEXTHOP_SELF, we need to set the
4678 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4680 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4681 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4682 SET_FLAG(peer
->af_flags
[afi
][safi
],
4683 PEER_FLAG_NEXTHOP_UNCHANGED
);
4688 * If the peer is a route server client let's not
4689 * muck with the nexthop on the way out the door
4691 if (flag
& PEER_FLAG_RSERVER_CLIENT
) {
4693 SET_FLAG(peer
->af_flags
[afi
][safi
],
4694 PEER_FLAG_NEXTHOP_UNCHANGED
);
4696 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4697 PEER_FLAG_NEXTHOP_UNCHANGED
);
4700 /* Inherit from peer-group or set/unset flags accordingly. */
4701 if (peer_group_active(peer
) && set
== invert
)
4702 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4704 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4706 /* Execute action when peer is established. */
4707 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4708 && peer_established(peer
)) {
4709 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4710 bgp_clear_adj_in(peer
, afi
, safi
);
4712 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4713 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4714 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4715 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4716 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4717 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4718 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4719 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4721 peer_change_action(peer
, afi
, safi
, action
.type
);
4725 /* Check if handling a regular peer. */
4726 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4727 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4731 * Update peer-group members, unless they are explicitly
4732 * overriding peer-group configuration.
4734 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4736 /* Skip peers with overridden configuration. */
4737 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4741 /* Check if only member without group is inverted. */
4743 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4747 /* Skip peers with equivalent configuration. */
4748 if (set
!= member_invert
4749 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4752 if (set
== member_invert
4753 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4756 /* Update flag on peer-group member. */
4757 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4758 set
!= member_invert
);
4760 /* Execute flag action on peer-group member. */
4761 if (peer_established(member
)) {
4762 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4763 bgp_clear_adj_in(member
, afi
, safi
);
4765 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4766 member
->last_reset
=
4767 PEER_DOWN_RR_CLIENT_CHANGE
;
4769 == PEER_FLAG_RSERVER_CLIENT
)
4770 member
->last_reset
=
4771 PEER_DOWN_RS_CLIENT_CHANGE
;
4773 == PEER_FLAG_ORF_PREFIX_SM
)
4774 member
->last_reset
=
4775 PEER_DOWN_CAPABILITY_CHANGE
;
4777 == PEER_FLAG_ORF_PREFIX_RM
)
4778 member
->last_reset
=
4779 PEER_DOWN_CAPABILITY_CHANGE
;
4781 peer_change_action(member
, afi
, safi
,
4791 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint64_t flag
)
4793 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4796 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint64_t flag
)
4798 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4802 void peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4804 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4805 peer
->tx_shutdown_message
=
4806 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4809 void peer_tx_shutdown_message_unset(struct peer
*peer
)
4811 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4815 /* EBGP multihop configuration. */
4816 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4818 struct peer_group
*group
;
4819 struct listnode
*node
, *nnode
;
4822 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4825 /* is there anything to do? */
4826 if (peer
->ttl
== ttl
)
4829 /* see comment in peer_ttl_security_hops_set() */
4830 if (ttl
!= MAXTTL
) {
4831 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4832 group
= peer
->group
;
4833 if (group
->conf
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4834 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4836 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4838 if (peer1
->sort
== BGP_PEER_IBGP
)
4841 if (peer1
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4842 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4845 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4846 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4852 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4853 if (peer
->sort
!= BGP_PEER_IBGP
) {
4854 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4855 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4856 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4858 bgp_session_reset(peer
);
4860 /* Reconfigure BFD peer with new TTL. */
4861 if (peer
->bfd_config
)
4862 bgp_peer_bfd_update_source(peer
);
4865 group
= peer
->group
;
4866 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4867 if (peer
->sort
== BGP_PEER_IBGP
)
4870 peer
->ttl
= group
->conf
->ttl
;
4872 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4873 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4874 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4876 bgp_session_reset(peer
);
4878 /* Reconfigure BFD peer with new TTL. */
4879 if (peer
->bfd_config
)
4880 bgp_peer_bfd_update_source(peer
);
4886 int peer_ebgp_multihop_unset(struct peer
*peer
)
4888 struct peer_group
*group
;
4889 struct listnode
*node
, *nnode
;
4892 if (peer
->sort
== BGP_PEER_IBGP
)
4895 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
&& peer
->ttl
!= MAXTTL
)
4896 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4898 if (peer_group_active(peer
))
4899 ttl
= peer
->group
->conf
->ttl
;
4901 ttl
= BGP_DEFAULT_TTL
;
4903 if (ttl
== peer
->ttl
)
4908 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4909 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4910 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4911 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4913 bgp_session_reset(peer
);
4915 /* Reconfigure BFD peer with new TTL. */
4916 if (peer
->bfd_config
)
4917 bgp_peer_bfd_update_source(peer
);
4919 group
= peer
->group
;
4920 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4921 if (peer
->sort
== BGP_PEER_IBGP
)
4924 peer
->ttl
= BGP_DEFAULT_TTL
;
4926 if (peer
->fd
>= 0) {
4927 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4929 peer
, BGP_NOTIFY_CEASE
,
4930 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4932 bgp_session_reset(peer
);
4935 /* Reconfigure BFD peer with new TTL. */
4936 if (peer
->bfd_config
)
4937 bgp_peer_bfd_update_source(peer
);
4943 /* Set Open Policy Role and check its correctness */
4944 int peer_role_set(struct peer
*peer
, uint8_t role
, bool strict_mode
)
4946 struct peer
*member
;
4947 struct listnode
*node
, *nnode
;
4949 peer_flag_set(peer
, PEER_FLAG_ROLE
);
4951 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4952 if (peer
->sort
!= BGP_PEER_EBGP
)
4953 return BGP_ERR_INVALID_INTERNAL_ROLE
;
4955 if (peer
->local_role
== role
) {
4956 if (CHECK_FLAG(peer
->flags
,
4957 PEER_FLAG_ROLE_STRICT_MODE
) &&
4959 /* TODO: Is session restart needed if it was
4962 UNSET_FLAG(peer
->flags
,
4963 PEER_FLAG_ROLE_STRICT_MODE
);
4964 if (!CHECK_FLAG(peer
->flags
,
4965 PEER_FLAG_ROLE_STRICT_MODE
) &&
4967 SET_FLAG(peer
->flags
,
4968 PEER_FLAG_ROLE_STRICT_MODE
);
4969 /* Restart session to throw Role Mismatch
4972 if (peer
->remote_role
== ROLE_UNDEFINED
)
4973 bgp_session_reset(peer
);
4976 peer
->local_role
= role
;
4978 SET_FLAG(peer
->flags
,
4979 PEER_FLAG_ROLE_STRICT_MODE
);
4981 UNSET_FLAG(peer
->flags
,
4982 PEER_FLAG_ROLE_STRICT_MODE
);
4983 bgp_session_reset(peer
);
4989 peer
->local_role
= role
;
4990 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4991 if (member
->sort
!= BGP_PEER_EBGP
)
4992 return BGP_ERR_INVALID_INTERNAL_ROLE
;
4994 if (member
->local_role
== role
) {
4995 if (CHECK_FLAG(member
->flags
,
4996 PEER_FLAG_ROLE_STRICT_MODE
) &&
4998 /* TODO: Is session restart needed if it was
5001 UNSET_FLAG(member
->flags
,
5002 PEER_FLAG_ROLE_STRICT_MODE
);
5003 if (!CHECK_FLAG(member
->flags
,
5004 PEER_FLAG_ROLE_STRICT_MODE
) &&
5006 SET_FLAG(peer
->flags
,
5007 PEER_FLAG_ROLE_STRICT_MODE
);
5008 SET_FLAG(member
->flags
,
5009 PEER_FLAG_ROLE_STRICT_MODE
);
5010 /* Restart session to throw Role Mismatch
5013 if (member
->remote_role
== ROLE_UNDEFINED
)
5014 bgp_session_reset(member
);
5017 member
->local_role
= role
;
5020 SET_FLAG(peer
->flags
,
5021 PEER_FLAG_ROLE_STRICT_MODE
);
5022 SET_FLAG(member
->flags
,
5023 PEER_FLAG_ROLE_STRICT_MODE
);
5025 UNSET_FLAG(member
->flags
,
5026 PEER_FLAG_ROLE_STRICT_MODE
);
5028 bgp_session_reset(member
);
5035 int peer_role_unset(struct peer
*peer
)
5037 struct peer
*member
;
5038 struct listnode
*node
, *nnode
;
5040 peer_flag_unset(peer
, PEER_FLAG_ROLE
);
5042 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5043 return peer_role_set(peer
, ROLE_UNDEFINED
, 0);
5045 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
))
5046 peer_role_set(member
, ROLE_UNDEFINED
, 0);
5051 /* Neighbor description. */
5052 void peer_description_set(struct peer
*peer
, const char *desc
)
5054 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
5056 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
5059 void peer_description_unset(struct peer
*peer
)
5061 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
5064 /* Neighbor update-source. */
5065 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
5067 struct peer
*member
;
5068 struct listnode
*node
, *nnode
;
5070 /* Set flag and configuration on peer. */
5071 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
5072 if (peer
->update_if
) {
5073 if (strcmp(peer
->update_if
, ifname
) == 0)
5075 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
5077 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
5078 sockunion_free(peer
->update_source
);
5079 peer
->update_source
= NULL
;
5081 /* Check if handling a regular peer. */
5082 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5083 /* Send notification or reset peer depending on state. */
5084 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5085 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5086 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5087 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5089 bgp_session_reset(peer
);
5091 /* Apply new source configuration to BFD session. */
5092 if (peer
->bfd_config
)
5093 bgp_peer_bfd_update_source(peer
);
5095 /* Skip peer-group mechanics for regular peers. */
5100 * Set flag and configuration on all peer-group members, unless they are
5101 * explicitly overriding peer-group configuration.
5103 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5104 /* Skip peers with overridden configuration. */
5105 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
5108 /* Skip peers with the same configuration. */
5109 if (member
->update_if
) {
5110 if (strcmp(member
->update_if
, ifname
) == 0)
5112 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
5115 /* Set flag and configuration on peer-group member. */
5116 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
5117 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
5118 sockunion_free(member
->update_source
);
5119 member
->update_source
= NULL
;
5121 /* Send notification or reset peer depending on state. */
5122 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5123 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5124 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5125 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5127 bgp_session_reset(member
);
5129 /* Apply new source configuration to BFD session. */
5130 if (member
->bfd_config
)
5131 bgp_peer_bfd_update_source(member
);
5137 void peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
5139 struct peer
*member
;
5140 struct listnode
*node
, *nnode
;
5142 /* Set flag and configuration on peer. */
5143 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
5144 if (peer
->update_source
) {
5145 if (sockunion_cmp(peer
->update_source
, su
) == 0)
5147 sockunion_free(peer
->update_source
);
5149 peer
->update_source
= sockunion_dup(su
);
5150 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
5152 /* Check if handling a regular peer. */
5153 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5154 /* Send notification or reset peer depending on state. */
5155 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5156 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5157 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5158 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5160 bgp_session_reset(peer
);
5162 /* Apply new source configuration to BFD session. */
5163 if (peer
->bfd_config
)
5164 bgp_peer_bfd_update_source(peer
);
5166 /* Skip peer-group mechanics for regular peers. */
5171 * Set flag and configuration on all peer-group members, unless they are
5172 * explicitly overriding peer-group configuration.
5174 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5175 /* Skip peers with overridden configuration. */
5176 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
5179 /* Skip peers with the same configuration. */
5180 if (member
->update_source
) {
5181 if (sockunion_cmp(member
->update_source
, su
) == 0)
5183 sockunion_free(member
->update_source
);
5186 /* Set flag and configuration on peer-group member. */
5187 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
5188 member
->update_source
= sockunion_dup(su
);
5189 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
5191 /* Send notification or reset peer depending on state. */
5192 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5193 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5194 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5195 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5197 bgp_session_reset(member
);
5199 /* Apply new source configuration to BFD session. */
5200 if (member
->bfd_config
)
5201 bgp_peer_bfd_update_source(member
);
5205 void peer_update_source_unset(struct peer
*peer
)
5207 struct peer
*member
;
5208 struct listnode
*node
, *nnode
;
5210 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
5213 /* Inherit configuration from peer-group if peer is member. */
5214 if (peer_group_active(peer
)) {
5215 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
5216 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
5217 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
5218 MTYPE_PEER_UPDATE_SOURCE
);
5220 /* Otherwise remove flag and configuration from peer. */
5221 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
5222 sockunion_free(peer
->update_source
);
5223 peer
->update_source
= NULL
;
5224 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
5227 /* Check if handling a regular peer. */
5228 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5229 /* Send notification or reset peer depending on state. */
5230 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5231 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5233 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5235 bgp_session_reset(peer
);
5237 /* Apply new source configuration to BFD session. */
5238 if (peer
->bfd_config
)
5239 bgp_peer_bfd_update_source(peer
);
5241 /* Skip peer-group mechanics for regular peers. */
5246 * Set flag and configuration on all peer-group members, unless they are
5247 * explicitly overriding peer-group configuration.
5249 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5250 /* Skip peers with overridden configuration. */
5251 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
5254 /* Skip peers with the same configuration. */
5255 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
5256 && !member
->update_source
&& !member
->update_if
)
5259 /* Remove flag and configuration on peer-group member. */
5260 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
5261 sockunion_free(member
->update_source
);
5262 member
->update_source
= NULL
;
5263 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
5265 /* Send notification or reset peer depending on state. */
5266 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5267 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
5268 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5269 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5271 bgp_session_reset(member
);
5273 /* Apply new source configuration to BFD session. */
5274 if (member
->bfd_config
)
5275 bgp_peer_bfd_update_source(member
);
5279 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5280 const char *rmap
, struct route_map
*route_map
)
5282 struct peer
*member
;
5283 struct listnode
*node
, *nnode
;
5284 struct update_subgroup
*subgrp
;
5286 /* Set flag and configuration on peer. */
5287 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
5289 subgrp
= peer_subgroup(peer
, afi
, safi
);
5292 if (!peer
->default_rmap
[afi
][safi
].name
5293 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
5294 if (peer
->default_rmap
[afi
][safi
].name
)
5295 XFREE(MTYPE_ROUTE_MAP_NAME
,
5296 peer
->default_rmap
[afi
][safi
].name
);
5299 * When there is a change in route-map policy,
5300 * this flow gets triggered. Since, the default
5301 * route is already originated, the flag is set.
5302 * The flag should be unset here,
5303 * to trigger the flow of sending update message.
5306 UNSET_FLAG(subgrp
->sflags
,
5307 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
5309 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
5310 peer
->default_rmap
[afi
][safi
].name
=
5311 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
5312 peer
->default_rmap
[afi
][safi
].map
= route_map
;
5313 route_map_counter_increment(route_map
);
5316 if (peer
->default_rmap
[afi
][safi
].name
)
5317 XFREE(MTYPE_ROUTE_MAP_NAME
,
5318 peer
->default_rmap
[afi
][safi
].name
);
5321 * This is triggered in case of route-map deletion.
5322 * The flag needs to be unset, to trigger the flow
5323 * of sending an update message.
5326 UNSET_FLAG(subgrp
->sflags
,
5327 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
5329 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
5330 peer
->default_rmap
[afi
][safi
].name
= NULL
;
5331 peer
->default_rmap
[afi
][safi
].map
= NULL
;
5334 /* Check if handling a regular peer. */
5335 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5336 /* Update peer route announcements. */
5337 if (peer_established(peer
) && peer
->afc_nego
[afi
][safi
]) {
5338 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
5339 bgp_default_originate(peer
, afi
, safi
, 0);
5340 bgp_announce_route(peer
, afi
, safi
, false);
5343 /* Skip peer-group mechanics for regular peers. */
5348 * Set flag and configuration on all peer-group members, unless they are
5349 * explicitly overriding peer-group configuration.
5351 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5352 /* Skip peers with overridden configuration. */
5353 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5354 PEER_FLAG_DEFAULT_ORIGINATE
))
5357 /* Set flag and configuration on peer-group member. */
5358 SET_FLAG(member
->af_flags
[afi
][safi
],
5359 PEER_FLAG_DEFAULT_ORIGINATE
);
5361 if (member
->default_rmap
[afi
][safi
].name
)
5362 XFREE(MTYPE_ROUTE_MAP_NAME
,
5363 member
->default_rmap
[afi
][safi
].name
);
5364 route_map_counter_decrement(
5365 member
->default_rmap
[afi
][safi
].map
);
5366 member
->default_rmap
[afi
][safi
].name
=
5367 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
5368 member
->default_rmap
[afi
][safi
].map
= route_map
;
5369 route_map_counter_increment(route_map
);
5372 /* Update peer route announcements. */
5373 if (peer_established(member
) && member
->afc_nego
[afi
][safi
]) {
5374 update_group_adjust_peer(
5375 peer_af_find(member
, afi
, safi
));
5376 bgp_default_originate(member
, afi
, safi
, 0);
5377 bgp_announce_route(member
, afi
, safi
, false);
5384 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5386 struct peer
*member
;
5387 struct listnode
*node
, *nnode
;
5389 /* Inherit configuration from peer-group if peer is member. */
5390 if (peer_group_active(peer
)) {
5391 peer_af_flag_inherit(peer
, afi
, safi
,
5392 PEER_FLAG_DEFAULT_ORIGINATE
);
5393 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5394 default_rmap
[afi
][safi
].name
,
5395 MTYPE_ROUTE_MAP_NAME
);
5396 PEER_ATTR_INHERIT(peer
, peer
->group
,
5397 default_rmap
[afi
][safi
].map
);
5399 /* Otherwise remove flag and configuration from peer. */
5400 peer_af_flag_unset(peer
, afi
, safi
,
5401 PEER_FLAG_DEFAULT_ORIGINATE
);
5402 if (peer
->default_rmap
[afi
][safi
].name
)
5403 XFREE(MTYPE_ROUTE_MAP_NAME
,
5404 peer
->default_rmap
[afi
][safi
].name
);
5405 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
5406 peer
->default_rmap
[afi
][safi
].name
= NULL
;
5407 peer
->default_rmap
[afi
][safi
].map
= NULL
;
5410 /* Check if handling a regular peer. */
5411 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5412 /* Update peer route announcements. */
5413 if (peer_established(peer
) && peer
->afc_nego
[afi
][safi
]) {
5414 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
5415 bgp_default_originate(peer
, afi
, safi
, 1);
5416 bgp_announce_route(peer
, afi
, safi
, false);
5419 /* Skip peer-group mechanics for regular peers. */
5424 * Remove flag and configuration from all peer-group members, unless
5425 * they are explicitly overriding peer-group configuration.
5427 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5428 /* Skip peers with overridden configuration. */
5429 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5430 PEER_FLAG_DEFAULT_ORIGINATE
))
5433 /* Remove flag and configuration on peer-group member. */
5434 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5435 PEER_FLAG_DEFAULT_ORIGINATE
);
5436 if (member
->default_rmap
[afi
][safi
].name
)
5437 XFREE(MTYPE_ROUTE_MAP_NAME
,
5438 member
->default_rmap
[afi
][safi
].name
);
5439 route_map_counter_decrement(member
->default_rmap
[afi
][safi
].map
);
5440 member
->default_rmap
[afi
][safi
].name
= NULL
;
5441 member
->default_rmap
[afi
][safi
].map
= NULL
;
5443 /* Update peer route announcements. */
5444 if (peer_established(member
) && member
->afc_nego
[afi
][safi
]) {
5445 update_group_adjust_peer(peer_af_find(member
, afi
, safi
));
5446 bgp_default_originate(member
, afi
, safi
, 1);
5447 bgp_announce_route(member
, afi
, safi
, false);
5454 void peer_port_set(struct peer
*peer
, uint16_t port
)
5457 peer_flag_set(peer
, PEER_FLAG_PORT
);
5460 void peer_port_unset(struct peer
*peer
)
5462 peer
->port
= BGP_PORT_DEFAULT
;
5463 peer_flag_unset(peer
, PEER_FLAG_PORT
);
5466 /* Set the TCP-MSS value in the peer structure,
5467 * This gets applied only after connection reset
5468 * So this value will be used in bgp_connect.
5470 void peer_tcp_mss_set(struct peer
*peer
, uint32_t tcp_mss
)
5472 peer
->tcp_mss
= tcp_mss
;
5473 SET_FLAG(peer
->flags
, PEER_FLAG_TCP_MSS
);
5476 /* Reset the TCP-MSS value in the peer structure,
5477 * This gets applied only after connection reset
5478 * So this value will be used in bgp_connect.
5480 void peer_tcp_mss_unset(struct peer
*peer
)
5482 UNSET_FLAG(peer
->flags
, PEER_FLAG_TCP_MSS
);
5487 * Helper function that is called after the name of the policy
5488 * being used by a peer has changed (AF specific). Automatically
5489 * initiates inbound or outbound processing as needed.
5491 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
5495 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
5496 if (peer_established(peer
))
5497 bgp_announce_route(peer
, afi
, safi
, false);
5499 if (!peer_established(peer
))
5502 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5503 PEER_FLAG_SOFT_RECONFIG
)) {
5504 bgp_soft_reconfig_in(peer
, afi
, safi
);
5505 } else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
) ||
5506 CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
)) {
5507 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
5508 PEER_CAP_ORF_PREFIX_SM_ADV
) &&
5509 (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
5510 PEER_CAP_ORF_PREFIX_RM_RCV
) ||
5511 CHECK_FLAG(peer
->af_cap
[afi
][safi
],
5512 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
)))
5513 peer_clear_soft(peer
, afi
, safi
,
5514 BGP_CLEAR_SOFT_IN_ORF_PREFIX
);
5516 bgp_route_refresh_send(
5517 peer
, afi
, safi
, 0, 0, 0,
5518 BGP_ROUTE_REFRESH_NORMAL
);
5524 /* neighbor weight. */
5525 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
5527 struct peer
*member
;
5528 struct listnode
*node
, *nnode
;
5530 /* Set flag and configuration on peer. */
5531 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
5532 if (peer
->weight
[afi
][safi
] != weight
) {
5533 peer
->weight
[afi
][safi
] = weight
;
5534 peer_on_policy_change(peer
, afi
, safi
, 0);
5537 /* Skip peer-group mechanics for regular peers. */
5538 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5542 * Set flag and configuration on all peer-group members, unless they are
5543 * explicitly overriding peer-group configuration.
5545 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5546 /* Skip peers with overridden configuration. */
5547 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5551 /* Set flag and configuration on peer-group member. */
5552 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
5553 if (member
->weight
[afi
][safi
] != weight
) {
5554 member
->weight
[afi
][safi
] = weight
;
5555 peer_on_policy_change(member
, afi
, safi
, 0);
5562 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5564 struct peer
*member
;
5565 struct listnode
*node
, *nnode
;
5567 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
5570 /* Inherit configuration from peer-group if peer is member. */
5571 if (peer_group_active(peer
)) {
5572 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
5573 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
5575 peer_on_policy_change(peer
, afi
, safi
, 0);
5579 /* Remove flag and configuration from peer. */
5580 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
5581 peer
->weight
[afi
][safi
] = 0;
5582 peer_on_policy_change(peer
, afi
, safi
, 0);
5584 /* Skip peer-group mechanics for regular peers. */
5585 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5589 * Remove flag and configuration from all peer-group members, unless
5590 * they are explicitly overriding peer-group configuration.
5592 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5593 /* Skip peers with overridden configuration. */
5594 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5598 /* Skip peers where flag is already disabled. */
5599 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
5602 /* Remove flag and configuration on peer-group member. */
5603 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
5604 member
->weight
[afi
][safi
] = 0;
5605 peer_on_policy_change(member
, afi
, safi
, 0);
5611 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
5613 struct peer
*member
;
5614 struct listnode
*node
, *nnode
;
5616 if (keepalive
> UINT16_MAX
)
5617 return BGP_ERR_INVALID_VALUE
;
5619 if (holdtime
> UINT16_MAX
)
5620 return BGP_ERR_INVALID_VALUE
;
5622 if (holdtime
< 3 && holdtime
!= 0)
5623 return BGP_ERR_INVALID_VALUE
;
5625 /* Set flag and configuration on peer. */
5626 peer_flag_set(peer
, PEER_FLAG_TIMER
);
5627 peer
->holdtime
= holdtime
;
5628 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
5630 /* Skip peer-group mechanics for regular peers. */
5631 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5635 * Set flag and configuration on all peer-group members, unless they are
5636 * explicitly overriding peer-group configuration.
5638 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5639 /* Skip peers with overridden configuration. */
5640 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
5643 /* Set flag and configuration on peer-group member. */
5644 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
5645 PEER_ATTR_INHERIT(member
, peer
->group
, holdtime
);
5646 PEER_ATTR_INHERIT(member
, peer
->group
, keepalive
);
5652 int peer_timers_unset(struct peer
*peer
)
5654 struct peer
*member
;
5655 struct listnode
*node
, *nnode
;
5657 /* Inherit configuration from peer-group if peer is member. */
5658 if (peer_group_active(peer
)) {
5659 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
5660 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
5661 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
5663 /* Otherwise remove flag and configuration from peer. */
5664 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
5666 peer
->keepalive
= 0;
5669 /* Skip peer-group mechanics for regular peers. */
5670 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5674 * Remove flag and configuration from all peer-group members, unless
5675 * they are explicitly overriding peer-group configuration.
5677 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5678 /* Skip peers with overridden configuration. */
5679 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
5682 /* Remove flag and configuration on peer-group member. */
5683 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
5684 member
->holdtime
= 0;
5685 member
->keepalive
= 0;
5691 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
5693 struct peer
*member
;
5694 struct listnode
*node
, *nnode
;
5696 if (connect
> UINT16_MAX
)
5697 return BGP_ERR_INVALID_VALUE
;
5699 /* Set flag and configuration on peer. */
5700 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
5701 peer
->connect
= connect
;
5702 peer
->v_connect
= connect
;
5704 /* Skip peer-group mechanics for regular peers. */
5705 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5706 if (!peer_established(peer
)) {
5707 if (peer_active(peer
))
5708 BGP_EVENT_ADD(peer
, BGP_Stop
);
5709 BGP_EVENT_ADD(peer
, BGP_Start
);
5714 * Set flag and configuration on all peer-group members, unless they are
5715 * explicitly overriding peer-group configuration.
5717 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5718 /* Skip peers with overridden configuration. */
5719 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5722 /* Set flag and configuration on peer-group member. */
5723 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5724 member
->connect
= connect
;
5725 member
->v_connect
= connect
;
5727 if (!peer_established(member
)) {
5728 if (peer_active(member
))
5729 BGP_EVENT_ADD(member
, BGP_Stop
);
5730 BGP_EVENT_ADD(member
, BGP_Start
);
5737 int peer_timers_connect_unset(struct peer
*peer
)
5739 struct peer
*member
;
5740 struct listnode
*node
, *nnode
;
5742 /* Inherit configuration from peer-group if peer is member. */
5743 if (peer_group_active(peer
)) {
5744 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5745 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5747 /* Otherwise remove flag and configuration from peer. */
5748 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5752 /* Set timer with fallback to default value. */
5754 peer
->v_connect
= peer
->connect
;
5756 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
5758 /* Skip peer-group mechanics for regular peers. */
5759 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5760 if (!peer_established(peer
)) {
5761 if (peer_active(peer
))
5762 BGP_EVENT_ADD(peer
, BGP_Stop
);
5763 BGP_EVENT_ADD(peer
, BGP_Start
);
5768 * Remove flag and configuration from all peer-group members, unless
5769 * they are explicitly overriding peer-group configuration.
5771 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5772 /* Skip peers with overridden configuration. */
5773 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5776 /* Remove flag and configuration on peer-group member. */
5777 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5778 member
->connect
= 0;
5779 member
->v_connect
= peer
->bgp
->default_connect_retry
;
5781 if (!peer_established(member
)) {
5782 if (peer_active(member
))
5783 BGP_EVENT_ADD(member
, BGP_Stop
);
5784 BGP_EVENT_ADD(member
, BGP_Start
);
5791 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5793 struct peer
*member
;
5794 struct listnode
*node
, *nnode
;
5797 return BGP_ERR_INVALID_VALUE
;
5799 /* Set flag and configuration on peer. */
5800 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5801 peer
->routeadv
= routeadv
;
5802 peer
->v_routeadv
= routeadv
;
5804 /* Check if handling a regular peer. */
5805 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5806 /* Update peer route announcements. */
5807 update_group_adjust_peer_afs(peer
);
5808 if (peer_established(peer
))
5809 bgp_announce_route_all(peer
);
5811 /* Skip peer-group mechanics for regular peers. */
5816 * Set flag and configuration on all peer-group members, unless they are
5817 * explicitly overriding peer-group configuration.
5819 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5820 /* Skip peers with overridden configuration. */
5821 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5824 /* Set flag and configuration on peer-group member. */
5825 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5826 member
->routeadv
= routeadv
;
5827 member
->v_routeadv
= routeadv
;
5829 /* Update peer route announcements. */
5830 update_group_adjust_peer_afs(member
);
5831 if (peer_established(member
))
5832 bgp_announce_route_all(member
);
5838 int peer_advertise_interval_unset(struct peer
*peer
)
5840 struct peer
*member
;
5841 struct listnode
*node
, *nnode
;
5843 /* Inherit configuration from peer-group if peer is member. */
5844 if (peer_group_active(peer
)) {
5845 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5846 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5848 /* Otherwise remove flag and configuration from peer. */
5849 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5853 /* Set timer with fallback to default value. */
5855 peer
->v_routeadv
= peer
->routeadv
;
5857 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5858 ? BGP_DEFAULT_IBGP_ROUTEADV
5859 : BGP_DEFAULT_EBGP_ROUTEADV
;
5861 /* Check if handling a regular peer. */
5862 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5863 /* Update peer route announcements. */
5864 update_group_adjust_peer_afs(peer
);
5865 if (peer_established(peer
))
5866 bgp_announce_route_all(peer
);
5868 /* Skip peer-group mechanics for regular peers. */
5873 * Remove flag and configuration from all peer-group members, unless
5874 * they are explicitly overriding peer-group configuration.
5876 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5877 /* Skip peers with overridden configuration. */
5878 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5881 /* Remove flag and configuration on peer-group member. */
5882 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5883 member
->routeadv
= 0;
5884 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5885 ? BGP_DEFAULT_IBGP_ROUTEADV
5886 : BGP_DEFAULT_EBGP_ROUTEADV
;
5888 /* Update peer route announcements. */
5889 update_group_adjust_peer_afs(member
);
5890 if (peer_established(member
))
5891 bgp_announce_route_all(member
);
5897 /* set the peers RFC 4271 DelayOpen session attribute flag and DelayOpenTimer
5900 int peer_timers_delayopen_set(struct peer
*peer
, uint32_t delayopen
)
5902 struct peer
*member
;
5903 struct listnode
*node
;
5905 /* Set peers session attribute flag and timer interval. */
5906 peer_flag_set(peer
, PEER_FLAG_TIMER_DELAYOPEN
);
5907 peer
->delayopen
= delayopen
;
5908 peer
->v_delayopen
= delayopen
;
5910 /* Skip group mechanics for regular peers. */
5911 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5914 /* Set flag and configuration on all peer-group members, unless they are
5915 * explicitly overriding peer-group configuration.
5917 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
5918 /* Skip peers with overridden configuration. */
5919 if (CHECK_FLAG(member
->flags_override
,
5920 PEER_FLAG_TIMER_DELAYOPEN
))
5923 /* Set session attribute flag and timer intervals on peer-group
5926 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_DELAYOPEN
);
5927 member
->delayopen
= delayopen
;
5928 member
->v_delayopen
= delayopen
;
5934 /* unset the peers RFC 4271 DelayOpen session attribute flag and reset the
5935 * DelayOpenTimer interval to the default value.
5937 int peer_timers_delayopen_unset(struct peer
*peer
)
5939 struct peer
*member
;
5940 struct listnode
*node
;
5942 /* Inherit configuration from peer-group if peer is member. */
5943 if (peer_group_active(peer
)) {
5944 peer_flag_inherit(peer
, PEER_FLAG_TIMER_DELAYOPEN
);
5945 PEER_ATTR_INHERIT(peer
, peer
->group
, delayopen
);
5947 /* Otherwise remove session attribute flag and set timer
5948 * interval to default value.
5950 peer_flag_unset(peer
, PEER_FLAG_TIMER_DELAYOPEN
);
5951 peer
->delayopen
= peer
->bgp
->default_delayopen
;
5954 /* Set timer value to zero */
5955 peer
->v_delayopen
= 0;
5957 /* Skip peer-group mechanics for regular peers. */
5958 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5961 /* Remove flag and configuration from all peer-group members, unless
5962 * they are explicitly overriding peer-group configuration.
5964 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
5965 /* Skip peers with overridden configuration. */
5966 if (CHECK_FLAG(member
->flags_override
,
5967 PEER_FLAG_TIMER_DELAYOPEN
))
5970 /* Remove session attribute flag, reset the timer interval to
5971 * the default value and set the timer value to zero.
5973 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_DELAYOPEN
);
5974 member
->delayopen
= peer
->bgp
->default_delayopen
;
5975 member
->v_delayopen
= 0;
5981 /* neighbor interface */
5982 void peer_interface_set(struct peer
*peer
, const char *str
)
5984 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5985 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5988 void peer_interface_unset(struct peer
*peer
)
5990 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5994 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5995 int allow_num
, int origin
)
5997 struct peer
*member
;
5998 struct listnode
*node
, *nnode
;
6000 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
6001 return BGP_ERR_INVALID_VALUE
;
6003 /* Set flag and configuration on peer. */
6004 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
6006 if (peer
->allowas_in
[afi
][safi
] != 0
6007 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6008 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6009 peer_af_flag_set(peer
, afi
, safi
,
6010 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6011 peer
->allowas_in
[afi
][safi
] = 0;
6012 peer_on_policy_change(peer
, afi
, safi
, 0);
6015 if (peer
->allowas_in
[afi
][safi
] != allow_num
6016 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6017 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6019 peer_af_flag_unset(peer
, afi
, safi
,
6020 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6021 peer
->allowas_in
[afi
][safi
] = allow_num
;
6022 peer_on_policy_change(peer
, afi
, safi
, 0);
6026 /* Skip peer-group mechanics for regular peers. */
6027 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
6031 * Set flag and configuration on all peer-group members, unless
6032 * they are explicitly overriding peer-group configuration.
6034 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6035 /* Skip peers with overridden configuration. */
6036 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6037 PEER_FLAG_ALLOWAS_IN
))
6040 /* Set flag and configuration on peer-group member. */
6041 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
6043 if (member
->allowas_in
[afi
][safi
] != 0
6044 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
6045 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6046 SET_FLAG(member
->af_flags
[afi
][safi
],
6047 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6048 member
->allowas_in
[afi
][safi
] = 0;
6049 peer_on_policy_change(peer
, afi
, safi
, 0);
6052 if (member
->allowas_in
[afi
][safi
] != allow_num
6053 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
6054 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6055 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6056 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6057 member
->allowas_in
[afi
][safi
] = allow_num
;
6058 peer_on_policy_change(peer
, afi
, safi
, 0);
6066 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6068 struct peer
*member
;
6069 struct listnode
*node
, *nnode
;
6071 /* Skip peer if flag is already disabled. */
6072 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
6075 /* Inherit configuration from peer-group if peer is member. */
6076 if (peer_group_active(peer
)) {
6077 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
6078 peer_af_flag_inherit(peer
, afi
, safi
,
6079 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6080 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
6081 peer_on_policy_change(peer
, afi
, safi
, 0);
6086 /* Remove flag and configuration from peer. */
6087 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
6088 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6089 peer
->allowas_in
[afi
][safi
] = 0;
6090 peer_on_policy_change(peer
, afi
, safi
, 0);
6092 /* Skip peer-group mechanics if handling a regular peer. */
6093 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
6097 * Remove flags and configuration from all peer-group members, unless
6098 * they are explicitly overriding peer-group configuration.
6100 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6101 /* Skip peers with overridden configuration. */
6102 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6103 PEER_FLAG_ALLOWAS_IN
))
6106 /* Remove flags and configuration on peer-group member. */
6107 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
6108 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6109 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
6110 member
->allowas_in
[afi
][safi
] = 0;
6111 peer_on_policy_change(member
, afi
, safi
, 0);
6117 int peer_local_as_set(struct peer
*peer
, as_t as
, bool no_prepend
,
6120 bool old_no_prepend
, old_replace_as
;
6121 struct bgp
*bgp
= peer
->bgp
;
6122 struct peer
*member
;
6123 struct listnode
*node
, *nnode
;
6124 enum bgp_peer_sort ptype
= peer_sort(peer
);
6126 if (ptype
!= BGP_PEER_EBGP
&& ptype
!= BGP_PEER_INTERNAL
)
6127 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
6130 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
6133 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
6135 /* Save previous flag states. */
6137 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
6139 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
6141 /* Set flag and configuration on peer. */
6142 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
6143 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
6144 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
6146 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
6147 && old_replace_as
== replace_as
)
6149 peer
->change_local_as
= as
;
6151 /* Check if handling a regular peer. */
6152 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6153 /* Send notification or reset peer depending on state. */
6154 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
6155 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
6156 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6157 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6159 bgp_session_reset(peer
);
6161 /* Skip peer-group mechanics for regular peers. */
6166 * Set flag and configuration on all peer-group members, unless they are
6167 * explicitly overriding peer-group configuration.
6169 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6170 /* Skip peers with overridden configuration. */
6171 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
6174 /* Skip peers with the same configuration. */
6175 old_no_prepend
= CHECK_FLAG(member
->flags
,
6176 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
6177 old_replace_as
= CHECK_FLAG(member
->flags
,
6178 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
6179 if (member
->change_local_as
== as
6180 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
6181 && old_no_prepend
== no_prepend
6182 && old_replace_as
== replace_as
)
6185 /* Set flag and configuration on peer-group member. */
6186 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
6187 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
6189 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
6191 member
->change_local_as
= as
;
6193 /* Send notification or stop peer depending on state. */
6194 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
6195 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
6196 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
6197 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6199 BGP_EVENT_ADD(member
, BGP_Stop
);
6205 int peer_local_as_unset(struct peer
*peer
)
6207 struct peer
*member
;
6208 struct listnode
*node
, *nnode
;
6210 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
6213 /* Inherit configuration from peer-group if peer is member. */
6214 if (peer_group_active(peer
)) {
6215 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
6216 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
6217 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
6218 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
6220 /* Otherwise remove flag and configuration from peer. */
6221 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
6222 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
6223 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
6224 peer
->change_local_as
= 0;
6227 /* Check if handling a regular peer. */
6228 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6229 /* Send notification or stop peer depending on state. */
6230 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
6231 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
6232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6233 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6235 BGP_EVENT_ADD(peer
, BGP_Stop
);
6237 /* Skip peer-group mechanics for regular peers. */
6242 * Remove flag and configuration from all peer-group members, unless
6243 * they are explicitly overriding peer-group configuration.
6245 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6246 /* Skip peers with overridden configuration. */
6247 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
6250 /* Remove flag and configuration on peer-group member. */
6251 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
6252 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
6253 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
6254 member
->change_local_as
= 0;
6256 /* Send notification or stop peer depending on state. */
6257 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
6258 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
6259 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
6260 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6262 bgp_session_reset(member
);
6268 /* Set password for authenticating with the peer. */
6269 int peer_password_set(struct peer
*peer
, const char *password
)
6271 struct peer
*member
;
6272 struct listnode
*node
, *nnode
;
6273 int len
= password
? strlen(password
) : 0;
6274 int ret
= BGP_SUCCESS
;
6276 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
6277 return BGP_ERR_INVALID_VALUE
;
6279 /* Set flag and configuration on peer. */
6280 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
6281 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
6283 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
6284 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
6286 /* Check if handling a regular peer. */
6287 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6288 /* Send notification or reset peer depending on state. */
6289 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6290 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6291 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6293 bgp_session_reset(peer
);
6296 * Attempt to install password on socket and skip peer-group
6299 if (BGP_PEER_SU_UNSPEC(peer
))
6301 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
6302 : BGP_ERR_TCPSIG_FAILED
;
6306 * Set flag and configuration on all peer-group members, unless they are
6307 * explicitly overriding peer-group configuration.
6309 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6310 /* Skip peers with overridden configuration. */
6311 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
6314 /* Skip peers with the same password. */
6315 if (member
->password
&& strcmp(member
->password
, password
) == 0)
6318 /* Set flag and configuration on peer-group member. */
6319 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
6320 if (member
->password
)
6321 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
6322 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
6324 /* Send notification or reset peer depending on state. */
6325 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
6326 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
6327 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6329 bgp_session_reset(member
);
6331 /* Attempt to install password on socket. */
6332 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
6333 ret
= BGP_ERR_TCPSIG_FAILED
;
6336 /* Set flag and configuration on all peer-group listen ranges */
6337 struct listnode
*ln
;
6340 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
6341 bgp_md5_set_prefix(peer
->bgp
, lr
, password
);
6342 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
6343 bgp_md5_set_prefix(peer
->bgp
, lr
, password
);
6348 int peer_password_unset(struct peer
*peer
)
6350 struct peer
*member
;
6351 struct listnode
*node
, *nnode
;
6353 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
6356 /* Inherit configuration from peer-group if peer is member. */
6357 if (peer_group_active(peer
)) {
6358 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
6359 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
6360 MTYPE_PEER_PASSWORD
);
6362 /* Otherwise remove flag and configuration from peer. */
6363 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
6364 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
6367 /* Check if handling a regular peer. */
6368 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6369 /* Send notification or reset peer depending on state. */
6370 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6371 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6372 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6374 bgp_session_reset(peer
);
6376 /* Attempt to uninstall password on socket. */
6377 if (!BGP_PEER_SU_UNSPEC(peer
))
6378 bgp_md5_unset(peer
);
6379 /* Skip peer-group mechanics for regular peers. */
6384 * Remove flag and configuration from all peer-group members, unless
6385 * they are explicitly overriding peer-group configuration.
6387 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6388 /* Skip peers with overridden configuration. */
6389 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
6392 /* Remove flag and configuration on peer-group member. */
6393 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
6394 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
6396 /* Send notification or reset peer depending on state. */
6397 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
6398 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
6399 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
6401 bgp_session_reset(member
);
6403 /* Attempt to uninstall password on socket. */
6404 if (!BGP_PEER_SU_UNSPEC(member
))
6405 bgp_md5_unset(member
);
6408 /* Set flag and configuration on all peer-group listen ranges */
6409 struct listnode
*ln
;
6412 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
6413 bgp_md5_unset_prefix(peer
->bgp
, lr
);
6414 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
6415 bgp_md5_unset_prefix(peer
->bgp
, lr
);
6421 /* Set distribute list to the peer. */
6422 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6425 struct peer
*member
;
6426 struct bgp_filter
*filter
;
6427 struct listnode
*node
, *nnode
;
6429 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6430 return BGP_ERR_INVALID_VALUE
;
6432 /* Set configuration on peer. */
6433 filter
= &peer
->filter
[afi
][safi
];
6434 if (filter
->plist
[direct
].name
)
6435 return BGP_ERR_PEER_FILTER_CONFLICT
;
6436 if (filter
->dlist
[direct
].name
)
6437 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
6438 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6439 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
6441 /* Check if handling a regular peer. */
6442 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6443 /* Set override-flag and process peer route updates. */
6444 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6445 PEER_FT_DISTRIBUTE_LIST
);
6446 peer_on_policy_change(peer
, afi
, safi
,
6447 (direct
== FILTER_OUT
) ? 1 : 0);
6449 /* Skip peer-group mechanics for regular peers. */
6454 * Set configuration on all peer-group members, un less they are
6455 * explicitly overriding peer-group configuration.
6457 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6458 /* Skip peers with overridden configuration. */
6459 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6460 PEER_FT_DISTRIBUTE_LIST
))
6463 /* Set configuration on peer-group member. */
6464 filter
= &member
->filter
[afi
][safi
];
6465 if (filter
->dlist
[direct
].name
)
6466 XFREE(MTYPE_BGP_FILTER_NAME
,
6467 filter
->dlist
[direct
].name
);
6468 filter
->dlist
[direct
].name
=
6469 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6470 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
6472 /* Process peer route updates. */
6473 peer_on_policy_change(member
, afi
, safi
,
6474 (direct
== FILTER_OUT
) ? 1 : 0);
6480 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6482 struct peer
*member
;
6483 struct bgp_filter
*filter
;
6484 struct listnode
*node
, *nnode
;
6486 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6487 return BGP_ERR_INVALID_VALUE
;
6489 /* Unset override-flag unconditionally. */
6490 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6491 PEER_FT_DISTRIBUTE_LIST
);
6493 /* Inherit configuration from peer-group if peer is member. */
6494 if (peer_group_active(peer
)) {
6495 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6496 filter
[afi
][safi
].dlist
[direct
].name
,
6497 MTYPE_BGP_FILTER_NAME
);
6498 PEER_ATTR_INHERIT(peer
, peer
->group
,
6499 filter
[afi
][safi
].dlist
[direct
].alist
);
6501 /* Otherwise remove configuration from peer. */
6502 filter
= &peer
->filter
[afi
][safi
];
6503 if (filter
->dlist
[direct
].name
)
6504 XFREE(MTYPE_BGP_FILTER_NAME
,
6505 filter
->dlist
[direct
].name
);
6506 filter
->dlist
[direct
].name
= NULL
;
6507 filter
->dlist
[direct
].alist
= NULL
;
6510 /* Check if handling a regular peer. */
6511 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6512 /* Process peer route updates. */
6513 peer_on_policy_change(peer
, afi
, safi
,
6514 (direct
== FILTER_OUT
) ? 1 : 0);
6516 /* Skip peer-group mechanics for regular peers. */
6521 * Remove configuration on all peer-group members, unless they are
6522 * explicitly overriding peer-group configuration.
6524 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6525 /* Skip peers with overridden configuration. */
6526 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6527 PEER_FT_DISTRIBUTE_LIST
))
6530 /* Remove configuration on peer-group member. */
6531 filter
= &member
->filter
[afi
][safi
];
6532 if (filter
->dlist
[direct
].name
)
6533 XFREE(MTYPE_BGP_FILTER_NAME
,
6534 filter
->dlist
[direct
].name
);
6535 filter
->dlist
[direct
].name
= NULL
;
6536 filter
->dlist
[direct
].alist
= NULL
;
6538 /* Process peer route updates. */
6539 peer_on_policy_change(member
, afi
, safi
,
6540 (direct
== FILTER_OUT
) ? 1 : 0);
6546 /* Update distribute list. */
6547 static void peer_distribute_update(struct access_list
*access
)
6552 struct listnode
*mnode
, *mnnode
;
6553 struct listnode
*node
, *nnode
;
6556 struct peer_group
*group
;
6557 struct bgp_filter
*filter
;
6559 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6561 update_group_policy_update(bgp
,
6562 BGP_POLICY_DISTRIBUTE_LIST
,
6563 access
->name
, true, 0);
6564 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6565 FOREACH_AFI_SAFI (afi
, safi
) {
6566 filter
= &peer
->filter
[afi
][safi
];
6568 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6570 if (filter
->dlist
[direct
].name
)
6571 filter
->dlist
[direct
]
6572 .alist
= access_list_lookup(
6574 filter
->dlist
[direct
]
6577 filter
->dlist
[direct
].alist
=
6582 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6583 FOREACH_AFI_SAFI (afi
, safi
) {
6584 filter
= &group
->conf
->filter
[afi
][safi
];
6586 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6588 if (filter
->dlist
[direct
].name
)
6589 filter
->dlist
[direct
]
6590 .alist
= access_list_lookup(
6592 filter
->dlist
[direct
]
6595 filter
->dlist
[direct
].alist
=
6600 #ifdef ENABLE_BGP_VNC
6601 vnc_prefix_list_update(bgp
);
6606 /* Set prefix list to the peer. */
6607 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6610 struct peer
*member
;
6611 struct bgp_filter
*filter
;
6612 struct listnode
*node
, *nnode
;
6614 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6615 return BGP_ERR_INVALID_VALUE
;
6617 /* Set configuration on peer. */
6618 filter
= &peer
->filter
[afi
][safi
];
6619 if (filter
->dlist
[direct
].name
)
6620 return BGP_ERR_PEER_FILTER_CONFLICT
;
6621 if (filter
->plist
[direct
].name
)
6622 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
6623 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6624 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
6626 /* Check if handling a regular peer. */
6627 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6628 /* Set override-flag and process peer route updates. */
6629 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6630 PEER_FT_PREFIX_LIST
);
6631 peer_on_policy_change(peer
, afi
, safi
,
6632 (direct
== FILTER_OUT
) ? 1 : 0);
6634 /* Skip peer-group mechanics for regular peers. */
6639 * Set configuration on all peer-group members, unless they are
6640 * explicitly overriding peer-group configuration.
6642 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6643 /* Skip peers with overridden configuration. */
6644 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6645 PEER_FT_PREFIX_LIST
))
6648 /* Set configuration on peer-group member. */
6649 filter
= &member
->filter
[afi
][safi
];
6650 if (filter
->plist
[direct
].name
)
6651 XFREE(MTYPE_BGP_FILTER_NAME
,
6652 filter
->plist
[direct
].name
);
6653 filter
->plist
[direct
].name
=
6654 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6655 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
6657 /* Process peer route updates. */
6658 peer_on_policy_change(member
, afi
, safi
,
6659 (direct
== FILTER_OUT
) ? 1 : 0);
6665 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
6668 struct peer
*member
;
6669 struct bgp_filter
*filter
;
6670 struct listnode
*node
, *nnode
;
6672 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6673 return BGP_ERR_INVALID_VALUE
;
6675 /* Unset override-flag unconditionally. */
6676 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6677 PEER_FT_PREFIX_LIST
);
6679 /* Inherit configuration from peer-group if peer is member. */
6680 if (peer_group_active(peer
)) {
6681 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6682 filter
[afi
][safi
].plist
[direct
].name
,
6683 MTYPE_BGP_FILTER_NAME
);
6684 PEER_ATTR_INHERIT(peer
, peer
->group
,
6685 filter
[afi
][safi
].plist
[direct
].plist
);
6687 /* Otherwise remove configuration from peer. */
6688 filter
= &peer
->filter
[afi
][safi
];
6689 if (filter
->plist
[direct
].name
)
6690 XFREE(MTYPE_BGP_FILTER_NAME
,
6691 filter
->plist
[direct
].name
);
6692 filter
->plist
[direct
].name
= NULL
;
6693 filter
->plist
[direct
].plist
= NULL
;
6696 /* Check if handling a regular peer. */
6697 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6698 /* Process peer route updates. */
6699 peer_on_policy_change(peer
, afi
, safi
,
6700 (direct
== FILTER_OUT
) ? 1 : 0);
6702 /* Skip peer-group mechanics for regular peers. */
6707 * Remove configuration on all peer-group members, unless they are
6708 * explicitly overriding peer-group configuration.
6710 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6711 /* Skip peers with overridden configuration. */
6712 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6713 PEER_FT_PREFIX_LIST
))
6716 /* Remove configuration on peer-group member. */
6717 filter
= &member
->filter
[afi
][safi
];
6718 if (filter
->plist
[direct
].name
)
6719 XFREE(MTYPE_BGP_FILTER_NAME
,
6720 filter
->plist
[direct
].name
);
6721 filter
->plist
[direct
].name
= NULL
;
6722 filter
->plist
[direct
].plist
= NULL
;
6724 /* Process peer route updates. */
6725 peer_on_policy_change(member
, afi
, safi
,
6726 (direct
== FILTER_OUT
) ? 1 : 0);
6732 /* Update prefix-list list. */
6733 static void peer_prefix_list_update(struct prefix_list
*plist
)
6735 struct listnode
*mnode
, *mnnode
;
6736 struct listnode
*node
, *nnode
;
6739 struct peer_group
*group
;
6740 struct bgp_filter
*filter
;
6745 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6748 * Update the prefix-list on update groups.
6750 update_group_policy_update(
6751 bgp
, BGP_POLICY_PREFIX_LIST
,
6752 plist
? prefix_list_name(plist
) : NULL
, true, 0);
6754 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6755 FOREACH_AFI_SAFI (afi
, safi
) {
6756 filter
= &peer
->filter
[afi
][safi
];
6758 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6760 if (filter
->plist
[direct
].name
)
6761 filter
->plist
[direct
]
6762 .plist
= prefix_list_lookup(
6764 filter
->plist
[direct
]
6767 filter
->plist
[direct
].plist
=
6771 /* If we touch prefix-list, we need to process
6772 * new updates. This is important for ORF to
6773 * work correctly as well.
6775 if (peer
->afc_nego
[afi
][safi
])
6776 peer_on_policy_change(peer
, afi
, safi
,
6780 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6781 FOREACH_AFI_SAFI (afi
, safi
) {
6782 filter
= &group
->conf
->filter
[afi
][safi
];
6784 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6786 if (filter
->plist
[direct
].name
)
6787 filter
->plist
[direct
]
6788 .plist
= prefix_list_lookup(
6790 filter
->plist
[direct
]
6793 filter
->plist
[direct
].plist
=
6801 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6804 struct peer
*member
;
6805 struct bgp_filter
*filter
;
6806 struct listnode
*node
, *nnode
;
6808 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6809 return BGP_ERR_INVALID_VALUE
;
6811 /* Set configuration on peer. */
6812 filter
= &peer
->filter
[afi
][safi
];
6813 if (filter
->aslist
[direct
].name
)
6814 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6815 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6816 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6818 /* Check if handling a regular peer. */
6819 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6820 /* Set override-flag and process peer route updates. */
6821 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6822 PEER_FT_FILTER_LIST
);
6823 peer_on_policy_change(peer
, afi
, safi
,
6824 (direct
== FILTER_OUT
) ? 1 : 0);
6826 /* Skip peer-group mechanics for regular peers. */
6831 * Set configuration on all peer-group members, unless they are
6832 * explicitly overriding peer-group configuration.
6834 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6835 /* Skip peers with overridden configuration. */
6836 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6837 PEER_FT_FILTER_LIST
))
6840 /* Set configuration on peer-group member. */
6841 filter
= &member
->filter
[afi
][safi
];
6842 if (filter
->aslist
[direct
].name
)
6843 XFREE(MTYPE_BGP_FILTER_NAME
,
6844 filter
->aslist
[direct
].name
);
6845 filter
->aslist
[direct
].name
=
6846 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6847 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6849 /* Process peer route updates. */
6850 peer_on_policy_change(member
, afi
, safi
,
6851 (direct
== FILTER_OUT
) ? 1 : 0);
6857 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6859 struct peer
*member
;
6860 struct bgp_filter
*filter
;
6861 struct listnode
*node
, *nnode
;
6863 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6864 return BGP_ERR_INVALID_VALUE
;
6866 /* Unset override-flag unconditionally. */
6867 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6868 PEER_FT_FILTER_LIST
);
6870 /* Inherit configuration from peer-group if peer is member. */
6871 if (peer_group_active(peer
)) {
6872 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6873 filter
[afi
][safi
].aslist
[direct
].name
,
6874 MTYPE_BGP_FILTER_NAME
);
6875 PEER_ATTR_INHERIT(peer
, peer
->group
,
6876 filter
[afi
][safi
].aslist
[direct
].aslist
);
6878 /* Otherwise remove configuration from peer. */
6879 filter
= &peer
->filter
[afi
][safi
];
6880 if (filter
->aslist
[direct
].name
)
6881 XFREE(MTYPE_BGP_FILTER_NAME
,
6882 filter
->aslist
[direct
].name
);
6883 filter
->aslist
[direct
].name
= NULL
;
6884 filter
->aslist
[direct
].aslist
= NULL
;
6887 /* Check if handling a regular peer. */
6888 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6889 /* Process peer route updates. */
6890 peer_on_policy_change(peer
, afi
, safi
,
6891 (direct
== FILTER_OUT
) ? 1 : 0);
6893 /* Skip peer-group mechanics for regular peers. */
6898 * Remove configuration on all peer-group members, unless they are
6899 * explicitly overriding peer-group configuration.
6901 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6902 /* Skip peers with overridden configuration. */
6903 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6904 PEER_FT_FILTER_LIST
))
6907 /* Remove configuration on peer-group member. */
6908 filter
= &member
->filter
[afi
][safi
];
6909 if (filter
->aslist
[direct
].name
)
6910 XFREE(MTYPE_BGP_FILTER_NAME
,
6911 filter
->aslist
[direct
].name
);
6912 filter
->aslist
[direct
].name
= NULL
;
6913 filter
->aslist
[direct
].aslist
= NULL
;
6915 /* Process peer route updates. */
6916 peer_on_policy_change(member
, afi
, safi
,
6917 (direct
== FILTER_OUT
) ? 1 : 0);
6923 static void peer_aslist_update(const char *aslist_name
)
6928 struct listnode
*mnode
, *mnnode
;
6929 struct listnode
*node
, *nnode
;
6932 struct peer_group
*group
;
6933 struct bgp_filter
*filter
;
6935 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6936 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6937 aslist_name
, true, 0);
6939 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6940 FOREACH_AFI_SAFI (afi
, safi
) {
6941 filter
= &peer
->filter
[afi
][safi
];
6943 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6945 if (filter
->aslist
[direct
].name
)
6946 filter
->aslist
[direct
]
6947 .aslist
= as_list_lookup(
6948 filter
->aslist
[direct
]
6951 filter
->aslist
[direct
].aslist
=
6956 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6957 FOREACH_AFI_SAFI (afi
, safi
) {
6958 filter
= &group
->conf
->filter
[afi
][safi
];
6960 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6962 if (filter
->aslist
[direct
].name
)
6963 filter
->aslist
[direct
]
6964 .aslist
= as_list_lookup(
6965 filter
->aslist
[direct
]
6968 filter
->aslist
[direct
].aslist
=
6976 static void peer_aslist_add(char *aslist_name
)
6978 peer_aslist_update(aslist_name
);
6979 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_ADDED
);
6982 static void peer_aslist_del(const char *aslist_name
)
6984 peer_aslist_update(aslist_name
);
6985 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6989 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6990 const char *name
, struct route_map
*route_map
)
6992 struct peer
*member
;
6993 struct bgp_filter
*filter
;
6994 struct listnode
*node
, *nnode
;
6996 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6997 return BGP_ERR_INVALID_VALUE
;
6999 /* Set configuration on peer. */
7000 filter
= &peer
->filter
[afi
][safi
];
7001 if (filter
->map
[direct
].name
) {
7002 /* If the neighbor is configured with the same route-map
7003 * again then, ignore the duplicate configuration.
7005 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
7008 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
7010 route_map_counter_decrement(filter
->map
[direct
].map
);
7011 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
7012 filter
->map
[direct
].map
= route_map
;
7013 route_map_counter_increment(route_map
);
7015 /* Check if handling a regular peer. */
7016 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7017 /* Set override-flag and process peer route updates. */
7018 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
7020 peer_on_policy_change(peer
, afi
, safi
,
7021 (direct
== RMAP_OUT
) ? 1 : 0);
7023 /* Skip peer-group mechanics for regular peers. */
7028 * Set configuration on all peer-group members, unless they are
7029 * explicitly overriding peer-group configuration.
7031 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7032 /* Skip peers with overridden configuration. */
7033 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
7037 /* Set configuration on peer-group member. */
7038 filter
= &member
->filter
[afi
][safi
];
7039 if (filter
->map
[direct
].name
)
7040 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
7041 route_map_counter_decrement(filter
->map
[direct
].map
);
7042 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
7043 filter
->map
[direct
].map
= route_map
;
7044 route_map_counter_increment(route_map
);
7046 /* Process peer route updates. */
7047 peer_on_policy_change(member
, afi
, safi
,
7048 (direct
== RMAP_OUT
) ? 1 : 0);
7053 /* Unset route-map from the peer. */
7054 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
7056 struct peer
*member
;
7057 struct bgp_filter
*filter
;
7058 struct listnode
*node
, *nnode
;
7060 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
7061 return BGP_ERR_INVALID_VALUE
;
7063 /* Unset override-flag unconditionally. */
7064 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
7066 /* Inherit configuration from peer-group if peer is member. */
7067 if (peer_group_active(peer
)) {
7068 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
7069 filter
[afi
][safi
].map
[direct
].name
,
7070 MTYPE_BGP_FILTER_NAME
);
7071 PEER_ATTR_INHERIT(peer
, peer
->group
,
7072 filter
[afi
][safi
].map
[direct
].map
);
7074 /* Otherwise remove configuration from peer. */
7075 filter
= &peer
->filter
[afi
][safi
];
7076 if (filter
->map
[direct
].name
)
7077 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
7078 route_map_counter_decrement(filter
->map
[direct
].map
);
7079 filter
->map
[direct
].name
= NULL
;
7080 filter
->map
[direct
].map
= NULL
;
7083 /* Check if handling a regular peer. */
7084 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7085 /* Process peer route updates. */
7086 peer_on_policy_change(peer
, afi
, safi
,
7087 (direct
== RMAP_OUT
) ? 1 : 0);
7089 /* Skip peer-group mechanics for regular peers. */
7094 * Remove configuration on all peer-group members, unless they are
7095 * explicitly overriding peer-group configuration.
7097 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7098 /* Skip peers with overridden configuration. */
7099 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
7103 /* Remove configuration on peer-group member. */
7104 filter
= &member
->filter
[afi
][safi
];
7105 if (filter
->map
[direct
].name
)
7106 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
7107 route_map_counter_decrement(filter
->map
[direct
].map
);
7108 filter
->map
[direct
].name
= NULL
;
7109 filter
->map
[direct
].map
= NULL
;
7111 /* Process peer route updates. */
7112 peer_on_policy_change(member
, afi
, safi
,
7113 (direct
== RMAP_OUT
) ? 1 : 0);
7119 /* Set unsuppress-map to the peer. */
7120 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
7121 const char *name
, struct route_map
*route_map
)
7123 struct peer
*member
;
7124 struct bgp_filter
*filter
;
7125 struct listnode
*node
, *nnode
;
7127 /* Set configuration on peer. */
7128 filter
= &peer
->filter
[afi
][safi
];
7129 if (filter
->usmap
.name
)
7130 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
7131 route_map_counter_decrement(filter
->usmap
.map
);
7132 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
7133 filter
->usmap
.map
= route_map
;
7134 route_map_counter_increment(route_map
);
7136 /* Check if handling a regular peer. */
7137 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7138 /* Set override-flag and process peer route updates. */
7139 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
7140 PEER_FT_UNSUPPRESS_MAP
);
7141 peer_on_policy_change(peer
, afi
, safi
, 1);
7143 /* Skip peer-group mechanics for regular peers. */
7148 * Set configuration on all peer-group members, unless they are
7149 * explicitly overriding peer-group configuration.
7151 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7152 /* Skip peers with overridden configuration. */
7153 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
7154 PEER_FT_UNSUPPRESS_MAP
))
7157 /* Set configuration on peer-group member. */
7158 filter
= &member
->filter
[afi
][safi
];
7159 if (filter
->usmap
.name
)
7160 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
7161 route_map_counter_decrement(filter
->usmap
.map
);
7162 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
7163 filter
->usmap
.map
= route_map
;
7164 route_map_counter_increment(route_map
);
7166 /* Process peer route updates. */
7167 peer_on_policy_change(member
, afi
, safi
, 1);
7173 /* Unset route-map from the peer. */
7174 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
7176 struct peer
*member
;
7177 struct bgp_filter
*filter
;
7178 struct listnode
*node
, *nnode
;
7180 /* Unset override-flag unconditionally. */
7181 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
7183 /* Inherit configuration from peer-group if peer is member. */
7184 if (peer_group_active(peer
)) {
7185 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
7186 filter
[afi
][safi
].usmap
.name
,
7187 MTYPE_BGP_FILTER_NAME
);
7188 PEER_ATTR_INHERIT(peer
, peer
->group
,
7189 filter
[afi
][safi
].usmap
.map
);
7191 /* Otherwise remove configuration from peer. */
7192 filter
= &peer
->filter
[afi
][safi
];
7193 if (filter
->usmap
.name
)
7194 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
7195 route_map_counter_decrement(filter
->usmap
.map
);
7196 filter
->usmap
.name
= NULL
;
7197 filter
->usmap
.map
= NULL
;
7200 /* Check if handling a regular peer. */
7201 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7202 /* Process peer route updates. */
7203 peer_on_policy_change(peer
, afi
, safi
, 1);
7205 /* Skip peer-group mechanics for regular peers. */
7210 * Remove configuration on all peer-group members, unless they are
7211 * explicitly overriding peer-group configuration.
7213 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7214 /* Skip peers with overridden configuration. */
7215 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
7216 PEER_FT_UNSUPPRESS_MAP
))
7219 /* Remove configuration on peer-group member. */
7220 filter
= &member
->filter
[afi
][safi
];
7221 if (filter
->usmap
.name
)
7222 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
7223 route_map_counter_decrement(filter
->usmap
.map
);
7224 filter
->usmap
.name
= NULL
;
7225 filter
->usmap
.map
= NULL
;
7227 /* Process peer route updates. */
7228 peer_on_policy_change(member
, afi
, safi
, 1);
7234 static void peer_advertise_map_filter_update(struct peer
*peer
, afi_t afi
,
7235 safi_t safi
, const char *amap_name
,
7236 struct route_map
*amap
,
7237 const char *cmap_name
,
7238 struct route_map
*cmap
,
7239 bool condition
, bool set
)
7241 struct bgp_filter
*filter
;
7242 bool filter_exists
= false;
7244 filter
= &peer
->filter
[afi
][safi
];
7246 /* advertise-map is already configured. */
7247 if (filter
->advmap
.aname
) {
7248 filter_exists
= true;
7249 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->advmap
.aname
);
7250 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->advmap
.cname
);
7253 route_map_counter_decrement(filter
->advmap
.amap
);
7255 /* Removed advertise-map configuration */
7257 memset(&filter
->advmap
, 0, sizeof(filter
->advmap
));
7259 /* decrement condition_filter_count delete timer if
7260 * this is the last advertise-map to be removed.
7263 bgp_conditional_adv_disable(peer
, afi
, safi
);
7265 /* Process peer route updates. */
7266 peer_on_policy_change(peer
, afi
, safi
, 1);
7271 /* Update filter data with newly configured values. */
7272 filter
->advmap
.aname
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, amap_name
);
7273 filter
->advmap
.cname
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, cmap_name
);
7274 filter
->advmap
.amap
= amap
;
7275 filter
->advmap
.cmap
= cmap
;
7276 filter
->advmap
.condition
= condition
;
7277 route_map_counter_increment(filter
->advmap
.amap
);
7278 peer
->advmap_config_change
[afi
][safi
] = true;
7280 /* Increment condition_filter_count and/or create timer. */
7281 if (!filter_exists
) {
7282 filter
->advmap
.update_type
= UPDATE_TYPE_ADVERTISE
;
7283 bgp_conditional_adv_enable(peer
, afi
, safi
);
7286 /* Process peer route updates. */
7287 peer_on_policy_change(peer
, afi
, safi
, 1);
7290 /* Set advertise-map to the peer. */
7291 int peer_advertise_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
7292 const char *advertise_name
,
7293 struct route_map
*advertise_map
,
7294 const char *condition_name
,
7295 struct route_map
*condition_map
, bool condition
)
7297 struct peer
*member
;
7298 struct listnode
*node
, *nnode
;
7300 /* Set configuration on peer. */
7301 peer_advertise_map_filter_update(peer
, afi
, safi
, advertise_name
,
7302 advertise_map
, condition_name
,
7303 condition_map
, condition
, true);
7305 /* Check if handling a regular peer & Skip peer-group mechanics. */
7306 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7307 /* Set override-flag and process peer route updates. */
7308 SET_FLAG(peer
->filter_override
[afi
][safi
][RMAP_OUT
],
7309 PEER_FT_ADVERTISE_MAP
);
7314 * Set configuration on all peer-group members, unless they are
7315 * explicitly overriding peer-group configuration.
7317 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7318 /* Skip peers with overridden configuration. */
7319 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][RMAP_OUT
],
7320 PEER_FT_ADVERTISE_MAP
))
7323 /* Set configuration on peer-group member. */
7324 peer_advertise_map_filter_update(
7325 member
, afi
, safi
, advertise_name
, advertise_map
,
7326 condition_name
, condition_map
, condition
, true);
7332 /* Unset advertise-map from the peer. */
7333 int peer_advertise_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
7334 const char *advertise_name
,
7335 struct route_map
*advertise_map
,
7336 const char *condition_name
,
7337 struct route_map
*condition_map
, bool condition
)
7339 struct peer
*member
;
7340 struct listnode
*node
, *nnode
;
7342 /* advertise-map is not configured */
7343 if (!peer
->filter
[afi
][safi
].advmap
.aname
)
7346 /* Unset override-flag unconditionally. */
7347 UNSET_FLAG(peer
->filter_override
[afi
][safi
][RMAP_OUT
],
7348 PEER_FT_ADVERTISE_MAP
);
7350 /* Inherit configuration from peer-group if peer is member. */
7351 if (peer_group_active(peer
)) {
7352 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
7353 filter
[afi
][safi
].advmap
.aname
,
7354 MTYPE_BGP_FILTER_NAME
);
7355 PEER_ATTR_INHERIT(peer
, peer
->group
,
7356 filter
[afi
][safi
].advmap
.amap
);
7358 peer_advertise_map_filter_update(
7359 peer
, afi
, safi
, advertise_name
, advertise_map
,
7360 condition_name
, condition_map
, condition
, false);
7362 /* Check if handling a regular peer and skip peer-group mechanics. */
7363 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7364 /* Process peer route updates. */
7365 if (BGP_DEBUG(update
, UPDATE_OUT
))
7366 zlog_debug("%s: Send normal update to %s for %s",
7367 __func__
, peer
->host
,
7368 get_afi_safi_str(afi
, safi
, false));
7374 * Remove configuration on all peer-group members, unless they are
7375 * explicitly overriding peer-group configuration.
7377 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7378 /* Skip peers with overridden configuration. */
7379 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][RMAP_OUT
],
7380 PEER_FT_ADVERTISE_MAP
))
7382 /* Remove configuration on peer-group member. */
7383 peer_advertise_map_filter_update(
7384 member
, afi
, safi
, advertise_name
, advertise_map
,
7385 condition_name
, condition_map
, condition
, false);
7387 /* Process peer route updates. */
7388 if (BGP_DEBUG(update
, UPDATE_OUT
))
7389 zlog_debug("%s: Send normal update to %s for %s ",
7390 __func__
, member
->host
,
7391 get_afi_safi_str(afi
, safi
, false));
7397 static bool peer_maximum_prefix_clear_overflow(struct peer
*peer
)
7399 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
))
7402 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
7403 if (peer
->t_pmax_restart
) {
7404 THREAD_OFF(peer
->t_pmax_restart
);
7405 if (bgp_debug_neighbor_events(peer
))
7407 "%pBP Maximum-prefix restart timer cancelled",
7410 BGP_EVENT_ADD(peer
, BGP_Start
);
7414 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
7415 uint32_t max
, uint8_t threshold
, int warning
,
7416 uint16_t restart
, bool force
)
7418 struct peer
*member
;
7419 struct listnode
*node
, *nnode
;
7421 /* Set flags and configuration on peer. */
7422 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
7425 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_FORCE
);
7427 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_FORCE
);
7430 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
7432 peer_af_flag_unset(peer
, afi
, safi
,
7433 PEER_FLAG_MAX_PREFIX_WARNING
);
7435 peer
->pmax
[afi
][safi
] = max
;
7436 peer
->pmax_threshold
[afi
][safi
] = threshold
;
7437 peer
->pmax_restart
[afi
][safi
] = restart
;
7439 /* Check if handling a regular peer. */
7440 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7441 /* Re-check if peer violates maximum-prefix. */
7442 if ((peer_established(peer
)) && (peer
->afc
[afi
][safi
]))
7443 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
7445 /* Skip peer-group mechanics for regular peers. */
7450 * Set flags and configuration on all peer-group members, unless they
7451 * are explicitly overriding peer-group configuration.
7453 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7454 /* Skip peers with overridden configuration. */
7455 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
7456 PEER_FLAG_MAX_PREFIX
))
7459 /* Set flag and configuration on peer-group member. */
7460 member
->pmax
[afi
][safi
] = max
;
7461 member
->pmax_threshold
[afi
][safi
] = threshold
;
7462 member
->pmax_restart
[afi
][safi
] = restart
;
7465 SET_FLAG(member
->af_flags
[afi
][safi
],
7466 PEER_FLAG_MAX_PREFIX_FORCE
);
7468 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7469 PEER_FLAG_MAX_PREFIX_FORCE
);
7472 SET_FLAG(member
->af_flags
[afi
][safi
],
7473 PEER_FLAG_MAX_PREFIX_WARNING
);
7475 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7476 PEER_FLAG_MAX_PREFIX_WARNING
);
7478 /* Re-check if peer violates maximum-prefix. */
7479 if ((peer_established(member
)) && (member
->afc
[afi
][safi
]))
7480 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
7486 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
7488 /* Inherit configuration from peer-group if peer is member. */
7489 if (peer_group_active(peer
)) {
7490 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
7491 peer_af_flag_inherit(peer
, afi
, safi
,
7492 PEER_FLAG_MAX_PREFIX_FORCE
);
7493 peer_af_flag_inherit(peer
, afi
, safi
,
7494 PEER_FLAG_MAX_PREFIX_WARNING
);
7495 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
7496 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
7497 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
7502 /* Remove flags and configuration from peer. */
7503 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
7504 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_FORCE
);
7505 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
7506 peer
->pmax
[afi
][safi
] = 0;
7507 peer
->pmax_threshold
[afi
][safi
] = 0;
7508 peer
->pmax_restart
[afi
][safi
] = 0;
7511 * Remove flags and configuration from all peer-group members, unless
7512 * they are explicitly overriding peer-group configuration.
7514 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7515 struct peer
*member
;
7516 struct listnode
*node
;
7518 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
7519 /* Skip peers with overridden configuration. */
7520 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
7521 PEER_FLAG_MAX_PREFIX
))
7524 /* Remove flag and configuration on peer-group member.
7526 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7527 PEER_FLAG_MAX_PREFIX
);
7528 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7529 PEER_FLAG_MAX_PREFIX_FORCE
);
7530 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7531 PEER_FLAG_MAX_PREFIX_WARNING
);
7532 member
->pmax
[afi
][safi
] = 0;
7533 member
->pmax_threshold
[afi
][safi
] = 0;
7534 member
->pmax_restart
[afi
][safi
] = 0;
7536 peer_maximum_prefix_clear_overflow(member
);
7539 peer_maximum_prefix_clear_overflow(peer
);
7545 void peer_maximum_prefix_out_refresh_routes(struct peer
*peer
, afi_t afi
,
7548 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
7550 if (peer_established(peer
))
7551 bgp_announce_route(peer
, afi
, safi
, false);
7554 int peer_maximum_prefix_out_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
7557 struct peer
*member
;
7558 struct listnode
*node
, *nnode
;
7560 /* Set flag on peer and peer-group member if any */
7561 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_OUT
);
7562 /* Set configuration on peer. */
7563 peer
->pmax_out
[afi
][safi
] = max
;
7565 /* Check if handling a regular peer. */
7566 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7567 /* Skip peer-group mechanics for regular peers. */
7568 peer_maximum_prefix_out_refresh_routes(peer
, afi
, safi
);
7573 * Set flag and configuration on all peer-group members, unless they
7574 * are explicitly overriding peer-group configuration.
7576 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
7577 /* Skip peers with overridden configuration. */
7578 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
7579 PEER_FLAG_MAX_PREFIX_OUT
))
7582 /* Set configuration on peer-group member. */
7583 member
->pmax_out
[afi
][safi
] = max
;
7585 peer_maximum_prefix_out_refresh_routes(member
, afi
, safi
);
7590 int peer_maximum_prefix_out_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
7592 struct peer
*member
;
7593 struct listnode
*node
;
7594 /* Inherit configuration from peer-group if peer is member. */
7595 if (peer_group_active(peer
)) {
7596 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_OUT
);
7597 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_out
[afi
][safi
]);
7599 peer_maximum_prefix_out_refresh_routes(peer
, afi
, safi
);
7603 /* Remove flag and configuration from peer. */
7604 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_OUT
);
7605 peer
->pmax_out
[afi
][safi
] = 0;
7607 /* Check if handling a regular peer. */
7608 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7609 /* Skip peer-group mechanics for regular peers. */
7610 peer_maximum_prefix_out_refresh_routes(peer
, afi
, safi
);
7615 * Remove flag and configuration from all peer-group members, unless
7616 * they are explicitly overriding peer-group configuration.
7618 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
7619 /* Skip peers with overridden configuration. */
7620 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
7621 PEER_FLAG_MAX_PREFIX_OUT
))
7624 /* Remove flag and configuration on peer-group member.
7626 UNSET_FLAG(member
->af_flags
[afi
][safi
],
7627 PEER_FLAG_MAX_PREFIX_OUT
);
7628 member
->pmax_out
[afi
][safi
] = 0;
7630 peer_maximum_prefix_out_refresh_routes(member
, afi
, safi
);
7635 int is_ebgp_multihop_configured(struct peer
*peer
)
7637 struct peer_group
*group
;
7638 struct listnode
*node
, *nnode
;
7641 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7642 group
= peer
->group
;
7643 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
7644 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
7647 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
7648 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
7649 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
7653 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
7654 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
7660 /* Set # of hops between us and BGP peer. */
7661 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
7663 struct peer_group
*group
;
7665 struct listnode
*node
, *nnode
;
7668 zlog_debug("%s: set gtsm_hops to %d for %s", __func__
, gtsm_hops
,
7671 /* We cannot configure ttl-security hops when ebgp-multihop is already
7672 set. For non peer-groups, the check is simple. For peer-groups,
7674 slightly messy, because we need to check both the peer-group
7676 and all peer-group members for any trace of ebgp-multihop
7678 before actually applying the ttl-security rules. Cisco really made a
7679 mess of this configuration parameter, and OpenBGPD got it right.
7682 if ((peer
->gtsm_hops
== BGP_GTSM_HOPS_DISABLED
)
7683 && (peer
->sort
!= BGP_PEER_IBGP
)) {
7684 if (is_ebgp_multihop_configured(peer
))
7685 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
7687 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7688 peer
->gtsm_hops
= gtsm_hops
;
7690 /* Calling ebgp multihop also resets the session.
7691 * On restart, NHT will get setup correctly as will the
7692 * min & max ttls on the socket. The return value is
7695 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
7700 group
= peer
->group
;
7701 group
->conf
->gtsm_hops
= gtsm_hops
;
7702 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
7704 gpeer
->gtsm_hops
= group
->conf
->gtsm_hops
;
7706 /* Calling ebgp multihop also resets the
7708 * On restart, NHT will get setup correctly as
7710 * min & max ttls on the socket. The return
7714 peer_ebgp_multihop_set(gpeer
, MAXTTL
);
7718 /* Post the first gtsm setup or if its ibgp, maxttl setting
7720 * necessary, just set the minttl.
7722 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7723 peer
->gtsm_hops
= gtsm_hops
;
7726 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
7727 MAXTTL
+ 1 - gtsm_hops
);
7728 if ((peer
->status
< Established
) && peer
->doppelganger
7729 && (peer
->doppelganger
->fd
>= 0))
7730 sockopt_minttl(peer
->su
.sa
.sa_family
,
7731 peer
->doppelganger
->fd
,
7732 MAXTTL
+ 1 - gtsm_hops
);
7734 group
= peer
->group
;
7735 group
->conf
->gtsm_hops
= gtsm_hops
;
7736 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
7738 gpeer
->gtsm_hops
= group
->conf
->gtsm_hops
;
7740 /* Change setting of existing peer
7741 * established then change value (may break
7743 * not established yet (teardown session and
7745 * no session then do nothing (will get
7746 * handled by next connection)
7750 != BGP_GTSM_HOPS_DISABLED
)
7752 gpeer
->su
.sa
.sa_family
,
7754 MAXTTL
+ 1 - gpeer
->gtsm_hops
);
7755 if ((gpeer
->status
< Established
)
7756 && gpeer
->doppelganger
7757 && (gpeer
->doppelganger
->fd
>= 0))
7758 sockopt_minttl(gpeer
->su
.sa
.sa_family
,
7759 gpeer
->doppelganger
->fd
,
7760 MAXTTL
+ 1 - gtsm_hops
);
7768 int peer_ttl_security_hops_unset(struct peer
*peer
)
7770 struct peer_group
*group
;
7771 struct listnode
*node
, *nnode
;
7774 zlog_debug("%s: set gtsm_hops to zero for %s", __func__
, peer
->host
);
7776 /* if a peer-group member, then reset to peer-group default rather than
7778 if (peer_group_active(peer
))
7779 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
7781 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
7783 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7784 /* Invoking ebgp_multihop_set will set the TTL back to the
7786 * value as well as restting the NHT and such. The session is
7789 if (peer
->sort
== BGP_PEER_EBGP
)
7790 ret
= peer_ebgp_multihop_unset(peer
);
7793 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
7796 if ((peer
->status
< Established
) && peer
->doppelganger
7797 && (peer
->doppelganger
->fd
>= 0))
7798 sockopt_minttl(peer
->su
.sa
.sa_family
,
7799 peer
->doppelganger
->fd
, 0);
7802 group
= peer
->group
;
7803 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
7804 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
7805 if (peer
->sort
== BGP_PEER_EBGP
)
7806 ret
= peer_ebgp_multihop_unset(peer
);
7809 sockopt_minttl(peer
->su
.sa
.sa_family
,
7812 if ((peer
->status
< Established
)
7813 && peer
->doppelganger
7814 && (peer
->doppelganger
->fd
>= 0))
7815 sockopt_minttl(peer
->su
.sa
.sa_family
,
7816 peer
->doppelganger
->fd
,
7825 static void peer_reset_message_stats(struct peer
*peer
)
7828 atomic_store_explicit(&peer
->open_in
, 0, memory_order_relaxed
);
7829 atomic_store_explicit(&peer
->open_out
, 0, memory_order_relaxed
);
7830 atomic_store_explicit(&peer
->update_in
, 0,
7831 memory_order_relaxed
);
7832 atomic_store_explicit(&peer
->update_out
, 0,
7833 memory_order_relaxed
);
7834 atomic_store_explicit(&peer
->keepalive_in
, 0,
7835 memory_order_relaxed
);
7836 atomic_store_explicit(&peer
->keepalive_out
, 0,
7837 memory_order_relaxed
);
7838 atomic_store_explicit(&peer
->notify_in
, 0,
7839 memory_order_relaxed
);
7840 atomic_store_explicit(&peer
->notify_out
, 0,
7841 memory_order_relaxed
);
7842 atomic_store_explicit(&peer
->refresh_in
, 0,
7843 memory_order_relaxed
);
7844 atomic_store_explicit(&peer
->refresh_out
, 0,
7845 memory_order_relaxed
);
7846 atomic_store_explicit(&peer
->dynamic_cap_in
, 0,
7847 memory_order_relaxed
);
7848 atomic_store_explicit(&peer
->dynamic_cap_out
, 0,
7849 memory_order_relaxed
);
7854 * If peer clear is invoked in a loop for all peers on the BGP instance,
7855 * it may end up freeing the doppelganger, and if this was the next node
7856 * to the current node, we would end up accessing the freed next node.
7857 * Pass along additional parameter which can be updated if next node
7858 * is freed; only required when walking the peer list on BGP instance.
7860 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
7862 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)
7863 || !CHECK_FLAG(peer
->bgp
->flags
, BGP_FLAG_SHUTDOWN
)) {
7864 if (peer_maximum_prefix_clear_overflow(peer
))
7867 peer
->v_start
= BGP_INIT_START_TIMER
;
7868 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
7869 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7870 BGP_NOTIFY_CEASE_ADMIN_RESET
);
7872 bgp_session_reset_safe(peer
, nnode
);
7877 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
7878 enum bgp_clear_type stype
)
7880 struct peer_af
*paf
;
7882 if (!peer_established(peer
))
7885 if (!peer
->afc
[afi
][safi
])
7886 return BGP_ERR_AF_UNCONFIGURED
;
7888 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
7890 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
7891 /* Clear the "neighbor x.x.x.x default-originate" flag */
7892 paf
= peer_af_find(peer
, afi
, safi
);
7893 if (paf
&& paf
->subgroup
7894 && CHECK_FLAG(paf
->subgroup
->sflags
,
7895 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
7896 UNSET_FLAG(paf
->subgroup
->sflags
,
7897 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
7899 bgp_announce_route(peer
, afi
, safi
, false);
7902 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
7903 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
7904 PEER_CAP_ORF_PREFIX_SM_ADV
)
7905 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
7906 PEER_CAP_ORF_PREFIX_RM_RCV
)
7907 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
7908 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
7909 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
7910 uint8_t prefix_type
;
7912 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
7913 PEER_CAP_ORF_PREFIX_RM_RCV
))
7914 prefix_type
= ORF_TYPE_PREFIX
;
7916 prefix_type
= ORF_TYPE_PREFIX_OLD
;
7918 if (filter
->plist
[FILTER_IN
].plist
) {
7919 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
7920 PEER_STATUS_ORF_PREFIX_SEND
))
7921 bgp_route_refresh_send(
7922 peer
, afi
, safi
, prefix_type
,
7924 BGP_ROUTE_REFRESH_NORMAL
);
7925 bgp_route_refresh_send(
7926 peer
, afi
, safi
, prefix_type
,
7927 REFRESH_IMMEDIATE
, 0,
7928 BGP_ROUTE_REFRESH_NORMAL
);
7930 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
7931 PEER_STATUS_ORF_PREFIX_SEND
))
7932 bgp_route_refresh_send(
7933 peer
, afi
, safi
, prefix_type
,
7934 REFRESH_IMMEDIATE
, 1,
7935 BGP_ROUTE_REFRESH_NORMAL
);
7937 bgp_route_refresh_send(
7938 peer
, afi
, safi
, 0, 0, 0,
7939 BGP_ROUTE_REFRESH_NORMAL
);
7945 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
7946 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
7947 /* If neighbor has soft reconfiguration inbound flag.
7948 Use Adj-RIB-In database. */
7949 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7950 PEER_FLAG_SOFT_RECONFIG
))
7951 bgp_soft_reconfig_in(peer
, afi
, safi
);
7953 /* If neighbor has route refresh capability, send route
7955 message to the peer. */
7956 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
7957 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
7958 bgp_route_refresh_send(
7959 peer
, afi
, safi
, 0, 0, 0,
7960 BGP_ROUTE_REFRESH_NORMAL
);
7962 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
7966 if (stype
== BGP_CLEAR_MESSAGE_STATS
)
7967 peer_reset_message_stats(peer
);
7972 /* Display peer uptime.*/
7973 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
7976 time_t uptime1
, epoch_tbuf
;
7979 /* If there is no connection has been done before print `never'. */
7982 json_object_string_add(json
, "peerUptime", "never");
7983 json_object_int_add(json
, "peerUptimeMsec", 0);
7985 snprintf(buf
, len
, "never");
7989 /* Get current time. */
7990 uptime1
= monotime(NULL
);
7992 gmtime_r(&uptime1
, &tm
);
7994 if (uptime1
< ONE_DAY_SECOND
)
7995 snprintf(buf
, len
, "%02d:%02d:%02d", tm
.tm_hour
, tm
.tm_min
,
7997 else if (uptime1
< ONE_WEEK_SECOND
)
7998 snprintf(buf
, len
, "%dd%02dh%02dm", tm
.tm_yday
, tm
.tm_hour
,
8000 else if (uptime1
< ONE_YEAR_SECOND
)
8001 snprintf(buf
, len
, "%02dw%dd%02dh", tm
.tm_yday
/ 7,
8002 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7), tm
.tm_hour
);
8004 snprintf(buf
, len
, "%02dy%02dw%dd", tm
.tm_year
- 70,
8006 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7));
8009 epoch_tbuf
= time(NULL
) - uptime1
;
8010 json_object_string_add(json
, "peerUptime", buf
);
8011 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
8012 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
8019 void bgp_master_init(struct thread_master
*master
, const int buffer_size
,
8020 struct list
*addresses
)
8024 memset(&bgp_master
, 0, sizeof(bgp_master
));
8027 bm
->bgp
= list_new();
8028 bm
->listen_sockets
= list_new();
8029 bm
->port
= BGP_PORT_DEFAULT
;
8030 bm
->addresses
= addresses
;
8031 bm
->master
= master
;
8032 bm
->start_time
= monotime(NULL
);
8033 bm
->t_rmap_update
= NULL
;
8034 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
8035 bm
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
8036 bm
->v_establish_wait
= BGP_UPDATE_DELAY_DEF
;
8037 bm
->terminating
= false;
8038 bm
->socket_buffer
= buffer_size
;
8039 bm
->wait_for_fib
= false;
8040 bm
->tcp_dscp
= IPTOS_PREC_INTERNETCONTROL
;
8043 /* init the rd id space.
8044 assign 0th index in the bitfield,
8045 so that we start with id 1
8047 bf_init(bm
->rd_idspace
, UINT16_MAX
);
8048 bf_assign_zero_index(bm
->rd_idspace
);
8050 /* mpls label dynamic allocation pool */
8051 bgp_lp_init(bm
->master
, &bm
->labelpool
);
8055 QOBJ_REG(bm
, bgp_master
);
8059 * Free up connected routes and interfaces for a BGP instance. Invoked upon
8060 * instance delete (non-default only) or BGP exit.
8062 static void bgp_if_finish(struct bgp
*bgp
)
8065 struct interface
*ifp
;
8067 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
8069 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
8072 FOR_ALL_INTERFACES (vrf
, ifp
) {
8073 struct listnode
*c_node
, *c_nnode
;
8074 struct connected
*c
;
8076 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
8077 bgp_connected_delete(bgp
, c
);
8081 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
8083 struct vrf
*vrf
= NULL
;
8084 struct listnode
*next
;
8087 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
8088 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
8090 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
8091 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
8094 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
8098 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
8100 struct listnode
*next
, *next2
;
8101 struct bgp
*bgp
, *bgp2
;
8104 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
8106 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
8107 if (bgp2
->as
== bgp
->as
)
8115 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
8116 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
8120 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
8121 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
8122 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
8123 {.completions
= NULL
},
8126 struct frr_pthread
*bgp_pth_io
;
8127 struct frr_pthread
*bgp_pth_ka
;
8129 static void bgp_pthreads_init(void)
8131 assert(!bgp_pth_io
);
8132 assert(!bgp_pth_ka
);
8134 struct frr_pthread_attr io
= {
8135 .start
= frr_pthread_attr_default
.start
,
8136 .stop
= frr_pthread_attr_default
.stop
,
8138 struct frr_pthread_attr ka
= {
8139 .start
= bgp_keepalives_start
,
8140 .stop
= bgp_keepalives_stop
,
8142 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
8143 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
8146 void bgp_pthreads_run(void)
8148 frr_pthread_run(bgp_pth_io
, NULL
);
8149 frr_pthread_run(bgp_pth_ka
, NULL
);
8151 /* Wait until threads are ready. */
8152 frr_pthread_wait_running(bgp_pth_io
);
8153 frr_pthread_wait_running(bgp_pth_ka
);
8156 void bgp_pthreads_finish(void)
8158 frr_pthread_stop_all();
8161 static int peer_unshut_after_cfg(struct bgp
*bgp
)
8163 struct listnode
*node
;
8166 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
8167 if (!peer
->shut_during_cfg
)
8170 if (bgp_debug_neighbor_events(peer
))
8171 zlog_debug("%s: released from config-pending hold",
8174 peer
->shut_during_cfg
= false;
8175 if (peer_active(peer
) && peer
->status
!= Established
) {
8176 if (peer
->status
!= Idle
)
8177 BGP_EVENT_ADD(peer
, BGP_Stop
);
8178 BGP_EVENT_ADD(peer
, BGP_Start
);
8185 void bgp_init(unsigned short instance
)
8187 hook_register(bgp_config_end
, peer_unshut_after_cfg
);
8189 /* allocates some vital data structures used by peer commands in
8192 /* pre-init pthreads */
8193 bgp_pthreads_init();
8196 bgp_zebra_init(bm
->master
, instance
);
8198 #ifdef ENABLE_BGP_VNC
8199 vnc_zebra_init(bm
->master
);
8202 /* BGP VTY commands installation. */
8208 bgp_community_alias_init();
8211 bgp_route_map_init();
8212 bgp_scan_vty_init();
8214 #ifdef ENABLE_BGP_VNC
8217 bgp_ethernetvpn_init();
8218 bgp_flowspec_vty_init();
8220 /* Access list initialize. */
8222 access_list_add_hook(peer_distribute_update
);
8223 access_list_delete_hook(peer_distribute_update
);
8225 /* Filter list initialize. */
8227 as_list_add_hook(peer_aslist_add
);
8228 as_list_delete_hook(peer_aslist_del
);
8230 /* Prefix list initialize.*/
8232 prefix_list_add_hook(peer_prefix_list_update
);
8233 prefix_list_delete_hook(peer_prefix_list_update
);
8235 /* Community list initialize. */
8236 bgp_clist
= community_list_init();
8239 bgp_bfd_init(bm
->master
);
8243 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
8246 void bgp_terminate(void)
8250 struct listnode
*node
, *nnode
;
8251 struct listnode
*mnode
, *mnnode
;
8255 /* Close the listener sockets first as this prevents peers from
8257 * to reconnect on receiving the peer unconfig message. In the presence
8258 * of a large number of peers this will ensure that no peer is left with
8259 * a dangling connection
8263 /* reverse bgp_master_init */
8264 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
8265 bgp_close_vrf_socket(bgp
);
8266 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8267 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
)) {
8268 if (bgp_debug_neighbor_events(peer
))
8270 "%pBP configured Graceful-Restart, skipping unconfig notification",
8274 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
8275 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
8276 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
8280 if (bm
->listen_sockets
)
8281 list_delete(&bm
->listen_sockets
);
8283 THREAD_OFF(bm
->t_rmap_update
);
8288 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
8289 const char *ip_str
, bool use_json
)
8295 /* Get peer sockunion. */
8296 ret
= str2sockunion(ip_str
, &su
);
8298 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
8300 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8304 json_object
*json_no
= NULL
;
8305 json_no
= json_object_new_object();
8306 json_object_string_add(
8308 "malformedAddressOrName",
8310 vty_json(vty
, json_no
);
8313 "%% Malformed address or name: %s\n",
8321 /* Peer structure lookup. */
8322 peer
= peer_lookup(bgp
, &su
);
8325 json_object
*json_no
= NULL
;
8326 json_no
= json_object_new_object();
8327 json_object_string_add(json_no
, "warning",
8328 "No such neighbor in this view/vrf");
8329 vty_json(vty
, json_no
);
8331 vty_out(vty
, "No such neighbor in this view/vrf\n");
8338 void bgp_gr_apply_running_config(void)
8340 struct peer
*peer
= NULL
;
8341 struct bgp
*bgp
= NULL
;
8342 struct listnode
*node
, *nnode
;
8343 bool gr_router_detected
= false;
8345 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
8346 zlog_debug("[BGP_GR] %s called !", __func__
);
8348 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8349 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8350 bgp_peer_gr_flags_update(peer
);
8351 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
))
8352 gr_router_detected
= true;
8355 if (gr_router_detected
8356 && bgp
->present_zebra_gr_state
== ZEBRA_GR_DISABLE
) {
8357 bgp_zebra_send_capabilities(bgp
, true);
8358 } else if (!gr_router_detected
8359 && bgp
->present_zebra_gr_state
== ZEBRA_GR_ENABLE
) {
8360 bgp_zebra_send_capabilities(bgp
, false);
8363 gr_router_detected
= false;
8367 printfrr_ext_autoreg_p("BP", printfrr_bp
);
8368 static ssize_t
printfrr_bp(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
8371 const struct peer
*peer
= ptr
;
8374 return bputs(buf
, "(null)");
8376 return bprintfrr(buf
, "%s(%s)", peer
->host
,
8377 peer
->hostname
? peer
->hostname
: "Unknown");