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
;
1467 struct bgp_table
*table
;
1469 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1470 rn
= bgp_route_next(rn
)) {
1471 table
= bgp_node_get_bgp_table_info(rn
);
1472 if (table
!= NULL
) {
1473 /* Special handling for 2-level routing
1475 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1476 || safi
== SAFI_EVPN
) {
1477 for (nrn
= bgp_table_top(table
);
1478 nrn
; nrn
= bgp_route_next(nrn
))
1479 bgp_process(bgp
, nrn
, afi
, safi
);
1481 bgp_process(bgp
, rn
, afi
, safi
);
1486 /* Force a bestpath recalculation for all prefixes. This is used
1487 * when 'bgp bestpath' commands are entered.
1489 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1494 FOREACH_AFI_SAFI (afi
, safi
) {
1495 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1500 * Create new BGP peer.
1502 * conf_if and su are mutually exclusive if configuring from the cli.
1503 * If we are handing a doppelganger, then we *must* pass in both
1504 * the original peer's su and conf_if, so that we can appropriately
1505 * track the bgp->peerhash( ie we don't want to remove the current
1506 * one from the config ).
1508 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1509 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1510 int as_type
, afi_t afi
, safi_t safi
,
1511 struct peer_group
*group
)
1515 char buf
[SU_ADDRSTRLEN
];
1517 peer
= peer_new(bgp
);
1519 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1523 bgp_peer_conf_if_to_su_update(peer
);
1525 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1526 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1529 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1531 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1532 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1534 peer
->local_as
= local_as
;
1535 peer
->as
= remote_as
;
1536 peer
->as_type
= as_type
;
1537 peer
->local_id
= bgp
->router_id
;
1538 peer
->v_holdtime
= bgp
->default_holdtime
;
1539 peer
->v_keepalive
= bgp
->default_keepalive
;
1540 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1541 ? BGP_DEFAULT_IBGP_ROUTEADV
1542 : BGP_DEFAULT_EBGP_ROUTEADV
;
1544 peer
= peer_lock(peer
); /* bgp peer list reference */
1545 peer
->group
= group
;
1546 listnode_add_sort(bgp
->peer
, peer
);
1547 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1549 /* Adjust update-group coalesce timer heuristics for # peers. */
1550 if (bgp
->heuristic_coalesce
) {
1551 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1553 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1554 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1557 active
= peer_active(peer
);
1559 /* Last read and reset time set */
1560 peer
->readtime
= peer
->resettime
= bgp_clock();
1562 /* Default TTL set. */
1563 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1565 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1568 peer
->afc
[afi
][safi
] = 1;
1569 peer_af_create(peer
, afi
, safi
);
1572 /* auto shutdown if configured */
1573 if (bgp
->autoshutdown
)
1574 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1575 /* Set up peer's events and timers. */
1576 else if (!active
&& peer_active(peer
))
1577 bgp_timer_set(peer
);
1582 /* Make accept BGP peer. This function is only called from the test code */
1583 struct peer
*peer_create_accept(struct bgp
*bgp
)
1587 peer
= peer_new(bgp
);
1589 peer
= peer_lock(peer
); /* bgp peer list reference */
1590 listnode_add_sort(bgp
->peer
, peer
);
1596 * Return true if we have a peer configured to use this afi/safi
1598 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1600 struct listnode
*node
;
1603 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1604 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1607 if (peer
->afc
[afi
][safi
])
1614 /* Change peer's AS number. */
1615 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1617 bgp_peer_sort_t type
;
1620 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1621 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1622 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1623 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1624 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1626 bgp_session_reset(peer
);
1628 type
= peer_sort(peer
);
1630 peer
->as_type
= as_specified
;
1632 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1633 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1634 && peer
->bgp
->as
!= as
)
1635 peer
->local_as
= peer
->bgp
->confed_id
;
1637 peer
->local_as
= peer
->bgp
->as
;
1639 /* Advertisement-interval reset */
1640 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1641 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1642 ? BGP_DEFAULT_IBGP_ROUTEADV
1643 : BGP_DEFAULT_EBGP_ROUTEADV
;
1647 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1649 else if (type
== BGP_PEER_IBGP
)
1652 /* reflector-client reset */
1653 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1654 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1655 PEER_FLAG_REFLECTOR_CLIENT
);
1656 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1657 PEER_FLAG_REFLECTOR_CLIENT
);
1658 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1659 PEER_FLAG_REFLECTOR_CLIENT
);
1660 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1661 PEER_FLAG_REFLECTOR_CLIENT
);
1662 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1663 PEER_FLAG_REFLECTOR_CLIENT
);
1664 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1665 PEER_FLAG_REFLECTOR_CLIENT
);
1666 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1667 PEER_FLAG_REFLECTOR_CLIENT
);
1668 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1669 PEER_FLAG_REFLECTOR_CLIENT
);
1670 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1671 PEER_FLAG_REFLECTOR_CLIENT
);
1672 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1673 PEER_FLAG_REFLECTOR_CLIENT
);
1674 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1675 PEER_FLAG_REFLECTOR_CLIENT
);
1676 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1677 PEER_FLAG_REFLECTOR_CLIENT
);
1678 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1679 PEER_FLAG_REFLECTOR_CLIENT
);
1682 /* local-as reset */
1683 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1684 peer
->change_local_as
= 0;
1685 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1686 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1687 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1691 /* If peer does not exist, create new one. If peer already exists,
1692 set AS number to the peer. */
1693 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1694 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1700 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1702 peer
= peer_lookup(bgp
, su
);
1705 /* Not allowed for a dynamic peer. */
1706 if (peer_dynamic_neighbor(peer
)) {
1708 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1711 /* When this peer is a member of peer-group. */
1713 if (peer
->group
->conf
->as
) {
1714 /* Return peer group's AS number. */
1715 *as
= peer
->group
->conf
->as
;
1716 return BGP_ERR_PEER_GROUP_MEMBER
;
1718 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1719 if ((as_type
!= AS_INTERNAL
)
1720 && (bgp
->as
!= *as
)) {
1722 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1725 if ((as_type
!= AS_EXTERNAL
)
1726 && (bgp
->as
== *as
)) {
1728 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1733 /* Existing peer's AS number change. */
1734 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1735 || (peer
->as_type
!= as_type
))
1736 peer_as_change(peer
, *as
, as_type
);
1739 return BGP_ERR_NO_INTERFACE_CONFIG
;
1741 /* If the peer is not part of our confederation, and its not an
1742 iBGP peer then spoof the source AS */
1743 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1744 && !bgp_confederation_peers_check(bgp
, *as
)
1746 local_as
= bgp
->confed_id
;
1750 /* If this is IPv4 unicast configuration and "no bgp default
1751 ipv4-unicast" is specified. */
1753 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1754 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1755 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1758 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1765 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1766 struct peer
*peer
, afi_t afi
,
1770 int out
= FILTER_OUT
;
1772 uint32_t pflags_ovrd
;
1773 uint8_t *pfilter_ovrd
;
1777 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1778 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1780 /* peer af_flags apply */
1781 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1782 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1783 ^ peer
->af_flags_invert
[afi
][safi
];
1784 flags_tmp
&= ~pflags_ovrd
;
1786 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1787 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1788 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1789 conf
->af_flags_invert
[afi
][safi
]);
1791 /* maximum-prefix */
1792 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1793 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1794 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1795 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1799 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1800 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1803 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1804 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1806 /* default-originate route-map */
1807 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1808 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1809 MTYPE_ROUTE_MAP_NAME
);
1810 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1813 /* inbound filter apply */
1814 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1815 PEER_STR_ATTR_INHERIT(peer
, group
,
1816 filter
[afi
][safi
].dlist
[in
].name
,
1817 MTYPE_BGP_FILTER_NAME
);
1818 PEER_ATTR_INHERIT(peer
, group
,
1819 filter
[afi
][safi
].dlist
[in
].alist
);
1822 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1823 PEER_STR_ATTR_INHERIT(peer
, group
,
1824 filter
[afi
][safi
].plist
[in
].name
,
1825 MTYPE_BGP_FILTER_NAME
);
1826 PEER_ATTR_INHERIT(peer
, group
,
1827 filter
[afi
][safi
].plist
[in
].plist
);
1830 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1831 PEER_STR_ATTR_INHERIT(peer
, group
,
1832 filter
[afi
][safi
].aslist
[in
].name
,
1833 MTYPE_BGP_FILTER_NAME
);
1834 PEER_ATTR_INHERIT(peer
, group
,
1835 filter
[afi
][safi
].aslist
[in
].aslist
);
1838 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1839 PEER_STR_ATTR_INHERIT(peer
, group
,
1840 filter
[afi
][safi
].map
[in
].name
,
1841 MTYPE_BGP_FILTER_NAME
);
1842 PEER_ATTR_INHERIT(peer
, group
,
1843 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1846 /* outbound filter apply */
1847 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1848 PEER_STR_ATTR_INHERIT(peer
, group
,
1849 filter
[afi
][safi
].dlist
[out
].name
,
1850 MTYPE_BGP_FILTER_NAME
);
1851 PEER_ATTR_INHERIT(peer
, group
,
1852 filter
[afi
][safi
].dlist
[out
].alist
);
1855 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1856 PEER_STR_ATTR_INHERIT(peer
, group
,
1857 filter
[afi
][safi
].plist
[out
].name
,
1858 MTYPE_BGP_FILTER_NAME
);
1859 PEER_ATTR_INHERIT(peer
, group
,
1860 filter
[afi
][safi
].plist
[out
].plist
);
1863 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1864 PEER_STR_ATTR_INHERIT(peer
, group
,
1865 filter
[afi
][safi
].aslist
[out
].name
,
1866 MTYPE_BGP_FILTER_NAME
);
1867 PEER_ATTR_INHERIT(peer
, group
,
1868 filter
[afi
][safi
].aslist
[out
].aslist
);
1871 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1872 PEER_STR_ATTR_INHERIT(peer
, group
,
1873 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1874 MTYPE_BGP_FILTER_NAME
);
1875 PEER_ATTR_INHERIT(peer
, group
,
1876 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1879 /* nondirectional filter apply */
1880 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1881 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1882 MTYPE_BGP_FILTER_NAME
);
1883 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1886 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1887 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1888 bgp_addpath_type_changed(conf
->bgp
);
1892 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1897 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1898 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1899 __func__
, peer
->host
);
1903 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1905 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1906 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1907 return BGP_ERR_PEER_SAFI_CONFLICT
;
1909 /* Nothing to do if we've already activated this peer */
1910 if (peer
->afc
[afi
][safi
])
1913 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1916 active
= peer_active(peer
);
1917 peer
->afc
[afi
][safi
] = 1;
1920 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1922 if (!active
&& peer_active(peer
)) {
1923 bgp_timer_set(peer
);
1925 if (peer
->status
== Established
) {
1926 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1927 peer
->afc_adv
[afi
][safi
] = 1;
1928 bgp_capability_send(peer
, afi
, safi
,
1930 CAPABILITY_ACTION_SET
);
1931 if (peer
->afc_recv
[afi
][safi
]) {
1932 peer
->afc_nego
[afi
][safi
] = 1;
1933 bgp_announce_route(peer
, afi
, safi
);
1936 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1937 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1938 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1941 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1942 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1943 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1944 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1947 * If we are turning on a AFI/SAFI locally and we've
1948 * started bringing a peer up, we need to tell
1949 * the other peer to restart because we might loose
1950 * configuration here because when the doppelganger
1951 * gets to a established state due to how
1952 * we resolve we could just overwrite the afi/safi
1955 other
= peer
->doppelganger
;
1957 && (other
->status
== OpenSent
1958 || other
->status
== OpenConfirm
)) {
1959 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1960 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1961 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1968 /* Activate the peer or peer group for specified AFI and SAFI. */
1969 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1972 struct peer_group
*group
;
1973 struct listnode
*node
, *nnode
;
1974 struct peer
*tmp_peer
;
1977 /* Nothing to do if we've already activated this peer */
1978 if (peer
->afc
[afi
][safi
])
1983 /* This is a peer-group so activate all of the members of the
1984 * peer-group as well */
1985 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1987 /* Do not activate a peer for both SAFI_UNICAST and
1988 * SAFI_LABELED_UNICAST */
1989 if ((safi
== SAFI_UNICAST
1990 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1991 || (safi
== SAFI_LABELED_UNICAST
1992 && peer
->afc
[afi
][SAFI_UNICAST
]))
1993 return BGP_ERR_PEER_SAFI_CONFLICT
;
1995 peer
->afc
[afi
][safi
] = 1;
1996 group
= peer
->group
;
1998 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1999 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2002 ret
|= peer_activate_af(peer
, afi
, safi
);
2005 /* If this is the first peer to be activated for this
2006 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2007 if (safi
== SAFI_LABELED_UNICAST
2008 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2010 if (BGP_DEBUG(zebra
, ZEBRA
))
2012 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2014 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2015 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2018 if (safi
== SAFI_FLOWSPEC
) {
2019 /* connect to table manager */
2020 bgp_zebra_init_tm_connect(bgp
);
2025 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2028 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2029 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2030 __func__
, peer
->host
);
2034 /* Nothing to do if we've already deactivated this peer */
2035 if (!peer
->afc
[afi
][safi
])
2038 /* De-activate the address family configuration. */
2039 peer
->afc
[afi
][safi
] = 0;
2041 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2042 flog_err(EC_BGP_PEER_DELETE
,
2043 "couldn't delete af structure for peer %s",
2048 if (peer
->status
== Established
) {
2049 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2050 peer
->afc_adv
[afi
][safi
] = 0;
2051 peer
->afc_nego
[afi
][safi
] = 0;
2053 if (peer_active_nego(peer
)) {
2054 bgp_capability_send(peer
, afi
, safi
,
2056 CAPABILITY_ACTION_UNSET
);
2057 bgp_clear_route(peer
, afi
, safi
);
2058 peer
->pcount
[afi
][safi
] = 0;
2060 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2061 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2062 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2065 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2066 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2067 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2074 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2077 struct peer_group
*group
;
2078 struct peer
*tmp_peer
;
2079 struct listnode
*node
, *nnode
;
2082 /* Nothing to do if we've already de-activated this peer */
2083 if (!peer
->afc
[afi
][safi
])
2086 /* This is a peer-group so de-activate all of the members of the
2087 * peer-group as well */
2088 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2089 peer
->afc
[afi
][safi
] = 0;
2090 group
= peer
->group
;
2092 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2093 flog_err(EC_BGP_PEER_DELETE
,
2094 "couldn't delete af structure for peer %s",
2098 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2099 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2102 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2107 /* If this is the last peer to be deactivated for this
2108 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2109 if (safi
== SAFI_LABELED_UNICAST
2110 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2111 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2113 if (BGP_DEBUG(zebra
, ZEBRA
))
2115 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2117 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2118 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2123 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2126 return peer_activate(peer
, afi
, safi
);
2128 return peer_deactivate(peer
, afi
, safi
);
2131 static void peer_nsf_stop(struct peer
*peer
)
2136 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2137 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2139 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2140 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2141 peer
->nsf
[afi
][safi
] = 0;
2143 if (peer
->t_gr_restart
) {
2144 BGP_TIMER_OFF(peer
->t_gr_restart
);
2145 if (bgp_debug_neighbor_events(peer
))
2146 zlog_debug("%s graceful restart timer stopped",
2149 if (peer
->t_gr_stale
) {
2150 BGP_TIMER_OFF(peer
->t_gr_stale
);
2151 if (bgp_debug_neighbor_events(peer
))
2153 "%s graceful restart stalepath timer stopped",
2156 bgp_clear_route_all(peer
);
2159 /* Delete peer from confguration.
2161 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2162 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2164 * This function /should/ take care to be idempotent, to guard against
2165 * it being called multiple times through stray events that come in
2166 * that happen to result in this function being called again. That
2167 * said, getting here for a "Deleted" peer is a bug in the neighbour
2170 int peer_delete(struct peer
*peer
)
2176 struct bgp_filter
*filter
;
2177 struct listnode
*pn
;
2180 assert(peer
->status
!= Deleted
);
2183 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2185 bgp_reads_off(peer
);
2186 bgp_writes_off(peer
);
2187 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2188 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2190 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2191 peer_nsf_stop(peer
);
2193 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2195 /* If this peer belongs to peer group, clear up the
2198 if (peer_dynamic_neighbor(peer
))
2199 peer_drop_dynamic_neighbor(peer
);
2201 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2203 peer
); /* group->peer list reference */
2204 list_delete_node(peer
->group
->peer
, pn
);
2209 /* Withdraw all information from routing table. We can not use
2210 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2211 * executed after peer structure is deleted.
2213 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2215 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2217 if (peer
->doppelganger
) {
2218 peer
->doppelganger
->doppelganger
= NULL
;
2219 peer
->doppelganger
= NULL
;
2222 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2223 bgp_fsm_change_status(peer
, Deleted
);
2225 /* Remove from NHT */
2226 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2227 bgp_unlink_nexthop_by_peer(peer
);
2229 /* Password configuration */
2230 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2231 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2233 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2234 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2235 bgp_md5_unset(peer
);
2238 bgp_timer_set(peer
); /* stops all timers for Deleted */
2240 /* Delete from all peer list. */
2241 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2242 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2243 peer_unlock(peer
); /* bgp peer list reference */
2244 list_delete_node(bgp
->peer
, pn
);
2245 hash_release(bgp
->peerhash
, peer
);
2250 stream_fifo_free(peer
->ibuf
);
2255 stream_fifo_free(peer
->obuf
);
2259 if (peer
->ibuf_work
) {
2260 ringbuf_del(peer
->ibuf_work
);
2261 peer
->ibuf_work
= NULL
;
2264 if (peer
->obuf_work
) {
2265 stream_free(peer
->obuf_work
);
2266 peer
->obuf_work
= NULL
;
2269 if (peer
->scratch
) {
2270 stream_free(peer
->scratch
);
2271 peer
->scratch
= NULL
;
2274 /* Local and remote addresses. */
2275 if (peer
->su_local
) {
2276 sockunion_free(peer
->su_local
);
2277 peer
->su_local
= NULL
;
2280 if (peer
->su_remote
) {
2281 sockunion_free(peer
->su_remote
);
2282 peer
->su_remote
= NULL
;
2285 /* Free filter related memory. */
2286 FOREACH_AFI_SAFI (afi
, safi
) {
2287 filter
= &peer
->filter
[afi
][safi
];
2289 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2290 if (filter
->dlist
[i
].name
) {
2291 XFREE(MTYPE_BGP_FILTER_NAME
,
2292 filter
->dlist
[i
].name
);
2293 filter
->dlist
[i
].name
= NULL
;
2296 if (filter
->plist
[i
].name
) {
2297 XFREE(MTYPE_BGP_FILTER_NAME
,
2298 filter
->plist
[i
].name
);
2299 filter
->plist
[i
].name
= NULL
;
2302 if (filter
->aslist
[i
].name
) {
2303 XFREE(MTYPE_BGP_FILTER_NAME
,
2304 filter
->aslist
[i
].name
);
2305 filter
->aslist
[i
].name
= NULL
;
2309 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2310 if (filter
->map
[i
].name
) {
2311 XFREE(MTYPE_BGP_FILTER_NAME
,
2312 filter
->map
[i
].name
);
2313 filter
->map
[i
].name
= NULL
;
2317 if (filter
->usmap
.name
) {
2318 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2319 filter
->usmap
.name
= NULL
;
2322 if (peer
->default_rmap
[afi
][safi
].name
) {
2323 XFREE(MTYPE_ROUTE_MAP_NAME
,
2324 peer
->default_rmap
[afi
][safi
].name
);
2325 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2329 FOREACH_AFI_SAFI (afi
, safi
)
2330 peer_af_delete(peer
, afi
, safi
);
2332 if (peer
->hostname
) {
2333 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2334 peer
->hostname
= NULL
;
2337 if (peer
->domainname
) {
2338 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2339 peer
->domainname
= NULL
;
2342 peer_unlock(peer
); /* initial reference */
2347 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2349 return strcmp(g1
->name
, g2
->name
);
2352 /* Peer group cofiguration. */
2353 static struct peer_group
*peer_group_new(void)
2355 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2356 sizeof(struct peer_group
));
2359 static void peer_group_free(struct peer_group
*group
)
2361 XFREE(MTYPE_PEER_GROUP
, group
);
2364 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2366 struct peer_group
*group
;
2367 struct listnode
*node
, *nnode
;
2369 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2370 if (strcmp(group
->name
, name
) == 0)
2376 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2378 struct peer_group
*group
;
2381 group
= peer_group_lookup(bgp
, name
);
2385 group
= peer_group_new();
2388 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2389 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2390 group
->peer
= list_new();
2391 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2392 group
->listen_range
[afi
] = list_new();
2393 group
->conf
= peer_new(bgp
);
2394 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2395 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2396 if (group
->conf
->host
)
2397 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2398 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2399 group
->conf
->group
= group
;
2400 group
->conf
->as
= 0;
2401 group
->conf
->ttl
= 1;
2402 group
->conf
->gtsm_hops
= 0;
2403 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2404 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2405 listnode_add_sort(bgp
->group
, group
);
2410 static void peer_group2peer_config_copy(struct peer_group
*group
,
2420 peer
->as
= conf
->as
;
2423 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2424 peer
->change_local_as
= conf
->change_local_as
;
2427 peer
->ttl
= conf
->ttl
;
2430 peer
->gtsm_hops
= conf
->gtsm_hops
;
2432 /* peer flags apply */
2433 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2434 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2435 flags_tmp
&= ~peer
->flags_override
;
2437 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2438 SET_FLAG(peer
->flags
, flags_tmp
);
2439 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2441 /* peer timers apply */
2442 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2443 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2444 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2447 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2448 PEER_ATTR_INHERIT(peer
, group
, connect
);
2449 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2450 peer
->v_connect
= conf
->connect
;
2452 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2455 /* advertisement-interval apply */
2456 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2457 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2458 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2459 peer
->v_routeadv
= conf
->routeadv
;
2461 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2462 ? BGP_DEFAULT_IBGP_ROUTEADV
2463 : BGP_DEFAULT_EBGP_ROUTEADV
;
2466 /* password apply */
2467 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2468 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2469 MTYPE_PEER_PASSWORD
);
2471 if (!BGP_PEER_SU_UNSPEC(peer
))
2474 /* update-source apply */
2475 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2476 if (conf
->update_source
) {
2477 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2478 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2479 } else if (conf
->update_if
) {
2480 sockunion_free(peer
->update_source
);
2481 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2482 MTYPE_PEER_UPDATE_SOURCE
);
2486 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2489 /* Peer group's remote AS configuration. */
2490 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2493 struct peer_group
*group
;
2495 struct listnode
*node
, *nnode
;
2497 group
= peer_group_lookup(bgp
, group_name
);
2501 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2505 /* When we setup peer-group AS number all peer group member's AS
2506 number must be updated to same number. */
2507 peer_as_change(group
->conf
, *as
, as_type
);
2509 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2510 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2511 || (peer
->as_type
!= as_type
))
2512 peer_as_change(peer
, *as
, as_type
);
2518 int peer_group_delete(struct peer_group
*group
)
2522 struct prefix
*prefix
;
2524 struct listnode
*node
, *nnode
;
2529 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2530 other
= peer
->doppelganger
;
2532 if (other
&& other
->status
!= Deleted
) {
2533 other
->group
= NULL
;
2537 list_delete(&group
->peer
);
2539 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2540 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2542 prefix_free(prefix
);
2544 list_delete(&group
->listen_range
[afi
]);
2547 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2550 bfd_info_free(&(group
->conf
->bfd_info
));
2552 group
->conf
->group
= NULL
;
2553 peer_delete(group
->conf
);
2555 /* Delete from all peer_group list. */
2556 listnode_delete(bgp
->group
, group
);
2558 peer_group_free(group
);
2563 int peer_group_remote_as_delete(struct peer_group
*group
)
2565 struct peer
*peer
, *other
;
2566 struct listnode
*node
, *nnode
;
2568 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2569 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2572 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2573 other
= peer
->doppelganger
;
2577 if (other
&& other
->status
!= Deleted
) {
2578 other
->group
= NULL
;
2582 list_delete_all_node(group
->peer
);
2584 group
->conf
->as
= 0;
2585 group
->conf
->as_type
= AS_UNSPECIFIED
;
2590 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2592 struct prefix
*prefix
;
2593 struct listnode
*node
, *nnode
;
2596 afi
= family2afi(range
->family
);
2598 /* Group needs remote AS configured. */
2599 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2600 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2602 /* Ensure no duplicates. Currently we don't care about overlaps. */
2603 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2604 if (prefix_same(range
, prefix
))
2608 prefix
= prefix_new();
2609 prefix_copy(prefix
, range
);
2610 listnode_add(group
->listen_range
[afi
], prefix
);
2614 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2616 struct prefix
*prefix
, prefix2
;
2617 struct listnode
*node
, *nnode
;
2620 char buf
[PREFIX2STR_BUFFER
];
2622 afi
= family2afi(range
->family
);
2624 /* Identify the listen range. */
2625 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2626 if (prefix_same(range
, prefix
))
2631 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2633 prefix2str(prefix
, buf
, sizeof(buf
));
2635 /* Dispose off any dynamic neighbors that exist due to this listen range
2637 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2638 if (!peer_dynamic_neighbor(peer
))
2641 sockunion2hostprefix(&peer
->su
, &prefix2
);
2642 if (prefix_match(prefix
, &prefix2
)) {
2643 if (bgp_debug_neighbor_events(peer
))
2645 "Deleting dynamic neighbor %s group %s upon "
2646 "delete of listen range %s",
2647 peer
->host
, group
->name
, buf
);
2652 /* Get rid of the listen range */
2653 listnode_delete(group
->listen_range
[afi
], prefix
);
2658 /* Bind specified peer to peer group. */
2659 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2660 struct peer_group
*group
, as_t
*as
)
2662 int first_member
= 0;
2666 /* Lookup the peer. */
2668 peer
= peer_lookup(bgp
, su
);
2670 /* The peer exist, bind it to the peer-group */
2672 /* When the peer already belongs to a peer-group, check the
2674 if (peer_group_active(peer
)) {
2676 /* The peer is already bound to the peer-group,
2679 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2682 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2685 /* The peer has not specified a remote-as, inherit it from the
2687 if (peer
->as_type
== AS_UNSPECIFIED
) {
2688 peer
->as_type
= group
->conf
->as_type
;
2689 peer
->as
= group
->conf
->as
;
2692 if (!group
->conf
->as
) {
2693 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2694 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2697 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2700 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2704 peer_group2peer_config_copy(group
, peer
);
2706 FOREACH_AFI_SAFI (afi
, safi
) {
2707 if (group
->conf
->afc
[afi
][safi
]) {
2708 peer
->afc
[afi
][safi
] = 1;
2710 if (peer_af_find(peer
, afi
, safi
)
2711 || peer_af_create(peer
, afi
, safi
)) {
2712 peer_group2peer_config_copy_af(
2713 group
, peer
, afi
, safi
);
2715 } else if (peer
->afc
[afi
][safi
])
2716 peer_deactivate(peer
, afi
, safi
);
2720 assert(group
&& peer
->group
== group
);
2722 listnode_delete(bgp
->peer
, peer
);
2724 peer
->group
= group
;
2725 listnode_add_sort(bgp
->peer
, peer
);
2727 peer
= peer_lock(peer
); /* group->peer list reference */
2728 listnode_add(group
->peer
, peer
);
2732 /* Advertisement-interval reset */
2733 if (!CHECK_FLAG(group
->conf
->flags
,
2734 PEER_FLAG_ROUTEADV
)) {
2735 group
->conf
->v_routeadv
=
2736 (peer_sort(group
->conf
)
2738 ? BGP_DEFAULT_IBGP_ROUTEADV
2739 : BGP_DEFAULT_EBGP_ROUTEADV
;
2742 /* ebgp-multihop reset */
2743 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2744 group
->conf
->ttl
= MAXTTL
;
2746 /* local-as reset */
2747 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2748 group
->conf
->change_local_as
= 0;
2749 peer_flag_unset(group
->conf
,
2750 PEER_FLAG_LOCAL_AS
);
2751 peer_flag_unset(group
->conf
,
2752 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2753 peer_flag_unset(group
->conf
,
2754 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2758 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2760 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2761 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2762 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2763 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2765 bgp_session_reset(peer
);
2769 /* Create a new peer. */
2771 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2772 && (!group
->conf
->as
)) {
2773 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2776 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2777 group
->conf
->as_type
, 0, 0, group
);
2779 peer
= peer_lock(peer
); /* group->peer list reference */
2780 listnode_add(group
->peer
, peer
);
2782 peer_group2peer_config_copy(group
, peer
);
2784 /* If the peer-group is active for this afi/safi then activate
2786 FOREACH_AFI_SAFI (afi
, safi
) {
2787 if (group
->conf
->afc
[afi
][safi
]) {
2788 peer
->afc
[afi
][safi
] = 1;
2789 peer_af_create(peer
, afi
, safi
);
2790 peer_group2peer_config_copy_af(group
, peer
, afi
,
2792 } else if (peer
->afc
[afi
][safi
])
2793 peer_deactivate(peer
, afi
, safi
);
2796 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2798 /* Set up peer's events and timers. */
2799 if (peer_active(peer
))
2800 bgp_timer_set(peer
);
2806 static int bgp_startup_timer_expire(struct thread
*thread
)
2810 bgp
= THREAD_ARG(thread
);
2811 bgp
->t_startup
= NULL
;
2817 * On shutdown we call the cleanup function which
2818 * does a free of the link list nodes, free up
2819 * the data we are pointing at too.
2821 static void bgp_vrf_string_name_delete(void *data
)
2825 XFREE(MTYPE_TMP
, vname
);
2828 /* BGP instance creation by `router bgp' commands. */
2829 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2830 enum bgp_instance_type inst_type
)
2836 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2839 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2840 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2841 zlog_debug("Creating Default VRF, AS %u", *as
);
2843 zlog_debug("Creating %s %s, AS %u",
2844 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2851 bgp
->heuristic_coalesce
= true;
2852 bgp
->inst_type
= inst_type
;
2853 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2855 bgp
->peer_self
= peer_new(bgp
);
2856 if (bgp
->peer_self
->host
)
2857 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2858 bgp
->peer_self
->host
=
2859 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2860 if (bgp
->peer_self
->hostname
!= NULL
) {
2861 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2862 bgp
->peer_self
->hostname
= NULL
;
2864 if (cmd_hostname_get())
2865 bgp
->peer_self
->hostname
=
2866 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2868 if (bgp
->peer_self
->domainname
!= NULL
) {
2869 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2870 bgp
->peer_self
->domainname
= NULL
;
2872 if (cmd_domainname_get())
2873 bgp
->peer_self
->domainname
=
2874 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2875 bgp
->peer
= list_new();
2876 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2877 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2879 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2881 bgp
->group
= list_new();
2882 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2884 FOREACH_AFI_SAFI (afi
, safi
) {
2885 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2886 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2887 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2889 /* Enable maximum-paths */
2890 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2892 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2896 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2897 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2898 bgp
->default_subgroup_pkt_queue_max
=
2899 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2900 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2901 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2902 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2903 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2904 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2905 bgp
->dynamic_neighbors_count
= 0;
2906 #if DFLT_BGP_IMPORT_CHECK
2907 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2909 #if DFLT_BGP_SHOW_HOSTNAME
2910 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2912 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2913 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2915 #if DFLT_BGP_DETERMINISTIC_MED
2916 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2918 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2923 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2924 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2926 assert(bgp
->rfapi_cfg
);
2928 #endif /* ENABLE_BGP_VNC */
2930 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2931 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2932 bgp
->vpn_policy
[afi
].afi
= afi
;
2933 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2934 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2937 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2938 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2939 bgp_vrf_string_name_delete
;
2940 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2941 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2942 bgp_vrf_string_name_delete
;
2945 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2947 /* TODO - The startup timer needs to be run for the whole of BGP
2949 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2950 bgp
->restart_time
, &bgp
->t_startup
);
2953 /* printable name we can use in debug messages */
2954 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2955 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2965 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2967 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2968 snprintf(bgp
->name_pretty
, len
, "%s %s",
2969 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2975 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2976 memory_order_relaxed
);
2977 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2978 memory_order_relaxed
);
2979 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2983 update_bgp_group_init(bgp
);
2985 /* assign a unique rd id for auto derivation of vrf's RD */
2986 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2988 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
2989 sizeof(struct bgp_evpn_info
));
2996 /* Return the "default VRF" instance of BGP. */
2997 struct bgp
*bgp_get_default(void)
3000 struct listnode
*node
, *nnode
;
3002 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3003 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3008 /* Lookup BGP entry. */
3009 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3012 struct listnode
*node
, *nnode
;
3014 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3016 && ((bgp
->name
== NULL
&& name
== NULL
)
3017 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3022 /* Lookup BGP structure by view name. */
3023 struct bgp
*bgp_lookup_by_name(const char *name
)
3026 struct listnode
*node
, *nnode
;
3028 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3029 if ((bgp
->name
== NULL
&& name
== NULL
)
3030 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3035 /* Lookup BGP instance based on VRF id. */
3036 /* Note: Only to be used for incoming messages from Zebra. */
3037 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3041 /* Lookup VRF (in tree) and follow link. */
3042 vrf
= vrf_lookup_by_id(vrf_id
);
3045 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3048 /* handle socket creation or deletion, if necessary
3049 * this is called for all new BGP instances
3051 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3056 /* Create BGP server socket, if listen mode not disabled */
3057 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3059 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3061 * suppress vrf socket
3063 if (create
== FALSE
) {
3064 bgp_close_vrf_socket(bgp
);
3068 return BGP_ERR_INVALID_VALUE
;
3070 * if vrf_id did not change
3072 if (vrf
->vrf_id
== old_vrf_id
)
3074 if (old_vrf_id
!= VRF_UNKNOWN
) {
3075 /* look for old socket. close it. */
3076 bgp_close_vrf_socket(bgp
);
3078 /* if backend is not yet identified ( VRF_UNKNOWN) then
3079 * creation will be done later
3081 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3083 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3085 return BGP_ERR_INVALID_VALUE
;
3088 return bgp_check_main_socket(create
, bgp
);
3091 /* Called from VTY commands. */
3092 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3093 enum bgp_instance_type inst_type
)
3096 struct vrf
*vrf
= NULL
;
3098 /* Multiple instance check. */
3099 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3101 bgp
= bgp_lookup_by_name(name
);
3103 bgp
= bgp_get_default();
3105 /* Already exists. */
3107 if (bgp
->as
!= *as
) {
3109 return BGP_ERR_INSTANCE_MISMATCH
;
3111 if (bgp
->inst_type
!= inst_type
)
3112 return BGP_ERR_INSTANCE_MISMATCH
;
3117 /* BGP instance name can not be specified for single instance.
3120 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3122 /* Get default BGP structure if exists. */
3123 bgp
= bgp_get_default();
3126 if (bgp
->as
!= *as
) {
3128 return BGP_ERR_AS_MISMATCH
;
3135 bgp
= bgp_create(as
, name
, inst_type
);
3136 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3137 bgp
->vrf_id
= vrf_generate_id();
3138 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3139 bgp_address_init(bgp
);
3140 bgp_tip_hash_init(bgp
);
3144 bgp
->t_rmap_def_originate_eval
= NULL
;
3146 /* If Default instance or VRF, link to the VRF structure, if present. */
3147 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3148 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3149 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3151 bgp_vrf_link(bgp
, vrf
);
3153 /* BGP server socket already processed if BGP instance
3154 * already part of the list
3156 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3157 listnode_add(bm
->bgp
, bgp
);
3159 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3160 if (BGP_DEBUG(zebra
, ZEBRA
))
3161 zlog_debug("%s: Registering BGP instance %s to zebra",
3162 __PRETTY_FUNCTION__
, name
);
3163 bgp_zebra_instance_register(bgp
);
3170 * Make BGP instance "up". Applies only to VRFs (non-default) and
3171 * implies the VRF has been learnt from Zebra.
3173 void bgp_instance_up(struct bgp
*bgp
)
3176 struct listnode
*node
, *next
;
3178 /* Register with zebra. */
3179 bgp_zebra_instance_register(bgp
);
3181 /* Kick off any peers that may have been configured. */
3182 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3183 if (!BGP_PEER_START_SUPPRESSED(peer
))
3184 BGP_EVENT_ADD(peer
, BGP_Start
);
3187 /* Process any networks that have been configured. */
3188 bgp_static_add(bgp
);
3192 * Make BGP instance "down". Applies only to VRFs (non-default) and
3193 * implies the VRF has been deleted by Zebra.
3195 void bgp_instance_down(struct bgp
*bgp
)
3198 struct listnode
*node
;
3199 struct listnode
*next
;
3202 if (bgp
->t_rmap_def_originate_eval
) {
3203 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3204 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3208 /* Bring down peers, so corresponding routes are purged. */
3209 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3210 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3211 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3212 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3214 bgp_session_reset(peer
);
3217 /* Purge network and redistributed routes. */
3218 bgp_purge_static_redist_routes(bgp
);
3220 /* Cleanup registered nexthops (flags) */
3221 bgp_cleanup_nexthops(bgp
);
3224 /* Delete BGP instance. */
3225 int bgp_delete(struct bgp
*bgp
)
3228 struct peer_group
*group
;
3229 struct listnode
*node
, *next
;
3235 THREAD_OFF(bgp
->t_startup
);
3236 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3237 THREAD_OFF(bgp
->t_update_delay
);
3238 THREAD_OFF(bgp
->t_establish_wait
);
3240 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3241 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3242 zlog_debug("Deleting Default VRF");
3244 zlog_debug("Deleting %s %s",
3245 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3251 /* unmap from RT list */
3252 bgp_evpn_vrf_delete(bgp
);
3255 if (bgp
->t_rmap_def_originate_eval
) {
3256 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3257 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3261 /* Inform peers we're going down. */
3262 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3263 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3265 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3268 /* Delete static routes (networks). */
3269 bgp_static_delete(bgp
);
3271 /* Unset redistribution. */
3272 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3273 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3274 if (i
!= ZEBRA_ROUTE_BGP
)
3275 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3277 /* Free peers and peer-groups. */
3278 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3279 peer_group_delete(group
);
3281 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3284 if (bgp
->peer_self
) {
3285 peer_delete(bgp
->peer_self
);
3286 bgp
->peer_self
= NULL
;
3289 update_bgp_group_free(bgp
);
3291 /* TODO - Other memory may need to be freed - e.g., NHT */
3296 bgp_cleanup_routes(bgp
);
3298 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3299 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3302 &bgp
->vpn_policy
[afi
]
3303 .import_redirect_rtlist
);
3304 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3307 /* Deregister from Zebra, if needed */
3308 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3309 if (BGP_DEBUG(zebra
, ZEBRA
))
3310 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3311 __PRETTY_FUNCTION__
, bgp
->name
);
3312 bgp_zebra_instance_deregister(bgp
);
3315 /* Remove visibility via the master list - there may however still be
3316 * routes to be processed still referencing the struct bgp.
3318 listnode_delete(bm
->bgp
, bgp
);
3320 /* Free interfaces in this instance. */
3323 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3324 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3326 bgp_vrf_unlink(bgp
, vrf
);
3328 thread_master_free_unused(bm
->master
);
3329 bgp_unlock(bgp
); /* initial reference */
3334 void bgp_free(struct bgp
*bgp
)
3338 struct bgp_table
*table
;
3339 struct bgp_node
*rn
;
3340 struct bgp_rmap
*rmap
;
3344 list_delete(&bgp
->group
);
3345 list_delete(&bgp
->peer
);
3347 if (bgp
->peerhash
) {
3348 hash_free(bgp
->peerhash
);
3349 bgp
->peerhash
= NULL
;
3352 FOREACH_AFI_SAFI (afi
, safi
) {
3353 /* Special handling for 2-level routing tables. */
3354 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3355 || safi
== SAFI_EVPN
) {
3356 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3357 rn
= bgp_route_next(rn
)) {
3358 table
= bgp_node_get_bgp_table_info(rn
);
3359 bgp_table_finish(&table
);
3362 if (bgp
->route
[afi
][safi
])
3363 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3364 if (bgp
->aggregate
[afi
][safi
])
3365 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3366 if (bgp
->rib
[afi
][safi
])
3367 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3368 rmap
= &bgp
->table_map
[afi
][safi
];
3370 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3373 bgp_scan_finish(bgp
);
3374 bgp_address_destroy(bgp
);
3375 bgp_tip_hash_destroy(bgp
);
3377 /* release the auto RD id */
3378 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3380 bgp_evpn_cleanup(bgp
);
3381 bgp_pbr_cleanup(bgp
);
3382 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3384 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3385 vpn_policy_direction_t dir
;
3387 if (bgp
->vpn_policy
[afi
].import_vrf
)
3388 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3389 if (bgp
->vpn_policy
[afi
].export_vrf
)
3390 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3392 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3393 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3394 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3395 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3396 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3397 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3401 XFREE(MTYPE_BGP
, bgp
->name
);
3402 if (bgp
->name_pretty
)
3403 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3405 XFREE(MTYPE_BGP
, bgp
);
3408 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3411 struct listnode
*node
, *nnode
;
3417 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3418 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3419 && !CHECK_FLAG(peer
->sflags
,
3420 PEER_STATUS_ACCEPT_PEER
))
3422 } else if (bm
->bgp
!= NULL
) {
3423 struct listnode
*bgpnode
, *nbgpnode
;
3425 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3426 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3428 && !strcmp(peer
->conf_if
, conf_if
)
3429 && !CHECK_FLAG(peer
->sflags
,
3430 PEER_STATUS_ACCEPT_PEER
))
3436 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3439 struct listnode
*node
, *nnode
;
3445 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3446 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3447 && !CHECK_FLAG(peer
->sflags
,
3448 PEER_STATUS_ACCEPT_PEER
))
3450 } else if (bm
->bgp
!= NULL
) {
3451 struct listnode
*bgpnode
, *nbgpnode
;
3453 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3454 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3456 && !strcmp(peer
->hostname
, hostname
)
3457 && !CHECK_FLAG(peer
->sflags
,
3458 PEER_STATUS_ACCEPT_PEER
))
3464 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3466 struct peer
*peer
= NULL
;
3467 struct peer tmp_peer
;
3469 memset(&tmp_peer
, 0, sizeof(struct peer
));
3472 * We do not want to find the doppelganger peer so search for the peer
3474 * the hash that has PEER_FLAG_CONFIG_NODE
3476 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3481 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3482 } else if (bm
->bgp
!= NULL
) {
3483 struct listnode
*bgpnode
, *nbgpnode
;
3485 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3486 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3495 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3496 union sockunion
*su
,
3497 struct peer_group
*group
)
3503 /* Create peer first; we've already checked group config is valid. */
3504 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3505 group
->conf
->as_type
, 0, 0, group
);
3510 peer
= peer_lock(peer
);
3511 listnode_add(group
->peer
, peer
);
3513 peer_group2peer_config_copy(group
, peer
);
3516 * Bind peer for all AFs configured for the group. We don't call
3517 * peer_group_bind as that is sub-optimal and does some stuff we don't
3520 FOREACH_AFI_SAFI (afi
, safi
) {
3521 if (!group
->conf
->afc
[afi
][safi
])
3523 peer
->afc
[afi
][safi
] = 1;
3525 if (!peer_af_find(peer
, afi
, safi
))
3526 peer_af_create(peer
, afi
, safi
);
3528 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3531 /* Mark as dynamic, but also as a "config node" for other things to
3533 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3534 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3540 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3541 struct prefix
*prefix
)
3543 struct listnode
*node
, *nnode
;
3544 struct prefix
*range
;
3547 afi
= family2afi(prefix
->family
);
3549 if (group
->listen_range
[afi
])
3550 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3552 if (prefix_match(range
, prefix
))
3559 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3560 struct prefix
**listen_range
)
3562 struct prefix
*range
= NULL
;
3563 struct peer_group
*group
= NULL
;
3564 struct listnode
*node
, *nnode
;
3566 *listen_range
= NULL
;
3568 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3569 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3572 } else if (bm
->bgp
!= NULL
) {
3573 struct listnode
*bgpnode
, *nbgpnode
;
3575 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3576 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3577 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3583 *listen_range
= range
;
3584 return (group
&& range
) ? group
: NULL
;
3587 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3589 struct peer_group
*group
;
3592 struct prefix prefix
;
3593 struct prefix
*listen_range
;
3595 char buf
[PREFIX2STR_BUFFER
];
3596 char buf1
[PREFIX2STR_BUFFER
];
3598 sockunion2hostprefix(su
, &prefix
);
3600 /* See if incoming connection matches a configured listen range. */
3601 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3612 prefix2str(&prefix
, buf
, sizeof(buf
));
3613 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3615 if (bgp_debug_neighbor_events(NULL
))
3617 "Dynamic Neighbor %s matches group %s listen range %s",
3618 buf
, group
->name
, buf1
);
3620 /* Are we within the listen limit? */
3621 dncount
= gbgp
->dynamic_neighbors_count
;
3623 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3624 if (bgp_debug_neighbor_events(NULL
))
3625 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3626 inet_sutop(su
, buf
),
3627 gbgp
->dynamic_neighbors_limit
);
3631 /* Ensure group is not disabled. */
3632 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3633 if (bgp_debug_neighbor_events(NULL
))
3635 "Dynamic Neighbor %s rejected - group %s disabled",
3640 /* Check that at least one AF is activated for the group. */
3641 if (!peer_group_af_configured(group
)) {
3642 if (bgp_debug_neighbor_events(NULL
))
3644 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3649 /* Create dynamic peer and bind to associated group. */
3650 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3653 gbgp
->dynamic_neighbors_count
= ++dncount
;
3655 if (bgp_debug_neighbor_events(peer
))
3656 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3657 peer
->host
, group
->name
, dncount
);
3662 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3665 if (peer
->group
->bgp
) {
3666 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3668 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3670 if (bgp_debug_neighbor_events(peer
))
3671 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3672 peer
->group
->name
, dncount
);
3675 /* If peer is configured at least one address family return 1. */
3676 int peer_active(struct peer
*peer
)
3678 if (BGP_PEER_SU_UNSPEC(peer
))
3680 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3681 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3682 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3683 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3684 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3685 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3686 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3687 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3688 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3689 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3690 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3695 /* If peer is negotiated at least one address family return 1. */
3696 int peer_active_nego(struct peer
*peer
)
3698 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3699 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3700 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3701 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3702 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3703 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3704 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3705 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3706 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3707 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3708 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3709 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3710 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3715 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3716 enum peer_change_type type
)
3718 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3721 if (peer
->status
!= Established
)
3724 if (type
== peer_change_reset
) {
3725 /* If we're resetting session, we've to delete both peer struct
3727 if ((peer
->doppelganger
)
3728 && (peer
->doppelganger
->status
!= Deleted
)
3729 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3730 PEER_FLAG_CONFIG_NODE
)))
3731 peer_delete(peer
->doppelganger
);
3733 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3734 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3735 } else if (type
== peer_change_reset_in
) {
3736 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3737 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3738 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3740 if ((peer
->doppelganger
)
3741 && (peer
->doppelganger
->status
!= Deleted
)
3742 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3743 PEER_FLAG_CONFIG_NODE
)))
3744 peer_delete(peer
->doppelganger
);
3746 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3747 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3749 } else if (type
== peer_change_reset_out
) {
3750 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3751 bgp_announce_route(peer
, afi
, safi
);
3755 struct peer_flag_action
{
3759 /* This flag can be set for peer-group member. */
3760 uint8_t not_for_member
;
3762 /* Action when the flag is changed. */
3763 enum peer_change_type type
;
3766 static const struct peer_flag_action peer_flag_action_list
[] = {
3767 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3768 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3769 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3770 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3771 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3772 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3773 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3774 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3775 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3776 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3777 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3778 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3779 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3780 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3781 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3782 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3783 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3786 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3787 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3788 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3789 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3790 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3791 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3792 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3793 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3794 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3795 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3796 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3797 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3798 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3799 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3800 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3801 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3802 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3803 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3804 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3805 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3806 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3807 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3808 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3809 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3810 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3811 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3814 /* Proper action set. */
3815 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3816 int size
, struct peer_flag_action
*action
,
3823 const struct peer_flag_action
*match
= NULL
;
3825 /* Check peer's frag action. */
3826 for (i
= 0; i
< size
; i
++) {
3827 match
= &action_list
[i
];
3829 if (match
->flag
== 0)
3832 if (match
->flag
& flag
) {
3835 if (match
->type
== peer_change_reset_in
)
3837 if (match
->type
== peer_change_reset_out
)
3839 if (match
->type
== peer_change_reset
) {
3843 if (match
->not_for_member
)
3844 action
->not_for_member
= 1;
3848 /* Set peer clear type. */
3849 if (reset_in
&& reset_out
)
3850 action
->type
= peer_change_reset
;
3852 action
->type
= peer_change_reset_in
;
3854 action
->type
= peer_change_reset_out
;
3856 action
->type
= peer_change_none
;
3861 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3863 if (flag
== PEER_FLAG_SHUTDOWN
) {
3864 if (CHECK_FLAG(peer
->flags
, flag
)) {
3865 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3866 peer_nsf_stop(peer
);
3868 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3869 if (peer
->t_pmax_restart
) {
3870 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3871 if (bgp_debug_neighbor_events(peer
))
3873 "%s Maximum-prefix restart timer canceled",
3877 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3878 peer_nsf_stop(peer
);
3880 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3881 char *msg
= peer
->tx_shutdown_message
;
3884 if (!msg
&& peer_group_active(peer
))
3885 msg
= peer
->group
->conf
3886 ->tx_shutdown_message
;
3887 msglen
= msg
? strlen(msg
) : 0;
3892 uint8_t msgbuf
[129];
3895 memcpy(msgbuf
+ 1, msg
, msglen
);
3897 bgp_notify_send_with_data(
3898 peer
, BGP_NOTIFY_CEASE
,
3899 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3900 msgbuf
, msglen
+ 1);
3903 peer
, BGP_NOTIFY_CEASE
,
3904 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3906 bgp_session_reset(peer
);
3908 peer
->v_start
= BGP_INIT_START_TIMER
;
3909 BGP_EVENT_ADD(peer
, BGP_Stop
);
3911 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3912 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3913 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3914 else if (flag
== PEER_FLAG_PASSIVE
)
3915 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3916 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3917 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3919 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3920 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3922 bgp_session_reset(peer
);
3925 /* Change specified peer flag. */
3926 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3930 bool invert
, member_invert
;
3931 struct peer
*member
;
3932 struct listnode
*node
, *nnode
;
3933 struct peer_flag_action action
;
3935 memset(&action
, 0, sizeof(struct peer_flag_action
));
3936 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3938 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3939 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3942 /* Abort if no flag action exists. */
3944 return BGP_ERR_INVALID_FLAG
;
3946 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3947 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3948 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3949 return BGP_ERR_PEER_FLAG_CONFLICT
;
3951 /* Handle flag updates where desired state matches current state. */
3952 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3953 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3954 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3958 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3959 COND_FLAG(peer
->flags_override
, flag
, invert
);
3964 /* Inherit from peer-group or set/unset flags accordingly. */
3965 if (peer_group_active(peer
) && set
== invert
)
3966 peer_flag_inherit(peer
, flag
);
3968 COND_FLAG(peer
->flags
, flag
, set
);
3970 /* Check if handling a regular peer. */
3971 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3972 /* Update flag override state accordingly. */
3973 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3975 /* Execute flag action on peer. */
3976 if (action
.type
== peer_change_reset
)
3977 peer_flag_modify_action(peer
, flag
);
3979 /* Skip peer-group mechanics for regular peers. */
3983 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
3984 bgp_nht_register_enhe_capability_interfaces(peer
);
3987 * Update peer-group members, unless they are explicitely overriding
3988 * peer-group configuration.
3990 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3991 /* Skip peers with overridden configuration. */
3992 if (CHECK_FLAG(member
->flags_override
, flag
))
3995 /* Check if only member without group is inverted. */
3997 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3999 /* Skip peers with equivalent configuration. */
4000 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4003 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4006 /* Update flag on peer-group member. */
4007 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4009 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4010 bgp_nht_register_enhe_capability_interfaces(member
);
4012 /* Execute flag action on peer-group member. */
4013 if (action
.type
== peer_change_reset
)
4014 peer_flag_modify_action(member
, flag
);
4020 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4022 return peer_flag_modify(peer
, flag
, 1);
4025 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4027 return peer_flag_modify(peer
, flag
, 0);
4030 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4031 uint32_t flag
, bool set
)
4035 bool invert
, member_invert
;
4036 struct peer
*member
;
4037 struct listnode
*node
, *nnode
;
4038 struct peer_flag_action action
;
4040 memset(&action
, 0, sizeof(struct peer_flag_action
));
4041 size
= sizeof peer_af_flag_action_list
4042 / sizeof(struct peer_flag_action
);
4044 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4045 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4048 /* Abort if flag action exists. */
4050 return BGP_ERR_INVALID_FLAG
;
4052 /* Special check for reflector client. */
4053 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4054 && peer_sort(peer
) != BGP_PEER_IBGP
)
4055 return BGP_ERR_NOT_INTERNAL_PEER
;
4057 /* Special check for remove-private-AS. */
4058 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4059 && peer_sort(peer
) == BGP_PEER_IBGP
)
4060 return BGP_ERR_REMOVE_PRIVATE_AS
;
4062 /* as-override is not allowed for IBGP peers */
4063 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4064 return BGP_ERR_AS_OVERRIDE
;
4066 /* Handle flag updates where desired state matches current state. */
4067 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4068 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4069 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4074 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4075 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4082 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4083 * if we are setting/unsetting flags which conflict with this flag
4084 * handle accordingly
4086 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4090 * if we are setting NEXTHOP_SELF, we need to unset the
4091 * NEXTHOP_UNCHANGED flag
4093 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4094 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4095 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4096 PEER_FLAG_NEXTHOP_UNCHANGED
);
4100 * if we are unsetting NEXTHOP_SELF, we need to set the
4101 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4103 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4104 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4105 SET_FLAG(peer
->af_flags
[afi
][safi
],
4106 PEER_FLAG_NEXTHOP_UNCHANGED
);
4110 /* Inherit from peer-group or set/unset flags accordingly. */
4111 if (peer_group_active(peer
) && set
== invert
)
4112 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4114 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4116 /* Execute action when peer is established. */
4117 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4118 && peer
->status
== Established
) {
4119 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4120 bgp_clear_adj_in(peer
, afi
, safi
);
4122 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4123 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4124 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4125 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4126 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4127 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4128 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4129 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4131 peer_change_action(peer
, afi
, safi
, action
.type
);
4135 /* Check if handling a regular peer. */
4136 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4137 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4141 * Update peer-group members, unless they are explicitely
4142 * overriding peer-group configuration.
4144 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4146 /* Skip peers with overridden configuration. */
4147 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4151 /* Check if only member without group is inverted. */
4153 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4157 /* Skip peers with equivalent configuration. */
4158 if (set
!= member_invert
4159 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4162 if (set
== member_invert
4163 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4166 /* Update flag on peer-group member. */
4167 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4168 set
!= member_invert
);
4170 /* Execute flag action on peer-group member. */
4171 if (member
->status
== Established
) {
4172 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4173 bgp_clear_adj_in(member
, afi
, safi
);
4175 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4176 member
->last_reset
=
4177 PEER_DOWN_RR_CLIENT_CHANGE
;
4179 == PEER_FLAG_RSERVER_CLIENT
)
4180 member
->last_reset
=
4181 PEER_DOWN_RS_CLIENT_CHANGE
;
4183 == PEER_FLAG_ORF_PREFIX_SM
)
4184 member
->last_reset
=
4185 PEER_DOWN_CAPABILITY_CHANGE
;
4187 == PEER_FLAG_ORF_PREFIX_RM
)
4188 member
->last_reset
=
4189 PEER_DOWN_CAPABILITY_CHANGE
;
4191 peer_change_action(member
, afi
, safi
,
4201 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4203 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4206 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4208 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4212 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4214 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4215 peer
->tx_shutdown_message
=
4216 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4220 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4222 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4227 /* EBGP multihop configuration. */
4228 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4230 struct peer_group
*group
;
4231 struct listnode
*node
, *nnode
;
4234 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4237 /* see comment in peer_ttl_security_hops_set() */
4238 if (ttl
!= MAXTTL
) {
4239 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4240 group
= peer
->group
;
4241 if (group
->conf
->gtsm_hops
!= 0)
4242 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4244 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4246 if (peer1
->sort
== BGP_PEER_IBGP
)
4249 if (peer1
->gtsm_hops
!= 0)
4250 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4253 if (peer
->gtsm_hops
!= 0)
4254 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4260 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4261 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4264 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4266 bgp_session_reset(peer
);
4269 group
= peer
->group
;
4270 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4271 if (peer
->sort
== BGP_PEER_IBGP
)
4274 peer
->ttl
= group
->conf
->ttl
;
4276 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4277 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4278 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4280 bgp_session_reset(peer
);
4286 int peer_ebgp_multihop_unset(struct peer
*peer
)
4288 struct peer_group
*group
;
4289 struct listnode
*node
, *nnode
;
4291 if (peer
->sort
== BGP_PEER_IBGP
)
4294 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4295 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4297 if (peer_group_active(peer
))
4298 peer
->ttl
= peer
->group
->conf
->ttl
;
4302 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4303 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4304 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4305 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4307 bgp_session_reset(peer
);
4309 group
= peer
->group
;
4310 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4311 if (peer
->sort
== BGP_PEER_IBGP
)
4316 if (peer
->fd
>= 0) {
4317 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4319 peer
, BGP_NOTIFY_CEASE
,
4320 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4322 bgp_session_reset(peer
);
4329 /* Neighbor description. */
4330 int peer_description_set(struct peer
*peer
, const char *desc
)
4333 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4335 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4340 int peer_description_unset(struct peer
*peer
)
4343 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4350 /* Neighbor update-source. */
4351 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4353 struct peer
*member
;
4354 struct listnode
*node
, *nnode
;
4356 /* Set flag and configuration on peer. */
4357 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4358 if (peer
->update_if
) {
4359 if (strcmp(peer
->update_if
, ifname
) == 0)
4361 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4363 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4364 sockunion_free(peer
->update_source
);
4365 peer
->update_source
= NULL
;
4367 /* Check if handling a regular peer. */
4368 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4369 /* Send notification or reset peer depending on state. */
4370 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4371 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4372 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4373 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4375 bgp_session_reset(peer
);
4377 /* Skip peer-group mechanics for regular peers. */
4382 * Set flag and configuration on all peer-group members, unless they are
4383 * explicitely overriding peer-group configuration.
4385 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4386 /* Skip peers with overridden configuration. */
4387 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4390 /* Skip peers with the same configuration. */
4391 if (member
->update_if
) {
4392 if (strcmp(member
->update_if
, ifname
) == 0)
4394 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4397 /* Set flag and configuration on peer-group member. */
4398 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4399 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4400 sockunion_free(member
->update_source
);
4401 member
->update_source
= NULL
;
4403 /* Send notification or reset peer depending on state. */
4404 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4405 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4406 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4407 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4409 bgp_session_reset(member
);
4415 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4417 struct peer
*member
;
4418 struct listnode
*node
, *nnode
;
4420 /* Set flag and configuration on peer. */
4421 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4422 if (peer
->update_source
) {
4423 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4425 sockunion_free(peer
->update_source
);
4427 peer
->update_source
= sockunion_dup(su
);
4428 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4430 /* Check if handling a regular peer. */
4431 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4432 /* Send notification or reset peer depending on state. */
4433 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4434 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4435 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4436 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4438 bgp_session_reset(peer
);
4440 /* Skip peer-group mechanics for regular peers. */
4445 * Set flag and configuration on all peer-group members, unless they are
4446 * explicitely overriding peer-group configuration.
4448 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4449 /* Skip peers with overridden configuration. */
4450 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4453 /* Skip peers with the same configuration. */
4454 if (member
->update_source
) {
4455 if (sockunion_cmp(member
->update_source
, su
) == 0)
4457 sockunion_free(member
->update_source
);
4460 /* Set flag and configuration on peer-group member. */
4461 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4462 member
->update_source
= sockunion_dup(su
);
4463 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4465 /* Send notification or reset peer depending on state. */
4466 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4467 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4468 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4469 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4471 bgp_session_reset(member
);
4477 int peer_update_source_unset(struct peer
*peer
)
4479 struct peer
*member
;
4480 struct listnode
*node
, *nnode
;
4482 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4485 /* Inherit configuration from peer-group if peer is member. */
4486 if (peer_group_active(peer
)) {
4487 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4488 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4489 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4490 MTYPE_PEER_UPDATE_SOURCE
);
4492 /* Otherwise remove flag and configuration from peer. */
4493 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4494 sockunion_free(peer
->update_source
);
4495 peer
->update_source
= NULL
;
4496 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4499 /* Check if handling a regular peer. */
4500 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4501 /* Send notification or reset peer depending on state. */
4502 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4503 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4504 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4505 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4507 bgp_session_reset(peer
);
4509 /* Skip peer-group mechanics for regular peers. */
4514 * Set flag and configuration on all peer-group members, unless they are
4515 * explicitely overriding peer-group configuration.
4517 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4518 /* Skip peers with overridden configuration. */
4519 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4522 /* Skip peers with the same configuration. */
4523 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4524 && !member
->update_source
&& !member
->update_if
)
4527 /* Remove flag and configuration on peer-group member. */
4528 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4529 sockunion_free(member
->update_source
);
4530 member
->update_source
= NULL
;
4531 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4533 /* Send notification or reset peer depending on state. */
4534 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4535 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4536 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4537 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4539 bgp_session_reset(member
);
4545 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4546 const char *rmap
, struct route_map
*route_map
)
4548 struct peer
*member
;
4549 struct listnode
*node
, *nnode
;
4551 /* Set flag and configuration on peer. */
4552 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4554 if (!peer
->default_rmap
[afi
][safi
].name
4555 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4556 if (peer
->default_rmap
[afi
][safi
].name
)
4557 XFREE(MTYPE_ROUTE_MAP_NAME
,
4558 peer
->default_rmap
[afi
][safi
].name
);
4560 peer
->default_rmap
[afi
][safi
].name
=
4561 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4562 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4565 if (peer
->default_rmap
[afi
][safi
].name
)
4566 XFREE(MTYPE_ROUTE_MAP_NAME
,
4567 peer
->default_rmap
[afi
][safi
].name
);
4569 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4570 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4573 /* Check if handling a regular peer. */
4574 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4575 /* Update peer route announcements. */
4576 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4577 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4578 bgp_default_originate(peer
, afi
, safi
, 0);
4579 bgp_announce_route(peer
, afi
, safi
);
4582 /* Skip peer-group mechanics for regular peers. */
4587 * Set flag and configuration on all peer-group members, unless they are
4588 * explicitely overriding peer-group configuration.
4590 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4591 /* Skip peers with overridden configuration. */
4592 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4593 PEER_FLAG_DEFAULT_ORIGINATE
))
4596 /* Set flag and configuration on peer-group member. */
4597 SET_FLAG(member
->af_flags
[afi
][safi
],
4598 PEER_FLAG_DEFAULT_ORIGINATE
);
4600 if (member
->default_rmap
[afi
][safi
].name
)
4601 XFREE(MTYPE_ROUTE_MAP_NAME
,
4602 member
->default_rmap
[afi
][safi
].name
);
4604 member
->default_rmap
[afi
][safi
].name
=
4605 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4606 member
->default_rmap
[afi
][safi
].map
= route_map
;
4609 /* Update peer route announcements. */
4610 if (member
->status
== Established
4611 && member
->afc_nego
[afi
][safi
]) {
4612 update_group_adjust_peer(
4613 peer_af_find(member
, afi
, safi
));
4614 bgp_default_originate(member
, afi
, safi
, 0);
4615 bgp_announce_route(member
, afi
, safi
);
4622 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4624 struct peer
*member
;
4625 struct listnode
*node
, *nnode
;
4627 /* Inherit configuration from peer-group if peer is member. */
4628 if (peer_group_active(peer
)) {
4629 peer_af_flag_inherit(peer
, afi
, safi
,
4630 PEER_FLAG_DEFAULT_ORIGINATE
);
4631 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4632 default_rmap
[afi
][safi
].name
,
4633 MTYPE_ROUTE_MAP_NAME
);
4634 PEER_ATTR_INHERIT(peer
, peer
->group
,
4635 default_rmap
[afi
][safi
].map
);
4637 /* Otherwise remove flag and configuration from peer. */
4638 peer_af_flag_unset(peer
, afi
, safi
,
4639 PEER_FLAG_DEFAULT_ORIGINATE
);
4640 if (peer
->default_rmap
[afi
][safi
].name
)
4641 XFREE(MTYPE_ROUTE_MAP_NAME
,
4642 peer
->default_rmap
[afi
][safi
].name
);
4643 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4644 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4647 /* Check if handling a regular peer. */
4648 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4649 /* Update peer route announcements. */
4650 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4651 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4652 bgp_default_originate(peer
, afi
, safi
, 1);
4653 bgp_announce_route(peer
, afi
, safi
);
4656 /* Skip peer-group mechanics for regular peers. */
4661 * Remove flag and configuration from all peer-group members, unless
4662 * they are explicitely overriding peer-group configuration.
4664 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4665 /* Skip peers with overridden configuration. */
4666 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4667 PEER_FLAG_DEFAULT_ORIGINATE
))
4670 /* Remove flag and configuration on peer-group member. */
4671 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4672 PEER_FLAG_DEFAULT_ORIGINATE
);
4673 if (peer
->default_rmap
[afi
][safi
].name
)
4674 XFREE(MTYPE_ROUTE_MAP_NAME
,
4675 peer
->default_rmap
[afi
][safi
].name
);
4676 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4677 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4679 /* Update peer route announcements. */
4680 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4681 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4682 bgp_default_originate(peer
, afi
, safi
, 1);
4683 bgp_announce_route(peer
, afi
, safi
);
4690 int peer_port_set(struct peer
*peer
, uint16_t port
)
4696 int peer_port_unset(struct peer
*peer
)
4698 peer
->port
= BGP_PORT_DEFAULT
;
4703 * Helper function that is called after the name of the policy
4704 * being used by a peer has changed (AF specific). Automatically
4705 * initiates inbound or outbound processing as needed.
4707 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4711 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4712 if (peer
->status
== Established
)
4713 bgp_announce_route(peer
, afi
, safi
);
4715 if (peer
->status
!= Established
)
4718 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4719 PEER_FLAG_SOFT_RECONFIG
))
4720 bgp_soft_reconfig_in(peer
, afi
, safi
);
4721 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4722 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4723 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4728 /* neighbor weight. */
4729 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4731 struct peer
*member
;
4732 struct listnode
*node
, *nnode
;
4734 /* Set flag and configuration on peer. */
4735 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4736 if (peer
->weight
[afi
][safi
] != weight
) {
4737 peer
->weight
[afi
][safi
] = weight
;
4738 peer_on_policy_change(peer
, afi
, safi
, 0);
4741 /* Skip peer-group mechanics for regular peers. */
4742 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4746 * Set flag and configuration on all peer-group members, unless they are
4747 * explicitely overriding peer-group configuration.
4749 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4750 /* Skip peers with overridden configuration. */
4751 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4755 /* Set flag and configuration on peer-group member. */
4756 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4757 if (member
->weight
[afi
][safi
] != weight
) {
4758 member
->weight
[afi
][safi
] = weight
;
4759 peer_on_policy_change(member
, afi
, safi
, 0);
4766 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4768 struct peer
*member
;
4769 struct listnode
*node
, *nnode
;
4771 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4774 /* Inherit configuration from peer-group if peer is member. */
4775 if (peer_group_active(peer
)) {
4776 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4777 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4779 peer_on_policy_change(peer
, afi
, safi
, 0);
4783 /* Remove flag and configuration from peer. */
4784 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4785 peer
->weight
[afi
][safi
] = 0;
4786 peer_on_policy_change(peer
, afi
, safi
, 0);
4788 /* Skip peer-group mechanics for regular peers. */
4789 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4793 * Remove flag and configuration from all peer-group members, unless
4794 * they are explicitely overriding peer-group configuration.
4796 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4797 /* Skip peers with overridden configuration. */
4798 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4802 /* Skip peers where flag is already disabled. */
4803 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4806 /* Remove flag and configuration on peer-group member. */
4807 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4808 member
->weight
[afi
][safi
] = 0;
4809 peer_on_policy_change(member
, afi
, safi
, 0);
4815 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4817 struct peer
*member
;
4818 struct listnode
*node
, *nnode
;
4820 if (keepalive
> 65535)
4821 return BGP_ERR_INVALID_VALUE
;
4823 if (holdtime
> 65535)
4824 return BGP_ERR_INVALID_VALUE
;
4826 if (holdtime
< 3 && holdtime
!= 0)
4827 return BGP_ERR_INVALID_VALUE
;
4829 /* Set flag and configuration on peer. */
4830 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4831 peer
->holdtime
= holdtime
;
4832 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4834 /* Skip peer-group mechanics for regular peers. */
4835 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4839 * Set flag and configuration on all peer-group members, unless they are
4840 * explicitely overriding peer-group configuration.
4842 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4843 /* Skip peers with overridden configuration. */
4844 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4847 /* Set flag and configuration on peer-group member. */
4848 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4849 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4850 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4856 int peer_timers_unset(struct peer
*peer
)
4858 struct peer
*member
;
4859 struct listnode
*node
, *nnode
;
4861 /* Inherit configuration from peer-group if peer is member. */
4862 if (peer_group_active(peer
)) {
4863 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4864 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4865 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4867 /* Otherwise remove flag and configuration from peer. */
4868 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4870 peer
->keepalive
= 0;
4873 /* Skip peer-group mechanics for regular peers. */
4874 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4878 * Remove flag and configuration from all peer-group members, unless
4879 * they are explicitely overriding peer-group configuration.
4881 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4882 /* Skip peers with overridden configuration. */
4883 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4886 /* Remove flag and configuration on peer-group member. */
4887 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4888 member
->holdtime
= 0;
4889 member
->keepalive
= 0;
4895 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4897 struct peer
*member
;
4898 struct listnode
*node
, *nnode
;
4900 if (connect
> 65535)
4901 return BGP_ERR_INVALID_VALUE
;
4903 /* Set flag and configuration on peer. */
4904 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4905 peer
->connect
= connect
;
4906 peer
->v_connect
= connect
;
4908 /* Skip peer-group mechanics for regular peers. */
4909 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4913 * Set flag and configuration on all peer-group members, unless they are
4914 * explicitely overriding peer-group configuration.
4916 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4917 /* Skip peers with overridden configuration. */
4918 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4921 /* Set flag and configuration on peer-group member. */
4922 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4923 member
->connect
= connect
;
4924 member
->v_connect
= connect
;
4930 int peer_timers_connect_unset(struct peer
*peer
)
4932 struct peer
*member
;
4933 struct listnode
*node
, *nnode
;
4935 /* Inherit configuration from peer-group if peer is member. */
4936 if (peer_group_active(peer
)) {
4937 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4938 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4940 /* Otherwise remove flag and configuration from peer. */
4941 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4945 /* Set timer with fallback to default value. */
4947 peer
->v_connect
= peer
->connect
;
4949 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4951 /* Skip peer-group mechanics for regular peers. */
4952 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4956 * Remove flag and configuration from all peer-group members, unless
4957 * they are explicitely overriding peer-group configuration.
4959 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4960 /* Skip peers with overridden configuration. */
4961 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4964 /* Remove flag and configuration on peer-group member. */
4965 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4966 member
->connect
= 0;
4967 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4973 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4975 struct peer
*member
;
4976 struct listnode
*node
, *nnode
;
4979 return BGP_ERR_INVALID_VALUE
;
4981 /* Set flag and configuration on peer. */
4982 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4983 peer
->routeadv
= routeadv
;
4984 peer
->v_routeadv
= routeadv
;
4986 /* Check if handling a regular peer. */
4987 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4988 /* Update peer route announcements. */
4989 update_group_adjust_peer_afs(peer
);
4990 if (peer
->status
== Established
)
4991 bgp_announce_route_all(peer
);
4993 /* Skip peer-group mechanics for regular peers. */
4998 * Set flag and configuration on all peer-group members, unless they are
4999 * explicitely overriding peer-group configuration.
5001 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5002 /* Skip peers with overridden configuration. */
5003 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5006 /* Set flag and configuration on peer-group member. */
5007 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5008 member
->routeadv
= routeadv
;
5009 member
->v_routeadv
= routeadv
;
5011 /* Update peer route announcements. */
5012 update_group_adjust_peer_afs(member
);
5013 if (member
->status
== Established
)
5014 bgp_announce_route_all(member
);
5020 int peer_advertise_interval_unset(struct peer
*peer
)
5022 struct peer
*member
;
5023 struct listnode
*node
, *nnode
;
5025 /* Inherit configuration from peer-group if peer is member. */
5026 if (peer_group_active(peer
)) {
5027 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5028 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5030 /* Otherwise remove flag and configuration from peer. */
5031 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5035 /* Set timer with fallback to default value. */
5037 peer
->v_routeadv
= peer
->routeadv
;
5039 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5040 ? BGP_DEFAULT_IBGP_ROUTEADV
5041 : BGP_DEFAULT_EBGP_ROUTEADV
;
5043 /* Check if handling a regular peer. */
5044 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5045 /* Update peer route announcements. */
5046 update_group_adjust_peer_afs(peer
);
5047 if (peer
->status
== Established
)
5048 bgp_announce_route_all(peer
);
5050 /* Skip peer-group mechanics for regular peers. */
5055 * Remove flag and configuration from all peer-group members, unless
5056 * they are explicitely overriding peer-group configuration.
5058 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5059 /* Skip peers with overridden configuration. */
5060 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5063 /* Remove flag and configuration on peer-group member. */
5064 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5065 member
->routeadv
= 0;
5066 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5067 ? BGP_DEFAULT_IBGP_ROUTEADV
5068 : BGP_DEFAULT_EBGP_ROUTEADV
;
5070 /* Update peer route announcements. */
5071 update_group_adjust_peer_afs(member
);
5072 if (member
->status
== Established
)
5073 bgp_announce_route_all(member
);
5079 /* neighbor interface */
5080 void peer_interface_set(struct peer
*peer
, const char *str
)
5083 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5084 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5087 void peer_interface_unset(struct peer
*peer
)
5090 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5091 peer
->ifname
= NULL
;
5095 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5096 int allow_num
, int origin
)
5098 struct peer
*member
;
5099 struct listnode
*node
, *nnode
;
5101 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5102 return BGP_ERR_INVALID_VALUE
;
5104 /* Set flag and configuration on peer. */
5105 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5107 if (peer
->allowas_in
[afi
][safi
] != 0
5108 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5109 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5110 peer_af_flag_set(peer
, afi
, safi
,
5111 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5112 peer
->allowas_in
[afi
][safi
] = 0;
5113 peer_on_policy_change(peer
, afi
, safi
, 0);
5116 if (peer
->allowas_in
[afi
][safi
] != allow_num
5117 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5118 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5120 peer_af_flag_unset(peer
, afi
, safi
,
5121 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5122 peer
->allowas_in
[afi
][safi
] = allow_num
;
5123 peer_on_policy_change(peer
, afi
, safi
, 0);
5127 /* Skip peer-group mechanics for regular peers. */
5128 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5132 * Set flag and configuration on all peer-group members, unless
5133 * they are explicitely overriding peer-group configuration.
5135 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5136 /* Skip peers with overridden configuration. */
5137 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5138 PEER_FLAG_ALLOWAS_IN
))
5141 /* Set flag and configuration on peer-group member. */
5142 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5144 if (member
->allowas_in
[afi
][safi
] != 0
5145 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5146 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5147 SET_FLAG(member
->af_flags
[afi
][safi
],
5148 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5149 member
->allowas_in
[afi
][safi
] = 0;
5150 peer_on_policy_change(peer
, afi
, safi
, 0);
5153 if (member
->allowas_in
[afi
][safi
] != allow_num
5154 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5155 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5156 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5157 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5158 member
->allowas_in
[afi
][safi
] = allow_num
;
5159 peer_on_policy_change(peer
, afi
, safi
, 0);
5167 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5169 struct peer
*member
;
5170 struct listnode
*node
, *nnode
;
5172 /* Skip peer if flag is already disabled. */
5173 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5176 /* Inherit configuration from peer-group if peer is member. */
5177 if (peer_group_active(peer
)) {
5178 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5179 peer_af_flag_inherit(peer
, afi
, safi
,
5180 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5181 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5182 peer_on_policy_change(peer
, afi
, safi
, 0);
5187 /* Remove flag and configuration from peer. */
5188 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5189 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5190 peer
->allowas_in
[afi
][safi
] = 0;
5191 peer_on_policy_change(peer
, afi
, safi
, 0);
5193 /* Skip peer-group mechanics if handling a regular peer. */
5194 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5198 * Remove flags and configuration from all peer-group members, unless
5199 * they are explicitely overriding peer-group configuration.
5201 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5202 /* Skip peers with overridden configuration. */
5203 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5204 PEER_FLAG_ALLOWAS_IN
))
5207 /* Skip peers where flag is already disabled. */
5208 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5209 PEER_FLAG_ALLOWAS_IN
))
5212 /* Remove flags and configuration on peer-group member. */
5213 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5214 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5215 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5216 member
->allowas_in
[afi
][safi
] = 0;
5217 peer_on_policy_change(member
, afi
, safi
, 0);
5223 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5226 bool old_no_prepend
, old_replace_as
;
5227 struct bgp
*bgp
= peer
->bgp
;
5228 struct peer
*member
;
5229 struct listnode
*node
, *nnode
;
5231 if (peer_sort(peer
) != BGP_PEER_EBGP
5232 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5233 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5236 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5239 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5241 /* Save previous flag states. */
5243 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5245 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5247 /* Set flag and configuration on peer. */
5248 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5249 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5250 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5252 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5253 && old_replace_as
== replace_as
)
5255 peer
->change_local_as
= as
;
5257 /* Check if handling a regular peer. */
5258 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5259 /* Send notification or reset peer depending on state. */
5260 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5261 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5262 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5263 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5265 bgp_session_reset(peer
);
5267 /* Skip peer-group mechanics for regular peers. */
5272 * Set flag and configuration on all peer-group members, unless they are
5273 * explicitely overriding peer-group configuration.
5275 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5276 /* Skip peers with overridden configuration. */
5277 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5280 /* Skip peers with the same configuration. */
5281 old_no_prepend
= CHECK_FLAG(member
->flags
,
5282 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5283 old_replace_as
= CHECK_FLAG(member
->flags
,
5284 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5285 if (member
->change_local_as
== as
5286 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5287 && old_no_prepend
== no_prepend
5288 && old_replace_as
== replace_as
)
5291 /* Set flag and configuration on peer-group member. */
5292 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5293 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5295 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5297 member
->change_local_as
= as
;
5299 /* Send notification or stop peer depending on state. */
5300 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5301 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5302 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5303 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5305 BGP_EVENT_ADD(member
, BGP_Stop
);
5311 int peer_local_as_unset(struct peer
*peer
)
5313 struct peer
*member
;
5314 struct listnode
*node
, *nnode
;
5316 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5319 /* Inherit configuration from peer-group if peer is member. */
5320 if (peer_group_active(peer
)) {
5321 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5322 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5323 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5324 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5326 /* Otherwise remove flag and configuration from peer. */
5327 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5328 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5329 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5330 peer
->change_local_as
= 0;
5333 /* Check if handling a regular peer. */
5334 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5335 /* Send notification or stop peer depending on state. */
5336 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5337 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5338 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5339 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5341 BGP_EVENT_ADD(peer
, BGP_Stop
);
5343 /* Skip peer-group mechanics for regular peers. */
5348 * Remove flag and configuration from all peer-group members, unless
5349 * they are explicitely overriding peer-group configuration.
5351 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5352 /* Skip peers with overridden configuration. */
5353 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5356 /* Remove flag and configuration on peer-group member. */
5357 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5358 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5359 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5360 member
->change_local_as
= 0;
5362 /* Send notification or stop peer depending on state. */
5363 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5364 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5365 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5366 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5368 bgp_session_reset(member
);
5374 /* Set password for authenticating with the peer. */
5375 int peer_password_set(struct peer
*peer
, const char *password
)
5377 struct peer
*member
;
5378 struct listnode
*node
, *nnode
;
5379 int len
= password
? strlen(password
) : 0;
5380 int ret
= BGP_SUCCESS
;
5382 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5383 return BGP_ERR_INVALID_VALUE
;
5385 /* Set flag and configuration on peer. */
5386 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5387 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5389 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5390 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5392 /* Check if handling a regular peer. */
5393 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5394 /* Send notification or reset peer depending on state. */
5395 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5396 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5397 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5399 bgp_session_reset(peer
);
5402 * Attempt to install password on socket and skip peer-group
5405 if (BGP_PEER_SU_UNSPEC(peer
))
5407 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5408 : BGP_ERR_TCPSIG_FAILED
;
5412 * Set flag and configuration on all peer-group members, unless they are
5413 * explicitely overriding peer-group configuration.
5415 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5416 /* Skip peers with overridden configuration. */
5417 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5420 /* Skip peers with the same password. */
5421 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5424 /* Set flag and configuration on peer-group member. */
5425 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5426 if (member
->password
)
5427 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5428 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5430 /* Send notification or reset peer depending on state. */
5431 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5432 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5433 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5435 bgp_session_reset(member
);
5437 /* Attempt to install password on socket. */
5438 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5439 ret
= BGP_ERR_TCPSIG_FAILED
;
5445 int peer_password_unset(struct peer
*peer
)
5447 struct peer
*member
;
5448 struct listnode
*node
, *nnode
;
5450 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5453 /* Inherit configuration from peer-group if peer is member. */
5454 if (peer_group_active(peer
)) {
5455 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5456 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5457 MTYPE_PEER_PASSWORD
);
5459 /* Otherwise remove flag and configuration from peer. */
5460 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5461 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5464 /* Check if handling a regular peer. */
5465 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5466 /* Send notification or reset peer depending on state. */
5467 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5468 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5469 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5471 bgp_session_reset(peer
);
5473 /* Attempt to uninstall password on socket. */
5474 if (!BGP_PEER_SU_UNSPEC(peer
))
5475 bgp_md5_unset(peer
);
5477 /* Skip peer-group mechanics for regular peers. */
5482 * Remove flag and configuration from all peer-group members, unless
5483 * they are explicitely overriding peer-group configuration.
5485 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5486 /* Skip peers with overridden configuration. */
5487 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5490 /* Remove flag and configuration on peer-group member. */
5491 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5492 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5494 /* Send notification or reset peer depending on state. */
5495 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5496 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5497 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5499 bgp_session_reset(member
);
5501 /* Attempt to uninstall password on socket. */
5502 if (!BGP_PEER_SU_UNSPEC(member
))
5503 bgp_md5_unset(member
);
5510 /* Set distribute list to the peer. */
5511 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5514 struct peer
*member
;
5515 struct bgp_filter
*filter
;
5516 struct listnode
*node
, *nnode
;
5518 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5519 return BGP_ERR_INVALID_VALUE
;
5521 /* Set configuration on peer. */
5522 filter
= &peer
->filter
[afi
][safi
];
5523 if (filter
->plist
[direct
].name
)
5524 return BGP_ERR_PEER_FILTER_CONFLICT
;
5525 if (filter
->dlist
[direct
].name
)
5526 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5527 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5528 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5530 /* Check if handling a regular peer. */
5531 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5532 /* Set override-flag and process peer route updates. */
5533 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5534 PEER_FT_DISTRIBUTE_LIST
);
5535 peer_on_policy_change(peer
, afi
, safi
,
5536 (direct
== FILTER_OUT
) ? 1 : 0);
5538 /* Skip peer-group mechanics for regular peers. */
5543 * Set configuration on all peer-group members, un less they are
5544 * explicitely overriding peer-group configuration.
5546 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5547 /* Skip peers with overridden configuration. */
5548 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5549 PEER_FT_DISTRIBUTE_LIST
))
5552 /* Set configuration on peer-group member. */
5553 filter
= &member
->filter
[afi
][safi
];
5554 if (filter
->dlist
[direct
].name
)
5555 XFREE(MTYPE_BGP_FILTER_NAME
,
5556 filter
->dlist
[direct
].name
);
5557 filter
->dlist
[direct
].name
=
5558 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5559 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5561 /* Process peer route updates. */
5562 peer_on_policy_change(member
, afi
, safi
,
5563 (direct
== FILTER_OUT
) ? 1 : 0);
5569 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5571 struct peer
*member
;
5572 struct bgp_filter
*filter
;
5573 struct listnode
*node
, *nnode
;
5575 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5576 return BGP_ERR_INVALID_VALUE
;
5578 /* Unset override-flag unconditionally. */
5579 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5580 PEER_FT_DISTRIBUTE_LIST
);
5582 /* Inherit configuration from peer-group if peer is member. */
5583 if (peer_group_active(peer
)) {
5584 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5585 filter
[afi
][safi
].dlist
[direct
].name
,
5586 MTYPE_BGP_FILTER_NAME
);
5587 PEER_ATTR_INHERIT(peer
, peer
->group
,
5588 filter
[afi
][safi
].dlist
[direct
].alist
);
5590 /* Otherwise remove configuration from peer. */
5591 filter
= &peer
->filter
[afi
][safi
];
5592 if (filter
->dlist
[direct
].name
)
5593 XFREE(MTYPE_BGP_FILTER_NAME
,
5594 filter
->dlist
[direct
].name
);
5595 filter
->dlist
[direct
].name
= NULL
;
5596 filter
->dlist
[direct
].alist
= NULL
;
5599 /* Check if handling a regular peer. */
5600 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5601 /* Process peer route updates. */
5602 peer_on_policy_change(peer
, afi
, safi
,
5603 (direct
== FILTER_OUT
) ? 1 : 0);
5605 /* Skip peer-group mechanics for regular peers. */
5610 * Remove configuration on all peer-group members, unless they are
5611 * explicitely overriding peer-group configuration.
5613 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5614 /* Skip peers with overridden configuration. */
5615 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5616 PEER_FT_DISTRIBUTE_LIST
))
5619 /* Remove configuration on peer-group member. */
5620 filter
= &member
->filter
[afi
][safi
];
5621 if (filter
->dlist
[direct
].name
)
5622 XFREE(MTYPE_BGP_FILTER_NAME
,
5623 filter
->dlist
[direct
].name
);
5624 filter
->dlist
[direct
].name
= NULL
;
5625 filter
->dlist
[direct
].alist
= NULL
;
5627 /* Process peer route updates. */
5628 peer_on_policy_change(member
, afi
, safi
,
5629 (direct
== FILTER_OUT
) ? 1 : 0);
5635 /* Update distribute list. */
5636 static void peer_distribute_update(struct access_list
*access
)
5641 struct listnode
*mnode
, *mnnode
;
5642 struct listnode
*node
, *nnode
;
5645 struct peer_group
*group
;
5646 struct bgp_filter
*filter
;
5648 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5650 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5651 access
->name
, 0, 0);
5652 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5653 FOREACH_AFI_SAFI (afi
, safi
) {
5654 filter
= &peer
->filter
[afi
][safi
];
5656 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5658 if (filter
->dlist
[direct
].name
)
5659 filter
->dlist
[direct
]
5660 .alist
= access_list_lookup(
5662 filter
->dlist
[direct
]
5665 filter
->dlist
[direct
].alist
=
5670 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5671 FOREACH_AFI_SAFI (afi
, safi
) {
5672 filter
= &group
->conf
->filter
[afi
][safi
];
5674 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5676 if (filter
->dlist
[direct
].name
)
5677 filter
->dlist
[direct
]
5678 .alist
= access_list_lookup(
5680 filter
->dlist
[direct
]
5683 filter
->dlist
[direct
].alist
=
5689 vnc_prefix_list_update(bgp
);
5694 /* Set prefix list to the peer. */
5695 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5698 struct peer
*member
;
5699 struct bgp_filter
*filter
;
5700 struct listnode
*node
, *nnode
;
5702 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5703 return BGP_ERR_INVALID_VALUE
;
5705 /* Set configuration on peer. */
5706 filter
= &peer
->filter
[afi
][safi
];
5707 if (filter
->dlist
[direct
].name
)
5708 return BGP_ERR_PEER_FILTER_CONFLICT
;
5709 if (filter
->plist
[direct
].name
)
5710 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5711 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5712 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5714 /* Check if handling a regular peer. */
5715 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5716 /* Set override-flag and process peer route updates. */
5717 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5718 PEER_FT_PREFIX_LIST
);
5719 peer_on_policy_change(peer
, afi
, safi
,
5720 (direct
== FILTER_OUT
) ? 1 : 0);
5722 /* Skip peer-group mechanics for regular peers. */
5727 * Set configuration on all peer-group members, unless they are
5728 * explicitely overriding peer-group configuration.
5730 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5731 /* Skip peers with overridden configuration. */
5732 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5733 PEER_FT_PREFIX_LIST
))
5736 /* Set configuration on peer-group member. */
5737 filter
= &member
->filter
[afi
][safi
];
5738 if (filter
->plist
[direct
].name
)
5739 XFREE(MTYPE_BGP_FILTER_NAME
,
5740 filter
->plist
[direct
].name
);
5741 filter
->plist
[direct
].name
=
5742 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5743 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5745 /* Process peer route updates. */
5746 peer_on_policy_change(member
, afi
, safi
,
5747 (direct
== FILTER_OUT
) ? 1 : 0);
5753 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5756 struct peer
*member
;
5757 struct bgp_filter
*filter
;
5758 struct listnode
*node
, *nnode
;
5760 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5761 return BGP_ERR_INVALID_VALUE
;
5763 /* Unset override-flag unconditionally. */
5764 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5765 PEER_FT_PREFIX_LIST
);
5767 /* Inherit configuration from peer-group if peer is member. */
5768 if (peer_group_active(peer
)) {
5769 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5770 filter
[afi
][safi
].plist
[direct
].name
,
5771 MTYPE_BGP_FILTER_NAME
);
5772 PEER_ATTR_INHERIT(peer
, peer
->group
,
5773 filter
[afi
][safi
].plist
[direct
].plist
);
5775 /* Otherwise remove configuration from peer. */
5776 filter
= &peer
->filter
[afi
][safi
];
5777 if (filter
->plist
[direct
].name
)
5778 XFREE(MTYPE_BGP_FILTER_NAME
,
5779 filter
->plist
[direct
].name
);
5780 filter
->plist
[direct
].name
= NULL
;
5781 filter
->plist
[direct
].plist
= NULL
;
5784 /* Check if handling a regular peer. */
5785 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5786 /* Process peer route updates. */
5787 peer_on_policy_change(peer
, afi
, safi
,
5788 (direct
== FILTER_OUT
) ? 1 : 0);
5790 /* Skip peer-group mechanics for regular peers. */
5795 * Remove configuration on all peer-group members, unless they are
5796 * explicitely overriding peer-group configuration.
5798 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5799 /* Skip peers with overridden configuration. */
5800 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5801 PEER_FT_PREFIX_LIST
))
5804 /* Remove configuration on peer-group member. */
5805 filter
= &member
->filter
[afi
][safi
];
5806 if (filter
->plist
[direct
].name
)
5807 XFREE(MTYPE_BGP_FILTER_NAME
,
5808 filter
->plist
[direct
].name
);
5809 filter
->plist
[direct
].name
= NULL
;
5810 filter
->plist
[direct
].plist
= NULL
;
5812 /* Process peer route updates. */
5813 peer_on_policy_change(member
, afi
, safi
,
5814 (direct
== FILTER_OUT
) ? 1 : 0);
5820 /* Update prefix-list list. */
5821 static void peer_prefix_list_update(struct prefix_list
*plist
)
5823 struct listnode
*mnode
, *mnnode
;
5824 struct listnode
*node
, *nnode
;
5827 struct peer_group
*group
;
5828 struct bgp_filter
*filter
;
5833 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5836 * Update the prefix-list on update groups.
5838 update_group_policy_update(
5839 bgp
, BGP_POLICY_PREFIX_LIST
,
5840 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5842 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5843 FOREACH_AFI_SAFI (afi
, safi
) {
5844 filter
= &peer
->filter
[afi
][safi
];
5846 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5848 if (filter
->plist
[direct
].name
)
5849 filter
->plist
[direct
]
5850 .plist
= prefix_list_lookup(
5852 filter
->plist
[direct
]
5855 filter
->plist
[direct
].plist
=
5860 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5861 FOREACH_AFI_SAFI (afi
, safi
) {
5862 filter
= &group
->conf
->filter
[afi
][safi
];
5864 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5866 if (filter
->plist
[direct
].name
)
5867 filter
->plist
[direct
]
5868 .plist
= prefix_list_lookup(
5870 filter
->plist
[direct
]
5873 filter
->plist
[direct
].plist
=
5881 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5884 struct peer
*member
;
5885 struct bgp_filter
*filter
;
5886 struct listnode
*node
, *nnode
;
5888 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5889 return BGP_ERR_INVALID_VALUE
;
5891 /* Set configuration on peer. */
5892 filter
= &peer
->filter
[afi
][safi
];
5893 if (filter
->aslist
[direct
].name
)
5894 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5895 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5896 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5898 /* Check if handling a regular peer. */
5899 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5900 /* Set override-flag and process peer route updates. */
5901 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5902 PEER_FT_FILTER_LIST
);
5903 peer_on_policy_change(peer
, afi
, safi
,
5904 (direct
== FILTER_OUT
) ? 1 : 0);
5906 /* Skip peer-group mechanics for regular peers. */
5911 * Set configuration on all peer-group members, unless they are
5912 * explicitely overriding peer-group configuration.
5914 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5915 /* Skip peers with overridden configuration. */
5916 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5917 PEER_FT_FILTER_LIST
))
5920 /* Set configuration on peer-group member. */
5921 filter
= &member
->filter
[afi
][safi
];
5922 if (filter
->aslist
[direct
].name
)
5923 XFREE(MTYPE_BGP_FILTER_NAME
,
5924 filter
->aslist
[direct
].name
);
5925 filter
->aslist
[direct
].name
=
5926 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5927 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5929 /* Process peer route updates. */
5930 peer_on_policy_change(member
, afi
, safi
,
5931 (direct
== FILTER_OUT
) ? 1 : 0);
5937 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5939 struct peer
*member
;
5940 struct bgp_filter
*filter
;
5941 struct listnode
*node
, *nnode
;
5943 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5944 return BGP_ERR_INVALID_VALUE
;
5946 /* Unset override-flag unconditionally. */
5947 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5948 PEER_FT_FILTER_LIST
);
5950 /* Inherit configuration from peer-group if peer is member. */
5951 if (peer_group_active(peer
)) {
5952 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5953 filter
[afi
][safi
].aslist
[direct
].name
,
5954 MTYPE_BGP_FILTER_NAME
);
5955 PEER_ATTR_INHERIT(peer
, peer
->group
,
5956 filter
[afi
][safi
].aslist
[direct
].aslist
);
5958 /* Otherwise remove configuration from peer. */
5959 filter
= &peer
->filter
[afi
][safi
];
5960 if (filter
->aslist
[direct
].name
)
5961 XFREE(MTYPE_BGP_FILTER_NAME
,
5962 filter
->aslist
[direct
].name
);
5963 filter
->aslist
[direct
].name
= NULL
;
5964 filter
->aslist
[direct
].aslist
= NULL
;
5967 /* Check if handling a regular peer. */
5968 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5969 /* Process peer route updates. */
5970 peer_on_policy_change(peer
, afi
, safi
,
5971 (direct
== FILTER_OUT
) ? 1 : 0);
5973 /* Skip peer-group mechanics for regular peers. */
5978 * Remove configuration on all peer-group members, unless they are
5979 * explicitely overriding peer-group configuration.
5981 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5982 /* Skip peers with overridden configuration. */
5983 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5984 PEER_FT_FILTER_LIST
))
5987 /* Remove configuration on peer-group member. */
5988 filter
= &member
->filter
[afi
][safi
];
5989 if (filter
->aslist
[direct
].name
)
5990 XFREE(MTYPE_BGP_FILTER_NAME
,
5991 filter
->aslist
[direct
].name
);
5992 filter
->aslist
[direct
].name
= NULL
;
5993 filter
->aslist
[direct
].aslist
= NULL
;
5995 /* Process peer route updates. */
5996 peer_on_policy_change(member
, afi
, safi
,
5997 (direct
== FILTER_OUT
) ? 1 : 0);
6003 static void peer_aslist_update(const char *aslist_name
)
6008 struct listnode
*mnode
, *mnnode
;
6009 struct listnode
*node
, *nnode
;
6012 struct peer_group
*group
;
6013 struct bgp_filter
*filter
;
6015 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6016 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6019 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6020 FOREACH_AFI_SAFI (afi
, safi
) {
6021 filter
= &peer
->filter
[afi
][safi
];
6023 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6025 if (filter
->aslist
[direct
].name
)
6026 filter
->aslist
[direct
]
6027 .aslist
= as_list_lookup(
6028 filter
->aslist
[direct
]
6031 filter
->aslist
[direct
].aslist
=
6036 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6037 FOREACH_AFI_SAFI (afi
, safi
) {
6038 filter
= &group
->conf
->filter
[afi
][safi
];
6040 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6042 if (filter
->aslist
[direct
].name
)
6043 filter
->aslist
[direct
]
6044 .aslist
= as_list_lookup(
6045 filter
->aslist
[direct
]
6048 filter
->aslist
[direct
].aslist
=
6056 static void peer_aslist_add(char *aslist_name
)
6058 peer_aslist_update(aslist_name
);
6059 route_map_notify_dependencies((char *)aslist_name
,
6060 RMAP_EVENT_ASLIST_ADDED
);
6063 static void peer_aslist_del(const char *aslist_name
)
6065 peer_aslist_update(aslist_name
);
6066 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6070 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6071 const char *name
, struct route_map
*route_map
)
6073 struct peer
*member
;
6074 struct bgp_filter
*filter
;
6075 struct listnode
*node
, *nnode
;
6077 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6078 return BGP_ERR_INVALID_VALUE
;
6080 /* Set configuration on peer. */
6081 filter
= &peer
->filter
[afi
][safi
];
6082 if (filter
->map
[direct
].name
)
6083 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6084 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6085 filter
->map
[direct
].map
= route_map
;
6087 /* Check if handling a regular peer. */
6088 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6089 /* Set override-flag and process peer route updates. */
6090 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6092 peer_on_policy_change(peer
, afi
, safi
,
6093 (direct
== RMAP_OUT
) ? 1 : 0);
6095 /* Skip peer-group mechanics for regular peers. */
6100 * Set configuration on all peer-group members, unless they are
6101 * explicitely overriding peer-group configuration.
6103 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6104 /* Skip peers with overridden configuration. */
6105 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6109 /* Set configuration on peer-group member. */
6110 filter
= &member
->filter
[afi
][safi
];
6111 if (filter
->map
[direct
].name
)
6112 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6113 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6114 filter
->map
[direct
].map
= route_map
;
6116 /* Process peer route updates. */
6117 peer_on_policy_change(member
, afi
, safi
,
6118 (direct
== RMAP_OUT
) ? 1 : 0);
6123 /* Unset route-map from the peer. */
6124 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6126 struct peer
*member
;
6127 struct bgp_filter
*filter
;
6128 struct listnode
*node
, *nnode
;
6130 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6131 return BGP_ERR_INVALID_VALUE
;
6133 /* Unset override-flag unconditionally. */
6134 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6136 /* Inherit configuration from peer-group if peer is member. */
6137 if (peer_group_active(peer
)) {
6138 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6139 filter
[afi
][safi
].map
[direct
].name
,
6140 MTYPE_BGP_FILTER_NAME
);
6141 PEER_ATTR_INHERIT(peer
, peer
->group
,
6142 filter
[afi
][safi
].map
[direct
].map
);
6144 /* Otherwise remove configuration from peer. */
6145 filter
= &peer
->filter
[afi
][safi
];
6146 if (filter
->map
[direct
].name
)
6147 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6148 filter
->map
[direct
].name
= NULL
;
6149 filter
->map
[direct
].map
= NULL
;
6152 /* Check if handling a regular peer. */
6153 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6154 /* Process peer route updates. */
6155 peer_on_policy_change(peer
, afi
, safi
,
6156 (direct
== RMAP_OUT
) ? 1 : 0);
6158 /* Skip peer-group mechanics for regular peers. */
6163 * Remove configuration on all peer-group members, unless they are
6164 * explicitely overriding peer-group configuration.
6166 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6167 /* Skip peers with overridden configuration. */
6168 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6172 /* Remove configuration on peer-group member. */
6173 filter
= &member
->filter
[afi
][safi
];
6174 if (filter
->map
[direct
].name
)
6175 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6176 filter
->map
[direct
].name
= NULL
;
6177 filter
->map
[direct
].map
= NULL
;
6179 /* Process peer route updates. */
6180 peer_on_policy_change(member
, afi
, safi
,
6181 (direct
== RMAP_OUT
) ? 1 : 0);
6187 /* Set unsuppress-map to the peer. */
6188 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6189 const char *name
, struct route_map
*route_map
)
6191 struct peer
*member
;
6192 struct bgp_filter
*filter
;
6193 struct listnode
*node
, *nnode
;
6195 /* Set configuration on peer. */
6196 filter
= &peer
->filter
[afi
][safi
];
6197 if (filter
->usmap
.name
)
6198 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6199 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6200 filter
->usmap
.map
= route_map
;
6202 /* Check if handling a regular peer. */
6203 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6204 /* Set override-flag and process peer route updates. */
6205 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6206 PEER_FT_UNSUPPRESS_MAP
);
6207 peer_on_policy_change(peer
, afi
, safi
, 1);
6209 /* Skip peer-group mechanics for regular peers. */
6214 * Set configuration on all peer-group members, unless they are
6215 * explicitely overriding peer-group configuration.
6217 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6218 /* Skip peers with overridden configuration. */
6219 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6220 PEER_FT_UNSUPPRESS_MAP
))
6223 /* Set configuration on peer-group member. */
6224 filter
= &member
->filter
[afi
][safi
];
6225 if (filter
->usmap
.name
)
6226 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6227 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6228 filter
->usmap
.map
= route_map
;
6230 /* Process peer route updates. */
6231 peer_on_policy_change(member
, afi
, safi
, 1);
6237 /* Unset route-map from the peer. */
6238 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6240 struct peer
*member
;
6241 struct bgp_filter
*filter
;
6242 struct listnode
*node
, *nnode
;
6244 /* Unset override-flag unconditionally. */
6245 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6247 /* Inherit configuration from peer-group if peer is member. */
6248 if (peer_group_active(peer
)) {
6249 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6250 filter
[afi
][safi
].usmap
.name
,
6251 MTYPE_BGP_FILTER_NAME
);
6252 PEER_ATTR_INHERIT(peer
, peer
->group
,
6253 filter
[afi
][safi
].usmap
.map
);
6255 /* Otherwise remove configuration from peer. */
6256 filter
= &peer
->filter
[afi
][safi
];
6257 if (filter
->usmap
.name
)
6258 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6259 filter
->usmap
.name
= NULL
;
6260 filter
->usmap
.map
= NULL
;
6263 /* Check if handling a regular peer. */
6264 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6265 /* Process peer route updates. */
6266 peer_on_policy_change(peer
, afi
, safi
, 1);
6268 /* Skip peer-group mechanics for regular peers. */
6273 * Remove configuration on all peer-group members, unless they are
6274 * explicitely overriding peer-group configuration.
6276 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6277 /* Skip peers with overridden configuration. */
6278 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6279 PEER_FT_UNSUPPRESS_MAP
))
6282 /* Remove configuration on peer-group member. */
6283 filter
= &member
->filter
[afi
][safi
];
6284 if (filter
->usmap
.name
)
6285 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6286 filter
->usmap
.name
= NULL
;
6287 filter
->usmap
.map
= NULL
;
6289 /* Process peer route updates. */
6290 peer_on_policy_change(member
, afi
, safi
, 1);
6296 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6297 uint32_t max
, uint8_t threshold
, int warning
,
6300 struct peer
*member
;
6301 struct listnode
*node
, *nnode
;
6303 /* Set flags and configuration on peer. */
6304 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6306 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6308 peer_af_flag_unset(peer
, afi
, safi
,
6309 PEER_FLAG_MAX_PREFIX_WARNING
);
6311 peer
->pmax
[afi
][safi
] = max
;
6312 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6313 peer
->pmax_restart
[afi
][safi
] = restart
;
6315 /* Check if handling a regular peer. */
6316 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6317 /* Re-check if peer violates maximum-prefix. */
6318 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6319 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6321 /* Skip peer-group mechanics for regular peers. */
6326 * Set flags and configuration on all peer-group members, unless they
6327 * are explicitely overriding peer-group configuration.
6329 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6330 /* Skip peers with overridden configuration. */
6331 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6332 PEER_FLAG_MAX_PREFIX
))
6335 /* Set flag and configuration on peer-group member. */
6336 member
->pmax
[afi
][safi
] = max
;
6337 member
->pmax_threshold
[afi
][safi
] = threshold
;
6338 member
->pmax_restart
[afi
][safi
] = restart
;
6340 SET_FLAG(member
->af_flags
[afi
][safi
],
6341 PEER_FLAG_MAX_PREFIX_WARNING
);
6343 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6344 PEER_FLAG_MAX_PREFIX_WARNING
);
6346 /* Re-check if peer violates maximum-prefix. */
6347 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6348 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6354 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6356 /* Inherit configuration from peer-group if peer is member. */
6357 if (peer_group_active(peer
)) {
6358 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6359 peer_af_flag_inherit(peer
, afi
, safi
,
6360 PEER_FLAG_MAX_PREFIX_WARNING
);
6361 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6362 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6363 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6368 /* Remove flags and configuration from peer. */
6369 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6370 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6371 peer
->pmax
[afi
][safi
] = 0;
6372 peer
->pmax_threshold
[afi
][safi
] = 0;
6373 peer
->pmax_restart
[afi
][safi
] = 0;
6376 * Remove flags and configuration from all peer-group members, unless
6377 * they are explicitely overriding peer-group configuration.
6379 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6380 struct peer
*member
;
6381 struct listnode
*node
;
6383 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6384 /* Skip peers with overridden configuration. */
6385 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6386 PEER_FLAG_MAX_PREFIX
))
6389 /* Remove flag and configuration on peer-group member.
6391 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6392 PEER_FLAG_MAX_PREFIX
);
6393 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6394 PEER_FLAG_MAX_PREFIX_WARNING
);
6395 member
->pmax
[afi
][safi
] = 0;
6396 member
->pmax_threshold
[afi
][safi
] = 0;
6397 member
->pmax_restart
[afi
][safi
] = 0;
6404 int is_ebgp_multihop_configured(struct peer
*peer
)
6406 struct peer_group
*group
;
6407 struct listnode
*node
, *nnode
;
6410 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6411 group
= peer
->group
;
6412 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6413 && (group
->conf
->ttl
!= 1))
6416 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6417 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6418 && (peer1
->ttl
!= 1))
6422 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6428 /* Set # of hops between us and BGP peer. */
6429 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6431 struct peer_group
*group
;
6432 struct listnode
*node
, *nnode
;
6435 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6436 gtsm_hops
, peer
->host
);
6438 /* We cannot configure ttl-security hops when ebgp-multihop is already
6439 set. For non peer-groups, the check is simple. For peer-groups,
6441 slightly messy, because we need to check both the peer-group
6443 and all peer-group members for any trace of ebgp-multihop
6445 before actually applying the ttl-security rules. Cisco really made a
6446 mess of this configuration parameter, and OpenBGPD got it right.
6449 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6450 if (is_ebgp_multihop_configured(peer
))
6451 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6453 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6454 peer
->gtsm_hops
= gtsm_hops
;
6456 /* Calling ebgp multihop also resets the session.
6457 * On restart, NHT will get setup correctly as will the
6458 * min & max ttls on the socket. The return value is
6461 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6466 group
= peer
->group
;
6467 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6469 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6471 /* Calling ebgp multihop also resets the
6473 * On restart, NHT will get setup correctly as
6475 * min & max ttls on the socket. The return
6479 peer_ebgp_multihop_set(peer
, MAXTTL
);
6483 /* Post the first gtsm setup or if its ibgp, maxttl setting
6485 * necessary, just set the minttl.
6487 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6488 peer
->gtsm_hops
= gtsm_hops
;
6491 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6492 MAXTTL
+ 1 - gtsm_hops
);
6493 if ((peer
->status
< Established
) && peer
->doppelganger
6494 && (peer
->doppelganger
->fd
>= 0))
6495 sockopt_minttl(peer
->su
.sa
.sa_family
,
6496 peer
->doppelganger
->fd
,
6497 MAXTTL
+ 1 - gtsm_hops
);
6499 group
= peer
->group
;
6500 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6502 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6504 /* Change setting of existing peer
6505 * established then change value (may break
6507 * not established yet (teardown session and
6509 * no session then do nothing (will get
6510 * handled by next connection)
6512 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6514 peer
->su
.sa
.sa_family
, peer
->fd
,
6515 MAXTTL
+ 1 - peer
->gtsm_hops
);
6516 if ((peer
->status
< Established
)
6517 && peer
->doppelganger
6518 && (peer
->doppelganger
->fd
>= 0))
6519 sockopt_minttl(peer
->su
.sa
.sa_family
,
6520 peer
->doppelganger
->fd
,
6521 MAXTTL
+ 1 - gtsm_hops
);
6529 int peer_ttl_security_hops_unset(struct peer
*peer
)
6531 struct peer_group
*group
;
6532 struct listnode
*node
, *nnode
;
6535 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6538 /* if a peer-group member, then reset to peer-group default rather than
6540 if (peer_group_active(peer
))
6541 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6543 peer
->gtsm_hops
= 0;
6545 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6546 /* Invoking ebgp_multihop_set will set the TTL back to the
6548 * value as well as restting the NHT and such. The session is
6551 if (peer
->sort
== BGP_PEER_EBGP
)
6552 ret
= peer_ebgp_multihop_unset(peer
);
6555 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6558 if ((peer
->status
< Established
) && peer
->doppelganger
6559 && (peer
->doppelganger
->fd
>= 0))
6560 sockopt_minttl(peer
->su
.sa
.sa_family
,
6561 peer
->doppelganger
->fd
, 0);
6564 group
= peer
->group
;
6565 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6566 peer
->gtsm_hops
= 0;
6567 if (peer
->sort
== BGP_PEER_EBGP
)
6568 ret
= peer_ebgp_multihop_unset(peer
);
6571 sockopt_minttl(peer
->su
.sa
.sa_family
,
6574 if ((peer
->status
< Established
)
6575 && peer
->doppelganger
6576 && (peer
->doppelganger
->fd
>= 0))
6577 sockopt_minttl(peer
->su
.sa
.sa_family
,
6578 peer
->doppelganger
->fd
,
6588 * If peer clear is invoked in a loop for all peers on the BGP instance,
6589 * it may end up freeing the doppelganger, and if this was the next node
6590 * to the current node, we would end up accessing the freed next node.
6591 * Pass along additional parameter which can be updated if next node
6592 * is freed; only required when walking the peer list on BGP instance.
6594 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6596 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6597 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6598 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6599 if (peer
->t_pmax_restart
) {
6600 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6601 if (bgp_debug_neighbor_events(peer
))
6603 "%s Maximum-prefix restart timer canceled",
6606 BGP_EVENT_ADD(peer
, BGP_Start
);
6610 peer
->v_start
= BGP_INIT_START_TIMER
;
6611 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6612 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6613 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6615 bgp_session_reset_safe(peer
, nnode
);
6620 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6621 enum bgp_clear_type stype
)
6623 struct peer_af
*paf
;
6625 if (peer
->status
!= Established
)
6628 if (!peer
->afc
[afi
][safi
])
6629 return BGP_ERR_AF_UNCONFIGURED
;
6631 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6633 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6634 /* Clear the "neighbor x.x.x.x default-originate" flag */
6635 paf
= peer_af_find(peer
, afi
, safi
);
6636 if (paf
&& paf
->subgroup
6637 && CHECK_FLAG(paf
->subgroup
->sflags
,
6638 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6639 UNSET_FLAG(paf
->subgroup
->sflags
,
6640 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6642 bgp_announce_route(peer
, afi
, safi
);
6645 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6646 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6647 PEER_CAP_ORF_PREFIX_SM_ADV
)
6648 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6649 PEER_CAP_ORF_PREFIX_RM_RCV
)
6650 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6651 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6652 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6653 uint8_t prefix_type
;
6655 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6656 PEER_CAP_ORF_PREFIX_RM_RCV
))
6657 prefix_type
= ORF_TYPE_PREFIX
;
6659 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6661 if (filter
->plist
[FILTER_IN
].plist
) {
6662 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6663 PEER_STATUS_ORF_PREFIX_SEND
))
6664 bgp_route_refresh_send(
6665 peer
, afi
, safi
, prefix_type
,
6667 bgp_route_refresh_send(peer
, afi
, safi
,
6669 REFRESH_IMMEDIATE
, 0);
6671 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6672 PEER_STATUS_ORF_PREFIX_SEND
))
6673 bgp_route_refresh_send(
6674 peer
, afi
, safi
, prefix_type
,
6675 REFRESH_IMMEDIATE
, 1);
6677 bgp_route_refresh_send(peer
, afi
, safi
,
6684 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6685 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6686 /* If neighbor has soft reconfiguration inbound flag.
6687 Use Adj-RIB-In database. */
6688 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6689 PEER_FLAG_SOFT_RECONFIG
))
6690 bgp_soft_reconfig_in(peer
, afi
, safi
);
6692 /* If neighbor has route refresh capability, send route
6694 message to the peer. */
6695 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6696 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6697 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6700 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6706 /* Display peer uptime.*/
6707 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6710 time_t uptime1
, epoch_tbuf
;
6713 /* If there is no connection has been done before print `never'. */
6716 json_object_string_add(json
, "peerUptime", "never");
6717 json_object_int_add(json
, "peerUptimeMsec", 0);
6719 snprintf(buf
, len
, "never");
6723 /* Get current time. */
6724 uptime1
= bgp_clock();
6726 tm
= gmtime(&uptime1
);
6728 if (uptime1
< ONE_DAY_SECOND
)
6729 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6731 else if (uptime1
< ONE_WEEK_SECOND
)
6732 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6734 else if (uptime1
< ONE_YEAR_SECOND
)
6735 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6736 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6738 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6740 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6743 epoch_tbuf
= time(NULL
) - uptime1
;
6744 json_object_string_add(json
, "peerUptime", buf
);
6745 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6746 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6753 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6754 afi_t afi
, safi_t safi
)
6756 struct bgp_filter
*filter
;
6760 filter
= &peer
->filter
[afi
][safi
];
6762 /* distribute-list. */
6763 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6765 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6766 filter
->dlist
[FILTER_IN
].name
);
6768 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6770 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6771 filter
->dlist
[FILTER_OUT
].name
);
6774 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6776 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6777 filter
->plist
[FILTER_IN
].name
);
6779 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6781 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6782 filter
->plist
[FILTER_OUT
].name
);
6785 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6786 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6787 filter
->map
[RMAP_IN
].name
);
6789 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6791 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6792 filter
->map
[RMAP_OUT
].name
);
6794 /* unsuppress-map */
6795 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6796 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6797 filter
->usmap
.name
);
6800 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6802 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6803 filter
->aslist
[FILTER_IN
].name
);
6805 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6807 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6808 filter
->aslist
[FILTER_OUT
].name
);
6811 /* BGP peer configuration display function. */
6812 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6815 struct peer
*g_peer
= NULL
;
6816 char buf
[SU_ADDRSTRLEN
];
6818 int if_pg_printed
= FALSE
;
6819 int if_ras_printed
= FALSE
;
6821 /* Skip dynamic neighbors. */
6822 if (peer_dynamic_neighbor(peer
))
6826 addr
= peer
->conf_if
;
6830 /************************************
6831 ****** Global to the neighbor ******
6832 ************************************/
6833 if (peer
->conf_if
) {
6834 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6835 vty_out(vty
, " neighbor %s interface v6only", addr
);
6837 vty_out(vty
, " neighbor %s interface", addr
);
6839 if (peer_group_active(peer
)) {
6840 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6841 if_pg_printed
= TRUE
;
6842 } else if (peer
->as_type
== AS_SPECIFIED
) {
6843 vty_out(vty
, " remote-as %u", peer
->as
);
6844 if_ras_printed
= TRUE
;
6845 } else if (peer
->as_type
== AS_INTERNAL
) {
6846 vty_out(vty
, " remote-as internal");
6847 if_ras_printed
= TRUE
;
6848 } else if (peer
->as_type
== AS_EXTERNAL
) {
6849 vty_out(vty
, " remote-as external");
6850 if_ras_printed
= TRUE
;
6856 /* remote-as and peer-group */
6857 /* peer is a member of a peer-group */
6858 if (peer_group_active(peer
)) {
6859 g_peer
= peer
->group
->conf
;
6861 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6862 if (peer
->as_type
== AS_SPECIFIED
) {
6863 vty_out(vty
, " neighbor %s remote-as %u\n",
6865 } else if (peer
->as_type
== AS_INTERNAL
) {
6867 " neighbor %s remote-as internal\n",
6869 } else if (peer
->as_type
== AS_EXTERNAL
) {
6871 " neighbor %s remote-as external\n",
6876 /* For swpX peers we displayed the peer-group
6877 * via 'neighbor swpX interface peer-group WORD' */
6879 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6883 /* peer is NOT a member of a peer-group */
6885 /* peer is a peer-group, declare the peer-group */
6886 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6887 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6890 if (!if_ras_printed
) {
6891 if (peer
->as_type
== AS_SPECIFIED
) {
6892 vty_out(vty
, " neighbor %s remote-as %u\n",
6894 } else if (peer
->as_type
== AS_INTERNAL
) {
6896 " neighbor %s remote-as internal\n",
6898 } else if (peer
->as_type
== AS_EXTERNAL
) {
6900 " neighbor %s remote-as external\n",
6907 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6908 vty_out(vty
, " neighbor %s local-as %u", addr
,
6909 peer
->change_local_as
);
6910 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6911 vty_out(vty
, " no-prepend");
6912 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6913 vty_out(vty
, " replace-as");
6919 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6923 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6924 if (peer
->tx_shutdown_message
)
6925 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6926 peer
->tx_shutdown_message
);
6928 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6932 if (peer
->bfd_info
) {
6933 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6934 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6939 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6940 vty_out(vty
, " neighbor %s password %s\n", addr
,
6944 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6945 if (!peer_group_active(peer
)) {
6946 vty_out(vty
, " neighbor %s solo\n", addr
);
6951 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6952 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6955 /* Local interface name */
6957 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6961 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6962 vty_out(vty
, " neighbor %s passive\n", addr
);
6965 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6966 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6967 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6968 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6973 /* ttl-security hops */
6974 if (peer
->gtsm_hops
!= 0) {
6975 if (!peer_group_active(peer
)
6976 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6977 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6978 addr
, peer
->gtsm_hops
);
6982 /* disable-connected-check */
6983 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6984 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6986 /* enforce-first-as */
6987 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6988 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6991 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6992 if (peer
->update_source
)
6993 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6994 sockunion2str(peer
->update_source
, buf
,
6996 else if (peer
->update_if
)
6997 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7001 /* advertisement-interval */
7002 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7003 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7007 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7008 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7009 peer
->keepalive
, peer
->holdtime
);
7011 /* timers connect */
7012 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7013 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7016 /* capability dynamic */
7017 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7018 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7020 /* capability extended-nexthop */
7021 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7022 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
7024 " no neighbor %s capability extended-nexthop\n",
7028 " neighbor %s capability extended-nexthop\n",
7032 /* dont-capability-negotiation */
7033 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7034 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7036 /* override-capability */
7037 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7038 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7040 /* strict-capability-match */
7041 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7042 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7045 /* BGP peer configuration display function. */
7046 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7047 struct peer
*peer
, afi_t afi
, safi_t safi
)
7049 struct peer
*g_peer
= NULL
;
7051 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7053 /* Skip dynamic neighbors. */
7054 if (peer_dynamic_neighbor(peer
))
7058 addr
= peer
->conf_if
;
7062 /************************************
7063 ****** Per AF to the neighbor ******
7064 ************************************/
7065 if (peer_group_active(peer
)) {
7066 g_peer
= peer
->group
->conf
;
7068 /* If the peer-group is active but peer is not, print a 'no
7070 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7071 vty_out(vty
, " no neighbor %s activate\n", addr
);
7074 /* If the peer-group is not active but peer is, print an
7076 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7077 vty_out(vty
, " neighbor %s activate\n", addr
);
7080 if (peer
->afc
[afi
][safi
]) {
7081 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7082 if (bgp_flag_check(bgp
,
7083 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7084 vty_out(vty
, " neighbor %s activate\n",
7088 vty_out(vty
, " neighbor %s activate\n", addr
);
7090 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7091 if (!bgp_flag_check(bgp
,
7092 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7094 " no neighbor %s activate\n",
7101 /* addpath TX knobs */
7102 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7103 switch (peer
->addpath_type
[afi
][safi
]) {
7104 case BGP_ADDPATH_ALL
:
7105 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7108 case BGP_ADDPATH_BEST_PER_AS
:
7110 " neighbor %s addpath-tx-bestpath-per-AS\n",
7113 case BGP_ADDPATH_MAX
:
7114 case BGP_ADDPATH_NONE
:
7119 /* ORF capability. */
7120 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7121 || peergroup_af_flag_check(peer
, afi
, safi
,
7122 PEER_FLAG_ORF_PREFIX_RM
)) {
7123 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7125 if (peergroup_af_flag_check(peer
, afi
, safi
,
7126 PEER_FLAG_ORF_PREFIX_SM
)
7127 && peergroup_af_flag_check(peer
, afi
, safi
,
7128 PEER_FLAG_ORF_PREFIX_RM
))
7129 vty_out(vty
, " both");
7130 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7131 PEER_FLAG_ORF_PREFIX_SM
))
7132 vty_out(vty
, " send");
7134 vty_out(vty
, " receive");
7138 /* Route reflector client. */
7139 if (peergroup_af_flag_check(peer
, afi
, safi
,
7140 PEER_FLAG_REFLECTOR_CLIENT
)) {
7141 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7144 /* next-hop-self force */
7145 if (peergroup_af_flag_check(peer
, afi
, safi
,
7146 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7147 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7151 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7152 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7155 /* remove-private-AS */
7156 if (peergroup_af_flag_check(peer
, afi
, safi
,
7157 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7158 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7162 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7163 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7164 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7168 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7169 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7170 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7173 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7174 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7175 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7179 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7180 vty_out(vty
, " neighbor %s as-override\n", addr
);
7183 /* send-community print. */
7184 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7185 PEER_FLAG_SEND_COMMUNITY
);
7186 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7187 PEER_FLAG_SEND_EXT_COMMUNITY
);
7188 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7189 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7191 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7192 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7193 vty_out(vty
, " no neighbor %s send-community all\n",
7198 " no neighbor %s send-community\n",
7202 " no neighbor %s send-community extended\n",
7207 " no neighbor %s send-community large\n",
7211 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7212 vty_out(vty
, " neighbor %s send-community all\n",
7214 } else if (flag_scomm
&& flag_secomm
) {
7215 vty_out(vty
, " neighbor %s send-community both\n",
7219 vty_out(vty
, " neighbor %s send-community\n",
7223 " neighbor %s send-community extended\n",
7227 " neighbor %s send-community large\n",
7232 /* Default information */
7233 if (peergroup_af_flag_check(peer
, afi
, safi
,
7234 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7235 vty_out(vty
, " neighbor %s default-originate", addr
);
7237 if (peer
->default_rmap
[afi
][safi
].name
)
7238 vty_out(vty
, " route-map %s",
7239 peer
->default_rmap
[afi
][safi
].name
);
7244 /* Soft reconfiguration inbound. */
7245 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7246 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7250 /* maximum-prefix. */
7251 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7252 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7253 peer
->pmax
[afi
][safi
]);
7255 if (peer
->pmax_threshold
[afi
][safi
]
7256 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7257 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7258 if (peer_af_flag_check(peer
, afi
, safi
,
7259 PEER_FLAG_MAX_PREFIX_WARNING
))
7260 vty_out(vty
, " warning-only");
7261 if (peer
->pmax_restart
[afi
][safi
])
7262 vty_out(vty
, " restart %u",
7263 peer
->pmax_restart
[afi
][safi
]);
7268 /* Route server client. */
7269 if (peergroup_af_flag_check(peer
, afi
, safi
,
7270 PEER_FLAG_RSERVER_CLIENT
)) {
7271 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7274 /* Nexthop-local unchanged. */
7275 if (peergroup_af_flag_check(peer
, afi
, safi
,
7276 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7277 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7280 /* allowas-in <1-10> */
7281 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7282 if (peer_af_flag_check(peer
, afi
, safi
,
7283 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7284 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7285 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7286 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7288 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7289 peer
->allowas_in
[afi
][safi
]);
7294 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7295 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7296 peer
->weight
[afi
][safi
]);
7299 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7301 /* atribute-unchanged. */
7302 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7303 || (safi
!= SAFI_EVPN
7304 && peer_af_flag_check(peer
, afi
, safi
,
7305 PEER_FLAG_NEXTHOP_UNCHANGED
))
7306 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7308 if (!peer_group_active(peer
)
7309 || peergroup_af_flag_check(peer
, afi
, safi
,
7310 PEER_FLAG_AS_PATH_UNCHANGED
)
7311 || peergroup_af_flag_check(peer
, afi
, safi
,
7312 PEER_FLAG_NEXTHOP_UNCHANGED
)
7313 || peergroup_af_flag_check(peer
, afi
, safi
,
7314 PEER_FLAG_MED_UNCHANGED
)) {
7317 " neighbor %s attribute-unchanged%s%s%s\n",
7319 peer_af_flag_check(peer
, afi
, safi
,
7320 PEER_FLAG_AS_PATH_UNCHANGED
)
7323 peer_af_flag_check(peer
, afi
, safi
,
7324 PEER_FLAG_NEXTHOP_UNCHANGED
)
7327 peer_af_flag_check(peer
, afi
, safi
,
7328 PEER_FLAG_MED_UNCHANGED
)
7335 /* Address family based peer configuration display. */
7336 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7340 struct peer_group
*group
;
7341 struct listnode
*node
, *nnode
;
7344 vty_frame(vty
, " !\n address-family ");
7345 if (afi
== AFI_IP
) {
7346 if (safi
== SAFI_UNICAST
)
7347 vty_frame(vty
, "ipv4 unicast");
7348 else if (safi
== SAFI_LABELED_UNICAST
)
7349 vty_frame(vty
, "ipv4 labeled-unicast");
7350 else if (safi
== SAFI_MULTICAST
)
7351 vty_frame(vty
, "ipv4 multicast");
7352 else if (safi
== SAFI_MPLS_VPN
)
7353 vty_frame(vty
, "ipv4 vpn");
7354 else if (safi
== SAFI_ENCAP
)
7355 vty_frame(vty
, "ipv4 encap");
7356 else if (safi
== SAFI_FLOWSPEC
)
7357 vty_frame(vty
, "ipv4 flowspec");
7358 } else if (afi
== AFI_IP6
) {
7359 if (safi
== SAFI_UNICAST
)
7360 vty_frame(vty
, "ipv6 unicast");
7361 else if (safi
== SAFI_LABELED_UNICAST
)
7362 vty_frame(vty
, "ipv6 labeled-unicast");
7363 else if (safi
== SAFI_MULTICAST
)
7364 vty_frame(vty
, "ipv6 multicast");
7365 else if (safi
== SAFI_MPLS_VPN
)
7366 vty_frame(vty
, "ipv6 vpn");
7367 else if (safi
== SAFI_ENCAP
)
7368 vty_frame(vty
, "ipv6 encap");
7369 else if (safi
== SAFI_FLOWSPEC
)
7370 vty_frame(vty
, "ipv6 flowspec");
7371 } else if (afi
== AFI_L2VPN
) {
7372 if (safi
== SAFI_EVPN
)
7373 vty_frame(vty
, "l2vpn evpn");
7375 vty_frame(vty
, "\n");
7377 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7379 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7381 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7383 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7384 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7386 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7387 /* Skip dynamic neighbors. */
7388 if (peer_dynamic_neighbor(peer
))
7391 /* Do not display doppelganger peers */
7392 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7393 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7396 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7397 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7399 if (safi
== SAFI_EVPN
)
7400 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7402 if (safi
== SAFI_FLOWSPEC
)
7403 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7405 if (safi
== SAFI_UNICAST
) {
7406 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7407 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7408 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7410 vty_out(vty
, " export vpn\n");
7412 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7413 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7415 vty_out(vty
, " import vpn\n");
7417 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7418 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7421 for (ALL_LIST_ELEMENTS_RO(
7422 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7424 vty_out(vty
, " import vrf %s\n", name
);
7428 vty_endframe(vty
, " exit-address-family\n");
7431 /* clang-format off */
7432 #if CONFDATE > 20190517
7433 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7435 /* clang-format on */
7437 int bgp_config_write(struct vty
*vty
)
7441 struct peer_group
*group
;
7443 struct listnode
*node
, *nnode
;
7444 struct listnode
*mnode
, *mnnode
;
7446 /* BGP Multiple instance. */
7447 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7448 vty_out(vty
, "no bgp multiple-instance\n");
7452 /* BGP Config type. */
7453 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7454 vty_out(vty
, "bgp config-type cisco\n");
7458 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7459 vty_out(vty
, "bgp route-map delay-timer %u\n",
7460 bm
->rmap_update_timer
);
7463 vty_out(vty
, "!\n");
7465 /* BGP configuration. */
7466 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7468 /* skip all auto created vrf as they dont have user config */
7469 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7472 /* Migrate deprecated 'bgp enforce-first-as'
7473 * config to 'neighbor * enforce-first-as' configs
7475 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7476 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7477 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7478 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7481 /* Router bgp ASN */
7482 vty_out(vty
, "router bgp %u", bgp
->as
);
7484 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7486 vty_out(vty
, " %s %s",
7488 == BGP_INSTANCE_TYPE_VIEW
)
7495 /* No Synchronization */
7496 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7497 vty_out(vty
, " no synchronization\n");
7499 /* BGP fast-external-failover. */
7500 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7501 vty_out(vty
, " no bgp fast-external-failover\n");
7503 /* BGP router ID. */
7504 if (bgp
->router_id_static
.s_addr
!= 0)
7505 vty_out(vty
, " bgp router-id %s\n",
7506 inet_ntoa(bgp
->router_id_static
));
7508 /* BGP log-neighbor-changes. */
7509 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7510 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7511 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7513 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7517 /* BGP configuration. */
7518 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7519 vty_out(vty
, " bgp always-compare-med\n");
7521 /* BGP default ipv4-unicast. */
7522 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7523 vty_out(vty
, " no bgp default ipv4-unicast\n");
7525 /* BGP default local-preference. */
7526 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7527 vty_out(vty
, " bgp default local-preference %u\n",
7528 bgp
->default_local_pref
);
7530 /* BGP default show-hostname */
7531 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7532 != DFLT_BGP_SHOW_HOSTNAME
)
7533 vty_out(vty
, " %sbgp default show-hostname\n",
7534 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7538 /* BGP default subgroup-pkt-queue-max. */
7539 if (bgp
->default_subgroup_pkt_queue_max
7540 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7541 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7542 bgp
->default_subgroup_pkt_queue_max
);
7544 /* BGP client-to-client reflection. */
7545 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7546 vty_out(vty
, " no bgp client-to-client reflection\n");
7548 /* BGP cluster ID. */
7549 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7550 vty_out(vty
, " bgp cluster-id %s\n",
7551 inet_ntoa(bgp
->cluster_id
));
7553 /* Disable ebgp connected nexthop check */
7554 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7556 " bgp disable-ebgp-connected-route-check\n");
7558 /* Confederation identifier*/
7559 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7560 vty_out(vty
, " bgp confederation identifier %u\n",
7563 /* Confederation peer */
7564 if (bgp
->confed_peers_cnt
> 0) {
7567 vty_out(vty
, " bgp confederation peers");
7569 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7570 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7575 /* BGP deterministic-med. */
7576 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7577 != DFLT_BGP_DETERMINISTIC_MED
)
7578 vty_out(vty
, " %sbgp deterministic-med\n",
7579 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7583 /* BGP update-delay. */
7584 bgp_config_write_update_delay(vty
, bgp
);
7586 if (bgp
->v_maxmed_onstartup
7587 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7588 vty_out(vty
, " bgp max-med on-startup %u",
7589 bgp
->v_maxmed_onstartup
);
7590 if (bgp
->maxmed_onstartup_value
7591 != BGP_MAXMED_VALUE_DEFAULT
)
7593 bgp
->maxmed_onstartup_value
);
7596 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7597 vty_out(vty
, " bgp max-med administrative");
7598 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7599 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7604 bgp_config_write_wpkt_quanta(vty
, bgp
);
7606 bgp_config_write_rpkt_quanta(vty
, bgp
);
7609 bgp_config_write_coalesce_time(vty
, bgp
);
7611 /* BGP graceful-restart. */
7612 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7614 " bgp graceful-restart stalepath-time %u\n",
7615 bgp
->stalepath_time
);
7616 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7617 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7619 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7620 vty_out(vty
, " bgp graceful-restart\n");
7622 /* BGP graceful-shutdown */
7623 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7624 vty_out(vty
, " bgp graceful-shutdown\n");
7626 /* BGP graceful-restart Preserve State F bit. */
7627 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7629 " bgp graceful-restart preserve-fw-state\n");
7631 /* BGP bestpath method. */
7632 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7633 vty_out(vty
, " bgp bestpath as-path ignore\n");
7634 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7635 vty_out(vty
, " bgp bestpath as-path confed\n");
7637 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7638 if (bgp_flag_check(bgp
,
7639 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7641 " bgp bestpath as-path multipath-relax as-set\n");
7644 " bgp bestpath as-path multipath-relax\n");
7648 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7650 " bgp route-reflector allow-outbound-policy\n");
7652 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7653 vty_out(vty
, " bgp bestpath compare-routerid\n");
7654 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7655 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7656 vty_out(vty
, " bgp bestpath med");
7657 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7658 vty_out(vty
, " confed");
7659 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7660 vty_out(vty
, " missing-as-worst");
7664 /* BGP network import check. */
7665 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7666 != DFLT_BGP_IMPORT_CHECK
)
7667 vty_out(vty
, " %sbgp network import-check\n",
7668 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7672 /* BGP flag dampening. */
7673 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7674 BGP_CONFIG_DAMPENING
))
7675 bgp_config_write_damp(vty
);
7677 /* BGP timers configuration. */
7678 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7679 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7680 vty_out(vty
, " timers bgp %u %u\n",
7681 bgp
->default_keepalive
, bgp
->default_holdtime
);
7684 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7685 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7688 /* Normal neighbor configuration. */
7689 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7690 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7691 bgp_config_write_peer_global(vty
, bgp
, peer
);
7694 /* listen range and limit for dynamic BGP neighbors */
7695 bgp_config_write_listen(vty
, bgp
);
7698 * BGP default autoshutdown neighbors
7700 * This must be placed after any peer and peer-group
7701 * configuration, to avoid setting all peers to shutdown after
7702 * a daemon restart, which is undesired behavior. (see #2286)
7704 if (bgp
->autoshutdown
)
7705 vty_out(vty
, " bgp default shutdown\n");
7707 /* No auto-summary */
7708 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7709 vty_out(vty
, " no auto-summary\n");
7711 /* IPv4 unicast configuration. */
7712 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7714 /* IPv4 multicast configuration. */
7715 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7717 /* IPv4 labeled-unicast configuration. */
7718 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7720 /* IPv4 VPN configuration. */
7721 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7723 /* ENCAPv4 configuration. */
7724 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7726 /* FLOWSPEC v4 configuration. */
7727 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7729 /* IPv6 unicast configuration. */
7730 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7732 /* IPv6 multicast configuration. */
7733 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7735 /* IPv6 labeled-unicast configuration. */
7736 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7737 SAFI_LABELED_UNICAST
);
7739 /* IPv6 VPN configuration. */
7740 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7742 /* ENCAPv6 configuration. */
7743 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7745 /* FLOWSPEC v6 configuration. */
7746 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7748 /* EVPN configuration. */
7749 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7752 bgp_rfapi_cfg_write(vty
, bgp
);
7755 vty_out(vty
, "!\n");
7760 void bgp_master_init(struct thread_master
*master
)
7764 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7767 bm
->bgp
= list_new();
7768 bm
->listen_sockets
= list_new();
7769 bm
->port
= BGP_PORT_DEFAULT
;
7770 bm
->master
= master
;
7771 bm
->start_time
= bgp_clock();
7772 bm
->t_rmap_update
= NULL
;
7773 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7774 bm
->terminating
= false;
7776 bgp_process_queue_init();
7778 /* init the rd id space.
7779 assign 0th index in the bitfield,
7780 so that we start with id 1
7782 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7783 bf_assign_zero_index(bm
->rd_idspace
);
7785 /* Enable multiple instances by default. */
7786 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7788 /* mpls label dynamic allocation pool */
7789 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7791 QOBJ_REG(bm
, bgp_master
);
7795 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7796 * instance delete (non-default only) or BGP exit.
7798 static void bgp_if_finish(struct bgp
*bgp
)
7800 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7801 struct interface
*ifp
;
7803 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7806 FOR_ALL_INTERFACES (vrf
, ifp
) {
7807 struct listnode
*c_node
, *c_nnode
;
7808 struct connected
*c
;
7810 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7811 bgp_connected_delete(bgp
, c
);
7815 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7817 struct vrf
*vrf
= NULL
;
7818 struct listnode
*next
;
7821 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7822 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7824 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7825 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7828 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7832 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7833 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7834 {.completions
= NULL
},
7837 struct frr_pthread
*bgp_pth_io
;
7838 struct frr_pthread
*bgp_pth_ka
;
7840 static void bgp_pthreads_init()
7842 assert(!bgp_pth_io
);
7843 assert(!bgp_pth_ka
);
7847 struct frr_pthread_attr io
= {
7848 .start
= frr_pthread_attr_default
.start
,
7849 .stop
= frr_pthread_attr_default
.stop
,
7851 struct frr_pthread_attr ka
= {
7852 .start
= bgp_keepalives_start
,
7853 .stop
= bgp_keepalives_stop
,
7855 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7856 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7859 void bgp_pthreads_run()
7861 frr_pthread_run(bgp_pth_io
, NULL
);
7862 frr_pthread_run(bgp_pth_ka
, NULL
);
7864 /* Wait until threads are ready. */
7865 frr_pthread_wait_running(bgp_pth_io
);
7866 frr_pthread_wait_running(bgp_pth_ka
);
7869 void bgp_pthreads_finish()
7871 frr_pthread_stop_all();
7872 frr_pthread_finish();
7875 void bgp_init(unsigned short instance
)
7878 /* allocates some vital data structures used by peer commands in
7881 /* pre-init pthreads */
7882 bgp_pthreads_init();
7885 bgp_zebra_init(bm
->master
, instance
);
7888 vnc_zebra_init(bm
->master
);
7891 /* BGP VTY commands installation. */
7899 bgp_route_map_init();
7900 bgp_scan_vty_init();
7905 bgp_ethernetvpn_init();
7906 bgp_flowspec_vty_init();
7908 /* Access list initialize. */
7910 access_list_add_hook(peer_distribute_update
);
7911 access_list_delete_hook(peer_distribute_update
);
7913 /* Filter list initialize. */
7915 as_list_add_hook(peer_aslist_add
);
7916 as_list_delete_hook(peer_aslist_del
);
7918 /* Prefix list initialize.*/
7920 prefix_list_add_hook(peer_prefix_list_update
);
7921 prefix_list_delete_hook(peer_prefix_list_update
);
7923 /* Community list initialize. */
7924 bgp_clist
= community_list_init();
7929 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7932 void bgp_terminate(void)
7936 struct listnode
*node
, *nnode
;
7937 struct listnode
*mnode
, *mnnode
;
7941 /* Close the listener sockets first as this prevents peers from
7943 * to reconnect on receiving the peer unconfig message. In the presence
7944 * of a large number of peers this will ensure that no peer is left with
7945 * a dangling connection
7947 /* reverse bgp_master_init */
7950 if (bm
->listen_sockets
)
7951 list_delete(&bm
->listen_sockets
);
7953 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7954 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7955 if (peer
->status
== Established
7956 || peer
->status
== OpenSent
7957 || peer
->status
== OpenConfirm
)
7958 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7959 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7961 if (bm
->process_main_queue
)
7962 work_queue_free_and_null(&bm
->process_main_queue
);
7964 if (bm
->t_rmap_update
)
7965 BGP_TIMER_OFF(bm
->t_rmap_update
);