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"
89 #include "bgpd/bgp_evpn_private.h"
91 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
92 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
93 DEFINE_QOBJ_TYPE(bgp_master
)
95 DEFINE_QOBJ_TYPE(peer
)
97 /* BGP process wide configuration. */
98 static struct bgp_master bgp_master
;
100 /* BGP process wide configuration pointer to export. */
101 struct bgp_master
*bm
;
103 /* BGP community-list. */
104 struct community_list_handler
*bgp_clist
;
106 unsigned int multipath_num
= MULTIPATH_NUM
;
108 static void bgp_if_finish(struct bgp
*bgp
);
109 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
111 extern struct zclient
*zclient
;
113 /* handle main socket creation or deletion */
114 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
116 static int bgp_server_main_created
;
118 if (create
== true) {
119 if (bgp_server_main_created
)
121 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
122 return BGP_ERR_INVALID_VALUE
;
123 bgp_server_main_created
= 1;
126 if (!bgp_server_main_created
)
129 bgp_server_main_created
= 0;
133 void bgp_session_reset(struct peer
*peer
)
135 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
136 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
137 peer_delete(peer
->doppelganger
);
139 BGP_EVENT_ADD(peer
, BGP_Stop
);
143 * During session reset, we may delete the doppelganger peer, which would
144 * be the next node to the current node. If the session reset was invoked
145 * during walk of peer list, we would end up accessing the freed next
146 * node. This function moves the next node along.
148 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
153 n
= (nnode
) ? *nnode
: NULL
;
154 npeer
= (n
) ? listgetdata(n
) : NULL
;
156 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
157 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
158 PEER_FLAG_CONFIG_NODE
))) {
159 if (peer
->doppelganger
== npeer
)
160 /* nnode and *nnode are confirmed to be non-NULL here */
161 *nnode
= (*nnode
)->next
;
162 peer_delete(peer
->doppelganger
);
165 BGP_EVENT_ADD(peer
, BGP_Stop
);
168 /* BGP global flag manipulation. */
169 int bgp_option_set(int flag
)
173 case BGP_OPT_MULTIPLE_INSTANCE
:
174 case BGP_OPT_CONFIG_CISCO
:
175 case BGP_OPT_NO_LISTEN
:
176 case BGP_OPT_NO_ZEBRA
:
177 SET_FLAG(bm
->options
, flag
);
180 return BGP_ERR_INVALID_FLAG
;
185 int bgp_option_unset(int flag
)
188 case BGP_OPT_MULTIPLE_INSTANCE
:
189 if (listcount(bm
->bgp
) > 1)
190 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
192 case BGP_OPT_NO_ZEBRA
:
194 case BGP_OPT_CONFIG_CISCO
:
195 UNSET_FLAG(bm
->options
, flag
);
198 return BGP_ERR_INVALID_FLAG
;
203 int bgp_option_check(int flag
)
205 return CHECK_FLAG(bm
->options
, flag
);
208 /* BGP flag manipulation. */
209 int bgp_flag_set(struct bgp
*bgp
, int flag
)
211 SET_FLAG(bgp
->flags
, flag
);
215 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
217 UNSET_FLAG(bgp
->flags
, flag
);
221 int bgp_flag_check(struct bgp
*bgp
, int flag
)
223 return CHECK_FLAG(bgp
->flags
, flag
);
226 /* Internal function to set BGP structure configureation flag. */
227 static void bgp_config_set(struct bgp
*bgp
, int config
)
229 SET_FLAG(bgp
->config
, config
);
232 static void bgp_config_unset(struct bgp
*bgp
, int config
)
234 UNSET_FLAG(bgp
->config
, config
);
237 static int bgp_config_check(struct bgp
*bgp
, int config
)
239 return CHECK_FLAG(bgp
->config
, config
);
242 /* Set BGP router identifier. */
243 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
246 struct listnode
*node
, *nnode
;
248 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
251 /* EVPN uses router id in RD, withdraw them */
252 if (is_evpn_enabled())
253 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
255 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
257 /* Set all peer's local identifier with this value. */
258 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
259 IPV4_ADDR_COPY(&peer
->local_id
, id
);
261 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
262 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
264 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
268 /* EVPN uses router id in RD, update them */
269 if (is_evpn_enabled())
270 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
275 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
277 struct listnode
*node
, *nnode
;
279 struct in_addr
*addr
= NULL
;
281 if (router_id
!= NULL
)
282 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
284 if (vrf_id
== VRF_DEFAULT
) {
285 /* Router-id change for default VRF has to also update all
287 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
288 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
292 bgp
->router_id_zebra
= *addr
;
294 addr
= &bgp
->router_id_zebra
;
296 if (!bgp
->router_id_static
.s_addr
) {
297 /* Router ID is updated if there are no active
300 if (bgp
->established_peers
== 0) {
301 if (BGP_DEBUG(zebra
, ZEBRA
))
302 zlog_debug("RID change : vrf %u, RTR ID %s",
303 bgp
->vrf_id
, inet_ntoa(*addr
));
304 bgp_router_id_set(bgp
, addr
);
309 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
312 bgp
->router_id_zebra
= *addr
;
314 addr
= &bgp
->router_id_zebra
;
316 if (!bgp
->router_id_static
.s_addr
) {
317 /* Router ID is updated if there are no active
320 if (bgp
->established_peers
== 0) {
321 if (BGP_DEBUG(zebra
, ZEBRA
))
322 zlog_debug("RID change : vrf %u, RTR ID %s",
323 bgp
->vrf_id
, inet_ntoa(*addr
));
324 bgp_router_id_set(bgp
, addr
);
332 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
334 bgp
->router_id_static
= id
;
335 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
339 /* BGP's cluster-id control. */
340 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
343 struct listnode
*node
, *nnode
;
345 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
346 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
349 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
350 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
352 /* Clear all IBGP peer. */
353 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
354 if (peer
->sort
!= BGP_PEER_IBGP
)
357 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
358 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
366 int bgp_cluster_id_unset(struct bgp
*bgp
)
369 struct listnode
*node
, *nnode
;
371 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
374 bgp
->cluster_id
.s_addr
= 0;
375 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
377 /* Clear all IBGP peer. */
378 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
379 if (peer
->sort
!= BGP_PEER_IBGP
)
382 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
383 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
384 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
385 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
391 /* time_t value that is monotonicly increasing
392 * and uneffected by adjustments to system clock
394 time_t bgp_clock(void)
402 /* BGP timer configuration. */
403 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
405 bgp
->default_keepalive
=
406 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
407 bgp
->default_holdtime
= holdtime
;
412 int bgp_timers_unset(struct bgp
*bgp
)
414 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
415 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
420 /* BGP confederation configuration. */
421 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
424 struct listnode
*node
, *nnode
;
428 return BGP_ERR_INVALID_AS
;
430 /* Remember - were we doing confederation before? */
431 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
433 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
435 /* If we were doing confederation already, this is just an external
436 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
437 were not doing confederation before, reset all EBGP sessions. */
438 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
439 /* We're looking for peers who's AS is not local or part of our
441 if (already_confed
) {
442 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
444 if (BGP_IS_VALID_STATE_FOR_NOTIF(
447 PEER_DOWN_CONFED_ID_CHANGE
;
449 peer
, BGP_NOTIFY_CEASE
,
450 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
452 bgp_session_reset_safe(peer
, &nnode
);
455 /* Not doign confederation before, so reset every
458 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
459 /* Reset the local_as to be our EBGP one */
460 if (peer_sort(peer
) == BGP_PEER_EBGP
)
462 if (BGP_IS_VALID_STATE_FOR_NOTIF(
465 PEER_DOWN_CONFED_ID_CHANGE
;
467 peer
, BGP_NOTIFY_CEASE
,
468 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
470 bgp_session_reset_safe(peer
, &nnode
);
477 int bgp_confederation_id_unset(struct bgp
*bgp
)
480 struct listnode
*node
, *nnode
;
483 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
485 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
486 /* We're looking for peers who's AS is not local */
487 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
488 peer
->local_as
= bgp
->as
;
489 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
490 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
491 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
492 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
496 bgp_session_reset_safe(peer
, &nnode
);
502 /* Is an AS part of the confed or not? */
503 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
510 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
511 if (bgp
->confed_peers
[i
] == as
)
517 /* Add an AS to the confederation set. */
518 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
521 struct listnode
*node
, *nnode
;
524 return BGP_ERR_INVALID_BGP
;
527 return BGP_ERR_INVALID_AS
;
529 if (bgp_confederation_peers_check(bgp
, as
))
532 if (bgp
->confed_peers
)
534 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
535 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
538 XMALLOC(MTYPE_BGP_CONFED_LIST
,
539 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
541 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
542 bgp
->confed_peers_cnt
++;
544 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
545 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
546 if (peer
->as
== as
) {
547 peer
->local_as
= bgp
->as
;
548 if (BGP_IS_VALID_STATE_FOR_NOTIF(
551 PEER_DOWN_CONFED_PEER_CHANGE
;
553 peer
, BGP_NOTIFY_CEASE
,
554 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
556 bgp_session_reset_safe(peer
, &nnode
);
563 /* Delete an AS from the confederation set. */
564 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
569 struct listnode
*node
, *nnode
;
574 if (!bgp_confederation_peers_check(bgp
, as
))
577 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
578 if (bgp
->confed_peers
[i
] == as
)
579 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
580 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
582 bgp
->confed_peers_cnt
--;
584 if (bgp
->confed_peers_cnt
== 0) {
585 if (bgp
->confed_peers
)
586 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
587 bgp
->confed_peers
= NULL
;
590 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
591 bgp
->confed_peers_cnt
* sizeof(as_t
));
593 /* Now reset any peer who's remote AS has just been removed from the
595 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
596 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
597 if (peer
->as
== as
) {
598 peer
->local_as
= bgp
->confed_id
;
599 if (BGP_IS_VALID_STATE_FOR_NOTIF(
602 PEER_DOWN_CONFED_PEER_CHANGE
;
604 peer
, BGP_NOTIFY_CEASE
,
605 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
607 bgp_session_reset_safe(peer
, &nnode
);
615 /* Local preference configuration. */
616 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
621 bgp
->default_local_pref
= local_pref
;
626 int bgp_default_local_preference_unset(struct bgp
*bgp
)
631 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
636 /* Local preference configuration. */
637 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
642 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
647 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
651 bgp
->default_subgroup_pkt_queue_max
=
652 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
657 /* Listen limit configuration. */
658 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
663 bgp
->dynamic_neighbors_limit
= listen_limit
;
668 int bgp_listen_limit_unset(struct bgp
*bgp
)
673 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
678 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
679 afi_t
*afi
, safi_t
*safi
)
681 /* Map from IANA values to internal values, return error if
682 * values are unrecognized.
684 *afi
= afi_iana2int(pkt_afi
);
685 *safi
= safi_iana2int(pkt_safi
);
686 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
692 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
693 iana_safi_t
*pkt_safi
)
695 /* Map from internal values to IANA values, return error if
696 * internal values are bad (unexpected).
698 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
700 *pkt_afi
= afi_int2iana(afi
);
701 *pkt_safi
= safi_int2iana(safi
);
705 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
713 afid
= afindex(afi
, safi
);
714 if (afid
>= BGP_AF_MAX
)
717 assert(peer
->peer_af_array
[afid
] == NULL
);
719 /* Allocate new peer af */
720 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
722 peer
->peer_af_array
[afid
] = af
;
731 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
738 afid
= afindex(afi
, safi
);
739 if (afid
>= BGP_AF_MAX
)
742 return peer
->peer_af_array
[afid
];
745 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
753 afid
= afindex(afi
, safi
);
754 if (afid
>= BGP_AF_MAX
)
757 af
= peer
->peer_af_array
[afid
];
761 bgp_stop_announce_route_timer(af
);
763 if (PAF_SUBGRP(af
)) {
764 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
765 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
766 af
->subgroup
->update_group
->id
,
767 af
->subgroup
->id
, peer
->host
);
770 update_subgroup_remove_peer(af
->subgroup
, af
);
772 peer
->peer_af_array
[afid
] = NULL
;
773 XFREE(MTYPE_BGP_PEER_AF
, af
);
777 /* Peer comparison function for sorting. */
778 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
780 if (p1
->group
&& !p2
->group
)
783 if (!p1
->group
&& p2
->group
)
786 if (p1
->group
== p2
->group
) {
787 if (p1
->conf_if
&& !p2
->conf_if
)
790 if (!p1
->conf_if
&& p2
->conf_if
)
793 if (p1
->conf_if
&& p2
->conf_if
)
794 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
796 return strcmp(p1
->group
->name
, p2
->group
->name
);
798 return sockunion_cmp(&p1
->su
, &p2
->su
);
801 static unsigned int peer_hash_key_make(void *p
)
803 struct peer
*peer
= p
;
804 return sockunion_hash(&peer
->su
);
807 static bool peer_hash_same(const void *p1
, const void *p2
)
809 const struct peer
*peer1
= p1
;
810 const struct peer
*peer2
= p2
;
811 return (sockunion_same(&peer1
->su
, &peer2
->su
)
812 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
813 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
816 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
820 /* Skip if peer is not a peer-group member. */
821 if (!peer_group_active(peer
))
824 /* Unset override flag to signal inheritance from peer-group. */
825 UNSET_FLAG(peer
->flags_override
, flag
);
828 * Inherit flag state from peer-group. If the flag of the peer-group is
829 * not being inverted, the peer must inherit the inverse of the current
830 * peer-group flag state.
832 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
833 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
834 && CHECK_FLAG(peer
->flags_invert
, flag
))
835 COND_FLAG(peer
->flags
, flag
, !group_val
);
837 COND_FLAG(peer
->flags
, flag
, group_val
);
840 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
842 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
845 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
850 /* Skip if peer is not a peer-group member. */
851 if (!peer_group_active(peer
))
854 /* Unset override flag to signal inheritance from peer-group. */
855 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
858 * Inherit flag state from peer-group. If the flag of the peer-group is
859 * not being inverted, the peer must inherit the inverse of the current
860 * peer-group flag state.
862 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
863 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
864 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
865 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
867 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
870 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
872 if (!peer_group_active(peer
)) {
873 if (CHECK_FLAG(peer
->flags_invert
, flag
))
874 return !CHECK_FLAG(peer
->flags
, flag
);
876 return !!CHECK_FLAG(peer
->flags
, flag
);
879 return !!CHECK_FLAG(peer
->flags_override
, flag
);
882 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
885 if (!peer_group_active(peer
)) {
886 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
887 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
889 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
892 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
895 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
896 uint8_t type
, int direct
)
898 struct bgp_filter
*filter
;
900 if (peer_group_active(peer
))
901 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
904 filter
= &peer
->filter
[afi
][safi
];
906 case PEER_FT_DISTRIBUTE_LIST
:
907 return !!(filter
->dlist
[direct
].name
);
908 case PEER_FT_FILTER_LIST
:
909 return !!(filter
->aslist
[direct
].name
);
910 case PEER_FT_PREFIX_LIST
:
911 return !!(filter
->plist
[direct
].name
);
912 case PEER_FT_ROUTE_MAP
:
913 return !!(filter
->map
[direct
].name
);
914 case PEER_FT_UNSUPPRESS_MAP
:
915 return !!(filter
->usmap
.name
);
921 /* Return true if the addpath type is set for peer and different from
924 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
926 enum bgp_addpath_strat type
, g_type
;
928 type
= peer
->addpath_type
[afi
][safi
];
930 if (type
!= BGP_ADDPATH_NONE
) {
931 if (peer_group_active(peer
)) {
932 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
946 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
947 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
954 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
955 if (peer
->as_type
== AS_INTERNAL
)
956 return BGP_PEER_IBGP
;
958 else if (peer
->as_type
== AS_EXTERNAL
)
959 return BGP_PEER_EBGP
;
961 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
963 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
971 peer1
= listnode_head(peer
->group
->peer
);
976 return BGP_PEER_INTERNAL
;
980 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
981 if (peer
->local_as
== 0)
982 return BGP_PEER_INTERNAL
;
984 if (peer
->local_as
== peer
->as
) {
985 if (bgp
->as
== bgp
->confed_id
) {
986 if (peer
->local_as
== bgp
->as
)
987 return BGP_PEER_IBGP
;
989 return BGP_PEER_EBGP
;
991 if (peer
->local_as
== bgp
->confed_id
)
992 return BGP_PEER_EBGP
;
994 return BGP_PEER_IBGP
;
998 if (bgp_confederation_peers_check(bgp
, peer
->as
))
999 return BGP_PEER_CONFED
;
1001 return BGP_PEER_EBGP
;
1003 if (peer
->as_type
!= AS_SPECIFIED
)
1004 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1007 return (peer
->local_as
== 0
1009 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1014 /* Calculate and cache the peer "sort" */
1015 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1017 peer
->sort
= peer_calc_sort(peer
);
1021 static void peer_free(struct peer
*peer
)
1026 assert(peer
->status
== Deleted
);
1030 /* this /ought/ to have been done already through bgp_stop earlier,
1031 * but just to be sure..
1033 bgp_timer_set(peer
);
1034 bgp_reads_off(peer
);
1035 bgp_writes_off(peer
);
1036 assert(!peer
->t_write
);
1037 assert(!peer
->t_read
);
1038 BGP_EVENT_FLUSH(peer
);
1040 pthread_mutex_destroy(&peer
->io_mtx
);
1042 /* Free connected nexthop, if present */
1043 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1044 && !peer_dynamic_neighbor(peer
))
1045 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1048 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1051 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1055 /* Free allocated host character. */
1057 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1061 if (peer
->domainname
) {
1062 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1063 peer
->domainname
= NULL
;
1067 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1068 peer
->ifname
= NULL
;
1071 /* Update source configuration. */
1072 if (peer
->update_source
) {
1073 sockunion_free(peer
->update_source
);
1074 peer
->update_source
= NULL
;
1077 if (peer
->update_if
) {
1078 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1079 peer
->update_if
= NULL
;
1082 if (peer
->notify
.data
)
1083 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1084 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1086 if (peer
->clear_node_queue
)
1087 work_queue_free_and_null(&peer
->clear_node_queue
);
1089 bgp_sync_delete(peer
);
1091 if (peer
->conf_if
) {
1092 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1093 peer
->conf_if
= NULL
;
1096 bfd_info_free(&(peer
->bfd_info
));
1098 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1099 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1100 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1105 bgp_unlock(peer
->bgp
);
1107 memset(peer
, 0, sizeof(struct peer
));
1109 XFREE(MTYPE_BGP_PEER
, peer
);
1112 /* increase reference count on a struct peer */
1113 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1115 assert(peer
&& (peer
->lock
>= 0));
1118 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1126 /* decrease reference count on a struct peer
1127 * struct peer is freed and NULL returned if last reference
1129 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1131 assert(peer
&& (peer
->lock
> 0));
1134 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1139 if (peer
->lock
== 0) {
1147 /* Allocate new peer object, implicitely locked. */
1148 struct peer
*peer_new(struct bgp
*bgp
)
1155 /* bgp argument is absolutely required */
1160 /* Allocate new peer. */
1161 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1163 /* Set default value. */
1165 peer
->v_start
= BGP_INIT_START_TIMER
;
1166 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1167 peer
->status
= Idle
;
1168 peer
->ostatus
= Idle
;
1169 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1170 peer
->bgp
= bgp_lock(bgp
);
1171 peer
= peer_lock(peer
); /* initial reference */
1172 peer
->password
= NULL
;
1174 /* Set default flags. */
1175 FOREACH_AFI_SAFI (afi
, safi
) {
1176 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1177 SET_FLAG(peer
->af_flags
[afi
][safi
],
1178 PEER_FLAG_SEND_COMMUNITY
);
1179 SET_FLAG(peer
->af_flags
[afi
][safi
],
1180 PEER_FLAG_SEND_EXT_COMMUNITY
);
1181 SET_FLAG(peer
->af_flags
[afi
][safi
],
1182 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1184 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1185 PEER_FLAG_SEND_COMMUNITY
);
1186 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1187 PEER_FLAG_SEND_EXT_COMMUNITY
);
1188 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1189 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1191 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1194 /* set nexthop-unchanged for l2vpn evpn by default */
1195 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1196 PEER_FLAG_NEXTHOP_UNCHANGED
);
1198 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1200 /* Create buffers. */
1201 peer
->ibuf
= stream_fifo_new();
1202 peer
->obuf
= stream_fifo_new();
1203 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1205 /* We use a larger buffer for peer->obuf_work in the event that:
1206 * - We RX a BGP_UPDATE where the attributes alone are just
1207 * under BGP_MAX_PACKET_SIZE
1208 * - The user configures an outbound route-map that does many as-path
1209 * prepends or adds many communities. At most they can have
1210 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1211 * large they can make the attributes.
1213 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1214 * bounds checking for every single attribute as we construct an
1218 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1220 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1222 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1224 bgp_sync_init(peer
);
1226 /* Get service port number. */
1227 sp
= getservbyname("bgp", "tcp");
1228 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1230 QOBJ_REG(peer
, peer
);
1235 * This function is invoked when a duplicate peer structure associated with
1236 * a neighbor is being deleted. If this about-to-be-deleted structure is
1237 * the one with all the config, then we have to copy over the info.
1239 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1241 struct peer_af
*paf
;
1249 /* The following function is used by both peer group config copy to
1250 * individual peer and when we transfer config
1252 if (peer_src
->change_local_as
)
1253 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1255 /* peer flags apply */
1256 peer_dst
->flags
= peer_src
->flags
;
1257 peer_dst
->cap
= peer_src
->cap
;
1259 peer_dst
->local_as
= peer_src
->local_as
;
1260 peer_dst
->port
= peer_src
->port
;
1261 (void)peer_sort(peer_dst
);
1262 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1265 peer_dst
->holdtime
= peer_src
->holdtime
;
1266 peer_dst
->keepalive
= peer_src
->keepalive
;
1267 peer_dst
->connect
= peer_src
->connect
;
1268 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1269 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1270 peer_dst
->routeadv
= peer_src
->routeadv
;
1271 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1273 /* password apply */
1274 if (peer_src
->password
&& !peer_dst
->password
)
1275 peer_dst
->password
=
1276 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1278 FOREACH_AFI_SAFI (afi
, safi
) {
1279 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1280 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1281 peer_dst
->allowas_in
[afi
][safi
] =
1282 peer_src
->allowas_in
[afi
][safi
];
1283 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1284 peer_dst
->addpath_type
[afi
][safi
] =
1285 peer_src
->addpath_type
[afi
][safi
];
1288 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1289 paf
= peer_src
->peer_af_array
[afidx
];
1291 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1294 /* update-source apply */
1295 if (peer_src
->update_source
) {
1296 if (peer_dst
->update_source
)
1297 sockunion_free(peer_dst
->update_source
);
1298 if (peer_dst
->update_if
) {
1299 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1300 peer_dst
->update_if
= NULL
;
1302 peer_dst
->update_source
=
1303 sockunion_dup(peer_src
->update_source
);
1304 } else if (peer_src
->update_if
) {
1305 if (peer_dst
->update_if
)
1306 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1307 if (peer_dst
->update_source
) {
1308 sockunion_free(peer_dst
->update_source
);
1309 peer_dst
->update_source
= NULL
;
1311 peer_dst
->update_if
=
1312 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1315 if (peer_src
->ifname
) {
1316 if (peer_dst
->ifname
)
1317 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1320 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1324 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1325 struct interface
*ifp
)
1327 struct connected
*ifc
;
1330 struct listnode
*node
;
1332 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1333 * IPv4 address of the other end.
1335 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1336 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1337 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1338 if (p
.prefixlen
== 30) {
1339 peer
->su
.sa
.sa_family
= AF_INET
;
1340 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1342 peer
->su
.sin
.sin_addr
.s_addr
=
1344 else if (addr
% 4 == 2)
1345 peer
->su
.sin
.sin_addr
.s_addr
=
1347 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1348 peer
->su
.sin
.sin_len
=
1349 sizeof(struct sockaddr_in
);
1350 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1352 } else if (p
.prefixlen
== 31) {
1353 peer
->su
.sa
.sa_family
= AF_INET
;
1354 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1356 peer
->su
.sin
.sin_addr
.s_addr
=
1359 peer
->su
.sin
.sin_addr
.s_addr
=
1361 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1362 peer
->su
.sin
.sin_len
=
1363 sizeof(struct sockaddr_in
);
1364 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1366 } else if (bgp_debug_neighbor_events(peer
))
1368 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1376 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1377 struct interface
*ifp
)
1379 struct nbr_connected
*ifc_nbr
;
1381 /* Have we learnt the peer's IPv6 link-local address? */
1382 if (ifp
->nbr_connected
1383 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1384 peer
->su
.sa
.sa_family
= AF_INET6
;
1385 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1386 sizeof(struct in6_addr
));
1388 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1390 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1398 * Set or reset the peer address socketunion structure based on the
1399 * learnt/derived peer address. If the address has changed, update the
1400 * password on the listen socket, if needed.
1402 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1404 struct interface
*ifp
;
1406 int peer_addr_updated
= 0;
1412 * Our peer structure is stored in the bgp->peerhash
1413 * release it before we modify anything.
1415 hash_release(peer
->bgp
->peerhash
, peer
);
1417 prev_family
= peer
->su
.sa
.sa_family
;
1418 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1420 /* If BGP unnumbered is not "v6only", we first see if we can
1422 * peer's IPv4 address.
1424 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1426 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1428 /* If "v6only" or we can't derive peer's IPv4 address, see if
1430 * learnt the peer's IPv6 link-local address. This is from the
1432 * IPv6 address in router advertisement.
1434 if (!peer_addr_updated
)
1436 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1438 /* If we could derive the peer address, we may need to install the
1440 * configured for the peer, if any, on the listen socket. Otherwise,
1442 * that peer's address is not available and uninstall the password, if
1445 if (peer_addr_updated
) {
1446 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1447 && prev_family
== AF_UNSPEC
)
1450 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1451 && prev_family
!= AF_UNSPEC
)
1452 bgp_md5_unset(peer
);
1453 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1454 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1458 * Since our su changed we need to del/add peer to the peerhash
1460 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1463 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1466 struct bgp_node
*rn
, *nrn
;
1468 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1469 rn
= bgp_route_next(rn
)) {
1470 if (rn
->info
!= NULL
) {
1471 /* Special handling for 2-level routing
1473 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1474 || safi
== SAFI_EVPN
) {
1475 for (nrn
= bgp_table_top(
1476 (struct bgp_table
*)(rn
->info
));
1477 nrn
; nrn
= bgp_route_next(nrn
))
1478 bgp_process(bgp
, nrn
, afi
, safi
);
1480 bgp_process(bgp
, rn
, afi
, safi
);
1485 /* Force a bestpath recalculation for all prefixes. This is used
1486 * when 'bgp bestpath' commands are entered.
1488 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1493 FOREACH_AFI_SAFI (afi
, safi
) {
1494 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1499 * Create new BGP peer.
1501 * conf_if and su are mutually exclusive if configuring from the cli.
1502 * If we are handing a doppelganger, then we *must* pass in both
1503 * the original peer's su and conf_if, so that we can appropriately
1504 * track the bgp->peerhash( ie we don't want to remove the current
1505 * one from the config ).
1507 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1508 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1509 int as_type
, afi_t afi
, safi_t safi
,
1510 struct peer_group
*group
)
1514 char buf
[SU_ADDRSTRLEN
];
1516 peer
= peer_new(bgp
);
1518 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1522 bgp_peer_conf_if_to_su_update(peer
);
1524 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1525 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1528 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1530 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1531 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1533 peer
->local_as
= local_as
;
1534 peer
->as
= remote_as
;
1535 peer
->as_type
= as_type
;
1536 peer
->local_id
= bgp
->router_id
;
1537 peer
->v_holdtime
= bgp
->default_holdtime
;
1538 peer
->v_keepalive
= bgp
->default_keepalive
;
1539 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1540 ? BGP_DEFAULT_IBGP_ROUTEADV
1541 : BGP_DEFAULT_EBGP_ROUTEADV
;
1543 peer
= peer_lock(peer
); /* bgp peer list reference */
1544 peer
->group
= group
;
1545 listnode_add_sort(bgp
->peer
, peer
);
1546 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1548 /* Adjust update-group coalesce timer heuristics for # peers. */
1549 if (bgp
->heuristic_coalesce
) {
1550 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1552 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1553 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1556 active
= peer_active(peer
);
1558 /* Last read and reset time set */
1559 peer
->readtime
= peer
->resettime
= bgp_clock();
1561 /* Default TTL set. */
1562 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1564 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1567 peer
->afc
[afi
][safi
] = 1;
1568 peer_af_create(peer
, afi
, safi
);
1571 /* auto shutdown if configured */
1572 if (bgp
->autoshutdown
)
1573 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1574 /* Set up peer's events and timers. */
1575 else if (!active
&& peer_active(peer
))
1576 bgp_timer_set(peer
);
1581 /* Make accept BGP peer. This function is only called from the test code */
1582 struct peer
*peer_create_accept(struct bgp
*bgp
)
1586 peer
= peer_new(bgp
);
1588 peer
= peer_lock(peer
); /* bgp peer list reference */
1589 listnode_add_sort(bgp
->peer
, peer
);
1595 * Return true if we have a peer configured to use this afi/safi
1597 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1599 struct listnode
*node
;
1602 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1603 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1606 if (peer
->afc
[afi
][safi
])
1613 /* Change peer's AS number. */
1614 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1616 bgp_peer_sort_t type
;
1619 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1620 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1621 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1622 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1623 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1625 bgp_session_reset(peer
);
1627 type
= peer_sort(peer
);
1629 peer
->as_type
= as_specified
;
1631 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1632 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1633 && peer
->bgp
->as
!= as
)
1634 peer
->local_as
= peer
->bgp
->confed_id
;
1636 peer
->local_as
= peer
->bgp
->as
;
1638 /* Advertisement-interval reset */
1639 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1640 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1641 ? BGP_DEFAULT_IBGP_ROUTEADV
1642 : BGP_DEFAULT_EBGP_ROUTEADV
;
1646 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1648 else if (type
== BGP_PEER_IBGP
)
1651 /* reflector-client reset */
1652 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1653 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1654 PEER_FLAG_REFLECTOR_CLIENT
);
1655 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1656 PEER_FLAG_REFLECTOR_CLIENT
);
1657 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1658 PEER_FLAG_REFLECTOR_CLIENT
);
1659 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1660 PEER_FLAG_REFLECTOR_CLIENT
);
1661 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1662 PEER_FLAG_REFLECTOR_CLIENT
);
1663 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1664 PEER_FLAG_REFLECTOR_CLIENT
);
1665 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1666 PEER_FLAG_REFLECTOR_CLIENT
);
1667 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1668 PEER_FLAG_REFLECTOR_CLIENT
);
1669 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1670 PEER_FLAG_REFLECTOR_CLIENT
);
1671 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1672 PEER_FLAG_REFLECTOR_CLIENT
);
1673 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1674 PEER_FLAG_REFLECTOR_CLIENT
);
1675 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1676 PEER_FLAG_REFLECTOR_CLIENT
);
1677 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1678 PEER_FLAG_REFLECTOR_CLIENT
);
1681 /* local-as reset */
1682 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1683 peer
->change_local_as
= 0;
1684 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1685 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1686 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1690 /* If peer does not exist, create new one. If peer already exists,
1691 set AS number to the peer. */
1692 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1693 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1699 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1701 peer
= peer_lookup(bgp
, su
);
1704 /* Not allowed for a dynamic peer. */
1705 if (peer_dynamic_neighbor(peer
)) {
1707 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1710 /* When this peer is a member of peer-group. */
1712 if (peer
->group
->conf
->as
) {
1713 /* Return peer group's AS number. */
1714 *as
= peer
->group
->conf
->as
;
1715 return BGP_ERR_PEER_GROUP_MEMBER
;
1717 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1718 if ((as_type
!= AS_INTERNAL
)
1719 && (bgp
->as
!= *as
)) {
1721 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1724 if ((as_type
!= AS_EXTERNAL
)
1725 && (bgp
->as
== *as
)) {
1727 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1732 /* Existing peer's AS number change. */
1733 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1734 || (peer
->as_type
!= as_type
))
1735 peer_as_change(peer
, *as
, as_type
);
1738 return BGP_ERR_NO_INTERFACE_CONFIG
;
1740 /* If the peer is not part of our confederation, and its not an
1741 iBGP peer then spoof the source AS */
1742 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1743 && !bgp_confederation_peers_check(bgp
, *as
)
1745 local_as
= bgp
->confed_id
;
1749 /* If this is IPv4 unicast configuration and "no bgp default
1750 ipv4-unicast" is specified. */
1752 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1753 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1754 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1757 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1764 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1765 struct peer
*peer
, afi_t afi
,
1769 int out
= FILTER_OUT
;
1771 uint32_t pflags_ovrd
;
1772 uint8_t *pfilter_ovrd
;
1776 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1777 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1779 /* peer af_flags apply */
1780 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1781 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1782 ^ peer
->af_flags_invert
[afi
][safi
];
1783 flags_tmp
&= ~pflags_ovrd
;
1785 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1786 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1787 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1788 conf
->af_flags_invert
[afi
][safi
]);
1790 /* maximum-prefix */
1791 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1792 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1793 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1794 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1798 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1799 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1802 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1803 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1805 /* default-originate route-map */
1806 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1807 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1808 MTYPE_ROUTE_MAP_NAME
);
1809 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1812 /* inbound filter apply */
1813 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1814 PEER_STR_ATTR_INHERIT(peer
, group
,
1815 filter
[afi
][safi
].dlist
[in
].name
,
1816 MTYPE_BGP_FILTER_NAME
);
1817 PEER_ATTR_INHERIT(peer
, group
,
1818 filter
[afi
][safi
].dlist
[in
].alist
);
1821 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1822 PEER_STR_ATTR_INHERIT(peer
, group
,
1823 filter
[afi
][safi
].plist
[in
].name
,
1824 MTYPE_BGP_FILTER_NAME
);
1825 PEER_ATTR_INHERIT(peer
, group
,
1826 filter
[afi
][safi
].plist
[in
].plist
);
1829 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1830 PEER_STR_ATTR_INHERIT(peer
, group
,
1831 filter
[afi
][safi
].aslist
[in
].name
,
1832 MTYPE_BGP_FILTER_NAME
);
1833 PEER_ATTR_INHERIT(peer
, group
,
1834 filter
[afi
][safi
].aslist
[in
].aslist
);
1837 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1838 PEER_STR_ATTR_INHERIT(peer
, group
,
1839 filter
[afi
][safi
].map
[in
].name
,
1840 MTYPE_BGP_FILTER_NAME
);
1841 PEER_ATTR_INHERIT(peer
, group
,
1842 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1845 /* outbound filter apply */
1846 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1847 PEER_STR_ATTR_INHERIT(peer
, group
,
1848 filter
[afi
][safi
].dlist
[out
].name
,
1849 MTYPE_BGP_FILTER_NAME
);
1850 PEER_ATTR_INHERIT(peer
, group
,
1851 filter
[afi
][safi
].dlist
[out
].alist
);
1854 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1855 PEER_STR_ATTR_INHERIT(peer
, group
,
1856 filter
[afi
][safi
].plist
[out
].name
,
1857 MTYPE_BGP_FILTER_NAME
);
1858 PEER_ATTR_INHERIT(peer
, group
,
1859 filter
[afi
][safi
].plist
[out
].plist
);
1862 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1863 PEER_STR_ATTR_INHERIT(peer
, group
,
1864 filter
[afi
][safi
].aslist
[out
].name
,
1865 MTYPE_BGP_FILTER_NAME
);
1866 PEER_ATTR_INHERIT(peer
, group
,
1867 filter
[afi
][safi
].aslist
[out
].aslist
);
1870 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1871 PEER_STR_ATTR_INHERIT(peer
, group
,
1872 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1873 MTYPE_BGP_FILTER_NAME
);
1874 PEER_ATTR_INHERIT(peer
, group
,
1875 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1878 /* nondirectional filter apply */
1879 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1880 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1881 MTYPE_BGP_FILTER_NAME
);
1882 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1885 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1886 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1887 bgp_addpath_type_changed(conf
->bgp
);
1891 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1896 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1897 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1898 __func__
, peer
->host
);
1902 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1904 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1905 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1906 return BGP_ERR_PEER_SAFI_CONFLICT
;
1908 /* Nothing to do if we've already activated this peer */
1909 if (peer
->afc
[afi
][safi
])
1912 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1915 active
= peer_active(peer
);
1916 peer
->afc
[afi
][safi
] = 1;
1919 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1921 if (!active
&& peer_active(peer
)) {
1922 bgp_timer_set(peer
);
1924 if (peer
->status
== Established
) {
1925 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1926 peer
->afc_adv
[afi
][safi
] = 1;
1927 bgp_capability_send(peer
, afi
, safi
,
1929 CAPABILITY_ACTION_SET
);
1930 if (peer
->afc_recv
[afi
][safi
]) {
1931 peer
->afc_nego
[afi
][safi
] = 1;
1932 bgp_announce_route(peer
, afi
, safi
);
1935 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1936 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1937 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1940 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1941 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1942 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1943 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1946 * If we are turning on a AFI/SAFI locally and we've
1947 * started bringing a peer up, we need to tell
1948 * the other peer to restart because we might loose
1949 * configuration here because when the doppelganger
1950 * gets to a established state due to how
1951 * we resolve we could just overwrite the afi/safi
1954 other
= peer
->doppelganger
;
1956 && (other
->status
== OpenSent
1957 || other
->status
== OpenConfirm
)) {
1958 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1959 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1960 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1967 /* Activate the peer or peer group for specified AFI and SAFI. */
1968 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1971 struct peer_group
*group
;
1972 struct listnode
*node
, *nnode
;
1973 struct peer
*tmp_peer
;
1976 /* Nothing to do if we've already activated this peer */
1977 if (peer
->afc
[afi
][safi
])
1982 /* This is a peer-group so activate all of the members of the
1983 * peer-group as well */
1984 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1986 /* Do not activate a peer for both SAFI_UNICAST and
1987 * SAFI_LABELED_UNICAST */
1988 if ((safi
== SAFI_UNICAST
1989 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1990 || (safi
== SAFI_LABELED_UNICAST
1991 && peer
->afc
[afi
][SAFI_UNICAST
]))
1992 return BGP_ERR_PEER_SAFI_CONFLICT
;
1994 peer
->afc
[afi
][safi
] = 1;
1995 group
= peer
->group
;
1997 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1998 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2001 ret
|= peer_activate_af(peer
, afi
, safi
);
2004 /* If this is the first peer to be activated for this
2005 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2006 if (safi
== SAFI_LABELED_UNICAST
2007 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2009 if (BGP_DEBUG(zebra
, ZEBRA
))
2011 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2013 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2014 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2017 if (safi
== SAFI_FLOWSPEC
) {
2018 /* connect to table manager */
2019 bgp_zebra_init_tm_connect(bgp
);
2024 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2027 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2028 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2029 __func__
, peer
->host
);
2033 /* Nothing to do if we've already deactivated this peer */
2034 if (!peer
->afc
[afi
][safi
])
2037 /* De-activate the address family configuration. */
2038 peer
->afc
[afi
][safi
] = 0;
2040 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2041 flog_err(EC_BGP_PEER_DELETE
,
2042 "couldn't delete af structure for peer %s",
2047 if (peer
->status
== Established
) {
2048 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2049 peer
->afc_adv
[afi
][safi
] = 0;
2050 peer
->afc_nego
[afi
][safi
] = 0;
2052 if (peer_active_nego(peer
)) {
2053 bgp_capability_send(peer
, afi
, safi
,
2055 CAPABILITY_ACTION_UNSET
);
2056 bgp_clear_route(peer
, afi
, safi
);
2057 peer
->pcount
[afi
][safi
] = 0;
2059 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2060 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2061 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2064 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2065 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2066 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2073 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2076 struct peer_group
*group
;
2077 struct peer
*tmp_peer
;
2078 struct listnode
*node
, *nnode
;
2081 /* Nothing to do if we've already de-activated this peer */
2082 if (!peer
->afc
[afi
][safi
])
2085 /* This is a peer-group so de-activate all of the members of the
2086 * peer-group as well */
2087 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2088 peer
->afc
[afi
][safi
] = 0;
2089 group
= peer
->group
;
2091 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2092 flog_err(EC_BGP_PEER_DELETE
,
2093 "couldn't delete af structure for peer %s",
2097 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2098 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2101 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2106 /* If this is the last peer to be deactivated for this
2107 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2108 if (safi
== SAFI_LABELED_UNICAST
2109 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2110 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2112 if (BGP_DEBUG(zebra
, ZEBRA
))
2114 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2116 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2117 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2122 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2125 return peer_activate(peer
, afi
, safi
);
2127 return peer_deactivate(peer
, afi
, safi
);
2130 static void peer_nsf_stop(struct peer
*peer
)
2135 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2136 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2138 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2139 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2140 peer
->nsf
[afi
][safi
] = 0;
2142 if (peer
->t_gr_restart
) {
2143 BGP_TIMER_OFF(peer
->t_gr_restart
);
2144 if (bgp_debug_neighbor_events(peer
))
2145 zlog_debug("%s graceful restart timer stopped",
2148 if (peer
->t_gr_stale
) {
2149 BGP_TIMER_OFF(peer
->t_gr_stale
);
2150 if (bgp_debug_neighbor_events(peer
))
2152 "%s graceful restart stalepath timer stopped",
2155 bgp_clear_route_all(peer
);
2158 /* Delete peer from confguration.
2160 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2161 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2163 * This function /should/ take care to be idempotent, to guard against
2164 * it being called multiple times through stray events that come in
2165 * that happen to result in this function being called again. That
2166 * said, getting here for a "Deleted" peer is a bug in the neighbour
2169 int peer_delete(struct peer
*peer
)
2175 struct bgp_filter
*filter
;
2176 struct listnode
*pn
;
2179 assert(peer
->status
!= Deleted
);
2182 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2184 bgp_reads_off(peer
);
2185 bgp_writes_off(peer
);
2186 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2187 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2189 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2190 peer_nsf_stop(peer
);
2192 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2194 /* If this peer belongs to peer group, clear up the
2197 if (peer_dynamic_neighbor(peer
))
2198 peer_drop_dynamic_neighbor(peer
);
2200 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2202 peer
); /* group->peer list reference */
2203 list_delete_node(peer
->group
->peer
, pn
);
2208 /* Withdraw all information from routing table. We can not use
2209 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2210 * executed after peer structure is deleted.
2212 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2214 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2216 if (peer
->doppelganger
) {
2217 peer
->doppelganger
->doppelganger
= NULL
;
2218 peer
->doppelganger
= NULL
;
2221 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2222 bgp_fsm_change_status(peer
, Deleted
);
2224 /* Remove from NHT */
2225 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2226 bgp_unlink_nexthop_by_peer(peer
);
2228 /* Password configuration */
2229 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2230 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2232 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2233 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2234 bgp_md5_unset(peer
);
2237 bgp_timer_set(peer
); /* stops all timers for Deleted */
2239 /* Delete from all peer list. */
2240 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2241 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2242 peer_unlock(peer
); /* bgp peer list reference */
2243 list_delete_node(bgp
->peer
, pn
);
2244 hash_release(bgp
->peerhash
, peer
);
2249 stream_fifo_free(peer
->ibuf
);
2254 stream_fifo_free(peer
->obuf
);
2258 if (peer
->ibuf_work
) {
2259 ringbuf_del(peer
->ibuf_work
);
2260 peer
->ibuf_work
= NULL
;
2263 if (peer
->obuf_work
) {
2264 stream_free(peer
->obuf_work
);
2265 peer
->obuf_work
= NULL
;
2268 if (peer
->scratch
) {
2269 stream_free(peer
->scratch
);
2270 peer
->scratch
= NULL
;
2273 /* Local and remote addresses. */
2274 if (peer
->su_local
) {
2275 sockunion_free(peer
->su_local
);
2276 peer
->su_local
= NULL
;
2279 if (peer
->su_remote
) {
2280 sockunion_free(peer
->su_remote
);
2281 peer
->su_remote
= NULL
;
2284 /* Free filter related memory. */
2285 FOREACH_AFI_SAFI (afi
, safi
) {
2286 filter
= &peer
->filter
[afi
][safi
];
2288 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2289 if (filter
->dlist
[i
].name
) {
2290 XFREE(MTYPE_BGP_FILTER_NAME
,
2291 filter
->dlist
[i
].name
);
2292 filter
->dlist
[i
].name
= NULL
;
2295 if (filter
->plist
[i
].name
) {
2296 XFREE(MTYPE_BGP_FILTER_NAME
,
2297 filter
->plist
[i
].name
);
2298 filter
->plist
[i
].name
= NULL
;
2301 if (filter
->aslist
[i
].name
) {
2302 XFREE(MTYPE_BGP_FILTER_NAME
,
2303 filter
->aslist
[i
].name
);
2304 filter
->aslist
[i
].name
= NULL
;
2308 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2309 if (filter
->map
[i
].name
) {
2310 XFREE(MTYPE_BGP_FILTER_NAME
,
2311 filter
->map
[i
].name
);
2312 filter
->map
[i
].name
= NULL
;
2316 if (filter
->usmap
.name
) {
2317 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2318 filter
->usmap
.name
= NULL
;
2321 if (peer
->default_rmap
[afi
][safi
].name
) {
2322 XFREE(MTYPE_ROUTE_MAP_NAME
,
2323 peer
->default_rmap
[afi
][safi
].name
);
2324 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2328 FOREACH_AFI_SAFI (afi
, safi
)
2329 peer_af_delete(peer
, afi
, safi
);
2331 if (peer
->hostname
) {
2332 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2333 peer
->hostname
= NULL
;
2336 if (peer
->domainname
) {
2337 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2338 peer
->domainname
= NULL
;
2341 peer_unlock(peer
); /* initial reference */
2346 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2348 return strcmp(g1
->name
, g2
->name
);
2351 /* Peer group cofiguration. */
2352 static struct peer_group
*peer_group_new(void)
2354 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2355 sizeof(struct peer_group
));
2358 static void peer_group_free(struct peer_group
*group
)
2360 XFREE(MTYPE_PEER_GROUP
, group
);
2363 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2365 struct peer_group
*group
;
2366 struct listnode
*node
, *nnode
;
2368 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2369 if (strcmp(group
->name
, name
) == 0)
2375 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2377 struct peer_group
*group
;
2380 group
= peer_group_lookup(bgp
, name
);
2384 group
= peer_group_new();
2387 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2388 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2389 group
->peer
= list_new();
2390 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2391 group
->listen_range
[afi
] = list_new();
2392 group
->conf
= peer_new(bgp
);
2393 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2394 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2395 if (group
->conf
->host
)
2396 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2397 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2398 group
->conf
->group
= group
;
2399 group
->conf
->as
= 0;
2400 group
->conf
->ttl
= 1;
2401 group
->conf
->gtsm_hops
= 0;
2402 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2403 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2404 listnode_add_sort(bgp
->group
, group
);
2409 static void peer_group2peer_config_copy(struct peer_group
*group
,
2419 peer
->as
= conf
->as
;
2422 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2423 peer
->change_local_as
= conf
->change_local_as
;
2426 peer
->ttl
= conf
->ttl
;
2429 peer
->gtsm_hops
= conf
->gtsm_hops
;
2431 /* peer flags apply */
2432 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2433 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2434 flags_tmp
&= ~peer
->flags_override
;
2436 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2437 SET_FLAG(peer
->flags
, flags_tmp
);
2438 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2440 /* peer timers apply */
2441 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2442 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2443 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2446 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2447 PEER_ATTR_INHERIT(peer
, group
, connect
);
2448 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2449 peer
->v_connect
= conf
->connect
;
2451 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2454 /* advertisement-interval apply */
2455 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2456 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2457 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2458 peer
->v_routeadv
= conf
->routeadv
;
2460 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2461 ? BGP_DEFAULT_IBGP_ROUTEADV
2462 : BGP_DEFAULT_EBGP_ROUTEADV
;
2465 /* password apply */
2466 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2467 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2468 MTYPE_PEER_PASSWORD
);
2470 if (!BGP_PEER_SU_UNSPEC(peer
))
2473 /* update-source apply */
2474 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2475 if (conf
->update_source
) {
2476 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2477 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2478 } else if (conf
->update_if
) {
2479 sockunion_free(peer
->update_source
);
2480 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2481 MTYPE_PEER_UPDATE_SOURCE
);
2485 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2488 /* Peer group's remote AS configuration. */
2489 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2492 struct peer_group
*group
;
2494 struct listnode
*node
, *nnode
;
2496 group
= peer_group_lookup(bgp
, group_name
);
2500 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2504 /* When we setup peer-group AS number all peer group member's AS
2505 number must be updated to same number. */
2506 peer_as_change(group
->conf
, *as
, as_type
);
2508 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2509 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2510 || (peer
->as_type
!= as_type
))
2511 peer_as_change(peer
, *as
, as_type
);
2517 int peer_group_delete(struct peer_group
*group
)
2521 struct prefix
*prefix
;
2523 struct listnode
*node
, *nnode
;
2528 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2529 other
= peer
->doppelganger
;
2531 if (other
&& other
->status
!= Deleted
) {
2532 other
->group
= NULL
;
2536 list_delete(&group
->peer
);
2538 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2539 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2541 prefix_free(prefix
);
2543 list_delete(&group
->listen_range
[afi
]);
2546 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2549 bfd_info_free(&(group
->conf
->bfd_info
));
2551 group
->conf
->group
= NULL
;
2552 peer_delete(group
->conf
);
2554 /* Delete from all peer_group list. */
2555 listnode_delete(bgp
->group
, group
);
2557 peer_group_free(group
);
2562 int peer_group_remote_as_delete(struct peer_group
*group
)
2564 struct peer
*peer
, *other
;
2565 struct listnode
*node
, *nnode
;
2567 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2568 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2571 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2572 other
= peer
->doppelganger
;
2576 if (other
&& other
->status
!= Deleted
) {
2577 other
->group
= NULL
;
2581 list_delete_all_node(group
->peer
);
2583 group
->conf
->as
= 0;
2584 group
->conf
->as_type
= AS_UNSPECIFIED
;
2589 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2591 struct prefix
*prefix
;
2592 struct listnode
*node
, *nnode
;
2595 afi
= family2afi(range
->family
);
2597 /* Group needs remote AS configured. */
2598 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2599 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2601 /* Ensure no duplicates. Currently we don't care about overlaps. */
2602 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2603 if (prefix_same(range
, prefix
))
2607 prefix
= prefix_new();
2608 prefix_copy(prefix
, range
);
2609 listnode_add(group
->listen_range
[afi
], prefix
);
2613 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2615 struct prefix
*prefix
, prefix2
;
2616 struct listnode
*node
, *nnode
;
2619 char buf
[PREFIX2STR_BUFFER
];
2621 afi
= family2afi(range
->family
);
2623 /* Identify the listen range. */
2624 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2625 if (prefix_same(range
, prefix
))
2630 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2632 prefix2str(prefix
, buf
, sizeof(buf
));
2634 /* Dispose off any dynamic neighbors that exist due to this listen range
2636 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2637 if (!peer_dynamic_neighbor(peer
))
2640 sockunion2hostprefix(&peer
->su
, &prefix2
);
2641 if (prefix_match(prefix
, &prefix2
)) {
2642 if (bgp_debug_neighbor_events(peer
))
2644 "Deleting dynamic neighbor %s group %s upon "
2645 "delete of listen range %s",
2646 peer
->host
, group
->name
, buf
);
2651 /* Get rid of the listen range */
2652 listnode_delete(group
->listen_range
[afi
], prefix
);
2657 /* Bind specified peer to peer group. */
2658 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2659 struct peer_group
*group
, as_t
*as
)
2661 int first_member
= 0;
2665 /* Lookup the peer. */
2667 peer
= peer_lookup(bgp
, su
);
2669 /* The peer exist, bind it to the peer-group */
2671 /* When the peer already belongs to a peer-group, check the
2673 if (peer_group_active(peer
)) {
2675 /* The peer is already bound to the peer-group,
2678 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2681 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2684 /* The peer has not specified a remote-as, inherit it from the
2686 if (peer
->as_type
== AS_UNSPECIFIED
) {
2687 peer
->as_type
= group
->conf
->as_type
;
2688 peer
->as
= group
->conf
->as
;
2691 if (!group
->conf
->as
) {
2692 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2693 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2696 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2699 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2703 peer_group2peer_config_copy(group
, peer
);
2705 FOREACH_AFI_SAFI (afi
, safi
) {
2706 if (group
->conf
->afc
[afi
][safi
]) {
2707 peer
->afc
[afi
][safi
] = 1;
2709 if (peer_af_find(peer
, afi
, safi
)
2710 || peer_af_create(peer
, afi
, safi
)) {
2711 peer_group2peer_config_copy_af(
2712 group
, peer
, afi
, safi
);
2714 } else if (peer
->afc
[afi
][safi
])
2715 peer_deactivate(peer
, afi
, safi
);
2719 assert(group
&& peer
->group
== group
);
2721 listnode_delete(bgp
->peer
, peer
);
2723 peer
->group
= group
;
2724 listnode_add_sort(bgp
->peer
, peer
);
2726 peer
= peer_lock(peer
); /* group->peer list reference */
2727 listnode_add(group
->peer
, peer
);
2731 /* Advertisement-interval reset */
2732 if (!CHECK_FLAG(group
->conf
->flags
,
2733 PEER_FLAG_ROUTEADV
)) {
2734 group
->conf
->v_routeadv
=
2735 (peer_sort(group
->conf
)
2737 ? BGP_DEFAULT_IBGP_ROUTEADV
2738 : BGP_DEFAULT_EBGP_ROUTEADV
;
2741 /* ebgp-multihop reset */
2742 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2743 group
->conf
->ttl
= MAXTTL
;
2745 /* local-as reset */
2746 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2747 group
->conf
->change_local_as
= 0;
2748 peer_flag_unset(group
->conf
,
2749 PEER_FLAG_LOCAL_AS
);
2750 peer_flag_unset(group
->conf
,
2751 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2752 peer_flag_unset(group
->conf
,
2753 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2757 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2759 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2760 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2761 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2762 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2764 bgp_session_reset(peer
);
2768 /* Create a new peer. */
2770 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2771 && (!group
->conf
->as
)) {
2772 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2775 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2776 group
->conf
->as_type
, 0, 0, group
);
2778 peer
= peer_lock(peer
); /* group->peer list reference */
2779 listnode_add(group
->peer
, peer
);
2781 peer_group2peer_config_copy(group
, peer
);
2783 /* If the peer-group is active for this afi/safi then activate
2785 FOREACH_AFI_SAFI (afi
, safi
) {
2786 if (group
->conf
->afc
[afi
][safi
]) {
2787 peer
->afc
[afi
][safi
] = 1;
2788 peer_af_create(peer
, afi
, safi
);
2789 peer_group2peer_config_copy_af(group
, peer
, afi
,
2791 } else if (peer
->afc
[afi
][safi
])
2792 peer_deactivate(peer
, afi
, safi
);
2795 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2797 /* Set up peer's events and timers. */
2798 if (peer_active(peer
))
2799 bgp_timer_set(peer
);
2805 static int bgp_startup_timer_expire(struct thread
*thread
)
2809 bgp
= THREAD_ARG(thread
);
2810 bgp
->t_startup
= NULL
;
2816 * On shutdown we call the cleanup function which
2817 * does a free of the link list nodes, free up
2818 * the data we are pointing at too.
2820 static void bgp_vrf_string_name_delete(void *data
)
2824 XFREE(MTYPE_TMP
, vname
);
2827 /* BGP instance creation by `router bgp' commands. */
2828 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2829 enum bgp_instance_type inst_type
)
2835 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2838 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2839 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2840 zlog_debug("Creating Default VRF, AS %u", *as
);
2842 zlog_debug("Creating %s %s, AS %u",
2843 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2850 bgp
->heuristic_coalesce
= true;
2851 bgp
->inst_type
= inst_type
;
2852 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2854 bgp
->peer_self
= peer_new(bgp
);
2855 if (bgp
->peer_self
->host
)
2856 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2857 bgp
->peer_self
->host
=
2858 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2859 if (bgp
->peer_self
->hostname
!= NULL
) {
2860 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2861 bgp
->peer_self
->hostname
= NULL
;
2863 if (cmd_hostname_get())
2864 bgp
->peer_self
->hostname
=
2865 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2867 if (bgp
->peer_self
->domainname
!= NULL
) {
2868 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2869 bgp
->peer_self
->domainname
= NULL
;
2871 if (cmd_domainname_get())
2872 bgp
->peer_self
->domainname
=
2873 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2874 bgp
->peer
= list_new();
2875 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2876 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2878 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2880 bgp
->group
= list_new();
2881 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2883 FOREACH_AFI_SAFI (afi
, safi
) {
2884 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2885 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2886 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2888 /* Enable maximum-paths */
2889 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2891 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2895 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2896 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2897 bgp
->default_subgroup_pkt_queue_max
=
2898 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2899 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2900 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2901 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2902 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2903 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2904 bgp
->dynamic_neighbors_count
= 0;
2905 #if DFLT_BGP_IMPORT_CHECK
2906 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2908 #if DFLT_BGP_SHOW_HOSTNAME
2909 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2911 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2912 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2914 #if DFLT_BGP_DETERMINISTIC_MED
2915 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2917 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2922 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2923 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2925 assert(bgp
->rfapi_cfg
);
2927 #endif /* ENABLE_BGP_VNC */
2929 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2930 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2931 bgp
->vpn_policy
[afi
].afi
= afi
;
2932 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2933 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2936 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2937 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2938 bgp_vrf_string_name_delete
;
2939 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2940 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2941 bgp_vrf_string_name_delete
;
2944 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2946 /* TODO - The startup timer needs to be run for the whole of BGP
2948 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2949 bgp
->restart_time
, &bgp
->t_startup
);
2952 /* printable name we can use in debug messages */
2953 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2954 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2964 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2966 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2967 snprintf(bgp
->name_pretty
, len
, "%s %s",
2968 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2974 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2975 memory_order_relaxed
);
2976 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2977 memory_order_relaxed
);
2978 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2982 update_bgp_group_init(bgp
);
2984 /* assign a unique rd id for auto derivation of vrf's RD */
2985 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2987 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
2988 sizeof(struct bgp_evpn_info
));
2995 /* Return the "default VRF" instance of BGP. */
2996 struct bgp
*bgp_get_default(void)
2999 struct listnode
*node
, *nnode
;
3001 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3002 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3007 /* Lookup BGP entry. */
3008 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3011 struct listnode
*node
, *nnode
;
3013 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3015 && ((bgp
->name
== NULL
&& name
== NULL
)
3016 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3021 /* Lookup BGP structure by view name. */
3022 struct bgp
*bgp_lookup_by_name(const char *name
)
3025 struct listnode
*node
, *nnode
;
3027 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3028 if ((bgp
->name
== NULL
&& name
== NULL
)
3029 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3034 /* Lookup BGP instance based on VRF id. */
3035 /* Note: Only to be used for incoming messages from Zebra. */
3036 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3040 /* Lookup VRF (in tree) and follow link. */
3041 vrf
= vrf_lookup_by_id(vrf_id
);
3044 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3047 /* handle socket creation or deletion, if necessary
3048 * this is called for all new BGP instances
3050 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3055 /* Create BGP server socket, if listen mode not disabled */
3056 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3058 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3060 * suppress vrf socket
3062 if (create
== FALSE
) {
3063 bgp_close_vrf_socket(bgp
);
3067 return BGP_ERR_INVALID_VALUE
;
3069 * if vrf_id did not change
3071 if (vrf
->vrf_id
== old_vrf_id
)
3073 if (old_vrf_id
!= VRF_UNKNOWN
) {
3074 /* look for old socket. close it. */
3075 bgp_close_vrf_socket(bgp
);
3077 /* if backend is not yet identified ( VRF_UNKNOWN) then
3078 * creation will be done later
3080 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3082 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3084 return BGP_ERR_INVALID_VALUE
;
3087 return bgp_check_main_socket(create
, bgp
);
3090 /* Called from VTY commands. */
3091 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3092 enum bgp_instance_type inst_type
)
3095 struct vrf
*vrf
= NULL
;
3097 /* Multiple instance check. */
3098 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3100 bgp
= bgp_lookup_by_name(name
);
3102 bgp
= bgp_get_default();
3104 /* Already exists. */
3106 if (bgp
->as
!= *as
) {
3108 return BGP_ERR_INSTANCE_MISMATCH
;
3110 if (bgp
->inst_type
!= inst_type
)
3111 return BGP_ERR_INSTANCE_MISMATCH
;
3116 /* BGP instance name can not be specified for single instance.
3119 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3121 /* Get default BGP structure if exists. */
3122 bgp
= bgp_get_default();
3125 if (bgp
->as
!= *as
) {
3127 return BGP_ERR_AS_MISMATCH
;
3134 bgp
= bgp_create(as
, name
, inst_type
);
3135 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3136 bgp
->vrf_id
= vrf_generate_id();
3137 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3138 bgp_address_init(bgp
);
3139 bgp_tip_hash_init(bgp
);
3143 bgp
->t_rmap_def_originate_eval
= NULL
;
3145 /* If Default instance or VRF, link to the VRF structure, if present. */
3146 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3147 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3148 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3150 bgp_vrf_link(bgp
, vrf
);
3152 /* BGP server socket already processed if BGP instance
3153 * already part of the list
3155 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3156 listnode_add(bm
->bgp
, bgp
);
3158 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3159 if (BGP_DEBUG(zebra
, ZEBRA
))
3160 zlog_debug("%s: Registering BGP instance %s to zebra",
3161 __PRETTY_FUNCTION__
, name
);
3162 bgp_zebra_instance_register(bgp
);
3169 * Make BGP instance "up". Applies only to VRFs (non-default) and
3170 * implies the VRF has been learnt from Zebra.
3172 void bgp_instance_up(struct bgp
*bgp
)
3175 struct listnode
*node
, *next
;
3177 /* Register with zebra. */
3178 bgp_zebra_instance_register(bgp
);
3180 /* Kick off any peers that may have been configured. */
3181 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3182 if (!BGP_PEER_START_SUPPRESSED(peer
))
3183 BGP_EVENT_ADD(peer
, BGP_Start
);
3186 /* Process any networks that have been configured. */
3187 bgp_static_add(bgp
);
3191 * Make BGP instance "down". Applies only to VRFs (non-default) and
3192 * implies the VRF has been deleted by Zebra.
3194 void bgp_instance_down(struct bgp
*bgp
)
3197 struct listnode
*node
;
3198 struct listnode
*next
;
3201 if (bgp
->t_rmap_def_originate_eval
) {
3202 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3203 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3207 /* Bring down peers, so corresponding routes are purged. */
3208 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3209 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3210 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3211 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3213 bgp_session_reset(peer
);
3216 /* Purge network and redistributed routes. */
3217 bgp_purge_static_redist_routes(bgp
);
3219 /* Cleanup registered nexthops (flags) */
3220 bgp_cleanup_nexthops(bgp
);
3223 /* Delete BGP instance. */
3224 int bgp_delete(struct bgp
*bgp
)
3227 struct peer_group
*group
;
3228 struct listnode
*node
, *next
;
3234 THREAD_OFF(bgp
->t_startup
);
3235 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3236 THREAD_OFF(bgp
->t_update_delay
);
3237 THREAD_OFF(bgp
->t_establish_wait
);
3239 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3240 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3241 zlog_debug("Deleting Default VRF");
3243 zlog_debug("Deleting %s %s",
3244 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3250 /* unmap from RT list */
3251 bgp_evpn_vrf_delete(bgp
);
3254 if (bgp
->t_rmap_def_originate_eval
) {
3255 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3256 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3260 /* Inform peers we're going down. */
3261 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3264 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3267 /* Delete static routes (networks). */
3268 bgp_static_delete(bgp
);
3270 /* Unset redistribution. */
3271 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3272 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3273 if (i
!= ZEBRA_ROUTE_BGP
)
3274 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3276 /* Free peers and peer-groups. */
3277 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3278 peer_group_delete(group
);
3280 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3283 if (bgp
->peer_self
) {
3284 peer_delete(bgp
->peer_self
);
3285 bgp
->peer_self
= NULL
;
3288 update_bgp_group_free(bgp
);
3290 /* TODO - Other memory may need to be freed - e.g., NHT */
3295 bgp_cleanup_routes(bgp
);
3297 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3298 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3301 &bgp
->vpn_policy
[afi
]
3302 .import_redirect_rtlist
);
3303 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3306 /* Deregister from Zebra, if needed */
3307 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3308 if (BGP_DEBUG(zebra
, ZEBRA
))
3309 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3310 __PRETTY_FUNCTION__
, bgp
->name
);
3311 bgp_zebra_instance_deregister(bgp
);
3314 /* Remove visibility via the master list - there may however still be
3315 * routes to be processed still referencing the struct bgp.
3317 listnode_delete(bm
->bgp
, bgp
);
3319 /* Free interfaces in this instance. */
3322 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3323 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3325 bgp_vrf_unlink(bgp
, vrf
);
3327 thread_master_free_unused(bm
->master
);
3328 bgp_unlock(bgp
); /* initial reference */
3333 void bgp_free(struct bgp
*bgp
)
3337 struct bgp_table
*table
;
3338 struct bgp_node
*rn
;
3339 struct bgp_rmap
*rmap
;
3343 list_delete(&bgp
->group
);
3344 list_delete(&bgp
->peer
);
3346 if (bgp
->peerhash
) {
3347 hash_free(bgp
->peerhash
);
3348 bgp
->peerhash
= NULL
;
3351 FOREACH_AFI_SAFI (afi
, safi
) {
3352 /* Special handling for 2-level routing tables. */
3353 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3354 || safi
== SAFI_EVPN
) {
3355 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3356 rn
= bgp_route_next(rn
)) {
3357 table
= (struct bgp_table
*)rn
->info
;
3358 bgp_table_finish(&table
);
3361 if (bgp
->route
[afi
][safi
])
3362 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3363 if (bgp
->aggregate
[afi
][safi
])
3364 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3365 if (bgp
->rib
[afi
][safi
])
3366 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3367 rmap
= &bgp
->table_map
[afi
][safi
];
3369 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3372 bgp_scan_finish(bgp
);
3373 bgp_address_destroy(bgp
);
3374 bgp_tip_hash_destroy(bgp
);
3376 /* release the auto RD id */
3377 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3379 bgp_evpn_cleanup(bgp
);
3380 bgp_pbr_cleanup(bgp
);
3381 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3383 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3384 vpn_policy_direction_t dir
;
3386 if (bgp
->vpn_policy
[afi
].import_vrf
)
3387 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3388 if (bgp
->vpn_policy
[afi
].export_vrf
)
3389 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3391 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3392 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3393 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3394 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3395 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3396 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3400 XFREE(MTYPE_BGP
, bgp
->name
);
3401 if (bgp
->name_pretty
)
3402 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3404 XFREE(MTYPE_BGP
, bgp
);
3407 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3410 struct listnode
*node
, *nnode
;
3416 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3417 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3418 && !CHECK_FLAG(peer
->sflags
,
3419 PEER_STATUS_ACCEPT_PEER
))
3421 } else if (bm
->bgp
!= NULL
) {
3422 struct listnode
*bgpnode
, *nbgpnode
;
3424 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3425 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3427 && !strcmp(peer
->conf_if
, conf_if
)
3428 && !CHECK_FLAG(peer
->sflags
,
3429 PEER_STATUS_ACCEPT_PEER
))
3435 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3438 struct listnode
*node
, *nnode
;
3444 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3445 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3446 && !CHECK_FLAG(peer
->sflags
,
3447 PEER_STATUS_ACCEPT_PEER
))
3449 } else if (bm
->bgp
!= NULL
) {
3450 struct listnode
*bgpnode
, *nbgpnode
;
3452 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3453 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3455 && !strcmp(peer
->hostname
, hostname
)
3456 && !CHECK_FLAG(peer
->sflags
,
3457 PEER_STATUS_ACCEPT_PEER
))
3463 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3465 struct peer
*peer
= NULL
;
3466 struct peer tmp_peer
;
3468 memset(&tmp_peer
, 0, sizeof(struct peer
));
3471 * We do not want to find the doppelganger peer so search for the peer
3473 * the hash that has PEER_FLAG_CONFIG_NODE
3475 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3480 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3481 } else if (bm
->bgp
!= NULL
) {
3482 struct listnode
*bgpnode
, *nbgpnode
;
3484 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3485 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3494 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3495 union sockunion
*su
,
3496 struct peer_group
*group
)
3502 /* Create peer first; we've already checked group config is valid. */
3503 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3504 group
->conf
->as_type
, 0, 0, group
);
3509 peer
= peer_lock(peer
);
3510 listnode_add(group
->peer
, peer
);
3512 peer_group2peer_config_copy(group
, peer
);
3515 * Bind peer for all AFs configured for the group. We don't call
3516 * peer_group_bind as that is sub-optimal and does some stuff we don't
3519 FOREACH_AFI_SAFI (afi
, safi
) {
3520 if (!group
->conf
->afc
[afi
][safi
])
3522 peer
->afc
[afi
][safi
] = 1;
3524 if (!peer_af_find(peer
, afi
, safi
))
3525 peer_af_create(peer
, afi
, safi
);
3527 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3530 /* Mark as dynamic, but also as a "config node" for other things to
3532 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3533 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3539 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3540 struct prefix
*prefix
)
3542 struct listnode
*node
, *nnode
;
3543 struct prefix
*range
;
3546 afi
= family2afi(prefix
->family
);
3548 if (group
->listen_range
[afi
])
3549 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3551 if (prefix_match(range
, prefix
))
3558 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3559 struct prefix
**listen_range
)
3561 struct prefix
*range
= NULL
;
3562 struct peer_group
*group
= NULL
;
3563 struct listnode
*node
, *nnode
;
3565 *listen_range
= NULL
;
3567 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3568 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3571 } else if (bm
->bgp
!= NULL
) {
3572 struct listnode
*bgpnode
, *nbgpnode
;
3574 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3575 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3576 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3582 *listen_range
= range
;
3583 return (group
&& range
) ? group
: NULL
;
3586 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3588 struct peer_group
*group
;
3591 struct prefix prefix
;
3592 struct prefix
*listen_range
;
3594 char buf
[PREFIX2STR_BUFFER
];
3595 char buf1
[PREFIX2STR_BUFFER
];
3597 sockunion2hostprefix(su
, &prefix
);
3599 /* See if incoming connection matches a configured listen range. */
3600 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3611 prefix2str(&prefix
, buf
, sizeof(buf
));
3612 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3614 if (bgp_debug_neighbor_events(NULL
))
3616 "Dynamic Neighbor %s matches group %s listen range %s",
3617 buf
, group
->name
, buf1
);
3619 /* Are we within the listen limit? */
3620 dncount
= gbgp
->dynamic_neighbors_count
;
3622 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3623 if (bgp_debug_neighbor_events(NULL
))
3624 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3625 inet_sutop(su
, buf
),
3626 gbgp
->dynamic_neighbors_limit
);
3630 /* Ensure group is not disabled. */
3631 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3632 if (bgp_debug_neighbor_events(NULL
))
3634 "Dynamic Neighbor %s rejected - group %s disabled",
3639 /* Check that at least one AF is activated for the group. */
3640 if (!peer_group_af_configured(group
)) {
3641 if (bgp_debug_neighbor_events(NULL
))
3643 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3648 /* Create dynamic peer and bind to associated group. */
3649 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3652 gbgp
->dynamic_neighbors_count
= ++dncount
;
3654 if (bgp_debug_neighbor_events(peer
))
3655 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3656 peer
->host
, group
->name
, dncount
);
3661 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3664 if (peer
->group
->bgp
) {
3665 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3667 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3669 if (bgp_debug_neighbor_events(peer
))
3670 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3671 peer
->group
->name
, dncount
);
3674 /* If peer is configured at least one address family return 1. */
3675 int peer_active(struct peer
*peer
)
3677 if (BGP_PEER_SU_UNSPEC(peer
))
3679 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3680 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3681 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3682 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3683 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3684 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3685 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3686 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3687 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3688 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3689 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3694 /* If peer is negotiated at least one address family return 1. */
3695 int peer_active_nego(struct peer
*peer
)
3697 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3698 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3699 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3700 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3701 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3702 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3703 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3704 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3705 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3706 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3707 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3708 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3709 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3714 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3715 enum peer_change_type type
)
3717 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3720 if (peer
->status
!= Established
)
3723 if (type
== peer_change_reset
) {
3724 /* If we're resetting session, we've to delete both peer struct
3726 if ((peer
->doppelganger
)
3727 && (peer
->doppelganger
->status
!= Deleted
)
3728 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3729 PEER_FLAG_CONFIG_NODE
)))
3730 peer_delete(peer
->doppelganger
);
3732 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3733 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3734 } else if (type
== peer_change_reset_in
) {
3735 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3736 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3737 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3739 if ((peer
->doppelganger
)
3740 && (peer
->doppelganger
->status
!= Deleted
)
3741 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3742 PEER_FLAG_CONFIG_NODE
)))
3743 peer_delete(peer
->doppelganger
);
3745 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3746 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3748 } else if (type
== peer_change_reset_out
) {
3749 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3750 bgp_announce_route(peer
, afi
, safi
);
3754 struct peer_flag_action
{
3758 /* This flag can be set for peer-group member. */
3759 uint8_t not_for_member
;
3761 /* Action when the flag is changed. */
3762 enum peer_change_type type
;
3765 static const struct peer_flag_action peer_flag_action_list
[] = {
3766 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3767 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3768 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3769 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3770 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3771 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3772 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3773 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3774 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3775 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3776 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3777 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3778 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3779 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3780 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3781 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3782 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3785 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3786 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3787 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3788 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3789 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3790 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3791 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3792 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3793 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3794 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3795 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3796 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3797 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3798 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3799 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3800 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3801 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3802 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3803 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3804 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3805 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3806 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3807 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3808 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3809 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3810 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3813 /* Proper action set. */
3814 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3815 int size
, struct peer_flag_action
*action
,
3822 const struct peer_flag_action
*match
= NULL
;
3824 /* Check peer's frag action. */
3825 for (i
= 0; i
< size
; i
++) {
3826 match
= &action_list
[i
];
3828 if (match
->flag
== 0)
3831 if (match
->flag
& flag
) {
3834 if (match
->type
== peer_change_reset_in
)
3836 if (match
->type
== peer_change_reset_out
)
3838 if (match
->type
== peer_change_reset
) {
3842 if (match
->not_for_member
)
3843 action
->not_for_member
= 1;
3847 /* Set peer clear type. */
3848 if (reset_in
&& reset_out
)
3849 action
->type
= peer_change_reset
;
3851 action
->type
= peer_change_reset_in
;
3853 action
->type
= peer_change_reset_out
;
3855 action
->type
= peer_change_none
;
3860 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3862 if (flag
== PEER_FLAG_SHUTDOWN
) {
3863 if (CHECK_FLAG(peer
->flags
, flag
)) {
3864 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3865 peer_nsf_stop(peer
);
3867 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3868 if (peer
->t_pmax_restart
) {
3869 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3870 if (bgp_debug_neighbor_events(peer
))
3872 "%s Maximum-prefix restart timer canceled",
3876 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3877 peer_nsf_stop(peer
);
3879 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3880 char *msg
= peer
->tx_shutdown_message
;
3883 if (!msg
&& peer_group_active(peer
))
3884 msg
= peer
->group
->conf
3885 ->tx_shutdown_message
;
3886 msglen
= msg
? strlen(msg
) : 0;
3891 uint8_t msgbuf
[129];
3894 memcpy(msgbuf
+ 1, msg
, msglen
);
3896 bgp_notify_send_with_data(
3897 peer
, BGP_NOTIFY_CEASE
,
3898 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3899 msgbuf
, msglen
+ 1);
3902 peer
, BGP_NOTIFY_CEASE
,
3903 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3905 bgp_session_reset(peer
);
3907 peer
->v_start
= BGP_INIT_START_TIMER
;
3908 BGP_EVENT_ADD(peer
, BGP_Stop
);
3910 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3911 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3912 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3913 else if (flag
== PEER_FLAG_PASSIVE
)
3914 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3915 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3916 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3918 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3919 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3921 bgp_session_reset(peer
);
3924 /* Change specified peer flag. */
3925 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3929 bool invert
, member_invert
;
3930 struct peer
*member
;
3931 struct listnode
*node
, *nnode
;
3932 struct peer_flag_action action
;
3934 memset(&action
, 0, sizeof(struct peer_flag_action
));
3935 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3937 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3938 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3941 /* Abort if no flag action exists. */
3943 return BGP_ERR_INVALID_FLAG
;
3945 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3946 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3947 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3948 return BGP_ERR_PEER_FLAG_CONFLICT
;
3950 /* Handle flag updates where desired state matches current state. */
3951 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3952 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3953 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3957 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3958 COND_FLAG(peer
->flags_override
, flag
, invert
);
3963 /* Inherit from peer-group or set/unset flags accordingly. */
3964 if (peer_group_active(peer
) && set
== invert
)
3965 peer_flag_inherit(peer
, flag
);
3967 COND_FLAG(peer
->flags
, flag
, set
);
3969 /* Check if handling a regular peer. */
3970 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3971 /* Update flag override state accordingly. */
3972 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3974 /* Execute flag action on peer. */
3975 if (action
.type
== peer_change_reset
)
3976 peer_flag_modify_action(peer
, flag
);
3978 /* Skip peer-group mechanics for regular peers. */
3982 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3983 bgp_nht_register_enhe_capability_interfaces(peer
);
3986 * Update peer-group members, unless they are explicitely overriding
3987 * peer-group configuration.
3989 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3990 /* Skip peers with overridden configuration. */
3991 if (CHECK_FLAG(member
->flags_override
, flag
))
3994 /* Check if only member without group is inverted. */
3996 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3998 /* Skip peers with equivalent configuration. */
3999 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4002 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4005 /* Update flag on peer-group member. */
4006 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4008 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4009 bgp_nht_register_enhe_capability_interfaces(member
);
4011 /* Execute flag action on peer-group member. */
4012 if (action
.type
== peer_change_reset
)
4013 peer_flag_modify_action(member
, flag
);
4019 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4021 return peer_flag_modify(peer
, flag
, 1);
4024 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4026 return peer_flag_modify(peer
, flag
, 0);
4029 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4030 uint32_t flag
, bool set
)
4034 bool invert
, member_invert
;
4035 struct peer
*member
;
4036 struct listnode
*node
, *nnode
;
4037 struct peer_flag_action action
;
4039 memset(&action
, 0, sizeof(struct peer_flag_action
));
4040 size
= sizeof peer_af_flag_action_list
4041 / sizeof(struct peer_flag_action
);
4043 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4044 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4047 /* Abort if flag action exists. */
4049 return BGP_ERR_INVALID_FLAG
;
4051 /* Special check for reflector client. */
4052 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4053 && peer_sort(peer
) != BGP_PEER_IBGP
)
4054 return BGP_ERR_NOT_INTERNAL_PEER
;
4056 /* Special check for remove-private-AS. */
4057 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4058 && peer_sort(peer
) == BGP_PEER_IBGP
)
4059 return BGP_ERR_REMOVE_PRIVATE_AS
;
4061 /* as-override is not allowed for IBGP peers */
4062 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4063 return BGP_ERR_AS_OVERRIDE
;
4065 /* Handle flag updates where desired state matches current state. */
4066 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4067 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4068 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4073 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4074 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4081 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4082 * if we are setting/unsetting flags which conflict with this flag
4083 * handle accordingly
4085 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4089 * if we are setting NEXTHOP_SELF, we need to unset the
4090 * NEXTHOP_UNCHANGED flag
4092 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4093 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4094 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4095 PEER_FLAG_NEXTHOP_UNCHANGED
);
4099 * if we are unsetting NEXTHOP_SELF, we need to set the
4100 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4102 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4103 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4104 SET_FLAG(peer
->af_flags
[afi
][safi
],
4105 PEER_FLAG_NEXTHOP_UNCHANGED
);
4109 /* Inherit from peer-group or set/unset flags accordingly. */
4110 if (peer_group_active(peer
) && set
== invert
)
4111 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4113 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4115 /* Execute action when peer is established. */
4116 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4117 && peer
->status
== Established
) {
4118 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4119 bgp_clear_adj_in(peer
, afi
, safi
);
4121 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4122 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4123 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4124 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4125 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4126 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4127 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4128 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4130 peer_change_action(peer
, afi
, safi
, action
.type
);
4134 /* Check if handling a regular peer. */
4135 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4136 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4140 * Update peer-group members, unless they are explicitely
4141 * overriding peer-group configuration.
4143 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4145 /* Skip peers with overridden configuration. */
4146 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4150 /* Check if only member without group is inverted. */
4152 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4156 /* Skip peers with equivalent configuration. */
4157 if (set
!= member_invert
4158 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4161 if (set
== member_invert
4162 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4165 /* Update flag on peer-group member. */
4166 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4167 set
!= member_invert
);
4169 /* Execute flag action on peer-group member. */
4170 if (member
->status
== Established
) {
4171 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4172 bgp_clear_adj_in(member
, afi
, safi
);
4174 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4175 member
->last_reset
=
4176 PEER_DOWN_RR_CLIENT_CHANGE
;
4178 == PEER_FLAG_RSERVER_CLIENT
)
4179 member
->last_reset
=
4180 PEER_DOWN_RS_CLIENT_CHANGE
;
4182 == PEER_FLAG_ORF_PREFIX_SM
)
4183 member
->last_reset
=
4184 PEER_DOWN_CAPABILITY_CHANGE
;
4186 == PEER_FLAG_ORF_PREFIX_RM
)
4187 member
->last_reset
=
4188 PEER_DOWN_CAPABILITY_CHANGE
;
4190 peer_change_action(member
, afi
, safi
,
4200 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4202 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4205 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4207 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4211 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4213 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4214 peer
->tx_shutdown_message
=
4215 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4219 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4221 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4226 /* EBGP multihop configuration. */
4227 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4229 struct peer_group
*group
;
4230 struct listnode
*node
, *nnode
;
4233 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4236 /* see comment in peer_ttl_security_hops_set() */
4237 if (ttl
!= MAXTTL
) {
4238 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4239 group
= peer
->group
;
4240 if (group
->conf
->gtsm_hops
!= 0)
4241 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4243 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4245 if (peer1
->sort
== BGP_PEER_IBGP
)
4248 if (peer1
->gtsm_hops
!= 0)
4249 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4252 if (peer
->gtsm_hops
!= 0)
4253 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4259 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4260 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4261 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4262 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4263 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4265 bgp_session_reset(peer
);
4268 group
= peer
->group
;
4269 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4270 if (peer
->sort
== BGP_PEER_IBGP
)
4273 peer
->ttl
= group
->conf
->ttl
;
4275 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4276 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4277 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4279 bgp_session_reset(peer
);
4285 int peer_ebgp_multihop_unset(struct peer
*peer
)
4287 struct peer_group
*group
;
4288 struct listnode
*node
, *nnode
;
4290 if (peer
->sort
== BGP_PEER_IBGP
)
4293 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4294 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4296 if (peer_group_active(peer
))
4297 peer
->ttl
= peer
->group
->conf
->ttl
;
4301 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4302 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4303 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4304 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4306 bgp_session_reset(peer
);
4308 group
= peer
->group
;
4309 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4310 if (peer
->sort
== BGP_PEER_IBGP
)
4315 if (peer
->fd
>= 0) {
4316 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4318 peer
, BGP_NOTIFY_CEASE
,
4319 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4321 bgp_session_reset(peer
);
4328 /* Neighbor description. */
4329 int peer_description_set(struct peer
*peer
, const char *desc
)
4332 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4334 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4339 int peer_description_unset(struct peer
*peer
)
4342 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4349 /* Neighbor update-source. */
4350 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4352 struct peer
*member
;
4353 struct listnode
*node
, *nnode
;
4355 /* Set flag and configuration on peer. */
4356 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4357 if (peer
->update_if
) {
4358 if (strcmp(peer
->update_if
, ifname
) == 0)
4360 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4362 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4363 sockunion_free(peer
->update_source
);
4364 peer
->update_source
= NULL
;
4366 /* Check if handling a regular peer. */
4367 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4368 /* Send notification or reset peer depending on state. */
4369 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4370 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4371 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4372 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4374 bgp_session_reset(peer
);
4376 /* Skip peer-group mechanics for regular peers. */
4381 * Set flag and configuration on all peer-group members, unless they are
4382 * explicitely overriding peer-group configuration.
4384 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4385 /* Skip peers with overridden configuration. */
4386 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4389 /* Skip peers with the same configuration. */
4390 if (member
->update_if
) {
4391 if (strcmp(member
->update_if
, ifname
) == 0)
4393 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4396 /* Set flag and configuration on peer-group member. */
4397 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4398 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4399 sockunion_free(member
->update_source
);
4400 member
->update_source
= NULL
;
4402 /* Send notification or reset peer depending on state. */
4403 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4404 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4405 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4406 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4408 bgp_session_reset(member
);
4414 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4416 struct peer
*member
;
4417 struct listnode
*node
, *nnode
;
4419 /* Set flag and configuration on peer. */
4420 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4421 if (peer
->update_source
) {
4422 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4424 sockunion_free(peer
->update_source
);
4426 peer
->update_source
= sockunion_dup(su
);
4427 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4429 /* Check if handling a regular peer. */
4430 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4431 /* Send notification or reset peer depending on state. */
4432 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4433 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4434 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4435 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4437 bgp_session_reset(peer
);
4439 /* Skip peer-group mechanics for regular peers. */
4444 * Set flag and configuration on all peer-group members, unless they are
4445 * explicitely overriding peer-group configuration.
4447 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4448 /* Skip peers with overridden configuration. */
4449 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4452 /* Skip peers with the same configuration. */
4453 if (member
->update_source
) {
4454 if (sockunion_cmp(member
->update_source
, su
) == 0)
4456 sockunion_free(member
->update_source
);
4459 /* Set flag and configuration on peer-group member. */
4460 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4461 member
->update_source
= sockunion_dup(su
);
4462 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4464 /* Send notification or reset peer depending on state. */
4465 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4466 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4467 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4468 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4470 bgp_session_reset(member
);
4476 int peer_update_source_unset(struct peer
*peer
)
4478 struct peer
*member
;
4479 struct listnode
*node
, *nnode
;
4481 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4484 /* Inherit configuration from peer-group if peer is member. */
4485 if (peer_group_active(peer
)) {
4486 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4487 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4488 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4489 MTYPE_PEER_UPDATE_SOURCE
);
4491 /* Otherwise remove flag and configuration from peer. */
4492 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4493 sockunion_free(peer
->update_source
);
4494 peer
->update_source
= NULL
;
4495 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4498 /* Check if handling a regular peer. */
4499 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4500 /* Send notification or reset peer depending on state. */
4501 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4502 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4503 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4504 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4506 bgp_session_reset(peer
);
4508 /* Skip peer-group mechanics for regular peers. */
4513 * Set flag and configuration on all peer-group members, unless they are
4514 * explicitely overriding peer-group configuration.
4516 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4517 /* Skip peers with overridden configuration. */
4518 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4521 /* Skip peers with the same configuration. */
4522 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4523 && !member
->update_source
&& !member
->update_if
)
4526 /* Remove flag and configuration on peer-group member. */
4527 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4528 sockunion_free(member
->update_source
);
4529 member
->update_source
= NULL
;
4530 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4532 /* Send notification or reset peer depending on state. */
4533 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4534 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4535 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4536 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4538 bgp_session_reset(member
);
4544 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4545 const char *rmap
, struct route_map
*route_map
)
4547 struct peer
*member
;
4548 struct listnode
*node
, *nnode
;
4550 /* Set flag and configuration on peer. */
4551 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4553 if (!peer
->default_rmap
[afi
][safi
].name
4554 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4555 if (peer
->default_rmap
[afi
][safi
].name
)
4556 XFREE(MTYPE_ROUTE_MAP_NAME
,
4557 peer
->default_rmap
[afi
][safi
].name
);
4559 peer
->default_rmap
[afi
][safi
].name
=
4560 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4561 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4564 if (peer
->default_rmap
[afi
][safi
].name
)
4565 XFREE(MTYPE_ROUTE_MAP_NAME
,
4566 peer
->default_rmap
[afi
][safi
].name
);
4568 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4569 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4572 /* Check if handling a regular peer. */
4573 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4574 /* Update peer route announcements. */
4575 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4576 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4577 bgp_default_originate(peer
, afi
, safi
, 0);
4578 bgp_announce_route(peer
, afi
, safi
);
4581 /* Skip peer-group mechanics for regular peers. */
4586 * Set flag and configuration on all peer-group members, unless they are
4587 * explicitely overriding peer-group configuration.
4589 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4590 /* Skip peers with overridden configuration. */
4591 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4592 PEER_FLAG_DEFAULT_ORIGINATE
))
4595 /* Set flag and configuration on peer-group member. */
4596 SET_FLAG(member
->af_flags
[afi
][safi
],
4597 PEER_FLAG_DEFAULT_ORIGINATE
);
4599 if (member
->default_rmap
[afi
][safi
].name
)
4600 XFREE(MTYPE_ROUTE_MAP_NAME
,
4601 member
->default_rmap
[afi
][safi
].name
);
4603 member
->default_rmap
[afi
][safi
].name
=
4604 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4605 member
->default_rmap
[afi
][safi
].map
= route_map
;
4608 /* Update peer route announcements. */
4609 if (member
->status
== Established
4610 && member
->afc_nego
[afi
][safi
]) {
4611 update_group_adjust_peer(
4612 peer_af_find(member
, afi
, safi
));
4613 bgp_default_originate(member
, afi
, safi
, 0);
4614 bgp_announce_route(member
, afi
, safi
);
4621 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4623 struct peer
*member
;
4624 struct listnode
*node
, *nnode
;
4626 /* Inherit configuration from peer-group if peer is member. */
4627 if (peer_group_active(peer
)) {
4628 peer_af_flag_inherit(peer
, afi
, safi
,
4629 PEER_FLAG_DEFAULT_ORIGINATE
);
4630 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4631 default_rmap
[afi
][safi
].name
,
4632 MTYPE_ROUTE_MAP_NAME
);
4633 PEER_ATTR_INHERIT(peer
, peer
->group
,
4634 default_rmap
[afi
][safi
].map
);
4636 /* Otherwise remove flag and configuration from peer. */
4637 peer_af_flag_unset(peer
, afi
, safi
,
4638 PEER_FLAG_DEFAULT_ORIGINATE
);
4639 if (peer
->default_rmap
[afi
][safi
].name
)
4640 XFREE(MTYPE_ROUTE_MAP_NAME
,
4641 peer
->default_rmap
[afi
][safi
].name
);
4642 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4643 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4646 /* Check if handling a regular peer. */
4647 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4648 /* Update peer route announcements. */
4649 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4650 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4651 bgp_default_originate(peer
, afi
, safi
, 1);
4652 bgp_announce_route(peer
, afi
, safi
);
4655 /* Skip peer-group mechanics for regular peers. */
4660 * Remove flag and configuration from all peer-group members, unless
4661 * they are explicitely overriding peer-group configuration.
4663 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4664 /* Skip peers with overridden configuration. */
4665 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4666 PEER_FLAG_DEFAULT_ORIGINATE
))
4669 /* Remove flag and configuration on peer-group member. */
4670 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4671 PEER_FLAG_DEFAULT_ORIGINATE
);
4672 if (peer
->default_rmap
[afi
][safi
].name
)
4673 XFREE(MTYPE_ROUTE_MAP_NAME
,
4674 peer
->default_rmap
[afi
][safi
].name
);
4675 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4676 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4678 /* Update peer route announcements. */
4679 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4680 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4681 bgp_default_originate(peer
, afi
, safi
, 1);
4682 bgp_announce_route(peer
, afi
, safi
);
4689 int peer_port_set(struct peer
*peer
, uint16_t port
)
4695 int peer_port_unset(struct peer
*peer
)
4697 peer
->port
= BGP_PORT_DEFAULT
;
4702 * Helper function that is called after the name of the policy
4703 * being used by a peer has changed (AF specific). Automatically
4704 * initiates inbound or outbound processing as needed.
4706 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4710 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4711 if (peer
->status
== Established
)
4712 bgp_announce_route(peer
, afi
, safi
);
4714 if (peer
->status
!= Established
)
4717 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4718 PEER_FLAG_SOFT_RECONFIG
))
4719 bgp_soft_reconfig_in(peer
, afi
, safi
);
4720 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4721 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4722 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4727 /* neighbor weight. */
4728 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4730 struct peer
*member
;
4731 struct listnode
*node
, *nnode
;
4733 /* Set flag and configuration on peer. */
4734 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4735 if (peer
->weight
[afi
][safi
] != weight
) {
4736 peer
->weight
[afi
][safi
] = weight
;
4737 peer_on_policy_change(peer
, afi
, safi
, 0);
4740 /* Skip peer-group mechanics for regular peers. */
4741 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4745 * Set flag and configuration on all peer-group members, unless they are
4746 * explicitely overriding peer-group configuration.
4748 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4749 /* Skip peers with overridden configuration. */
4750 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4754 /* Set flag and configuration on peer-group member. */
4755 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4756 if (member
->weight
[afi
][safi
] != weight
) {
4757 member
->weight
[afi
][safi
] = weight
;
4758 peer_on_policy_change(member
, afi
, safi
, 0);
4765 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4767 struct peer
*member
;
4768 struct listnode
*node
, *nnode
;
4770 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4773 /* Inherit configuration from peer-group if peer is member. */
4774 if (peer_group_active(peer
)) {
4775 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4776 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4778 peer_on_policy_change(peer
, afi
, safi
, 0);
4782 /* Remove flag and configuration from peer. */
4783 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4784 peer
->weight
[afi
][safi
] = 0;
4785 peer_on_policy_change(peer
, afi
, safi
, 0);
4787 /* Skip peer-group mechanics for regular peers. */
4788 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4792 * Remove flag and configuration from all peer-group members, unless
4793 * they are explicitely overriding peer-group configuration.
4795 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4796 /* Skip peers with overridden configuration. */
4797 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4801 /* Skip peers where flag is already disabled. */
4802 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4805 /* Remove flag and configuration on peer-group member. */
4806 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4807 member
->weight
[afi
][safi
] = 0;
4808 peer_on_policy_change(member
, afi
, safi
, 0);
4814 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4816 struct peer
*member
;
4817 struct listnode
*node
, *nnode
;
4819 if (keepalive
> 65535)
4820 return BGP_ERR_INVALID_VALUE
;
4822 if (holdtime
> 65535)
4823 return BGP_ERR_INVALID_VALUE
;
4825 if (holdtime
< 3 && holdtime
!= 0)
4826 return BGP_ERR_INVALID_VALUE
;
4828 /* Set flag and configuration on peer. */
4829 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4830 peer
->holdtime
= holdtime
;
4831 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4833 /* Skip peer-group mechanics for regular peers. */
4834 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4838 * Set flag and configuration on all peer-group members, unless they are
4839 * explicitely overriding peer-group configuration.
4841 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4842 /* Skip peers with overridden configuration. */
4843 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4846 /* Set flag and configuration on peer-group member. */
4847 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4848 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4849 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4855 int peer_timers_unset(struct peer
*peer
)
4857 struct peer
*member
;
4858 struct listnode
*node
, *nnode
;
4860 /* Inherit configuration from peer-group if peer is member. */
4861 if (peer_group_active(peer
)) {
4862 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4863 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4864 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4866 /* Otherwise remove flag and configuration from peer. */
4867 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4869 peer
->keepalive
= 0;
4872 /* Skip peer-group mechanics for regular peers. */
4873 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4877 * Remove flag and configuration from all peer-group members, unless
4878 * they are explicitely overriding peer-group configuration.
4880 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4881 /* Skip peers with overridden configuration. */
4882 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4885 /* Remove flag and configuration on peer-group member. */
4886 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4887 member
->holdtime
= 0;
4888 member
->keepalive
= 0;
4894 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4896 struct peer
*member
;
4897 struct listnode
*node
, *nnode
;
4899 if (connect
> 65535)
4900 return BGP_ERR_INVALID_VALUE
;
4902 /* Set flag and configuration on peer. */
4903 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4904 peer
->connect
= connect
;
4905 peer
->v_connect
= connect
;
4907 /* Skip peer-group mechanics for regular peers. */
4908 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4912 * Set flag and configuration on all peer-group members, unless they are
4913 * explicitely overriding peer-group configuration.
4915 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4916 /* Skip peers with overridden configuration. */
4917 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4920 /* Set flag and configuration on peer-group member. */
4921 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4922 member
->connect
= connect
;
4923 member
->v_connect
= connect
;
4929 int peer_timers_connect_unset(struct peer
*peer
)
4931 struct peer
*member
;
4932 struct listnode
*node
, *nnode
;
4934 /* Inherit configuration from peer-group if peer is member. */
4935 if (peer_group_active(peer
)) {
4936 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4937 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4939 /* Otherwise remove flag and configuration from peer. */
4940 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4944 /* Set timer with fallback to default value. */
4946 peer
->v_connect
= peer
->connect
;
4948 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4950 /* Skip peer-group mechanics for regular peers. */
4951 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4955 * Remove flag and configuration from all peer-group members, unless
4956 * they are explicitely overriding peer-group configuration.
4958 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4959 /* Skip peers with overridden configuration. */
4960 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4963 /* Remove flag and configuration on peer-group member. */
4964 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4965 member
->connect
= 0;
4966 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4972 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4974 struct peer
*member
;
4975 struct listnode
*node
, *nnode
;
4978 return BGP_ERR_INVALID_VALUE
;
4980 /* Set flag and configuration on peer. */
4981 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4982 peer
->routeadv
= routeadv
;
4983 peer
->v_routeadv
= routeadv
;
4985 /* Check if handling a regular peer. */
4986 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4987 /* Update peer route announcements. */
4988 update_group_adjust_peer_afs(peer
);
4989 if (peer
->status
== Established
)
4990 bgp_announce_route_all(peer
);
4992 /* Skip peer-group mechanics for regular peers. */
4997 * Set flag and configuration on all peer-group members, unless they are
4998 * explicitely overriding peer-group configuration.
5000 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5001 /* Skip peers with overridden configuration. */
5002 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5005 /* Set flag and configuration on peer-group member. */
5006 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5007 member
->routeadv
= routeadv
;
5008 member
->v_routeadv
= routeadv
;
5010 /* Update peer route announcements. */
5011 update_group_adjust_peer_afs(member
);
5012 if (member
->status
== Established
)
5013 bgp_announce_route_all(member
);
5019 int peer_advertise_interval_unset(struct peer
*peer
)
5021 struct peer
*member
;
5022 struct listnode
*node
, *nnode
;
5024 /* Inherit configuration from peer-group if peer is member. */
5025 if (peer_group_active(peer
)) {
5026 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5027 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5029 /* Otherwise remove flag and configuration from peer. */
5030 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5034 /* Set timer with fallback to default value. */
5036 peer
->v_routeadv
= peer
->routeadv
;
5038 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5039 ? BGP_DEFAULT_IBGP_ROUTEADV
5040 : BGP_DEFAULT_EBGP_ROUTEADV
;
5042 /* Check if handling a regular peer. */
5043 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5044 /* Update peer route announcements. */
5045 update_group_adjust_peer_afs(peer
);
5046 if (peer
->status
== Established
)
5047 bgp_announce_route_all(peer
);
5049 /* Skip peer-group mechanics for regular peers. */
5054 * Remove flag and configuration from all peer-group members, unless
5055 * they are explicitely overriding peer-group configuration.
5057 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5058 /* Skip peers with overridden configuration. */
5059 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5062 /* Remove flag and configuration on peer-group member. */
5063 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5064 member
->routeadv
= 0;
5065 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5066 ? BGP_DEFAULT_IBGP_ROUTEADV
5067 : BGP_DEFAULT_EBGP_ROUTEADV
;
5069 /* Update peer route announcements. */
5070 update_group_adjust_peer_afs(member
);
5071 if (member
->status
== Established
)
5072 bgp_announce_route_all(member
);
5078 /* neighbor interface */
5079 void peer_interface_set(struct peer
*peer
, const char *str
)
5082 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5083 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5086 void peer_interface_unset(struct peer
*peer
)
5089 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5090 peer
->ifname
= NULL
;
5094 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5095 int allow_num
, int origin
)
5097 struct peer
*member
;
5098 struct listnode
*node
, *nnode
;
5100 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5101 return BGP_ERR_INVALID_VALUE
;
5103 /* Set flag and configuration on peer. */
5104 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5106 if (peer
->allowas_in
[afi
][safi
] != 0
5107 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5108 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5109 peer_af_flag_set(peer
, afi
, safi
,
5110 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5111 peer
->allowas_in
[afi
][safi
] = 0;
5112 peer_on_policy_change(peer
, afi
, safi
, 0);
5115 if (peer
->allowas_in
[afi
][safi
] != allow_num
5116 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5117 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5119 peer_af_flag_unset(peer
, afi
, safi
,
5120 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5121 peer
->allowas_in
[afi
][safi
] = allow_num
;
5122 peer_on_policy_change(peer
, afi
, safi
, 0);
5126 /* Skip peer-group mechanics for regular peers. */
5127 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5131 * Set flag and configuration on all peer-group members, unless
5132 * they are explicitely overriding peer-group configuration.
5134 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5135 /* Skip peers with overridden configuration. */
5136 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5137 PEER_FLAG_ALLOWAS_IN
))
5140 /* Set flag and configuration on peer-group member. */
5141 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5143 if (member
->allowas_in
[afi
][safi
] != 0
5144 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5145 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5146 SET_FLAG(member
->af_flags
[afi
][safi
],
5147 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5148 member
->allowas_in
[afi
][safi
] = 0;
5149 peer_on_policy_change(peer
, afi
, safi
, 0);
5152 if (member
->allowas_in
[afi
][safi
] != allow_num
5153 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5154 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5155 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5156 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5157 member
->allowas_in
[afi
][safi
] = allow_num
;
5158 peer_on_policy_change(peer
, afi
, safi
, 0);
5166 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5168 struct peer
*member
;
5169 struct listnode
*node
, *nnode
;
5171 /* Skip peer if flag is already disabled. */
5172 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5175 /* Inherit configuration from peer-group if peer is member. */
5176 if (peer_group_active(peer
)) {
5177 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5178 peer_af_flag_inherit(peer
, afi
, safi
,
5179 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5180 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5181 peer_on_policy_change(peer
, afi
, safi
, 0);
5186 /* Remove flag and configuration from peer. */
5187 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5188 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5189 peer
->allowas_in
[afi
][safi
] = 0;
5190 peer_on_policy_change(peer
, afi
, safi
, 0);
5192 /* Skip peer-group mechanics if handling a regular peer. */
5193 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5197 * Remove flags and configuration from all peer-group members, unless
5198 * they are explicitely overriding peer-group configuration.
5200 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5201 /* Skip peers with overridden configuration. */
5202 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5203 PEER_FLAG_ALLOWAS_IN
))
5206 /* Skip peers where flag is already disabled. */
5207 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5208 PEER_FLAG_ALLOWAS_IN
))
5211 /* Remove flags and configuration on peer-group member. */
5212 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5213 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5214 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5215 member
->allowas_in
[afi
][safi
] = 0;
5216 peer_on_policy_change(member
, afi
, safi
, 0);
5222 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5225 bool old_no_prepend
, old_replace_as
;
5226 struct bgp
*bgp
= peer
->bgp
;
5227 struct peer
*member
;
5228 struct listnode
*node
, *nnode
;
5230 if (peer_sort(peer
) != BGP_PEER_EBGP
5231 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5232 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5235 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5238 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5240 /* Save previous flag states. */
5242 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5244 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5246 /* Set flag and configuration on peer. */
5247 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5248 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5249 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5251 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5252 && old_replace_as
== replace_as
)
5254 peer
->change_local_as
= as
;
5256 /* Check if handling a regular peer. */
5257 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5258 /* Send notification or reset peer depending on state. */
5259 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5260 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5261 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5262 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5264 bgp_session_reset(peer
);
5266 /* Skip peer-group mechanics for regular peers. */
5271 * Set flag and configuration on all peer-group members, unless they are
5272 * explicitely overriding peer-group configuration.
5274 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5275 /* Skip peers with overridden configuration. */
5276 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5279 /* Skip peers with the same configuration. */
5280 old_no_prepend
= CHECK_FLAG(member
->flags
,
5281 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5282 old_replace_as
= CHECK_FLAG(member
->flags
,
5283 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5284 if (member
->change_local_as
== as
5285 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5286 && old_no_prepend
== no_prepend
5287 && old_replace_as
== replace_as
)
5290 /* Set flag and configuration on peer-group member. */
5291 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5292 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5294 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5296 member
->change_local_as
= as
;
5298 /* Send notification or stop peer depending on state. */
5299 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5300 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5301 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5302 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5304 BGP_EVENT_ADD(member
, BGP_Stop
);
5310 int peer_local_as_unset(struct peer
*peer
)
5312 struct peer
*member
;
5313 struct listnode
*node
, *nnode
;
5315 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5318 /* Inherit configuration from peer-group if peer is member. */
5319 if (peer_group_active(peer
)) {
5320 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5321 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5322 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5323 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5325 /* Otherwise remove flag and configuration from peer. */
5326 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5327 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5328 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5329 peer
->change_local_as
= 0;
5332 /* Check if handling a regular peer. */
5333 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5334 /* Send notification or stop peer depending on state. */
5335 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5336 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5337 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5338 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5340 BGP_EVENT_ADD(peer
, BGP_Stop
);
5342 /* Skip peer-group mechanics for regular peers. */
5347 * Remove flag and configuration from all peer-group members, unless
5348 * they are explicitely overriding peer-group configuration.
5350 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5351 /* Skip peers with overridden configuration. */
5352 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5355 /* Remove flag and configuration on peer-group member. */
5356 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5357 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5358 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5359 member
->change_local_as
= 0;
5361 /* Send notification or stop peer depending on state. */
5362 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5363 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5364 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5365 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5367 bgp_session_reset(member
);
5373 /* Set password for authenticating with the peer. */
5374 int peer_password_set(struct peer
*peer
, const char *password
)
5376 struct peer
*member
;
5377 struct listnode
*node
, *nnode
;
5378 int len
= password
? strlen(password
) : 0;
5379 int ret
= BGP_SUCCESS
;
5381 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5382 return BGP_ERR_INVALID_VALUE
;
5384 /* Set flag and configuration on peer. */
5385 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5386 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5388 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5389 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5391 /* Check if handling a regular peer. */
5392 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5393 /* Send notification or reset peer depending on state. */
5394 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5395 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5396 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5398 bgp_session_reset(peer
);
5401 * Attempt to install password on socket and skip peer-group
5404 if (BGP_PEER_SU_UNSPEC(peer
))
5406 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5407 : BGP_ERR_TCPSIG_FAILED
;
5411 * Set flag and configuration on all peer-group members, unless they are
5412 * explicitely overriding peer-group configuration.
5414 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5415 /* Skip peers with overridden configuration. */
5416 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5419 /* Skip peers with the same password. */
5420 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5423 /* Set flag and configuration on peer-group member. */
5424 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5425 if (member
->password
)
5426 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5427 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5429 /* Send notification or reset peer depending on state. */
5430 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5431 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5432 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5434 bgp_session_reset(member
);
5436 /* Attempt to install password on socket. */
5437 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5438 ret
= BGP_ERR_TCPSIG_FAILED
;
5444 int peer_password_unset(struct peer
*peer
)
5446 struct peer
*member
;
5447 struct listnode
*node
, *nnode
;
5449 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5452 /* Inherit configuration from peer-group if peer is member. */
5453 if (peer_group_active(peer
)) {
5454 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5455 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5456 MTYPE_PEER_PASSWORD
);
5458 /* Otherwise remove flag and configuration from peer. */
5459 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5460 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5463 /* Check if handling a regular peer. */
5464 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5465 /* Send notification or reset peer depending on state. */
5466 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5467 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5468 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5470 bgp_session_reset(peer
);
5472 /* Attempt to uninstall password on socket. */
5473 if (!BGP_PEER_SU_UNSPEC(peer
))
5474 bgp_md5_unset(peer
);
5476 /* Skip peer-group mechanics for regular peers. */
5481 * Remove flag and configuration from all peer-group members, unless
5482 * they are explicitely overriding peer-group configuration.
5484 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5485 /* Skip peers with overridden configuration. */
5486 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5489 /* Remove flag and configuration on peer-group member. */
5490 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5491 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5493 /* Send notification or reset peer depending on state. */
5494 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5495 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5496 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5498 bgp_session_reset(member
);
5500 /* Attempt to uninstall password on socket. */
5501 if (!BGP_PEER_SU_UNSPEC(member
))
5502 bgp_md5_unset(member
);
5509 /* Set distribute list to the peer. */
5510 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5513 struct peer
*member
;
5514 struct bgp_filter
*filter
;
5515 struct listnode
*node
, *nnode
;
5517 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5518 return BGP_ERR_INVALID_VALUE
;
5520 /* Set configuration on peer. */
5521 filter
= &peer
->filter
[afi
][safi
];
5522 if (filter
->plist
[direct
].name
)
5523 return BGP_ERR_PEER_FILTER_CONFLICT
;
5524 if (filter
->dlist
[direct
].name
)
5525 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5526 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5527 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5529 /* Check if handling a regular peer. */
5530 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5531 /* Set override-flag and process peer route updates. */
5532 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5533 PEER_FT_DISTRIBUTE_LIST
);
5534 peer_on_policy_change(peer
, afi
, safi
,
5535 (direct
== FILTER_OUT
) ? 1 : 0);
5537 /* Skip peer-group mechanics for regular peers. */
5542 * Set configuration on all peer-group members, un less they are
5543 * explicitely overriding peer-group configuration.
5545 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5546 /* Skip peers with overridden configuration. */
5547 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5548 PEER_FT_DISTRIBUTE_LIST
))
5551 /* Set configuration on peer-group member. */
5552 filter
= &member
->filter
[afi
][safi
];
5553 if (filter
->dlist
[direct
].name
)
5554 XFREE(MTYPE_BGP_FILTER_NAME
,
5555 filter
->dlist
[direct
].name
);
5556 filter
->dlist
[direct
].name
=
5557 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5558 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5560 /* Process peer route updates. */
5561 peer_on_policy_change(member
, afi
, safi
,
5562 (direct
== FILTER_OUT
) ? 1 : 0);
5568 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5570 struct peer
*member
;
5571 struct bgp_filter
*filter
;
5572 struct listnode
*node
, *nnode
;
5574 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5575 return BGP_ERR_INVALID_VALUE
;
5577 /* Unset override-flag unconditionally. */
5578 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5579 PEER_FT_DISTRIBUTE_LIST
);
5581 /* Inherit configuration from peer-group if peer is member. */
5582 if (peer_group_active(peer
)) {
5583 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5584 filter
[afi
][safi
].dlist
[direct
].name
,
5585 MTYPE_BGP_FILTER_NAME
);
5586 PEER_ATTR_INHERIT(peer
, peer
->group
,
5587 filter
[afi
][safi
].dlist
[direct
].alist
);
5589 /* Otherwise remove configuration from peer. */
5590 filter
= &peer
->filter
[afi
][safi
];
5591 if (filter
->dlist
[direct
].name
)
5592 XFREE(MTYPE_BGP_FILTER_NAME
,
5593 filter
->dlist
[direct
].name
);
5594 filter
->dlist
[direct
].name
= NULL
;
5595 filter
->dlist
[direct
].alist
= NULL
;
5598 /* Check if handling a regular peer. */
5599 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5600 /* Process peer route updates. */
5601 peer_on_policy_change(peer
, afi
, safi
,
5602 (direct
== FILTER_OUT
) ? 1 : 0);
5604 /* Skip peer-group mechanics for regular peers. */
5609 * Remove configuration on all peer-group members, unless they are
5610 * explicitely overriding peer-group configuration.
5612 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5613 /* Skip peers with overridden configuration. */
5614 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5615 PEER_FT_DISTRIBUTE_LIST
))
5618 /* Remove configuration on peer-group member. */
5619 filter
= &member
->filter
[afi
][safi
];
5620 if (filter
->dlist
[direct
].name
)
5621 XFREE(MTYPE_BGP_FILTER_NAME
,
5622 filter
->dlist
[direct
].name
);
5623 filter
->dlist
[direct
].name
= NULL
;
5624 filter
->dlist
[direct
].alist
= NULL
;
5626 /* Process peer route updates. */
5627 peer_on_policy_change(member
, afi
, safi
,
5628 (direct
== FILTER_OUT
) ? 1 : 0);
5634 /* Update distribute list. */
5635 static void peer_distribute_update(struct access_list
*access
)
5640 struct listnode
*mnode
, *mnnode
;
5641 struct listnode
*node
, *nnode
;
5644 struct peer_group
*group
;
5645 struct bgp_filter
*filter
;
5647 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5649 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5650 access
->name
, 0, 0);
5651 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5652 FOREACH_AFI_SAFI (afi
, safi
) {
5653 filter
= &peer
->filter
[afi
][safi
];
5655 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5657 if (filter
->dlist
[direct
].name
)
5658 filter
->dlist
[direct
]
5659 .alist
= access_list_lookup(
5661 filter
->dlist
[direct
]
5664 filter
->dlist
[direct
].alist
=
5669 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5670 FOREACH_AFI_SAFI (afi
, safi
) {
5671 filter
= &group
->conf
->filter
[afi
][safi
];
5673 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5675 if (filter
->dlist
[direct
].name
)
5676 filter
->dlist
[direct
]
5677 .alist
= access_list_lookup(
5679 filter
->dlist
[direct
]
5682 filter
->dlist
[direct
].alist
=
5688 vnc_prefix_list_update(bgp
);
5693 /* Set prefix list to the peer. */
5694 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5697 struct peer
*member
;
5698 struct bgp_filter
*filter
;
5699 struct listnode
*node
, *nnode
;
5701 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5702 return BGP_ERR_INVALID_VALUE
;
5704 /* Set configuration on peer. */
5705 filter
= &peer
->filter
[afi
][safi
];
5706 if (filter
->dlist
[direct
].name
)
5707 return BGP_ERR_PEER_FILTER_CONFLICT
;
5708 if (filter
->plist
[direct
].name
)
5709 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5710 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5711 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5713 /* Check if handling a regular peer. */
5714 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5715 /* Set override-flag and process peer route updates. */
5716 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5717 PEER_FT_PREFIX_LIST
);
5718 peer_on_policy_change(peer
, afi
, safi
,
5719 (direct
== FILTER_OUT
) ? 1 : 0);
5721 /* Skip peer-group mechanics for regular peers. */
5726 * Set configuration on all peer-group members, unless they are
5727 * explicitely overriding peer-group configuration.
5729 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5730 /* Skip peers with overridden configuration. */
5731 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5732 PEER_FT_PREFIX_LIST
))
5735 /* Set configuration on peer-group member. */
5736 filter
= &member
->filter
[afi
][safi
];
5737 if (filter
->plist
[direct
].name
)
5738 XFREE(MTYPE_BGP_FILTER_NAME
,
5739 filter
->plist
[direct
].name
);
5740 filter
->plist
[direct
].name
=
5741 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5742 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5744 /* Process peer route updates. */
5745 peer_on_policy_change(member
, afi
, safi
,
5746 (direct
== FILTER_OUT
) ? 1 : 0);
5752 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5755 struct peer
*member
;
5756 struct bgp_filter
*filter
;
5757 struct listnode
*node
, *nnode
;
5759 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5760 return BGP_ERR_INVALID_VALUE
;
5762 /* Unset override-flag unconditionally. */
5763 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5764 PEER_FT_PREFIX_LIST
);
5766 /* Inherit configuration from peer-group if peer is member. */
5767 if (peer_group_active(peer
)) {
5768 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5769 filter
[afi
][safi
].plist
[direct
].name
,
5770 MTYPE_BGP_FILTER_NAME
);
5771 PEER_ATTR_INHERIT(peer
, peer
->group
,
5772 filter
[afi
][safi
].plist
[direct
].plist
);
5774 /* Otherwise remove configuration from peer. */
5775 filter
= &peer
->filter
[afi
][safi
];
5776 if (filter
->plist
[direct
].name
)
5777 XFREE(MTYPE_BGP_FILTER_NAME
,
5778 filter
->plist
[direct
].name
);
5779 filter
->plist
[direct
].name
= NULL
;
5780 filter
->plist
[direct
].plist
= NULL
;
5783 /* Check if handling a regular peer. */
5784 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5785 /* Process peer route updates. */
5786 peer_on_policy_change(peer
, afi
, safi
,
5787 (direct
== FILTER_OUT
) ? 1 : 0);
5789 /* Skip peer-group mechanics for regular peers. */
5794 * Remove configuration on all peer-group members, unless they are
5795 * explicitely overriding peer-group configuration.
5797 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5798 /* Skip peers with overridden configuration. */
5799 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5800 PEER_FT_PREFIX_LIST
))
5803 /* Remove configuration on peer-group member. */
5804 filter
= &member
->filter
[afi
][safi
];
5805 if (filter
->plist
[direct
].name
)
5806 XFREE(MTYPE_BGP_FILTER_NAME
,
5807 filter
->plist
[direct
].name
);
5808 filter
->plist
[direct
].name
= NULL
;
5809 filter
->plist
[direct
].plist
= NULL
;
5811 /* Process peer route updates. */
5812 peer_on_policy_change(member
, afi
, safi
,
5813 (direct
== FILTER_OUT
) ? 1 : 0);
5819 /* Update prefix-list list. */
5820 static void peer_prefix_list_update(struct prefix_list
*plist
)
5822 struct listnode
*mnode
, *mnnode
;
5823 struct listnode
*node
, *nnode
;
5826 struct peer_group
*group
;
5827 struct bgp_filter
*filter
;
5832 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5835 * Update the prefix-list on update groups.
5837 update_group_policy_update(
5838 bgp
, BGP_POLICY_PREFIX_LIST
,
5839 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5841 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5842 FOREACH_AFI_SAFI (afi
, safi
) {
5843 filter
= &peer
->filter
[afi
][safi
];
5845 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5847 if (filter
->plist
[direct
].name
)
5848 filter
->plist
[direct
]
5849 .plist
= prefix_list_lookup(
5851 filter
->plist
[direct
]
5854 filter
->plist
[direct
].plist
=
5859 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5860 FOREACH_AFI_SAFI (afi
, safi
) {
5861 filter
= &group
->conf
->filter
[afi
][safi
];
5863 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5865 if (filter
->plist
[direct
].name
)
5866 filter
->plist
[direct
]
5867 .plist
= prefix_list_lookup(
5869 filter
->plist
[direct
]
5872 filter
->plist
[direct
].plist
=
5880 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5883 struct peer
*member
;
5884 struct bgp_filter
*filter
;
5885 struct listnode
*node
, *nnode
;
5887 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5888 return BGP_ERR_INVALID_VALUE
;
5890 /* Set configuration on peer. */
5891 filter
= &peer
->filter
[afi
][safi
];
5892 if (filter
->aslist
[direct
].name
)
5893 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5894 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5895 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5897 /* Check if handling a regular peer. */
5898 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5899 /* Set override-flag and process peer route updates. */
5900 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5901 PEER_FT_FILTER_LIST
);
5902 peer_on_policy_change(peer
, afi
, safi
,
5903 (direct
== FILTER_OUT
) ? 1 : 0);
5905 /* Skip peer-group mechanics for regular peers. */
5910 * Set configuration on all peer-group members, unless they are
5911 * explicitely overriding peer-group configuration.
5913 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5914 /* Skip peers with overridden configuration. */
5915 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5916 PEER_FT_FILTER_LIST
))
5919 /* Set configuration on peer-group member. */
5920 filter
= &member
->filter
[afi
][safi
];
5921 if (filter
->aslist
[direct
].name
)
5922 XFREE(MTYPE_BGP_FILTER_NAME
,
5923 filter
->aslist
[direct
].name
);
5924 filter
->aslist
[direct
].name
=
5925 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5926 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5928 /* Process peer route updates. */
5929 peer_on_policy_change(member
, afi
, safi
,
5930 (direct
== FILTER_OUT
) ? 1 : 0);
5936 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5938 struct peer
*member
;
5939 struct bgp_filter
*filter
;
5940 struct listnode
*node
, *nnode
;
5942 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5943 return BGP_ERR_INVALID_VALUE
;
5945 /* Unset override-flag unconditionally. */
5946 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5947 PEER_FT_FILTER_LIST
);
5949 /* Inherit configuration from peer-group if peer is member. */
5950 if (peer_group_active(peer
)) {
5951 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5952 filter
[afi
][safi
].aslist
[direct
].name
,
5953 MTYPE_BGP_FILTER_NAME
);
5954 PEER_ATTR_INHERIT(peer
, peer
->group
,
5955 filter
[afi
][safi
].aslist
[direct
].aslist
);
5957 /* Otherwise remove configuration from peer. */
5958 filter
= &peer
->filter
[afi
][safi
];
5959 if (filter
->aslist
[direct
].name
)
5960 XFREE(MTYPE_BGP_FILTER_NAME
,
5961 filter
->aslist
[direct
].name
);
5962 filter
->aslist
[direct
].name
= NULL
;
5963 filter
->aslist
[direct
].aslist
= NULL
;
5966 /* Check if handling a regular peer. */
5967 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5968 /* Process peer route updates. */
5969 peer_on_policy_change(peer
, afi
, safi
,
5970 (direct
== FILTER_OUT
) ? 1 : 0);
5972 /* Skip peer-group mechanics for regular peers. */
5977 * Remove configuration on all peer-group members, unless they are
5978 * explicitely overriding peer-group configuration.
5980 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5981 /* Skip peers with overridden configuration. */
5982 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5983 PEER_FT_FILTER_LIST
))
5986 /* Remove configuration on peer-group member. */
5987 filter
= &member
->filter
[afi
][safi
];
5988 if (filter
->aslist
[direct
].name
)
5989 XFREE(MTYPE_BGP_FILTER_NAME
,
5990 filter
->aslist
[direct
].name
);
5991 filter
->aslist
[direct
].name
= NULL
;
5992 filter
->aslist
[direct
].aslist
= NULL
;
5994 /* Process peer route updates. */
5995 peer_on_policy_change(member
, afi
, safi
,
5996 (direct
== FILTER_OUT
) ? 1 : 0);
6002 static void peer_aslist_update(const char *aslist_name
)
6007 struct listnode
*mnode
, *mnnode
;
6008 struct listnode
*node
, *nnode
;
6011 struct peer_group
*group
;
6012 struct bgp_filter
*filter
;
6014 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6015 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6018 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6019 FOREACH_AFI_SAFI (afi
, safi
) {
6020 filter
= &peer
->filter
[afi
][safi
];
6022 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6024 if (filter
->aslist
[direct
].name
)
6025 filter
->aslist
[direct
]
6026 .aslist
= as_list_lookup(
6027 filter
->aslist
[direct
]
6030 filter
->aslist
[direct
].aslist
=
6035 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6036 FOREACH_AFI_SAFI (afi
, safi
) {
6037 filter
= &group
->conf
->filter
[afi
][safi
];
6039 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6041 if (filter
->aslist
[direct
].name
)
6042 filter
->aslist
[direct
]
6043 .aslist
= as_list_lookup(
6044 filter
->aslist
[direct
]
6047 filter
->aslist
[direct
].aslist
=
6055 static void peer_aslist_add(char *aslist_name
)
6057 peer_aslist_update(aslist_name
);
6058 route_map_notify_dependencies((char *)aslist_name
,
6059 RMAP_EVENT_ASLIST_ADDED
);
6062 static void peer_aslist_del(const char *aslist_name
)
6064 peer_aslist_update(aslist_name
);
6065 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6069 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6070 const char *name
, struct route_map
*route_map
)
6072 struct peer
*member
;
6073 struct bgp_filter
*filter
;
6074 struct listnode
*node
, *nnode
;
6076 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6077 return BGP_ERR_INVALID_VALUE
;
6079 /* Set configuration on peer. */
6080 filter
= &peer
->filter
[afi
][safi
];
6081 if (filter
->map
[direct
].name
)
6082 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6083 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6084 filter
->map
[direct
].map
= route_map
;
6086 /* Check if handling a regular peer. */
6087 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6088 /* Set override-flag and process peer route updates. */
6089 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6091 peer_on_policy_change(peer
, afi
, safi
,
6092 (direct
== RMAP_OUT
) ? 1 : 0);
6094 /* Skip peer-group mechanics for regular peers. */
6099 * Set configuration on all peer-group members, unless they are
6100 * explicitely overriding peer-group configuration.
6102 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6103 /* Skip peers with overridden configuration. */
6104 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6108 /* Set configuration on peer-group member. */
6109 filter
= &member
->filter
[afi
][safi
];
6110 if (filter
->map
[direct
].name
)
6111 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6112 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6113 filter
->map
[direct
].map
= route_map
;
6115 /* Process peer route updates. */
6116 peer_on_policy_change(member
, afi
, safi
,
6117 (direct
== RMAP_OUT
) ? 1 : 0);
6122 /* Unset route-map from the peer. */
6123 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6125 struct peer
*member
;
6126 struct bgp_filter
*filter
;
6127 struct listnode
*node
, *nnode
;
6129 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6130 return BGP_ERR_INVALID_VALUE
;
6132 /* Unset override-flag unconditionally. */
6133 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6135 /* Inherit configuration from peer-group if peer is member. */
6136 if (peer_group_active(peer
)) {
6137 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6138 filter
[afi
][safi
].map
[direct
].name
,
6139 MTYPE_BGP_FILTER_NAME
);
6140 PEER_ATTR_INHERIT(peer
, peer
->group
,
6141 filter
[afi
][safi
].map
[direct
].map
);
6143 /* Otherwise remove configuration from peer. */
6144 filter
= &peer
->filter
[afi
][safi
];
6145 if (filter
->map
[direct
].name
)
6146 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6147 filter
->map
[direct
].name
= NULL
;
6148 filter
->map
[direct
].map
= NULL
;
6151 /* Check if handling a regular peer. */
6152 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6153 /* Process peer route updates. */
6154 peer_on_policy_change(peer
, afi
, safi
,
6155 (direct
== RMAP_OUT
) ? 1 : 0);
6157 /* Skip peer-group mechanics for regular peers. */
6162 * Remove configuration on all peer-group members, unless they are
6163 * explicitely overriding peer-group configuration.
6165 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6166 /* Skip peers with overridden configuration. */
6167 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6171 /* Remove configuration on peer-group member. */
6172 filter
= &member
->filter
[afi
][safi
];
6173 if (filter
->map
[direct
].name
)
6174 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6175 filter
->map
[direct
].name
= NULL
;
6176 filter
->map
[direct
].map
= NULL
;
6178 /* Process peer route updates. */
6179 peer_on_policy_change(member
, afi
, safi
,
6180 (direct
== RMAP_OUT
) ? 1 : 0);
6186 /* Set unsuppress-map to the peer. */
6187 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6188 const char *name
, struct route_map
*route_map
)
6190 struct peer
*member
;
6191 struct bgp_filter
*filter
;
6192 struct listnode
*node
, *nnode
;
6194 /* Set configuration on peer. */
6195 filter
= &peer
->filter
[afi
][safi
];
6196 if (filter
->usmap
.name
)
6197 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6198 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6199 filter
->usmap
.map
= route_map
;
6201 /* Check if handling a regular peer. */
6202 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6203 /* Set override-flag and process peer route updates. */
6204 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6205 PEER_FT_UNSUPPRESS_MAP
);
6206 peer_on_policy_change(peer
, afi
, safi
, 1);
6208 /* Skip peer-group mechanics for regular peers. */
6213 * Set configuration on all peer-group members, unless they are
6214 * explicitely overriding peer-group configuration.
6216 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6217 /* Skip peers with overridden configuration. */
6218 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6219 PEER_FT_UNSUPPRESS_MAP
))
6222 /* Set configuration on peer-group member. */
6223 filter
= &member
->filter
[afi
][safi
];
6224 if (filter
->usmap
.name
)
6225 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6226 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6227 filter
->usmap
.map
= route_map
;
6229 /* Process peer route updates. */
6230 peer_on_policy_change(member
, afi
, safi
, 1);
6236 /* Unset route-map from the peer. */
6237 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6239 struct peer
*member
;
6240 struct bgp_filter
*filter
;
6241 struct listnode
*node
, *nnode
;
6243 /* Unset override-flag unconditionally. */
6244 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6246 /* Inherit configuration from peer-group if peer is member. */
6247 if (peer_group_active(peer
)) {
6248 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6249 filter
[afi
][safi
].usmap
.name
,
6250 MTYPE_BGP_FILTER_NAME
);
6251 PEER_ATTR_INHERIT(peer
, peer
->group
,
6252 filter
[afi
][safi
].usmap
.map
);
6254 /* Otherwise remove configuration from peer. */
6255 filter
= &peer
->filter
[afi
][safi
];
6256 if (filter
->usmap
.name
)
6257 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6258 filter
->usmap
.name
= NULL
;
6259 filter
->usmap
.map
= NULL
;
6262 /* Check if handling a regular peer. */
6263 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6264 /* Process peer route updates. */
6265 peer_on_policy_change(peer
, afi
, safi
, 1);
6267 /* Skip peer-group mechanics for regular peers. */
6272 * Remove configuration on all peer-group members, unless they are
6273 * explicitely overriding peer-group configuration.
6275 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6276 /* Skip peers with overridden configuration. */
6277 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6278 PEER_FT_UNSUPPRESS_MAP
))
6281 /* Remove configuration on peer-group member. */
6282 filter
= &member
->filter
[afi
][safi
];
6283 if (filter
->usmap
.name
)
6284 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6285 filter
->usmap
.name
= NULL
;
6286 filter
->usmap
.map
= NULL
;
6288 /* Process peer route updates. */
6289 peer_on_policy_change(member
, afi
, safi
, 1);
6295 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6296 uint32_t max
, uint8_t threshold
, int warning
,
6299 struct peer
*member
;
6300 struct listnode
*node
, *nnode
;
6302 /* Set flags and configuration on peer. */
6303 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6305 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6307 peer_af_flag_unset(peer
, afi
, safi
,
6308 PEER_FLAG_MAX_PREFIX_WARNING
);
6310 peer
->pmax
[afi
][safi
] = max
;
6311 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6312 peer
->pmax_restart
[afi
][safi
] = restart
;
6314 /* Check if handling a regular peer. */
6315 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6316 /* Re-check if peer violates maximum-prefix. */
6317 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6318 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6320 /* Skip peer-group mechanics for regular peers. */
6325 * Set flags and configuration on all peer-group members, unless they
6326 * are explicitely overriding peer-group configuration.
6328 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6329 /* Skip peers with overridden configuration. */
6330 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6331 PEER_FLAG_MAX_PREFIX
))
6334 /* Set flag and configuration on peer-group member. */
6335 member
->pmax
[afi
][safi
] = max
;
6336 member
->pmax_threshold
[afi
][safi
] = threshold
;
6337 member
->pmax_restart
[afi
][safi
] = restart
;
6339 SET_FLAG(member
->af_flags
[afi
][safi
],
6340 PEER_FLAG_MAX_PREFIX_WARNING
);
6342 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6343 PEER_FLAG_MAX_PREFIX_WARNING
);
6345 /* Re-check if peer violates maximum-prefix. */
6346 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6347 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6353 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6355 /* Inherit configuration from peer-group if peer is member. */
6356 if (peer_group_active(peer
)) {
6357 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6358 peer_af_flag_inherit(peer
, afi
, safi
,
6359 PEER_FLAG_MAX_PREFIX_WARNING
);
6360 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6361 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6362 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6367 /* Remove flags and configuration from peer. */
6368 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6369 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6370 peer
->pmax
[afi
][safi
] = 0;
6371 peer
->pmax_threshold
[afi
][safi
] = 0;
6372 peer
->pmax_restart
[afi
][safi
] = 0;
6375 * Remove flags and configuration from all peer-group members, unless
6376 * they are explicitely overriding peer-group configuration.
6378 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6379 struct peer
*member
;
6380 struct listnode
*node
;
6382 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6383 /* Skip peers with overridden configuration. */
6384 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6385 PEER_FLAG_MAX_PREFIX
))
6388 /* Remove flag and configuration on peer-group member.
6390 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6391 PEER_FLAG_MAX_PREFIX
);
6392 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6393 PEER_FLAG_MAX_PREFIX_WARNING
);
6394 member
->pmax
[afi
][safi
] = 0;
6395 member
->pmax_threshold
[afi
][safi
] = 0;
6396 member
->pmax_restart
[afi
][safi
] = 0;
6403 int is_ebgp_multihop_configured(struct peer
*peer
)
6405 struct peer_group
*group
;
6406 struct listnode
*node
, *nnode
;
6409 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6410 group
= peer
->group
;
6411 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6412 && (group
->conf
->ttl
!= 1))
6415 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6416 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6417 && (peer1
->ttl
!= 1))
6421 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6427 /* Set # of hops between us and BGP peer. */
6428 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6430 struct peer_group
*group
;
6431 struct listnode
*node
, *nnode
;
6434 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6435 gtsm_hops
, peer
->host
);
6437 /* We cannot configure ttl-security hops when ebgp-multihop is already
6438 set. For non peer-groups, the check is simple. For peer-groups,
6440 slightly messy, because we need to check both the peer-group
6442 and all peer-group members for any trace of ebgp-multihop
6444 before actually applying the ttl-security rules. Cisco really made a
6445 mess of this configuration parameter, and OpenBGPD got it right.
6448 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6449 if (is_ebgp_multihop_configured(peer
))
6450 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6452 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6453 peer
->gtsm_hops
= gtsm_hops
;
6455 /* Calling ebgp multihop also resets the session.
6456 * On restart, NHT will get setup correctly as will the
6457 * min & max ttls on the socket. The return value is
6460 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6465 group
= peer
->group
;
6466 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6468 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6470 /* Calling ebgp multihop also resets the
6472 * On restart, NHT will get setup correctly as
6474 * min & max ttls on the socket. The return
6478 peer_ebgp_multihop_set(peer
, MAXTTL
);
6482 /* Post the first gtsm setup or if its ibgp, maxttl setting
6484 * necessary, just set the minttl.
6486 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6487 peer
->gtsm_hops
= gtsm_hops
;
6490 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6491 MAXTTL
+ 1 - gtsm_hops
);
6492 if ((peer
->status
< Established
) && peer
->doppelganger
6493 && (peer
->doppelganger
->fd
>= 0))
6494 sockopt_minttl(peer
->su
.sa
.sa_family
,
6495 peer
->doppelganger
->fd
,
6496 MAXTTL
+ 1 - gtsm_hops
);
6498 group
= peer
->group
;
6499 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6501 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6503 /* Change setting of existing peer
6504 * established then change value (may break
6506 * not established yet (teardown session and
6508 * no session then do nothing (will get
6509 * handled by next connection)
6511 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6513 peer
->su
.sa
.sa_family
, peer
->fd
,
6514 MAXTTL
+ 1 - peer
->gtsm_hops
);
6515 if ((peer
->status
< Established
)
6516 && peer
->doppelganger
6517 && (peer
->doppelganger
->fd
>= 0))
6518 sockopt_minttl(peer
->su
.sa
.sa_family
,
6519 peer
->doppelganger
->fd
,
6520 MAXTTL
+ 1 - gtsm_hops
);
6528 int peer_ttl_security_hops_unset(struct peer
*peer
)
6530 struct peer_group
*group
;
6531 struct listnode
*node
, *nnode
;
6534 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6537 /* if a peer-group member, then reset to peer-group default rather than
6539 if (peer_group_active(peer
))
6540 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6542 peer
->gtsm_hops
= 0;
6544 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6545 /* Invoking ebgp_multihop_set will set the TTL back to the
6547 * value as well as restting the NHT and such. The session is
6550 if (peer
->sort
== BGP_PEER_EBGP
)
6551 ret
= peer_ebgp_multihop_unset(peer
);
6554 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6557 if ((peer
->status
< Established
) && peer
->doppelganger
6558 && (peer
->doppelganger
->fd
>= 0))
6559 sockopt_minttl(peer
->su
.sa
.sa_family
,
6560 peer
->doppelganger
->fd
, 0);
6563 group
= peer
->group
;
6564 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6565 peer
->gtsm_hops
= 0;
6566 if (peer
->sort
== BGP_PEER_EBGP
)
6567 ret
= peer_ebgp_multihop_unset(peer
);
6570 sockopt_minttl(peer
->su
.sa
.sa_family
,
6573 if ((peer
->status
< Established
)
6574 && peer
->doppelganger
6575 && (peer
->doppelganger
->fd
>= 0))
6576 sockopt_minttl(peer
->su
.sa
.sa_family
,
6577 peer
->doppelganger
->fd
,
6587 * If peer clear is invoked in a loop for all peers on the BGP instance,
6588 * it may end up freeing the doppelganger, and if this was the next node
6589 * to the current node, we would end up accessing the freed next node.
6590 * Pass along additional parameter which can be updated if next node
6591 * is freed; only required when walking the peer list on BGP instance.
6593 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6595 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6596 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6597 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6598 if (peer
->t_pmax_restart
) {
6599 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6600 if (bgp_debug_neighbor_events(peer
))
6602 "%s Maximum-prefix restart timer canceled",
6605 BGP_EVENT_ADD(peer
, BGP_Start
);
6609 peer
->v_start
= BGP_INIT_START_TIMER
;
6610 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6611 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6612 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6614 bgp_session_reset_safe(peer
, nnode
);
6619 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6620 enum bgp_clear_type stype
)
6622 struct peer_af
*paf
;
6624 if (peer
->status
!= Established
)
6627 if (!peer
->afc
[afi
][safi
])
6628 return BGP_ERR_AF_UNCONFIGURED
;
6630 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6632 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6633 /* Clear the "neighbor x.x.x.x default-originate" flag */
6634 paf
= peer_af_find(peer
, afi
, safi
);
6635 if (paf
&& paf
->subgroup
6636 && CHECK_FLAG(paf
->subgroup
->sflags
,
6637 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6638 UNSET_FLAG(paf
->subgroup
->sflags
,
6639 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6641 bgp_announce_route(peer
, afi
, safi
);
6644 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6645 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6646 PEER_CAP_ORF_PREFIX_SM_ADV
)
6647 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6648 PEER_CAP_ORF_PREFIX_RM_RCV
)
6649 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6650 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6651 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6652 uint8_t prefix_type
;
6654 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6655 PEER_CAP_ORF_PREFIX_RM_RCV
))
6656 prefix_type
= ORF_TYPE_PREFIX
;
6658 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6660 if (filter
->plist
[FILTER_IN
].plist
) {
6661 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6662 PEER_STATUS_ORF_PREFIX_SEND
))
6663 bgp_route_refresh_send(
6664 peer
, afi
, safi
, prefix_type
,
6666 bgp_route_refresh_send(peer
, afi
, safi
,
6668 REFRESH_IMMEDIATE
, 0);
6670 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6671 PEER_STATUS_ORF_PREFIX_SEND
))
6672 bgp_route_refresh_send(
6673 peer
, afi
, safi
, prefix_type
,
6674 REFRESH_IMMEDIATE
, 1);
6676 bgp_route_refresh_send(peer
, afi
, safi
,
6683 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6684 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6685 /* If neighbor has soft reconfiguration inbound flag.
6686 Use Adj-RIB-In database. */
6687 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6688 PEER_FLAG_SOFT_RECONFIG
))
6689 bgp_soft_reconfig_in(peer
, afi
, safi
);
6691 /* If neighbor has route refresh capability, send route
6693 message to the peer. */
6694 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6695 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6696 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6699 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6705 /* Display peer uptime.*/
6706 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6709 time_t uptime1
, epoch_tbuf
;
6712 /* If there is no connection has been done before print `never'. */
6715 json_object_string_add(json
, "peerUptime", "never");
6716 json_object_int_add(json
, "peerUptimeMsec", 0);
6718 snprintf(buf
, len
, "never");
6722 /* Get current time. */
6723 uptime1
= bgp_clock();
6725 tm
= gmtime(&uptime1
);
6727 if (uptime1
< ONE_DAY_SECOND
)
6728 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6730 else if (uptime1
< ONE_WEEK_SECOND
)
6731 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6733 else if (uptime1
< ONE_YEAR_SECOND
)
6734 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6735 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6737 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6739 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6742 epoch_tbuf
= time(NULL
) - uptime1
;
6743 json_object_string_add(json
, "peerUptime", buf
);
6744 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6745 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6752 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6753 afi_t afi
, safi_t safi
)
6755 struct bgp_filter
*filter
;
6759 filter
= &peer
->filter
[afi
][safi
];
6761 /* distribute-list. */
6762 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6764 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6765 filter
->dlist
[FILTER_IN
].name
);
6767 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6769 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6770 filter
->dlist
[FILTER_OUT
].name
);
6773 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6775 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6776 filter
->plist
[FILTER_IN
].name
);
6778 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6780 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6781 filter
->plist
[FILTER_OUT
].name
);
6784 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6785 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6786 filter
->map
[RMAP_IN
].name
);
6788 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6790 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6791 filter
->map
[RMAP_OUT
].name
);
6793 /* unsuppress-map */
6794 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6795 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6796 filter
->usmap
.name
);
6799 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6801 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6802 filter
->aslist
[FILTER_IN
].name
);
6804 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6806 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6807 filter
->aslist
[FILTER_OUT
].name
);
6810 /* BGP peer configuration display function. */
6811 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6814 struct peer
*g_peer
= NULL
;
6815 char buf
[SU_ADDRSTRLEN
];
6817 int if_pg_printed
= FALSE
;
6818 int if_ras_printed
= FALSE
;
6820 /* Skip dynamic neighbors. */
6821 if (peer_dynamic_neighbor(peer
))
6825 addr
= peer
->conf_if
;
6829 /************************************
6830 ****** Global to the neighbor ******
6831 ************************************/
6832 if (peer
->conf_if
) {
6833 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6834 vty_out(vty
, " neighbor %s interface v6only", addr
);
6836 vty_out(vty
, " neighbor %s interface", addr
);
6838 if (peer_group_active(peer
)) {
6839 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6840 if_pg_printed
= TRUE
;
6841 } else if (peer
->as_type
== AS_SPECIFIED
) {
6842 vty_out(vty
, " remote-as %u", peer
->as
);
6843 if_ras_printed
= TRUE
;
6844 } else if (peer
->as_type
== AS_INTERNAL
) {
6845 vty_out(vty
, " remote-as internal");
6846 if_ras_printed
= TRUE
;
6847 } else if (peer
->as_type
== AS_EXTERNAL
) {
6848 vty_out(vty
, " remote-as external");
6849 if_ras_printed
= TRUE
;
6855 /* remote-as and peer-group */
6856 /* peer is a member of a peer-group */
6857 if (peer_group_active(peer
)) {
6858 g_peer
= peer
->group
->conf
;
6860 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6861 if (peer
->as_type
== AS_SPECIFIED
) {
6862 vty_out(vty
, " neighbor %s remote-as %u\n",
6864 } else if (peer
->as_type
== AS_INTERNAL
) {
6866 " neighbor %s remote-as internal\n",
6868 } else if (peer
->as_type
== AS_EXTERNAL
) {
6870 " neighbor %s remote-as external\n",
6875 /* For swpX peers we displayed the peer-group
6876 * via 'neighbor swpX interface peer-group WORD' */
6878 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6882 /* peer is NOT a member of a peer-group */
6884 /* peer is a peer-group, declare the peer-group */
6885 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6886 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6889 if (!if_ras_printed
) {
6890 if (peer
->as_type
== AS_SPECIFIED
) {
6891 vty_out(vty
, " neighbor %s remote-as %u\n",
6893 } else if (peer
->as_type
== AS_INTERNAL
) {
6895 " neighbor %s remote-as internal\n",
6897 } else if (peer
->as_type
== AS_EXTERNAL
) {
6899 " neighbor %s remote-as external\n",
6906 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6907 vty_out(vty
, " neighbor %s local-as %u", addr
,
6908 peer
->change_local_as
);
6909 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6910 vty_out(vty
, " no-prepend");
6911 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6912 vty_out(vty
, " replace-as");
6918 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6922 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6923 if (peer
->tx_shutdown_message
)
6924 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6925 peer
->tx_shutdown_message
);
6927 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6931 if (peer
->bfd_info
) {
6932 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6933 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6938 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6939 vty_out(vty
, " neighbor %s password %s\n", addr
,
6943 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6944 if (!peer_group_active(peer
)) {
6945 vty_out(vty
, " neighbor %s solo\n", addr
);
6950 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6951 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6954 /* Local interface name */
6956 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6960 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6961 vty_out(vty
, " neighbor %s passive\n", addr
);
6964 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6965 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6966 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6967 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6972 /* ttl-security hops */
6973 if (peer
->gtsm_hops
!= 0) {
6974 if (!peer_group_active(peer
)
6975 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6976 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6977 addr
, peer
->gtsm_hops
);
6981 /* disable-connected-check */
6982 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6983 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6985 /* enforce-first-as */
6986 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6987 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6990 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6991 if (peer
->update_source
)
6992 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6993 sockunion2str(peer
->update_source
, buf
,
6995 else if (peer
->update_if
)
6996 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7000 /* advertisement-interval */
7001 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7002 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7006 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7007 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7008 peer
->keepalive
, peer
->holdtime
);
7010 /* timers connect */
7011 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7012 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7015 /* capability dynamic */
7016 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7017 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7019 /* capability extended-nexthop */
7020 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7021 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
7023 " no neighbor %s capability extended-nexthop\n",
7027 " neighbor %s capability extended-nexthop\n",
7031 /* dont-capability-negotiation */
7032 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7033 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7035 /* override-capability */
7036 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7037 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7039 /* strict-capability-match */
7040 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7041 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7044 /* BGP peer configuration display function. */
7045 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7046 struct peer
*peer
, afi_t afi
, safi_t safi
)
7048 struct peer
*g_peer
= NULL
;
7050 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7052 /* Skip dynamic neighbors. */
7053 if (peer_dynamic_neighbor(peer
))
7057 addr
= peer
->conf_if
;
7061 /************************************
7062 ****** Per AF to the neighbor ******
7063 ************************************/
7064 if (peer_group_active(peer
)) {
7065 g_peer
= peer
->group
->conf
;
7067 /* If the peer-group is active but peer is not, print a 'no
7069 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7070 vty_out(vty
, " no neighbor %s activate\n", addr
);
7073 /* If the peer-group is not active but peer is, print an
7075 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7076 vty_out(vty
, " neighbor %s activate\n", addr
);
7079 if (peer
->afc
[afi
][safi
]) {
7080 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7081 if (bgp_flag_check(bgp
,
7082 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7083 vty_out(vty
, " neighbor %s activate\n",
7087 vty_out(vty
, " neighbor %s activate\n", addr
);
7089 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7090 if (!bgp_flag_check(bgp
,
7091 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7093 " no neighbor %s activate\n",
7100 /* addpath TX knobs */
7101 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7102 switch (peer
->addpath_type
[afi
][safi
]) {
7103 case BGP_ADDPATH_ALL
:
7104 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7107 case BGP_ADDPATH_BEST_PER_AS
:
7109 " neighbor %s addpath-tx-bestpath-per-AS\n",
7112 case BGP_ADDPATH_MAX
:
7113 case BGP_ADDPATH_NONE
:
7118 /* ORF capability. */
7119 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7120 || peergroup_af_flag_check(peer
, afi
, safi
,
7121 PEER_FLAG_ORF_PREFIX_RM
)) {
7122 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7124 if (peergroup_af_flag_check(peer
, afi
, safi
,
7125 PEER_FLAG_ORF_PREFIX_SM
)
7126 && peergroup_af_flag_check(peer
, afi
, safi
,
7127 PEER_FLAG_ORF_PREFIX_RM
))
7128 vty_out(vty
, " both");
7129 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7130 PEER_FLAG_ORF_PREFIX_SM
))
7131 vty_out(vty
, " send");
7133 vty_out(vty
, " receive");
7137 /* Route reflector client. */
7138 if (peergroup_af_flag_check(peer
, afi
, safi
,
7139 PEER_FLAG_REFLECTOR_CLIENT
)) {
7140 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7143 /* next-hop-self force */
7144 if (peergroup_af_flag_check(peer
, afi
, safi
,
7145 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7146 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7150 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7151 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7154 /* remove-private-AS */
7155 if (peergroup_af_flag_check(peer
, afi
, safi
,
7156 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7157 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7161 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7162 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7163 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7167 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7168 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7169 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7172 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7173 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7174 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7178 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7179 vty_out(vty
, " neighbor %s as-override\n", addr
);
7182 /* send-community print. */
7183 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7184 PEER_FLAG_SEND_COMMUNITY
);
7185 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7186 PEER_FLAG_SEND_EXT_COMMUNITY
);
7187 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7188 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7190 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7191 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7192 vty_out(vty
, " no neighbor %s send-community all\n",
7197 " no neighbor %s send-community\n",
7201 " no neighbor %s send-community extended\n",
7206 " no neighbor %s send-community large\n",
7210 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7211 vty_out(vty
, " neighbor %s send-community all\n",
7213 } else if (flag_scomm
&& flag_secomm
) {
7214 vty_out(vty
, " neighbor %s send-community both\n",
7218 vty_out(vty
, " neighbor %s send-community\n",
7222 " neighbor %s send-community extended\n",
7226 " neighbor %s send-community large\n",
7231 /* Default information */
7232 if (peergroup_af_flag_check(peer
, afi
, safi
,
7233 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7234 vty_out(vty
, " neighbor %s default-originate", addr
);
7236 if (peer
->default_rmap
[afi
][safi
].name
)
7237 vty_out(vty
, " route-map %s",
7238 peer
->default_rmap
[afi
][safi
].name
);
7243 /* Soft reconfiguration inbound. */
7244 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7245 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7249 /* maximum-prefix. */
7250 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7251 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7252 peer
->pmax
[afi
][safi
]);
7254 if (peer
->pmax_threshold
[afi
][safi
]
7255 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7256 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7257 if (peer_af_flag_check(peer
, afi
, safi
,
7258 PEER_FLAG_MAX_PREFIX_WARNING
))
7259 vty_out(vty
, " warning-only");
7260 if (peer
->pmax_restart
[afi
][safi
])
7261 vty_out(vty
, " restart %u",
7262 peer
->pmax_restart
[afi
][safi
]);
7267 /* Route server client. */
7268 if (peergroup_af_flag_check(peer
, afi
, safi
,
7269 PEER_FLAG_RSERVER_CLIENT
)) {
7270 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7273 /* Nexthop-local unchanged. */
7274 if (peergroup_af_flag_check(peer
, afi
, safi
,
7275 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7276 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7279 /* allowas-in <1-10> */
7280 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7281 if (peer_af_flag_check(peer
, afi
, safi
,
7282 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7283 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7284 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7285 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7287 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7288 peer
->allowas_in
[afi
][safi
]);
7293 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7294 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7295 peer
->weight
[afi
][safi
]);
7298 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7300 /* atribute-unchanged. */
7301 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7302 || (safi
!= SAFI_EVPN
7303 && peer_af_flag_check(peer
, afi
, safi
,
7304 PEER_FLAG_NEXTHOP_UNCHANGED
))
7305 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7307 if (!peer_group_active(peer
)
7308 || peergroup_af_flag_check(peer
, afi
, safi
,
7309 PEER_FLAG_AS_PATH_UNCHANGED
)
7310 || peergroup_af_flag_check(peer
, afi
, safi
,
7311 PEER_FLAG_NEXTHOP_UNCHANGED
)
7312 || peergroup_af_flag_check(peer
, afi
, safi
,
7313 PEER_FLAG_MED_UNCHANGED
)) {
7316 " neighbor %s attribute-unchanged%s%s%s\n",
7318 peer_af_flag_check(peer
, afi
, safi
,
7319 PEER_FLAG_AS_PATH_UNCHANGED
)
7322 peer_af_flag_check(peer
, afi
, safi
,
7323 PEER_FLAG_NEXTHOP_UNCHANGED
)
7326 peer_af_flag_check(peer
, afi
, safi
,
7327 PEER_FLAG_MED_UNCHANGED
)
7334 /* Address family based peer configuration display. */
7335 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7339 struct peer_group
*group
;
7340 struct listnode
*node
, *nnode
;
7343 vty_frame(vty
, " !\n address-family ");
7344 if (afi
== AFI_IP
) {
7345 if (safi
== SAFI_UNICAST
)
7346 vty_frame(vty
, "ipv4 unicast");
7347 else if (safi
== SAFI_LABELED_UNICAST
)
7348 vty_frame(vty
, "ipv4 labeled-unicast");
7349 else if (safi
== SAFI_MULTICAST
)
7350 vty_frame(vty
, "ipv4 multicast");
7351 else if (safi
== SAFI_MPLS_VPN
)
7352 vty_frame(vty
, "ipv4 vpn");
7353 else if (safi
== SAFI_ENCAP
)
7354 vty_frame(vty
, "ipv4 encap");
7355 else if (safi
== SAFI_FLOWSPEC
)
7356 vty_frame(vty
, "ipv4 flowspec");
7357 } else if (afi
== AFI_IP6
) {
7358 if (safi
== SAFI_UNICAST
)
7359 vty_frame(vty
, "ipv6 unicast");
7360 else if (safi
== SAFI_LABELED_UNICAST
)
7361 vty_frame(vty
, "ipv6 labeled-unicast");
7362 else if (safi
== SAFI_MULTICAST
)
7363 vty_frame(vty
, "ipv6 multicast");
7364 else if (safi
== SAFI_MPLS_VPN
)
7365 vty_frame(vty
, "ipv6 vpn");
7366 else if (safi
== SAFI_ENCAP
)
7367 vty_frame(vty
, "ipv6 encap");
7368 else if (safi
== SAFI_FLOWSPEC
)
7369 vty_frame(vty
, "ipv6 flowspec");
7370 } else if (afi
== AFI_L2VPN
) {
7371 if (safi
== SAFI_EVPN
)
7372 vty_frame(vty
, "l2vpn evpn");
7374 vty_frame(vty
, "\n");
7376 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7378 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7380 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7382 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7383 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7385 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7386 /* Skip dynamic neighbors. */
7387 if (peer_dynamic_neighbor(peer
))
7390 /* Do not display doppelganger peers */
7391 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7392 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7395 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7396 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7398 if (safi
== SAFI_EVPN
)
7399 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7401 if (safi
== SAFI_FLOWSPEC
)
7402 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7404 if (safi
== SAFI_UNICAST
) {
7405 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7406 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7407 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7409 vty_out(vty
, " export vpn\n");
7411 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7412 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7414 vty_out(vty
, " import vpn\n");
7416 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7417 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7420 for (ALL_LIST_ELEMENTS_RO(
7421 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7423 vty_out(vty
, " import vrf %s\n", name
);
7427 vty_endframe(vty
, " exit-address-family\n");
7430 /* clang-format off */
7431 #if CONFDATE > 20190517
7432 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7434 /* clang-format on */
7436 int bgp_config_write(struct vty
*vty
)
7440 struct peer_group
*group
;
7442 struct listnode
*node
, *nnode
;
7443 struct listnode
*mnode
, *mnnode
;
7445 /* BGP Multiple instance. */
7446 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7447 vty_out(vty
, "no bgp multiple-instance\n");
7451 /* BGP Config type. */
7452 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7453 vty_out(vty
, "bgp config-type cisco\n");
7457 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7458 vty_out(vty
, "bgp route-map delay-timer %u\n",
7459 bm
->rmap_update_timer
);
7462 vty_out(vty
, "!\n");
7464 /* BGP configuration. */
7465 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7467 /* skip all auto created vrf as they dont have user config */
7468 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7471 /* Migrate deprecated 'bgp enforce-first-as'
7472 * config to 'neighbor * enforce-first-as' configs
7474 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7475 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7476 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7477 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7480 /* Router bgp ASN */
7481 vty_out(vty
, "router bgp %u", bgp
->as
);
7483 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7485 vty_out(vty
, " %s %s",
7487 == BGP_INSTANCE_TYPE_VIEW
)
7494 /* No Synchronization */
7495 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7496 vty_out(vty
, " no synchronization\n");
7498 /* BGP fast-external-failover. */
7499 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7500 vty_out(vty
, " no bgp fast-external-failover\n");
7502 /* BGP router ID. */
7503 if (bgp
->router_id_static
.s_addr
!= 0)
7504 vty_out(vty
, " bgp router-id %s\n",
7505 inet_ntoa(bgp
->router_id_static
));
7507 /* BGP log-neighbor-changes. */
7508 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7509 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7510 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7512 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7516 /* BGP configuration. */
7517 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7518 vty_out(vty
, " bgp always-compare-med\n");
7520 /* BGP default ipv4-unicast. */
7521 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7522 vty_out(vty
, " no bgp default ipv4-unicast\n");
7524 /* BGP default local-preference. */
7525 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7526 vty_out(vty
, " bgp default local-preference %u\n",
7527 bgp
->default_local_pref
);
7529 /* BGP default show-hostname */
7530 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7531 != DFLT_BGP_SHOW_HOSTNAME
)
7532 vty_out(vty
, " %sbgp default show-hostname\n",
7533 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7537 /* BGP default subgroup-pkt-queue-max. */
7538 if (bgp
->default_subgroup_pkt_queue_max
7539 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7540 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7541 bgp
->default_subgroup_pkt_queue_max
);
7543 /* BGP client-to-client reflection. */
7544 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7545 vty_out(vty
, " no bgp client-to-client reflection\n");
7547 /* BGP cluster ID. */
7548 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7549 vty_out(vty
, " bgp cluster-id %s\n",
7550 inet_ntoa(bgp
->cluster_id
));
7552 /* Disable ebgp connected nexthop check */
7553 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7555 " bgp disable-ebgp-connected-route-check\n");
7557 /* Confederation identifier*/
7558 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7559 vty_out(vty
, " bgp confederation identifier %i\n",
7562 /* Confederation peer */
7563 if (bgp
->confed_peers_cnt
> 0) {
7566 vty_out(vty
, " bgp confederation peers");
7568 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7569 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7574 /* BGP deterministic-med. */
7575 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7576 != DFLT_BGP_DETERMINISTIC_MED
)
7577 vty_out(vty
, " %sbgp deterministic-med\n",
7578 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7582 /* BGP update-delay. */
7583 bgp_config_write_update_delay(vty
, bgp
);
7585 if (bgp
->v_maxmed_onstartup
7586 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7587 vty_out(vty
, " bgp max-med on-startup %u",
7588 bgp
->v_maxmed_onstartup
);
7589 if (bgp
->maxmed_onstartup_value
7590 != BGP_MAXMED_VALUE_DEFAULT
)
7592 bgp
->maxmed_onstartup_value
);
7595 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7596 vty_out(vty
, " bgp max-med administrative");
7597 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7598 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7603 bgp_config_write_wpkt_quanta(vty
, bgp
);
7605 bgp_config_write_rpkt_quanta(vty
, bgp
);
7608 bgp_config_write_coalesce_time(vty
, bgp
);
7610 /* BGP graceful-restart. */
7611 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7613 " bgp graceful-restart stalepath-time %u\n",
7614 bgp
->stalepath_time
);
7615 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7616 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7618 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7619 vty_out(vty
, " bgp graceful-restart\n");
7621 /* BGP graceful-shutdown */
7622 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7623 vty_out(vty
, " bgp graceful-shutdown\n");
7625 /* BGP graceful-restart Preserve State F bit. */
7626 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7628 " bgp graceful-restart preserve-fw-state\n");
7630 /* BGP bestpath method. */
7631 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7632 vty_out(vty
, " bgp bestpath as-path ignore\n");
7633 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7634 vty_out(vty
, " bgp bestpath as-path confed\n");
7636 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7637 if (bgp_flag_check(bgp
,
7638 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7640 " bgp bestpath as-path multipath-relax as-set\n");
7643 " bgp bestpath as-path multipath-relax\n");
7647 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7649 " bgp route-reflector allow-outbound-policy\n");
7651 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7652 vty_out(vty
, " bgp bestpath compare-routerid\n");
7653 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7654 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7655 vty_out(vty
, " bgp bestpath med");
7656 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7657 vty_out(vty
, " confed");
7658 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7659 vty_out(vty
, " missing-as-worst");
7663 /* BGP network import check. */
7664 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7665 != DFLT_BGP_IMPORT_CHECK
)
7666 vty_out(vty
, " %sbgp network import-check\n",
7667 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7671 /* BGP flag dampening. */
7672 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7673 BGP_CONFIG_DAMPENING
))
7674 bgp_config_write_damp(vty
);
7676 /* BGP timers configuration. */
7677 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7678 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7679 vty_out(vty
, " timers bgp %u %u\n",
7680 bgp
->default_keepalive
, bgp
->default_holdtime
);
7683 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7684 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7687 /* Normal neighbor configuration. */
7688 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7689 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7690 bgp_config_write_peer_global(vty
, bgp
, peer
);
7693 /* listen range and limit for dynamic BGP neighbors */
7694 bgp_config_write_listen(vty
, bgp
);
7697 * BGP default autoshutdown neighbors
7699 * This must be placed after any peer and peer-group
7700 * configuration, to avoid setting all peers to shutdown after
7701 * a daemon restart, which is undesired behavior. (see #2286)
7703 if (bgp
->autoshutdown
)
7704 vty_out(vty
, " bgp default shutdown\n");
7706 /* No auto-summary */
7707 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7708 vty_out(vty
, " no auto-summary\n");
7710 /* IPv4 unicast configuration. */
7711 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7713 /* IPv4 multicast configuration. */
7714 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7716 /* IPv4 labeled-unicast configuration. */
7717 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7719 /* IPv4 VPN configuration. */
7720 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7722 /* ENCAPv4 configuration. */
7723 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7725 /* FLOWSPEC v4 configuration. */
7726 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7728 /* IPv6 unicast configuration. */
7729 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7731 /* IPv6 multicast configuration. */
7732 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7734 /* IPv6 labeled-unicast configuration. */
7735 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7736 SAFI_LABELED_UNICAST
);
7738 /* IPv6 VPN configuration. */
7739 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7741 /* ENCAPv6 configuration. */
7742 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7744 /* FLOWSPEC v6 configuration. */
7745 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7747 /* EVPN configuration. */
7748 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7751 bgp_rfapi_cfg_write(vty
, bgp
);
7754 vty_out(vty
, "!\n");
7759 void bgp_master_init(struct thread_master
*master
)
7763 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7766 bm
->bgp
= list_new();
7767 bm
->listen_sockets
= list_new();
7768 bm
->port
= BGP_PORT_DEFAULT
;
7769 bm
->master
= master
;
7770 bm
->start_time
= bgp_clock();
7771 bm
->t_rmap_update
= NULL
;
7772 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7773 bm
->terminating
= false;
7775 bgp_process_queue_init();
7777 /* init the rd id space.
7778 assign 0th index in the bitfield,
7779 so that we start with id 1
7781 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7782 bf_assign_zero_index(bm
->rd_idspace
);
7784 /* Enable multiple instances by default. */
7785 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7787 /* mpls label dynamic allocation pool */
7788 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7790 QOBJ_REG(bm
, bgp_master
);
7794 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7795 * instance delete (non-default only) or BGP exit.
7797 static void bgp_if_finish(struct bgp
*bgp
)
7799 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7800 struct interface
*ifp
;
7802 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7805 FOR_ALL_INTERFACES (vrf
, ifp
) {
7806 struct listnode
*c_node
, *c_nnode
;
7807 struct connected
*c
;
7809 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7810 bgp_connected_delete(bgp
, c
);
7814 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7816 struct vrf
*vrf
= NULL
;
7817 struct listnode
*next
;
7820 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7821 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7823 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7824 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7827 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7831 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7832 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7833 {.completions
= NULL
},
7836 struct frr_pthread
*bgp_pth_io
;
7837 struct frr_pthread
*bgp_pth_ka
;
7839 static void bgp_pthreads_init()
7841 assert(!bgp_pth_io
);
7842 assert(!bgp_pth_ka
);
7846 struct frr_pthread_attr io
= {
7847 .start
= frr_pthread_attr_default
.start
,
7848 .stop
= frr_pthread_attr_default
.stop
,
7850 struct frr_pthread_attr ka
= {
7851 .start
= bgp_keepalives_start
,
7852 .stop
= bgp_keepalives_stop
,
7854 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7855 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7858 void bgp_pthreads_run()
7860 frr_pthread_run(bgp_pth_io
, NULL
);
7861 frr_pthread_run(bgp_pth_ka
, NULL
);
7863 /* Wait until threads are ready. */
7864 frr_pthread_wait_running(bgp_pth_io
);
7865 frr_pthread_wait_running(bgp_pth_ka
);
7868 void bgp_pthreads_finish()
7870 frr_pthread_stop_all();
7871 frr_pthread_finish();
7874 void bgp_init(unsigned short instance
)
7877 /* allocates some vital data structures used by peer commands in
7880 /* pre-init pthreads */
7881 bgp_pthreads_init();
7884 bgp_zebra_init(bm
->master
, instance
);
7887 vnc_zebra_init(bm
->master
);
7890 /* BGP VTY commands installation. */
7898 bgp_route_map_init();
7899 bgp_scan_vty_init();
7904 bgp_ethernetvpn_init();
7905 bgp_flowspec_vty_init();
7907 /* Access list initialize. */
7909 access_list_add_hook(peer_distribute_update
);
7910 access_list_delete_hook(peer_distribute_update
);
7912 /* Filter list initialize. */
7914 as_list_add_hook(peer_aslist_add
);
7915 as_list_delete_hook(peer_aslist_del
);
7917 /* Prefix list initialize.*/
7919 prefix_list_add_hook(peer_prefix_list_update
);
7920 prefix_list_delete_hook(peer_prefix_list_update
);
7922 /* Community list initialize. */
7923 bgp_clist
= community_list_init();
7928 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7931 void bgp_terminate(void)
7935 struct listnode
*node
, *nnode
;
7936 struct listnode
*mnode
, *mnnode
;
7940 /* Close the listener sockets first as this prevents peers from
7942 * to reconnect on receiving the peer unconfig message. In the presence
7943 * of a large number of peers this will ensure that no peer is left with
7944 * a dangling connection
7946 /* reverse bgp_master_init */
7949 if (bm
->listen_sockets
)
7950 list_delete(&bm
->listen_sockets
);
7952 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7953 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7954 if (peer
->status
== Established
7955 || peer
->status
== OpenSent
7956 || peer
->status
== OpenConfirm
)
7957 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7958 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7960 if (bm
->process_main_queue
)
7961 work_queue_free_and_null(&bm
->process_main_queue
);
7963 if (bm
->t_rmap_update
)
7964 BGP_TIMER_OFF(bm
->t_rmap_update
);