1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
90 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
91 DEFINE_QOBJ_TYPE(bgp_master
)
93 DEFINE_QOBJ_TYPE(peer
)
95 /* BGP process wide configuration. */
96 static struct bgp_master bgp_master
;
98 /* BGP process wide configuration pointer to export. */
99 struct bgp_master
*bm
;
101 /* BGP community-list. */
102 struct community_list_handler
*bgp_clist
;
104 unsigned int multipath_num
= MULTIPATH_NUM
;
106 static void bgp_if_finish(struct bgp
*bgp
);
107 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
109 extern struct zclient
*zclient
;
111 /* handle main socket creation or deletion */
112 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
114 static int bgp_server_main_created
;
116 if (create
== true) {
117 if (bgp_server_main_created
)
119 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
120 return BGP_ERR_INVALID_VALUE
;
121 bgp_server_main_created
= 1;
124 if (!bgp_server_main_created
)
127 bgp_server_main_created
= 0;
131 void bgp_session_reset(struct peer
*peer
)
133 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
134 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
135 peer_delete(peer
->doppelganger
);
137 BGP_EVENT_ADD(peer
, BGP_Stop
);
141 * During session reset, we may delete the doppelganger peer, which would
142 * be the next node to the current node. If the session reset was invoked
143 * during walk of peer list, we would end up accessing the freed next
144 * node. This function moves the next node along.
146 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
151 n
= (nnode
) ? *nnode
: NULL
;
152 npeer
= (n
) ? listgetdata(n
) : NULL
;
154 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
155 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
156 PEER_FLAG_CONFIG_NODE
))) {
157 if (peer
->doppelganger
== npeer
)
158 /* nnode and *nnode are confirmed to be non-NULL here */
159 *nnode
= (*nnode
)->next
;
160 peer_delete(peer
->doppelganger
);
163 BGP_EVENT_ADD(peer
, BGP_Stop
);
166 /* BGP global flag manipulation. */
167 int bgp_option_set(int flag
)
171 case BGP_OPT_MULTIPLE_INSTANCE
:
172 case BGP_OPT_CONFIG_CISCO
:
173 case BGP_OPT_NO_LISTEN
:
174 case BGP_OPT_NO_ZEBRA
:
175 SET_FLAG(bm
->options
, flag
);
178 return BGP_ERR_INVALID_FLAG
;
183 int bgp_option_unset(int flag
)
186 case BGP_OPT_MULTIPLE_INSTANCE
:
187 if (listcount(bm
->bgp
) > 1)
188 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
190 case BGP_OPT_NO_ZEBRA
:
192 case BGP_OPT_CONFIG_CISCO
:
193 UNSET_FLAG(bm
->options
, flag
);
196 return BGP_ERR_INVALID_FLAG
;
201 int bgp_option_check(int flag
)
203 return CHECK_FLAG(bm
->options
, flag
);
206 /* BGP flag manipulation. */
207 int bgp_flag_set(struct bgp
*bgp
, int flag
)
209 SET_FLAG(bgp
->flags
, flag
);
213 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
215 UNSET_FLAG(bgp
->flags
, flag
);
219 int bgp_flag_check(struct bgp
*bgp
, int flag
)
221 return CHECK_FLAG(bgp
->flags
, flag
);
224 /* Internal function to set BGP structure configureation flag. */
225 static void bgp_config_set(struct bgp
*bgp
, int config
)
227 SET_FLAG(bgp
->config
, config
);
230 static void bgp_config_unset(struct bgp
*bgp
, int config
)
232 UNSET_FLAG(bgp
->config
, config
);
235 static int bgp_config_check(struct bgp
*bgp
, int config
)
237 return CHECK_FLAG(bgp
->config
, config
);
240 /* Set BGP router identifier. */
241 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
244 struct listnode
*node
, *nnode
;
246 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
249 /* EVPN uses router id in RD, withdraw them */
250 if (is_evpn_enabled())
251 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
253 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
255 /* Set all peer's local identifier with this value. */
256 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
257 IPV4_ADDR_COPY(&peer
->local_id
, id
);
259 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
260 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
261 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
262 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
266 /* EVPN uses router id in RD, update them */
267 if (is_evpn_enabled())
268 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
273 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
275 struct listnode
*node
, *nnode
;
278 if (vrf_id
== VRF_DEFAULT
) {
279 /* Router-id change for default VRF has to also update all
281 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
282 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
285 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
286 if (!bgp
->router_id_static
.s_addr
)
287 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
290 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
292 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
294 if (!bgp
->router_id_static
.s_addr
)
295 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
300 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
302 bgp
->router_id_static
= id
;
303 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
307 /* BGP's cluster-id control. */
308 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
311 struct listnode
*node
, *nnode
;
313 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
314 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
317 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
318 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
320 /* Clear all IBGP peer. */
321 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
322 if (peer
->sort
!= BGP_PEER_IBGP
)
325 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
326 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
327 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
328 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
334 int bgp_cluster_id_unset(struct bgp
*bgp
)
337 struct listnode
*node
, *nnode
;
339 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
342 bgp
->cluster_id
.s_addr
= 0;
343 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
345 /* Clear all IBGP peer. */
346 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
347 if (peer
->sort
!= BGP_PEER_IBGP
)
350 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
351 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
352 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
353 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
359 /* time_t value that is monotonicly increasing
360 * and uneffected by adjustments to system clock
362 time_t bgp_clock(void)
370 /* BGP timer configuration. */
371 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
373 bgp
->default_keepalive
=
374 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
375 bgp
->default_holdtime
= holdtime
;
380 int bgp_timers_unset(struct bgp
*bgp
)
382 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
383 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
388 /* BGP confederation configuration. */
389 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
392 struct listnode
*node
, *nnode
;
396 return BGP_ERR_INVALID_AS
;
398 /* Remember - were we doing confederation before? */
399 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
401 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
403 /* If we were doing confederation already, this is just an external
404 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
405 were not doing confederation before, reset all EBGP sessions. */
406 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
407 /* We're looking for peers who's AS is not local or part of our
409 if (already_confed
) {
410 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
412 if (BGP_IS_VALID_STATE_FOR_NOTIF(
415 PEER_DOWN_CONFED_ID_CHANGE
;
417 peer
, BGP_NOTIFY_CEASE
,
418 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
420 bgp_session_reset_safe(peer
, &nnode
);
423 /* Not doign confederation before, so reset every
426 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
427 /* Reset the local_as to be our EBGP one */
428 if (peer_sort(peer
) == BGP_PEER_EBGP
)
430 if (BGP_IS_VALID_STATE_FOR_NOTIF(
433 PEER_DOWN_CONFED_ID_CHANGE
;
435 peer
, BGP_NOTIFY_CEASE
,
436 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
438 bgp_session_reset_safe(peer
, &nnode
);
445 int bgp_confederation_id_unset(struct bgp
*bgp
)
448 struct listnode
*node
, *nnode
;
451 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
453 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
454 /* We're looking for peers who's AS is not local */
455 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
456 peer
->local_as
= bgp
->as
;
457 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
458 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
459 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
460 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
464 bgp_session_reset_safe(peer
, &nnode
);
470 /* Is an AS part of the confed or not? */
471 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
478 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
479 if (bgp
->confed_peers
[i
] == as
)
485 /* Add an AS to the confederation set. */
486 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
489 struct listnode
*node
, *nnode
;
492 return BGP_ERR_INVALID_BGP
;
495 return BGP_ERR_INVALID_AS
;
497 if (bgp_confederation_peers_check(bgp
, as
))
500 if (bgp
->confed_peers
)
502 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
503 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
506 XMALLOC(MTYPE_BGP_CONFED_LIST
,
507 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
509 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
510 bgp
->confed_peers_cnt
++;
512 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
513 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
514 if (peer
->as
== as
) {
515 peer
->local_as
= bgp
->as
;
516 if (BGP_IS_VALID_STATE_FOR_NOTIF(
519 PEER_DOWN_CONFED_PEER_CHANGE
;
521 peer
, BGP_NOTIFY_CEASE
,
522 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
524 bgp_session_reset_safe(peer
, &nnode
);
531 /* Delete an AS from the confederation set. */
532 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
537 struct listnode
*node
, *nnode
;
542 if (!bgp_confederation_peers_check(bgp
, as
))
545 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
546 if (bgp
->confed_peers
[i
] == as
)
547 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
548 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
550 bgp
->confed_peers_cnt
--;
552 if (bgp
->confed_peers_cnt
== 0) {
553 if (bgp
->confed_peers
)
554 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
555 bgp
->confed_peers
= NULL
;
558 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
559 bgp
->confed_peers_cnt
* sizeof(as_t
));
561 /* Now reset any peer who's remote AS has just been removed from the
563 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
564 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
565 if (peer
->as
== as
) {
566 peer
->local_as
= bgp
->confed_id
;
567 if (BGP_IS_VALID_STATE_FOR_NOTIF(
570 PEER_DOWN_CONFED_PEER_CHANGE
;
572 peer
, BGP_NOTIFY_CEASE
,
573 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
575 bgp_session_reset_safe(peer
, &nnode
);
583 /* Local preference configuration. */
584 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
589 bgp
->default_local_pref
= local_pref
;
594 int bgp_default_local_preference_unset(struct bgp
*bgp
)
599 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
604 /* Local preference configuration. */
605 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
610 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
615 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
619 bgp
->default_subgroup_pkt_queue_max
=
620 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
625 /* Listen limit configuration. */
626 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
631 bgp
->dynamic_neighbors_limit
= listen_limit
;
636 int bgp_listen_limit_unset(struct bgp
*bgp
)
641 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
646 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
647 afi_t
*afi
, safi_t
*safi
)
649 /* Map from IANA values to internal values, return error if
650 * values are unrecognized.
652 *afi
= afi_iana2int(pkt_afi
);
653 *safi
= safi_iana2int(pkt_safi
);
654 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
660 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
661 iana_safi_t
*pkt_safi
)
663 /* Map from internal values to IANA values, return error if
664 * internal values are bad (unexpected).
666 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
668 *pkt_afi
= afi_int2iana(afi
);
669 *pkt_safi
= safi_int2iana(safi
);
673 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
681 afid
= afindex(afi
, safi
);
682 if (afid
>= BGP_AF_MAX
)
685 assert(peer
->peer_af_array
[afid
] == NULL
);
687 /* Allocate new peer af */
688 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
690 peer
->peer_af_array
[afid
] = af
;
699 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
706 afid
= afindex(afi
, safi
);
707 if (afid
>= BGP_AF_MAX
)
710 return peer
->peer_af_array
[afid
];
713 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
721 afid
= afindex(afi
, safi
);
722 if (afid
>= BGP_AF_MAX
)
725 af
= peer
->peer_af_array
[afid
];
729 bgp_stop_announce_route_timer(af
);
731 if (PAF_SUBGRP(af
)) {
732 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
733 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
734 af
->subgroup
->update_group
->id
,
735 af
->subgroup
->id
, peer
->host
);
738 update_subgroup_remove_peer(af
->subgroup
, af
);
740 peer
->peer_af_array
[afid
] = NULL
;
741 XFREE(MTYPE_BGP_PEER_AF
, af
);
745 /* Peer comparison function for sorting. */
746 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
748 if (p1
->group
&& !p2
->group
)
751 if (!p1
->group
&& p2
->group
)
754 if (p1
->group
== p2
->group
) {
755 if (p1
->conf_if
&& !p2
->conf_if
)
758 if (!p1
->conf_if
&& p2
->conf_if
)
761 if (p1
->conf_if
&& p2
->conf_if
)
762 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
764 return strcmp(p1
->group
->name
, p2
->group
->name
);
766 return sockunion_cmp(&p1
->su
, &p2
->su
);
769 static unsigned int peer_hash_key_make(void *p
)
771 struct peer
*peer
= p
;
772 return sockunion_hash(&peer
->su
);
775 static bool peer_hash_same(const void *p1
, const void *p2
)
777 const struct peer
*peer1
= p1
;
778 const struct peer
*peer2
= p2
;
779 return (sockunion_same(&peer1
->su
, &peer2
->su
)
780 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
781 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
784 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
788 /* Skip if peer is not a peer-group member. */
789 if (!peer_group_active(peer
))
792 /* Unset override flag to signal inheritance from peer-group. */
793 UNSET_FLAG(peer
->flags_override
, flag
);
796 * Inherit flag state from peer-group. If the flag of the peer-group is
797 * not being inverted, the peer must inherit the inverse of the current
798 * peer-group flag state.
800 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
801 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
802 && CHECK_FLAG(peer
->flags_invert
, flag
))
803 COND_FLAG(peer
->flags
, flag
, !group_val
);
805 COND_FLAG(peer
->flags
, flag
, group_val
);
808 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
810 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
813 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
818 /* Skip if peer is not a peer-group member. */
819 if (!peer_group_active(peer
))
822 /* Unset override flag to signal inheritance from peer-group. */
823 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
826 * Inherit flag state from peer-group. If the flag of the peer-group is
827 * not being inverted, the peer must inherit the inverse of the current
828 * peer-group flag state.
830 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
831 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
832 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
833 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
835 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
838 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
840 if (!peer_group_active(peer
)) {
841 if (CHECK_FLAG(peer
->flags_invert
, flag
))
842 return !CHECK_FLAG(peer
->flags
, flag
);
844 return !!CHECK_FLAG(peer
->flags
, flag
);
847 return !!CHECK_FLAG(peer
->flags_override
, flag
);
850 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
853 if (!peer_group_active(peer
)) {
854 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
855 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
857 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
860 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
863 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
864 uint8_t type
, int direct
)
866 struct bgp_filter
*filter
;
868 if (peer_group_active(peer
))
869 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
872 filter
= &peer
->filter
[afi
][safi
];
874 case PEER_FT_DISTRIBUTE_LIST
:
875 return !!(filter
->dlist
[direct
].name
);
876 case PEER_FT_FILTER_LIST
:
877 return !!(filter
->aslist
[direct
].name
);
878 case PEER_FT_PREFIX_LIST
:
879 return !!(filter
->plist
[direct
].name
);
880 case PEER_FT_ROUTE_MAP
:
881 return !!(filter
->map
[direct
].name
);
882 case PEER_FT_UNSUPPRESS_MAP
:
883 return !!(filter
->usmap
.name
);
889 /* Return true if the addpath type is set for peer and different from
892 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
894 enum bgp_addpath_strat type
, g_type
;
896 type
= peer
->addpath_type
[afi
][safi
];
898 if (type
!= BGP_ADDPATH_NONE
) {
899 if (peer_group_active(peer
)) {
900 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
914 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
915 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
922 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
923 if (peer
->as_type
== AS_INTERNAL
)
924 return BGP_PEER_IBGP
;
926 else if (peer
->as_type
== AS_EXTERNAL
)
927 return BGP_PEER_EBGP
;
929 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
931 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
939 peer1
= listnode_head(peer
->group
->peer
);
944 return BGP_PEER_INTERNAL
;
948 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
949 if (peer
->local_as
== 0)
950 return BGP_PEER_INTERNAL
;
952 if (peer
->local_as
== peer
->as
) {
953 if (bgp
->as
== bgp
->confed_id
) {
954 if (peer
->local_as
== bgp
->as
)
955 return BGP_PEER_IBGP
;
957 return BGP_PEER_EBGP
;
959 if (peer
->local_as
== bgp
->confed_id
)
960 return BGP_PEER_EBGP
;
962 return BGP_PEER_IBGP
;
966 if (bgp_confederation_peers_check(bgp
, peer
->as
))
967 return BGP_PEER_CONFED
;
969 return BGP_PEER_EBGP
;
971 if (peer
->as_type
!= AS_SPECIFIED
)
972 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
975 return (peer
->local_as
== 0
977 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
982 /* Calculate and cache the peer "sort" */
983 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
985 peer
->sort
= peer_calc_sort(peer
);
989 static void peer_free(struct peer
*peer
)
994 assert(peer
->status
== Deleted
);
998 /* this /ought/ to have been done already through bgp_stop earlier,
999 * but just to be sure..
1001 bgp_timer_set(peer
);
1002 bgp_reads_off(peer
);
1003 bgp_writes_off(peer
);
1004 assert(!peer
->t_write
);
1005 assert(!peer
->t_read
);
1006 BGP_EVENT_FLUSH(peer
);
1008 pthread_mutex_destroy(&peer
->io_mtx
);
1010 /* Free connected nexthop, if present */
1011 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1012 && !peer_dynamic_neighbor(peer
))
1013 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1016 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1019 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1023 /* Free allocated host character. */
1025 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1029 if (peer
->domainname
) {
1030 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1031 peer
->domainname
= NULL
;
1035 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1036 peer
->ifname
= NULL
;
1039 /* Update source configuration. */
1040 if (peer
->update_source
) {
1041 sockunion_free(peer
->update_source
);
1042 peer
->update_source
= NULL
;
1045 if (peer
->update_if
) {
1046 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1047 peer
->update_if
= NULL
;
1050 if (peer
->notify
.data
)
1051 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1052 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1054 if (peer
->clear_node_queue
)
1055 work_queue_free_and_null(&peer
->clear_node_queue
);
1057 bgp_sync_delete(peer
);
1059 if (peer
->conf_if
) {
1060 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1061 peer
->conf_if
= NULL
;
1064 bfd_info_free(&(peer
->bfd_info
));
1066 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1067 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1068 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1073 bgp_unlock(peer
->bgp
);
1075 memset(peer
, 0, sizeof(struct peer
));
1077 XFREE(MTYPE_BGP_PEER
, peer
);
1080 /* increase reference count on a struct peer */
1081 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1083 assert(peer
&& (peer
->lock
>= 0));
1086 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1094 /* decrease reference count on a struct peer
1095 * struct peer is freed and NULL returned if last reference
1097 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1099 assert(peer
&& (peer
->lock
> 0));
1102 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1107 if (peer
->lock
== 0) {
1115 /* Allocate new peer object, implicitely locked. */
1116 struct peer
*peer_new(struct bgp
*bgp
)
1123 /* bgp argument is absolutely required */
1128 /* Allocate new peer. */
1129 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1131 /* Set default value. */
1133 peer
->v_start
= BGP_INIT_START_TIMER
;
1134 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1135 peer
->status
= Idle
;
1136 peer
->ostatus
= Idle
;
1137 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1138 peer
->bgp
= bgp_lock(bgp
);
1139 peer
= peer_lock(peer
); /* initial reference */
1140 peer
->password
= NULL
;
1142 /* Set default flags. */
1143 FOREACH_AFI_SAFI (afi
, safi
) {
1144 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1145 SET_FLAG(peer
->af_flags
[afi
][safi
],
1146 PEER_FLAG_SEND_COMMUNITY
);
1147 SET_FLAG(peer
->af_flags
[afi
][safi
],
1148 PEER_FLAG_SEND_EXT_COMMUNITY
);
1149 SET_FLAG(peer
->af_flags
[afi
][safi
],
1150 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1152 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1153 PEER_FLAG_SEND_COMMUNITY
);
1154 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1155 PEER_FLAG_SEND_EXT_COMMUNITY
);
1156 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1157 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1159 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1162 /* set nexthop-unchanged for l2vpn evpn by default */
1163 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1164 PEER_FLAG_NEXTHOP_UNCHANGED
);
1166 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1168 /* Create buffers. */
1169 peer
->ibuf
= stream_fifo_new();
1170 peer
->obuf
= stream_fifo_new();
1171 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1173 /* We use a larger buffer for peer->obuf_work in the event that:
1174 * - We RX a BGP_UPDATE where the attributes alone are just
1175 * under BGP_MAX_PACKET_SIZE
1176 * - The user configures an outbound route-map that does many as-path
1177 * prepends or adds many communities. At most they can have
1178 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1179 * large they can make the attributes.
1181 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1182 * bounds checking for every single attribute as we construct an
1186 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1188 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1190 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1192 bgp_sync_init(peer
);
1194 /* Get service port number. */
1195 sp
= getservbyname("bgp", "tcp");
1196 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1198 QOBJ_REG(peer
, peer
);
1203 * This function is invoked when a duplicate peer structure associated with
1204 * a neighbor is being deleted. If this about-to-be-deleted structure is
1205 * the one with all the config, then we have to copy over the info.
1207 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1209 struct peer_af
*paf
;
1217 /* The following function is used by both peer group config copy to
1218 * individual peer and when we transfer config
1220 if (peer_src
->change_local_as
)
1221 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1223 /* peer flags apply */
1224 peer_dst
->flags
= peer_src
->flags
;
1225 peer_dst
->cap
= peer_src
->cap
;
1227 peer_dst
->local_as
= peer_src
->local_as
;
1228 peer_dst
->port
= peer_src
->port
;
1229 (void)peer_sort(peer_dst
);
1230 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1233 peer_dst
->holdtime
= peer_src
->holdtime
;
1234 peer_dst
->keepalive
= peer_src
->keepalive
;
1235 peer_dst
->connect
= peer_src
->connect
;
1236 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1237 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1238 peer_dst
->routeadv
= peer_src
->routeadv
;
1239 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1241 /* password apply */
1242 if (peer_src
->password
&& !peer_dst
->password
)
1243 peer_dst
->password
=
1244 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1246 FOREACH_AFI_SAFI (afi
, safi
) {
1247 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1248 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1249 peer_dst
->allowas_in
[afi
][safi
] =
1250 peer_src
->allowas_in
[afi
][safi
];
1251 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1252 peer_dst
->addpath_type
[afi
][safi
] =
1253 peer_src
->addpath_type
[afi
][safi
];
1256 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1257 paf
= peer_src
->peer_af_array
[afidx
];
1259 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1262 /* update-source apply */
1263 if (peer_src
->update_source
) {
1264 if (peer_dst
->update_source
)
1265 sockunion_free(peer_dst
->update_source
);
1266 if (peer_dst
->update_if
) {
1267 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1268 peer_dst
->update_if
= NULL
;
1270 peer_dst
->update_source
=
1271 sockunion_dup(peer_src
->update_source
);
1272 } else if (peer_src
->update_if
) {
1273 if (peer_dst
->update_if
)
1274 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1275 if (peer_dst
->update_source
) {
1276 sockunion_free(peer_dst
->update_source
);
1277 peer_dst
->update_source
= NULL
;
1279 peer_dst
->update_if
=
1280 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1283 if (peer_src
->ifname
) {
1284 if (peer_dst
->ifname
)
1285 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1288 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1292 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1293 struct interface
*ifp
)
1295 struct connected
*ifc
;
1298 struct listnode
*node
;
1300 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1301 * IPv4 address of the other end.
1303 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1304 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1305 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1306 if (p
.prefixlen
== 30) {
1307 peer
->su
.sa
.sa_family
= AF_INET
;
1308 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1310 peer
->su
.sin
.sin_addr
.s_addr
=
1312 else if (addr
% 4 == 2)
1313 peer
->su
.sin
.sin_addr
.s_addr
=
1315 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1316 peer
->su
.sin
.sin_len
=
1317 sizeof(struct sockaddr_in
);
1318 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1320 } else if (p
.prefixlen
== 31) {
1321 peer
->su
.sa
.sa_family
= AF_INET
;
1322 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1324 peer
->su
.sin
.sin_addr
.s_addr
=
1327 peer
->su
.sin
.sin_addr
.s_addr
=
1329 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1330 peer
->su
.sin
.sin_len
=
1331 sizeof(struct sockaddr_in
);
1332 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1334 } else if (bgp_debug_neighbor_events(peer
))
1336 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1344 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1345 struct interface
*ifp
)
1347 struct nbr_connected
*ifc_nbr
;
1349 /* Have we learnt the peer's IPv6 link-local address? */
1350 if (ifp
->nbr_connected
1351 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1352 peer
->su
.sa
.sa_family
= AF_INET6
;
1353 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1354 sizeof(struct in6_addr
));
1356 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1358 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1366 * Set or reset the peer address socketunion structure based on the
1367 * learnt/derived peer address. If the address has changed, update the
1368 * password on the listen socket, if needed.
1370 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1372 struct interface
*ifp
;
1374 int peer_addr_updated
= 0;
1380 * Our peer structure is stored in the bgp->peerhash
1381 * release it before we modify anything.
1383 hash_release(peer
->bgp
->peerhash
, peer
);
1385 prev_family
= peer
->su
.sa
.sa_family
;
1386 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1388 /* If BGP unnumbered is not "v6only", we first see if we can
1390 * peer's IPv4 address.
1392 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1394 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1396 /* If "v6only" or we can't derive peer's IPv4 address, see if
1398 * learnt the peer's IPv6 link-local address. This is from the
1400 * IPv6 address in router advertisement.
1402 if (!peer_addr_updated
)
1404 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1406 /* If we could derive the peer address, we may need to install the
1408 * configured for the peer, if any, on the listen socket. Otherwise,
1410 * that peer's address is not available and uninstall the password, if
1413 if (peer_addr_updated
) {
1414 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1415 && prev_family
== AF_UNSPEC
)
1418 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1419 && prev_family
!= AF_UNSPEC
)
1420 bgp_md5_unset(peer
);
1421 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1422 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1426 * Since our su changed we need to del/add peer to the peerhash
1428 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1431 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1434 struct bgp_node
*rn
, *nrn
;
1436 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1437 rn
= bgp_route_next(rn
)) {
1438 if (rn
->info
!= NULL
) {
1439 /* Special handling for 2-level routing
1441 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1442 || safi
== SAFI_EVPN
) {
1443 for (nrn
= bgp_table_top(
1444 (struct bgp_table
*)(rn
->info
));
1445 nrn
; nrn
= bgp_route_next(nrn
))
1446 bgp_process(bgp
, nrn
, afi
, safi
);
1448 bgp_process(bgp
, rn
, afi
, safi
);
1453 /* Force a bestpath recalculation for all prefixes. This is used
1454 * when 'bgp bestpath' commands are entered.
1456 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1461 FOREACH_AFI_SAFI (afi
, safi
) {
1462 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1467 * Create new BGP peer.
1469 * conf_if and su are mutually exclusive if configuring from the cli.
1470 * If we are handing a doppelganger, then we *must* pass in both
1471 * the original peer's su and conf_if, so that we can appropriately
1472 * track the bgp->peerhash( ie we don't want to remove the current
1473 * one from the config ).
1475 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1476 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1477 int as_type
, afi_t afi
, safi_t safi
,
1478 struct peer_group
*group
)
1482 char buf
[SU_ADDRSTRLEN
];
1484 peer
= peer_new(bgp
);
1486 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1490 bgp_peer_conf_if_to_su_update(peer
);
1492 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1493 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1496 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1498 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1499 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1501 peer
->local_as
= local_as
;
1502 peer
->as
= remote_as
;
1503 peer
->as_type
= as_type
;
1504 peer
->local_id
= bgp
->router_id
;
1505 peer
->v_holdtime
= bgp
->default_holdtime
;
1506 peer
->v_keepalive
= bgp
->default_keepalive
;
1507 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1508 ? BGP_DEFAULT_IBGP_ROUTEADV
1509 : BGP_DEFAULT_EBGP_ROUTEADV
;
1511 peer
= peer_lock(peer
); /* bgp peer list reference */
1512 peer
->group
= group
;
1513 listnode_add_sort(bgp
->peer
, peer
);
1514 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1516 /* Adjust update-group coalesce timer heuristics for # peers. */
1517 if (bgp
->heuristic_coalesce
) {
1518 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1520 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1521 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1524 active
= peer_active(peer
);
1526 /* Last read and reset time set */
1527 peer
->readtime
= peer
->resettime
= bgp_clock();
1529 /* Default TTL set. */
1530 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1532 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1535 peer
->afc
[afi
][safi
] = 1;
1536 peer_af_create(peer
, afi
, safi
);
1539 /* auto shutdown if configured */
1540 if (bgp
->autoshutdown
)
1541 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1542 /* Set up peer's events and timers. */
1543 else if (!active
&& peer_active(peer
))
1544 bgp_timer_set(peer
);
1549 /* Make accept BGP peer. This function is only called from the test code */
1550 struct peer
*peer_create_accept(struct bgp
*bgp
)
1554 peer
= peer_new(bgp
);
1556 peer
= peer_lock(peer
); /* bgp peer list reference */
1557 listnode_add_sort(bgp
->peer
, peer
);
1563 * Return true if we have a peer configured to use this afi/safi
1565 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1567 struct listnode
*node
;
1570 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1571 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1574 if (peer
->afc
[afi
][safi
])
1581 /* Change peer's AS number. */
1582 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1584 bgp_peer_sort_t type
;
1587 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1588 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1589 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1590 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1591 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1593 bgp_session_reset(peer
);
1595 type
= peer_sort(peer
);
1597 peer
->as_type
= as_specified
;
1599 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1600 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1601 && peer
->bgp
->as
!= as
)
1602 peer
->local_as
= peer
->bgp
->confed_id
;
1604 peer
->local_as
= peer
->bgp
->as
;
1606 /* Advertisement-interval reset */
1607 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1608 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1609 ? BGP_DEFAULT_IBGP_ROUTEADV
1610 : BGP_DEFAULT_EBGP_ROUTEADV
;
1614 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1616 else if (type
== BGP_PEER_IBGP
)
1619 /* reflector-client reset */
1620 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1621 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1622 PEER_FLAG_REFLECTOR_CLIENT
);
1623 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1624 PEER_FLAG_REFLECTOR_CLIENT
);
1625 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1626 PEER_FLAG_REFLECTOR_CLIENT
);
1627 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1628 PEER_FLAG_REFLECTOR_CLIENT
);
1629 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1630 PEER_FLAG_REFLECTOR_CLIENT
);
1631 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1632 PEER_FLAG_REFLECTOR_CLIENT
);
1633 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1634 PEER_FLAG_REFLECTOR_CLIENT
);
1635 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1636 PEER_FLAG_REFLECTOR_CLIENT
);
1637 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1638 PEER_FLAG_REFLECTOR_CLIENT
);
1639 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1640 PEER_FLAG_REFLECTOR_CLIENT
);
1641 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1642 PEER_FLAG_REFLECTOR_CLIENT
);
1643 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1644 PEER_FLAG_REFLECTOR_CLIENT
);
1645 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1646 PEER_FLAG_REFLECTOR_CLIENT
);
1649 /* local-as reset */
1650 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1651 peer
->change_local_as
= 0;
1652 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1653 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1654 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1658 /* If peer does not exist, create new one. If peer already exists,
1659 set AS number to the peer. */
1660 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1661 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1667 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1669 peer
= peer_lookup(bgp
, su
);
1672 /* Not allowed for a dynamic peer. */
1673 if (peer_dynamic_neighbor(peer
)) {
1675 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1678 /* When this peer is a member of peer-group. */
1680 if (peer
->group
->conf
->as
) {
1681 /* Return peer group's AS number. */
1682 *as
= peer
->group
->conf
->as
;
1683 return BGP_ERR_PEER_GROUP_MEMBER
;
1685 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1686 if ((as_type
!= AS_INTERNAL
)
1687 && (bgp
->as
!= *as
)) {
1689 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1692 if ((as_type
!= AS_EXTERNAL
)
1693 && (bgp
->as
== *as
)) {
1695 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1700 /* Existing peer's AS number change. */
1701 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1702 || (peer
->as_type
!= as_type
))
1703 peer_as_change(peer
, *as
, as_type
);
1706 return BGP_ERR_NO_INTERFACE_CONFIG
;
1708 /* If the peer is not part of our confederation, and its not an
1709 iBGP peer then spoof the source AS */
1710 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1711 && !bgp_confederation_peers_check(bgp
, *as
)
1713 local_as
= bgp
->confed_id
;
1717 /* If this is IPv4 unicast configuration and "no bgp default
1718 ipv4-unicast" is specified. */
1720 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1721 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1722 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1725 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1732 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1733 struct peer
*peer
, afi_t afi
,
1737 int out
= FILTER_OUT
;
1739 uint32_t pflags_ovrd
;
1740 uint8_t *pfilter_ovrd
;
1744 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1745 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1747 /* peer af_flags apply */
1748 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1749 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1750 ^ peer
->af_flags_invert
[afi
][safi
];
1751 flags_tmp
&= ~pflags_ovrd
;
1753 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1754 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1755 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1756 conf
->af_flags_invert
[afi
][safi
]);
1758 /* maximum-prefix */
1759 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1760 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1761 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1762 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1766 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1767 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1770 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1771 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1773 /* default-originate route-map */
1774 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1775 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1776 MTYPE_ROUTE_MAP_NAME
);
1777 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1780 /* inbound filter apply */
1781 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1782 PEER_STR_ATTR_INHERIT(peer
, group
,
1783 filter
[afi
][safi
].dlist
[in
].name
,
1784 MTYPE_BGP_FILTER_NAME
);
1785 PEER_ATTR_INHERIT(peer
, group
,
1786 filter
[afi
][safi
].dlist
[in
].alist
);
1789 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1790 PEER_STR_ATTR_INHERIT(peer
, group
,
1791 filter
[afi
][safi
].plist
[in
].name
,
1792 MTYPE_BGP_FILTER_NAME
);
1793 PEER_ATTR_INHERIT(peer
, group
,
1794 filter
[afi
][safi
].plist
[in
].plist
);
1797 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1798 PEER_STR_ATTR_INHERIT(peer
, group
,
1799 filter
[afi
][safi
].aslist
[in
].name
,
1800 MTYPE_BGP_FILTER_NAME
);
1801 PEER_ATTR_INHERIT(peer
, group
,
1802 filter
[afi
][safi
].aslist
[in
].aslist
);
1805 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1806 PEER_STR_ATTR_INHERIT(peer
, group
,
1807 filter
[afi
][safi
].map
[in
].name
,
1808 MTYPE_BGP_FILTER_NAME
);
1809 PEER_ATTR_INHERIT(peer
, group
,
1810 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1813 /* outbound filter apply */
1814 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1815 PEER_STR_ATTR_INHERIT(peer
, group
,
1816 filter
[afi
][safi
].dlist
[out
].name
,
1817 MTYPE_BGP_FILTER_NAME
);
1818 PEER_ATTR_INHERIT(peer
, group
,
1819 filter
[afi
][safi
].dlist
[out
].alist
);
1822 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1823 PEER_STR_ATTR_INHERIT(peer
, group
,
1824 filter
[afi
][safi
].plist
[out
].name
,
1825 MTYPE_BGP_FILTER_NAME
);
1826 PEER_ATTR_INHERIT(peer
, group
,
1827 filter
[afi
][safi
].plist
[out
].plist
);
1830 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1831 PEER_STR_ATTR_INHERIT(peer
, group
,
1832 filter
[afi
][safi
].aslist
[out
].name
,
1833 MTYPE_BGP_FILTER_NAME
);
1834 PEER_ATTR_INHERIT(peer
, group
,
1835 filter
[afi
][safi
].aslist
[out
].aslist
);
1838 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1839 PEER_STR_ATTR_INHERIT(peer
, group
,
1840 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1841 MTYPE_BGP_FILTER_NAME
);
1842 PEER_ATTR_INHERIT(peer
, group
,
1843 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1846 /* nondirectional filter apply */
1847 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1848 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1849 MTYPE_BGP_FILTER_NAME
);
1850 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1853 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1854 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1855 bgp_addpath_type_changed(conf
->bgp
);
1859 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1864 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1865 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1866 __func__
, peer
->host
);
1870 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1872 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1873 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1874 return BGP_ERR_PEER_SAFI_CONFLICT
;
1876 /* Nothing to do if we've already activated this peer */
1877 if (peer
->afc
[afi
][safi
])
1880 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1883 active
= peer_active(peer
);
1884 peer
->afc
[afi
][safi
] = 1;
1887 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1889 if (!active
&& peer_active(peer
)) {
1890 bgp_timer_set(peer
);
1892 if (peer
->status
== Established
) {
1893 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1894 peer
->afc_adv
[afi
][safi
] = 1;
1895 bgp_capability_send(peer
, afi
, safi
,
1897 CAPABILITY_ACTION_SET
);
1898 if (peer
->afc_recv
[afi
][safi
]) {
1899 peer
->afc_nego
[afi
][safi
] = 1;
1900 bgp_announce_route(peer
, afi
, safi
);
1903 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1904 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1905 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1908 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1909 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1910 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1911 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1914 * If we are turning on a AFI/SAFI locally and we've
1915 * started bringing a peer up, we need to tell
1916 * the other peer to restart because we might loose
1917 * configuration here because when the doppelganger
1918 * gets to a established state due to how
1919 * we resolve we could just overwrite the afi/safi
1922 other
= peer
->doppelganger
;
1924 && (other
->status
== OpenSent
1925 || other
->status
== OpenConfirm
)) {
1926 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1927 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1928 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1935 /* Activate the peer or peer group for specified AFI and SAFI. */
1936 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1939 struct peer_group
*group
;
1940 struct listnode
*node
, *nnode
;
1941 struct peer
*tmp_peer
;
1944 /* Nothing to do if we've already activated this peer */
1945 if (peer
->afc
[afi
][safi
])
1950 /* This is a peer-group so activate all of the members of the
1951 * peer-group as well */
1952 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1954 /* Do not activate a peer for both SAFI_UNICAST and
1955 * SAFI_LABELED_UNICAST */
1956 if ((safi
== SAFI_UNICAST
1957 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1958 || (safi
== SAFI_LABELED_UNICAST
1959 && peer
->afc
[afi
][SAFI_UNICAST
]))
1960 return BGP_ERR_PEER_SAFI_CONFLICT
;
1962 peer
->afc
[afi
][safi
] = 1;
1963 group
= peer
->group
;
1965 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1966 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1969 ret
|= peer_activate_af(peer
, afi
, safi
);
1972 /* If this is the first peer to be activated for this
1973 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1974 if (safi
== SAFI_LABELED_UNICAST
1975 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1977 if (BGP_DEBUG(zebra
, ZEBRA
))
1979 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1981 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1982 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1985 if (safi
== SAFI_FLOWSPEC
) {
1986 /* connect to table manager */
1987 bgp_zebra_init_tm_connect(bgp
);
1992 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1995 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1996 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1997 __func__
, peer
->host
);
2001 /* Nothing to do if we've already deactivated this peer */
2002 if (!peer
->afc
[afi
][safi
])
2005 /* De-activate the address family configuration. */
2006 peer
->afc
[afi
][safi
] = 0;
2008 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2009 flog_err(EC_BGP_PEER_DELETE
,
2010 "couldn't delete af structure for peer %s",
2015 if (peer
->status
== Established
) {
2016 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2017 peer
->afc_adv
[afi
][safi
] = 0;
2018 peer
->afc_nego
[afi
][safi
] = 0;
2020 if (peer_active_nego(peer
)) {
2021 bgp_capability_send(peer
, afi
, safi
,
2023 CAPABILITY_ACTION_UNSET
);
2024 bgp_clear_route(peer
, afi
, safi
);
2025 peer
->pcount
[afi
][safi
] = 0;
2027 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2028 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2029 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2032 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2033 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2034 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2041 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2044 struct peer_group
*group
;
2045 struct peer
*tmp_peer
;
2046 struct listnode
*node
, *nnode
;
2049 /* Nothing to do if we've already de-activated this peer */
2050 if (!peer
->afc
[afi
][safi
])
2053 /* This is a peer-group so de-activate all of the members of the
2054 * peer-group as well */
2055 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2056 peer
->afc
[afi
][safi
] = 0;
2057 group
= peer
->group
;
2059 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2060 flog_err(EC_BGP_PEER_DELETE
,
2061 "couldn't delete af structure for peer %s",
2065 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2066 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2069 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2074 /* If this is the last peer to be deactivated for this
2075 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2076 if (safi
== SAFI_LABELED_UNICAST
2077 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2078 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2080 if (BGP_DEBUG(zebra
, ZEBRA
))
2082 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2084 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2085 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2090 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2093 return peer_activate(peer
, afi
, safi
);
2095 return peer_deactivate(peer
, afi
, safi
);
2098 static void peer_nsf_stop(struct peer
*peer
)
2103 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2104 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2106 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2107 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2108 peer
->nsf
[afi
][safi
] = 0;
2110 if (peer
->t_gr_restart
) {
2111 BGP_TIMER_OFF(peer
->t_gr_restart
);
2112 if (bgp_debug_neighbor_events(peer
))
2113 zlog_debug("%s graceful restart timer stopped",
2116 if (peer
->t_gr_stale
) {
2117 BGP_TIMER_OFF(peer
->t_gr_stale
);
2118 if (bgp_debug_neighbor_events(peer
))
2120 "%s graceful restart stalepath timer stopped",
2123 bgp_clear_route_all(peer
);
2126 /* Delete peer from confguration.
2128 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2129 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2131 * This function /should/ take care to be idempotent, to guard against
2132 * it being called multiple times through stray events that come in
2133 * that happen to result in this function being called again. That
2134 * said, getting here for a "Deleted" peer is a bug in the neighbour
2137 int peer_delete(struct peer
*peer
)
2143 struct bgp_filter
*filter
;
2144 struct listnode
*pn
;
2147 assert(peer
->status
!= Deleted
);
2150 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2152 bgp_reads_off(peer
);
2153 bgp_writes_off(peer
);
2154 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2155 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2157 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2158 peer_nsf_stop(peer
);
2160 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2162 /* If this peer belongs to peer group, clear up the
2165 if (peer_dynamic_neighbor(peer
))
2166 peer_drop_dynamic_neighbor(peer
);
2168 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2170 peer
); /* group->peer list reference */
2171 list_delete_node(peer
->group
->peer
, pn
);
2176 /* Withdraw all information from routing table. We can not use
2177 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2178 * executed after peer structure is deleted.
2180 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2182 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2184 if (peer
->doppelganger
) {
2185 peer
->doppelganger
->doppelganger
= NULL
;
2186 peer
->doppelganger
= NULL
;
2189 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2190 bgp_fsm_change_status(peer
, Deleted
);
2192 /* Remove from NHT */
2193 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2194 bgp_unlink_nexthop_by_peer(peer
);
2196 /* Password configuration */
2197 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2198 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2200 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2201 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2202 bgp_md5_unset(peer
);
2205 bgp_timer_set(peer
); /* stops all timers for Deleted */
2207 /* Delete from all peer list. */
2208 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2209 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2210 peer_unlock(peer
); /* bgp peer list reference */
2211 list_delete_node(bgp
->peer
, pn
);
2212 hash_release(bgp
->peerhash
, peer
);
2217 stream_fifo_free(peer
->ibuf
);
2222 stream_fifo_free(peer
->obuf
);
2226 if (peer
->ibuf_work
) {
2227 ringbuf_del(peer
->ibuf_work
);
2228 peer
->ibuf_work
= NULL
;
2231 if (peer
->obuf_work
) {
2232 stream_free(peer
->obuf_work
);
2233 peer
->obuf_work
= NULL
;
2236 if (peer
->scratch
) {
2237 stream_free(peer
->scratch
);
2238 peer
->scratch
= NULL
;
2241 /* Local and remote addresses. */
2242 if (peer
->su_local
) {
2243 sockunion_free(peer
->su_local
);
2244 peer
->su_local
= NULL
;
2247 if (peer
->su_remote
) {
2248 sockunion_free(peer
->su_remote
);
2249 peer
->su_remote
= NULL
;
2252 /* Free filter related memory. */
2253 FOREACH_AFI_SAFI (afi
, safi
) {
2254 filter
= &peer
->filter
[afi
][safi
];
2256 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2257 if (filter
->dlist
[i
].name
) {
2258 XFREE(MTYPE_BGP_FILTER_NAME
,
2259 filter
->dlist
[i
].name
);
2260 filter
->dlist
[i
].name
= NULL
;
2263 if (filter
->plist
[i
].name
) {
2264 XFREE(MTYPE_BGP_FILTER_NAME
,
2265 filter
->plist
[i
].name
);
2266 filter
->plist
[i
].name
= NULL
;
2269 if (filter
->aslist
[i
].name
) {
2270 XFREE(MTYPE_BGP_FILTER_NAME
,
2271 filter
->aslist
[i
].name
);
2272 filter
->aslist
[i
].name
= NULL
;
2276 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2277 if (filter
->map
[i
].name
) {
2278 XFREE(MTYPE_BGP_FILTER_NAME
,
2279 filter
->map
[i
].name
);
2280 filter
->map
[i
].name
= NULL
;
2284 if (filter
->usmap
.name
) {
2285 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2286 filter
->usmap
.name
= NULL
;
2289 if (peer
->default_rmap
[afi
][safi
].name
) {
2290 XFREE(MTYPE_ROUTE_MAP_NAME
,
2291 peer
->default_rmap
[afi
][safi
].name
);
2292 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2296 FOREACH_AFI_SAFI (afi
, safi
)
2297 peer_af_delete(peer
, afi
, safi
);
2299 if (peer
->hostname
) {
2300 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2301 peer
->hostname
= NULL
;
2304 if (peer
->domainname
) {
2305 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2306 peer
->domainname
= NULL
;
2309 peer_unlock(peer
); /* initial reference */
2314 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2316 return strcmp(g1
->name
, g2
->name
);
2319 /* Peer group cofiguration. */
2320 static struct peer_group
*peer_group_new(void)
2322 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2323 sizeof(struct peer_group
));
2326 static void peer_group_free(struct peer_group
*group
)
2328 XFREE(MTYPE_PEER_GROUP
, group
);
2331 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2333 struct peer_group
*group
;
2334 struct listnode
*node
, *nnode
;
2336 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2337 if (strcmp(group
->name
, name
) == 0)
2343 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2345 struct peer_group
*group
;
2348 group
= peer_group_lookup(bgp
, name
);
2352 group
= peer_group_new();
2355 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2356 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2357 group
->peer
= list_new();
2358 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2359 group
->listen_range
[afi
] = list_new();
2360 group
->conf
= peer_new(bgp
);
2361 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2362 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2363 if (group
->conf
->host
)
2364 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2365 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2366 group
->conf
->group
= group
;
2367 group
->conf
->as
= 0;
2368 group
->conf
->ttl
= 1;
2369 group
->conf
->gtsm_hops
= 0;
2370 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2371 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2372 listnode_add_sort(bgp
->group
, group
);
2377 static void peer_group2peer_config_copy(struct peer_group
*group
,
2387 peer
->as
= conf
->as
;
2390 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2391 peer
->change_local_as
= conf
->change_local_as
;
2394 peer
->ttl
= conf
->ttl
;
2397 peer
->gtsm_hops
= conf
->gtsm_hops
;
2399 /* peer flags apply */
2400 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2401 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2402 flags_tmp
&= ~peer
->flags_override
;
2404 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2405 SET_FLAG(peer
->flags
, flags_tmp
);
2406 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2408 /* peer timers apply */
2409 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2410 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2411 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2414 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2415 PEER_ATTR_INHERIT(peer
, group
, connect
);
2416 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2417 peer
->v_connect
= conf
->connect
;
2419 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2422 /* advertisement-interval apply */
2423 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2424 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2425 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2426 peer
->v_routeadv
= conf
->routeadv
;
2428 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2429 ? BGP_DEFAULT_IBGP_ROUTEADV
2430 : BGP_DEFAULT_EBGP_ROUTEADV
;
2433 /* password apply */
2434 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2435 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2436 MTYPE_PEER_PASSWORD
);
2438 if (!BGP_PEER_SU_UNSPEC(peer
))
2441 /* update-source apply */
2442 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2443 if (conf
->update_source
) {
2444 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2445 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2446 } else if (conf
->update_if
) {
2447 sockunion_free(peer
->update_source
);
2448 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2449 MTYPE_PEER_UPDATE_SOURCE
);
2453 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2456 /* Peer group's remote AS configuration. */
2457 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2460 struct peer_group
*group
;
2462 struct listnode
*node
, *nnode
;
2464 group
= peer_group_lookup(bgp
, group_name
);
2468 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2472 /* When we setup peer-group AS number all peer group member's AS
2473 number must be updated to same number. */
2474 peer_as_change(group
->conf
, *as
, as_type
);
2476 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2477 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2478 || (peer
->as_type
!= as_type
))
2479 peer_as_change(peer
, *as
, as_type
);
2485 int peer_group_delete(struct peer_group
*group
)
2489 struct prefix
*prefix
;
2491 struct listnode
*node
, *nnode
;
2496 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2497 other
= peer
->doppelganger
;
2499 if (other
&& other
->status
!= Deleted
) {
2500 other
->group
= NULL
;
2504 list_delete(&group
->peer
);
2506 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2507 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2509 prefix_free(prefix
);
2511 list_delete(&group
->listen_range
[afi
]);
2514 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2517 bfd_info_free(&(group
->conf
->bfd_info
));
2519 group
->conf
->group
= NULL
;
2520 peer_delete(group
->conf
);
2522 /* Delete from all peer_group list. */
2523 listnode_delete(bgp
->group
, group
);
2525 peer_group_free(group
);
2530 int peer_group_remote_as_delete(struct peer_group
*group
)
2532 struct peer
*peer
, *other
;
2533 struct listnode
*node
, *nnode
;
2535 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2536 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2539 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2540 other
= peer
->doppelganger
;
2544 if (other
&& other
->status
!= Deleted
) {
2545 other
->group
= NULL
;
2549 list_delete_all_node(group
->peer
);
2551 group
->conf
->as
= 0;
2552 group
->conf
->as_type
= AS_UNSPECIFIED
;
2557 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2559 struct prefix
*prefix
;
2560 struct listnode
*node
, *nnode
;
2563 afi
= family2afi(range
->family
);
2565 /* Group needs remote AS configured. */
2566 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2567 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2569 /* Ensure no duplicates. Currently we don't care about overlaps. */
2570 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2571 if (prefix_same(range
, prefix
))
2575 prefix
= prefix_new();
2576 prefix_copy(prefix
, range
);
2577 listnode_add(group
->listen_range
[afi
], prefix
);
2581 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2583 struct prefix
*prefix
, prefix2
;
2584 struct listnode
*node
, *nnode
;
2587 char buf
[PREFIX2STR_BUFFER
];
2589 afi
= family2afi(range
->family
);
2591 /* Identify the listen range. */
2592 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2593 if (prefix_same(range
, prefix
))
2598 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2600 prefix2str(prefix
, buf
, sizeof(buf
));
2602 /* Dispose off any dynamic neighbors that exist due to this listen range
2604 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2605 if (!peer_dynamic_neighbor(peer
))
2608 sockunion2hostprefix(&peer
->su
, &prefix2
);
2609 if (prefix_match(prefix
, &prefix2
)) {
2610 if (bgp_debug_neighbor_events(peer
))
2612 "Deleting dynamic neighbor %s group %s upon "
2613 "delete of listen range %s",
2614 peer
->host
, group
->name
, buf
);
2619 /* Get rid of the listen range */
2620 listnode_delete(group
->listen_range
[afi
], prefix
);
2625 /* Bind specified peer to peer group. */
2626 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2627 struct peer_group
*group
, as_t
*as
)
2629 int first_member
= 0;
2633 /* Lookup the peer. */
2635 peer
= peer_lookup(bgp
, su
);
2637 /* The peer exist, bind it to the peer-group */
2639 /* When the peer already belongs to a peer-group, check the
2641 if (peer_group_active(peer
)) {
2643 /* The peer is already bound to the peer-group,
2646 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2649 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2652 /* The peer has not specified a remote-as, inherit it from the
2654 if (peer
->as_type
== AS_UNSPECIFIED
) {
2655 peer
->as_type
= group
->conf
->as_type
;
2656 peer
->as
= group
->conf
->as
;
2659 if (!group
->conf
->as
) {
2660 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2661 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2664 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2667 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2671 peer_group2peer_config_copy(group
, peer
);
2673 FOREACH_AFI_SAFI (afi
, safi
) {
2674 if (group
->conf
->afc
[afi
][safi
]) {
2675 peer
->afc
[afi
][safi
] = 1;
2677 if (peer_af_find(peer
, afi
, safi
)
2678 || peer_af_create(peer
, afi
, safi
)) {
2679 peer_group2peer_config_copy_af(
2680 group
, peer
, afi
, safi
);
2682 } else if (peer
->afc
[afi
][safi
])
2683 peer_deactivate(peer
, afi
, safi
);
2687 assert(group
&& peer
->group
== group
);
2689 listnode_delete(bgp
->peer
, peer
);
2691 peer
->group
= group
;
2692 listnode_add_sort(bgp
->peer
, peer
);
2694 peer
= peer_lock(peer
); /* group->peer list reference */
2695 listnode_add(group
->peer
, peer
);
2699 /* Advertisement-interval reset */
2700 if (!CHECK_FLAG(group
->conf
->flags
,
2701 PEER_FLAG_ROUTEADV
)) {
2702 group
->conf
->v_routeadv
=
2703 (peer_sort(group
->conf
)
2705 ? BGP_DEFAULT_IBGP_ROUTEADV
2706 : BGP_DEFAULT_EBGP_ROUTEADV
;
2709 /* ebgp-multihop reset */
2710 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2711 group
->conf
->ttl
= MAXTTL
;
2713 /* local-as reset */
2714 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2715 group
->conf
->change_local_as
= 0;
2716 peer_flag_unset(group
->conf
,
2717 PEER_FLAG_LOCAL_AS
);
2718 peer_flag_unset(group
->conf
,
2719 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2720 peer_flag_unset(group
->conf
,
2721 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2725 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2727 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2728 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2729 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2730 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2732 bgp_session_reset(peer
);
2736 /* Create a new peer. */
2738 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2739 && (!group
->conf
->as
)) {
2740 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2743 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2744 group
->conf
->as_type
, 0, 0, group
);
2746 peer
= peer_lock(peer
); /* group->peer list reference */
2747 listnode_add(group
->peer
, peer
);
2749 peer_group2peer_config_copy(group
, peer
);
2751 /* If the peer-group is active for this afi/safi then activate
2753 FOREACH_AFI_SAFI (afi
, safi
) {
2754 if (group
->conf
->afc
[afi
][safi
]) {
2755 peer
->afc
[afi
][safi
] = 1;
2756 peer_af_create(peer
, afi
, safi
);
2757 peer_group2peer_config_copy_af(group
, peer
, afi
,
2759 } else if (peer
->afc
[afi
][safi
])
2760 peer_deactivate(peer
, afi
, safi
);
2763 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2765 /* Set up peer's events and timers. */
2766 if (peer_active(peer
))
2767 bgp_timer_set(peer
);
2773 static int bgp_startup_timer_expire(struct thread
*thread
)
2777 bgp
= THREAD_ARG(thread
);
2778 bgp
->t_startup
= NULL
;
2784 * On shutdown we call the cleanup function which
2785 * does a free of the link list nodes, free up
2786 * the data we are pointing at too.
2788 static void bgp_vrf_string_name_delete(void *data
)
2792 XFREE(MTYPE_TMP
, vname
);
2795 /* BGP instance creation by `router bgp' commands. */
2796 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2797 enum bgp_instance_type inst_type
)
2803 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2806 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2807 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2808 zlog_debug("Creating Default VRF, AS %u", *as
);
2810 zlog_debug("Creating %s %s, AS %u",
2811 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2818 bgp
->heuristic_coalesce
= true;
2819 bgp
->inst_type
= inst_type
;
2820 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2822 bgp
->peer_self
= peer_new(bgp
);
2823 if (bgp
->peer_self
->host
)
2824 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2825 bgp
->peer_self
->host
=
2826 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2827 if (bgp
->peer_self
->hostname
!= NULL
) {
2828 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2829 bgp
->peer_self
->hostname
= NULL
;
2831 if (cmd_hostname_get())
2832 bgp
->peer_self
->hostname
=
2833 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2835 if (bgp
->peer_self
->domainname
!= NULL
) {
2836 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2837 bgp
->peer_self
->domainname
= NULL
;
2839 if (cmd_domainname_get())
2840 bgp
->peer_self
->domainname
=
2841 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2842 bgp
->peer
= list_new();
2843 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2844 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2846 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2848 bgp
->group
= list_new();
2849 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2851 FOREACH_AFI_SAFI (afi
, safi
) {
2852 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2853 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2854 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2856 /* Enable maximum-paths */
2857 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2859 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2863 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2864 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2865 bgp
->default_subgroup_pkt_queue_max
=
2866 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2867 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2868 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2869 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2870 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2871 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2872 bgp
->dynamic_neighbors_count
= 0;
2873 #if DFLT_BGP_IMPORT_CHECK
2874 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2876 #if DFLT_BGP_SHOW_HOSTNAME
2877 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2879 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2880 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2882 #if DFLT_BGP_DETERMINISTIC_MED
2883 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2885 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2890 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2891 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2893 assert(bgp
->rfapi_cfg
);
2895 #endif /* ENABLE_BGP_VNC */
2897 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2898 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2899 bgp
->vpn_policy
[afi
].afi
= afi
;
2900 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2901 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2904 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2905 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2906 bgp_vrf_string_name_delete
;
2907 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2908 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2909 bgp_vrf_string_name_delete
;
2912 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2914 /* TODO - The startup timer needs to be run for the whole of BGP
2916 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2917 bgp
->restart_time
, &bgp
->t_startup
);
2920 /* printable name we can use in debug messages */
2921 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2922 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2932 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2934 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2935 snprintf(bgp
->name_pretty
, len
, "%s %s",
2936 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2942 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2943 memory_order_relaxed
);
2944 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2945 memory_order_relaxed
);
2946 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2950 update_bgp_group_init(bgp
);
2952 /* assign a unique rd id for auto derivation of vrf's RD */
2953 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2960 /* Return the "default VRF" instance of BGP. */
2961 struct bgp
*bgp_get_default(void)
2964 struct listnode
*node
, *nnode
;
2966 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2967 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2972 /* Lookup BGP entry. */
2973 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2976 struct listnode
*node
, *nnode
;
2978 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2980 && ((bgp
->name
== NULL
&& name
== NULL
)
2981 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2986 /* Lookup BGP structure by view name. */
2987 struct bgp
*bgp_lookup_by_name(const char *name
)
2990 struct listnode
*node
, *nnode
;
2992 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2993 if ((bgp
->name
== NULL
&& name
== NULL
)
2994 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2999 /* Lookup BGP instance based on VRF id. */
3000 /* Note: Only to be used for incoming messages from Zebra. */
3001 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3005 /* Lookup VRF (in tree) and follow link. */
3006 vrf
= vrf_lookup_by_id(vrf_id
);
3009 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3012 /* handle socket creation or deletion, if necessary
3013 * this is called for all new BGP instances
3015 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3020 /* Create BGP server socket, if listen mode not disabled */
3021 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3023 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3025 * suppress vrf socket
3027 if (create
== FALSE
) {
3028 bgp_close_vrf_socket(bgp
);
3032 return BGP_ERR_INVALID_VALUE
;
3034 * if vrf_id did not change
3036 if (vrf
->vrf_id
== old_vrf_id
)
3038 if (old_vrf_id
!= VRF_UNKNOWN
) {
3039 /* look for old socket. close it. */
3040 bgp_close_vrf_socket(bgp
);
3042 /* if backend is not yet identified ( VRF_UNKNOWN) then
3043 * creation will be done later
3045 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3047 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3049 return BGP_ERR_INVALID_VALUE
;
3052 return bgp_check_main_socket(create
, bgp
);
3055 /* Called from VTY commands. */
3056 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3057 enum bgp_instance_type inst_type
)
3060 struct vrf
*vrf
= NULL
;
3062 /* Multiple instance check. */
3063 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3065 bgp
= bgp_lookup_by_name(name
);
3067 bgp
= bgp_get_default();
3069 /* Already exists. */
3071 if (bgp
->as
!= *as
) {
3073 return BGP_ERR_INSTANCE_MISMATCH
;
3075 if (bgp
->inst_type
!= inst_type
)
3076 return BGP_ERR_INSTANCE_MISMATCH
;
3081 /* BGP instance name can not be specified for single instance.
3084 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3086 /* Get default BGP structure if exists. */
3087 bgp
= bgp_get_default();
3090 if (bgp
->as
!= *as
) {
3092 return BGP_ERR_AS_MISMATCH
;
3099 bgp
= bgp_create(as
, name
, inst_type
);
3100 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3101 bgp
->vrf_id
= vrf_generate_id();
3102 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3103 bgp_address_init(bgp
);
3104 bgp_tip_hash_init(bgp
);
3108 bgp
->t_rmap_def_originate_eval
= NULL
;
3110 /* If Default instance or VRF, link to the VRF structure, if present. */
3111 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3112 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3113 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3115 bgp_vrf_link(bgp
, vrf
);
3117 /* BGP server socket already processed if BGP instance
3118 * already part of the list
3120 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3121 listnode_add(bm
->bgp
, bgp
);
3123 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3124 if (BGP_DEBUG(zebra
, ZEBRA
))
3125 zlog_debug("%s: Registering BGP instance %s to zebra",
3126 __PRETTY_FUNCTION__
, name
);
3127 bgp_zebra_instance_register(bgp
);
3134 * Make BGP instance "up". Applies only to VRFs (non-default) and
3135 * implies the VRF has been learnt from Zebra.
3137 void bgp_instance_up(struct bgp
*bgp
)
3140 struct listnode
*node
, *next
;
3142 /* Register with zebra. */
3143 bgp_zebra_instance_register(bgp
);
3145 /* Kick off any peers that may have been configured. */
3146 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3147 if (!BGP_PEER_START_SUPPRESSED(peer
))
3148 BGP_EVENT_ADD(peer
, BGP_Start
);
3151 /* Process any networks that have been configured. */
3152 bgp_static_add(bgp
);
3156 * Make BGP instance "down". Applies only to VRFs (non-default) and
3157 * implies the VRF has been deleted by Zebra.
3159 void bgp_instance_down(struct bgp
*bgp
)
3162 struct listnode
*node
;
3163 struct listnode
*next
;
3166 if (bgp
->t_rmap_def_originate_eval
) {
3167 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3168 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3172 /* Bring down peers, so corresponding routes are purged. */
3173 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3174 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3175 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3176 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3178 bgp_session_reset(peer
);
3181 /* Purge network and redistributed routes. */
3182 bgp_purge_static_redist_routes(bgp
);
3184 /* Cleanup registered nexthops (flags) */
3185 bgp_cleanup_nexthops(bgp
);
3188 /* Delete BGP instance. */
3189 int bgp_delete(struct bgp
*bgp
)
3192 struct peer_group
*group
;
3193 struct listnode
*node
, *next
;
3199 THREAD_OFF(bgp
->t_startup
);
3200 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3201 THREAD_OFF(bgp
->t_update_delay
);
3202 THREAD_OFF(bgp
->t_establish_wait
);
3204 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3205 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3206 zlog_debug("Deleting Default VRF");
3208 zlog_debug("Deleting %s %s",
3209 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3215 /* unmap from RT list */
3216 bgp_evpn_vrf_delete(bgp
);
3219 if (bgp
->t_rmap_def_originate_eval
) {
3220 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3221 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3225 /* Inform peers we're going down. */
3226 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3227 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3228 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3229 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3232 /* Delete static routes (networks). */
3233 bgp_static_delete(bgp
);
3235 /* Unset redistribution. */
3236 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3237 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3238 if (i
!= ZEBRA_ROUTE_BGP
)
3239 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3241 /* Free peers and peer-groups. */
3242 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3243 peer_group_delete(group
);
3245 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3248 if (bgp
->peer_self
) {
3249 peer_delete(bgp
->peer_self
);
3250 bgp
->peer_self
= NULL
;
3253 update_bgp_group_free(bgp
);
3255 /* TODO - Other memory may need to be freed - e.g., NHT */
3260 bgp_cleanup_routes(bgp
);
3262 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3263 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3266 &bgp
->vpn_policy
[afi
]
3267 .import_redirect_rtlist
);
3268 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3271 /* Deregister from Zebra, if needed */
3272 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3273 if (BGP_DEBUG(zebra
, ZEBRA
))
3274 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3275 __PRETTY_FUNCTION__
, bgp
->name
);
3276 bgp_zebra_instance_deregister(bgp
);
3279 /* Remove visibility via the master list - there may however still be
3280 * routes to be processed still referencing the struct bgp.
3282 listnode_delete(bm
->bgp
, bgp
);
3284 /* Free interfaces in this instance. */
3287 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3288 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3290 bgp_vrf_unlink(bgp
, vrf
);
3292 thread_master_free_unused(bm
->master
);
3293 bgp_unlock(bgp
); /* initial reference */
3298 void bgp_free(struct bgp
*bgp
)
3302 struct bgp_table
*table
;
3303 struct bgp_node
*rn
;
3304 struct bgp_rmap
*rmap
;
3308 list_delete(&bgp
->group
);
3309 list_delete(&bgp
->peer
);
3311 if (bgp
->peerhash
) {
3312 hash_free(bgp
->peerhash
);
3313 bgp
->peerhash
= NULL
;
3316 FOREACH_AFI_SAFI (afi
, safi
) {
3317 /* Special handling for 2-level routing tables. */
3318 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3319 || safi
== SAFI_EVPN
) {
3320 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3321 rn
= bgp_route_next(rn
)) {
3322 table
= (struct bgp_table
*)rn
->info
;
3323 bgp_table_finish(&table
);
3326 if (bgp
->route
[afi
][safi
])
3327 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3328 if (bgp
->aggregate
[afi
][safi
])
3329 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3330 if (bgp
->rib
[afi
][safi
])
3331 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3332 rmap
= &bgp
->table_map
[afi
][safi
];
3334 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3337 bgp_scan_finish(bgp
);
3338 bgp_address_destroy(bgp
);
3339 bgp_tip_hash_destroy(bgp
);
3341 /* release the auto RD id */
3342 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3344 bgp_evpn_cleanup(bgp
);
3345 bgp_pbr_cleanup(bgp
);
3347 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3348 vpn_policy_direction_t dir
;
3350 if (bgp
->vpn_policy
[afi
].import_vrf
)
3351 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3352 if (bgp
->vpn_policy
[afi
].export_vrf
)
3353 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3355 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3356 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3357 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3358 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3359 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3360 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3364 XFREE(MTYPE_BGP
, bgp
->name
);
3365 if (bgp
->name_pretty
)
3366 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3368 XFREE(MTYPE_BGP
, bgp
);
3371 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3374 struct listnode
*node
, *nnode
;
3380 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3381 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3382 && !CHECK_FLAG(peer
->sflags
,
3383 PEER_STATUS_ACCEPT_PEER
))
3385 } else if (bm
->bgp
!= NULL
) {
3386 struct listnode
*bgpnode
, *nbgpnode
;
3388 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3389 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3391 && !strcmp(peer
->conf_if
, conf_if
)
3392 && !CHECK_FLAG(peer
->sflags
,
3393 PEER_STATUS_ACCEPT_PEER
))
3399 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3402 struct listnode
*node
, *nnode
;
3408 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3409 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3410 && !CHECK_FLAG(peer
->sflags
,
3411 PEER_STATUS_ACCEPT_PEER
))
3413 } else if (bm
->bgp
!= NULL
) {
3414 struct listnode
*bgpnode
, *nbgpnode
;
3416 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3417 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3419 && !strcmp(peer
->hostname
, hostname
)
3420 && !CHECK_FLAG(peer
->sflags
,
3421 PEER_STATUS_ACCEPT_PEER
))
3427 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3429 struct peer
*peer
= NULL
;
3430 struct peer tmp_peer
;
3432 memset(&tmp_peer
, 0, sizeof(struct peer
));
3435 * We do not want to find the doppelganger peer so search for the peer
3437 * the hash that has PEER_FLAG_CONFIG_NODE
3439 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3444 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3445 } else if (bm
->bgp
!= NULL
) {
3446 struct listnode
*bgpnode
, *nbgpnode
;
3448 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3449 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3458 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3459 union sockunion
*su
,
3460 struct peer_group
*group
)
3466 /* Create peer first; we've already checked group config is valid. */
3467 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3468 group
->conf
->as_type
, 0, 0, group
);
3473 peer
= peer_lock(peer
);
3474 listnode_add(group
->peer
, peer
);
3476 peer_group2peer_config_copy(group
, peer
);
3479 * Bind peer for all AFs configured for the group. We don't call
3480 * peer_group_bind as that is sub-optimal and does some stuff we don't
3483 FOREACH_AFI_SAFI (afi
, safi
) {
3484 if (!group
->conf
->afc
[afi
][safi
])
3486 peer
->afc
[afi
][safi
] = 1;
3488 if (!peer_af_find(peer
, afi
, safi
))
3489 peer_af_create(peer
, afi
, safi
);
3491 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3494 /* Mark as dynamic, but also as a "config node" for other things to
3496 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3497 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3503 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3504 struct prefix
*prefix
)
3506 struct listnode
*node
, *nnode
;
3507 struct prefix
*range
;
3510 afi
= family2afi(prefix
->family
);
3512 if (group
->listen_range
[afi
])
3513 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3515 if (prefix_match(range
, prefix
))
3522 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3523 struct prefix
**listen_range
)
3525 struct prefix
*range
= NULL
;
3526 struct peer_group
*group
= NULL
;
3527 struct listnode
*node
, *nnode
;
3529 *listen_range
= NULL
;
3531 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3532 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3535 } else if (bm
->bgp
!= NULL
) {
3536 struct listnode
*bgpnode
, *nbgpnode
;
3538 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3539 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3540 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3546 *listen_range
= range
;
3547 return (group
&& range
) ? group
: NULL
;
3550 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3552 struct peer_group
*group
;
3555 struct prefix prefix
;
3556 struct prefix
*listen_range
;
3558 char buf
[PREFIX2STR_BUFFER
];
3559 char buf1
[PREFIX2STR_BUFFER
];
3561 sockunion2hostprefix(su
, &prefix
);
3563 /* See if incoming connection matches a configured listen range. */
3564 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3575 prefix2str(&prefix
, buf
, sizeof(buf
));
3576 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3578 if (bgp_debug_neighbor_events(NULL
))
3580 "Dynamic Neighbor %s matches group %s listen range %s",
3581 buf
, group
->name
, buf1
);
3583 /* Are we within the listen limit? */
3584 dncount
= gbgp
->dynamic_neighbors_count
;
3586 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3587 if (bgp_debug_neighbor_events(NULL
))
3588 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3589 inet_sutop(su
, buf
),
3590 gbgp
->dynamic_neighbors_limit
);
3594 /* Ensure group is not disabled. */
3595 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3596 if (bgp_debug_neighbor_events(NULL
))
3598 "Dynamic Neighbor %s rejected - group %s disabled",
3603 /* Check that at least one AF is activated for the group. */
3604 if (!peer_group_af_configured(group
)) {
3605 if (bgp_debug_neighbor_events(NULL
))
3607 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3612 /* Create dynamic peer and bind to associated group. */
3613 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3616 gbgp
->dynamic_neighbors_count
= ++dncount
;
3618 if (bgp_debug_neighbor_events(peer
))
3619 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3620 peer
->host
, group
->name
, dncount
);
3625 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3628 if (peer
->group
->bgp
) {
3629 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3631 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3633 if (bgp_debug_neighbor_events(peer
))
3634 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3635 peer
->group
->name
, dncount
);
3638 /* If peer is configured at least one address family return 1. */
3639 int peer_active(struct peer
*peer
)
3641 if (BGP_PEER_SU_UNSPEC(peer
))
3643 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3644 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3645 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3646 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3647 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3648 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3649 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3650 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3651 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3652 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3653 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3658 /* If peer is negotiated at least one address family return 1. */
3659 int peer_active_nego(struct peer
*peer
)
3661 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3662 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3663 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3664 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3665 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3666 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3667 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3668 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3669 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3670 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3671 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3672 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3673 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3678 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3679 enum peer_change_type type
)
3681 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3684 if (peer
->status
!= Established
)
3687 if (type
== peer_change_reset
) {
3688 /* If we're resetting session, we've to delete both peer struct
3690 if ((peer
->doppelganger
)
3691 && (peer
->doppelganger
->status
!= Deleted
)
3692 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3693 PEER_FLAG_CONFIG_NODE
)))
3694 peer_delete(peer
->doppelganger
);
3696 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3697 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3698 } else if (type
== peer_change_reset_in
) {
3699 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3700 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3701 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3703 if ((peer
->doppelganger
)
3704 && (peer
->doppelganger
->status
!= Deleted
)
3705 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3706 PEER_FLAG_CONFIG_NODE
)))
3707 peer_delete(peer
->doppelganger
);
3709 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3710 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3712 } else if (type
== peer_change_reset_out
) {
3713 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3714 bgp_announce_route(peer
, afi
, safi
);
3718 struct peer_flag_action
{
3722 /* This flag can be set for peer-group member. */
3723 uint8_t not_for_member
;
3725 /* Action when the flag is changed. */
3726 enum peer_change_type type
;
3729 static const struct peer_flag_action peer_flag_action_list
[] = {
3730 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3731 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3732 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3733 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3734 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3735 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3736 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3737 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3738 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3739 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3740 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3741 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3742 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3743 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3744 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3745 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3746 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3749 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3750 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3751 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3752 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3753 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3754 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3755 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3756 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3757 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3758 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3759 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3760 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3761 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3762 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3763 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3764 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3765 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3766 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3767 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3768 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3769 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3770 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3771 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3772 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3773 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3774 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3777 /* Proper action set. */
3778 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3779 int size
, struct peer_flag_action
*action
,
3786 const struct peer_flag_action
*match
= NULL
;
3788 /* Check peer's frag action. */
3789 for (i
= 0; i
< size
; i
++) {
3790 match
= &action_list
[i
];
3792 if (match
->flag
== 0)
3795 if (match
->flag
& flag
) {
3798 if (match
->type
== peer_change_reset_in
)
3800 if (match
->type
== peer_change_reset_out
)
3802 if (match
->type
== peer_change_reset
) {
3806 if (match
->not_for_member
)
3807 action
->not_for_member
= 1;
3811 /* Set peer clear type. */
3812 if (reset_in
&& reset_out
)
3813 action
->type
= peer_change_reset
;
3815 action
->type
= peer_change_reset_in
;
3817 action
->type
= peer_change_reset_out
;
3819 action
->type
= peer_change_none
;
3824 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3826 if (flag
== PEER_FLAG_SHUTDOWN
) {
3827 if (CHECK_FLAG(peer
->flags
, flag
)) {
3828 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3829 peer_nsf_stop(peer
);
3831 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3832 if (peer
->t_pmax_restart
) {
3833 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3834 if (bgp_debug_neighbor_events(peer
))
3836 "%s Maximum-prefix restart timer canceled",
3840 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3841 peer_nsf_stop(peer
);
3843 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3844 char *msg
= peer
->tx_shutdown_message
;
3847 if (!msg
&& peer_group_active(peer
))
3848 msg
= peer
->group
->conf
3849 ->tx_shutdown_message
;
3850 msglen
= msg
? strlen(msg
) : 0;
3855 uint8_t msgbuf
[129];
3858 memcpy(msgbuf
+ 1, msg
, msglen
);
3860 bgp_notify_send_with_data(
3861 peer
, BGP_NOTIFY_CEASE
,
3862 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3863 msgbuf
, msglen
+ 1);
3866 peer
, BGP_NOTIFY_CEASE
,
3867 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3869 bgp_session_reset(peer
);
3871 peer
->v_start
= BGP_INIT_START_TIMER
;
3872 BGP_EVENT_ADD(peer
, BGP_Stop
);
3874 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3875 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3876 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3877 else if (flag
== PEER_FLAG_PASSIVE
)
3878 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3879 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3880 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3882 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3883 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3885 bgp_session_reset(peer
);
3888 /* Change specified peer flag. */
3889 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3893 bool invert
, member_invert
;
3894 struct peer
*member
;
3895 struct listnode
*node
, *nnode
;
3896 struct peer_flag_action action
;
3898 memset(&action
, 0, sizeof(struct peer_flag_action
));
3899 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3901 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3902 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3905 /* Abort if no flag action exists. */
3907 return BGP_ERR_INVALID_FLAG
;
3909 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3910 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3911 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3912 return BGP_ERR_PEER_FLAG_CONFLICT
;
3914 /* Handle flag updates where desired state matches current state. */
3915 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3916 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3917 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3921 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3922 COND_FLAG(peer
->flags_override
, flag
, invert
);
3927 /* Inherit from peer-group or set/unset flags accordingly. */
3928 if (peer_group_active(peer
) && set
== invert
)
3929 peer_flag_inherit(peer
, flag
);
3931 COND_FLAG(peer
->flags
, flag
, set
);
3933 /* Check if handling a regular peer. */
3934 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3935 /* Update flag override state accordingly. */
3936 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3938 /* Execute flag action on peer. */
3939 if (action
.type
== peer_change_reset
)
3940 peer_flag_modify_action(peer
, flag
);
3942 /* Skip peer-group mechanics for regular peers. */
3946 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3947 bgp_nht_register_enhe_capability_interfaces(peer
);
3950 * Update peer-group members, unless they are explicitely overriding
3951 * peer-group configuration.
3953 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3954 /* Skip peers with overridden configuration. */
3955 if (CHECK_FLAG(member
->flags_override
, flag
))
3958 /* Check if only member without group is inverted. */
3960 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3962 /* Skip peers with equivalent configuration. */
3963 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3966 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3969 /* Update flag on peer-group member. */
3970 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3972 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3973 bgp_nht_register_enhe_capability_interfaces(member
);
3975 /* Execute flag action on peer-group member. */
3976 if (action
.type
== peer_change_reset
)
3977 peer_flag_modify_action(member
, flag
);
3983 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3985 return peer_flag_modify(peer
, flag
, 1);
3988 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3990 return peer_flag_modify(peer
, flag
, 0);
3993 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3994 uint32_t flag
, bool set
)
3998 bool invert
, member_invert
;
3999 struct peer
*member
;
4000 struct listnode
*node
, *nnode
;
4001 struct peer_flag_action action
;
4003 memset(&action
, 0, sizeof(struct peer_flag_action
));
4004 size
= sizeof peer_af_flag_action_list
4005 / sizeof(struct peer_flag_action
);
4007 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4008 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4011 /* Abort if flag action exists. */
4013 return BGP_ERR_INVALID_FLAG
;
4015 /* Special check for reflector client. */
4016 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4017 && peer_sort(peer
) != BGP_PEER_IBGP
)
4018 return BGP_ERR_NOT_INTERNAL_PEER
;
4020 /* Special check for remove-private-AS. */
4021 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4022 && peer_sort(peer
) == BGP_PEER_IBGP
)
4023 return BGP_ERR_REMOVE_PRIVATE_AS
;
4025 /* as-override is not allowed for IBGP peers */
4026 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4027 return BGP_ERR_AS_OVERRIDE
;
4029 /* Handle flag updates where desired state matches current state. */
4030 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4031 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4032 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4037 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4038 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4045 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4046 * if we are setting/unsetting flags which conflict with this flag
4047 * handle accordingly
4049 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4053 * if we are setting NEXTHOP_SELF, we need to unset the
4054 * NEXTHOP_UNCHANGED flag
4056 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4057 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4058 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4059 PEER_FLAG_NEXTHOP_UNCHANGED
);
4063 * if we are unsetting NEXTHOP_SELF, we need to set the
4064 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4066 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4067 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4068 SET_FLAG(peer
->af_flags
[afi
][safi
],
4069 PEER_FLAG_NEXTHOP_UNCHANGED
);
4073 /* Inherit from peer-group or set/unset flags accordingly. */
4074 if (peer_group_active(peer
) && set
== invert
)
4075 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4077 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4079 /* Execute action when peer is established. */
4080 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4081 && peer
->status
== Established
) {
4082 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4083 bgp_clear_adj_in(peer
, afi
, safi
);
4085 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4086 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4087 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4088 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4089 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4090 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4091 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4092 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4094 peer_change_action(peer
, afi
, safi
, action
.type
);
4098 /* Check if handling a regular peer. */
4099 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4100 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4104 * Update peer-group members, unless they are explicitely
4105 * overriding peer-group configuration.
4107 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4109 /* Skip peers with overridden configuration. */
4110 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4114 /* Check if only member without group is inverted. */
4116 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4120 /* Skip peers with equivalent configuration. */
4121 if (set
!= member_invert
4122 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4125 if (set
== member_invert
4126 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4129 /* Update flag on peer-group member. */
4130 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4131 set
!= member_invert
);
4133 /* Execute flag action on peer-group member. */
4134 if (member
->status
== Established
) {
4135 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4136 bgp_clear_adj_in(member
, afi
, safi
);
4138 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4139 member
->last_reset
=
4140 PEER_DOWN_RR_CLIENT_CHANGE
;
4142 == PEER_FLAG_RSERVER_CLIENT
)
4143 member
->last_reset
=
4144 PEER_DOWN_RS_CLIENT_CHANGE
;
4146 == PEER_FLAG_ORF_PREFIX_SM
)
4147 member
->last_reset
=
4148 PEER_DOWN_CAPABILITY_CHANGE
;
4150 == PEER_FLAG_ORF_PREFIX_RM
)
4151 member
->last_reset
=
4152 PEER_DOWN_CAPABILITY_CHANGE
;
4154 peer_change_action(member
, afi
, safi
,
4164 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4166 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4169 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4171 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4175 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4177 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4178 peer
->tx_shutdown_message
=
4179 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4183 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4185 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4190 /* EBGP multihop configuration. */
4191 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4193 struct peer_group
*group
;
4194 struct listnode
*node
, *nnode
;
4197 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4200 /* see comment in peer_ttl_security_hops_set() */
4201 if (ttl
!= MAXTTL
) {
4202 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4203 group
= peer
->group
;
4204 if (group
->conf
->gtsm_hops
!= 0)
4205 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4207 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4209 if (peer1
->sort
== BGP_PEER_IBGP
)
4212 if (peer1
->gtsm_hops
!= 0)
4213 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4216 if (peer
->gtsm_hops
!= 0)
4217 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4223 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4224 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4225 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4226 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4227 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4229 bgp_session_reset(peer
);
4232 group
= peer
->group
;
4233 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4234 if (peer
->sort
== BGP_PEER_IBGP
)
4237 peer
->ttl
= group
->conf
->ttl
;
4239 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4240 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4241 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4243 bgp_session_reset(peer
);
4249 int peer_ebgp_multihop_unset(struct peer
*peer
)
4251 struct peer_group
*group
;
4252 struct listnode
*node
, *nnode
;
4254 if (peer
->sort
== BGP_PEER_IBGP
)
4257 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4258 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4260 if (peer_group_active(peer
))
4261 peer
->ttl
= peer
->group
->conf
->ttl
;
4265 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4266 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4267 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4268 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4270 bgp_session_reset(peer
);
4272 group
= peer
->group
;
4273 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4274 if (peer
->sort
== BGP_PEER_IBGP
)
4279 if (peer
->fd
>= 0) {
4280 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4282 peer
, BGP_NOTIFY_CEASE
,
4283 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4285 bgp_session_reset(peer
);
4292 /* Neighbor description. */
4293 int peer_description_set(struct peer
*peer
, const char *desc
)
4296 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4298 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4303 int peer_description_unset(struct peer
*peer
)
4306 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4313 /* Neighbor update-source. */
4314 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4316 struct peer
*member
;
4317 struct listnode
*node
, *nnode
;
4319 /* Set flag and configuration on peer. */
4320 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4321 if (peer
->update_if
) {
4322 if (strcmp(peer
->update_if
, ifname
) == 0)
4324 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4326 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4327 sockunion_free(peer
->update_source
);
4328 peer
->update_source
= NULL
;
4330 /* Check if handling a regular peer. */
4331 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4332 /* Send notification or reset peer depending on state. */
4333 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4334 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4335 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4336 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4338 bgp_session_reset(peer
);
4340 /* Skip peer-group mechanics for regular peers. */
4345 * Set flag and configuration on all peer-group members, unless they are
4346 * explicitely overriding peer-group configuration.
4348 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4349 /* Skip peers with overridden configuration. */
4350 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4353 /* Skip peers with the same configuration. */
4354 if (member
->update_if
) {
4355 if (strcmp(member
->update_if
, ifname
) == 0)
4357 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4360 /* Set flag and configuration on peer-group member. */
4361 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4362 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4363 sockunion_free(member
->update_source
);
4364 member
->update_source
= NULL
;
4366 /* Send notification or reset peer depending on state. */
4367 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4368 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4369 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4370 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4372 bgp_session_reset(member
);
4378 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4380 struct peer
*member
;
4381 struct listnode
*node
, *nnode
;
4383 /* Set flag and configuration on peer. */
4384 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4385 if (peer
->update_source
) {
4386 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4388 sockunion_free(peer
->update_source
);
4390 peer
->update_source
= sockunion_dup(su
);
4391 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4393 /* Check if handling a regular peer. */
4394 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4395 /* Send notification or reset peer depending on state. */
4396 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4397 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4398 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4399 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4401 bgp_session_reset(peer
);
4403 /* Skip peer-group mechanics for regular peers. */
4408 * Set flag and configuration on all peer-group members, unless they are
4409 * explicitely overriding peer-group configuration.
4411 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4412 /* Skip peers with overridden configuration. */
4413 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4416 /* Skip peers with the same configuration. */
4417 if (member
->update_source
) {
4418 if (sockunion_cmp(member
->update_source
, su
) == 0)
4420 sockunion_free(member
->update_source
);
4423 /* Set flag and configuration on peer-group member. */
4424 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4425 member
->update_source
= sockunion_dup(su
);
4426 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4428 /* Send notification or reset peer depending on state. */
4429 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4430 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4431 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4432 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4434 bgp_session_reset(member
);
4440 int peer_update_source_unset(struct peer
*peer
)
4442 struct peer
*member
;
4443 struct listnode
*node
, *nnode
;
4445 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4448 /* Inherit configuration from peer-group if peer is member. */
4449 if (peer_group_active(peer
)) {
4450 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4451 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4452 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4453 MTYPE_PEER_UPDATE_SOURCE
);
4455 /* Otherwise remove flag and configuration from peer. */
4456 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4457 sockunion_free(peer
->update_source
);
4458 peer
->update_source
= NULL
;
4459 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4462 /* Check if handling a regular peer. */
4463 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4464 /* Send notification or reset peer depending on state. */
4465 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4466 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4467 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4468 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4470 bgp_session_reset(peer
);
4472 /* Skip peer-group mechanics for regular peers. */
4477 * Set flag and configuration on all peer-group members, unless they are
4478 * explicitely overriding peer-group configuration.
4480 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4481 /* Skip peers with overridden configuration. */
4482 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4485 /* Skip peers with the same configuration. */
4486 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4487 && !member
->update_source
&& !member
->update_if
)
4490 /* Remove flag and configuration on peer-group member. */
4491 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4492 sockunion_free(member
->update_source
);
4493 member
->update_source
= NULL
;
4494 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4496 /* Send notification or reset peer depending on state. */
4497 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4498 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4499 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4500 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4502 bgp_session_reset(member
);
4508 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4509 const char *rmap
, struct route_map
*route_map
)
4511 struct peer
*member
;
4512 struct listnode
*node
, *nnode
;
4514 /* Set flag and configuration on peer. */
4515 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4517 if (!peer
->default_rmap
[afi
][safi
].name
4518 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4519 if (peer
->default_rmap
[afi
][safi
].name
)
4520 XFREE(MTYPE_ROUTE_MAP_NAME
,
4521 peer
->default_rmap
[afi
][safi
].name
);
4523 peer
->default_rmap
[afi
][safi
].name
=
4524 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4525 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4528 if (peer
->default_rmap
[afi
][safi
].name
)
4529 XFREE(MTYPE_ROUTE_MAP_NAME
,
4530 peer
->default_rmap
[afi
][safi
].name
);
4532 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4533 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4536 /* Check if handling a regular peer. */
4537 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4538 /* Update peer route announcements. */
4539 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4540 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4541 bgp_default_originate(peer
, afi
, safi
, 0);
4542 bgp_announce_route(peer
, afi
, safi
);
4545 /* Skip peer-group mechanics for regular peers. */
4550 * Set flag and configuration on all peer-group members, unless they are
4551 * explicitely overriding peer-group configuration.
4553 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4554 /* Skip peers with overridden configuration. */
4555 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4556 PEER_FLAG_DEFAULT_ORIGINATE
))
4559 /* Set flag and configuration on peer-group member. */
4560 SET_FLAG(member
->af_flags
[afi
][safi
],
4561 PEER_FLAG_DEFAULT_ORIGINATE
);
4563 if (member
->default_rmap
[afi
][safi
].name
)
4564 XFREE(MTYPE_ROUTE_MAP_NAME
,
4565 member
->default_rmap
[afi
][safi
].name
);
4567 member
->default_rmap
[afi
][safi
].name
=
4568 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4569 member
->default_rmap
[afi
][safi
].map
= route_map
;
4572 /* Update peer route announcements. */
4573 if (member
->status
== Established
4574 && member
->afc_nego
[afi
][safi
]) {
4575 update_group_adjust_peer(
4576 peer_af_find(member
, afi
, safi
));
4577 bgp_default_originate(member
, afi
, safi
, 0);
4578 bgp_announce_route(member
, afi
, safi
);
4585 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4587 struct peer
*member
;
4588 struct listnode
*node
, *nnode
;
4590 /* Inherit configuration from peer-group if peer is member. */
4591 if (peer_group_active(peer
)) {
4592 peer_af_flag_inherit(peer
, afi
, safi
,
4593 PEER_FLAG_DEFAULT_ORIGINATE
);
4594 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4595 default_rmap
[afi
][safi
].name
,
4596 MTYPE_ROUTE_MAP_NAME
);
4597 PEER_ATTR_INHERIT(peer
, peer
->group
,
4598 default_rmap
[afi
][safi
].map
);
4600 /* Otherwise remove flag and configuration from peer. */
4601 peer_af_flag_unset(peer
, afi
, safi
,
4602 PEER_FLAG_DEFAULT_ORIGINATE
);
4603 if (peer
->default_rmap
[afi
][safi
].name
)
4604 XFREE(MTYPE_ROUTE_MAP_NAME
,
4605 peer
->default_rmap
[afi
][safi
].name
);
4606 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4607 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4610 /* Check if handling a regular peer. */
4611 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4612 /* Update peer route announcements. */
4613 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4614 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4615 bgp_default_originate(peer
, afi
, safi
, 1);
4616 bgp_announce_route(peer
, afi
, safi
);
4619 /* Skip peer-group mechanics for regular peers. */
4624 * Remove flag and configuration from all peer-group members, unless
4625 * they are explicitely overriding peer-group configuration.
4627 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4628 /* Skip peers with overridden configuration. */
4629 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4630 PEER_FLAG_DEFAULT_ORIGINATE
))
4633 /* Remove flag and configuration on peer-group member. */
4634 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4635 PEER_FLAG_DEFAULT_ORIGINATE
);
4636 if (peer
->default_rmap
[afi
][safi
].name
)
4637 XFREE(MTYPE_ROUTE_MAP_NAME
,
4638 peer
->default_rmap
[afi
][safi
].name
);
4639 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4640 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4642 /* Update peer route announcements. */
4643 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4644 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4645 bgp_default_originate(peer
, afi
, safi
, 1);
4646 bgp_announce_route(peer
, afi
, safi
);
4653 int peer_port_set(struct peer
*peer
, uint16_t port
)
4659 int peer_port_unset(struct peer
*peer
)
4661 peer
->port
= BGP_PORT_DEFAULT
;
4666 * Helper function that is called after the name of the policy
4667 * being used by a peer has changed (AF specific). Automatically
4668 * initiates inbound or outbound processing as needed.
4670 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4674 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4675 if (peer
->status
== Established
)
4676 bgp_announce_route(peer
, afi
, safi
);
4678 if (peer
->status
!= Established
)
4681 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4682 PEER_FLAG_SOFT_RECONFIG
))
4683 bgp_soft_reconfig_in(peer
, afi
, safi
);
4684 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4685 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4686 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4691 /* neighbor weight. */
4692 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4694 struct peer
*member
;
4695 struct listnode
*node
, *nnode
;
4697 /* Set flag and configuration on peer. */
4698 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4699 if (peer
->weight
[afi
][safi
] != weight
) {
4700 peer
->weight
[afi
][safi
] = weight
;
4701 peer_on_policy_change(peer
, afi
, safi
, 0);
4704 /* Skip peer-group mechanics for regular peers. */
4705 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4709 * Set flag and configuration on all peer-group members, unless they are
4710 * explicitely overriding peer-group configuration.
4712 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4713 /* Skip peers with overridden configuration. */
4714 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4718 /* Set flag and configuration on peer-group member. */
4719 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4720 if (member
->weight
[afi
][safi
] != weight
) {
4721 member
->weight
[afi
][safi
] = weight
;
4722 peer_on_policy_change(member
, afi
, safi
, 0);
4729 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4731 struct peer
*member
;
4732 struct listnode
*node
, *nnode
;
4734 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4737 /* Inherit configuration from peer-group if peer is member. */
4738 if (peer_group_active(peer
)) {
4739 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4740 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4742 peer_on_policy_change(peer
, afi
, safi
, 0);
4746 /* Remove flag and configuration from peer. */
4747 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4748 peer
->weight
[afi
][safi
] = 0;
4749 peer_on_policy_change(peer
, afi
, safi
, 0);
4751 /* Skip peer-group mechanics for regular peers. */
4752 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4756 * Remove flag and configuration from all peer-group members, unless
4757 * they are explicitely overriding peer-group configuration.
4759 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4760 /* Skip peers with overridden configuration. */
4761 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4765 /* Skip peers where flag is already disabled. */
4766 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4769 /* Remove flag and configuration on peer-group member. */
4770 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4771 member
->weight
[afi
][safi
] = 0;
4772 peer_on_policy_change(member
, afi
, safi
, 0);
4778 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4780 struct peer
*member
;
4781 struct listnode
*node
, *nnode
;
4783 if (keepalive
> 65535)
4784 return BGP_ERR_INVALID_VALUE
;
4786 if (holdtime
> 65535)
4787 return BGP_ERR_INVALID_VALUE
;
4789 if (holdtime
< 3 && holdtime
!= 0)
4790 return BGP_ERR_INVALID_VALUE
;
4792 /* Set flag and configuration on peer. */
4793 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4794 peer
->holdtime
= holdtime
;
4795 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4797 /* Skip peer-group mechanics for regular peers. */
4798 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4802 * Set flag and configuration on all peer-group members, unless they are
4803 * explicitely overriding peer-group configuration.
4805 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4806 /* Skip peers with overridden configuration. */
4807 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4810 /* Set flag and configuration on peer-group member. */
4811 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4812 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4813 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4819 int peer_timers_unset(struct peer
*peer
)
4821 struct peer
*member
;
4822 struct listnode
*node
, *nnode
;
4824 /* Inherit configuration from peer-group if peer is member. */
4825 if (peer_group_active(peer
)) {
4826 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4827 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4828 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4830 /* Otherwise remove flag and configuration from peer. */
4831 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4833 peer
->keepalive
= 0;
4836 /* Skip peer-group mechanics for regular peers. */
4837 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4841 * Remove flag and configuration from all peer-group members, unless
4842 * they are explicitely overriding peer-group configuration.
4844 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4845 /* Skip peers with overridden configuration. */
4846 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4849 /* Remove flag and configuration on peer-group member. */
4850 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4851 member
->holdtime
= 0;
4852 member
->keepalive
= 0;
4858 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4860 struct peer
*member
;
4861 struct listnode
*node
, *nnode
;
4863 if (connect
> 65535)
4864 return BGP_ERR_INVALID_VALUE
;
4866 /* Set flag and configuration on peer. */
4867 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4868 peer
->connect
= connect
;
4869 peer
->v_connect
= connect
;
4871 /* Skip peer-group mechanics for regular peers. */
4872 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4876 * Set flag and configuration on all peer-group members, unless they are
4877 * explicitely overriding peer-group configuration.
4879 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4880 /* Skip peers with overridden configuration. */
4881 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4884 /* Set flag and configuration on peer-group member. */
4885 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4886 member
->connect
= connect
;
4887 member
->v_connect
= connect
;
4893 int peer_timers_connect_unset(struct peer
*peer
)
4895 struct peer
*member
;
4896 struct listnode
*node
, *nnode
;
4898 /* Inherit configuration from peer-group if peer is member. */
4899 if (peer_group_active(peer
)) {
4900 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4901 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4903 /* Otherwise remove flag and configuration from peer. */
4904 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4908 /* Set timer with fallback to default value. */
4910 peer
->v_connect
= peer
->connect
;
4912 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4914 /* Skip peer-group mechanics for regular peers. */
4915 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4919 * Remove flag and configuration from all peer-group members, unless
4920 * they are explicitely overriding peer-group configuration.
4922 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4923 /* Skip peers with overridden configuration. */
4924 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4927 /* Remove flag and configuration on peer-group member. */
4928 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4929 member
->connect
= 0;
4930 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4936 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4938 struct peer
*member
;
4939 struct listnode
*node
, *nnode
;
4942 return BGP_ERR_INVALID_VALUE
;
4944 /* Set flag and configuration on peer. */
4945 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4946 peer
->routeadv
= routeadv
;
4947 peer
->v_routeadv
= routeadv
;
4949 /* Check if handling a regular peer. */
4950 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4951 /* Update peer route announcements. */
4952 update_group_adjust_peer_afs(peer
);
4953 if (peer
->status
== Established
)
4954 bgp_announce_route_all(peer
);
4956 /* Skip peer-group mechanics for regular peers. */
4961 * Set flag and configuration on all peer-group members, unless they are
4962 * explicitely overriding peer-group configuration.
4964 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4965 /* Skip peers with overridden configuration. */
4966 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4969 /* Set flag and configuration on peer-group member. */
4970 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4971 member
->routeadv
= routeadv
;
4972 member
->v_routeadv
= routeadv
;
4974 /* Update peer route announcements. */
4975 update_group_adjust_peer_afs(member
);
4976 if (member
->status
== Established
)
4977 bgp_announce_route_all(member
);
4983 int peer_advertise_interval_unset(struct peer
*peer
)
4985 struct peer
*member
;
4986 struct listnode
*node
, *nnode
;
4988 /* Inherit configuration from peer-group if peer is member. */
4989 if (peer_group_active(peer
)) {
4990 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4991 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4993 /* Otherwise remove flag and configuration from peer. */
4994 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
4998 /* Set timer with fallback to default value. */
5000 peer
->v_routeadv
= peer
->routeadv
;
5002 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5003 ? BGP_DEFAULT_IBGP_ROUTEADV
5004 : BGP_DEFAULT_EBGP_ROUTEADV
;
5006 /* Check if handling a regular peer. */
5007 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5008 /* Update peer route announcements. */
5009 update_group_adjust_peer_afs(peer
);
5010 if (peer
->status
== Established
)
5011 bgp_announce_route_all(peer
);
5013 /* Skip peer-group mechanics for regular peers. */
5018 * Remove flag and configuration from all peer-group members, unless
5019 * they are explicitely overriding peer-group configuration.
5021 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5022 /* Skip peers with overridden configuration. */
5023 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5026 /* Remove flag and configuration on peer-group member. */
5027 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5028 member
->routeadv
= 0;
5029 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5030 ? BGP_DEFAULT_IBGP_ROUTEADV
5031 : BGP_DEFAULT_EBGP_ROUTEADV
;
5033 /* Update peer route announcements. */
5034 update_group_adjust_peer_afs(member
);
5035 if (member
->status
== Established
)
5036 bgp_announce_route_all(member
);
5042 /* neighbor interface */
5043 void peer_interface_set(struct peer
*peer
, const char *str
)
5046 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5047 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5050 void peer_interface_unset(struct peer
*peer
)
5053 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5054 peer
->ifname
= NULL
;
5058 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5059 int allow_num
, int origin
)
5061 struct peer
*member
;
5062 struct listnode
*node
, *nnode
;
5064 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5065 return BGP_ERR_INVALID_VALUE
;
5067 /* Set flag and configuration on peer. */
5068 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5070 if (peer
->allowas_in
[afi
][safi
] != 0
5071 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5072 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5073 peer_af_flag_set(peer
, afi
, safi
,
5074 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5075 peer
->allowas_in
[afi
][safi
] = 0;
5076 peer_on_policy_change(peer
, afi
, safi
, 0);
5079 if (peer
->allowas_in
[afi
][safi
] != allow_num
5080 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5081 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5083 peer_af_flag_unset(peer
, afi
, safi
,
5084 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5085 peer
->allowas_in
[afi
][safi
] = allow_num
;
5086 peer_on_policy_change(peer
, afi
, safi
, 0);
5090 /* Skip peer-group mechanics for regular peers. */
5091 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5095 * Set flag and configuration on all peer-group members, unless
5096 * they are explicitely overriding peer-group configuration.
5098 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5099 /* Skip peers with overridden configuration. */
5100 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5101 PEER_FLAG_ALLOWAS_IN
))
5104 /* Set flag and configuration on peer-group member. */
5105 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5107 if (member
->allowas_in
[afi
][safi
] != 0
5108 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5109 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5110 SET_FLAG(member
->af_flags
[afi
][safi
],
5111 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5112 member
->allowas_in
[afi
][safi
] = 0;
5113 peer_on_policy_change(peer
, afi
, safi
, 0);
5116 if (member
->allowas_in
[afi
][safi
] != allow_num
5117 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5118 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5119 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5120 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5121 member
->allowas_in
[afi
][safi
] = allow_num
;
5122 peer_on_policy_change(peer
, afi
, safi
, 0);
5130 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5132 struct peer
*member
;
5133 struct listnode
*node
, *nnode
;
5135 /* Skip peer if flag is already disabled. */
5136 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5139 /* Inherit configuration from peer-group if peer is member. */
5140 if (peer_group_active(peer
)) {
5141 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5142 peer_af_flag_inherit(peer
, afi
, safi
,
5143 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5144 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5145 peer_on_policy_change(peer
, afi
, safi
, 0);
5150 /* Remove flag and configuration from peer. */
5151 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5152 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5153 peer
->allowas_in
[afi
][safi
] = 0;
5154 peer_on_policy_change(peer
, afi
, safi
, 0);
5156 /* Skip peer-group mechanics if handling a regular peer. */
5157 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5161 * Remove flags and configuration from all peer-group members, unless
5162 * they are explicitely overriding peer-group configuration.
5164 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5165 /* Skip peers with overridden configuration. */
5166 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5167 PEER_FLAG_ALLOWAS_IN
))
5170 /* Skip peers where flag is already disabled. */
5171 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5172 PEER_FLAG_ALLOWAS_IN
))
5175 /* Remove flags and configuration on peer-group member. */
5176 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5177 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5178 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5179 member
->allowas_in
[afi
][safi
] = 0;
5180 peer_on_policy_change(member
, afi
, safi
, 0);
5186 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5189 bool old_no_prepend
, old_replace_as
;
5190 struct bgp
*bgp
= peer
->bgp
;
5191 struct peer
*member
;
5192 struct listnode
*node
, *nnode
;
5194 if (peer_sort(peer
) != BGP_PEER_EBGP
5195 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5196 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5199 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5202 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5204 /* Save previous flag states. */
5206 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5208 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5210 /* Set flag and configuration on peer. */
5211 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5212 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5213 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5215 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5216 && old_replace_as
== replace_as
)
5218 peer
->change_local_as
= as
;
5220 /* Check if handling a regular peer. */
5221 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5222 /* Send notification or reset peer depending on state. */
5223 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5224 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5225 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5226 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5228 bgp_session_reset(peer
);
5230 /* Skip peer-group mechanics for regular peers. */
5235 * Set flag and configuration on all peer-group members, unless they are
5236 * explicitely overriding peer-group configuration.
5238 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5239 /* Skip peers with overridden configuration. */
5240 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5243 /* Skip peers with the same configuration. */
5244 old_no_prepend
= CHECK_FLAG(member
->flags
,
5245 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5246 old_replace_as
= CHECK_FLAG(member
->flags
,
5247 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5248 if (member
->change_local_as
== as
5249 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5250 && old_no_prepend
== no_prepend
5251 && old_replace_as
== replace_as
)
5254 /* Set flag and configuration on peer-group member. */
5255 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5256 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5258 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5260 member
->change_local_as
= as
;
5262 /* Send notification or stop peer depending on state. */
5263 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5264 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5265 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5266 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5268 BGP_EVENT_ADD(member
, BGP_Stop
);
5274 int peer_local_as_unset(struct peer
*peer
)
5276 struct peer
*member
;
5277 struct listnode
*node
, *nnode
;
5279 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5282 /* Inherit configuration from peer-group if peer is member. */
5283 if (peer_group_active(peer
)) {
5284 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5285 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5286 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5287 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5289 /* Otherwise remove flag and configuration from peer. */
5290 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5291 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5292 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5293 peer
->change_local_as
= 0;
5296 /* Check if handling a regular peer. */
5297 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5298 /* Send notification or stop peer depending on state. */
5299 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5300 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5301 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5302 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5304 BGP_EVENT_ADD(peer
, BGP_Stop
);
5306 /* Skip peer-group mechanics for regular peers. */
5311 * Remove flag and configuration from all peer-group members, unless
5312 * they are explicitely overriding peer-group configuration.
5314 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5315 /* Skip peers with overridden configuration. */
5316 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5319 /* Remove flag and configuration on peer-group member. */
5320 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5321 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5322 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5323 member
->change_local_as
= 0;
5325 /* Send notification or stop peer depending on state. */
5326 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5327 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5328 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5329 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5331 bgp_session_reset(member
);
5337 /* Set password for authenticating with the peer. */
5338 int peer_password_set(struct peer
*peer
, const char *password
)
5340 struct peer
*member
;
5341 struct listnode
*node
, *nnode
;
5342 int len
= password
? strlen(password
) : 0;
5343 int ret
= BGP_SUCCESS
;
5345 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5346 return BGP_ERR_INVALID_VALUE
;
5348 /* Set flag and configuration on peer. */
5349 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5350 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5352 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5353 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5355 /* Check if handling a regular peer. */
5356 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5357 /* Send notification or reset peer depending on state. */
5358 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5362 bgp_session_reset(peer
);
5365 * Attempt to install password on socket and skip peer-group
5368 if (BGP_PEER_SU_UNSPEC(peer
))
5370 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5371 : BGP_ERR_TCPSIG_FAILED
;
5375 * Set flag and configuration on all peer-group members, unless they are
5376 * explicitely overriding peer-group configuration.
5378 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5379 /* Skip peers with overridden configuration. */
5380 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5383 /* Skip peers with the same password. */
5384 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5387 /* Set flag and configuration on peer-group member. */
5388 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5389 if (member
->password
)
5390 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5391 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5393 /* Send notification or reset peer depending on state. */
5394 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5395 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5396 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5398 bgp_session_reset(member
);
5400 /* Attempt to install password on socket. */
5401 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5402 ret
= BGP_ERR_TCPSIG_FAILED
;
5408 int peer_password_unset(struct peer
*peer
)
5410 struct peer
*member
;
5411 struct listnode
*node
, *nnode
;
5413 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5416 /* Inherit configuration from peer-group if peer is member. */
5417 if (peer_group_active(peer
)) {
5418 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5419 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5420 MTYPE_PEER_PASSWORD
);
5422 /* Otherwise remove flag and configuration from peer. */
5423 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5424 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5427 /* Check if handling a regular peer. */
5428 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5429 /* Send notification or reset peer depending on state. */
5430 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5431 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5432 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5434 bgp_session_reset(peer
);
5436 /* Attempt to uninstall password on socket. */
5437 if (!BGP_PEER_SU_UNSPEC(peer
))
5438 bgp_md5_unset(peer
);
5440 /* Skip peer-group mechanics for regular peers. */
5445 * Remove flag and configuration from all peer-group members, unless
5446 * they are explicitely overriding peer-group configuration.
5448 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5449 /* Skip peers with overridden configuration. */
5450 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5453 /* Remove flag and configuration on peer-group member. */
5454 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5455 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5457 /* Send notification or reset peer depending on state. */
5458 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5459 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5460 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5462 bgp_session_reset(member
);
5464 /* Attempt to uninstall password on socket. */
5465 if (!BGP_PEER_SU_UNSPEC(member
))
5466 bgp_md5_unset(member
);
5473 /* Set distribute list to the peer. */
5474 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5477 struct peer
*member
;
5478 struct bgp_filter
*filter
;
5479 struct listnode
*node
, *nnode
;
5481 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5482 return BGP_ERR_INVALID_VALUE
;
5484 /* Set configuration on peer. */
5485 filter
= &peer
->filter
[afi
][safi
];
5486 if (filter
->plist
[direct
].name
)
5487 return BGP_ERR_PEER_FILTER_CONFLICT
;
5488 if (filter
->dlist
[direct
].name
)
5489 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5490 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5491 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5493 /* Check if handling a regular peer. */
5494 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5495 /* Set override-flag and process peer route updates. */
5496 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5497 PEER_FT_DISTRIBUTE_LIST
);
5498 peer_on_policy_change(peer
, afi
, safi
,
5499 (direct
== FILTER_OUT
) ? 1 : 0);
5501 /* Skip peer-group mechanics for regular peers. */
5506 * Set configuration on all peer-group members, un less they are
5507 * explicitely overriding peer-group configuration.
5509 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5510 /* Skip peers with overridden configuration. */
5511 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5512 PEER_FT_DISTRIBUTE_LIST
))
5515 /* Set configuration on peer-group member. */
5516 filter
= &member
->filter
[afi
][safi
];
5517 if (filter
->dlist
[direct
].name
)
5518 XFREE(MTYPE_BGP_FILTER_NAME
,
5519 filter
->dlist
[direct
].name
);
5520 filter
->dlist
[direct
].name
=
5521 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5522 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5524 /* Process peer route updates. */
5525 peer_on_policy_change(member
, afi
, safi
,
5526 (direct
== FILTER_OUT
) ? 1 : 0);
5532 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5534 struct peer
*member
;
5535 struct bgp_filter
*filter
;
5536 struct listnode
*node
, *nnode
;
5538 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5539 return BGP_ERR_INVALID_VALUE
;
5541 /* Unset override-flag unconditionally. */
5542 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5543 PEER_FT_DISTRIBUTE_LIST
);
5545 /* Inherit configuration from peer-group if peer is member. */
5546 if (peer_group_active(peer
)) {
5547 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5548 filter
[afi
][safi
].dlist
[direct
].name
,
5549 MTYPE_BGP_FILTER_NAME
);
5550 PEER_ATTR_INHERIT(peer
, peer
->group
,
5551 filter
[afi
][safi
].dlist
[direct
].alist
);
5553 /* Otherwise remove configuration from peer. */
5554 filter
= &peer
->filter
[afi
][safi
];
5555 if (filter
->dlist
[direct
].name
)
5556 XFREE(MTYPE_BGP_FILTER_NAME
,
5557 filter
->dlist
[direct
].name
);
5558 filter
->dlist
[direct
].name
= NULL
;
5559 filter
->dlist
[direct
].alist
= NULL
;
5562 /* Check if handling a regular peer. */
5563 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5564 /* Process peer route updates. */
5565 peer_on_policy_change(peer
, afi
, safi
,
5566 (direct
== FILTER_OUT
) ? 1 : 0);
5568 /* Skip peer-group mechanics for regular peers. */
5573 * Remove configuration on all peer-group members, unless they are
5574 * explicitely overriding peer-group configuration.
5576 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5577 /* Skip peers with overridden configuration. */
5578 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5579 PEER_FT_DISTRIBUTE_LIST
))
5582 /* Remove configuration on peer-group member. */
5583 filter
= &member
->filter
[afi
][safi
];
5584 if (filter
->dlist
[direct
].name
)
5585 XFREE(MTYPE_BGP_FILTER_NAME
,
5586 filter
->dlist
[direct
].name
);
5587 filter
->dlist
[direct
].name
= NULL
;
5588 filter
->dlist
[direct
].alist
= NULL
;
5590 /* Process peer route updates. */
5591 peer_on_policy_change(member
, afi
, safi
,
5592 (direct
== FILTER_OUT
) ? 1 : 0);
5598 /* Update distribute list. */
5599 static void peer_distribute_update(struct access_list
*access
)
5604 struct listnode
*mnode
, *mnnode
;
5605 struct listnode
*node
, *nnode
;
5608 struct peer_group
*group
;
5609 struct bgp_filter
*filter
;
5611 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5613 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5614 access
->name
, 0, 0);
5615 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5616 FOREACH_AFI_SAFI (afi
, safi
) {
5617 filter
= &peer
->filter
[afi
][safi
];
5619 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5621 if (filter
->dlist
[direct
].name
)
5622 filter
->dlist
[direct
]
5623 .alist
= access_list_lookup(
5625 filter
->dlist
[direct
]
5628 filter
->dlist
[direct
].alist
=
5633 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5634 FOREACH_AFI_SAFI (afi
, safi
) {
5635 filter
= &group
->conf
->filter
[afi
][safi
];
5637 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5639 if (filter
->dlist
[direct
].name
)
5640 filter
->dlist
[direct
]
5641 .alist
= access_list_lookup(
5643 filter
->dlist
[direct
]
5646 filter
->dlist
[direct
].alist
=
5652 vnc_prefix_list_update(bgp
);
5657 /* Set prefix list to the peer. */
5658 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5661 struct peer
*member
;
5662 struct bgp_filter
*filter
;
5663 struct listnode
*node
, *nnode
;
5665 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5666 return BGP_ERR_INVALID_VALUE
;
5668 /* Set configuration on peer. */
5669 filter
= &peer
->filter
[afi
][safi
];
5670 if (filter
->dlist
[direct
].name
)
5671 return BGP_ERR_PEER_FILTER_CONFLICT
;
5672 if (filter
->plist
[direct
].name
)
5673 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5674 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5675 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5677 /* Check if handling a regular peer. */
5678 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5679 /* Set override-flag and process peer route updates. */
5680 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5681 PEER_FT_PREFIX_LIST
);
5682 peer_on_policy_change(peer
, afi
, safi
,
5683 (direct
== FILTER_OUT
) ? 1 : 0);
5685 /* Skip peer-group mechanics for regular peers. */
5690 * Set configuration on all peer-group members, unless they are
5691 * explicitely overriding peer-group configuration.
5693 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5694 /* Skip peers with overridden configuration. */
5695 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5696 PEER_FT_PREFIX_LIST
))
5699 /* Set configuration on peer-group member. */
5700 filter
= &member
->filter
[afi
][safi
];
5701 if (filter
->plist
[direct
].name
)
5702 XFREE(MTYPE_BGP_FILTER_NAME
,
5703 filter
->plist
[direct
].name
);
5704 filter
->plist
[direct
].name
=
5705 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5706 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5708 /* Process peer route updates. */
5709 peer_on_policy_change(member
, afi
, safi
,
5710 (direct
== FILTER_OUT
) ? 1 : 0);
5716 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5719 struct peer
*member
;
5720 struct bgp_filter
*filter
;
5721 struct listnode
*node
, *nnode
;
5723 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5724 return BGP_ERR_INVALID_VALUE
;
5726 /* Unset override-flag unconditionally. */
5727 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5728 PEER_FT_PREFIX_LIST
);
5730 /* Inherit configuration from peer-group if peer is member. */
5731 if (peer_group_active(peer
)) {
5732 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5733 filter
[afi
][safi
].plist
[direct
].name
,
5734 MTYPE_BGP_FILTER_NAME
);
5735 PEER_ATTR_INHERIT(peer
, peer
->group
,
5736 filter
[afi
][safi
].plist
[direct
].plist
);
5738 /* Otherwise remove configuration from peer. */
5739 filter
= &peer
->filter
[afi
][safi
];
5740 if (filter
->plist
[direct
].name
)
5741 XFREE(MTYPE_BGP_FILTER_NAME
,
5742 filter
->plist
[direct
].name
);
5743 filter
->plist
[direct
].name
= NULL
;
5744 filter
->plist
[direct
].plist
= NULL
;
5747 /* Check if handling a regular peer. */
5748 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5749 /* Process peer route updates. */
5750 peer_on_policy_change(peer
, afi
, safi
,
5751 (direct
== FILTER_OUT
) ? 1 : 0);
5753 /* Skip peer-group mechanics for regular peers. */
5758 * Remove configuration on all peer-group members, unless they are
5759 * explicitely overriding peer-group configuration.
5761 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5762 /* Skip peers with overridden configuration. */
5763 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5764 PEER_FT_PREFIX_LIST
))
5767 /* Remove configuration on peer-group member. */
5768 filter
= &member
->filter
[afi
][safi
];
5769 if (filter
->plist
[direct
].name
)
5770 XFREE(MTYPE_BGP_FILTER_NAME
,
5771 filter
->plist
[direct
].name
);
5772 filter
->plist
[direct
].name
= NULL
;
5773 filter
->plist
[direct
].plist
= NULL
;
5775 /* Process peer route updates. */
5776 peer_on_policy_change(member
, afi
, safi
,
5777 (direct
== FILTER_OUT
) ? 1 : 0);
5783 /* Update prefix-list list. */
5784 static void peer_prefix_list_update(struct prefix_list
*plist
)
5786 struct listnode
*mnode
, *mnnode
;
5787 struct listnode
*node
, *nnode
;
5790 struct peer_group
*group
;
5791 struct bgp_filter
*filter
;
5796 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5799 * Update the prefix-list on update groups.
5801 update_group_policy_update(
5802 bgp
, BGP_POLICY_PREFIX_LIST
,
5803 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5805 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5806 FOREACH_AFI_SAFI (afi
, safi
) {
5807 filter
= &peer
->filter
[afi
][safi
];
5809 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5811 if (filter
->plist
[direct
].name
)
5812 filter
->plist
[direct
]
5813 .plist
= prefix_list_lookup(
5815 filter
->plist
[direct
]
5818 filter
->plist
[direct
].plist
=
5823 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5824 FOREACH_AFI_SAFI (afi
, safi
) {
5825 filter
= &group
->conf
->filter
[afi
][safi
];
5827 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5829 if (filter
->plist
[direct
].name
)
5830 filter
->plist
[direct
]
5831 .plist
= prefix_list_lookup(
5833 filter
->plist
[direct
]
5836 filter
->plist
[direct
].plist
=
5844 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5847 struct peer
*member
;
5848 struct bgp_filter
*filter
;
5849 struct listnode
*node
, *nnode
;
5851 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5852 return BGP_ERR_INVALID_VALUE
;
5854 /* Set configuration on peer. */
5855 filter
= &peer
->filter
[afi
][safi
];
5856 if (filter
->aslist
[direct
].name
)
5857 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5858 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5859 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5861 /* Check if handling a regular peer. */
5862 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5863 /* Set override-flag and process peer route updates. */
5864 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5865 PEER_FT_FILTER_LIST
);
5866 peer_on_policy_change(peer
, afi
, safi
,
5867 (direct
== FILTER_OUT
) ? 1 : 0);
5869 /* Skip peer-group mechanics for regular peers. */
5874 * Set configuration on all peer-group members, unless they are
5875 * explicitely overriding peer-group configuration.
5877 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5878 /* Skip peers with overridden configuration. */
5879 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5880 PEER_FT_FILTER_LIST
))
5883 /* Set configuration on peer-group member. */
5884 filter
= &member
->filter
[afi
][safi
];
5885 if (filter
->aslist
[direct
].name
)
5886 XFREE(MTYPE_BGP_FILTER_NAME
,
5887 filter
->aslist
[direct
].name
);
5888 filter
->aslist
[direct
].name
=
5889 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5890 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5892 /* Process peer route updates. */
5893 peer_on_policy_change(member
, afi
, safi
,
5894 (direct
== FILTER_OUT
) ? 1 : 0);
5900 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5902 struct peer
*member
;
5903 struct bgp_filter
*filter
;
5904 struct listnode
*node
, *nnode
;
5906 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5907 return BGP_ERR_INVALID_VALUE
;
5909 /* Unset override-flag unconditionally. */
5910 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5911 PEER_FT_FILTER_LIST
);
5913 /* Inherit configuration from peer-group if peer is member. */
5914 if (peer_group_active(peer
)) {
5915 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5916 filter
[afi
][safi
].aslist
[direct
].name
,
5917 MTYPE_BGP_FILTER_NAME
);
5918 PEER_ATTR_INHERIT(peer
, peer
->group
,
5919 filter
[afi
][safi
].aslist
[direct
].aslist
);
5921 /* Otherwise remove configuration from peer. */
5922 filter
= &peer
->filter
[afi
][safi
];
5923 if (filter
->aslist
[direct
].name
)
5924 XFREE(MTYPE_BGP_FILTER_NAME
,
5925 filter
->aslist
[direct
].name
);
5926 filter
->aslist
[direct
].name
= NULL
;
5927 filter
->aslist
[direct
].aslist
= NULL
;
5930 /* Check if handling a regular peer. */
5931 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5932 /* Process peer route updates. */
5933 peer_on_policy_change(peer
, afi
, safi
,
5934 (direct
== FILTER_OUT
) ? 1 : 0);
5936 /* Skip peer-group mechanics for regular peers. */
5941 * Remove configuration on all peer-group members, unless they are
5942 * explicitely overriding peer-group configuration.
5944 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5945 /* Skip peers with overridden configuration. */
5946 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5947 PEER_FT_FILTER_LIST
))
5950 /* Remove configuration on peer-group member. */
5951 filter
= &member
->filter
[afi
][safi
];
5952 if (filter
->aslist
[direct
].name
)
5953 XFREE(MTYPE_BGP_FILTER_NAME
,
5954 filter
->aslist
[direct
].name
);
5955 filter
->aslist
[direct
].name
= NULL
;
5956 filter
->aslist
[direct
].aslist
= NULL
;
5958 /* Process peer route updates. */
5959 peer_on_policy_change(member
, afi
, safi
,
5960 (direct
== FILTER_OUT
) ? 1 : 0);
5966 static void peer_aslist_update(const char *aslist_name
)
5971 struct listnode
*mnode
, *mnnode
;
5972 struct listnode
*node
, *nnode
;
5975 struct peer_group
*group
;
5976 struct bgp_filter
*filter
;
5978 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5979 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5982 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5983 FOREACH_AFI_SAFI (afi
, safi
) {
5984 filter
= &peer
->filter
[afi
][safi
];
5986 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5988 if (filter
->aslist
[direct
].name
)
5989 filter
->aslist
[direct
]
5990 .aslist
= as_list_lookup(
5991 filter
->aslist
[direct
]
5994 filter
->aslist
[direct
].aslist
=
5999 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6000 FOREACH_AFI_SAFI (afi
, safi
) {
6001 filter
= &group
->conf
->filter
[afi
][safi
];
6003 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6005 if (filter
->aslist
[direct
].name
)
6006 filter
->aslist
[direct
]
6007 .aslist
= as_list_lookup(
6008 filter
->aslist
[direct
]
6011 filter
->aslist
[direct
].aslist
=
6019 static void peer_aslist_add(char *aslist_name
)
6021 peer_aslist_update(aslist_name
);
6022 route_map_notify_dependencies((char *)aslist_name
,
6023 RMAP_EVENT_ASLIST_ADDED
);
6026 static void peer_aslist_del(const char *aslist_name
)
6028 peer_aslist_update(aslist_name
);
6029 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6033 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6034 const char *name
, struct route_map
*route_map
)
6036 struct peer
*member
;
6037 struct bgp_filter
*filter
;
6038 struct listnode
*node
, *nnode
;
6040 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6041 return BGP_ERR_INVALID_VALUE
;
6043 /* Set configuration on peer. */
6044 filter
= &peer
->filter
[afi
][safi
];
6045 if (filter
->map
[direct
].name
)
6046 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6047 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6048 filter
->map
[direct
].map
= route_map
;
6050 /* Check if handling a regular peer. */
6051 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6052 /* Set override-flag and process peer route updates. */
6053 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6055 peer_on_policy_change(peer
, afi
, safi
,
6056 (direct
== RMAP_OUT
) ? 1 : 0);
6058 /* Skip peer-group mechanics for regular peers. */
6063 * Set configuration on all peer-group members, unless they are
6064 * explicitely overriding peer-group configuration.
6066 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6067 /* Skip peers with overridden configuration. */
6068 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6072 /* Set configuration on peer-group member. */
6073 filter
= &member
->filter
[afi
][safi
];
6074 if (filter
->map
[direct
].name
)
6075 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6076 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6077 filter
->map
[direct
].map
= route_map
;
6079 /* Process peer route updates. */
6080 peer_on_policy_change(member
, afi
, safi
,
6081 (direct
== RMAP_OUT
) ? 1 : 0);
6086 /* Unset route-map from the peer. */
6087 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6089 struct peer
*member
;
6090 struct bgp_filter
*filter
;
6091 struct listnode
*node
, *nnode
;
6093 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6094 return BGP_ERR_INVALID_VALUE
;
6096 /* Unset override-flag unconditionally. */
6097 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6099 /* Inherit configuration from peer-group if peer is member. */
6100 if (peer_group_active(peer
)) {
6101 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6102 filter
[afi
][safi
].map
[direct
].name
,
6103 MTYPE_BGP_FILTER_NAME
);
6104 PEER_ATTR_INHERIT(peer
, peer
->group
,
6105 filter
[afi
][safi
].map
[direct
].map
);
6107 /* Otherwise remove configuration from peer. */
6108 filter
= &peer
->filter
[afi
][safi
];
6109 if (filter
->map
[direct
].name
)
6110 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6111 filter
->map
[direct
].name
= NULL
;
6112 filter
->map
[direct
].map
= NULL
;
6115 /* Check if handling a regular peer. */
6116 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6117 /* Process peer route updates. */
6118 peer_on_policy_change(peer
, afi
, safi
,
6119 (direct
== RMAP_OUT
) ? 1 : 0);
6121 /* Skip peer-group mechanics for regular peers. */
6126 * Remove configuration on all peer-group members, unless they are
6127 * explicitely overriding peer-group configuration.
6129 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6130 /* Skip peers with overridden configuration. */
6131 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6135 /* Remove configuration on peer-group member. */
6136 filter
= &member
->filter
[afi
][safi
];
6137 if (filter
->map
[direct
].name
)
6138 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6139 filter
->map
[direct
].name
= NULL
;
6140 filter
->map
[direct
].map
= NULL
;
6142 /* Process peer route updates. */
6143 peer_on_policy_change(member
, afi
, safi
,
6144 (direct
== RMAP_OUT
) ? 1 : 0);
6150 /* Set unsuppress-map to the peer. */
6151 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6152 const char *name
, struct route_map
*route_map
)
6154 struct peer
*member
;
6155 struct bgp_filter
*filter
;
6156 struct listnode
*node
, *nnode
;
6158 /* Set configuration on peer. */
6159 filter
= &peer
->filter
[afi
][safi
];
6160 if (filter
->usmap
.name
)
6161 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6162 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6163 filter
->usmap
.map
= route_map
;
6165 /* Check if handling a regular peer. */
6166 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6167 /* Set override-flag and process peer route updates. */
6168 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6169 PEER_FT_UNSUPPRESS_MAP
);
6170 peer_on_policy_change(peer
, afi
, safi
, 1);
6172 /* Skip peer-group mechanics for regular peers. */
6177 * Set configuration on all peer-group members, unless they are
6178 * explicitely overriding peer-group configuration.
6180 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6181 /* Skip peers with overridden configuration. */
6182 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6183 PEER_FT_UNSUPPRESS_MAP
))
6186 /* Set configuration on peer-group member. */
6187 filter
= &member
->filter
[afi
][safi
];
6188 if (filter
->usmap
.name
)
6189 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6190 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6191 filter
->usmap
.map
= route_map
;
6193 /* Process peer route updates. */
6194 peer_on_policy_change(member
, afi
, safi
, 1);
6200 /* Unset route-map from the peer. */
6201 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6203 struct peer
*member
;
6204 struct bgp_filter
*filter
;
6205 struct listnode
*node
, *nnode
;
6207 /* Unset override-flag unconditionally. */
6208 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6210 /* Inherit configuration from peer-group if peer is member. */
6211 if (peer_group_active(peer
)) {
6212 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6213 filter
[afi
][safi
].usmap
.name
,
6214 MTYPE_BGP_FILTER_NAME
);
6215 PEER_ATTR_INHERIT(peer
, peer
->group
,
6216 filter
[afi
][safi
].usmap
.map
);
6218 /* Otherwise remove configuration from peer. */
6219 filter
= &peer
->filter
[afi
][safi
];
6220 if (filter
->usmap
.name
)
6221 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6222 filter
->usmap
.name
= NULL
;
6223 filter
->usmap
.map
= NULL
;
6226 /* Check if handling a regular peer. */
6227 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6228 /* Process peer route updates. */
6229 peer_on_policy_change(peer
, afi
, safi
, 1);
6231 /* Skip peer-group mechanics for regular peers. */
6236 * Remove configuration on all peer-group members, unless they are
6237 * explicitely overriding peer-group configuration.
6239 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6240 /* Skip peers with overridden configuration. */
6241 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6242 PEER_FT_UNSUPPRESS_MAP
))
6245 /* Remove configuration on peer-group member. */
6246 filter
= &member
->filter
[afi
][safi
];
6247 if (filter
->usmap
.name
)
6248 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6249 filter
->usmap
.name
= NULL
;
6250 filter
->usmap
.map
= NULL
;
6252 /* Process peer route updates. */
6253 peer_on_policy_change(member
, afi
, safi
, 1);
6259 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6260 uint32_t max
, uint8_t threshold
, int warning
,
6263 struct peer
*member
;
6264 struct listnode
*node
, *nnode
;
6266 /* Set flags and configuration on peer. */
6267 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6269 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6271 peer_af_flag_unset(peer
, afi
, safi
,
6272 PEER_FLAG_MAX_PREFIX_WARNING
);
6274 peer
->pmax
[afi
][safi
] = max
;
6275 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6276 peer
->pmax_restart
[afi
][safi
] = restart
;
6278 /* Check if handling a regular peer. */
6279 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6280 /* Re-check if peer violates maximum-prefix. */
6281 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6282 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6284 /* Skip peer-group mechanics for regular peers. */
6289 * Set flags and configuration on all peer-group members, unless they
6290 * are explicitely overriding peer-group configuration.
6292 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6293 /* Skip peers with overridden configuration. */
6294 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6295 PEER_FLAG_MAX_PREFIX
))
6298 /* Set flag and configuration on peer-group member. */
6299 member
->pmax
[afi
][safi
] = max
;
6300 member
->pmax_threshold
[afi
][safi
] = threshold
;
6301 member
->pmax_restart
[afi
][safi
] = restart
;
6303 SET_FLAG(member
->af_flags
[afi
][safi
],
6304 PEER_FLAG_MAX_PREFIX_WARNING
);
6306 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6307 PEER_FLAG_MAX_PREFIX_WARNING
);
6309 /* Re-check if peer violates maximum-prefix. */
6310 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6311 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6317 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6319 /* Inherit configuration from peer-group if peer is member. */
6320 if (peer_group_active(peer
)) {
6321 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6322 peer_af_flag_inherit(peer
, afi
, safi
,
6323 PEER_FLAG_MAX_PREFIX_WARNING
);
6324 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6325 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6326 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6331 /* Remove flags and configuration from peer. */
6332 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6333 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6334 peer
->pmax
[afi
][safi
] = 0;
6335 peer
->pmax_threshold
[afi
][safi
] = 0;
6336 peer
->pmax_restart
[afi
][safi
] = 0;
6339 * Remove flags and configuration from all peer-group members, unless
6340 * they are explicitely overriding peer-group configuration.
6342 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6343 struct peer
*member
;
6344 struct listnode
*node
;
6346 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6347 /* Skip peers with overridden configuration. */
6348 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6349 PEER_FLAG_MAX_PREFIX
))
6352 /* Remove flag and configuration on peer-group member.
6354 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6355 PEER_FLAG_MAX_PREFIX
);
6356 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6357 PEER_FLAG_MAX_PREFIX_WARNING
);
6358 member
->pmax
[afi
][safi
] = 0;
6359 member
->pmax_threshold
[afi
][safi
] = 0;
6360 member
->pmax_restart
[afi
][safi
] = 0;
6367 int is_ebgp_multihop_configured(struct peer
*peer
)
6369 struct peer_group
*group
;
6370 struct listnode
*node
, *nnode
;
6373 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6374 group
= peer
->group
;
6375 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6376 && (group
->conf
->ttl
!= 1))
6379 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6380 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6381 && (peer1
->ttl
!= 1))
6385 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6391 /* Set # of hops between us and BGP peer. */
6392 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6394 struct peer_group
*group
;
6395 struct listnode
*node
, *nnode
;
6398 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6399 gtsm_hops
, peer
->host
);
6401 /* We cannot configure ttl-security hops when ebgp-multihop is already
6402 set. For non peer-groups, the check is simple. For peer-groups,
6404 slightly messy, because we need to check both the peer-group
6406 and all peer-group members for any trace of ebgp-multihop
6408 before actually applying the ttl-security rules. Cisco really made a
6409 mess of this configuration parameter, and OpenBGPD got it right.
6412 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6413 if (is_ebgp_multihop_configured(peer
))
6414 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6416 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6417 peer
->gtsm_hops
= gtsm_hops
;
6419 /* Calling ebgp multihop also resets the session.
6420 * On restart, NHT will get setup correctly as will the
6421 * min & max ttls on the socket. The return value is
6424 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6429 group
= peer
->group
;
6430 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6432 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6434 /* Calling ebgp multihop also resets the
6436 * On restart, NHT will get setup correctly as
6438 * min & max ttls on the socket. The return
6442 peer_ebgp_multihop_set(peer
, MAXTTL
);
6446 /* Post the first gtsm setup or if its ibgp, maxttl setting
6448 * necessary, just set the minttl.
6450 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6451 peer
->gtsm_hops
= gtsm_hops
;
6454 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6455 MAXTTL
+ 1 - gtsm_hops
);
6456 if ((peer
->status
< Established
) && peer
->doppelganger
6457 && (peer
->doppelganger
->fd
>= 0))
6458 sockopt_minttl(peer
->su
.sa
.sa_family
,
6459 peer
->doppelganger
->fd
,
6460 MAXTTL
+ 1 - gtsm_hops
);
6462 group
= peer
->group
;
6463 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6465 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6467 /* Change setting of existing peer
6468 * established then change value (may break
6470 * not established yet (teardown session and
6472 * no session then do nothing (will get
6473 * handled by next connection)
6475 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6477 peer
->su
.sa
.sa_family
, peer
->fd
,
6478 MAXTTL
+ 1 - peer
->gtsm_hops
);
6479 if ((peer
->status
< Established
)
6480 && peer
->doppelganger
6481 && (peer
->doppelganger
->fd
>= 0))
6482 sockopt_minttl(peer
->su
.sa
.sa_family
,
6483 peer
->doppelganger
->fd
,
6484 MAXTTL
+ 1 - gtsm_hops
);
6492 int peer_ttl_security_hops_unset(struct peer
*peer
)
6494 struct peer_group
*group
;
6495 struct listnode
*node
, *nnode
;
6498 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6501 /* if a peer-group member, then reset to peer-group default rather than
6503 if (peer_group_active(peer
))
6504 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6506 peer
->gtsm_hops
= 0;
6508 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6509 /* Invoking ebgp_multihop_set will set the TTL back to the
6511 * value as well as restting the NHT and such. The session is
6514 if (peer
->sort
== BGP_PEER_EBGP
)
6515 ret
= peer_ebgp_multihop_unset(peer
);
6518 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6521 if ((peer
->status
< Established
) && peer
->doppelganger
6522 && (peer
->doppelganger
->fd
>= 0))
6523 sockopt_minttl(peer
->su
.sa
.sa_family
,
6524 peer
->doppelganger
->fd
, 0);
6527 group
= peer
->group
;
6528 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6529 peer
->gtsm_hops
= 0;
6530 if (peer
->sort
== BGP_PEER_EBGP
)
6531 ret
= peer_ebgp_multihop_unset(peer
);
6534 sockopt_minttl(peer
->su
.sa
.sa_family
,
6537 if ((peer
->status
< Established
)
6538 && peer
->doppelganger
6539 && (peer
->doppelganger
->fd
>= 0))
6540 sockopt_minttl(peer
->su
.sa
.sa_family
,
6541 peer
->doppelganger
->fd
,
6551 * If peer clear is invoked in a loop for all peers on the BGP instance,
6552 * it may end up freeing the doppelganger, and if this was the next node
6553 * to the current node, we would end up accessing the freed next node.
6554 * Pass along additional parameter which can be updated if next node
6555 * is freed; only required when walking the peer list on BGP instance.
6557 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6559 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6560 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6561 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6562 if (peer
->t_pmax_restart
) {
6563 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6564 if (bgp_debug_neighbor_events(peer
))
6566 "%s Maximum-prefix restart timer canceled",
6569 BGP_EVENT_ADD(peer
, BGP_Start
);
6573 peer
->v_start
= BGP_INIT_START_TIMER
;
6574 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6575 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6576 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6578 bgp_session_reset_safe(peer
, nnode
);
6583 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6584 enum bgp_clear_type stype
)
6586 struct peer_af
*paf
;
6588 if (peer
->status
!= Established
)
6591 if (!peer
->afc
[afi
][safi
])
6592 return BGP_ERR_AF_UNCONFIGURED
;
6594 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6596 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6597 /* Clear the "neighbor x.x.x.x default-originate" flag */
6598 paf
= peer_af_find(peer
, afi
, safi
);
6599 if (paf
&& paf
->subgroup
6600 && CHECK_FLAG(paf
->subgroup
->sflags
,
6601 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6602 UNSET_FLAG(paf
->subgroup
->sflags
,
6603 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6605 bgp_announce_route(peer
, afi
, safi
);
6608 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6609 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6610 PEER_CAP_ORF_PREFIX_SM_ADV
)
6611 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6612 PEER_CAP_ORF_PREFIX_RM_RCV
)
6613 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6614 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6615 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6616 uint8_t prefix_type
;
6618 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6619 PEER_CAP_ORF_PREFIX_RM_RCV
))
6620 prefix_type
= ORF_TYPE_PREFIX
;
6622 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6624 if (filter
->plist
[FILTER_IN
].plist
) {
6625 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6626 PEER_STATUS_ORF_PREFIX_SEND
))
6627 bgp_route_refresh_send(
6628 peer
, afi
, safi
, prefix_type
,
6630 bgp_route_refresh_send(peer
, afi
, safi
,
6632 REFRESH_IMMEDIATE
, 0);
6634 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6635 PEER_STATUS_ORF_PREFIX_SEND
))
6636 bgp_route_refresh_send(
6637 peer
, afi
, safi
, prefix_type
,
6638 REFRESH_IMMEDIATE
, 1);
6640 bgp_route_refresh_send(peer
, afi
, safi
,
6647 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6648 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6649 /* If neighbor has soft reconfiguration inbound flag.
6650 Use Adj-RIB-In database. */
6651 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6652 PEER_FLAG_SOFT_RECONFIG
))
6653 bgp_soft_reconfig_in(peer
, afi
, safi
);
6655 /* If neighbor has route refresh capability, send route
6657 message to the peer. */
6658 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6659 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6660 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6663 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6669 /* Display peer uptime.*/
6670 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6673 time_t uptime1
, epoch_tbuf
;
6676 /* If there is no connection has been done before print `never'. */
6679 json_object_string_add(json
, "peerUptime", "never");
6680 json_object_int_add(json
, "peerUptimeMsec", 0);
6682 snprintf(buf
, len
, "never");
6686 /* Get current time. */
6687 uptime1
= bgp_clock();
6689 tm
= gmtime(&uptime1
);
6691 if (uptime1
< ONE_DAY_SECOND
)
6692 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6694 else if (uptime1
< ONE_WEEK_SECOND
)
6695 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6697 else if (uptime1
< ONE_YEAR_SECOND
)
6698 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6699 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6701 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6703 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6706 epoch_tbuf
= time(NULL
) - uptime1
;
6707 json_object_string_add(json
, "peerUptime", buf
);
6708 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6709 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6716 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6717 afi_t afi
, safi_t safi
)
6719 struct bgp_filter
*filter
;
6723 filter
= &peer
->filter
[afi
][safi
];
6725 /* distribute-list. */
6726 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6728 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6729 filter
->dlist
[FILTER_IN
].name
);
6731 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6733 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6734 filter
->dlist
[FILTER_OUT
].name
);
6737 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6739 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6740 filter
->plist
[FILTER_IN
].name
);
6742 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6744 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6745 filter
->plist
[FILTER_OUT
].name
);
6748 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6749 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6750 filter
->map
[RMAP_IN
].name
);
6752 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6754 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6755 filter
->map
[RMAP_OUT
].name
);
6757 /* unsuppress-map */
6758 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6759 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6760 filter
->usmap
.name
);
6763 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6765 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6766 filter
->aslist
[FILTER_IN
].name
);
6768 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6770 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6771 filter
->aslist
[FILTER_OUT
].name
);
6774 /* BGP peer configuration display function. */
6775 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6778 struct peer
*g_peer
= NULL
;
6779 char buf
[SU_ADDRSTRLEN
];
6781 int if_pg_printed
= FALSE
;
6782 int if_ras_printed
= FALSE
;
6784 /* Skip dynamic neighbors. */
6785 if (peer_dynamic_neighbor(peer
))
6789 addr
= peer
->conf_if
;
6793 /************************************
6794 ****** Global to the neighbor ******
6795 ************************************/
6796 if (peer
->conf_if
) {
6797 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6798 vty_out(vty
, " neighbor %s interface v6only", addr
);
6800 vty_out(vty
, " neighbor %s interface", addr
);
6802 if (peer_group_active(peer
)) {
6803 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6804 if_pg_printed
= TRUE
;
6805 } else if (peer
->as_type
== AS_SPECIFIED
) {
6806 vty_out(vty
, " remote-as %u", peer
->as
);
6807 if_ras_printed
= TRUE
;
6808 } else if (peer
->as_type
== AS_INTERNAL
) {
6809 vty_out(vty
, " remote-as internal");
6810 if_ras_printed
= TRUE
;
6811 } else if (peer
->as_type
== AS_EXTERNAL
) {
6812 vty_out(vty
, " remote-as external");
6813 if_ras_printed
= TRUE
;
6819 /* remote-as and peer-group */
6820 /* peer is a member of a peer-group */
6821 if (peer_group_active(peer
)) {
6822 g_peer
= peer
->group
->conf
;
6824 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6825 if (peer
->as_type
== AS_SPECIFIED
) {
6826 vty_out(vty
, " neighbor %s remote-as %u\n",
6828 } else if (peer
->as_type
== AS_INTERNAL
) {
6830 " neighbor %s remote-as internal\n",
6832 } else if (peer
->as_type
== AS_EXTERNAL
) {
6834 " neighbor %s remote-as external\n",
6839 /* For swpX peers we displayed the peer-group
6840 * via 'neighbor swpX interface peer-group WORD' */
6842 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6846 /* peer is NOT a member of a peer-group */
6848 /* peer is a peer-group, declare the peer-group */
6849 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6850 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6853 if (!if_ras_printed
) {
6854 if (peer
->as_type
== AS_SPECIFIED
) {
6855 vty_out(vty
, " neighbor %s remote-as %u\n",
6857 } else if (peer
->as_type
== AS_INTERNAL
) {
6859 " neighbor %s remote-as internal\n",
6861 } else if (peer
->as_type
== AS_EXTERNAL
) {
6863 " neighbor %s remote-as external\n",
6870 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6871 vty_out(vty
, " neighbor %s local-as %u", addr
,
6872 peer
->change_local_as
);
6873 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6874 vty_out(vty
, " no-prepend");
6875 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6876 vty_out(vty
, " replace-as");
6882 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6886 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6887 if (peer
->tx_shutdown_message
)
6888 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6889 peer
->tx_shutdown_message
);
6891 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6895 if (peer
->bfd_info
) {
6896 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6897 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6902 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6903 vty_out(vty
, " neighbor %s password %s\n", addr
,
6907 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6908 if (!peer_group_active(peer
)) {
6909 vty_out(vty
, " neighbor %s solo\n", addr
);
6914 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6915 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6918 /* Local interface name */
6920 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6924 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6925 vty_out(vty
, " neighbor %s passive\n", addr
);
6928 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6929 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6930 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6931 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6936 /* ttl-security hops */
6937 if (peer
->gtsm_hops
!= 0) {
6938 if (!peer_group_active(peer
)
6939 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6940 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6941 addr
, peer
->gtsm_hops
);
6945 /* disable-connected-check */
6946 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6947 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6949 /* enforce-first-as */
6950 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6951 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6954 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6955 if (peer
->update_source
)
6956 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6957 sockunion2str(peer
->update_source
, buf
,
6959 else if (peer
->update_if
)
6960 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6964 /* advertisement-interval */
6965 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6966 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6970 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6971 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6972 peer
->keepalive
, peer
->holdtime
);
6974 /* timers connect */
6975 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6976 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6979 /* capability dynamic */
6980 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6981 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6983 /* capability extended-nexthop */
6984 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6985 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6987 " no neighbor %s capability extended-nexthop\n",
6991 " neighbor %s capability extended-nexthop\n",
6995 /* dont-capability-negotiation */
6996 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
6997 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
6999 /* override-capability */
7000 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7001 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7003 /* strict-capability-match */
7004 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7005 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7008 /* BGP peer configuration display function. */
7009 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7010 struct peer
*peer
, afi_t afi
, safi_t safi
)
7012 struct peer
*g_peer
= NULL
;
7014 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7016 /* Skip dynamic neighbors. */
7017 if (peer_dynamic_neighbor(peer
))
7021 addr
= peer
->conf_if
;
7025 /************************************
7026 ****** Per AF to the neighbor ******
7027 ************************************/
7028 if (peer_group_active(peer
)) {
7029 g_peer
= peer
->group
->conf
;
7031 /* If the peer-group is active but peer is not, print a 'no
7033 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7034 vty_out(vty
, " no neighbor %s activate\n", addr
);
7037 /* If the peer-group is not active but peer is, print an
7039 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7040 vty_out(vty
, " neighbor %s activate\n", addr
);
7043 if (peer
->afc
[afi
][safi
]) {
7044 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7045 if (bgp_flag_check(bgp
,
7046 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7047 vty_out(vty
, " neighbor %s activate\n",
7051 vty_out(vty
, " neighbor %s activate\n", addr
);
7053 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7054 if (!bgp_flag_check(bgp
,
7055 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7057 " no neighbor %s activate\n",
7064 /* addpath TX knobs */
7065 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7066 switch (peer
->addpath_type
[afi
][safi
]) {
7067 case BGP_ADDPATH_ALL
:
7068 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7071 case BGP_ADDPATH_BEST_PER_AS
:
7073 " neighbor %s addpath-tx-bestpath-per-AS\n",
7076 case BGP_ADDPATH_MAX
:
7077 case BGP_ADDPATH_NONE
:
7082 /* ORF capability. */
7083 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7084 || peergroup_af_flag_check(peer
, afi
, safi
,
7085 PEER_FLAG_ORF_PREFIX_RM
)) {
7086 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7088 if (peergroup_af_flag_check(peer
, afi
, safi
,
7089 PEER_FLAG_ORF_PREFIX_SM
)
7090 && peergroup_af_flag_check(peer
, afi
, safi
,
7091 PEER_FLAG_ORF_PREFIX_RM
))
7092 vty_out(vty
, " both");
7093 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7094 PEER_FLAG_ORF_PREFIX_SM
))
7095 vty_out(vty
, " send");
7097 vty_out(vty
, " receive");
7101 /* Route reflector client. */
7102 if (peergroup_af_flag_check(peer
, afi
, safi
,
7103 PEER_FLAG_REFLECTOR_CLIENT
)) {
7104 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7107 /* next-hop-self force */
7108 if (peergroup_af_flag_check(peer
, afi
, safi
,
7109 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7110 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7114 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7115 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7118 /* remove-private-AS */
7119 if (peergroup_af_flag_check(peer
, afi
, safi
,
7120 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7121 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7125 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7126 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7127 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7131 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7132 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7133 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7136 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7137 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7138 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7142 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7143 vty_out(vty
, " neighbor %s as-override\n", addr
);
7146 /* send-community print. */
7147 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7148 PEER_FLAG_SEND_COMMUNITY
);
7149 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7150 PEER_FLAG_SEND_EXT_COMMUNITY
);
7151 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7152 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7154 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7155 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7156 vty_out(vty
, " no neighbor %s send-community all\n",
7161 " no neighbor %s send-community\n",
7165 " no neighbor %s send-community extended\n",
7170 " no neighbor %s send-community large\n",
7174 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7175 vty_out(vty
, " neighbor %s send-community all\n",
7177 } else if (flag_scomm
&& flag_secomm
) {
7178 vty_out(vty
, " neighbor %s send-community both\n",
7182 vty_out(vty
, " neighbor %s send-community\n",
7186 " neighbor %s send-community extended\n",
7190 " neighbor %s send-community large\n",
7195 /* Default information */
7196 if (peergroup_af_flag_check(peer
, afi
, safi
,
7197 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7198 vty_out(vty
, " neighbor %s default-originate", addr
);
7200 if (peer
->default_rmap
[afi
][safi
].name
)
7201 vty_out(vty
, " route-map %s",
7202 peer
->default_rmap
[afi
][safi
].name
);
7207 /* Soft reconfiguration inbound. */
7208 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7209 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7213 /* maximum-prefix. */
7214 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7215 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7216 peer
->pmax
[afi
][safi
]);
7218 if (peer
->pmax_threshold
[afi
][safi
]
7219 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7220 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7221 if (peer_af_flag_check(peer
, afi
, safi
,
7222 PEER_FLAG_MAX_PREFIX_WARNING
))
7223 vty_out(vty
, " warning-only");
7224 if (peer
->pmax_restart
[afi
][safi
])
7225 vty_out(vty
, " restart %u",
7226 peer
->pmax_restart
[afi
][safi
]);
7231 /* Route server client. */
7232 if (peergroup_af_flag_check(peer
, afi
, safi
,
7233 PEER_FLAG_RSERVER_CLIENT
)) {
7234 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7237 /* Nexthop-local unchanged. */
7238 if (peergroup_af_flag_check(peer
, afi
, safi
,
7239 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7240 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7243 /* allowas-in <1-10> */
7244 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7245 if (peer_af_flag_check(peer
, afi
, safi
,
7246 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7247 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7248 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7249 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7251 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7252 peer
->allowas_in
[afi
][safi
]);
7257 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7258 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7259 peer
->weight
[afi
][safi
]);
7262 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7264 /* atribute-unchanged. */
7265 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7266 || (safi
!= SAFI_EVPN
7267 && peer_af_flag_check(peer
, afi
, safi
,
7268 PEER_FLAG_NEXTHOP_UNCHANGED
))
7269 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7271 if (!peer_group_active(peer
)
7272 || peergroup_af_flag_check(peer
, afi
, safi
,
7273 PEER_FLAG_AS_PATH_UNCHANGED
)
7274 || peergroup_af_flag_check(peer
, afi
, safi
,
7275 PEER_FLAG_NEXTHOP_UNCHANGED
)
7276 || peergroup_af_flag_check(peer
, afi
, safi
,
7277 PEER_FLAG_MED_UNCHANGED
)) {
7280 " neighbor %s attribute-unchanged%s%s%s\n",
7282 peer_af_flag_check(peer
, afi
, safi
,
7283 PEER_FLAG_AS_PATH_UNCHANGED
)
7286 peer_af_flag_check(peer
, afi
, safi
,
7287 PEER_FLAG_NEXTHOP_UNCHANGED
)
7290 peer_af_flag_check(peer
, afi
, safi
,
7291 PEER_FLAG_MED_UNCHANGED
)
7298 /* Address family based peer configuration display. */
7299 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7303 struct peer_group
*group
;
7304 struct listnode
*node
, *nnode
;
7307 vty_frame(vty
, " !\n address-family ");
7308 if (afi
== AFI_IP
) {
7309 if (safi
== SAFI_UNICAST
)
7310 vty_frame(vty
, "ipv4 unicast");
7311 else if (safi
== SAFI_LABELED_UNICAST
)
7312 vty_frame(vty
, "ipv4 labeled-unicast");
7313 else if (safi
== SAFI_MULTICAST
)
7314 vty_frame(vty
, "ipv4 multicast");
7315 else if (safi
== SAFI_MPLS_VPN
)
7316 vty_frame(vty
, "ipv4 vpn");
7317 else if (safi
== SAFI_ENCAP
)
7318 vty_frame(vty
, "ipv4 encap");
7319 else if (safi
== SAFI_FLOWSPEC
)
7320 vty_frame(vty
, "ipv4 flowspec");
7321 } else if (afi
== AFI_IP6
) {
7322 if (safi
== SAFI_UNICAST
)
7323 vty_frame(vty
, "ipv6 unicast");
7324 else if (safi
== SAFI_LABELED_UNICAST
)
7325 vty_frame(vty
, "ipv6 labeled-unicast");
7326 else if (safi
== SAFI_MULTICAST
)
7327 vty_frame(vty
, "ipv6 multicast");
7328 else if (safi
== SAFI_MPLS_VPN
)
7329 vty_frame(vty
, "ipv6 vpn");
7330 else if (safi
== SAFI_ENCAP
)
7331 vty_frame(vty
, "ipv6 encap");
7332 else if (safi
== SAFI_FLOWSPEC
)
7333 vty_frame(vty
, "ipv6 flowspec");
7334 } else if (afi
== AFI_L2VPN
) {
7335 if (safi
== SAFI_EVPN
)
7336 vty_frame(vty
, "l2vpn evpn");
7338 vty_frame(vty
, "\n");
7340 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7342 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7344 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7346 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7347 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7349 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7350 /* Skip dynamic neighbors. */
7351 if (peer_dynamic_neighbor(peer
))
7354 /* Do not display doppelganger peers */
7355 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7356 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7359 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7360 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7362 if (safi
== SAFI_EVPN
)
7363 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7365 if (safi
== SAFI_FLOWSPEC
)
7366 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7368 if (safi
== SAFI_UNICAST
) {
7369 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7370 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7371 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7373 vty_out(vty
, " export vpn\n");
7375 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7376 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7378 vty_out(vty
, " import vpn\n");
7380 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7381 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7384 for (ALL_LIST_ELEMENTS_RO(
7385 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7387 vty_out(vty
, " import vrf %s\n", name
);
7391 vty_endframe(vty
, " exit-address-family\n");
7394 /* clang-format off */
7395 #if CONFDATE > 20190517
7396 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7398 /* clang-format on */
7400 int bgp_config_write(struct vty
*vty
)
7404 struct peer_group
*group
;
7406 struct listnode
*node
, *nnode
;
7407 struct listnode
*mnode
, *mnnode
;
7409 /* BGP Multiple instance. */
7410 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7411 vty_out(vty
, "no bgp multiple-instance\n");
7415 /* BGP Config type. */
7416 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7417 vty_out(vty
, "bgp config-type cisco\n");
7421 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7422 vty_out(vty
, "bgp route-map delay-timer %u\n",
7423 bm
->rmap_update_timer
);
7426 vty_out(vty
, "!\n");
7428 /* BGP configuration. */
7429 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7431 /* skip all auto created vrf as they dont have user config */
7432 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7435 /* Migrate deprecated 'bgp enforce-first-as'
7436 * config to 'neighbor * enforce-first-as' configs
7438 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7439 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7440 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7441 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7444 /* Router bgp ASN */
7445 vty_out(vty
, "router bgp %u", bgp
->as
);
7447 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7449 vty_out(vty
, " %s %s",
7451 == BGP_INSTANCE_TYPE_VIEW
)
7458 /* No Synchronization */
7459 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7460 vty_out(vty
, " no synchronization\n");
7462 /* BGP fast-external-failover. */
7463 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7464 vty_out(vty
, " no bgp fast-external-failover\n");
7466 /* BGP router ID. */
7467 if (bgp
->router_id_static
.s_addr
!= 0)
7468 vty_out(vty
, " bgp router-id %s\n",
7469 inet_ntoa(bgp
->router_id_static
));
7471 /* BGP log-neighbor-changes. */
7472 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7473 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7474 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7476 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7480 /* BGP configuration. */
7481 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7482 vty_out(vty
, " bgp always-compare-med\n");
7484 /* BGP default ipv4-unicast. */
7485 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7486 vty_out(vty
, " no bgp default ipv4-unicast\n");
7488 /* BGP default local-preference. */
7489 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7490 vty_out(vty
, " bgp default local-preference %u\n",
7491 bgp
->default_local_pref
);
7493 /* BGP default show-hostname */
7494 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7495 != DFLT_BGP_SHOW_HOSTNAME
)
7496 vty_out(vty
, " %sbgp default show-hostname\n",
7497 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7501 /* BGP default subgroup-pkt-queue-max. */
7502 if (bgp
->default_subgroup_pkt_queue_max
7503 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7504 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7505 bgp
->default_subgroup_pkt_queue_max
);
7507 /* BGP client-to-client reflection. */
7508 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7509 vty_out(vty
, " no bgp client-to-client reflection\n");
7511 /* BGP cluster ID. */
7512 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7513 vty_out(vty
, " bgp cluster-id %s\n",
7514 inet_ntoa(bgp
->cluster_id
));
7516 /* Disable ebgp connected nexthop check */
7517 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7519 " bgp disable-ebgp-connected-route-check\n");
7521 /* Confederation identifier*/
7522 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7523 vty_out(vty
, " bgp confederation identifier %i\n",
7526 /* Confederation peer */
7527 if (bgp
->confed_peers_cnt
> 0) {
7530 vty_out(vty
, " bgp confederation peers");
7532 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7533 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7538 /* BGP deterministic-med. */
7539 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7540 != DFLT_BGP_DETERMINISTIC_MED
)
7541 vty_out(vty
, " %sbgp deterministic-med\n",
7542 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7546 /* BGP update-delay. */
7547 bgp_config_write_update_delay(vty
, bgp
);
7549 if (bgp
->v_maxmed_onstartup
7550 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7551 vty_out(vty
, " bgp max-med on-startup %u",
7552 bgp
->v_maxmed_onstartup
);
7553 if (bgp
->maxmed_onstartup_value
7554 != BGP_MAXMED_VALUE_DEFAULT
)
7556 bgp
->maxmed_onstartup_value
);
7559 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7560 vty_out(vty
, " bgp max-med administrative");
7561 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7562 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7567 bgp_config_write_wpkt_quanta(vty
, bgp
);
7569 bgp_config_write_rpkt_quanta(vty
, bgp
);
7572 bgp_config_write_coalesce_time(vty
, bgp
);
7574 /* BGP graceful-restart. */
7575 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7577 " bgp graceful-restart stalepath-time %u\n",
7578 bgp
->stalepath_time
);
7579 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7580 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7582 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7583 vty_out(vty
, " bgp graceful-restart\n");
7585 /* BGP graceful-shutdown */
7586 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7587 vty_out(vty
, " bgp graceful-shutdown\n");
7589 /* BGP graceful-restart Preserve State F bit. */
7590 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7592 " bgp graceful-restart preserve-fw-state\n");
7594 /* BGP bestpath method. */
7595 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7596 vty_out(vty
, " bgp bestpath as-path ignore\n");
7597 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7598 vty_out(vty
, " bgp bestpath as-path confed\n");
7600 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7601 if (bgp_flag_check(bgp
,
7602 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7604 " bgp bestpath as-path multipath-relax as-set\n");
7607 " bgp bestpath as-path multipath-relax\n");
7611 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7613 " bgp route-reflector allow-outbound-policy\n");
7615 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7616 vty_out(vty
, " bgp bestpath compare-routerid\n");
7617 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7618 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7619 vty_out(vty
, " bgp bestpath med");
7620 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7621 vty_out(vty
, " confed");
7622 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7623 vty_out(vty
, " missing-as-worst");
7627 /* BGP network import check. */
7628 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7629 != DFLT_BGP_IMPORT_CHECK
)
7630 vty_out(vty
, " %sbgp network import-check\n",
7631 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7635 /* BGP flag dampening. */
7636 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7637 BGP_CONFIG_DAMPENING
))
7638 bgp_config_write_damp(vty
);
7640 /* BGP timers configuration. */
7641 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7642 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7643 vty_out(vty
, " timers bgp %u %u\n",
7644 bgp
->default_keepalive
, bgp
->default_holdtime
);
7647 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7648 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7651 /* Normal neighbor configuration. */
7652 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7653 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7654 bgp_config_write_peer_global(vty
, bgp
, peer
);
7657 /* listen range and limit for dynamic BGP neighbors */
7658 bgp_config_write_listen(vty
, bgp
);
7661 * BGP default autoshutdown neighbors
7663 * This must be placed after any peer and peer-group
7664 * configuration, to avoid setting all peers to shutdown after
7665 * a daemon restart, which is undesired behavior. (see #2286)
7667 if (bgp
->autoshutdown
)
7668 vty_out(vty
, " bgp default shutdown\n");
7670 /* No auto-summary */
7671 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7672 vty_out(vty
, " no auto-summary\n");
7674 /* IPv4 unicast configuration. */
7675 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7677 /* IPv4 multicast configuration. */
7678 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7680 /* IPv4 labeled-unicast configuration. */
7681 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7683 /* IPv4 VPN configuration. */
7684 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7686 /* ENCAPv4 configuration. */
7687 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7689 /* FLOWSPEC v4 configuration. */
7690 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7692 /* IPv6 unicast configuration. */
7693 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7695 /* IPv6 multicast configuration. */
7696 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7698 /* IPv6 labeled-unicast configuration. */
7699 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7700 SAFI_LABELED_UNICAST
);
7702 /* IPv6 VPN configuration. */
7703 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7705 /* ENCAPv6 configuration. */
7706 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7708 /* FLOWSPEC v6 configuration. */
7709 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7711 /* EVPN configuration. */
7712 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7715 bgp_rfapi_cfg_write(vty
, bgp
);
7718 vty_out(vty
, "!\n");
7723 void bgp_master_init(struct thread_master
*master
)
7727 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7730 bm
->bgp
= list_new();
7731 bm
->listen_sockets
= list_new();
7732 bm
->port
= BGP_PORT_DEFAULT
;
7733 bm
->master
= master
;
7734 bm
->start_time
= bgp_clock();
7735 bm
->t_rmap_update
= NULL
;
7736 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7737 bm
->terminating
= false;
7739 bgp_process_queue_init();
7741 /* init the rd id space.
7742 assign 0th index in the bitfield,
7743 so that we start with id 1
7745 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7746 bf_assign_zero_index(bm
->rd_idspace
);
7748 /* Enable multiple instances by default. */
7749 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7751 /* mpls label dynamic allocation pool */
7752 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7754 QOBJ_REG(bm
, bgp_master
);
7758 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7759 * instance delete (non-default only) or BGP exit.
7761 static void bgp_if_finish(struct bgp
*bgp
)
7763 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7764 struct interface
*ifp
;
7766 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7769 FOR_ALL_INTERFACES (vrf
, ifp
) {
7770 struct listnode
*c_node
, *c_nnode
;
7771 struct connected
*c
;
7773 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7774 bgp_connected_delete(bgp
, c
);
7778 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7780 struct vrf
*vrf
= NULL
;
7781 struct listnode
*next
;
7784 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7785 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7787 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7788 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7791 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7795 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7796 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7797 {.completions
= NULL
},
7800 struct frr_pthread
*bgp_pth_io
;
7801 struct frr_pthread
*bgp_pth_ka
;
7803 static void bgp_pthreads_init()
7805 assert(!bgp_pth_io
);
7806 assert(!bgp_pth_ka
);
7810 struct frr_pthread_attr io
= {
7811 .start
= frr_pthread_attr_default
.start
,
7812 .stop
= frr_pthread_attr_default
.stop
,
7814 struct frr_pthread_attr ka
= {
7815 .start
= bgp_keepalives_start
,
7816 .stop
= bgp_keepalives_stop
,
7818 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7819 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7822 void bgp_pthreads_run()
7824 frr_pthread_run(bgp_pth_io
, NULL
);
7825 frr_pthread_run(bgp_pth_ka
, NULL
);
7827 /* Wait until threads are ready. */
7828 frr_pthread_wait_running(bgp_pth_io
);
7829 frr_pthread_wait_running(bgp_pth_ka
);
7832 void bgp_pthreads_finish()
7834 frr_pthread_stop_all();
7835 frr_pthread_finish();
7838 void bgp_init(unsigned short instance
)
7841 /* allocates some vital data structures used by peer commands in
7844 /* pre-init pthreads */
7845 bgp_pthreads_init();
7848 bgp_zebra_init(bm
->master
, instance
);
7851 vnc_zebra_init(bm
->master
);
7854 /* BGP VTY commands installation. */
7862 bgp_route_map_init();
7863 bgp_scan_vty_init();
7868 bgp_ethernetvpn_init();
7869 bgp_flowspec_vty_init();
7871 /* Access list initialize. */
7873 access_list_add_hook(peer_distribute_update
);
7874 access_list_delete_hook(peer_distribute_update
);
7876 /* Filter list initialize. */
7878 as_list_add_hook(peer_aslist_add
);
7879 as_list_delete_hook(peer_aslist_del
);
7881 /* Prefix list initialize.*/
7883 prefix_list_add_hook(peer_prefix_list_update
);
7884 prefix_list_delete_hook(peer_prefix_list_update
);
7886 /* Community list initialize. */
7887 bgp_clist
= community_list_init();
7892 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7895 void bgp_terminate(void)
7899 struct listnode
*node
, *nnode
;
7900 struct listnode
*mnode
, *mnnode
;
7904 /* Close the listener sockets first as this prevents peers from
7906 * to reconnect on receiving the peer unconfig message. In the presence
7907 * of a large number of peers this will ensure that no peer is left with
7908 * a dangling connection
7910 /* reverse bgp_master_init */
7913 if (bm
->listen_sockets
)
7914 list_delete(&bm
->listen_sockets
);
7916 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7917 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7918 if (peer
->status
== Established
7919 || peer
->status
== OpenSent
7920 || peer
->status
== OpenConfirm
)
7921 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7922 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7924 if (bm
->process_main_queue
)
7925 work_queue_free_and_null(&bm
->process_main_queue
);
7927 if (bm
->t_rmap_update
)
7928 BGP_TIMER_OFF(bm
->t_rmap_update
);